我有一个目前用R编写的Gibbs采样器,我正在尝试使用包Rcpp
和RcppGSL
加快速度。现在给我带来问题的是我似乎无法将随机变量生成器用于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采样器,一切似乎都有效。
答案 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参考手册中有所涉及......