MUQ  0.4.3
SMMALAProposal.cpp
Go to the documentation of this file.
2 
4 
6 
7 namespace pt = boost::property_tree;
8 using namespace muq::Modeling;
9 using namespace muq::SamplingAlgorithms;
10 using namespace muq::Utilities;
11 
12 
13 
14 
15 SMMALAProposal::SMMALAProposal(pt::ptree pt,
16  std::shared_ptr<AbstractSamplingProblem> const& probIn,
17  std::shared_ptr<muq::Modeling::ModPiece> const& forwardModIn,
18  std::shared_ptr<muq::Modeling::Gaussian> const& priorIn,
19  std::shared_ptr<muq::Modeling::Gaussian> const& likelihoodIn) :
20  MCMCProposal(pt,probIn),
21  prior(priorIn), likelihood(likelihoodIn), model(forwardModIn), meanScaling(pt.get("MeanScaling",0.5))
22 {
23  stepSize = pt.get("StepSize", 1.0);
24  assert(stepSize>0);
25 
26  assert(meanScaling>0);
27 }
28 
29 std::shared_ptr<SamplingState> SMMALAProposal::Sample(std::shared_ptr<SamplingState> const& currentState) {
30  assert(currentState->state.size()>blockInd);
31 
32  // the mean of the proposal is the current point
33  std::vector<Eigen::VectorXd> props = currentState->state;
34  assert(props.size()>blockInd);
35  Eigen::VectorXd const& xc = currentState->state.at(blockInd);
36 
37  // Get the gradient from the previous step
38  //Eigen::VectorXd sigmaGrad; // vector holding the covariance of the proposal times the gradient
39 
40  std::stringstream blockId;
41  blockId << "_" << blockInd;
42 
43  Eigen::MatrixXd hess;
44  Eigen::VectorXd grad;
45  if(!currentState->HasMeta("SMMALA_Hess" + blockId.str())){
46 
47  Eigen::MatrixXd jac = model->Jacobian(0,blockInd, currentState->state);
48  hess = prior->GetPrecision() + jac.transpose() * likelihood->ApplyPrecision(jac);
49 
50  currentState->meta["SMMALA_Hess" + blockId.str()] = hess;
51  }else{
52  hess = AnyCast( currentState->meta["SMMALA_Hess" + blockId.str()] );
53  }
54 
55  if(!currentState->HasMeta("SMMALA_Grad" + blockId.str())){
56  grad = prob->GradLogDensity(currentState, blockInd);
57  currentState->meta["SMMALA_Grad" + blockId.str()] = grad;
58  }else{
59  grad = AnyCast( currentState->meta["SMMALA_Grad" + blockId.str()] );
60  }
61 
62  hess /= stepSize*stepSize;
63  Gaussian prop(Eigen::VectorXd::Zero(xc.size()).eval(), hess, Gaussian::Mode::Precision);
64 
65  // Draw a sample
66  props.at(blockInd) = xc + meanScaling*prop.ApplyCovariance(grad) + prop.Sample();
67 
68  // store the new state in the output
69  return std::make_shared<SamplingState>(props, 1.0);
70 }
71 
72 double SMMALAProposal::LogDensity(std::shared_ptr<SamplingState> const& currState,
73  std::shared_ptr<SamplingState> const& propState) {
74 
75  std::stringstream blockId;
76  blockId << "_" << blockInd;
77 
78  Eigen::MatrixXd hess;
79  Eigen::VectorXd grad;
80  if(!currState->HasMeta("SMMALA_Hess" + blockId.str())){
81 
82  Eigen::MatrixXd jac = model->Jacobian(0,blockInd, currState->state);
83  hess = prior->GetPrecision() + jac.transpose() * likelihood->ApplyPrecision(jac);
84 
85  currState->meta["SMMALA_Hess" + blockId.str()] = hess;
86  }else{
87  hess = AnyCast( currState->meta["SMMALA_Hess" + blockId.str()] );
88  }
89 
90  if(!currState->HasMeta("SMMALA_Grad" + blockId.str())){
91  grad = prob->GradLogDensity(currState, blockInd);
92  currState->meta["SMMALA_Grad" + blockId.str()] = grad;
93  }else{
94  grad = AnyCast( currState->meta["SMMALA_Grad" + blockId.str()] );
95  }
96 
97  hess /= stepSize*stepSize;
98  Gaussian prop(Eigen::VectorXd::Zero( propState->state.at(blockInd).size()).eval(), hess, Gaussian::Mode::Precision);
99 
100  // Draw a sample
101  Eigen::VectorXd delta = propState->state.at(blockInd) - currState->state.at(blockInd) - meanScaling*prop.ApplyCovariance(grad);
102 
103  return prop.LogDensity(delta);
104 }
virtual double LogDensity(ref_vector< Eigen::VectorXd > const &inputs)
Evaluate the log-density.
Eigen::VectorXd Sample(ref_vector< Eigen::VectorXd > const &inputs)
Sample the distribution.
virtual Eigen::MatrixXd ApplyCovariance(Eigen::Ref< const Eigen::MatrixXd > const &x) const override
Definition: Gaussian.cpp:248
std::shared_ptr< AbstractSamplingProblem > prob
Definition: MCMCProposal.h:81
virtual std::shared_ptr< SamplingState > Sample(std::shared_ptr< SamplingState > const &currentState) override
std::shared_ptr< muq::Modeling::Gaussian > likelihood
std::shared_ptr< muq::Modeling::Gaussian > prior
The proposal distribution.
std::shared_ptr< muq::Modeling::ModPiece > model
virtual double LogDensity(std::shared_ptr< SamplingState > const &currState, std::shared_ptr< SamplingState > const &propState) override
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