Сбой R при вызове функции Rcpp в цикле - PullRequest
0 голосов
/ 09 декабря 2018

Итак, у меня есть эта функция Rcpp в файле .cpp.Вы увидите, что он вызывает другие пользовательские функции, которые я не показываю для простоты, но они не показывают никаких проблем.

// [[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.Я знаю, что не должен вызывать функции Rcpp в цикле R.В конце концов я намереваюсь вызвать его из другой функции Rcpp (чтобы сгенерировать матрицу данных), но все равно происходит сбой.

Я следил за другими случаями, которые я нашел, прибегая к помощи, и попробовал несколько вещей, как изменениена [] скобки для индекса массивов ( этот вопрос ), играя с сборщиком мусора gc() (, как предлагается здесь ).

Я подозревал, чточто-то случилось с определениями 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: я назначал локальные переменные, когдавызывая функции.Это было глупо с моей стороны, но безвредно.Та же ошибка все еще сохраняется.Но я исправил это.

Edit3: Как было отмечено Дирком в комментариях, я выполнял бессмысленное упражнение по переопределению rnorm().Теперь это снято и исправлено.

1 Ответ

0 голосов
/ 10 декабря 2018

Ответ был решен в комментариях @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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...