首页 文章

在循环中调用Rcpp函数时R崩溃

提问于
浏览
0

所以我在 .cpp 文件中有这个Rcpp函数 . 为简单起见,您显示了这些内容,但这些内容并未显示任何问题 .

// [[Rcpp::export]]
int sim_probability(float present_wealth , int time_left, int n, float mu, float sigma, float r, float gamma, float gu, float gl){
    int i;
    int count = 0;
    float final_wealth;
    NumericVector y(time_left);
    NumericVector rw(time_left);
    for(i=0;i<n;i++){
        rw = random_walk(time_left, 0);
        y = Y(rw, mu, sigma, r, gamma);
        final_wealth = y[time_left-1] - y[0] + present_wealth;
        if(final_wealth <= gu && final_wealth >= gl){
            count = count + 1;
        }
    }
    return count;
}

然后我可以无缝地从 .R 调用此函数:

library(Rcpp)
sourceCpp("functions.cpp")
sim_probability(present_wealth = 100, time_left = 10, n = 1e3, mu = 0.05, sigma = 0.20, r = 0, gamma = 2, gu = 200, gl = 90)

但是,如果我在一个 for 循环中调用它,无论它有多小,R都会崩溃而不会出现明显的错误 . 下面的块会让R崩溃 .

for(l in 1:1){
    sim_probability(present_wealth = 100, time_left = 10, n = 1e3, mu = 0.05, sigma = 0.20, r = 0, gamma = 2, gu = 200, gl = 90)
}

我也尝试过尽可能快地手动执行它(Ctrl Enter),并且我足够快它也崩溃了 .

我已尝试过更小或更大的循环,无论是在函数内还是函数内 . 如果从另一个Rcpp函数调用它也会崩溃 . 我知道我不应该在R循环中调用Rcpp函数 . 最终我打算从另一个Rcpp函数(生成数据矩阵)调用它,但它崩溃了所有相同 .

我已经跟踪了其他一些我发现谷歌搜索并尝试了一些事情的情况,如更改为数组索引(this question)的 [] 括号,使用 gc() 垃圾收集器(as suggested here) .

我怀疑 NumericVector 定义发生了什么 . 但据我所知,他们被宣布正确 .

在评论中已经相当指出,这不是一个可重复的例子 . 我将在这里添加缺少的函数 Y()random_walk()

// [[Rcpp::export]]
NumericVector Y(NumericVector path, float mu, float sigma, float r, float gamma){
    int time_step, n, i;
    time_step = 1;
    float theta, y0, prev, inc_W;
    theta = (mu - r) / sigma;
    y0 = theta / (sigma*gamma);

    n = path.size();
    NumericVector output(n);

    for(i=0;i<n;i++){
        if(i == 0){
            prev = y0;
            inc_W = path[0];
        }else{
            prev = output[i-1];
            inc_W = path[i] - path[i-1];
        }
        output[i] = prev + (theta / gamma) * (theta * time_step + inc_W);
    }
    return output;
}

// [[Rcpp::export]]
NumericVector random_walk(int length, float starting_point){
    if(length == 1){return starting_point;}
    NumericVector output(length);
    output[1] = starting_point;
    int i;
    for(i=0; i<length; i++){output[i+1] = output[i] + R::rnorm(0,1);}
    return output;
}

Edit1:添加了更多代码,因此它是可重现的 .

Edit2:我在调用函数时分配了局部变量 . 这对我来说是愚蠢的,但无害 . 同样的错误仍然存在 . 但我已经解决了这个问题 .

编辑3:正如Dirk在评论中指出的那样,我正在做一个无意义的练习,重新定义 rnorm() . 现在它已被删除并修复 .

1 回答

  • 0

    答案已在@coatless的评论中得到解决 . 我把它放在这里,以备将来的读者使用 . 问题是 random_walk() 函数没有正确设置 .

    问题是函数内部的循环允许 i 超出向量 output 的定义维度 . 当调用一次时这只是效率低下,但它有效 . 但是当它被称为真正快速多次时它会爆炸 .

    因此,为了避免此错误和许多其他错误,该函数应该被定义为

    // [[Rcpp::export]]
    NumericVector random_walk(int length, float starting_point){
        if(length == 0){return starting_point;}
        NumericVector output(length);
        output[0] = starting_point;
        int i;
        for(i=0; i<length-1; i++){output[i+1] = output[i] + R::rnorm(0,1);}
        return output;
    }
    

相关问题