我正在研究a package,它使用RcppArmadillo中的随机数。该程序包运行MCMC算法,并且要获得精确的可重复性,用户应该能够设置随机数种子。这样做时,似乎arma::randg()函数可从gamma分布生成随机数,从而在各个平台上返回不同的值。 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(v0.2.1)创建于2019-02-22

这是我在运行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(v0.2.1)创建于2019-02-22

可以看出,用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(v0.2.1)创建于2019-02-22

但是,正如警告所表明的那样,结果表明,种子不是以这种方式设置的。

使用arma::randg()时是否可以在平台之间获得可重复的结果,还是需要使用RcppArmadillo中提供的其他一些随机数生成器来实现伽马分布?

更新资料

如注释中所指出,使用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(v0.2.1)创建于2019-02-22

这为我解决了。但是,我不确定该问题是否得到解决,因为这似乎是意外行为,因此请公开。

最佳答案

在评论中总结讨论:


对于伽玛分布,犰狳使用C ++ 11的std::gamma_distribution标头c.f中的randomhttps://gitlab.com/conradsnicta/armadillo-code/blob/9.300.x/include/armadillo_bits/arma_rng_cxx11.hpp#L165
在C ++中产生标准随机数分布的算法为implementation-defined
如果需要跨平台的可重现结果,最简单的解决方案是使用R中通过R::rgammaRcpp::rgamma实现的伽马分布。

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

10-12 18:00
查看更多