当我调用C代码时,R会冻结

时间:2013-04-09 10:31:42

标签: c r

我写了一个小C代码来做随机漫步大都会,我在R中调用它。当我运行它时,R冻结了。我不确定代码的哪一部分是不正确的。我遵循这个Peng and Leeuw tutorial(第6页)。作为免责声明:我没有太多的C经验,只有一些C ++的基础知识

#----C code --------
#include <R.h>
#include <Rmath.h>

void mcmc(int *niter, double *mean, double *sd, double *lo_bound, 
          double *hi_bound, double *normal)
{
    int i, j;
    double x, x1, h, p;
    x = runif(-5, 5);
    for(i=0; i < *niter; i++) {
        x1 = runif(*lo_bound, *hi_bound);
        while((x1 + x) > 5 || (x1 + x) < -5)
            x1 = runif(*lo_bound, *hi_bound);
        h = dnorm(x+x1, *mean, *sd, 0)/dnorm(x, *mean, *sd, 0);
        if(h >= 1)
            h = 1;
        p = runif(0, 1);
        if(p < h)
            x += x1;
        normal[i] = x;
    }
}


#-----R code ---------
foo_C<-function(mean, sd, lo_bound, hi_bound, niter)
{
    result <- .C("mcmc",  as.integer(niter), as.double(mean), as.double(sd), 
                 as.double(lo_bound), as.double(hi_bound), normal=double(niter))
    result[["normal"]]
}

编译后:

dyn.load("foo_C.so")
foo_C(0, 1, -0.5, 0.5, 100)

关注: while循环是问题所在。但问题的根源似乎与函数runif有关,函数{{1}}应该在下限和上限之间生成一个随机变量。但似乎函数实际上做的是随机选择上限值(5)或下限值(-5)。

1 个答案:

答案 0 :(得分:4)

在拨打R的随机数生成例程之前,您需要按照Writing R Extensions部分6.3 Random number generation中的说明操作并致电GetRNGstate();。您还需要在完成后致电PutRNGstate();

您的代码开始工作的原因可能是因为您在调用set.seed C函数之前在R会话中调用了mcmc

所以你的C代码应该是这样的:

#include <R.h>
#include <Rmath.h>

void mcmc(int *niter, double *mean, double *sd, double *lo_bound, 
          double *hi_bound, double *normal)
{
    int i;
    double x, x1, h, p;
    GetRNGstate();
    x = runif(-5.0, 5.0);
    for(i=0; i < *niter; i++) {
        x1 = runif(*lo_bound, *hi_bound);
        while((x1 + x) > 5.0 || (x1 + x) < -5.0) {
            x1 = runif(*lo_bound, *hi_bound);
            //R_CheckUserInterrupt();
        }
        h = dnorm(x+x1, *mean, *sd, 0)/dnorm(x, *mean, *sd, 0);
        if(h >= 1)
            h = 1;
        p = runif(0, 1);
        if(p < h)
            x += x1;
        normal[i] = x;
    }
    PutRNGstate();
}