# Set R's Seed in Rcpp (Sequential Case)

## 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>

//' 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) {
Rcpp::Environment base_env("package:base");
Rcpp::Function set_seed_r = base_env["set.seed"];
set_seed_r(seed);
}


From there, you can invoke this function within other C++ code ala:

void gen_test(unsigned int n){
arma::vec m(n);

for(unsigned int i = 0; i < m.n_elem; i++){
m(i) =  R::rnorm(10,5);
}
Rcpp::Rcout << m << std::endl;
}

// [[Rcpp::export]]
void test_seed(unsigned int seed, unsigned int n){
set_seed(seed);

Rcpp::Rcout << "First realization after setting seed to " << seed << "." << std::endl;
gen_test(n);

set_seed(seed);

Rcpp::Rcout << "Second realization after setting seed to " << seed << "." << std::endl;

gen_test(n);
}


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
seed = 1335
obs = 6

# 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