简体   繁体   English

在 Rcpp 中使用 gsl_ran_multinomial 时出现问题

[英]Problem when using gsl_ran_multinomial in Rcpp

I'm trying to generate multinomial random variables as fast as possible.我正在尝试尽快生成多项式随机变量。 And I learned that gsl_ran_multinomial could be a good choice.我了解到gsl_ran_multinomial可能是一个不错的选择。 However, I tried to use it based on the answer in this post: https://stackoverflow.com/a/23100665/21039115 , and the results were always wrong.但是,我根据这篇帖子的回答尝试使用: https://stackoverflow.com/a/23100665/21039115 ,结果总是报错。

In detail, my code is详细来说,我的代码是

// [[Rcpp::export]]
arma::ivec rmvn_gsl(int K, arma::vec prob) {
    gsl_rng *s = gsl_rng_alloc(gsl_rng_mt19937); // Create RNG seed
    arma::ivec temp(K);
    gsl_ran_multinomial(s, K, 1, prob.begin(), (unsigned int *) temp.begin());
    gsl_rng_free(s); // Free memory
    return temp;
}

And the result was something like结果是这样的

rmvn_gsl(3, c(0.2, 0.7, 0.1))
     [,1]
[1,]    1
[2,]    0
[3,]    0

which is ridiculous.这太荒谬了。

I was wondering if there was any problem exist in the code... I couldn't find any other examples to compare.我想知道代码中是否存在任何问题......我找不到任何其他示例进行比较。 I appreciate any help!!!感谢您的帮助!!!

UPDATE:更新:

I found the primary problem here is that I didn't set a random seed, and it seems that gsl has its own default seed (FYI: https://stackoverflow.com/a/32939816/21039115 ).我发现这里的主要问题是我没有设置随机种子,而且gsl似乎有自己的默认种子(仅供参考: https://stackoverflow.com/a/32939816/21039115 )。 Once I set the seed by time, the code worked.一旦我按时间设置种子,代码就可以工作了。 But I will go with rmultinom since it can even be faster than gsl_ran_multinomial based on microbenchmark.但我会使用rmultinom ,因为它甚至可以比基于微基准测试的gsl_ran_multinomial更快。

Anyway, @Dirk Eddelbuettel provided a great example of implementing gsl_ran_multinomial below.无论如何,@Dirk Eddelbuettel 在下面提供了一个很好的实施gsl_ran_multinomial的例子。 Just pay attention to the random seeds issue if someone met the same problem as me.如果有人遇到和我一样的问题,请注意随机种子问题。

Here is a complete example taking a double vector of probabilities and returning an unsigned integer vector (at the compiled level) that is mapped to an integer vector by the time we are back in R:这是一个完整的示例,它采用概率的double精度向量并返回一个无符号的 integer 向量(在编译级别),当我们回到 R 时,该向量映射到 integer 向量:

Code代码

#include <RcppGSL.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

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

// [[Rcpp::export]]
std::vector<unsigned int> foo(int n, const std::vector <double> p) {
    int k = p.size();
    std::vector<unsigned int> nv(k);
    gsl_rng_env_setup();
    gsl_rng *s = gsl_rng_alloc(gsl_rng_mt19937); // Create RNG instance
    gsl_ran_multinomial(s, k, n, &(p[0]), &(nv[0]));
    gsl_rng_free(s);

    return nv;
}


/*** R
foo(400, c(0.1, 0.2, 0.3, 0.4))
*/

Output Output

> Rcpp::sourceCpp("~/git/stackoverflow/75165241/answer.cpp")

> foo(400, c(0.1, 0.2, 0.3, 0.4))
[1]  37  80 138 145
> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM