Intro
The goal behind this post is to quickly point out a solution for setting the random seed from within Rcpp. This is particularly helpful to control the reproducibility of the RNG.
RNG Seed Control from C++
By default in R, you can set a random seed using:
set.seed(seed_here)
However, the ability to modify the seed from within C++ is particularly problematic. This is most notably the case if you are trying to perform indirect inference.
In this case, I propose a quick function that is able to facilitate this.
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
//' Set the RNG Seed from within Rcpp
//'
//' Within Rcpp, one can set the R session seed without triggering
//' the CRAN rng modifier check.
//' @param seed A \code{unsigned int} that is the seed one wishes to use.
//' @return A set RNG scope.
//' @examples
//' set.seed(10)
//' x = rnorm(5,0,1)
//' set_seed(10)
//' y = rnorm(5,0,1)
//' all.equal(x,y, check.attributes = F)
// [[Rcpp::export]]
void set_seed(unsigned int seed) {
::Environment base_env("package:base");
Rcpp::Function set_seed_r = base_env["set.seed"];
Rcpp(seed);
set_seed_r}
From there, you can invoke this function within other C++ code ala:
void gen_test(unsigned int n){
::vec m(n);
arma
for(unsigned int i = 0; i < m.n_elem; i++){
(i) = R::rnorm(10,5);
m}
::Rcout << m << std::endl;
Rcpp}
// [[Rcpp::export]]
void test_seed(unsigned int seed, unsigned int n){
(seed);
set_seed
::Rcout << "First realization after setting seed to " << seed << "." << std::endl;
Rcpp(n);
gen_test
(seed);
set_seed
::Rcout << "Second realization after setting seed to " << seed << "." << std::endl;
Rcpp
(n);
gen_test}
Note that this approach is useful to control a seed that is begin used in a sequential manner (e.g. one after another). Unfortunately, under parallelization, the approach will fail horrible since the seed will be constantly reset. At a later time, I’ll address the use of engines and RNG within C++ (std / boost) that is able to be used in parallel. (This means that R::r* functions are unable to be used.)
Testing Solution
A quick test from both the R and Rcpp functions reveal that is a valid approach for seed control.
# Set values
= 1335
seed = 6
obs
# Generation from R:
set.seed(seed)
as.matrix(rnorm(obs,10,5))
## [,1]
## [1,] 10.518265
## [2,] 9.901971
## [3,] 13.124864
## [4,] 10.656016
## [5,] 13.169765
## [6,] 12.631096
# C++ Controlled Set
test_seed(seed,obs)
## First realization after setting seed to 1335.
## 10.5183
## 9.9020
## 13.1249
## 10.6560
## 13.1698
## 12.6311
##
## Second realization after setting seed to 1335.
## 10.5183
## 9.9020
## 13.1249
## 10.6560
## 13.1698
## 12.6311