// rareEvents() function callable from R via Rcpp -- which is essentially // the same as main() from SMCTC's examples/rare-events/main.cc extern "C" SEXP rareEvents(SEXP numberS, SEXP iteratesS, SEXP thresholdS, SEXP scheduleS) { long lNumber = Rcpp::as<long>(numberS); // Number of particles lIterates = Rcpp::as<long>(iteratesS); // Number of iterations dThreshold = Rcpp::as<double>(thresholdS); // Rare event threshold dSchedule = Rcpp::as<double>(scheduleS); // Annealing schedule constant try{ ///An array of move function pointers void (*pfMoves[])(long, smc::particle<mChain<double> > &,smc::rng*) = {fMove1, fMove2}; smc::moveset<mChain<double> > Moveset(fInitialiseMC, fSelect, sizeof(pfMoves) / sizeof(pfMoves[0]), pfMoves, fMCMC); smc::sampler<mChain<double> > Sampler(lNumber, SMC_HISTORY_RAM); Sampler.SetResampleParams(SMC_RESAMPLE_STRATIFIED,0.5); Sampler.SetMoveSet(Moveset); Sampler.Initialise(); Sampler.IterateUntil(lIterates); ///Estimate the normalising constant of the terminal distribution double zEstimate = Sampler.IntegratePathSampling(pIntegrandPS, pWidthPS, NULL) - log(2.0); ///Estimate the weighting factor for the terminal distribution double wEstimate = Sampler.Integrate(pIntegrandFS, NULL); // cout << zEstimate << " " << log(wEstimate) << " " << zEstimate + log(wEstimate) << endl; Rcpp::NumericVector res = Rcpp::NumericVector::create(Rcpp::Named("zEstimate") = zEstimate, Rcpp::Named("log(wEstimate)") = log(wEstimate), Rcpp::Named("sum") = zEstimate + log(wEstimate)); return res; } catch(smc::exception e) { Rcpp::Rcout << e; // not cerr, as R doesn't like to mix with i/o //exit(e.lCode); // we're just called from R so we should not exit } return R_NilValue; // to provide a return }
// [ref] ${SMCTC_HOME}/examples/rare-events/main.cc void rare_events_example() { // Number of Particles const long lNumber = 1000; // An array of move function pointers void (*pfMoves[])(long, smc::particle<mChain<double> > &, smc::rng *) = { simfunctions::fMove1, simfunctions::fMove2 }; smc::moveset<mChain<double> > Moveset(simfunctions::fInitialise, simfunctions::fSelect, sizeof(pfMoves) / sizeof(pfMoves[0]), pfMoves, simfunctions::fMCMC); smc::sampler<mChain<double> > Sampler(lNumber, SMC_HISTORY_RAM); Sampler.SetResampleParams(SMC_RESAMPLE_STRATIFIED, 0.5); Sampler.SetMoveSet(Moveset); Sampler.Initialise(); Sampler.IterateUntil(simfunctions::lIterates); // Estimate the normalising constant of the terminal distribution const double zEstimate = Sampler.IntegratePathSampling(simfunctions::pIntegrandPS, simfunctions::pWidthPS, NULL) - std::log(2.0); // Estimate the weighting factor for the terminal distribution const double wEstimate = Sampler.Integrate(simfunctions::pIntegrandFS, NULL); std::cout << zEstimate << " " << std::log(wEstimate) << " " << zEstimate + std::log(wEstimate) << endl; }