MUQ  0.4.3
InfMALAProposal.cpp
Go to the documentation of this file.
2 
4 
6 
7 using namespace muq::SamplingAlgorithms;
8 using namespace muq::Modeling;
9 using namespace muq::Utilities;
10 
12 
13 InfMALAProposal::InfMALAProposal(boost::property_tree::ptree const& pt,
14  std::shared_ptr<AbstractSamplingProblem> prob) :
15  MCMCProposal(pt,prob),
16  stepSize(pt.get("StepSize",1.0))
17 {
18  rho = (4.0 - stepSize) / (4.0 + stepSize);
19 
20  unsigned int dim = prob->blockSizes(blockInd);
21 
22  const Eigen::VectorXd cov = Eigen::VectorXd::Ones(dim);
23  zDist = std::make_shared<Gaussian>(Eigen::VectorXd::Zero(dim), cov);
24 }
25 
26 
27 
28 InfMALAProposal::InfMALAProposal(boost::property_tree::ptree const& pt,
29  std::shared_ptr<AbstractSamplingProblem> prob,
30  std::shared_ptr<GaussianBase> zDistIn) :
31  MCMCProposal(pt,prob),
32  zDist(zDistIn),
33  stepSize(pt.get("StepSize",1.0))
34 {
35  rho = (4.0 - stepSize) / (4.0 + stepSize);
36 }
37 
38 std::shared_ptr<SamplingState> InfMALAProposal::Sample(std::shared_ptr<SamplingState> const& currentState)
39 {
40  assert(currentState->state.size()>blockInd);
41 
42  // the mean of the proposal is the current point
43  std::vector<Eigen::VectorXd> props = currentState->state;
44  assert(props.size()>blockInd);
45  Eigen::VectorXd const& uc = currentState->state.at(blockInd);
46 
47  // vector holding the covariance of the proposal times the gradient
48  Eigen::VectorXd sigmaGrad = GetSigmaGrad(currentState);
49 
50  props.at(blockInd) = rho*uc + sqrt(1 - rho*rho)*(0.5*sqrt(stepSize)*(uc + sigmaGrad) + zDist->Sample());
51 
52  // store the new state in the output
53  return std::make_shared<SamplingState>(props, 1.0);
54 }
55 
56 double InfMALAProposal::LogDensity(std::shared_ptr<SamplingState> const& currState,
57  std::shared_ptr<SamplingState> const& propState)
58 {
59  double const beta = sqrt(1 - rho*rho);
60  Eigen::VectorXd sigmaGrad = GetSigmaGrad(currState);
61  Eigen::VectorXd mean = rho*currState->state.at(blockInd) + beta*0.5*sqrt(stepSize)*(currState->state.at(blockInd) + sigmaGrad);
62  Eigen::VectorXd diff = (propState->state.at(blockInd) - mean)/beta;
63 
64  return zDist->LogDensity(diff);
65 
66 }
67 
68 Eigen::VectorXd InfMALAProposal::GetSigmaGrad(std::shared_ptr<SamplingState> const& state) const
69 {
70  std::stringstream blockId;
71  blockId << "_" << blockInd;
72 
73  if(!state->HasMeta("MALA_SigmaGrad" + blockId.str())){
74  Eigen::VectorXd grad; // vector holding the gradient of the log density
75 
76  if(!state->HasMeta("GradLogDensity" + blockId.str()))
77  state->meta["GradLogDensity" + blockId.str()] = prob->GradLogDensity(state, blockInd);
78 
79  grad = AnyCast( state->meta["GradLogDensity" + blockId.str()] );
80 
81  state->meta["MALA_SigmaGrad" + blockId.str()] = zDist->ApplyCovariance(grad).col(0).eval();
82  }
83 
84  Eigen::VectorXd sigmaGrad = AnyCast(state->meta["MALA_SigmaGrad" + blockId.str()]);
85  return sigmaGrad;
86 }
REGISTER_MCMC_PROPOSAL(InfMALAProposal) InfMALAProposal
An implement of the dimension-independent MALA (or Inf-MALA) proposal.
virtual double LogDensity(std::shared_ptr< SamplingState > const &currState, std::shared_ptr< SamplingState > const &propState) override
InfMALAProposal(boost::property_tree::ptree const &pt, std::shared_ptr< AbstractSamplingProblem > prob)
virtual std::shared_ptr< SamplingState > Sample(std::shared_ptr< SamplingState > const &currentState) override
std::shared_ptr< muq::Modeling::GaussianBase > zDist
Eigen::VectorXd GetSigmaGrad(std::shared_ptr< SamplingState > const &currentState) const
std::shared_ptr< AbstractSamplingProblem > prob
Definition: MCMCProposal.h:81
Class for easily casting boost::any's in assignment operations.
Definition: AnyHelpers.h:34
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.h:3956