9 namespace pt = boost::property_tree;
16 MHKernel::MHKernel(pt::ptree
const& pt, std::shared_ptr<AbstractSamplingProblem> problem) :
TransitionKernel(pt, problem)
20 std::string proposalName = pt.get<std::string>(
"Proposal");
22 boost::property_tree::ptree subTree = pt.get_child(proposalName);
23 subTree.put(
"BlockIndex", blockInd);
26 proposal = MCMCProposal::Construct(subTree, problem);
30 MHKernel::MHKernel(pt::ptree
const& pt,
31 std::shared_ptr<AbstractSamplingProblem> problem,
33 proposal(proposalIn) {}
36 void MHKernel::PostStep(
unsigned int const t, std::vector<std::shared_ptr<SamplingState>>
const& state){
40 std::vector<std::shared_ptr<SamplingState>>
MHKernel::Step(
unsigned int const t, std::shared_ptr<SamplingState> prevState){
45 std::shared_ptr<SamplingState> prop =
proposal->Sample(prevState);
48 if(prevState->HasMeta(
"iteration"))
49 prop->meta[
"iteration"] = prevState->meta[
"iteration"];
50 prop->meta[
"IsProposal"] =
true;
56 if( prevState->HasMeta(
"LogTarget") && (prevState->HasMeta(
"QOI") ||
problem->numBlocksQOI == 0) && !
reeval ){
57 currentTarget =
AnyCast( prevState->meta[
"LogTarget"]);
59 currentTarget =
problem->LogDensity(prevState);
60 if (
problem->numBlocksQOI > 0) {
61 prevState->meta[
"QOI"] =
problem->QOI();
63 prevState->meta[
"LogTarget"] = currentTarget;
67 propTarget =
problem->LogDensity(prop);
69 }
catch(std::runtime_error &
e){
72 return std::vector<std::shared_ptr<SamplingState>>(1, prevState);
75 prop->meta[
"LogTarget"] = propTarget;
78 const double forwardPropDens =
proposal->LogDensity(prevState, prop);
79 const double backPropDens =
proposal->LogDensity(prop, prevState);
80 const double alpha = std::exp(propTarget - forwardPropDens - currentTarget + backPropDens);
84 if( RandomGenerator::GetUniform()<alpha ) {
85 if (
problem->numBlocksQOI > 0) {
86 prop->meta[
"QOI"] =
problem->QOI();
90 prop->meta[
"IsProposal"] =
false;
91 return std::vector<std::shared_ptr<SamplingState>>(1, prop);
93 return std::vector<std::shared_ptr<SamplingState>>(1, prevState);
99 std::stringstream out;
100 out << std::fixed << std::setw(3);
102 out <<
"MHKernel acceptance Rate = " << 100.0*double(
numAccepts)/double(
numCalls) <<
"%";
103 std::cout << prefix << out.str() << std::endl;
REGISTER_TRANSITION_KERNEL(MHKernel) MHKernel
An implementation of the standard Metropolis-Hastings transition kernel.
std::shared_ptr< MCMCProposal > proposal
virtual std::vector< std::shared_ptr< SamplingState > > Step(unsigned int const t, std::shared_ptr< SamplingState > prevState) override
Defines the transition kernel used by an MCMC algorithm.
std::shared_ptr< AbstractSamplingProblem > problem
The sampling problem that evaluates/samples the target distribution.
const bool reeval
true: reevaluate the log density (even if one already exists), false: use stored log density
virtual void PrintStatus() const
Class for easily casting boost::any's in assignment operations.