什么时候使用 RNGScope 会有所作为?
When does using RNGScope make a difference?
在 Rcpp 文档中,我经常发现在 Rcpp 中使用随机抽取之前放置 Rcpp::RNGScope scope;
的建议。我想知道这到底是做什么的,因为我只见过它被描述为“确保 RNG 状态得到 set/reset”。
然后,我进行了一些测试,但我似乎无法想出这样做有什么不同的例子。我使用了 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 在较新的版本中被弃用,那么我很抱歉提出这个问题。
当使用 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 属性范围之外操作,则只需要手动构造该对象。
一旦您阅读 Writing R Extensions manual, Section 6.3, "Random Numbers" 中的 原始 文档,这一切就会变得更加清晰。
RNGScope
scope 所做的只是 automagic 调用 "get" 和 "put" 以保持 RNG 的状态.
正如 Kevin 所解释的那样,您的测试代码存在的问题是 您已经遇到了。所以你只能通过手动 .Call()
来测试,在这种情况下你 肯定会 如果你使用它 并且做不 get/put 正确。
在 Rcpp 文档中,我经常发现在 Rcpp 中使用随机抽取之前放置 Rcpp::RNGScope scope;
的建议。我想知道这到底是做什么的,因为我只见过它被描述为“确保 RNG 状态得到 set/reset”。
然后,我进行了一些测试,但我似乎无法想出这样做有什么不同的例子。我使用了 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 在较新的版本中被弃用,那么我很抱歉提出这个问题。
当使用 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 属性范围之外操作,则只需要手动构造该对象。
一旦您阅读 Writing R Extensions manual, Section 6.3, "Random Numbers" 中的 原始 文档,这一切就会变得更加清晰。
RNGScope
scope 所做的只是 automagic 调用 "get" 和 "put" 以保持 RNG 的状态.
正如 Kevin 所解释的那样,您的测试代码存在的问题是 您已经遇到了。所以你只能通过手动 .Call()
来测试,在这种情况下你 肯定会 如果你使用它 并且做不 get/put 正确。