1 #ifndef PARALLELMIMCMCBOX_H_
2 #define PARALLELMIMCMCBOX_H_
13 #include <parcer/Communicator.h>
14 #include <boost/property_tree/ptree.hpp>
25 namespace pt = boost::property_tree;
29 namespace SamplingAlgorithms {
43 ParallelMIMCMCBox(boost::property_tree::ptree
const& pt, std::shared_ptr<MIComponentFactory> componentFactory, std::shared_ptr<MultiIndex> boxHighestIndex, std::shared_ptr<parcer::Communicator> global_comm, std::shared_ptr<PhonebookClient> phonebookClient, std::shared_ptr<muq::Utilities::OTF2TracerBase> tracer)
45 componentFactory(componentFactory),
46 boxHighestIndex(boxHighestIndex)
49 ptChains.put(
"NumSamples", 0);
50 ptChains.put(
"BurnIn", 0);
51 ptChains.put(
"PrintLevel", 0);
52 ptChains.put(
"BlockIndex",0);
54 ptBlockID.put(
"BlockIndex",0);
57 boxLowestIndex = MultiIndex::Copy(boxHighestIndex);
60 std::shared_ptr<MultiIndex> boxSize = std::make_shared<MultiIndex>(*boxHighestIndex - *boxLowestIndex);
64 boxChains.resize(boxIndices->Size());
66 std::shared_ptr<SingleChainMCMC> coarse_chain =
nullptr;
67 std::shared_ptr<AbstractSamplingProblem> coarse_problem =
nullptr;
69 for (uint i = 0; i < boxIndices->Size(); i++) {
70 std::shared_ptr<MultiIndex> boxIndex = (*boxIndices)[i];
72 if (boxIndex->Max() == 0) {
73 if (boxLowestIndex->Max() == 0) {
74 coarse_problem = componentFactory->SamplingProblem(boxLowestIndex);
75 auto proposal_coarse = componentFactory->Proposal(boxLowestIndex, coarse_problem);
77 std::vector<std::shared_ptr<TransitionKernel>> coarse_kernels(1);
78 if (componentFactory->IsInverseProblem())
79 coarse_kernels[0] = std::make_shared<MHKernel>(ptBlockID,coarse_problem,proposal_coarse);
81 coarse_kernels[0] = std::make_shared<DummyKernel>(ptBlockID, coarse_problem, proposal_coarse);
83 Eigen::VectorXd startPtCoarse = componentFactory->StartingPoint(boxLowestIndex);
85 pt::ptree ptCoarsestChain;
86 ptCoarsestChain.put(
"PrintLevel", 0);
87 ptCoarsestChain.put(
"NumSamples", 0);
88 ptCoarsestChain.put(
"BurnIn", pt.get<
int>(
"MCMC.BurnIn"));
90 coarse_chain = std::make_shared<SingleChainMCMC>(ptCoarsestChain,coarse_kernels);
91 coarse_chain->SetState(startPtCoarse);
92 boxChains[boxIndices->MultiToIndex(boxIndex)] = coarse_chain;
95 spdlog::debug(
"Rank {} burning in", global_comm->GetRank());
96 coarse_chain->AddNumSamps(pt.get<
int>(
"MCMC.BurnIn"));
98 spdlog::debug(
"Rank {} burned in", global_comm->GetRank());
102 std::shared_ptr<MultiIndex> remoteIndex = MultiIndex::Copy(boxLowestIndex);
104 int maxEntry = remoteIndex->GetVector().maxCoeff(&maxCoeffId);
105 assert (maxEntry > 0);
107 remoteIndex->SetValue(maxCoeffId, maxEntry - 1);
109 auto remote_problem = componentFactory->SamplingProblem(remoteIndex);
111 auto coarse_proposal = std::make_shared<RemoteMIProposal>(ptBlockID, remote_problem, global_comm, remoteIndex, boxHighestIndex, phonebookClient);
112 auto startingPoint = componentFactory->StartingPoint(boxLowestIndex);
113 auto problem = componentFactory->SamplingProblem(boxLowestIndex);
114 auto proposal = componentFactory->Proposal(boxLowestIndex, problem);
115 auto proposalInterpolation = componentFactory->Interpolation(boxLowestIndex);
117 std::vector<std::shared_ptr<TransitionKernel>> kernels(1);
118 if (componentFactory->IsInverseProblem())
119 kernels[0] = std::make_shared<MIKernel>(ptBlockID,problem,remote_problem,proposal,coarse_proposal,proposalInterpolation,
nullptr);
121 kernels[0] = std::make_shared<MIDummyKernel>(ptBlockID, problem, proposal, coarse_proposal, proposalInterpolation, coarse_chain);
123 auto startingState = std::make_shared<SamplingState>(startingPoint);
124 startingState->meta[
"coarseSample"] = std::make_shared<SamplingState>(componentFactory->StartingPoint(remoteIndex));
126 coarse_chain = std::make_shared<SingleChainMCMC>(ptChains,kernels);
127 coarse_chain->SetState(startingState);
129 boxChains[boxIndices->MultiToIndex(boxIndex)] = coarse_chain;
130 coarse_problem = problem;
134 std::shared_ptr<MultiIndex> index = std::make_shared<MultiIndex>(*boxLowestIndex + *boxIndex);
136 auto problem = componentFactory->SamplingProblem(index);
137 auto proposal = componentFactory->Proposal(index, problem);
138 auto coarse_proposal = componentFactory->CoarseProposal(index, boxLowestIndex, coarse_problem, coarse_chain);
139 auto proposalInterpolation = componentFactory->Interpolation(index);
140 auto startingPoint = componentFactory->StartingPoint(index);
142 std::vector<std::shared_ptr<TransitionKernel>> kernels(1);
143 if (componentFactory->IsInverseProblem())
144 kernels[0] = std::make_shared<MIKernel>(ptBlockID,problem,coarse_problem,proposal,coarse_proposal,proposalInterpolation,coarse_chain);
146 kernels[0] = std::make_shared<MIDummyKernel>(ptBlockID, problem, proposal, coarse_proposal, proposalInterpolation, coarse_chain);
148 auto chain = std::make_shared<SingleChainMCMC>(ptChains,kernels);
149 chain->SetState(startingPoint);
151 boxChains[boxIndices->MultiToIndex(boxIndex)] = chain;
153 if (*boxIndex == *boxSize)
154 finestProblem = problem;
158 if (boxHighestIndex->Max() == 0)
159 finestProblem = coarse_problem;
163 return finestProblem;
167 std::shared_ptr<MultiIndex> boxSize = std::make_shared<MultiIndex>(*boxHighestIndex - *boxLowestIndex);
168 return boxChains[boxIndices->MultiToIndex(boxSize)];
171 std::shared_ptr<SingleChainMCMC>
GetChain(
int index) {
172 return boxChains[index];
176 return boxIndices->Size();
181 const int num_components = GetFinestProblem()->blockSizesQOI.size();
182 std::vector<Eigen::VectorXd> sampDiff(num_components);
183 for (
int component = 0; component < num_components; component++) {
184 sampDiff[component] = Eigen::VectorXd::Zero(GetFinestProblem()->blockSizesQOI[component]);
193 for (
unsigned int i = 0; i < boxIndices->Size(); i++) {
194 std::shared_ptr<MultiIndex> boxIndex = (*boxIndices)[i];
195 auto chain = boxChains[boxIndices->MultiToIndex(boxIndex)];
196 chain->AddNumSamps(1);
200 for (
unsigned int i = 0; i < boxIndices->Size(); i++) {
201 std::shared_ptr<MultiIndex> boxIndex = (*boxIndices)[i];
202 auto chain = boxChains[boxIndices->MultiToIndex(boxIndex)];
205 if (chain->GetQOIs()->size() > 0) {
206 auto new_state = chain->GetQOIs()->back();
208 std::shared_ptr<MultiIndex> index = std::make_shared<MultiIndex>(*boxLowestIndex + *boxIndex);
209 auto indexDiffFromTop = std::make_shared<MultiIndex>(*boxHighestIndex - *index);
211 if (indexDiffFromTop->Sum() % 2 == 0) {
212 for (
int component = 0; component < num_components; component++) {
213 sampDiff[component] += new_state->state[component];
216 for (
int component = 0; component < num_components; component++) {
217 sampDiff[component] -= new_state->state[component];
222 if (boxChains[0]->GetQOIs()->size() > 0)
223 QOIDiff->Add(std::make_shared<SamplingState>(sampDiff));
228 Eigen::VectorXd sampMean = Eigen::VectorXd::Zero(GetFinestProblem()->blockSizesQOI.sum());
230 for (uint i = 0; i < boxIndices->Size(); i++) {
231 std::shared_ptr<MultiIndex> boxIndex = (*boxIndices)[i];
232 auto chain = boxChains[boxIndices->MultiToIndex(boxIndex)];
233 auto samps = chain->GetQOIs();
235 std::shared_ptr<MultiIndex> index = std::make_shared<MultiIndex>(*boxLowestIndex + *boxIndex);
236 auto indexDiffFromTop = std::make_shared<MultiIndex>(*boxHighestIndex - *index);
238 if (indexDiffFromTop->Sum() % 2 == 0) {
239 sampMean += samps->Mean();
241 sampMean -= samps->Mean();
259 std::vector<std::shared_ptr<SingleChainMCMC>>
boxChains;
261 std::shared_ptr<AbstractSamplingProblem> finestProblem =
nullptr;
A class for storing and working with the results of Markov chain Monte Carlo algorithms.
Parallel equivalent to the MIMCMCBox, holds chains representing telescoping sum component.
std::shared_ptr< SingleChainMCMC > FinestChain()
std::shared_ptr< AbstractSamplingProblem > GetFinestProblem()
std::shared_ptr< MultiIndex > boxLowestIndex
std::vector< std::shared_ptr< SingleChainMCMC > > boxChains
std::shared_ptr< MultiIndexSet > boxIndices
std::shared_ptr< MIComponentFactory > componentFactory
Eigen::VectorXd MeanQOI()
std::shared_ptr< SampleCollection > GetQOIDiff()
std::shared_ptr< SampleCollection > QOIDiff
std::shared_ptr< MultiIndex > boxHighestIndex
std::vector< std::shared_ptr< SingleChainMCMC > > tailChains
ParallelMIMCMCBox(boost::property_tree::ptree const &pt, std::shared_ptr< MIComponentFactory > componentFactory, std::shared_ptr< MultiIndex > boxHighestIndex, std::shared_ptr< parcer::Communicator > global_comm, std::shared_ptr< PhonebookClient > phonebookClient, std::shared_ptr< muq::Utilities::OTF2TracerBase > tracer)
std::shared_ptr< SingleChainMCMC > GetChain(int index)
static std::shared_ptr< MultiIndexSet > CreateFullTensor(unsigned int const length, unsigned int const order, std::shared_ptr< MultiIndexLimiter > limiter=std::make_shared< NoLimiter >())
Construct a full tensor product multiindex set.