3 #include <Eigen/Eigenvalues>
6 #include <cereal/types/tuple.hpp>
12 namespace pt = boost::property_tree;
21 typedef std::tuple<unsigned int, std::shared_ptr<SamplingState>,
bool> CurrentState;
25 inline ProposeState() {}
28 virtual ~ProposeState() =
default;
45 GMHKernel::GMHKernel(pt::ptree
const& pt, std::shared_ptr<AbstractSamplingProblem> problem) :
MHKernel(pt, problem),
46 N(pt.
get<unsigned int>(
"NumProposals")),
48 M(pt.
get<unsigned int>(
"NumAccepted", N)) {}
50 GMHKernel::GMHKernel(pt::ptree
const& pt, std::shared_ptr<AbstractSamplingProblem> problem, std::shared_ptr<MCMCProposal> proposalIn) :
52 N(pt.
get<unsigned int>(
"NumProposals")),
54 M(pt.
get<unsigned int>(
"NumAccepted", N)) {}
56 GMHKernel::~GMHKernel() {}
61 if(! state->HasMeta(
"LogTarget"))
62 state->meta[
"LogTarget"] =
problem->LogDensity(state);
70 (*it)->meta[
"LogTarget"] =
problem->LogDensity(*it);
74 Eigen::VectorXd R = Eigen::VectorXd::Zero(
Np1);
75 for(
unsigned int i=0; i<
Np1; ++i )
89 auto helper = std::make_shared<ProposeState>();
94 if(
comm->GetRank()==0 ) {
143 for(
unsigned int i=0; i<
Np1; ++i ) {
156 Eigen::MatrixXd A = Eigen::MatrixXd::Ones(
Np1,
Np1);
157 for(
unsigned int i=0; i<
Np1; ++i ) {
158 for(
unsigned int j=0; j<
Np1; ++j ) {
159 if( j==i ) {
continue; }
160 A(i,j) = std::fmin(1.0, std::exp(R(j)-R(i)))/(double)(
Np1);
173 Eigen::MatrixXd mat(
Np1+1,
Np1);
174 mat.block(0,0,
Np1,
Np1) = A.transpose()-Eigen::MatrixXd::Identity(
Np1,
Np1);
175 mat.row(
Np1) = Eigen::RowVectorXd::Ones(
Np1);
177 Eigen::VectorXd rhs = Eigen::VectorXd::Zero(
Np1+1);
187 if(
comm->GetRank()==0 ) { assert(state); }
198 std::vector<std::shared_ptr<SamplingState> > newStates(
M,
nullptr);
202 assert(indices.size()==
M);
205 for(
unsigned int i=0; i<
M; ++i ) { newStates[i] =
proposedStates[indices[i]]; }
210 std::vector<std::shared_ptr<SamplingState> >
GMHKernel::Step(
unsigned int const t, std::shared_ptr<SamplingState> state) {
214 return comm->GetRank()==0 ?
SampleStationary() : std::vector<std::shared_ptr<SamplingState> >(
M,
nullptr);
REGISTER_TRANSITION_KERNEL(DRKernel) DRKernel
A kernel for the generalized Metropolis-Hastings kernel.
void SerialProposal(unsigned int const t, std::shared_ptr< SamplingState > state)
Propose points in serial and evaluate the log target.
Eigen::MatrixXd AcceptanceMatrix(Eigen::VectorXd const &R) const
const unsigned int Np1
Number of proposals plus one.
void ParallelProposal(unsigned int const t, std::shared_ptr< SamplingState > state)
Propose points in parallel and evaluate the log target.
Eigen::VectorXd stationaryAcceptance
The cumulative stationary accepatnce probability.
std::shared_ptr< parcer::Communicator > GetCommunicator() const
std::vector< std::shared_ptr< SamplingState > > SampleStationary() const
Sample the stationary distribution.
Eigen::VectorXd StationaryAcceptance() const
Get the cumulative stationary acceptance probability.
void ComputeStationaryAcceptance(Eigen::VectorXd const &R)
Compute the cumulative acceptance density.
virtual std::vector< std::shared_ptr< SamplingState > > Step(unsigned int const t, std::shared_ptr< SamplingState > state) override
std::vector< std::shared_ptr< SamplingState > > proposedStates
Proposed states.
void AcceptanceDensity(Eigen::VectorXd &R)
Compute the stationary transition density.
virtual void PreStep(unsigned int const t, std::shared_ptr< SamplingState > state) override
const unsigned int M
Number of accepted points (number of points added to the chain)
An implementation of the standard Metropolis-Hastings transition kernel.
std::shared_ptr< MCMCProposal > proposal
std::shared_ptr< parcer::Communicator > comm
std::shared_ptr< AbstractSamplingProblem > problem
The sampling problem that evaluates/samples the target distribution.
Class for easily casting boost::any's in assignment operations.
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())