这是一个用于绘制N
个独立正态偏差的C ++函数,其均值为零且标准差为s
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
List rnorm_cpp(double s, int N){
arma::colvec epsilon = s * arma::randn(N);
return List::create(Named("e") = epsilon);
}
这是一个(几乎相同的)R版
rnormR <- function(s, N){
epsilon <- rnorm(N, mean = 0, sd = s)
return(list(e = epsilon))
}
在采购rnorm_cpp
和rnormR
之后,我运行了以下内容:
set.seed(1234)
fooR <- rnormR(s = 5, N = 10)
set.seed(1234)
barR <- rnormR(s = 5, N = 10)
set.seed(1234)
fooCpp <- rnorm_cpp(s = 5, N = 10)
set.seed(1234)
barCpp <- rnorm_cpp(s = 5, N = 10)
最后,我运行了identical
并获得了以下结果:
> identical(fooR, barR)
[1] TRUE
> identical(barR, fooCpp)
[1] FALSE
> identical(fooCpp, barCpp)
[1] FALSE
我希望所有这三个人都获得TRUE
。我该怎么做:(1)通过调用rnorm_cpp
复制随机抽取,(2)调用rnormR
和rnorm_cpp
的相同抽奖?
答案 0 :(得分:7)
功能arma::randn()
不连接到R RNG,因此调用set.seed()
已
没有影响。
我们在Rcpp中所做的是利用精细的R API,它允许我们从R和C ++访问相同的 RNG。通过小心RNGScope
个实例(自动插入),RG和C ++之间的RNG状态总是正确的。
但你根本不能假设任何其他第三方RNG(此处:Arma's)也自动对齐。此外,在这个特殊情况下,康拉德的犰狳文件很清楚:
要更改种子,请使用
std::srand()
功能
澄清(嗨,@ DWin)这里是完整的R和C ++示例:
R> set.seed(42); rnorm(5) ## Five N(0,1) draws in R
[1] 1.3710 -0.5647 0.3631 0.6329 0.4043
R> cppFunction('NumericVector foo(int n) { return rnorm(n); }')
R> set.seed(42); foo(5) ## Five N(0,1) draws from C++ fun.
[1] 1.3710 -0.5647 0.3631 0.6329 0.4043
R>
我们通过R和C ++获得相同的数字,因为我们a)相同地种子RNG和b)实际上调用R提供的相同RNG。