使用RcppGSL进行Dirichlet分布

时间:2015-10-29 17:29:52

标签: c++ r rcpp gsl

我有一个目前用R编写的Gibbs采样器,我正在尝试使用包RcppRcppGSL加快速度。现在给我带来问题的是我似乎无法将随机变量生成器用于dirichlet分布。这是一个在我的计算机上不起作用的简短脚本:

#include <Rcpp.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_blas.h>

#include <RcppGSL.h>

using namespace Rcpp;

// [[Rcpp::depends(RcppGSL)]]
// [[Rcpp::export]]

NumericVector rdirichlet_cpp(NumericVector alpha) {
  int n = alpha.size();
  NumericVector results(n);

  // Allocate random number generator
  gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937);

  gsl_ran_dirichlet(r, n, alpha, results);

  // Release random number generator
  gsl_rng_free(r);

  return(results);
}

当我尝试使用sourceCpp()来源时,我收到一条错误消息,说有no matching function for call to 'gsl_ran_dirichlet'。我几乎没有使用C / C ++的经验,所以我可能犯了一个愚蠢的错误(我还不太确定Rcpp如何管理内存)。但也许问题实际上是RcppGSL包,它以某种方式链接到不包含Dirichlet随机变量生成器的旧版GSL ......

为了它的价值,我最近也在Python中使用GSL RNG(在同一台计算机上)实现了相同的Gibbs采样器,一切似乎都有效。

1 个答案:

答案 0 :(得分:2)

您报告的错误与我看到的错误不同:

gsldiri.cpp: In function ‘Rcpp::NumericVector rdirichlet_cpp(Rcpp::NumericVector)’:
gsldiri.cpp:20:41: error: cannot convert ‘Rcpp::NumericVector {aka Rcpp::Vector<14, Rcpp::PreserveStorage>}’ to ‘const double*’ for argument ‘3’ to ‘void gsl_ran_dirichlet(const gsl_rng*, size_t, const double*, double*)’
   gsl_ran_dirichlet(r, n, alpha, results);
                                         ^
make: *** [gsldiri.o] Error 1

并且这个很有意义:你有点随机地将Rcpp::NumericVector()作为第三个参数插入到一个对Rcpp一无所知的GSL函数中。那不行。

更仔细地重新阅读RcppGSL文档和示例。这是可以修复的,但需要采用不同的方法。

编辑:即使按照GSL标准,界面也有些奇怪。但是通过用

替换引起错误的行,你会得到一个有点干净的解决方案
gsl_ran_dirichlet(r, n, alpha.begin(), results.begin());

之后它会构建并运行---你仍然需要在RNG引擎上播种。但这在GSL参考手册中有所涉及......