[Rcpp-devel] Segfault error during simulation in Rcpp
Dirk Eddelbuettel
edd at debian.org
Mon May 6 15:37:06 CEST 2013
Matteo,
This may reveal a subtle bug somewhere in the handling of temporary
expressions, with possible interactions with the garbage collection by R
itself.
That said, a trivial rewrite (below) which via a single sourceCpp() compiles
and runs, or re-runs it, has not lead to a single segfault here, and I even
increased N from 10^6 to 10^7.
The only other change I made was to move your params() matrix (you could have
used a named vector too; also why the log() with subsequent exp() ?) outside
the loop. It just works here...
Dirk
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix genRickerCpp(int days, int nSimul, int nBurn, NumericMatrix params) {
int nParams = params.ncol();
int totDays = nBurn + days;
bool multiParams = false;
if(nParams != 4) stop("Wrong number of parameters");
if(params.nrow() > 1) { multiParams = true; }
if(multiParams == true && params.nrow() != nSimul)
stop("Number of parameters vectors is different from the number of simulations");
double r = exp(params(0, 0));
double theta = exp(params(0, 1));
double sigma = exp(params(0, 2));
double phi = exp(params(0, 3));
NumericVector procNoise( rnorm( totDays * nSimul ) );
NumericVector initState( runif( nSimul ) );
NumericMatrix output( nSimul, days );
NumericVector::iterator noiseIter = procNoise.begin();
NumericVector::iterator initIter = initState.begin();
double currState;
for(int iRow = 0; iRow < nSimul; iRow++, initIter++) {
if( multiParams == true ) {
r = exp(params(iRow, 0));
theta = exp(params(iRow, 1));
sigma = exp(params(iRow, 2));
phi = exp(params(iRow, 3));
}
currState = *initIter;
for(int iCol = 1; iCol <= nBurn; iCol++, noiseIter++){
currState = r * currState * exp( - pow( currState, theta ) + *noiseIter * sigma );
}
output(iRow, 0) = rpois(1, phi * currState)[0];
for(int iCol = 1; iCol < days; iCol++, noiseIter++){
currState = r * currState * exp( - pow( currState, theta ) + *noiseIter * sigma );
output(iRow, iCol) = rpois(1, phi * currState)[0];
}
}
return output;
}
// #the function seems to work well, I tried to compare the output the an
// #equivalent R function
// #and I get the same results. The problem is that if I run it a lot of times:
// #library(Rcpp)
// #sourceCpp("~/Desktop/genRickerCpp.cpp")
/*** R
params <- matrix(log(c(r = exp(3.8), theta = 1, sigma = 0.3, phi = 10)), 1, 4)
for (ii in 1:10^7) {
data <- genRickerCpp(days = 1, nSimul = 1, nBurn = 1, params)
}
cat("Done\n")
*/
--
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
More information about the Rcpp-devel
mailing list