Dirk Eddelbuettel — Dec 24, 2012 | source
R comes with several random number generators supporting the ability to draw random samples from a wide variety of statistical distributions.
Rcpp builds on this, and provides access to the same random number generators, and distributions. Moreover, thanks to Rcpp sugar, these can be accessed in a vectorised manner, as we illustrated in the post simulating pi.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix rngCpp(const int N) {
RNGScope scope; // ensure RNG gets set/reset
NumericMatrix X(N, 4);
X(_, 0) = runif(N);
X(_, 1) = rnorm(N);
X(_, 2) = rt(N, 5);
X(_, 3) = rbeta(N, 1, 1);
return X;
}
set.seed(42) # setting seed
M1 <- rngCpp(5)
M1
[,1] [,2] [,3] [,4]
[1,] 0.9148 0.04788 2.9967 0.79234
[2,] 0.9371 -1.10460 0.8067 0.38822
[3,] 0.2861 0.53902 -1.7226 0.56423
[4,] 0.8304 0.58021 0.8337 0.02646
[5,] 0.6417 -0.65750 0.4019 0.04242
set.seed(42) # resetting seed
M2 <- cbind( runif(5), rnorm(5), rt(5, 5), rbeta(5, 1, 1))
M2
[,1] [,2] [,3] [,4]
[1,] 0.9148 0.04788 2.9967 0.79234
[2,] 0.9371 -1.10460 0.8067 0.38822
[3,] 0.2861 0.53902 -1.7226 0.56423
[4,] 0.8304 0.58021 0.8337 0.02646
[5,] 0.6417 -0.65750 0.4019 0.04242
all.equal(M1, M2)
[1] TRUE
The other method of using the R random-number generator is in scalar mode, one variable and draw at a time. This is very similar to the description of this API in the Writing R Extensions manual, and provided by Rcpp in the R namespace:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector rngCppScalar() {
RNGScope scope; // ensure RNG gets set/reset
NumericVector x(4);
x[0] = R::runif(0,1);
x[1] = R::rnorm(0,1);
x[2] = R::rt(5);
x[3] = R::rbeta(1,1);
return(x);
}
set.seed(42)
v1 <- rngCppScalar()
v1
[1] 0.9148 1.5307 1.0510 0.8653
set.seed(42)
v2 <-c(runif(1), rnorm(1,0,1), rt(1,5), rbeta(1,1,1))
v2
[1] 0.9148 1.5307 1.0510 0.8653
all.equal(v1, v2)
[1] TRUETweet