MUQ  0.4.3
MetropolisInGibbs.cpp
Go to the documentation of this file.
6 
12 
14 
15 #include <boost/property_tree/ptree.hpp>
16 
17 namespace pt = boost::property_tree;
18 using namespace muq::Modeling;
19 using namespace muq::SamplingAlgorithms;
20 using namespace muq::Utilities;
21 
22 int main(){
23 
24  Eigen::VectorXd mux(1), varx(1);
25  mux << 1.0;
26  varx << 0.5;
27 
28  auto px = std::make_shared<Gaussian>(mux,varx)->AsDensity();
29 
30  Eigen::VectorXd muy(2), vary(2);
31  muy << -1.0, -1.0;
32  vary << 1.0, 2.0;
33 
34  auto py = std::make_shared<Gaussian>(muy,vary)->AsDensity();
35 
36  auto graph = std::make_shared<WorkGraph>();
37  graph->AddNode(px, "p(x)");
38  graph->AddNode(py, "p(y)");
39  graph->AddNode(std::make_shared<DensityProduct>(2), "p(x,y)");
40  graph->AddEdge("p(x)",0,"p(x,y)",0);
41  graph->AddEdge("p(y)",0,"p(x,y)",1);
42 
43  auto pxy = graph->CreateModPiece("p(x,y)");
44 
45  // Define the sampling problem as normal
46  auto problem = std::make_shared<SamplingProblem>(pxy);
47 
48  // Construct two kernels: one for x and one for y
49  boost::property_tree::ptree opts;
50 
51  // A vector to holding the two transition kernels
52  std::vector<std::shared_ptr<TransitionKernel>> kernels(2);
53 
54  // Construct the kernel on x
55  opts.put("ProposalVariance", 3.0);
56  opts.put("BlockIndex", 0); // Specify that this proposal should target x
57  auto propx = std::make_shared<MHProposal>(opts, problem);
58  kernels.at(0) = std::make_shared<MHKernel>(opts, problem, propx);
59 
60  // Construct the kernel on y
61  opts.put("ProposalVariance", 5.0);
62  opts.put("BlockIndex", 1); // Specify that this proposal should target y
63  auto propy = std::make_shared<MHProposal>(opts, problem);
64  kernels.at(1) = std::make_shared<MHKernel>(opts, problem, propy);
65 
66  // Construct the MCMC sampler using this transition kernel
67  opts.put("NumSamples", 2000);
68  opts.put("BurnIn", 100);
69  opts.put("PrintLevel", 3);
70 
71 
72  // Run 4 independent chains to help assess convergence
73  unsigned int numChains = 4;
74  std::vector<std::shared_ptr<SampleCollection>> chains(numChains);
75  std::vector<Eigen::VectorXd> startPt(2);
76 
77  for(int i=0; i<numChains;++i){
78  startPt.at(0) = RandomGenerator::GetNormal(1);
79  startPt.at(1) = 2.0*RandomGenerator::GetNormal(2); // Initial point for y
80 
81  auto sampler = std::make_shared<SingleChainMCMC>(opts, kernels);
82  chains.at(i) = sampler->Run(startPt);
83  }
84 
85  // Compute the Rhat convergence diagnostic
86  Eigen::VectorXd rhat = Diagnostics::Rhat(chains);
87  std::cout << "Rhat = " << rhat.transpose() << std::endl;
88 
89  // Estimate the total effective sample size
90  Eigen::VectorXd ess = chains.at(0)->ESS();
91  for(int i=1; i<numChains; ++i)
92  ess += chains.at(i)->ESS();
93 
94  std::cout << "ESS: " << ess.transpose() << std::endl;
95 
96 
97 
98  return 0;
99 }
int main()