这是一个C++函数,用于绘制N具有平均零和标准偏差的独立法向偏差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);
}
Run Code Online (Sandbox Code Playgroud)
这是一个(几乎相同的)R版本
rnormR <- function(s, N){
epsilon <- rnorm(N, mean = 0, sd = s)
return(list(e = epsilon))
}
Run Code Online (Sandbox Code Playgroud)
采购后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)
Run Code Online (Sandbox Code Playgroud)
最后,我跑了identical,得到了以下结果:
> identical(fooR, barR)
[1] TRUE
> identical(barR, fooCpp)
[1] FALSE
> identical(fooCpp, barCpp)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
我期待得到TRUE所有这三个.我怎样才能:(1)通过调用复制随机抽取rnorm_cpp和(2)获取相同的抽奖来调用rnormR和rnorm_cpp?
该功能arma::randn()是未连接到R的RNG,所以主叫set.seed()上有没有影响.
我们在Rcpp中所做的是利用精细的R API,它允许我们从R和C++ 访问相同的 RNG.通过小心RNGScope实例(自动插入),RG和C++之间的RNG状态总是正确的.
但你根本不能假设任何其他第三方RNG(这里是:Arma)也是自动对齐的.此外,在这个特殊情况下,康拉德的犰狳文件很清楚:
要更改种子,请使用该
std::srand()功能
澄清(Hi,@ 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>
Run Code Online (Sandbox Code Playgroud)
我们通过R和C++获得相同的数字,因为我们a)相同地种子RNG和b)实际上调用由R提供的相同RNG.