MUQ  0.4.3
MultilevelMCMC_AdvancedInterface.cpp
Go to the documentation of this file.
1 /***
2 ## Overview
3 This example shows how to use the low-level API to MUQ's Multilevel MCMC algorithms. The actual sampling
4 problem is quite simple: we want to draw samples from a multivariate Gaussian distribution with
5 mean
6 \f[
7  \mu = \left[ \begin{array}{c} 1\\ 2\end{array}\right]
8 \f]
9 and covariance
10 \f[
11 \Sigma = \left[\begin{array}{cc} 0.7& 0.6\\ 0.6 & 1.0\end{array}\right].
12 \f]
13 It's of course possible to sample this distribution directly, but we will use Multilevel MCMC methods in
14 this example to illustrate their use without introducing unnecessary complexity to the problem definition.
15 
16 */
17 
21 
24 
30 
32 
34 
36 
37 #include <boost/property_tree/ptree.hpp>
38 #include <sstream>
39 
40 namespace pt = boost::property_tree;
41 using namespace muq::Modeling;
42 using namespace muq::SamplingAlgorithms;
43 using namespace muq::Utilities;
44 
45 
46 
47 class MySamplingProblem : public AbstractSamplingProblem {
48 public:
49  MySamplingProblem(std::shared_ptr<muq::Modeling::ModPiece> targetIn)
50  : AbstractSamplingProblem(Eigen::VectorXi::Constant(1,2), Eigen::VectorXi::Constant(1,2)),
51  target(targetIn){}
52 
53  virtual ~MySamplingProblem() = default;
54 
55 
56  virtual double LogDensity(std::shared_ptr<SamplingState> const& state) override {
57  lastState = state;
58  return target->Evaluate(state->state).at(0)(0);
59  };
60 
61  virtual std::shared_ptr<SamplingState> QOI() override {
62  assert (lastState != nullptr);
63  return std::make_shared<SamplingState>(lastState->state, 1.0);
64  }
65 
66 private:
67  std::shared_ptr<SamplingState> lastState = nullptr;
68 
69  std::shared_ptr<muq::Modeling::ModPiece> target;
70 
71 };
72 
73 
74 class MyInterpolation : public MIInterpolation {
75 public:
76  std::shared_ptr<SamplingState> Interpolate (std::shared_ptr<SamplingState> const& coarseProposal,
77  std::shared_ptr<SamplingState> const& fineProposal) {
78  return std::make_shared<SamplingState>(coarseProposal->state);
79  }
80 };
81 
82 
84 public:
85  MyMIComponentFactory (Eigen::VectorXd const& start, pt::ptree pt)
86  : startingPoint(start), pt(pt)
87  { }
88 
89  virtual std::shared_ptr<MCMCProposal> Proposal (std::shared_ptr<MultiIndex> const& index, std::shared_ptr<AbstractSamplingProblem> const& samplingProblem) override {
90  pt::ptree pt;
91  pt.put("BlockIndex",0);
92 
93  Eigen::VectorXd mu(2);
94  mu << 1.0, 2.0;
95  Eigen::MatrixXd cov(2,2);
96  cov << 0.7, 0.6,
97  0.6, 1.0;
98  cov *= 20.0;
99 
100  auto prior = std::make_shared<Gaussian>(mu, cov);
101 
102  return std::make_shared<CrankNicolsonProposal>(pt, samplingProblem, prior);
103  }
104 
105  virtual std::shared_ptr<MultiIndex> FinestIndex() override {
106  auto index = std::make_shared<MultiIndex>(1);
107  index->SetValue(0, 3);
108  return index;
109  }
110 
111  virtual std::shared_ptr<MCMCProposal> CoarseProposal (std::shared_ptr<MultiIndex> const& fineIndex,
112  std::shared_ptr<MultiIndex> const& coarseIndex,
113  std::shared_ptr<AbstractSamplingProblem> const& coarseProblem,
114  std::shared_ptr<SingleChainMCMC> const& coarseChain) override {
115  pt::ptree ptProposal = pt;
116  ptProposal.put("BlockIndex",0);
117  return std::make_shared<SubsamplingMIProposal>(ptProposal, coarseProblem, coarseIndex, coarseChain);
118  }
119 
120  virtual std::shared_ptr<AbstractSamplingProblem> SamplingProblem (std::shared_ptr<MultiIndex> const& index) override {
121  Eigen::VectorXd mu(2);
122  mu << 1.0, 2.0;
123  Eigen::MatrixXd cov(2,2);
124  cov << 0.7, 0.6,
125  0.6, 1.0;
126 
127  if (index->GetValue(0) == 0) {
128  mu *= 0.8;
129  cov *= 2.0;
130  } else if (index->GetValue(0) == 1) {
131  mu *= 0.9;
132  cov *= 1.5;
133  } else if (index->GetValue(0) == 2) {
134  mu *= 0.99;
135  cov *= 1.1;
136  } else if (index->GetValue(0) == 3) {
137  mu *= 1.0;
138  cov *= 1.0;
139  } else {
140  std::cerr << "Sampling problem not defined!" << std::endl;
141  assert (false);
142  }
143 
144  auto coarseTargetDensity = std::make_shared<Gaussian>(mu, cov)->AsDensity();
145  return std::make_shared<MySamplingProblem>(coarseTargetDensity);
146  }
147 
148  virtual std::shared_ptr<MIInterpolation> Interpolation (std::shared_ptr<MultiIndex> const& index) override {
149  return std::make_shared<MyInterpolation>();
150  }
151 
152  virtual Eigen::VectorXd StartingPoint (std::shared_ptr<MultiIndex> const& index) override {
153  return startingPoint;
154  }
155 
156 private:
157  Eigen::VectorXd startingPoint;
158  pt::ptree pt;
159 };
160 
161 
162 
163 
164 int main(){
165 
166  pt::ptree pt;
167 
168  pt.put("NumSamples", 1e2); // number of samples for single level
169  pt.put("NumInitialSamples", 1e3); // number of initial samples for greedy MLMCMC
170  pt.put("GreedyTargetVariance", 0.05); // estimator variance to be achieved by greedy algorithm
171  pt.put("verbosity", 1); // show some output
172  pt.put("MLMCMC.Subsampling_0", 8);
173  pt.put("MLMCMC.Subsampling_1", 4);
174  pt.put("MLMCMC.Subsampling_2", 2);
175  pt.put("MLMCMC.Subsampling_3", 0);
176 
177 
178  unsigned int numChains = 5;
179  std::vector<std::shared_ptr<MultiIndexEstimator>> estimators(numChains);
180 
181  for(int chainInd=0; chainInd<numChains; ++chainInd){
182  Eigen::VectorXd x0 = RandomGenerator::GetNormal(2);
183  auto componentFactory = std::make_shared<MyMIComponentFactory>(x0, pt);
184 
185  std::cout << "\n=============================\n";
186  std::cout << "Running MLMCMC Chain " << chainInd << ": \n";
187  std::cout << "-----------------------------\n";
188 
189  GreedyMLMCMC greedymlmcmc (pt, componentFactory);
190  estimators.at(chainInd) = greedymlmcmc.Run();
191 
192  std::cout << "mean QOI: " << estimators.at(chainInd)->Mean().transpose() << std::endl;
193 
194  std::stringstream filename;
195  filename << "MultilevelGaussianSampling_Chain" << chainInd << ".h5";
196  greedymlmcmc.WriteToFile(filename.str());
197  }
198 
199  std::cout << "\n=============================\n";
200  std::cout << "Multilevel Summary: \n";
201  std::cout << "-----------------------------\n";
202  std::cout << " Rhat: " << Diagnostics::Rhat(estimators).transpose() << std::endl;
203  std::cout << " Mean (chain 0): " << estimators.at(0)->Mean().transpose() << std::endl;
204  std::cout << " MCSE (chain 0): " << estimators.at(0)->StandardError().transpose() << std::endl;
205  std::cout << " ESS (chain 0): " << estimators.at(0)->ESS().transpose() << std::endl;
206  std::cout << " Variance (chain 0): " << estimators.at(0)->Variance().transpose() << std::endl;
207  std::cout << std::endl;
208 
209 
210  return 0;
211 }
std::shared_ptr< SamplingState > Interpolate(std::shared_ptr< SamplingState > const &coarseProposal, std::shared_ptr< SamplingState > const &fineProposal)
virtual Eigen::VectorXd StartingPoint(std::shared_ptr< MultiIndex > const &index) override
virtual std::shared_ptr< MCMCProposal > CoarseProposal(std::shared_ptr< MultiIndex > const &fineIndex, std::shared_ptr< MultiIndex > const &coarseIndex, std::shared_ptr< AbstractSamplingProblem > const &coarseProblem, std::shared_ptr< SingleChainMCMC > const &coarseChain) override
virtual std::shared_ptr< AbstractSamplingProblem > SamplingProblem(std::shared_ptr< MultiIndex > const &index) override
virtual std::shared_ptr< MultiIndex > FinestIndex() override
virtual std::shared_ptr< MCMCProposal > Proposal(std::shared_ptr< MultiIndex > const &index, std::shared_ptr< AbstractSamplingProblem > const &samplingProblem) override
MyMIComponentFactory(Eigen::VectorXd const &start, pt::ptree pt)
virtual std::shared_ptr< MIInterpolation > Interpolation(std::shared_ptr< MultiIndex > const &index) override
Abstract base class for MCMC and Importance Sampling problems.
Greedy Multilevel MCMC method.
Definition: GreedyMLMCMC.h:24
void WriteToFile(std::string filename)
virtual std::shared_ptr< MultiIndexEstimator > Run()
Interface defining models on a multiindex structure.
Interpolation interface combining coarse and fine samples.