0

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

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)

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)
}

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.

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.

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).

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

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: 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.

  • 1
    Do you know, that `length = time_left` etc. in your C++ function calls are assignments to local variables, not keyword arguments (which don't exist in C++)? –  Dec 09 '18 at 17:46
  • 3
    This isn't a reproducible example. Please include the `random_walk()` and `Y()` functions. – coatless Dec 09 '18 at 17:52
  • 2
    Also, you cannot specify parameter names to pass values into functions... e.g. replace `rw = random_walk(length = time_left, starting_point = 0);` with `rw = random_walk(time_left, 0);` – coatless Dec 09 '18 at 17:54
  • 1
    `random_walk()` isn't setup correctly. _C++_ indices start at 0. Not 1. This code is using: 1. an uninitialized value and 2. it is going out of bounds (e.g. `output[i+1]` allows for `i` to go up to `length` instead of `length-1`.) – coatless Dec 09 '18 at 18:15
  • 2
    Why do you think you need to reinvent an `N(0,1)`? Why do you think you should use a known poor RNG like `rand()` when R has better ones? Do you know about `rnorm()` and `set.seed()` ? Do you know Rcpp gives you access _in three different ways_ to R's RNGs? – Dirk Eddelbuettel Dec 10 '18 at 15:47

1 Answers1

0

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.

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