RcppArmadillo Gamma 分布在具有相同种子的平台之间不同

标签 r rcpp armadillo rcpp11

我正在研究 a package ,它使用来自 RcppArmadillo 的随机数。该软件包运行 MCMC 算法,为了获得精确的再现性,用户应该能够设置随机数种子。执行此操作时,似乎用于从 Gamma 分布生成随机数的 arma::randg() 函数会跨平台返回不同的值。 arma::randu()arma::randn() 不是这种情况。这可能与 arma::randg() 需要 C++11 这一事实有关吗?

这是我在运行 R3.5.2 的 macOS 10.13.6 上得到的:

library(Rcpp)
library(RcppArmadillo)

sourceCpp(code = '
#include <RcppArmadillo.h>
using namespace Rcpp;

 // [[Rcpp::plugins(cpp11)]]
 // [[Rcpp::depends(RcppArmadillo)]]

 // [[Rcpp::export]]
 double random_gamma() {
 return arma::randg();
 }

 // [[Rcpp::export]]
 double random_uniform() {
 return arma::randu();
 }

 // [[Rcpp::export]]
 double random_normal() {
 return arma::randn();
 }
 '
)

replicate(2, {set.seed(1); random_gamma()})
#> [1] 1.507675 1.507675
replicate(2, {set.seed(432); random_gamma()})
#> [1] 0.02234341 0.02234341
replicate(2, {set.seed(1); random_uniform()})
#> [1] 0.2655087 0.2655087
replicate(2, {set.seed(1); random_normal()})
#> [1] -1.390378 -1.390378

reprex package 创建于 2019-02-22 (v0.2.1)

这是我在运行 R3.5.2 的 Windows 10 上得到的结果:

library(Rcpp)
library(RcppArmadillo)

sourceCpp(code = '
          #include <RcppArmadillo.h>
          using namespace Rcpp;

          // [[Rcpp::plugins(cpp11)]]
          // [[Rcpp::depends(RcppArmadillo)]]

          // [[Rcpp::export]]
          double random_gamma() {
          return arma::randg();
          }

          // [[Rcpp::export]]
          double random_uniform() {
          return arma::randu();
          }

          // [[Rcpp::export]]
          double random_normal() {
          return arma::randn();
          }
          '
)

replicate(2, {set.seed(1); random_gamma()})
#> [1] 0.2549381 0.2549381
replicate(2, {set.seed(432); random_gamma()})
#> [1] 0.2648896 0.2648896
replicate(2, {set.seed(1); random_uniform()})
#> [1] 0.2655087 0.2655087
replicate(2, {set.seed(1); random_normal()})
#> [1] -1.390378 -1.390378

reprex package 创建于 2019-02-22 (v0.2.1)

可以看出,arma::randg() 生成的随机数内部是一致的,但在平台之间有所不同。

我尝试使用 Armadillo 文档中的说明设置种子:

library(Rcpp)
library(RcppArmadillo)

sourceCpp(code = '
          #include <RcppArmadillo.h>
          using namespace Rcpp;

          // [[Rcpp::plugins(cpp11)]]
          // [[Rcpp::depends(RcppArmadillo)]]

          // [[Rcpp::export]]
          double random_gamma(int seed) {
          arma::arma_rng::set_seed(seed);
          return arma::randg();
          }
          '
)

replicate(4, random_gamma(1))
#> Warning in random_gamma(1): When called from R, the RNG seed has to be set
#> at the R level via set.seed()
#> [1] 1.3659195 0.6447221 1.1771862 0.9099034

reprex package 创建于 2019-02-22 (v0.2.1)

但是,如警告和结果所示,种子不会以这种方式设置。

在使用 arma::randg() 时,是否有办法在平台之间获得可重现的结果,或者我是否需要使用 RcppArmadillo 中提供的一些其他随机数生成器来实现 Gamma 分布?

更新

正如评论中所指出的,使用 R::rgamma() 解决了这个问题。以下代码在 Mac 和 Windows 上返回相同的数字:

library(Rcpp)

sourceCpp(code = '
          #include <Rcpp.h>
          using namespace Rcpp;

          // [[Rcpp::export]]
          double random_gamma() {
            return R::rgamma(1.0, 1.0);
          }
          '
)

replicate(2, {set.seed(1); random_gamma()})
#> [1] 0.1551414 0.1551414

reprex package 创建于 2019-02-22 (v0.2.1)

这为我解决了这个问题。但是,我不确定问题是否已解决,因为这似乎是意外行为,因此请保持打开状态。

最佳答案

总结评论中的讨论:

关于RcppArmadillo Gamma 分布在具有相同种子的平台之间不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54822702/

相关文章:

r - 将 boost 多精度与 RcppEigen 结合使用

c++ - 使用 Armadillo 库中的索引 vector 对矩阵进行索引

c++ - Armadillo 中 SpMat<Type> 的迭代器是否只访问非零条目?

r - 使用 purrr::map 在自定义函数中输入列表数据框中的列参数

r - drc::optim 'vmmin' 中的初始值不是有限的

c++ - Rcpp:从包含类的代码创建包

c++ - ld 找不到 x86_64 架构的 Rcpp 符号

rcpp - 了解 `Makevars` 以链接到 R 包中的外部 C 库

r - 将 nberDates() 更改为 R 中的时间序列以进行子集化

r - 来自assert_that() 的警告而不是错误?