00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "BCEngineMCMC.h"
00011
00012 #include "BCParameter.h"
00013 #include "BCLog.h"
00014
00015 #include <TH1D.h>
00016 #include <TH2D.h>
00017 #include <TTree.h>
00018 #include <TRandom3.h>
00019
00020 #include <iostream>
00021 #include <math.h>
00022
00023
00024 BCEngineMCMC::BCEngineMCMC()
00025 {
00026
00027 MCMCSetValuesDefault();
00028
00029
00030 fRandom = new TRandom3(0);
00031 }
00032
00033
00034 BCEngineMCMC::BCEngineMCMC(int n)
00035 {
00036
00037 fMCMCNChains = n;
00038
00039
00040 BCEngineMCMC();
00041 }
00042
00043
00044 void BCEngineMCMC::MCMCSetValuesDefault()
00045 {
00046 fMCMCNParameters = 0;
00047 fMCMCFlagWriteChainToFile = false;
00048 fMCMCFlagWritePreRunToFile = false;
00049 fMCMCFlagPreRun = true;
00050 fMCMCFlagRun = false;
00051 fMCMCFlagFillHistograms = true;
00052 fMCMCEfficiencyMin = 0.15;
00053 fMCMCEfficiencyMax = 0.50;
00054 fMCMCFlagInitialPosition = 1;
00055 fMCMCNLag = 1;
00056 fMCMCCurrentIteration = -1;
00057 fMCMCCurrentChain = -1;
00058
00059 MCMCSetValuesDetail();
00060 }
00061
00062
00063 void BCEngineMCMC::MCMCSetValuesQuick()
00064 {
00065 fMCMCNChains = 2;
00066 fMCMCNIterationsMax = 10000;
00067 fMCMCNIterationsRun = 10000;
00068 fMCMCNIterationsPreRunMin = 500;
00069 fMCMCFlagInitialPosition = 1;
00070 fMCMCRValueUseStrict = false;
00071 fMCMCRValueCriterion = 0.1;
00072 fMCMCRValueParametersCriterion = 0.1;
00073 fMCMCNIterationsConvergenceGlobal = -1;
00074 fMCMCFlagConvergenceGlobal = false;
00075 fMCMCRValue = 100;
00076 fMCMCNIterationsUpdate = 1000;
00077 fMCMCNIterationsUpdateMax = 10000;
00078 fMCMCFlagOrderParameters = true;
00079 fMCMCCurrentIteration = -1;
00080 fMCMCCurrentChain = -1;
00081 }
00082
00083
00084 void BCEngineMCMC::MCMCSetValuesDetail()
00085 {
00086 fMCMCNChains = 5;
00087 fMCMCNIterationsMax = 1000000;
00088 fMCMCNIterationsRun = 100000;
00089 fMCMCNIterationsPreRunMin = 500;
00090 fMCMCFlagInitialPosition = 1;
00091 fMCMCRValueUseStrict = false;
00092 fMCMCRValueCriterion = 0.1;
00093 fMCMCRValueParametersCriterion = 0.1;
00094 fMCMCNIterationsConvergenceGlobal = -1;
00095 fMCMCFlagConvergenceGlobal = false;
00096 fMCMCRValue = 100;
00097 fMCMCNIterationsUpdate = 1000;
00098 fMCMCNIterationsUpdateMax = 10000;
00099 fMCMCFlagOrderParameters = true;
00100 fMCMCCurrentIteration = -1;
00101 fMCMCCurrentChain = -1;
00102 }
00103
00104
00105 void BCEngineMCMC::MCMCSetPrecision(BCEngineMCMC::Precision precision)
00106 {
00107 switch(precision) {
00108 case BCEngineMCMC::kLow:
00109 fMCMCNChains = 1;
00110 fMCMCNLag = 1;
00111 fMCMCNIterationsMax = 10000;
00112 fMCMCNIterationsRun = 10000;
00113 fMCMCNIterationsPreRunMin = 100;
00114 fMCMCNIterationsUpdate = 1000;
00115 fMCMCNIterationsUpdateMax = 10000;
00116 fMCMCRValueCriterion = 0.1;
00117 fMCMCRValueParametersCriterion = 0.1;
00118 fMCMCRValue = 100;
00119 break;
00120 case BCEngineMCMC::kMedium:
00121 fMCMCNChains = 5;
00122 fMCMCNLag = 1;
00123 fMCMCNIterationsMax = 100000;
00124 fMCMCNIterationsRun = 100000;
00125 fMCMCNIterationsPreRunMin = 100;
00126 fMCMCNIterationsUpdate = 1000;
00127 fMCMCNIterationsUpdateMax = 10000;
00128 fMCMCRValueCriterion = 0.1;
00129 fMCMCRValueParametersCriterion = 0.1;
00130 fMCMCRValue = 100;
00131 break;
00132 case BCEngineMCMC::kHigh:
00133 fMCMCNChains = 10;
00134 fMCMCNLag = 10;
00135 fMCMCNIterationsMax = 1000000;
00136 fMCMCNIterationsRun = 1000000;
00137 fMCMCNIterationsPreRunMin = 100;
00138 fMCMCNIterationsUpdate = 1000;
00139 fMCMCNIterationsUpdateMax = 10000;
00140 fMCMCRValueCriterion = 0.1;
00141 fMCMCRValueParametersCriterion = 0.1;
00142 fMCMCRValue = 100;
00143 break;
00144 case BCEngineMCMC::kVeryHigh:
00145 fMCMCNChains = 10;
00146 fMCMCNLag = 10;
00147 fMCMCNIterationsMax = 10000000;
00148 fMCMCNIterationsRun = 10000000;
00149 fMCMCNIterationsPreRunMin = 100;
00150 fMCMCNIterationsUpdate = 1000;
00151 fMCMCNIterationsUpdateMax = 10000;
00152 fMCMCRValueCriterion = 0.1;
00153 fMCMCRValueParametersCriterion = 0.1;
00154 fMCMCRValue = 100;
00155 break;
00156 }
00157
00158
00159 MCMCInitialize();
00160 }
00161
00162
00163 BCEngineMCMC::~BCEngineMCMC()
00164 {
00165
00166 if (fRandom)
00167 delete fRandom;
00168
00169
00170 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
00171 if (fMCMCH1Marginalized[i])
00172 delete fMCMCH1Marginalized[i];
00173 fMCMCH1Marginalized.clear();
00174
00175
00176 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
00177 if (fMCMCH2Marginalized[i])
00178 delete fMCMCH2Marginalized[i];
00179 fMCMCH2Marginalized.clear();
00180 }
00181
00182
00183 BCEngineMCMC::BCEngineMCMC(const BCEngineMCMC & enginemcmc)
00184 {
00185 fMCMCPointerToGetProposalPoint = enginemcmc.fMCMCPointerToGetProposalPoint;
00186 fMCMCNParameters = enginemcmc.fMCMCNParameters;
00187 fMCMCBoundaryMin = enginemcmc.fMCMCBoundaryMin;
00188 fMCMCBoundaryMax = enginemcmc.fMCMCBoundaryMax;
00189 fMCMCFlagsFillHistograms = enginemcmc.fMCMCFlagsFillHistograms;
00190 fMCMCNChains = enginemcmc.fMCMCNChains;
00191 fMCMCNLag = enginemcmc.fMCMCNLag;
00192 fMCMCNIterations = enginemcmc.fMCMCNIterations;
00193 fMCMCCurrentIteration = enginemcmc.fMCMCCurrentIteration;
00194 fMCMCCurrentChain = enginemcmc.fMCMCCurrentChain;
00195 fMCMCNIterationsUpdate = enginemcmc.fMCMCNIterationsUpdate;
00196 fMCMCNIterationsUpdateMax = enginemcmc.fMCMCNIterationsUpdateMax;
00197 fMCMCNIterationsConvergenceGlobal = enginemcmc.fMCMCNIterationsConvergenceGlobal;
00198 fMCMCFlagConvergenceGlobal = enginemcmc.fMCMCFlagConvergenceGlobal;
00199 fMCMCNIterationsMax = enginemcmc.fMCMCNIterationsMax;
00200 fMCMCNIterationsRun = enginemcmc.fMCMCNIterationsRun;
00201 fMCMCNIterationsPreRunMin = enginemcmc.fMCMCNIterationsPreRunMin;
00202 fMCMCNTrialsTrue = enginemcmc.fMCMCNTrialsTrue;
00203 fMCMCNTrialsFalse = enginemcmc.fMCMCNTrialsFalse;
00204 fMCMCFlagWriteChainToFile = enginemcmc.fMCMCFlagWriteChainToFile;
00205 fMCMCFlagWritePreRunToFile = enginemcmc.fMCMCFlagWritePreRunToFile;
00206 fMCMCTrialFunctionScaleFactor = enginemcmc.fMCMCTrialFunctionScaleFactor;
00207 fMCMCTrialFunctionScaleFactorStart = enginemcmc.fMCMCTrialFunctionScaleFactorStart;
00208 fMCMCFlagPreRun = enginemcmc.fMCMCFlagPreRun;
00209 fMCMCFlagRun = enginemcmc.fMCMCFlagRun;
00210 fMCMCInitialPosition = enginemcmc.fMCMCInitialPosition;
00211 fMCMCEfficiencyMin = enginemcmc.fMCMCEfficiencyMin;
00212 fMCMCEfficiencyMax = enginemcmc.fMCMCEfficiencyMax;
00213 fMCMCFlagInitialPosition = enginemcmc.fMCMCFlagInitialPosition;
00214 fMCMCFlagOrderParameters = enginemcmc.fMCMCFlagOrderParameters;
00215 fMCMCFlagFillHistograms = enginemcmc.fMCMCFlagFillHistograms;
00216 fMCMCPhase = enginemcmc.fMCMCPhase;
00217 fMCMCCycle = enginemcmc.fMCMCCycle;
00218 fMCMCx = enginemcmc.fMCMCx;
00219 fMCMCxMax = enginemcmc.fMCMCxMax;
00220 fMCMCxMean = enginemcmc.fMCMCxMean;
00221 fMCMCxVar = enginemcmc.fMCMCxVar;
00222 fMCMCxLocal = enginemcmc.fMCMCxLocal;
00223 fMCMCprob = enginemcmc.fMCMCprob;
00224 fMCMCprobMax = enginemcmc.fMCMCprobMax;
00225 fMCMCprobMean = enginemcmc.fMCMCprobMean;
00226 fMCMCprobVar = enginemcmc.fMCMCprobVar;
00227 fMCMCRValueUseStrict = enginemcmc.fMCMCRValueUseStrict;
00228 fMCMCRValueCriterion = enginemcmc.fMCMCRValueCriterion ;
00229 fMCMCRValueParametersCriterion = enginemcmc.fMCMCRValueParametersCriterion;
00230 fMCMCRValue = enginemcmc.fMCMCRValue;
00231 fMCMCRValueParameters = enginemcmc.fMCMCRValueParameters;
00232 if (enginemcmc.fRandom)
00233 fRandom = new TRandom3(*enginemcmc.fRandom);
00234 else
00235 fRandom = 0;
00236 fMCMCH1NBins = enginemcmc.fMCMCH1NBins;
00237
00238 for (int i = 0; i < int(enginemcmc.fMCMCH1Marginalized.size()); ++i) {
00239 if (enginemcmc.fMCMCH1Marginalized.at(i))
00240 fMCMCH1Marginalized.push_back(new TH1D(*(enginemcmc.fMCMCH1Marginalized.at(i))));
00241 else
00242 fMCMCH1Marginalized.push_back(0);
00243 }
00244
00245 for (int i = 0; i < int(enginemcmc.fMCMCH2Marginalized.size()); ++i) {
00246 if (enginemcmc.fMCMCH2Marginalized.at(i))
00247 fMCMCH2Marginalized.push_back(new TH2D(*(enginemcmc.fMCMCH2Marginalized.at(i))));
00248 else
00249 fMCMCH2Marginalized.push_back(0);
00250 }
00251
00252 for (int i = 0; i < int(enginemcmc.fMCMCTrees.size()); ++i) {
00253
00254 fMCMCTrees.push_back(0);
00255 }
00256 }
00257
00258
00259 BCEngineMCMC & BCEngineMCMC::operator = (const BCEngineMCMC & enginemcmc)
00260 {
00261 fMCMCPointerToGetProposalPoint = enginemcmc.fMCMCPointerToGetProposalPoint;
00262 fMCMCNParameters = enginemcmc.fMCMCNParameters;
00263 fMCMCBoundaryMin = enginemcmc.fMCMCBoundaryMin;
00264 fMCMCBoundaryMax = enginemcmc.fMCMCBoundaryMax;
00265 fMCMCFlagsFillHistograms = enginemcmc.fMCMCFlagsFillHistograms;
00266 fMCMCNChains = enginemcmc.fMCMCNChains;
00267 fMCMCNLag = enginemcmc.fMCMCNLag;
00268 fMCMCNIterations = enginemcmc.fMCMCNIterations;
00269 fMCMCCurrentIteration = enginemcmc.fMCMCCurrentIteration;
00270 fMCMCCurrentChain = enginemcmc.fMCMCCurrentChain;
00271 fMCMCNIterationsUpdate = enginemcmc.fMCMCNIterationsUpdate;
00272 fMCMCNIterationsUpdateMax = enginemcmc.fMCMCNIterationsUpdateMax;
00273 fMCMCNIterationsConvergenceGlobal = enginemcmc.fMCMCNIterationsConvergenceGlobal;
00274 fMCMCFlagConvergenceGlobal = enginemcmc.fMCMCFlagConvergenceGlobal;
00275 fMCMCNIterationsMax = enginemcmc.fMCMCNIterationsMax;
00276 fMCMCNIterationsRun = enginemcmc.fMCMCNIterationsRun;
00277 fMCMCNIterationsPreRunMin = enginemcmc.fMCMCNIterationsPreRunMin;
00278 fMCMCNTrialsTrue = enginemcmc.fMCMCNTrialsTrue;
00279 fMCMCNTrialsFalse = enginemcmc.fMCMCNTrialsFalse;
00280 fMCMCFlagWriteChainToFile = enginemcmc.fMCMCFlagWriteChainToFile;
00281 fMCMCFlagWritePreRunToFile = enginemcmc.fMCMCFlagWritePreRunToFile;
00282 fMCMCTrialFunctionScaleFactor = enginemcmc.fMCMCTrialFunctionScaleFactor;
00283 fMCMCTrialFunctionScaleFactorStart = enginemcmc.fMCMCTrialFunctionScaleFactorStart;
00284 fMCMCFlagPreRun = enginemcmc.fMCMCFlagPreRun;
00285 fMCMCFlagRun = enginemcmc.fMCMCFlagRun;
00286 fMCMCInitialPosition = enginemcmc.fMCMCInitialPosition;
00287 fMCMCEfficiencyMin = enginemcmc.fMCMCEfficiencyMin;
00288 fMCMCEfficiencyMax = enginemcmc.fMCMCEfficiencyMax;
00289 fMCMCFlagInitialPosition = enginemcmc.fMCMCFlagInitialPosition;
00290 fMCMCFlagOrderParameters = enginemcmc.fMCMCFlagOrderParameters;
00291 fMCMCFlagFillHistograms = enginemcmc.fMCMCFlagFillHistograms;
00292 fMCMCPhase = enginemcmc.fMCMCPhase;
00293 fMCMCCycle = enginemcmc.fMCMCCycle;
00294 fMCMCx = enginemcmc.fMCMCx;
00295 fMCMCxMax = enginemcmc.fMCMCxMax;
00296 fMCMCxMean = enginemcmc.fMCMCxMean;
00297 fMCMCxVar = enginemcmc.fMCMCxVar;
00298 fMCMCxLocal = enginemcmc.fMCMCxLocal;
00299 fMCMCprob = enginemcmc.fMCMCprob;
00300 fMCMCprobMax = enginemcmc.fMCMCprobMax;
00301 fMCMCprobMean = enginemcmc.fMCMCprobMean;
00302 fMCMCprobVar = enginemcmc.fMCMCprobVar;
00303 fMCMCRValueUseStrict = enginemcmc.fMCMCRValueUseStrict;
00304 fMCMCRValueCriterion = enginemcmc.fMCMCRValueCriterion ;
00305 fMCMCRValueParametersCriterion = enginemcmc.fMCMCRValueParametersCriterion;
00306 fMCMCRValue = enginemcmc.fMCMCRValue;
00307 fMCMCRValueParameters = enginemcmc.fMCMCRValueParameters;
00308 if (enginemcmc.fRandom)
00309 fRandom = new TRandom3(*enginemcmc.fRandom);
00310 else
00311 fRandom = 0;
00312 fMCMCH1NBins = enginemcmc.fMCMCH1NBins;
00313
00314 for (int i = 0; i < int(enginemcmc.fMCMCH1Marginalized.size()); ++i) {
00315 if (enginemcmc.fMCMCH1Marginalized.at(i))
00316 fMCMCH1Marginalized.push_back(new TH1D(*(enginemcmc.fMCMCH1Marginalized.at(i))));
00317 else
00318 fMCMCH1Marginalized.push_back(0);
00319 }
00320
00321 for (int i = 0; i < int(enginemcmc.fMCMCH2Marginalized.size()); ++i) {
00322 if (enginemcmc.fMCMCH2Marginalized.at(i))
00323 fMCMCH2Marginalized.push_back(new TH2D(*(enginemcmc.fMCMCH2Marginalized.at(i))));
00324 else
00325 fMCMCH2Marginalized.push_back(0);
00326 }
00327
00328 for (int i = 0; i < int(enginemcmc.fMCMCTrees.size()); ++i) {
00329
00330 fMCMCTrees.push_back(0);
00331 }
00332
00333
00334 return *this;
00335 }
00336
00337
00338
00339 TH1D * BCEngineMCMC::MCMCGetH1Marginalized(int index)
00340 {
00341
00342 if (index < 0 || index >= int(fMCMCH1Marginalized.size()))
00343 {
00344 BCLog::OutWarning("BCEngineMCMC::MCMCGetH1Marginalized. Index out of range.");
00345 return 0;
00346 }
00347
00348 return fMCMCH1Marginalized[index];
00349 }
00350
00351
00352 TH2D * BCEngineMCMC::MCMCGetH2Marginalized(int index1, int index2)
00353 {
00354 int counter = 0;
00355 int index = 0;
00356
00357
00358 for(int i = 0; i < fMCMCNParameters; i++)
00359 for (int j = 0; j < i; ++j)
00360 {
00361 if(j == index1 && i == index2)
00362 index = counter;
00363 counter++;
00364 }
00365
00366
00367 if (index < 0 || index >= int(fMCMCH2Marginalized.size()))
00368 {
00369 BCLog::OutWarning("BCEngineMCMC::MCMCGetH2Marginalized. Index out of range.");
00370 return 0;
00371 }
00372
00373 return fMCMCH2Marginalized[index];
00374 }
00375
00376
00377 std::vector <double> BCEngineMCMC::MCMCGetMaximumPoint(int i)
00378 {
00379
00380 std::vector <double> x;
00381
00382
00383 if (i < 0 || i >= fMCMCNChains)
00384 return x;
00385
00386
00387 for (int j = 0; j < fMCMCNParameters; ++j)
00388 x.push_back(fMCMCxMax.at(i * fMCMCNParameters + j));
00389
00390 return x;
00391 }
00392
00393
00394 void BCEngineMCMC::MCMCSetNChains(int n)
00395 {
00396 fMCMCNChains = n;
00397
00398
00399 MCMCInitialize();
00400 }
00401
00402
00403 void BCEngineMCMC::MCMCSetInitialPositions(std::vector<double> x0s)
00404 {
00405
00406 fMCMCInitialPosition.clear();
00407
00408
00409 int n = int(x0s.size());
00410
00411 for (int i = 0; i < n; ++i)
00412 fMCMCInitialPosition.push_back(x0s.at(i));
00413
00414
00415 MCMCSetFlagInitialPosition(2);
00416 }
00417
00418
00419 void BCEngineMCMC::MCMCSetInitialPositions(std::vector< std::vector<double> > x0s)
00420 {
00421
00422 std::vector <double> y0s;
00423
00424
00425 for (int i = 0; i < int(x0s.size()); ++i)
00426 for (int j = 0; j < int((x0s.at(i)).size()); ++j)
00427 y0s.push_back((x0s.at(i)).at(j));
00428
00429 MCMCSetInitialPositions(y0s);
00430 }
00431
00432
00433 void BCEngineMCMC::MCMCSetFlagFillHistograms(bool flag)
00434 {
00435 fMCMCFlagFillHistograms = flag;
00436
00437 for (int i = 0; i < fMCMCNParameters; ++i)
00438 fMCMCFlagsFillHistograms[i] = flag;
00439 }
00440
00441
00442 void BCEngineMCMC::MCMCSetFlagFillHistograms(int index, bool flag)
00443 {
00444
00445 if (index < 0 || index > fMCMCNParameters)
00446 {
00447 BCLog::OutWarning("BCEngineMCMC :MCMCSetFlagFillHistograms. Index out of range.");
00448 return;
00449 }
00450
00451
00452 fMCMCFlagsFillHistograms[index] = flag;
00453 }
00454
00455
00456 void BCEngineMCMC::MCMCSetMarkovChainTrees(std::vector <TTree *> trees)
00457 {
00458
00459 fMCMCTrees.clear();
00460
00461
00462 for (int i = 0; i < int(trees.size()); ++i)
00463 fMCMCTrees.push_back(trees[i]);
00464 }
00465
00466
00467 void BCEngineMCMC::MCMCInitializeMarkovChainTrees()
00468 {
00469
00470 fMCMCTrees.clear();
00471
00472
00473 for (int i = 0; i < fMCMCNChains; ++i) {
00474 fMCMCTrees.push_back(new TTree(TString::Format("MarkovChainTree_%i", i), "MarkovChainTree"));
00475 fMCMCTrees[i]->Branch("Iteration", &fMCMCNIterations[i], "iteration/I");
00476 fMCMCTrees[i]->Branch("NParameters", &fMCMCNParameters, "parameters/I");
00477 fMCMCTrees[i]->Branch("LogProbability", &fMCMCprob[i], "log(probability)/D");
00478 fMCMCTrees[i]->Branch("Phase", &fMCMCPhase, "phase/I");
00479 fMCMCTrees[i]->Branch("Cycle", &fMCMCCycle, "cycle/I");
00480
00481 for (int j = 0; j < fMCMCNParameters; ++j)
00482 fMCMCTrees[i]->Branch(TString::Format("Parameter%i", j),
00483 &fMCMCx[i * fMCMCNParameters + j],
00484 TString::Format("parameter %i/D", j));
00485 }
00486 }
00487
00488
00489 void BCEngineMCMC::MCMCTrialFunction(int ichain, std::vector <double> &x)
00490 {
00491
00492 for (int i = 0; i < fMCMCNParameters; ++i)
00493 x[i] = MCMCTrialFunctionSingle(ichain, i);
00494 }
00495
00496
00497 double BCEngineMCMC::MCMCTrialFunctionSingle(int ichain, int iparameter)
00498 {
00499
00500
00501
00502
00503
00504
00505 return fRandom->BreitWigner(0.0, fMCMCTrialFunctionScaleFactor[ichain * fMCMCNParameters + iparameter]);
00506 }
00507
00508
00509 std::vector <double> BCEngineMCMC::MCMCGetTrialFunctionScaleFactor(int ichain)
00510 {
00511
00512 std::vector <double> x;
00513
00514
00515 if (ichain < 0 || ichain >= fMCMCNChains)
00516 return x;
00517
00518
00519 for (int j = 0; j < fMCMCNParameters; ++j)
00520 x.push_back(fMCMCTrialFunctionScaleFactor.at(ichain * fMCMCNParameters + j));
00521
00522 return x;
00523 }
00524
00525
00526 double BCEngineMCMC::MCMCGetTrialFunctionScaleFactor(int ichain, int ipar)
00527 {
00528
00529 if (ichain < 0 || ichain >= fMCMCNChains)
00530 return 0;
00531
00532
00533 if (ipar < 0 || ipar >= fMCMCNParameters)
00534 return 0;
00535
00536
00537 return fMCMCTrialFunctionScaleFactor.at(ichain * fMCMCNChains + ipar);
00538 }
00539
00540
00541 std::vector <double> BCEngineMCMC::MCMCGetx(int ichain)
00542 {
00543
00544 std::vector <double> x;
00545
00546
00547 if (ichain < 0 || ichain >= fMCMCNChains)
00548 return x;
00549
00550
00551 for (int j = 0; j < fMCMCNParameters; ++j)
00552 x.push_back(fMCMCx.at(ichain * fMCMCNParameters + j));
00553
00554 return x;
00555 }
00556
00557
00558 double BCEngineMCMC::MCMCGetx(int ichain, int ipar)
00559 {
00560
00561 if (ichain < 0 || ichain >= fMCMCNChains)
00562 return 0;
00563
00564
00565 if (ipar < 0 || ipar >= fMCMCNParameters)
00566 return 0;
00567
00568
00569 return fMCMCx.at(ichain * fMCMCNParameters + ipar);
00570 }
00571
00572
00573 double BCEngineMCMC::MCMCGetLogProbx(int ichain)
00574 {
00575
00576 if (ichain < 0 || ichain >= fMCMCNChains)
00577 return -1;
00578
00579
00580 return fMCMCprob.at(ichain);
00581 }
00582
00583
00584 bool BCEngineMCMC::MCMCGetProposalPointMetropolis(int chain, std::vector <double> &x)
00585 {
00586
00587 MCMCTrialFunction(chain, x);
00588
00589
00590 for (int i = 0; i < fMCMCNParameters; ++i)
00591 x[i] = fMCMCx[chain * fMCMCNParameters + i] + x[i] * (fMCMCBoundaryMax.at(i) - fMCMCBoundaryMin.at(i));
00592
00593
00594 for (int i = 0; i < fMCMCNParameters; ++i)
00595 if ((x[i] < fMCMCBoundaryMin[i]) || (x[i] > fMCMCBoundaryMax[i]))
00596 return false;
00597
00598 return true;
00599 }
00600
00601
00602 bool BCEngineMCMC::MCMCGetProposalPointMetropolis(int ichain, int ipar, std::vector <double> &x)
00603 {
00604
00605
00606 double proposal = MCMCTrialFunctionSingle(ichain, ipar);
00607
00608
00609 for (int i = 0; i < fMCMCNParameters; ++i)
00610 x[i] = fMCMCx[ichain * fMCMCNParameters + i];
00611
00612
00613 x[ipar] += proposal * (fMCMCBoundaryMax[ipar] - fMCMCBoundaryMin[ipar]);
00614
00615
00616 if ((x[ipar] < fMCMCBoundaryMin[ipar]) || (x[ipar] > fMCMCBoundaryMax[ipar]))
00617 return false;
00618
00619 return true;
00620 }
00621
00622
00623 bool BCEngineMCMC::MCMCGetNewPointMetropolis(int chain, int parameter)
00624 {
00625
00626 int index = chain * fMCMCNParameters;
00627
00628 fMCMCCurrentChain = chain;
00629
00630
00631 fMCMCNIterations[chain]++;
00632
00633
00634 if (!MCMCGetProposalPointMetropolis(chain, parameter, fMCMCxLocal))
00635 {
00636
00637 fMCMCNTrialsFalse[chain * fMCMCNParameters + parameter]++;
00638
00639
00640 MCMCCurrentPointInterface(fMCMCxLocal, chain, false);
00641
00642 return false;
00643 }
00644
00645
00646 double p0 = fMCMCprob[chain];
00647 double p1 = LogEval(fMCMCxLocal);
00648
00649
00650 bool accept = false;
00651
00652
00653 if (p1 >= p0)
00654 accept = true;
00655
00656 else
00657 {
00658 double r = log(fRandom->Rndm());
00659
00660 if(r < p1 - p0)
00661 accept = true;
00662 }
00663
00664
00665 if(accept)
00666 {
00667
00668 fMCMCNTrialsTrue[chain * fMCMCNParameters + parameter]++;
00669
00670
00671 for(int i = 0; i < fMCMCNParameters; ++i)
00672 {
00673
00674 fMCMCx[index + i] = fMCMCxLocal[i];
00675
00676
00677 fMCMCprob[chain] = p1;
00678 }
00679 }
00680 else
00681 {
00682
00683 fMCMCNTrialsFalse[chain * fMCMCNParameters + parameter]++;
00684 }
00685
00686
00687 MCMCCurrentPointInterface(fMCMCxLocal, chain, accept);
00688
00689 return accept;
00690 }
00691
00692
00693 bool BCEngineMCMC::MCMCGetNewPointMetropolis(int chain)
00694 {
00695
00696 int index = chain * fMCMCNParameters;
00697
00698 fMCMCCurrentChain = chain;
00699
00700
00701 fMCMCNIterations[chain]++;
00702
00703
00704 if (!MCMCGetProposalPointMetropolis(chain, fMCMCxLocal))
00705 {
00706
00707 for (int i = 0; i < fMCMCNParameters; ++i)
00708 fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00709
00710
00711 MCMCCurrentPointInterface(fMCMCxLocal, chain, false);
00712
00713 return false;
00714 }
00715
00716
00717 double p0 = fMCMCprob[chain];
00718 double p1 = LogEval(fMCMCxLocal);
00719
00720
00721 bool accept = false;
00722
00723
00724 if (p1 >= p0)
00725 accept = true;
00726
00727
00728 else
00729 {
00730 double r = log(fRandom->Rndm());
00731
00732 if(r < p1 - p0)
00733 accept = true;
00734 }
00735
00736
00737 if(accept)
00738 {
00739
00740 for (int i = 0; i < fMCMCNParameters; ++i)
00741 fMCMCNTrialsTrue[chain * fMCMCNParameters + i]++;
00742
00743
00744 for(int i = 0; i < fMCMCNParameters; ++i)
00745 {
00746
00747 fMCMCx[index + i] = fMCMCxLocal[i];
00748
00749
00750 fMCMCprob[chain] = p1;
00751 }
00752 }
00753 else
00754 {
00755
00756 for (int i = 0; i < fMCMCNParameters; ++i)
00757 fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00758 }
00759
00760
00761 MCMCCurrentPointInterface(fMCMCxLocal, chain, accept);
00762
00763 return accept;
00764 }
00765
00766
00767 void BCEngineMCMC::MCMCInChainCheckMaximum()
00768 {
00769
00770 for (int i = 0; i < fMCMCNChains; ++i)
00771 {
00772
00773 if (fMCMCprob[i] > fMCMCprobMax[i] || fMCMCNIterations[i] == 1)
00774 {
00775
00776 fMCMCprobMax[i] = fMCMCprob[i];
00777
00778
00779 for (int j = 0; j < fMCMCNParameters; ++j)
00780 fMCMCxMax[i * fMCMCNParameters + j] = fMCMCx[i * fMCMCNParameters + j];
00781 }
00782 }
00783 }
00784
00785
00786 void BCEngineMCMC::MCMCInChainUpdateStatistics()
00787 {
00788
00789 int npoints = fMCMCNTrialsTrue[0] + fMCMCNTrialsFalse[0];
00790
00791
00792 int nentries = fMCMCNParameters * fMCMCNChains;
00793
00794
00795 for (int i = 0; i < nentries; ++i) {
00796
00797 fMCMCxMean[i] += (fMCMCx[i] - fMCMCxMean[i]) / double(npoints);
00798
00799
00800 if (npoints > 1)
00801 fMCMCxVar[i] = (1.0 - 1./double(npoints)) * fMCMCxVar[i]
00802 + (fMCMCx[i] - fMCMCxMean[i]) * (fMCMCx[i] - fMCMCxMean[i]) / double(npoints - 1);
00803 }
00804
00805
00806 for (int i = 0; i < fMCMCNChains; ++i) {
00807
00808 fMCMCprobMean[i] += (fMCMCprob[i] - fMCMCprobMean[i]) / double(npoints);
00809
00810
00811 if (npoints > 1)
00812 fMCMCprobVar[i] = (1.0 - 1/double(npoints)) * fMCMCprobVar[i]
00813 + (fMCMCprob[i] - fMCMCprobMean[i]) * (fMCMCprob[i] - fMCMCprobMean[i]) / double(npoints - 1);
00814 }
00815
00816 }
00817
00818
00819 void BCEngineMCMC::MCMCInChainFillHistograms()
00820 {
00821
00822 if (!fMCMCFlagFillHistograms)
00823 return;
00824
00825
00826 for (int i = 0; i < fMCMCNChains; ++i)
00827 {
00828
00829 for (int j = 0; j < fMCMCNParameters; ++j)
00830 if (fMCMCFlagsFillHistograms.at(j))
00831 fMCMCH1Marginalized[j]->Fill(fMCMCx[i * fMCMCNParameters + j]);
00832
00833
00834 int counter = 0;
00835
00836 for (int j = 0; j < fMCMCNParameters; ++j)
00837 for (int k = 0; k < j; ++k)
00838 {
00839 if (fMCMCFlagsFillHistograms.at(j) && fMCMCFlagsFillHistograms.at(k))
00840 fMCMCH2Marginalized[counter]->Fill(fMCMCx[i*fMCMCNParameters+k],fMCMCx[i* fMCMCNParameters+j]);
00841 counter ++;
00842 }
00843 }
00844 }
00845
00846
00847 void BCEngineMCMC::MCMCInChainTestConvergenceAllChains()
00848 {
00849
00850 int npoints = fMCMCNTrialsTrue[0] + fMCMCNTrialsFalse[0];
00851
00852 if (fMCMCNChains > 1 && npoints > 1)
00853 {
00854
00855 bool flag_convergence = true;
00856
00857
00858 for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
00859 {
00860 double sum = 0;
00861 double sum2 = 0;
00862 double sumv = 0;
00863
00864
00865 for (int ichains = 0; ichains < fMCMCNChains; ++ichains) {
00866
00867 int index = ichains * fMCMCNParameters + iparameters;
00868
00869
00870 sum += fMCMCxMean[index];
00871 sum2 += fMCMCxMean[index] * fMCMCxMean[index];
00872 sumv += fMCMCxVar[index];
00873 }
00874
00875
00876 double mean = sum / double(fMCMCNChains);
00877 double B = (sum2 / double(fMCMCNChains) - mean * mean) * double(fMCMCNChains) / double(fMCMCNChains-1) * double(npoints);
00878 double W = sumv * double(npoints) / double(npoints - 1) / double(fMCMCNChains);
00879
00880
00881 if (W > 0) {
00882
00883 fMCMCRValueParameters[iparameters] = MCMCCalculateRValue(
00884 fMCMCxMean, fMCMCxVar, mean, B, W, npoints, iparameters);
00885
00886
00887
00888 if (! ((fMCMCRValueParameters[iparameters]-1.0) < fMCMCRValueParametersCriterion))
00889 flag_convergence = false;
00890 }
00891
00892 }
00893
00894 double sum = 0;
00895 double sum2 = 0;
00896 double sumv = 0;
00897
00898
00899 for (int i = 0; i < fMCMCNChains; ++i)
00900 {
00901 sum += fMCMCprobMean[i];
00902 sum2 += fMCMCprobMean[i] * fMCMCprobMean[i]; ;
00903 sumv += fMCMCprobVar[i];
00904 }
00905
00906
00907
00908
00909 double mean = sum / double(fMCMCNChains);
00910
00911 double B = (sum2 / double(fMCMCNChains) - mean * mean) * double(fMCMCNChains) / double(fMCMCNChains-1) * double(npoints);
00912
00913 double W = sumv * double(npoints) / double(npoints - 1) / double(fMCMCNChains);
00914
00915 if (W > 0)
00916 {
00917 fMCMCRValue = MCMCCalculateRValue(fMCMCprobMean, fMCMCprobVar, mean, B, W,
00918 npoints);
00919
00920
00921 if (!((fMCMCRValue - 1.0) < fMCMCRValueCriterion))
00922 flag_convergence = false;
00923 }
00924
00925
00926
00927 if (fMCMCNIterationsConvergenceGlobal == -1 && flag_convergence == true)
00928 fMCMCNIterationsConvergenceGlobal = fMCMCNIterations[0] / fMCMCNParameters;
00929 }
00930 }
00931
00932
00933 double BCEngineMCMC::MCMCCalculateRValue(
00934 const std::vector<double> & chainMeans,
00935 const std::vector<double> & chainVariances, double mean, double B,
00936 double W, int nPoints, int iParam)
00937 {
00938
00939 double r = 0;
00940
00941
00942 if (!fMCMCRValueUseStrict){
00943 r = sqrt(((1 - 1 / double(nPoints)) * W + 1 / double(nPoints)
00944 * B) / W);
00945 return r;
00946 }
00947
00948
00949
00950 double varS = 0;
00951 double cov1 = 0;
00952 double cov2 = 0;
00953
00954
00955 for (int i = 0; i < fMCMCNChains; ++i) {
00956
00957 int index = i;
00958 if (iParam >= 0)
00959 index = i * fMCMCNParameters + iParam;
00960
00961 varS += chainVariances[index] * chainVariances[index];
00962 cov1 += (chainVariances[index] - W) * (chainMeans[index] * chainMeans[index]
00963 - mean * mean);
00964 cov2 += (chainVariances[index] - W) * (chainMeans[index] - mean);
00965 }
00966
00967
00968 double m = double(fMCMCNChains);
00969
00970
00971 double n = double(nPoints);
00972
00973
00974 varS = (varS / m - W * W) * m / (m - 1);
00975 cov1 = cov1 / (m - 1);
00976 cov2 = cov2 / (m - 1);
00977
00978
00979 double V = 1 / n * ((n - 1) * W + (1 + 1 / m) * B);
00980
00981
00982 double varV = (n - 1) * (n - 1) / (n * n * m) * varS + (m + 1) * (m + 1)
00983 / (m * n * m * n) * 2 / (m - 1) * B * B + 2 * (m + 1) * (n - 1) / (m
00984 * m * n) * (cov1 - 2 * mean * cov2);
00985
00986
00987 double df = 2 * V * V / varV;
00988
00989
00990 r = sqrt(V / W * df / (df - 2));
00991
00992 return r;
00993 }
00994
00995
00996 void BCEngineMCMC::MCMCInChainWriteChains()
00997 {
00998
00999 for (int i = 0; i < fMCMCNChains; ++i)
01000 fMCMCTrees[i]->Fill();
01001 }
01002
01003
01004 double BCEngineMCMC::LogEval(std::vector <double> parameters)
01005 {
01006
01007
01008 return 0.0;
01009 }
01010
01011
01012 int BCEngineMCMC::MCMCMetropolisPreRun()
01013 {
01014
01015 BCLog::OutSummary("Pre-run Metropolis MCMC...");
01016
01017
01018 MCMCInitialize();
01019 MCMCInitializeMarkovChains();
01020
01021
01022 int ndigits = (int)log10(fMCMCNParameters) +1;
01023 if(ndigits<4)
01024 ndigits=4;
01025
01026
01027 MCMCResetRunStatistics();
01028 fMCMCNIterationsConvergenceGlobal = -1;
01029
01030
01031 BCLog::OutSummary(Form(" --> Perform MCMC pre-run with %i chains, each with maximum %i iterations", fMCMCNChains, fMCMCNIterationsMax));
01032
01033
01034
01035 bool tempflag_writetofile = fMCMCFlagWriteChainToFile;
01036 fMCMCFlagWriteChainToFile = false;
01037
01038
01039 fMCMCCurrentIteration = 1;
01040 int counterupdate = 1;
01041 bool convergence = false;
01042 bool flagefficiency = false;
01043
01044
01045 std::vector <double> efficiency;
01046 efficiency.assign(fMCMCNParameters * fMCMCNChains, 0.0);
01047
01048
01049
01050
01051
01052 int updateLimit = ( fMCMCNIterationsUpdateMax<fMCMCNIterationsUpdate*(fMCMCNParameters) && fMCMCNIterationsUpdateMax>0 ) ?
01053 fMCMCNIterationsUpdateMax : fMCMCNIterationsUpdate*(fMCMCNParameters);
01054
01055
01056 for (int ichains = 0; ichains < fMCMCNChains; ++ichains) {
01057
01058 for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter){
01059
01060 int index = ichains * fMCMCNParameters + iparameter;
01061
01062 fMCMCNTrialsTrue[index] = 0;
01063 fMCMCNTrialsFalse[index] = 0;
01064 fMCMCxMean[index] = fMCMCx[index];
01065 fMCMCxVar[index] = 0;
01066 }
01067 fMCMCprobMean[ichains] = fMCMCprob[ichains];
01068 fMCMCprobVar[ichains] = 0;
01069 }
01070
01071
01072 fMCMCPhase = 1;
01073 fMCMCCycle = 0;
01074
01075
01076
01077
01078
01079
01080 while (fMCMCCurrentIteration < fMCMCNIterationsPreRunMin || (fMCMCCurrentIteration < fMCMCNIterationsMax && !(convergence && flagefficiency)))
01081 {
01082
01083
01084
01085
01086
01087 convergence = false;
01088
01089
01090 fMCMCNIterationsConvergenceGlobal = -1;
01091
01092
01093
01094
01095
01096
01097 if (fMCMCFlagOrderParameters)
01098 {
01099
01100 for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01101 {
01102
01103 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01104 MCMCGetNewPointMetropolis(ichains, iparameters);
01105
01106
01107 MCMCInChainCheckMaximum();
01108 }
01109 }
01110
01111
01112 else
01113 {
01114
01115 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01116
01117 MCMCGetNewPointMetropolis(ichains);
01118
01119
01120 MCMCInChainCheckMaximum();
01121 }
01122
01123
01124
01125
01126
01127
01128 if ( fMCMCCurrentIteration > 0 && fMCMCCurrentIteration % fMCMCNIterationsUpdate == 0 )
01129 BCLog::OutDetail(Form(" --> Iteration %i", fMCMCNIterations[0]/fMCMCNParameters));
01130
01131
01132
01133
01134
01135 if (counterupdate > 1)
01136 MCMCInChainUpdateStatistics();
01137
01138
01139
01140
01141
01142
01143
01144 if ( counterupdate % updateLimit == 0 && counterupdate > 0 && fMCMCCurrentIteration >= fMCMCNIterationsPreRunMin)
01145
01146 {
01147
01148
01149
01150
01151 bool rvalues_ok = true;
01152
01153 static bool has_converged = false;
01154
01155
01156
01157 fMCMCNIterationsConvergenceGlobal = -1;
01158
01159
01160
01161
01162
01163
01164 MCMCInChainTestConvergenceAllChains();
01165
01166
01167 if (fMCMCNIterationsConvergenceGlobal > 0)
01168 convergence = true;
01169
01170
01171 if (convergence && fMCMCNChains > 1)
01172 BCLog::OutDetail(Form(" * Convergence status: Set of %i Markov chains converged within %i iterations.", fMCMCNChains, fMCMCNIterationsConvergenceGlobal));
01173 else if (!convergence && fMCMCNChains > 1)
01174 {
01175 BCLog::OutDetail(Form(" * Convergence status: Set of %i Markov chains did not converge after %i iterations.", fMCMCNChains, fMCMCCurrentIteration));
01176
01177 BCLog::OutDetail(" - R-Values:");
01178 for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter)
01179 {
01180 if(fabs(fMCMCRValueParameters[iparameter]-1.) < fMCMCRValueParametersCriterion)
01181 BCLog::OutDetail(Form( TString::Format(" parameter %%%di : %%.06f",ndigits), iparameter, fMCMCRValueParameters.at(iparameter)));
01182 else
01183 {
01184 BCLog::OutDetail(Form( TString::Format(" parameter %%%di : %%.06f <--",ndigits), iparameter, fMCMCRValueParameters.at(iparameter)));
01185 rvalues_ok = false;
01186 }
01187 }
01188 if(fabs(fMCMCRValue-1.) < fMCMCRValueCriterion)
01189 BCLog::OutDetail(Form(" log-likelihood : %.06f", fMCMCRValue));
01190 else
01191 {
01192 BCLog::OutDetail(Form(" log-likelihood : %.06f <--", fMCMCRValue));
01193 rvalues_ok = false;
01194 }
01195 }
01196
01197
01198 if(!has_converged)
01199 if(rvalues_ok)
01200 has_converged = true;
01201
01202
01203
01204
01205
01206
01207 flagefficiency = true;
01208
01209 bool flagprintefficiency = true;
01210
01211
01212 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01213 {
01214
01215 for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter)
01216 {
01217
01218 int index = ichains * fMCMCNParameters + iparameter;
01219
01220
01221 efficiency[index] = double(fMCMCNTrialsTrue[index]) / double(fMCMCNTrialsTrue[index] + fMCMCNTrialsFalse[index]);
01222
01223
01224 if (efficiency[index] < fMCMCEfficiencyMin && fMCMCTrialFunctionScaleFactor[index] > .01)
01225 {
01226 if (flagprintefficiency)
01227 {
01228 BCLog::OutDetail(Form(" * Efficiency status: Efficiencies not within pre-defined range."));
01229 BCLog::OutDetail(Form(" - Efficiencies:"));
01230 flagprintefficiency = false;
01231 }
01232
01233 double fscale=2.;
01234 if(has_converged && fMCMCEfficiencyMin/efficiency[index] > 2.)
01235 fscale = 4.;
01236 fMCMCTrialFunctionScaleFactor[index] /= fscale;
01237
01238 BCLog::OutDetail(Form(" Efficiency of parameter %i dropped below %.2lf%% (eps = %.2lf%%) in chain %i. Set scale to %.4g",
01239 iparameter, 100. * fMCMCEfficiencyMin, 100. * efficiency[index], ichains, fMCMCTrialFunctionScaleFactor[index]));
01240 }
01241
01242
01243 else if (efficiency[index] > fMCMCEfficiencyMax && fMCMCTrialFunctionScaleFactor[index] < 1.0)
01244 {
01245 if (flagprintefficiency)
01246 {
01247 BCLog::OutDetail(Form(" * Efficiency status: Efficiencies not within pre-defined ranges."));
01248 BCLog::OutDetail(Form(" - Efficiencies:"));
01249 flagprintefficiency = false;
01250 }
01251
01252 fMCMCTrialFunctionScaleFactor[index] *= 2.;
01253
01254 BCLog::OutDetail(Form(" Efficiency of parameter %i above %.2lf%% (eps = %.2lf%%) in chain %i. Set scale to %.4g",
01255 iparameter, 100.0 * fMCMCEfficiencyMax, 100.0 * efficiency[index], ichains, fMCMCTrialFunctionScaleFactor[index]));
01256 }
01257
01258
01259 if ((efficiency[index] < fMCMCEfficiencyMin && fMCMCTrialFunctionScaleFactor[index] > .01)
01260 || (efficiency[index] > fMCMCEfficiencyMax && fMCMCTrialFunctionScaleFactor[index] < 1.))
01261 flagefficiency = false;
01262 }
01263 }
01264
01265
01266 if (flagefficiency)
01267 BCLog::OutDetail(Form(" * Efficiency status: Efficiencies within pre-defined ranges."));
01268
01269
01270
01271
01272
01273 counterupdate = 0;
01274
01275
01276 for (int ichains = 0; ichains < fMCMCNChains; ++ichains) {
01277
01278 for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter){
01279
01280 int index = ichains * fMCMCNParameters + iparameter;
01281
01282 fMCMCNTrialsTrue[index] = 0;
01283 fMCMCNTrialsFalse[index] = 0;
01284 fMCMCxMean[index] = fMCMCx[index];
01285 fMCMCxVar[index] = 0;
01286 }
01287 fMCMCprobMean[ichains] = fMCMCprob[ichains];
01288 fMCMCprobVar[ichains] = 0;
01289 }
01290 }
01291
01292
01293
01294
01295
01296
01297 if (fMCMCFlagWritePreRunToFile)
01298 MCMCInChainWriteChains();
01299
01300
01301
01302
01303
01304 if (counterupdate == 0 && fMCMCCurrentIteration > 1)
01305 fMCMCCycle++;
01306 fMCMCCurrentIteration++;
01307 counterupdate++;
01308
01309 }
01310
01311
01312
01313
01314
01315
01316 if (fMCMCCurrentIteration<updateLimit)
01317 {
01318 BCLog::OutWarning(" Convergence never checked !");
01319 BCLog::OutWarning(" Increase maximum number of iterations in the pre-run /MCMCSetNIterationsMax()/");
01320 BCLog::OutWarning(" or decrease maximum number of iterations for update /MCMCSetNIterationsUpdateMax()/");
01321 }
01322
01323
01324
01325
01326
01327
01328 if (fMCMCNIterationsConvergenceGlobal > 0)
01329 fMCMCFlagConvergenceGlobal = true;
01330 else
01331 fMCMCFlagConvergenceGlobal = false;
01332
01333
01334 if (fMCMCFlagConvergenceGlobal && fMCMCNChains > 1 && !flagefficiency)
01335 BCLog::OutSummary(Form(" --> Set of %i Markov chains converged within %i iterations but could not adjust scales.", fMCMCNChains, fMCMCNIterationsConvergenceGlobal));
01336
01337 else if (fMCMCFlagConvergenceGlobal && fMCMCNChains > 1 && flagefficiency)
01338 BCLog::OutSummary(Form(" --> Set of %i Markov chains converged within %i iterations and all scales are adjusted.", fMCMCNChains, fMCMCNIterationsConvergenceGlobal));
01339
01340 else if (!fMCMCFlagConvergenceGlobal && (fMCMCNChains > 1) && flagefficiency)
01341 BCLog::OutSummary(Form(" --> Set of %i Markov chains did not converge within %i iterations.", fMCMCNChains, fMCMCNIterationsMax));
01342
01343 else if (!fMCMCFlagConvergenceGlobal && (fMCMCNChains > 1) && !flagefficiency)
01344 BCLog::OutSummary(Form(" --> Set of %i Markov chains did not converge within %i iterations and could not adjust scales.", fMCMCNChains, fMCMCNIterationsMax));
01345
01346 else if(fMCMCNChains == 1)
01347 BCLog::OutSummary(" --> No convergence criterion for a single chain defined.");
01348
01349 else
01350 BCLog::OutSummary(" --> Only one Markov chain. No global convergence criterion defined.");
01351
01352 BCLog::OutSummary(Form(" --> Markov chains ran for %i iterations.", fMCMCCurrentIteration));
01353
01354
01355
01356 std::vector <double> efficiencies;
01357
01358 for (int i = 0; i < fMCMCNParameters; ++i)
01359 efficiencies.push_back(0.);
01360
01361 BCLog::OutDetail(" --> Average efficiencies:");
01362 for (int i = 0; i < fMCMCNParameters; ++i)
01363 {
01364 for (int j = 0; j < fMCMCNChains; ++j)
01365 efficiencies[i] += efficiency[j * fMCMCNParameters + i] / double(fMCMCNChains);
01366
01367 BCLog::OutDetail(Form(TString::Format(" --> parameter %%%di : %%.02f%%%%",ndigits), i, 100. * efficiencies[i]));
01368 }
01369
01370
01371
01372 std::vector <double> scalefactors;
01373
01374 for (int i = 0; i < fMCMCNParameters; ++i)
01375 scalefactors.push_back(0.0);
01376
01377 BCLog::OutDetail(" --> Average scale factors:");
01378 for (int i = 0; i < fMCMCNParameters; ++i)
01379 {
01380 for (int j = 0; j < fMCMCNChains; ++j)
01381 scalefactors[i] += fMCMCTrialFunctionScaleFactor[j * fMCMCNParameters + i] / double(fMCMCNChains);
01382
01383 BCLog::OutDetail(Form( TString::Format(" --> parameter %%%di : %%.02f%%%%",ndigits), i, 100. * scalefactors[i]));
01384 }
01385
01386
01387 fMCMCFlagWriteChainToFile = tempflag_writetofile;
01388
01389
01390 fMCMCCurrentIteration = -1;
01391
01392
01393 fMCMCCurrentChain = -1;
01394
01395
01396 return 1;
01397 }
01398
01399
01400 int BCEngineMCMC::MCMCMetropolis()
01401 {
01402
01403 if (fMCMCFlagPreRun)
01404 MCMCMetropolisPreRun();
01405 else
01406 BCLog::OutWarning("BCEngineMCMC::MCMCMetropolis. Not running prerun. This can cause trouble if the data have changed.");
01407
01408
01409 BCLog::OutSummary( "Run Metropolis MCMC...");
01410
01411
01412 MCMCResetRunStatistics();
01413
01414
01415 fMCMCPhase = 2;
01416 fMCMCCycle = 0;
01417
01418
01419 BCLog::OutSummary(Form(" --> Perform MCMC run with %i chains, each with %i iterations.", fMCMCNChains, fMCMCNIterationsRun));
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431 int nwrite = fMCMCNIterationsRun/10;
01432 if(nwrite < 100)
01433 nwrite=100;
01434 else if(nwrite < 500)
01435 nwrite=1000;
01436 else if(nwrite < 10000)
01437 nwrite=1000;
01438 else
01439 nwrite=10000;
01440
01441
01442 for (fMCMCCurrentIteration = 1; fMCMCCurrentIteration <= fMCMCNIterationsRun; ++fMCMCCurrentIteration)
01443 {
01444 if ( (fMCMCCurrentIteration)%nwrite == 0 )
01445 BCLog::OutDetail(Form(" --> iteration number %i (%.2f%%)", fMCMCCurrentIteration, (double)(fMCMCCurrentIteration)/(double)fMCMCNIterationsRun*100.));
01446
01447
01448 if (fMCMCFlagOrderParameters)
01449 {
01450
01451 for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01452 {
01453
01454 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01455 MCMCGetNewPointMetropolis(ichains, iparameters);
01456
01457
01458 fMCMCCurrentChain = -1;
01459
01460
01461 MCMCInChainCheckMaximum();
01462
01463 }
01464
01465
01466 if ( fMCMCCurrentIteration % fMCMCNLag == 0)
01467 {
01468
01469 MCMCInChainFillHistograms();
01470
01471
01472 if (fMCMCFlagWriteChainToFile)
01473 MCMCInChainWriteChains();
01474
01475
01476 MCMCIterationInterface();
01477 }
01478 }
01479
01480 else
01481 {
01482
01483 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01484
01485 MCMCGetNewPointMetropolis(ichains);
01486
01487
01488 fMCMCCurrentChain = -1;
01489
01490
01491 MCMCInChainCheckMaximum();
01492
01493
01494 if (fMCMCCurrentIteration % fMCMCNLag == 0)
01495 {
01496
01497 MCMCInChainFillHistograms();
01498
01499
01500 if (fMCMCFlagWriteChainToFile)
01501 MCMCInChainWriteChains();
01502
01503
01504 MCMCIterationInterface();
01505 }
01506 }
01507
01508 }
01509
01510
01511 BCLog::OutSummary(Form(" --> Markov chains ran for %i iterations.", fMCMCNIterationsRun));
01512
01513
01514
01515
01516 double probmax = fMCMCprobMax.at(0);
01517 int probmaxindex = 0;
01518
01519
01520 for (int i = 1; i < fMCMCNChains; ++i) {
01521 if (fMCMCprobMax.at(i) > probmax)
01522 {
01523 probmax = fMCMCprobMax.at(i);
01524 probmaxindex = i;
01525 }
01526 }
01527
01528 BCLog::OutDetail(" --> Global mode from MCMC:");
01529 BCLog::OutDebug(Form(" --> Posterior value: %g", probmax));
01530 int ndigits = (int) log10(fMCMCNParameters);
01531 for (int i = 0; i < fMCMCNParameters; ++i)
01532 BCLog::OutDetail(Form( TString::Format(" --> parameter %%%di: %%.4g", ndigits+1),
01533 i, fMCMCxMax[probmaxindex * fMCMCNParameters + i]));
01534
01535
01536 fMCMCCurrentIteration = -1;
01537
01538
01539 fMCMCCurrentChain = -1;
01540
01541
01542 fMCMCFlagRun = true;
01543
01544 return 1;
01545 }
01546
01547
01548 void BCEngineMCMC::MCMCResetRunStatistics()
01549 {
01550 for (int j = 0; j < fMCMCNChains; ++j)
01551 {
01552 fMCMCNIterations[j] = 0;
01553 fMCMCNTrialsTrue[j] = 0;
01554 fMCMCNTrialsFalse[j] = 0;
01555 fMCMCprobMean[j] = 0;
01556 fMCMCprobVar[j] = 0;
01557
01558 for (int k = 0; k < fMCMCNParameters; ++k)
01559 {
01560 fMCMCNTrialsTrue[j * fMCMCNParameters + k] = 0;
01561 fMCMCNTrialsFalse[j * fMCMCNParameters + k] = 0;
01562 }
01563 }
01564
01565
01566 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
01567 if (fMCMCH1Marginalized[i])
01568 fMCMCH1Marginalized[i]->Reset();
01569
01570 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
01571 if (fMCMCH2Marginalized[i])
01572 fMCMCH2Marginalized[i]->Reset();
01573
01574 fMCMCRValue = 100;
01575 }
01576
01577
01578 int BCEngineMCMC::MCMCAddParameter(double min, double max)
01579 {
01580
01581 fMCMCBoundaryMin.push_back(min);
01582 fMCMCBoundaryMax.push_back(max);
01583
01584
01585 fMCMCFlagsFillHistograms.push_back(true);
01586
01587
01588 fMCMCNParameters++;
01589
01590
01591 return fMCMCNParameters;
01592 }
01593
01594
01595 void BCEngineMCMC::MCMCInitializeMarkovChains()
01596 {
01597
01598 std::vector <double> x0;
01599
01600 for (int j = 0; j < fMCMCNChains; ++j)
01601 {
01602 x0.clear();
01603 for (int i = 0; i < fMCMCNParameters; ++i)
01604 x0.push_back(fMCMCx[j * fMCMCNParameters + i]);
01605 fMCMCprob[j] = LogEval(x0);
01606 }
01607
01608 x0.clear();
01609 }
01610
01611
01612 int BCEngineMCMC::MCMCResetResults()
01613 {
01614
01615 fMCMCNIterations.clear();
01616 fMCMCNTrialsTrue.clear();
01617 fMCMCNTrialsFalse.clear();
01618 fMCMCTrialFunctionScaleFactor.clear();
01619 fMCMCprobMean.clear();
01620 fMCMCprobVar.clear();
01621 fMCMCxMean.clear();
01622 fMCMCxVar.clear();
01623 fMCMCx.clear();
01624 fMCMCprob.clear();
01625 fMCMCxMax.clear();
01626 fMCMCprobMax.clear();
01627 fMCMCNIterationsConvergenceGlobal = -1;
01628 fMCMCRValueParameters.clear();
01629
01630 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
01631 if (fMCMCH1Marginalized[i])
01632 delete fMCMCH1Marginalized[i];
01633
01634 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
01635 if (fMCMCH2Marginalized[i])
01636 delete fMCMCH2Marginalized[i];
01637
01638
01639 fMCMCH1Marginalized.clear();
01640 fMCMCH2Marginalized.clear();
01641
01642
01643 fMCMCFlagPreRun = true;
01644 fMCMCFlagRun = false;
01645 fMCMCFlagConvergenceGlobal = false;
01646
01647
01648 return 1;
01649 }
01650
01651
01652 int BCEngineMCMC::MCMCInitialize()
01653 {
01654
01655 MCMCResetResults();
01656
01657
01658 fMCMCNIterations.assign(fMCMCNChains, 0);
01659 fMCMCprobMean.assign(fMCMCNChains, 0);
01660 fMCMCprobVar.assign(fMCMCNChains, 0);
01661 fMCMCprob.assign(fMCMCNChains, -1.0);
01662 fMCMCprobMax.assign(fMCMCNChains, -1.0);
01663
01664 fMCMCNTrialsTrue.assign(fMCMCNChains * fMCMCNParameters, 0);
01665 fMCMCNTrialsFalse.assign(fMCMCNChains * fMCMCNParameters, 0);
01666 fMCMCxMax.assign(fMCMCNChains * fMCMCNParameters, 0.);
01667 fMCMCxMean.assign(fMCMCNChains * fMCMCNParameters, 0);
01668 fMCMCxVar.assign(fMCMCNChains * fMCMCNParameters, 0);
01669
01670 fMCMCRValueParameters.assign(fMCMCNParameters, 0.);
01671
01672 if (fMCMCTrialFunctionScaleFactorStart.size() == 0)
01673 fMCMCTrialFunctionScaleFactor.assign(fMCMCNChains * fMCMCNParameters, 1.0);
01674 else
01675 for (int i = 0; i < fMCMCNChains; ++i)
01676 for (int j = 0; j < fMCMCNParameters; ++j)
01677 fMCMCTrialFunctionScaleFactor.push_back(fMCMCTrialFunctionScaleFactorStart.at(j));
01678
01679
01680 if (fMCMCFlagInitialPosition == 2)
01681 {
01682
01683 bool flag = true;
01684
01685
01686 if (int(fMCMCInitialPosition.size()) != (fMCMCNChains * fMCMCNParameters))
01687 {
01688 BCLog::OutError("BCEngine::MCMCInitialize : Length of vector containing initial positions does not have required length.");
01689 flag = false;
01690 }
01691
01692
01693 if (flag)
01694 {
01695 for (int j = 0; j < fMCMCNChains; ++j)
01696 for (int i = 0; i < fMCMCNParameters; ++i)
01697 if (fMCMCInitialPosition[j * fMCMCNParameters + i] < fMCMCBoundaryMin[i] ||
01698 fMCMCInitialPosition[j * fMCMCNParameters + i] > fMCMCBoundaryMax[i])
01699 {
01700 BCLog::OutError("BCEngine::MCMCInitialize : Initial position out of boundaries.");
01701 flag = false;
01702 }
01703 }
01704
01705
01706 if (!flag)
01707 fMCMCFlagInitialPosition = 1;
01708 }
01709
01710 if (fMCMCFlagInitialPosition == 0)
01711 for (int j = 0; j < fMCMCNChains; ++j)
01712 for (int i = 0; i < fMCMCNParameters; ++i)
01713 fMCMCx.push_back(fMCMCBoundaryMin[i] + .5 * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
01714
01715 else if (fMCMCFlagInitialPosition == 2)
01716 {
01717 for (int j = 0; j < fMCMCNChains; ++j)
01718 for (int i = 0; i < fMCMCNParameters; ++i)
01719 fMCMCx.push_back(fMCMCInitialPosition.at(j * fMCMCNParameters + i));
01720 }
01721
01722 else
01723 for (int j = 0; j < fMCMCNChains; ++j)
01724 for (int i = 0; i < fMCMCNParameters; ++i)
01725 fMCMCx.push_back(fMCMCBoundaryMin[i] + fRandom->Rndm() * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
01726
01727
01728 fMCMCxLocal.clear();
01729 for (int i = 0; i < fMCMCNParameters; ++i)
01730 fMCMCxLocal.push_back(fMCMCx[i]);
01731
01732
01733 for(int i = 0; i < fMCMCNParameters; ++i)
01734 {
01735 TH1D * h1 = 0;
01736 if (fMCMCFlagsFillHistograms.at(i))
01737 h1 = new TH1D(TString::Format("h1_%d_parameter_%i", BCLog::GetHIndex() ,i), "",
01738 fMCMCH1NBins[i], fMCMCBoundaryMin[i], fMCMCBoundaryMax[i]);
01739 fMCMCH1Marginalized.push_back(h1);
01740 }
01741
01742 for(int i = 0; i < fMCMCNParameters; ++i)
01743 for (int k = 0; k < i; ++k)
01744 {
01745 TH2D * h2 = 0;
01746 if (fMCMCFlagsFillHistograms.at(i) && fMCMCFlagsFillHistograms.at(k))
01747 h2 = new TH2D(Form("h2_%d_parameters_%i_vs_%i", BCLog::GetHIndex(), i, k), "",
01748 fMCMCH1NBins[k], fMCMCBoundaryMin[k], fMCMCBoundaryMax[k],
01749 fMCMCH1NBins[i], fMCMCBoundaryMin[i], fMCMCBoundaryMax[i] );
01750 fMCMCH2Marginalized.push_back(h2);
01751 }
01752
01753 return 1;
01754 }
01755
01756
01757 int BCEngineMCMC::SetMarginalized(int index, TH1D * h)
01758 {
01759 if((int)fMCMCH1Marginalized.size()<=index)
01760 return 0;
01761
01762 if(h==0)
01763 return 0;
01764
01765 if((int)fMCMCH1Marginalized.size()==index)
01766 fMCMCH1Marginalized.push_back(h);
01767 else
01768 fMCMCH1Marginalized[index]=h;
01769
01770 return index;
01771 }
01772
01773
01774 int BCEngineMCMC::SetMarginalized(int index1, int index2, TH2D * h)
01775 {
01776 int counter = 0;
01777 int index = 0;
01778
01779
01780 for(int i = 0; i < fMCMCNParameters; i++)
01781 for (int j = 0; j < i; ++j)
01782 {
01783 if(j == index1 && i == index2)
01784 index = counter;
01785 counter++;
01786 }
01787
01788 if((int)fMCMCH2Marginalized.size()<=index)
01789 return 0;
01790
01791 if(h==0)
01792 return 0;
01793
01794 if((int)fMCMCH2Marginalized.size()==index)
01795 fMCMCH2Marginalized.push_back(h);
01796 else
01797 fMCMCH2Marginalized[index]=h;
01798
01799 return index;
01800 }
01801
01802
01803