如何在RcppArmadillo中复制随机抽奖?

时间:2013-10-01 00:22:14

标签: r rcpp

这是一个用于绘制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_cpprnormR之后,我运行了以下内容:

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)调用rnormRrnorm_cpp的相同抽奖?

1 个答案:

答案 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。