R 在循环中调用 Rcpp 函数时崩溃 [英] R crashes when calling a Rcpp function in a loop

查看:81
本文介绍了R 在循环中调用 Rcpp 函数时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在 .cpp 文件中有这个 Rcpp 函数.您会看到它正在调用其他自定义函数,为了简单起见,我没有显示这些函数,但这些函数并没有显示出任何问题.

So I have this Rcpp function in a .cpp file. You'll see that it is calling other custom functions that I don't show for simplicity, but those don't show any problem whatsoever.

// [[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 无缝调用这个函数:

Then I can call this function from a .R seamlessly:

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 崩溃.

But, if I call it inside a for loop, no matter how small it is, R crashes without popping any apparent error. The chunk below would make R crash.

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)多次执行它,但我的速度足够快,但它也会崩溃.

I've also tried to execute it manually (Ctrl + Enter) many times as fast as I could, and I'm fast enough it also crashes.

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

I have tried smaller or bigger loops, both out and within the function. It also crashes if it's called from another Rcpp function. I know I shouldn't call Rcpp functions in a R loop. Eventually I intend to call it from another Rcpp function (to generate a matrix of data) but it crashes all the same.

我关注了我在谷歌搜索中发现的其他案例,并尝试了一些方法,例如更改为数组索引的 [] 括号(这个问题),使用 gc() 垃圾收集器(如此处建议).

I have followed other cases that I've found googling and tried a few things, as changing to [] brackets for the arrays' index (this question), playing with the gc() garbage collector (as suggested here).

我怀疑 NumericVector 定义发生了一些事情.但据我所知,它们的声明是正确的.

I suspected that something happened with the NumericVector definitions. But as far as I can tell they are declared properly.

评论中明确指出,这不是一个可重现的例子.我将在这里添加缺失的函数 Y()random_walk():

It is been fairly pointed out in the comments that this is not a reproducible exaxmple. I'll add down here the missing functions Y() and 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:添加了更多代码,因此可重现.

Added more code so it is reproducible.

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

I was assigning local variables when calling the functions. That was dumb from my part, but harmless. The same error still persists. But I've fixed that.

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

As it's been pointed out by Dirk in the comments, I was doing a pointless exercise redefining the rnorm(). Now it's removed and fixed.

推荐答案

答案已在评论中解决,作者 @coatless.我把它放在这里是为了给未来的读者留着.问题是 random_walk() 函数没有正确设置.

The answer has been solved in the comments, by @coatless. I put it here to keep it for future readers. The thing is that the random_walk() function wasn't properly set up correctly.

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

The problem was that the loop inside the function allowed i to go out of the defined dimension of the vector output. This is just inefficient when called once, yet it works. But it blows up when it's called many times real fast.

所以为了避免这个错误和许多其他错误,函数应该被定义为

So in order to avoid this error and many others, the function should have been defined as

// [[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;
}

这篇关于R 在循环中调用 Rcpp 函数时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆