R 从CUDA中的各种分布生成随机数

R 从CUDA中的各种分布生成随机数,r,cuda,statistics,R,Cuda,Statistics,我正在GPU上玩MCMC,需要为CUDA编写的各种采样器实现 我在StackOverflow上看到的大多数帖子都与统一、二项和正常采样有关。是否有任何库允许我使用r中的d-p-q-r函数的简单性和多样性(参见第页) 我希望能够从伽马分布、正态分布、二项式分布和贝叶斯问题中使用的逆分布(逆卡方分布、逆伽马分布)中取样,并且不希望必须使用逆概率变换和接受-拒绝取样来编写我自己的样本。对于伽马分布,这是我目前使用的。 这是GSL功能修改为与CuRAND一起使用 __device__ double ra

我正在GPU上玩MCMC,需要为CUDA编写的各种采样器实现

我在StackOverflow上看到的大多数帖子都与统一、二项和正常采样有关。是否有任何库允许我使用r中的d-p-q-r函数的简单性和多样性(参见第页)


我希望能够从伽马分布、正态分布、二项式分布和贝叶斯问题中使用的逆分布(逆卡方分布、逆伽马分布)中取样,并且不希望必须使用逆概率变换和接受-拒绝取样来编写我自己的样本。

对于伽马分布,这是我目前使用的。 这是GSL功能修改为与CuRAND一起使用

__device__ double ran_gamma (curandState localState, const double a, const double b){
/* assume a > 0 */

if (a < 1){
    double u = curand_uniform_double(&localState);
    return ran_gamma (localState, 1.0 + a, b) * pow (u, 1.0 / a);
}

{
    double x, v, u;
    double d = a - 1.0 / 3.0;
    double c = (1.0 / 3.0) / sqrt (d);

    while (1){
        do{
            x = curand_normal_double(&localState);
            v = 1.0 + c * x;
        } while (v <= 0);

        v = v * v * v;
        u = curand_uniform_double(&localState);

        if (u < 1 - 0.0331 * x * x * x * x) 
            break;

        if (log (u) < 0.5 * x * x + d * (1 - v + log (v)))
            break;
    }
    return b * d * v;
}
}
\uuuuuuu设备\uuuuuuuuuuuuu双运行\ugamma(curandState localState,常数双a,常数双b){
/*假设a>0*/
if(a<1){
double u=curand\u uniform\u double(&localState);
返回随机伽马(本地状态,1.0+a,b)*功率(u,1.0/a);
}
{
双x,v,u;
双d=a-1.0/3.0;
双c=(1.0/3.0)/sqrt(d);
而(1){
做{
x=curand\u normal\u double(&localState);
v=1.0+c*x;

}(v对于伽马分布,这是我目前使用的。 这是GSL功能修改为与CuRAND一起使用

__device__ double ran_gamma (curandState localState, const double a, const double b){
/* assume a > 0 */

if (a < 1){
    double u = curand_uniform_double(&localState);
    return ran_gamma (localState, 1.0 + a, b) * pow (u, 1.0 / a);
}

{
    double x, v, u;
    double d = a - 1.0 / 3.0;
    double c = (1.0 / 3.0) / sqrt (d);

    while (1){
        do{
            x = curand_normal_double(&localState);
            v = 1.0 + c * x;
        } while (v <= 0);

        v = v * v * v;
        u = curand_uniform_double(&localState);

        if (u < 1 - 0.0331 * x * x * x * x) 
            break;

        if (log (u) < 0.5 * x * x + d * (1 - v + log (v)))
            break;
    }
    return b * d * v;
}
}
\uuuuuuu设备\uuuuuuuuuuuuu双运行\ugamma(curandState localState,常数双a,常数双b){
/*假设a>0*/
if(a<1){
double u=curand\u uniform\u double(&localState);
返回随机伽马(本地状态,1.0+a,b)*功率(u,1.0/a);
}
{
双x,v,u;
双d=a-1.0/3.0;
双c=(1.0/3.0)/sqrt(d);
而(1){
做{
x=curand\u normal\u double(&localState);
v=1.0+c*x;

}while(v AFAIK,没有这样的库。或者支持通常的发行版,但是您可能需要为外来的内核制作自己的内核。如果您找不到任何库来实现,这可能不会太难,甚至可以集成到这些其他库中(特别是可以在Github上轻松分叉的推力库).AFAIK,没有这样的库。或者支持通常的发行版,但是您可能需要为外来的内核制作自己的内核。如果您找不到任何库,这可能不会太难实现,甚至可以集成到这些其他库中(特别是可以在Github上轻松分叉的推力库)。