在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在较新的版本中被弃用,那么我很抱歉。
答案 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弄得一团糟得到/妥善。