-
|
I would like to generate a random matrix of uniform distributed numbers in a "sequential" way. #include <Rcpp.h>
// [[Rcpp::depends(dqrng, BH)]]
#include <dqrng_distribution.h>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::NumericMatrix random_mtx(int n, int m) {
dqrng::uniform_distribution dist(0.0, 1.0); // Uniform distribution [0,1)
auto rng = dqrng::generator<dqrng::xoshiro256plusplus>();
// seeded from R's RNG
Rcpp::NumericMatrix res(n,m);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
res(j,i) = dist(*rng);
}
}
return res;
}
/*** R
vrng <- random_mtx(100, 10)
print(symnum(x = cor(vrng), cutpoints = c(0.001, 0.003, 0.999),
symbols = c(" ", "?", "!", "1"),
abbr.colnames = FALSE, corr = TRUE))
*/and and even the following has the same problem: #include <Rcpp.h>
// [[Rcpp::depends(dqrng, BH)]]
#include <dqrng_distribution.h>
#include <xoshiro.h>
template<typename RNG>
Rcpp::NumericVector runif_rng(int n, int seme, int procx) {
auto rng = dqrng::generator<RNG>(seme, procx);
dqrng::uniform_distribution dist;
Rcpp::NumericVector result(Rcpp::no_init(n));
std::generate(result.begin(), result.end(), [rng, dist] () {return dist(*rng);});
return result;
}
// [[Rcpp::export]]
Rcpp::NumericMatrix runif_256plusplus(int n, int m, int seme) {
Rcpp::NumericMatrix v0(n,m);
for (int i = 0; i < m; ++i) {
Rcpp::NumericVector v1 = runif_rng<dqrng::xoshiro256plusplus>(n, seme * i +1,i);
for (int j = 0; j < n; ++j){
v0(j,i)=v1(j);
}
}
return v0;
}
/*** R
library(bench)
N <- 100
bm <- bench::mark(
runif_256plusplus(N, 10, 2025),
check = FALSE,
min_time = 1
)
print(bm[, 1:6])
vec1 <- runif_256plusplus(N, 10, 2025)
print(symnum(x = cor(vec1), cutpoints = c(0.001, 0.003, 0.999),
symbols = c(" ", "?", "!", "1"),
abbr.colnames = FALSE, corr = TRUE))
*/
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
|
The cut points BTW, since it is possible to iterate over a #include <Rcpp.h>
// [[Rcpp::depends(dqrng, BH)]]
#include <dqrng_distribution.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix random_mtx(int n, int m) {
auto rng = dqrng::generator<dqrng::xoshiro256plusplus>();
// seeded from R's RNG
Rcpp::NumericMatrix res(n,m);
rng->generate<dqrng::uniform_distribution>(res, 0.0, 1.0);
return res;
} |
Beta Was this translation helpful? Give feedback.
-
|
Thank you very much for your precious help! Forgive me for some further questions. I would like to build a stochastic model for simulating the evolution of a population of insured people. The simulation process implies a huge number of random drawings at different steps (eg a time orizon of 10 years and 100 replications need 1000 random drawings), so I am wondering whether there are Rccp instructions to set the seed of the random number generator at each iteration. Morover I hope it is possible to get control over rng and to manage all the process by Rcpp, speed is crucial. |
Beta Was this translation helpful? Give feedback.
-
|
Sorry for taking some days before answering. I think you solved my problem, I had no dubt about! #include <Rcpp.h>
#include <random>
//#include <algorithm>
// [[Rcpp::depends(dqrng, BH)]]
#include <dqrng_distribution.h>
using namespace Rcpp;
inline Rcpp::NumericMatrix random_mtx(int n, int m) {
auto rng = dqrng::generator<dqrng::xoshiro256plusplus>();
// seeded from R's RNG
Rcpp::NumericMatrix res(n,m);
rng->generate<dqrng::uniform_distribution>(res, 0.0, 1.0);
return res;
}
inline Rcpp::IntegerMatrix permutazioni(int n,Rcpp::IntegerVector x) {
Rcpp::IntegerMatrix perm(n,x.size());
for(int i = 0; i < n; ++i) {
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(x.begin(), x.end(), g);
for(int j = 0; j <x.size();j++){
perm(i,j)=x[j];
}
}
return perm;
}
// [[Rcpp::export]]
Rcpp::NumericMatrix scenari_seq(int nR, int nC, IntegerVector mEventiAtt, IntegerVector mEventiCes, int nAnni, int nRip) {
Rcpp::NumericMatrix mSim(nR, nC + 3 * nAnni);
double mpcM=0.0;
double mpcU =0.0;
int nEA = mEventiAtt.size();
int nEC = mEventiCes.size();
for(int r = 1; r <= nRip; r++) {
Rcpp::NumericMatrix mpcMorte(nR, nAnni);
Rcpp::NumericMatrix mpcPensione(nR, nAnni);
Rcpp::NumericMatrix mpcRiscatto(nR, nAnni);
Rcpp::NumericMatrix mpcUscita(nR, nAnni);
Rcpp::IntegerMatrix mEventiAtt1(nR, nEA);
Rcpp::IntegerMatrix mEventiCes1(nR, nEC);
mpcMorte = random_mtx(nR, nAnni);
mpcPensione = random_mtx(nR, nAnni);
mpcRiscatto = random_mtx(nR, nAnni);
mpcUscita = random_mtx(nR, nAnni);
mEventiAtt1 = permutazioni(nR, mEventiAtt);
mEventiCes1 = permutazioni(nR, mEventiCes);
for(int t = 1; t <= nAnni; t++) {
for(int i = 0; i < nR; i++) {
} //next i
mpcM = mpcMorte(0,t-1);
mpcU = mpcUscita(0,t-1);
Rcout << "iterazione: "<< r << ", epoca: "<< t <<": " << mpcU << "; " << mpcM << std::endl;
} //next t
} //next r
return mSim;
}
/*** R
mEventiAtt <- as.matrix(c(1,2,3,4))
mEventiCes <- as.matrix(c(1,2,3,4))
set.seed(20250420)
scenari_seq(100, 8, mEventiAtt, mEventiCes, 10,100)
*/ |
Beta Was this translation helpful? Give feedback.
The cut points
c(0.001, 0.003, 0.999)forc(" ", "?", "!", "1")are very aggressive, i.e. anything above0.003is marked as!. I am not sure what the distribution function of correlation coefficients is, but it seems for vectors of 100 random numbers, it is unlikely to go below0.003. Things look much better if you use1e6instead of100, like it is done in the parallel vignette: