When does using RNGScope matter?

In the Rcpp documentation, I often find a recommendation to host Rcpp::RNGScope scope; before using a random draw in rcpp. I wondered what exactly this is happening because I only ever saw it described as "ensuring that the RNG state gets set / reset".

Then I tested a bit, but it seems I can’t come up with an example where it matters. I used an example here . My tests:

 #include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] NumericVector noscope() { Rcpp::Function rt("rt"); return rt(5, 3); } // [[Rcpp::export]] NumericVector withscope() { RNGScope scope; Rcpp::Function rt("rt"); return rt(5, 3); } 

and then

 set.seed(45) noscope() # [1] 0.6438 -0.6082 -1.9710 -0.1402 -0.6482 set.seed(45) withscope() # [1] 0.6438 -0.6082 -1.9710 -0.1402 -0.6482 set.seed(45) rt(5, 3) # [1] 0.6438 -0.6082 -1.9710 -0.1402 -0.6482 

So my question is twofold. First, when does RNGScope make a difference, and what exactly is it different from not using it? Secondly, does anyone have an example of code that shows different results with and without it?

If RNGScope is deprecated in a newer version, I wish I asked.

+5
source share
2 answers

When using the Rcpp attributes, an automatically generated interface to your code automatically inserts the corresponding RNGScope object RNGScope , so it is already being executed for you behind the scenes in this case. For example, if you write sourceCpp(..., verbose = TRUE) , you will see the output as follows:

 Generated extern "C" functions -------------------------------------------------------- #include <Rcpp.h> RcppExport SEXP sourceCpp_38808_timesTwo(SEXP xSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); __result = Rcpp::wrap(timesTwo(x)); return __result; END_RCPP } 

Note the automatic construction of the RNGScope object.

You only need to create this object manually if you are working outside of the Rcpp attributes.

+6
source

All this becomes a little clearer after you read the original documentation in the R Extension Writing Guide, Section 6.3, “Random Numbers” .

All that the RNGScope scope RNGScope is automatically call "get" and "put" to maintain the RNG health state.

The problem with your test code, as Kevin explained, is that this is already happening for you. This way you can test by going through .Call() manually, in which case you will definitely leave the RNG in a mess if you use it, and don’t get / put it correctly.

+5
source

Source: https://habr.com/ru/post/1213272/


All Articles