I\'m trying to learn how to draw random numbers from a normal and a binomial distribution from within a Rcpp OpenMP loop.
I wrote the following code using R::rnorm
A simple solution would be to create a new distribution object within the loop:
// [[Rcpp::depends(dqrng, BH, RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <boost/random/binomial_distribution.hpp>
#include <xoshiro.h>
#include <dqrng_distribution.h>
// [[Rcpp::plugins(openmp)]]
#include <omp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
arma::mat parallel_random_matrix(int n, int m, int ncores, double p=0.5) {
dqrng::xoshiro256plus rng(42);
arma::mat out(n,m);
// ok to use rng here
#pragma omp parallel num_threads(ncores)
{
dqrng::xoshiro256plus lrng(rng); // make thread local copy of rng
lrng.jump(omp_get_thread_num() + 1); // advance rng by 1 ... ncores jumps
#pragma omp for
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
// p can be a function of i and j
boost::random::binomial_distribution<int> dist(1,p);
auto gen = std::bind(dist, std::ref(lrng));
out(j,i) = gen();
}
}
}
// ok to use rng here
return out;
}
/*** R
parallel_random_matrix(5, 5, 4, 0.75)
*/
This way you can make p
depend on i
and j
. It might be more efficient to keep one global dist
object and reconfigure it within the loop, see here for a similar question.