[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