什么时候使用RNGScope有所作为?

时间:2015-02-12 20:55:30

标签: rcpp

在Rcpp文档中,我经常发现在使用Rcpp中的随机抽取之前放置Rcpp::RNGScope scope;的建议。我想知道这到底是做什么的,因为我只看到它被描述为" 确保RNG状态被设置/重置"。

然后,我测试了一下,但我似乎无法想出一个例子,这样做会有所不同。我使用了here中的一个例子。我的测试是:

#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);
}

然后

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

所以,我的问题是双重的。首先,RNGScope何时发挥作用,它与不使用它有什么不同?第二,有没有人有一个代码示例,无论是否有不同的结果?

如果RNGScope在较新的版本中被弃用,那么我很抱歉。

2 个答案:

答案 0 :(得分:6)

使用Rcpp属性时,代码的自动生成接口将自动插入RNGScope对象的相应构造 - 因此在这种情况下,它已在幕后为您完成。例如,如果您编写sourceCpp(..., verbose = TRUE),则会看到如下输出:

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
}

注意RNGScope对象的自动构造。

如果您在Rcpp属性范围之外操作,则只需手动构造该对象。

答案 1 :(得分:5)

一旦您阅读Writing R Extensions manual, Section 6.3, "Random Numbers"中的原始文档,这一切都会变得更加清晰。

所有RNGScope范围都是自动调用&#34; get&#34;和&#34;放&#34;为了保持RNG的健全状态。

凯文解释说,你的测试代码的问题在于已经为你发生了。因此,您只能通过手动执行.Call()进行测试,在这种情况下,肯定如果您使用将RNG弄得一团糟得到/妥善。