Beispiel #1
0
// 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;
}