MUQ  0.4.3
MultilevelMCMC_BasicInterface.cpp
Go to the documentation of this file.
1 /***
2 ## Overview
3 This example shows how to use the high-level (basic) 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 
35 
37 
38 #include <boost/property_tree/ptree.hpp>
39 #include <sstream>
40 
41 namespace pt = boost::property_tree;
42 using namespace muq::Modeling;
43 using namespace muq::SamplingAlgorithms;
44 using namespace muq::Utilities;
45 
46 
47 /***
48  ## Define the Target Distributions
49  To apply MLMCMC, we need to define
50 */
51 std::vector<std::shared_ptr<ModPiece>> ConstructDensities()
52 {
53  unsigned int numLevels = 4;
54  std::vector<std::shared_ptr<ModPiece>> logDensities(numLevels);
55 
56  Eigen::VectorXd tgtMu(2);
57  Eigen::MatrixXd tgtCov(2,2);
58  tgtMu << 1.0, 2.0;
59  tgtCov << 0.7, 0.2,
60  0.2, 1.0;
61 
62  // Define the problem at the coarsest level
63  Eigen::VectorXd levelMu = 0.8*tgtMu;
64  Eigen::MatrixXd levelCov = 2.0*tgtCov;
65  logDensities.at(0) = std::make_shared<Gaussian>(levelMu, levelCov)->AsDensity();
66 
67  // Define the second coarsest level
68  levelMu = 0.9*tgtMu;
69  levelCov = 1.5*tgtCov;
70  logDensities.at(1) = std::make_shared<Gaussian>(levelMu, levelCov)->AsDensity();
71 
72  // Define the second finest level
73  levelMu = 0.99*tgtMu;
74  levelCov = 1.1*tgtCov;
75  logDensities.at(2) = std::make_shared<Gaussian>(levelMu, levelCov)->AsDensity();
76 
77  // Deifne the finest level. This should be the target distribution.
78  logDensities.at(3) = std::make_shared<Gaussian>(tgtMu, tgtCov)->AsDensity();
79 
80  return logDensities;
81 }
82 
83 int main(){
84 
85  std::vector<std::shared_ptr<ModPiece>> logDensities = ConstructDensities();
86 
87 
88  pt::ptree options;
89 
90  options.put("NumInitialSamples", 1000); // number of initial samples for greedy MLMCMC
91  options.put("GreedyTargetVariance", 0.05); // Target estimator variance to be achieved by greedy algorithm
92  options.put("verbosity", 1); // show some output
93  options.put("MLMCMC.Subsampling_0", 8);
94  options.put("MLMCMC.Subsampling_1", 4);
95  options.put("MLMCMC.Subsampling_2", 2);
96  options.put("MLMCMC.Subsampling_3", 0);
97 
98  options.put("Proposal.Method", "MHProposal");
99  options.put("Proposal.ProposalVariance", 16.0);
100 
101 
102  unsigned int numChains = 5;
103  std::vector<std::shared_ptr<MultiIndexEstimator>> estimators(numChains);
104 
105  for(int chainInd=0; chainInd<numChains; ++chainInd){
106  Eigen::VectorXd x0 = RandomGenerator::GetNormal(2);
107 
108  std::cout << "\n=============================\n";
109  std::cout << "Running MLMCMC Chain " << chainInd << ": \n";
110  std::cout << "-----------------------------\n";
111 
112  GreedyMLMCMC sampler(options, x0, logDensities);
113  estimators.at(chainInd) = sampler.Run();
114 
115  std::cout << "Chain " << chainInd << " Mean: " << estimators.at(chainInd)->Mean().transpose() << std::endl;
116  std::cout << "Chain " << chainInd << " Variance: " << estimators.at(chainInd)->Variance().transpose() << std::endl;
117 
118  std::stringstream filename;
119  filename << "MultilevelGaussianSampling_Chain" << chainInd << ".h5";
120  sampler.WriteToFile(filename.str());
121 
122  }
123 
124 
125  unsigned int numCalls = logDensities.back()->GetNumCalls();
126 
127  std::cout << "\n=============================\n";
128  std::cout << "Multilevel Summary: \n";
129  std::cout << "-----------------------------\n";
130  std::cout << " Rhat: " << Diagnostics::Rhat(estimators).transpose() << std::endl;
131  std::cout << " Mean (chain 0): " << estimators.at(0)->Mean().transpose() << std::endl;
132  std::cout << " MCSE (chain 0): " << estimators.at(0)->StandardError().transpose() << std::endl;
133  std::cout << " ESS (chain 0): " << estimators.at(0)->ESS().transpose() << std::endl;
134  std::cout << " Variance (chain 0): " << estimators.at(0)->Variance().transpose() << std::endl;
135  std::cout << " Finest evals: " << logDensities.back()->GetNumCalls() << std::endl;
136  std::cout << std::endl;
137 
138 
139 
140  std::cout << "\n=============================\n";
141  std::cout << "Running Single Level Chain" << ": \n";
142  std::cout << "-----------------------------\n";
143 
144  // For comparison, run a single chain on this problem with the same number of density evaluations
145  auto problem = std::make_shared<SamplingProblem>(logDensities.back());
146 
147  // parameters for the sampler
148  pt::ptree pt;
149  pt.put("NumSamples", numCalls); // number of MCMC steps
150  pt.put("BurnIn", 0);
151  pt.put("PrintLevel",3);
152  pt.put("KernelList", "Kernel1"); // Name of block that defines the transition kernel
153  pt.put("Kernel1.Method","MHKernel"); // Name of the transition kernel class
154  pt.put("Kernel1.Proposal", "MyProposal"); // Name of block defining the proposal distribution
155  pt.put("Kernel1.MyProposal.Method", "MHProposal"); // Name of proposal class
156  pt.put("Kernel1.MyProposal.ProposalVariance", 4.0); // Variance of the isotropic MH proposal
157 
158  Eigen::VectorXd startPt(2);
159  startPt << 1.0, 2.0;
160  auto mcmc = std::make_shared<SingleChainMCMC>(pt, problem);
161 
162  auto samps = mcmc->Run(startPt);
163 
164  std::cout << "\n=============================\n";
165  std::cout << "Single Level Summary: \n";
166  std::cout << "-----------------------------\n";
167  std::cout << " Mean: " << samps->Mean().transpose() << std::endl;
168  std::cout << " MCSE: " << samps->StandardError().transpose() << std::endl;
169  std::cout << " ESS: " << samps->ESS().transpose() << std::endl;
170  std::cout << " Variance: " << samps->Variance().transpose() << std::endl;
171  std::cout << " Finest evals: " << logDensities.back()->GetNumCalls()- numCalls << std::endl;
172  std::cout << std::endl;
173 
174  return 0;
175 }
std::vector< std::shared_ptr< ModPiece > > ConstructDensities()
Greedy Multilevel MCMC method.
Definition: GreedyMLMCMC.h:24
void WriteToFile(std::string filename)
virtual std::shared_ptr< MultiIndexEstimator > Run()