00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "BCEngineMCMC.h"
00011 #include "BCLog.h"
00012
00013 #define DEBUG 0
00014
00015
00016
00017 BCEngineMCMC::BCEngineMCMC()
00018 {
00019
00020
00021
00022 fMCMCNParameters = 0;
00023 fMCMCNChains = 5;
00024 fMCMCNIterationsMax = 1000000;
00025 fMCMCNIterationsRun = 100000;
00026 fMCMCNIterationsBurnIn = 0;
00027 fMCMCNIterationsPCA = 10000;
00028 fMCMCNIterationsPreRunMin = 500;
00029 fMCMCFlagIterationsAuto = false;
00030 fMCMCTrialFunctionScale = 1.0;
00031 fMCMCFlagInitialPosition = 1;
00032 fMCMCRValueCriterion = 0.1;
00033 fMCMCRValueParametersCriterion = 0.1;
00034 fMCMCNIterationsConvergenceGlobal = -1;
00035 fMCMCFlagConvergenceGlobal = false;
00036 fMCMCRValue = 100;
00037 fMCMCFlagPCA = false;
00038 fMCMCSimulatedAnnealingT0 = 100;
00039 fMCMCH1NBins = 100;
00040 fMCMCH2NBinsX = 100;
00041 fMCMCH2NBinsY = 100;
00042 fMCMCFlagPCATruncate = false;
00043 fMCMCPCA = 0;
00044 fMCMCPCAMinimumRatio = 1e-7;
00045 fMCMCNIterationsUpdate = 1000;
00046 fMCMCFlagWriteChainToFile = false;
00047 fMCMCFlagPreRun = false;
00048 fMCMCEfficiencyMin = 0.15;
00049 fMCMCEfficiencyMax = 0.50;
00050
00051
00052
00053
00054
00055 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
00056 fMCMCH1Marginalized[i] = 0;
00057
00058 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
00059 fMCMCH2Marginalized[i] = 0;
00060
00061
00062
00063
00064
00065
00066 fMCMCRandom = new TRandom3(0);
00067
00068
00069
00070 this -> MCMCInitialize();
00071
00072 }
00073
00074
00075
00076 BCEngineMCMC::BCEngineMCMC(int n)
00077 {
00078
00079
00080
00081 fMCMCNChains = n;
00082
00083
00084
00085 BCEngineMCMC();
00086
00087 }
00088
00089
00090
00091 BCEngineMCMC::~BCEngineMCMC()
00092 {
00093
00094
00095
00096 if (fMCMCRandom)
00097 delete fMCMCRandom;
00098
00099
00100
00101 if (fMCMCPCA)
00102 delete fMCMCPCA;
00103
00104
00105
00106 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
00107 if (fMCMCH1Marginalized[i])
00108 delete fMCMCH1Marginalized[i];
00109
00110 fMCMCH1Marginalized.clear();
00111
00112 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
00113 if (fMCMCH2Marginalized[i])
00114 delete fMCMCH2Marginalized[i];
00115
00116 fMCMCH2Marginalized.clear();
00117
00118
00119
00120
00121
00122
00123
00124 }
00125
00126
00127
00128 BCEngineMCMC::BCEngineMCMC(const BCEngineMCMC & enginemcmc)
00129 {
00130
00131 enginemcmc.Copy(*this);
00132
00133 }
00134
00135
00136
00137 BCEngineMCMC & BCEngineMCMC::operator = (const BCEngineMCMC & enginemcmc)
00138 {
00139
00140 if (this != &enginemcmc)
00141 enginemcmc.Copy(* this);
00142
00143 return * this;
00144
00145 }
00146
00147
00148
00149 TH2D * BCEngineMCMC::MCMCGetH2Marginalized(int index1, int index2)
00150 {
00151
00152 int counter = 0;
00153 int index = 0;
00154
00155
00156
00157 for(int i = 0; i < fMCMCNParameters; i++)
00158 for (int j = 0; j < i; ++j)
00159 {
00160 if(j == index1 && i == index2)
00161 index = counter;
00162 counter++;
00163 }
00164
00165 return fMCMCH2Marginalized[index];
00166
00167 }
00168
00169
00170
00171 std::vector <double> BCEngineMCMC::MCMCGetMaximumPoint(int i)
00172 {
00173
00174
00175
00176 std::vector <double> x;
00177
00178
00179
00180 if (i < 0 || i >= fMCMCNChains)
00181 return x;
00182
00183
00184
00185 for (int j = 0; j < fMCMCNParameters; ++j)
00186 x.push_back(fMCMCMaximumPoints.at(i * fMCMCNParameters + j));
00187
00188 return x;
00189
00190 }
00191
00192
00193
00194 void BCEngineMCMC::MCMCSetNChains(int n)
00195 {
00196
00197 fMCMCNChains = n;
00198
00199
00200
00201 this -> MCMCInitialize();
00202
00203 }
00204
00205
00206
00207 void BCEngineMCMC::MCMCSetInitialPosition(int chain, std::vector<double> x0)
00208 {
00209
00210
00211
00212 if (chain >= fMCMCNChains)
00213 {
00214 fMCMCInitialPosition.clear();
00215
00216 return;
00217 }
00218
00219 if (int(x0.size()) == fMCMCNParameters)
00220 {
00221 fMCMCInitialPosition.clear();
00222 for (int j = 0; j < fMCMCNChains; ++j)
00223 for (int i = 0; i < fMCMCNParameters; ++i)
00224 fMCMCInitialPosition.push_back(x0.at(i));
00225 }
00226
00227 else
00228 return;
00229
00230 bool flagin = true;
00231
00232 for (int j = 0; j < fMCMCNChains; ++j)
00233 for (int i = 0; i < fMCMCNParameters; ++i)
00234 if (fMCMCInitialPosition[j * fMCMCNParameters + i] < fMCMCBoundaryMin[i] ||
00235 fMCMCInitialPosition[j * fMCMCNParameters + i] > fMCMCBoundaryMax[i])
00236 flagin = false;
00237
00238 if (flagin == false)
00239 {
00240 fMCMCInitialPosition.clear();
00241
00242 return;
00243 }
00244
00245
00246
00247 else
00248 {
00249 for (int i = 0; i < fMCMCNParameters; ++i)
00250 fMCMCInitialPosition[chain * fMCMCNParameters + i] = x0.at(i);
00251 }
00252
00253
00254
00255 this -> MCMCSetFlagInitialPosition(2);
00256
00257 }
00258
00259
00260
00261 void BCEngineMCMC::MCMCSetInitialPosition(std::vector<double> x0)
00262 {
00263
00264 for (int i = 0; i < fMCMCNChains; ++i)
00265 this -> MCMCSetInitialPosition(i, x0);
00266
00267 }
00268
00269
00270
00271 void BCEngineMCMC::MCMCSetInitialPositions(std::vector<double> x0s)
00272 {
00273
00274 if (int(fMCMCInitialPosition.size()) != (fMCMCNChains * fMCMCNParameters))
00275 return;
00276
00277 if (int(x0s.size()) != (fMCMCNChains * fMCMCNParameters))
00278 return;
00279
00280
00281
00282 for (int i = 0; i < (fMCMCNChains * fMCMCNParameters); ++i)
00283 fMCMCInitialPosition[i] = x0s.at(i);
00284
00285
00286
00287 this -> MCMCSetFlagInitialPosition(2);
00288
00289 }
00290
00291
00292
00293 void BCEngineMCMC::MCMCSetMarkovChainTrees(std::vector <TTree *> trees)
00294 {
00295
00296
00297
00298 fMCMCTrees.clear();
00299
00300
00301
00302 for (int i = 0; i < int(trees.size()); ++i)
00303 fMCMCTrees.push_back(trees[i]);
00304
00305 }
00306
00307
00308
00309 void BCEngineMCMC::MCMCUserInterface()
00310 {
00311
00312
00313
00314 }
00315
00316
00317
00318 void BCEngineMCMC::Copy(BCEngineMCMC & enginemcmc) const
00319 {
00320
00321 }
00322
00323
00324
00325 void BCEngineMCMC::MCMCTrialFunction(std::vector <double> &x)
00326 {
00327
00328
00329
00330 for (int i = 0; i < fMCMCNParameters; ++i)
00331 x[i] = fMCMCTrialFunctionScale * 2.0 * (0.5 - fMCMCRandom -> Rndm());
00332
00333 }
00334
00335
00336
00337 void BCEngineMCMC::MCMCTrialFunctionSingle(int ichain, int iparameter, std::vector <double> &x)
00338 {
00339
00340
00341
00342
00343
00344 x[iparameter] = fMCMCTrialFunctionScaleFactor[ichain * fMCMCNParameters + iparameter] * 2.0 * (0.5 - fMCMCRandom -> Rndm());
00345
00346 }
00347
00348
00349
00350 double BCEngineMCMC::MCMCTrialFunctionIndependent(std::vector <double> &xnew, std::vector <double> &xold, bool newpoint)
00351 {
00352
00353
00354
00355 if (newpoint)
00356 for (int i = 0; i < fMCMCNParameters; ++i)
00357 xnew[i] = fMCMCRandom -> Rndm()* (fMCMCBoundaryMax.at(i) - fMCMCBoundaryMin.at(i));
00358
00359 double prob = 1.0;
00360 for (int i = 0; i < fMCMCNParameters; ++i)
00361 prob *= 1.0 / (fMCMCBoundaryMax.at(i) - fMCMCBoundaryMin.at(i));
00362
00363 return prob;
00364
00365 }
00366
00367
00368
00369 void BCEngineMCMC::MCMCTrialFunctionAuto(std::vector <double> &x)
00370 {
00371
00372
00373 for (int i = 0; i < fMCMCNParameters; ++i)
00374 x[i] = fMCMCRandom -> Gaus(fMCMCPCAMean[i], sqrt(fMCMCPCAVariance[i]));
00375
00376 }
00377
00378
00379
00380 std::vector <double> BCEngineMCMC::MCMCGetTrialFunctionScaleFactor(int i)
00381 {
00382
00383
00384 std::vector <double> x;
00385
00386
00387 if (i < 0 || i >= fMCMCNChains)
00388 return x;
00389
00390
00391 for (int j = 0; j < fMCMCNParameters; ++j)
00392 x.push_back(fMCMCTrialFunctionScaleFactor.at(i * fMCMCNParameters + j));
00393
00394 return x;
00395
00396 }
00397
00398
00399
00400 double BCEngineMCMC::MCMCGetTrialFunctionScaleFactor(int i, int j)
00401 {
00402
00403
00404 if (i < 0 || i >= fMCMCNChains)
00405 return 0;
00406
00407
00408 if (j < 0 || j >= fMCMCNParameters)
00409 return 0;
00410
00411
00412 return fMCMCTrialFunctionScaleFactor.at(i * fMCMCNChains +j);
00413
00414 }
00415
00416
00417
00418 std::vector <double> BCEngineMCMC::MCMCGetx(int i)
00419 {
00420
00421
00422
00423 std::vector <double> x;
00424
00425
00426
00427 if (i < 0 || i >= fMCMCNChains)
00428 return x;
00429
00430
00431
00432 for (int j = 0; j < fMCMCNParameters; ++j)
00433 x.push_back(fMCMCx.at(i * fMCMCNParameters + j));
00434
00435 return x;
00436
00437 }
00438
00439
00440
00441 double BCEngineMCMC::MCMCGetx(int i, int j)
00442 {
00443
00444
00445
00446 if (i < 0 || i >= fMCMCNChains)
00447 return 0;
00448
00449
00450
00451 if (j < 0 || j >= fMCMCNParameters)
00452 return 0;
00453
00454
00455
00456 return fMCMCx.at(i * fMCMCNParameters + j);
00457
00458 }
00459
00460
00461
00462 double BCEngineMCMC::MCMCGetLogProbx(int i)
00463 {
00464
00465
00466
00467 if (i < 0 || i >= fMCMCNChains)
00468 return -1;
00469
00470
00471
00472 return fMCMCLogProbx.at(i);
00473
00474 }
00475
00476
00477
00478 bool BCEngineMCMC::MCMCGetProposalPointMetropolis(int chain, std::vector <double> &x, bool pca)
00479 {
00480
00481
00482
00483
00484 this -> MCMCTrialFunction(x);
00485
00486
00487
00488 if (pca == false)
00489 {
00490
00491
00492 for (int i = 0; i < fMCMCNParameters; ++i)
00493 x[i] = fMCMCx[chain * fMCMCNParameters + i] + x[i] * (fMCMCBoundaryMax.at(i) - fMCMCBoundaryMin.at(i));
00494 }
00495
00496 else
00497 {
00498
00499
00500 double * newp = new double[fMCMCNParameters];
00501 double * newx = new double[fMCMCNParameters];
00502
00503 for (int i = 0; i < fMCMCNParameters; i++)
00504 {
00505 newp[i] = 0.0;
00506 newx[i] = 0.0;
00507 }
00508
00509
00510
00511 this -> MCMCTrialFunctionAuto(x);
00512
00513
00514
00515 for (int i = 0; i < fMCMCNParameters; i++)
00516 newx[i] = fMCMCx[chain * fMCMCNParameters + i];
00517
00518
00519
00520 fMCMCPCA -> X2P(newx, newp);
00521
00522
00523
00524 for (int i = 0; i < fMCMCNParameters; i++)
00525 newp[i] += fMCMCTrialFunctionScale * x[i];
00526
00527
00528
00529
00530 fMCMCPCA -> P2X(newp, newx, fMCMCNDimensionsPCA);
00531
00532
00533
00534 for (int i = 0; i < fMCMCNParameters; ++i)
00535 x[i] = newx[i];
00536
00537 delete [] newp;
00538 delete [] newx;
00539 }
00540
00541
00542
00543 for (int i = 0; i < fMCMCNParameters; ++i)
00544 if ((x[i] < fMCMCBoundaryMin[i]) || (x[i] > fMCMCBoundaryMax[i]))
00545 return false;
00546
00547 return true;
00548
00549 }
00550
00551
00552 bool BCEngineMCMC::MCMCGetProposalPointMetropolis(int chain, int parameter, std::vector <double> &x, bool pca)
00553 {
00554
00555
00556
00557
00558 this -> MCMCTrialFunctionSingle(chain, parameter, x);
00559
00560
00561
00562 if (pca == false)
00563 {
00564
00565
00566 for (int i = 0; i < fMCMCNParameters; ++i)
00567 if (i != parameter)
00568 x[i] = fMCMCx[chain * fMCMCNParameters + i];
00569
00570
00571
00572 x[parameter] = fMCMCx[chain * fMCMCNParameters + parameter] + x[parameter] * (fMCMCBoundaryMax.at(parameter) - fMCMCBoundaryMin.at(parameter));
00573 }
00574
00575 else
00576 {
00577
00578
00579 double * newp = new double[fMCMCNParameters];
00580 double * newx = new double[fMCMCNParameters];
00581
00582 for (int i = 0; i < fMCMCNParameters; i++)
00583 {
00584 newp[i] = 0.0;
00585 newx[i] = 0.0;
00586 }
00587
00588
00589
00590 for (int i = 0; i < fMCMCNParameters; i++)
00591 newx[i] = fMCMCx[chain * fMCMCNParameters + i];
00592
00593
00594
00595 fMCMCPCA -> X2P(newx, newp);
00596
00597
00598
00599 newp[parameter] += x[parameter] * sqrt(fMCMCPCAVariance[parameter]);
00600
00601
00602
00603
00604 fMCMCPCA -> P2X(newp, newx, fMCMCNDimensionsPCA);
00605
00606
00607
00608 for (int i = 0; i < fMCMCNParameters; ++i)
00609 x[i] = newx[i];
00610
00611 delete [] newp;
00612 delete [] newx;
00613 }
00614
00615
00616 for (int i = 0; i < fMCMCNParameters; ++i)
00617 if ((x[i] < fMCMCBoundaryMin[i]) || (x[i] > fMCMCBoundaryMax[i]))
00618 return false;
00619
00620 return true;
00621
00622 }
00623
00624
00625
00626 bool BCEngineMCMC::MCMCGetProposalPointMetropolisHastings(int chain, std::vector <double> &xnew, std::vector <double> &xold)
00627 {
00628
00629
00630
00631 this -> MCMCTrialFunctionIndependent(xnew, xold, true);
00632
00633
00634
00635 for (int i = 0; i < fMCMCNParameters; ++i)
00636 if ((xnew[i] < fMCMCBoundaryMin[i]) || (xnew[i] > fMCMCBoundaryMax[i]))
00637 return false;
00638
00639 return true;
00640
00641 }
00642
00643
00644
00645 void BCEngineMCMC::MCMCGetNewPointPCA()
00646 {
00647
00648
00649
00650 for (int i = 0; i < fMCMCNParameters; ++i)
00651 fMCMCx[i] = fMCMCBoundaryMin.at(i) + (fMCMCBoundaryMax.at(i) - fMCMCBoundaryMin.at(i)) * 2.0 * (0.5 - fMCMCRandom -> Rndm());
00652
00653 }
00654
00655
00656
00657 bool BCEngineMCMC::MCMCGetNewPointMetropolis(int chain, int parameter, bool pca)
00658 {
00659
00660
00661
00662 int index = chain * fMCMCNParameters;
00663
00664
00665
00666 int counter = 0;
00667
00668 while (!this -> MCMCGetProposalPointMetropolis(chain, parameter, fMCMCxLocal, pca) && counter < 1000)
00669 counter++;
00670
00671
00672
00673 double p0 = fMCMCLogProbx[chain];
00674 double p1 = this -> LogEval(fMCMCxLocal);
00675
00676
00677
00678 bool accept = false;
00679
00680
00681
00682 if (p1 >= p0)
00683 accept = true;
00684
00685
00686
00687 else
00688 {
00689 double r = log(fMCMCRandom -> Rndm());
00690
00691 if(r < p1 - p0)
00692 accept = true;
00693 }
00694
00695
00696
00697 if(accept)
00698 {
00699
00700
00701 fMCMCNTrialsTrue[chain * fMCMCNParameters + parameter]++;
00702
00703
00704
00705 for(int i = 0; i < fMCMCNParameters; ++i)
00706 {
00707
00708
00709 fMCMCx[index + i] = fMCMCxLocal[i];
00710
00711
00712
00713 fMCMCLogProbx[chain] = p1;
00714 }
00715 }
00716
00717 else
00718 {
00719
00720
00721 fMCMCNTrialsFalse[chain * fMCMCNParameters + parameter]++;
00722 }
00723
00724
00725
00726 fMCMCNIterations[chain]++;
00727
00728 return accept;
00729
00730 }
00731
00732
00733
00734 bool BCEngineMCMC::MCMCGetNewPointMetropolis(int chain, bool pca)
00735 {
00736
00737
00738
00739 int index = chain * fMCMCNParameters;
00740
00741
00742
00743 int counter = 0;
00744
00745 while (!this -> MCMCGetProposalPointMetropolis(chain, fMCMCxLocal, pca) && counter < 1000)
00746 counter++;
00747
00748
00749
00750 double p0 = fMCMCLogProbx[chain];
00751 double p1 = this -> LogEval(fMCMCxLocal);
00752
00753
00754
00755 bool accept = false;
00756
00757
00758
00759 if (p1 >= p0)
00760 accept = true;
00761
00762
00763
00764 else
00765 {
00766 double r = log(fMCMCRandom -> Rndm());
00767
00768 if(r < p1 - p0)
00769 accept = true;
00770 }
00771
00772
00773
00774 if(accept)
00775 {
00776
00777
00778 for (int i = 0; i < fMCMCNParameters; ++i)
00779 fMCMCNTrialsTrue[chain * fMCMCNParameters + i]++;
00780
00781
00782
00783 for(int i = 0; i < fMCMCNParameters; ++i)
00784 {
00785
00786
00787 fMCMCx[index + i] = fMCMCxLocal[i];
00788
00789
00790
00791 fMCMCLogProbx[chain] = p1;
00792 }
00793 }
00794
00795 else
00796 {
00797
00798
00799 for (int i = 0; i < fMCMCNParameters; ++i)
00800 fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00801
00802 }
00803
00804
00805
00806 fMCMCNIterations[chain]++;
00807
00808 return accept;
00809
00810 }
00811
00812
00813
00814 bool BCEngineMCMC::MCMCGetNewPointMetropolisHastings(int chain)
00815 {
00816
00817
00818
00819 int index = chain * fMCMCNParameters;
00820
00821
00822
00823 std::vector <double> xold;
00824
00825 for (int i = 0; i < fMCMCNParameters; ++i)
00826 xold.push_back(fMCMCxLocal.at(i));
00827
00828
00829
00830 int counter = 0;
00831
00832 while (!this -> MCMCGetProposalPointMetropolisHastings(chain, fMCMCxLocal, xold) && counter < 1000)
00833 counter++;
00834
00835
00836
00837 double p0 = fMCMCLogProbx[chain] + log(this -> MCMCTrialFunctionIndependent(xold, fMCMCxLocal, false));
00838 double p1 = this -> LogEval(fMCMCxLocal) + log(this -> MCMCTrialFunctionIndependent(xold, fMCMCxLocal, false));
00839
00840
00841
00842 bool accept = false;
00843
00844
00845
00846 if (p1 >= p0)
00847 accept = true;
00848
00849
00850
00851 else
00852 {
00853 double r = log(fMCMCRandom -> Rndm());
00854
00855 if(r < p1 - p0)
00856 accept = true;
00857 }
00858
00859
00860
00861 if(accept)
00862 {
00863
00864
00865 for (int i = 0; i < fMCMCNParameters; ++i)
00866 fMCMCNTrialsTrue[chain * fMCMCNParameters + i]++;
00867
00868
00869
00870 for(int i = 0; i < fMCMCNParameters; ++i)
00871 {
00872
00873
00874 fMCMCx[index + i] = fMCMCxLocal[i];
00875
00876
00877
00878 fMCMCLogProbx[chain] = p1;
00879 }
00880 }
00881
00882 else
00883 {
00884
00885
00886 for (int i = 0; i < fMCMCNParameters; ++i)
00887 fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00888
00889 }
00890
00891
00892
00893 fMCMCNIterations[chain]++;
00894
00895 return accept;
00896
00897 }
00898
00899
00900
00901 bool BCEngineMCMC::MCMCGetNewPointSimulatedAnnealing(int chain, bool pca)
00902 {
00903
00904
00905
00906 int index = chain * fMCMCNParameters;
00907
00908
00909
00910 int counter = 0;
00911
00912 while (!this -> MCMCGetProposalPointMetropolis(chain, fMCMCxLocal, pca) && counter < 1000)
00913 counter++;
00914
00915
00916
00917 double p0 = fMCMCLogProbx[chain];
00918 double p1 = this -> LogEval(fMCMCxLocal);
00919
00920
00921
00922 bool accept = false;
00923
00924
00925
00926 if (p1 >= p0)
00927 accept = true;
00928
00929
00930
00931 else
00932 {
00933 double r = log(fMCMCRandom -> Rndm());
00934
00935 if(r < (p1 - p0) / this -> MCMCAnnealingSchedule(chain))
00936 accept = true;
00937 }
00938
00939
00940
00941 if(accept)
00942 {
00943
00944
00945 for (int i = 0; i < fMCMCNParameters; ++i)
00946 fMCMCNTrialsTrue[chain * fMCMCNParameters + i]++;
00947
00948
00949
00950
00951 for(int i = 0; i < fMCMCNParameters; ++i)
00952 {
00953
00954
00955 fMCMCx[index + i] = fMCMCxLocal[i];
00956
00957
00958
00959 fMCMCLogProbx[chain] = p1;
00960 }
00961 }
00962
00963 else
00964 {
00965
00966
00967 for (int i = 0; i < fMCMCNParameters; ++i)
00968 fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00969 }
00970
00971
00972
00973 fMCMCNIterations[chain]++;
00974
00975 return accept;
00976
00977 }
00978
00979
00980
00981 double BCEngineMCMC::MCMCAnnealingSchedule(int chain)
00982 {
00983
00984
00985
00986 return fMCMCSimulatedAnnealingT0 * pow(1.0/fMCMCSimulatedAnnealingT0, double(fMCMCNIterations[chain])/fMCMCNIterationsMax);
00987
00988 }
00989
00990
00991
00992 void BCEngineMCMC::MCMCUpdateStatisticsModeConvergence()
00993 {
00994
00995 double * mode_minimum = new double[fMCMCNParameters];
00996 double * mode_maximum = new double[fMCMCNParameters];
00997 double * mode_average = new double[fMCMCNParameters];
00998
00999
01000
01001 for (int j = 0; j < fMCMCNParameters; ++j)
01002 {
01003 mode_minimum[j] = fMCMCMaximumPoints[j];
01004 mode_maximum[j] = fMCMCMaximumPoints[j];
01005 mode_average[j] = 0;
01006 }
01007
01008
01009
01010 for (int i = 0; i < fMCMCNChains; ++i)
01011 for (int j = 0; j < fMCMCNParameters; ++j)
01012 {
01013 if (fMCMCMaximumPoints[i * fMCMCNParameters + j] < mode_minimum[j])
01014 mode_minimum[j] = fMCMCMaximumPoints[i * fMCMCNParameters + j];
01015
01016 if (fMCMCMaximumPoints[i * fMCMCNParameters + j] > mode_maximum[j])
01017 mode_maximum[j] = fMCMCMaximumPoints[i * fMCMCNParameters + j];
01018
01019 mode_average[j] += fMCMCMaximumPoints[i * fMCMCNParameters + j] / double(fMCMCNChains);
01020 }
01021
01022 for (int j = 0; j < fMCMCNParameters; ++j)
01023 fMCMCNumericalPrecisionModeValues[j] = (mode_maximum[j] - mode_minimum[j]);
01024
01025
01026 delete [] mode_minimum;
01027 delete [] mode_maximum;
01028 delete [] mode_average;
01029
01030 }
01031
01032
01033
01034 void BCEngineMCMC::MCMCUpdateStatisticsCheckMaximum()
01035 {
01036
01037
01038 for (int i = 0; i < fMCMCNChains; ++i)
01039 {
01040 if (fMCMCLogProbx[i] > fMCMCMaximumLogProb[i] || fMCMCNIterations[i] == 1)
01041 {
01042 fMCMCMaximumLogProb[i] = fMCMCLogProbx[i];
01043 for (int j = 0; j < fMCMCNParameters; ++j)
01044 fMCMCMaximumPoints[i * fMCMCNParameters + j] = fMCMCx[i * fMCMCNParameters + j];
01045 }
01046 }
01047
01048 }
01049
01050
01051
01052 void BCEngineMCMC::MCMCUpdateStatisticsFillHistograms()
01053 {
01054
01055
01056
01057 for (int i = 0; i < fMCMCNChains; ++i)
01058 {
01059
01060
01061 for (int j = 0; j < fMCMCNParameters; ++j)
01062 fMCMCH1Marginalized[j] -> Fill(fMCMCx[i * fMCMCNParameters + j]);
01063
01064
01065
01066 int counter = 0;
01067
01068 for (int j = 0; j < fMCMCNParameters; ++j)
01069 for (int k = 0; k < j; ++k)
01070 {
01071 fMCMCH2Marginalized[counter] -> Fill(fMCMCx[i * fMCMCNParameters + k],
01072 fMCMCx[i * fMCMCNParameters + j]);
01073
01074 counter ++;
01075 }
01076 }
01077
01078
01079 }
01080
01081
01082
01083 void BCEngineMCMC::MCMCUpdateStatisticsTestConvergenceAllChains()
01084 {
01085
01086
01087 int npoints = fMCMCNTrialsTrue[0] + fMCMCNTrialsFalse[0];
01088
01089
01090
01091 if (npoints < fMCMCNIterationsPreRunMin)
01092 {
01093 fMCMCNIterationsConvergenceGlobal = -1;
01094
01095 return;
01096 }
01097
01098 if (fMCMCNChains > 1 && npoints > 1)
01099 {
01100
01101
01102
01103 bool flag_convergence = true;
01104
01105
01106
01107 for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01108 {
01109 double sum = 0;
01110 double sum2 = 0;
01111 double sumv = 0;
01112
01113
01114
01115 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01116 {
01117 int index = ichains * fMCMCNParameters + iparameters;
01118
01119
01120
01121 fMCMCMeanx[index] += (fMCMCx[index] - fMCMCMeanx[index]) / double(npoints);
01122
01123
01124
01125 fMCMCVariancex[index] = (1.0 - 1/double(npoints)) * fMCMCVariancex[index]
01126 + (fMCMCx[index] - fMCMCMeanx[index]) * (fMCMCx[index] - fMCMCMeanx[index]) / double(npoints - 1);
01127
01128 sum += fMCMCMeanx[index];
01129 sum2 += fMCMCMeanx[index] * fMCMCMeanx[index];
01130 sumv += fMCMCVariancex[index];
01131 }
01132
01133
01134
01135 double mean = sum / double(fMCMCNChains);
01136 double B = (sum2 / double(fMCMCNChains) - mean * mean) * double(fMCMCNChains) / double(fMCMCNChains-1) * double(npoints);
01137 double W = sumv * double(npoints) / double(npoints - 1) / double(fMCMCNChains);
01138
01139 double r = 100.0;
01140
01141 if (W > 0)
01142 {
01143 r = sqrt( ( (1-1/double(npoints)) * W + 1/double(npoints) * B ) / W);
01144
01145 fMCMCRValueParameters[iparameters] = r;
01146 }
01147
01148
01149
01150 if (! ((fMCMCRValueParameters[iparameters]-1.0) < fMCMCRValueParametersCriterion))
01151 flag_convergence = false;
01152 }
01153
01154
01155
01156 double sum = 0;
01157 double sum2 = 0;
01158 double sumv = 0;
01159
01160
01161
01162 for (int i = 0; i < fMCMCNChains; ++i)
01163 {
01164
01165
01166 fMCMCMean[i] += (fMCMCLogProbx[i] - fMCMCMean[i]) / double(npoints);
01167
01168
01169
01170 if (npoints > 1)
01171 fMCMCVariance[i] = (1.0 - 1/double(npoints)) * fMCMCVariance[i]
01172 + (fMCMCLogProbx[i] - fMCMCMean[i]) * (fMCMCLogProbx[i] - fMCMCMean[i]) / double(npoints - 1);
01173
01174 sum += fMCMCMean[i];
01175 sum2 += fMCMCMean[i] * fMCMCMean[i]; ;
01176 sumv += fMCMCVariance[i];
01177 }
01178
01179
01180
01181 double mean = sum / double(fMCMCNChains);
01182 double B = (sum2 / double(fMCMCNChains) - mean * mean) * double(fMCMCNChains) / double(fMCMCNChains-1) * double(npoints);
01183 double W = sumv * double(npoints) / double(npoints - 1) / double(fMCMCNChains);
01184
01185 double r = 100.0;
01186
01187 if (W > 0)
01188 {
01189 r = sqrt( ( (1-1/double(npoints)) * W + 1/double(npoints) * B ) / W);
01190
01191 fMCMCRValue = r;
01192 }
01193
01194
01195
01196 if (! ((fMCMCRValue-1.0) < fMCMCRValueCriterion))
01197 flag_convergence = false;
01198
01199
01200
01201 if (fMCMCNIterationsConvergenceGlobal == -1 && flag_convergence == true)
01202 fMCMCNIterationsConvergenceGlobal = fMCMCNIterations[0] / fMCMCNParameters;
01203 }
01204
01205 }
01206
01207
01208
01209 void BCEngineMCMC::MCMCUpdateStatisticsWriteChains()
01210 {
01211
01212
01213
01214 for (int i = 0; i < fMCMCNChains; ++i)
01215 fMCMCTrees[i] -> Fill();
01216
01217 }
01218
01219
01220
01221 void BCEngineMCMC::MCMCUpdateStatistics()
01222 {
01223
01224
01225
01226 this -> MCMCUpdateStatisticsCheckMaximum();
01227
01228
01229
01230 this -> MCMCUpdateStatisticsFillHistograms();
01231
01232
01233
01234
01235
01236
01237 this -> MCMCUpdateStatisticsTestConvergenceAllChains();
01238
01239
01240
01241 if (fMCMCFlagWriteChainToFile)
01242 this -> MCMCUpdateStatisticsWriteChains();
01243
01244 }
01245
01246
01247
01248 double BCEngineMCMC::LogEval(std::vector <double> parameters)
01249 {
01250
01251
01252
01253
01254 return 0.0;
01255
01256 }
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444 int BCEngineMCMC::MCMCMetropolisPreRun()
01445 {
01446
01447
01448 BCLog::Out(BCLog::summary, BCLog::summary, "Pre-run Metropolis MCMC.");
01449
01450
01451 this -> MCMCInitialize();
01452
01453 this -> MCMCInitializeMarkovChains();
01454
01455
01456 if (fMCMCNIterationsBurnIn > 0)
01457 BCLog::Out(BCLog::detail, BCLog::detail,
01458 Form(" --> Start burn-in run with %i iterations.", fMCMCNIterationsBurnIn));
01459
01460 for (int i = 0; i < fMCMCNIterationsBurnIn; ++i)
01461 for (int j = 0; j < fMCMCNChains; ++j)
01462 for (int k = 0; k < fMCMCNParameters; ++k)
01463 this -> MCMCGetNewPointMetropolis(j, k, false);
01464
01465
01466
01467 this -> MCMCResetRunStatistics();
01468
01469
01470 double * dataall = 0;
01471 double * sum = 0;
01472 double * sum2 = 0;
01473
01474
01475 if (fMCMCFlagPCA)
01476 {
01477 BCLog::Out(BCLog::detail, BCLog::detail, " --> PCA switched on.");
01478
01479
01480 fMCMCPCA = new TPrincipal(fMCMCNParameters, "D");
01481
01482
01483 dataall = new double[fMCMCNParameters * fMCMCNIterationsPCA];
01484
01485
01486 sum = new double[fMCMCNParameters];
01487 sum2 = new double[fMCMCNParameters];
01488
01489
01490 for (int i = 0; i < fMCMCNParameters; ++i)
01491 {
01492 sum[i] = 0.0;
01493 sum2[i] = 0.0;
01494 }
01495
01496 if (fMCMCFlagPCATruncate == true)
01497 {
01498 fMCMCNDimensionsPCA = 0;
01499
01500 const double * ma = fMCMCPCA -> GetEigenValues() -> GetMatrixArray();
01501
01502 for (int i = 0; i < fMCMCNParameters; ++i)
01503 if (ma[i]/ma[0] > fMCMCPCAMinimumRatio)
01504 fMCMCNDimensionsPCA++;
01505
01506 BCLog::Out(BCLog::detail, BCLog::detail,
01507 Form(" --> Use %i out of %i dimensions.", fMCMCNDimensionsPCA, fMCMCNParameters));
01508
01509 }
01510
01511 else
01512 fMCMCNDimensionsPCA = fMCMCNParameters;
01513 }
01514
01515 else
01516 BCLog::Out(BCLog::detail, BCLog::detail, " --> No PCA run.");
01517
01518
01519
01520 this -> MCMCResetRunStatistics();
01521
01522
01523
01524 BCLog::Out(BCLog::detail, BCLog::detail,
01525 Form(" --> Perform MCMC run with %i chains each with %i iterations maximum.", fMCMCNChains, fMCMCNIterationsMax));
01526
01527 bool tempflag_writetofile = fMCMCFlagWriteChainToFile;
01528
01529
01530
01531 fMCMCFlagWriteChainToFile = false;
01532
01533 int counter = 0;
01534 int counterupdate = 0;
01535 bool convergence = false;
01536 bool flagefficiency = false;
01537
01538 std::vector <double> efficiency;
01539
01540 for (int i = 0; i < fMCMCNParameters; ++i)
01541 for (int j = 0; j < fMCMCNChains; ++j)
01542 efficiency.push_back(0.);
01543
01544 if (fMCMCFlagPCA)
01545 {
01546 fMCMCNIterationsPreRunMin = fMCMCNIterationsPCA;
01547 fMCMCNIterationsMax = fMCMCNIterationsPCA;
01548 }
01549
01550 while (counter < fMCMCNIterationsPreRunMin || (counter < fMCMCNIterationsMax && !(convergence && flagefficiency)))
01551 {
01552
01553
01554
01555 convergence = false;
01556
01557
01558 for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01559 {
01560
01561
01562 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01563 {
01564
01565 this -> MCMCGetNewPointMetropolis(ichains, iparameters, false);
01566
01567
01568 if (fMCMCFlagPCA)
01569 {
01570
01571 double * data = new double[fMCMCNParameters];
01572
01573
01574 for (int j = 0; j < fMCMCNParameters; ++j)
01575 {
01576 data[j] = fMCMCx[j];
01577 dataall[ichains * fMCMCNParameters + j] = fMCMCx[j];
01578 }
01579
01580
01581 fMCMCPCA -> AddRow(data);
01582
01583
01584 delete [] data;
01585
01586 }
01587 }
01588
01589
01590 this -> MCMCUpdateStatisticsCheckMaximum();
01591
01592
01593 this -> MCMCUpdateStatisticsTestConvergenceAllChains();
01594 }
01595
01596
01597 if (counterupdate % (fMCMCNIterationsUpdate*(fMCMCNParameters+1)) == 0 && counterupdate > 0)
01598 {
01599
01600
01601 BCLog::Out(BCLog::detail, BCLog::detail,
01602 Form(" -> Iteration %i", fMCMCNIterations[0] / fMCMCNParameters));
01603
01604 for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter)
01605 BCLog::Out(BCLog::detail, BCLog::detail,
01606 Form(" --> R-Value for parameter %i is %2lf. ", iparameter, fMCMCRValueParameters.at(iparameter)));
01607
01608 BCLog::Out(BCLog::detail, BCLog::detail,
01609 Form(" --> R-Value for log-likelihood is %2lf. ", fMCMCRValue));
01610
01611
01612 flagefficiency = true;
01613
01614
01615 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01616 {
01617
01618
01619 for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter)
01620 {
01621
01622 efficiency[ichains * fMCMCNParameters + iparameter] = double(fMCMCNTrialsTrue[ichains * fMCMCNParameters + iparameter]) / double(fMCMCNTrialsTrue[ichains * fMCMCNParameters + iparameter] + fMCMCNTrialsFalse[ichains * fMCMCNParameters + iparameter]);
01623
01624
01625 if (efficiency[ichains * fMCMCNParameters + iparameter] < fMCMCEfficiencyMin &&
01626 fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] > .01)
01627 {
01628 fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] = fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] / 2.;
01629
01630 BCLog::Out(BCLog::detail, BCLog::detail,
01631 Form(" --> Efficiency of parameter %i dropped below %.2lf%% (eps = %.2lf%%) in chain %i. Set scale to %.2lf%%. ", iparameter, 100.0 * fMCMCEfficiencyMin, 100.0 * efficiency[ichains * fMCMCNParameters + iparameter], ichains, 100. * fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter]));
01632 }
01633
01634
01635 else if (efficiency[ichains * fMCMCNParameters + iparameter] > fMCMCEfficiencyMax &&
01636 (fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] < 1. || (fMCMCFlagPCA && fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] < 10.)))
01637 {
01638 fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] = fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] * 2.;
01639
01640 BCLog::Out(BCLog::detail, BCLog::detail,
01641 Form(" --> Efficiency of parameter %i above %.2lf%% (eps = %.2lf%%) in chain %i. Set scale to %.2lf%%. ", iparameter, 100.0 * fMCMCEfficiencyMax, 100.0 * efficiency[ichains * fMCMCNParameters + iparameter], ichains, 100. * fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter]));
01642 }
01643
01644
01645 counterupdate = 0;
01646 fMCMCNTrialsTrue[ichains * fMCMCNParameters + iparameter] = 0;
01647 fMCMCNTrialsFalse[ichains * fMCMCNParameters + iparameter] = 0;
01648
01649
01650 if ((efficiency[ichains * fMCMCNParameters + iparameter] < fMCMCEfficiencyMin && fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] > 0.01) || (efficiency[ichains * fMCMCNParameters + iparameter] > fMCMCEfficiencyMax && fMCMCTrialFunctionScaleFactor[ichains * fMCMCNParameters + iparameter] < 1.))
01651 flagefficiency = false;
01652
01653 }
01654
01655
01656 fMCMCMean[ichains] = 0;
01657 fMCMCVariance[ichains] = 0;
01658
01659 }
01660 }
01661
01662
01663 counter++;
01664 counterupdate++;
01665
01666
01667 if (fMCMCNIterationsConvergenceGlobal > 0)
01668 convergence = true;
01669
01670 }
01671
01672
01673
01674 if (fMCMCNIterationsConvergenceGlobal > 0)
01675 fMCMCFlagConvergenceGlobal = true;
01676 else
01677 fMCMCFlagConvergenceGlobal = false;
01678
01679
01680
01681 if (fMCMCFlagConvergenceGlobal && fMCMCNChains > 0)
01682 BCLog::Out(BCLog::summary, BCLog::summary,
01683 Form(" --> Set of %i Markov chains converged within %i iterations. ", fMCMCNChains, fMCMCNIterationsConvergenceGlobal));
01684
01685 else if (!fMCMCFlagConvergenceGlobal && fMCMCNChains > 0)
01686 BCLog::Out(BCLog::summary, BCLog::summary,
01687 Form(" --> Set of %i Markov chains did not converge within %i iterations or could not adjust scales. ", fMCMCNChains, fMCMCNIterationsMax));
01688
01689 else
01690 BCLog::Out(BCLog::summary, BCLog::summary,
01691 " --> Only one Markov chain. No global convergence criterion defined.");
01692
01693 BCLog::Out(BCLog::summary, BCLog::summary,
01694 Form(" --> Markov chains ran for %i iterations. ", counter));
01695
01696
01697
01698 std::vector <double> efficiencies;
01699
01700 for (int i = 0; i < fMCMCNParameters; ++i)
01701 efficiencies.push_back(0.0);
01702
01703 for (int i = 0; i < fMCMCNParameters; ++i)
01704 {
01705 for (int j = 0; j < fMCMCNChains; ++j)
01706 efficiencies[i] += efficiency[j * fMCMCNParameters + i] / double(fMCMCNChains);
01707
01708 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Average efficiency for parameter %i: %.2lf%%. ", i, 100.0 * efficiencies[i]));
01709 }
01710
01711
01712
01713 std::vector <double> scalefactors;
01714
01715 for (int i = 0; i < fMCMCNParameters; ++i)
01716 scalefactors.push_back(0.0);
01717
01718 for (int i = 0; i < fMCMCNParameters; ++i)
01719 {
01720 for (int j = 0; j < fMCMCNChains; ++j)
01721 scalefactors[i] += fMCMCTrialFunctionScaleFactor[j * fMCMCNParameters + i] / double(fMCMCNChains);
01722
01723 BCLog::Out(BCLog::detail, BCLog::detail,
01724 Form(" --> Average scale factor for parameter %i: %.2lf%%. ", i, 100 * scalefactors[i]));
01725 }
01726
01727
01728
01729 if (fMCMCFlagPCA)
01730 {
01731
01732
01733 fMCMCPCA -> MakePrincipals();
01734
01735
01736 for (int i = 0; i < fMCMCNIterationsPCA; ++i)
01737 {
01738 double * data = new double[fMCMCNParameters];
01739 double * p = new double[fMCMCNParameters];
01740
01741 for (int j = 0; j < fMCMCNParameters; ++j)
01742 data[j] = dataall[i * fMCMCNParameters + j];
01743
01744 fMCMCPCA -> X2P(data, p);
01745
01746 for (int j = 0; j < fMCMCNParameters; ++j)
01747 {
01748 sum[j] += p[j];
01749 sum2[j] += p[j] * p[j];
01750 }
01751
01752 delete [] data;
01753 delete [] p;
01754 }
01755
01756 delete [] dataall;
01757
01758 fMCMCPCAMean.clear();
01759 fMCMCPCAVariance.clear();
01760
01761
01762 for (int j = 0; j < fMCMCNParameters; ++j)
01763 {
01764 fMCMCPCAMean.push_back(sum[j] / double(fMCMCNIterationsPCA) / double(fMCMCNChains));
01765 fMCMCPCAVariance.push_back(sum2[j] / double(fMCMCNIterationsPCA) / double(fMCMCNChains) - fMCMCPCAMean[j] * fMCMCPCAMean[j]);
01766 }
01767
01768
01769 int neigenvalues = fMCMCPCA -> GetEigenValues() -> GetNoElements();
01770
01771 const double * eigenv = fMCMCPCA -> GetEigenValues() -> GetMatrixArray();
01772
01773 bool flageigenvalues = true;
01774
01775 for (int i = 0; i < neigenvalues; ++i)
01776 if (isnan(eigenv[i]))
01777 flageigenvalues = false;
01778
01779
01780 if (flageigenvalues)
01781 BCLog::Out(BCLog::detail, BCLog::detail, " --> PCA : All eigenvalues ok.");
01782 else
01783 {
01784 BCLog::Out(BCLog::detail, BCLog::detail, " --> PCA : Not all eigenvalues ok. Don't use PCA.");
01785 fMCMCFlagPCA = false;
01786 }
01787
01788
01789 for (int i = 0; i < fMCMCNParameters; ++i)
01790 for (int j = 0; j < fMCMCNChains; ++j)
01791 fMCMCTrialFunctionScaleFactor[j * fMCMCNParameters + i] = 1.0;
01792
01793 if (DEBUG)
01794 {
01795 fMCMCPCA -> Print("MSEV");
01796
01797 for (int j = 0; j < fMCMCNParameters; ++j)
01798 std::cout << fMCMCPCAMean.at(j) << " " << sqrt(fMCMCPCAVariance.at(j)) << std::endl;
01799 }
01800
01801 }
01802
01803
01804
01805
01806
01807
01808 fMCMCFlagWriteChainToFile = tempflag_writetofile;
01809
01810
01811 fMCMCFlagPreRun = true;
01812
01813 return 1;
01814
01815 }
01816
01817
01818
01819 int BCEngineMCMC::MCMCMetropolis()
01820 {
01821
01822
01823
01824 if (!fMCMCFlagPreRun)
01825 this -> MCMCMetropolisPreRun();
01826
01827
01828
01829 BCLog::Out(BCLog::summary, BCLog::summary, "Run Metropolis MCMC.");
01830
01831 if (fMCMCFlagPCA)
01832 BCLog::Out(BCLog::detail, BCLog::detail, " --> PCA switched on.");
01833
01834
01835
01836 this -> MCMCResetRunStatistics();
01837
01838
01839
01840 BCLog::Out(BCLog::detail, BCLog::detail,
01841 Form(" --> Perform MCMC run with %i chains each with %i iterations.", fMCMCNChains, fMCMCNIterationsRun));
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 int nwrite = fMCMCNIterationsRun/10;
01854 if(nwrite < 100)
01855 nwrite=100;
01856 else if(nwrite < 500)
01857 nwrite=1000;
01858 else if(nwrite < 10000)
01859 nwrite=1000;
01860 else
01861 nwrite=10000;
01862
01863 for (int iiterations = 0; iiterations < fMCMCNIterationsRun; ++iiterations)
01864 {
01865
01866 if ( (iiterations+1)%nwrite == 0 )
01867 BCLog::Out(BCLog::detail, BCLog::detail,
01868 Form(" --> iteration number %i (%.2f%%)", iiterations+1, (double)(iiterations+1)/(double)fMCMCNIterationsRun*100.));
01869
01870
01871
01872 for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01873 {
01874
01875
01876 for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01877 this -> MCMCGetNewPointMetropolis(ichains, iparameters, fMCMCFlagPCA);
01878
01879
01880
01881 this -> MCMCUpdateStatistics();
01882
01883
01884
01885 this -> MCMCUpdateFunctionFitting();
01886
01887
01888
01889 this -> MCMCUserInterface();
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959 }
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970 BCLog::Out(BCLog::summary, BCLog::summary,
01971 Form(" --> Markov chains ran for %i iterations. ", fMCMCNIterationsRun));
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021 double probmax = fMCMCMaximumLogProb.at(0);
02022 int probmaxindex = 0;
02023
02024
02025 for (int i = 1; i < fMCMCNChains; ++i)
02026 if (fMCMCMaximumLogProb.at(i) > probmax)
02027 {
02028 probmax = fMCMCMaximumLogProb.at(i);
02029 probmaxindex = i;
02030 }
02031
02032 for (int i = 0; i < fMCMCNParameters; ++i)
02033 BCLog::Out(BCLog::detail, BCLog::detail,
02034 Form(" --> Global mode of parameter %i: %.2lf with abs. num. precision %.2e",
02035 i, fMCMCMaximumPoints.at(probmaxindex * fMCMCNParameters + i),
02036 fMCMCNumericalPrecisionModeValues.at(i)));
02037
02038
02039
02040
02041
02042
02043 fMCMCFlagPreRun = false;
02044
02045 return 1;
02046
02047 }
02048
02049
02050
02051 int BCEngineMCMC::MCMCMetropolisHastings()
02052 {
02053
02054 BCLog::Out(BCLog::summary, BCLog::summary, "Run Metropolis-Hastings MCMC.");
02055
02056
02057
02058 this -> MCMCInitializeMarkovChains();
02059
02060
02061
02062 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Start burn-in run with %i iterations.", fMCMCNIterationsBurnIn));
02063
02064 for (int i = 0; i < fMCMCNIterationsBurnIn; ++i)
02065 for (int j = 0; j < fMCMCNChains; ++j)
02066 this -> MCMCGetNewPointMetropolisHastings(j);
02067
02068
02069
02070 this -> MCMCResetRunStatistics();
02071
02072
02073
02074 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Perform MCMC run with %i iterations.", fMCMCNIterationsMax));
02075
02076 for (int i = 0; i < fMCMCNIterationsMax; ++i)
02077 {
02078 for (int j = 0; j < fMCMCNChains; ++j)
02079 {
02080
02081
02082 this -> MCMCGetNewPointMetropolisHastings(j);
02083 }
02084
02085
02086
02087 this -> MCMCUpdateStatistics();
02088
02089
02090
02091 this -> MCMCUserInterface();
02092 }
02093
02094 if (fMCMCNIterationsConvergenceGlobal > 0)
02095 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Set of %i Markov chains converged within %i iterations. ", fMCMCNChains, fMCMCNIterationsConvergenceGlobal));
02096
02097 else
02098 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Set of %i Markov chains did not converge within %i iterations. ", fMCMCNChains, fMCMCNIterationsMax));
02099
02100
02101
02102 if (DEBUG)
02103 {
02104 for (int i = 0; i < fMCMCNChains; ++i)
02105 {
02106 std::cout << i << " "
02107 << fMCMCMaximumLogProb[i] << std::endl;
02108
02109 for (int j = 0; j < fMCMCNParameters; ++j)
02110 std::cout << fMCMCMaximumPoints[i * fMCMCNParameters + j] << " ";
02111
02112 std::cout << std::endl;
02113 }
02114 }
02115
02116 return 1;
02117
02118 }
02119
02120
02121
02122 int BCEngineMCMC::MCMCSimulatedAnnealing()
02123 {
02124
02125 BCLog::Out(BCLog::summary, BCLog::summary, "Run Simulated Annealing MCMC.");
02126
02127
02128
02129 this -> MCMCInitializeMarkovChains();
02130
02131
02132
02133 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Start burn-in run with %i iterations.", fMCMCNIterationsBurnIn));
02134
02135 for (int i = 0; i < fMCMCNIterationsBurnIn; ++i)
02136 for (int j = 0; j < fMCMCNChains; ++j)
02137 this -> MCMCGetNewPointSimulatedAnnealing(j, false);
02138
02139
02140
02141 this -> MCMCResetRunStatistics();
02142
02143
02144
02145 if (fMCMCFlagPCA)
02146 {
02147 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Start PCA run with %i iterations.", fMCMCNIterationsPCA));
02148
02149
02150 }
02151
02152 else
02153 BCLog::Out(BCLog::detail, BCLog::detail, " --> No PCA run.");
02154
02155
02156
02157 this -> MCMCResetRunStatistics();
02158
02159
02160
02161 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Perform MCMC run with %i chains each with %i iterations.", fMCMCNChains, fMCMCNIterationsMax));
02162
02163 for (int i = 0; i < fMCMCNIterationsMax; ++i)
02164 {
02165 for (int j = 0; j < fMCMCNChains; ++j)
02166 {
02167
02168
02169 this -> MCMCGetNewPointSimulatedAnnealing(j, fMCMCFlagPCA);
02170 }
02171
02172
02173
02174 this -> MCMCUpdateStatistics();
02175
02176
02177
02178 this -> MCMCUserInterface();
02179 }
02180
02181 if (fMCMCNIterationsConvergenceGlobal > 0)
02182 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Set of %i Markov chains converged within %i iterations. ", fMCMCNChains, fMCMCNIterationsConvergenceGlobal));
02183
02184 else
02185 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Set of %i Markov chains did not converge within %i iterations. ", fMCMCNChains, fMCMCNIterationsMax));
02186
02187
02188
02189 if (DEBUG)
02190 {
02191 for (int i = 0; i < fMCMCNChains; ++i)
02192 {
02193 std::cout << i << " "
02194 << fMCMCMaximumLogProb[i] << std::endl;
02195
02196 for (int j = 0; j < fMCMCNParameters; ++j)
02197 std::cout << fMCMCMaximumPoints[i * fMCMCNParameters + j] << " ";
02198 std::cout << std::endl;
02199 }
02200 }
02201
02202 return 1;
02203
02204 }
02205
02206
02207
02208 void BCEngineMCMC::MCMCResetRunStatistics()
02209 {
02210
02211 fMCMCNIterationsConvergenceGlobal = -1;
02212
02213 for (int j = 0; j < fMCMCNChains; ++j)
02214 {
02215 fMCMCNIterations[j] = 0;
02216 fMCMCNTrialsTrue[j] = 0;
02217 fMCMCNTrialsFalse[j] = 0;
02218 fMCMCMean[j] = 0;
02219 fMCMCVariance[j] = 0;
02220
02221 for (int k = 0; k < fMCMCNParameters; ++k)
02222 {
02223 fMCMCNTrialsTrue[j * fMCMCNParameters + k] = 0;
02224 fMCMCNTrialsFalse[j * fMCMCNParameters + k] = 0;
02225 }
02226 }
02227
02228
02229
02230 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
02231 fMCMCH1Marginalized[i] -> Reset();
02232
02233 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
02234 fMCMCH2Marginalized[i] -> Reset();
02235
02236
02237
02238
02239
02240
02241
02242 fMCMCRValue = 100;
02243
02244 }
02245
02246
02247
02248 int BCEngineMCMC::MCMCAddParameter(double min, double max)
02249 {
02250
02251
02252
02253 fMCMCBoundaryMin.push_back(min);
02254 fMCMCBoundaryMax.push_back(max);
02255
02256
02257
02258 fMCMCNParameters++;
02259
02260
02261
02262 return fMCMCNParameters;
02263
02264 }
02265
02266
02267
02268 void BCEngineMCMC::MCMCInitializeMarkovChains()
02269 {
02270
02271
02272
02273 std::vector <double> x0;
02274
02275 for (int j = 0; j < fMCMCNChains; ++j)
02276 {
02277 x0.clear();
02278 for (int i = 0; i < fMCMCNParameters; ++i)
02279 {
02280 x0.push_back(fMCMCx[j * fMCMCNParameters + i]);
02281 }
02282 fMCMCLogProbx[j] = this -> LogEval(x0);
02283 }
02284
02285 x0.clear();
02286
02287 }
02288
02289
02290
02291 int BCEngineMCMC::MCMCInitialize()
02292 {
02293
02294
02295
02296 fMCMCNIterations.clear();
02297 fMCMCNIterationsConvergenceLocal.clear();
02298 fMCMCNTrialsTrue.clear();
02299 fMCMCNTrialsFalse.clear();
02300 fMCMCTrialFunctionScaleFactor.clear();
02301 fMCMCMean.clear();
02302 fMCMCVariance.clear();
02303 fMCMCMeanx.clear();
02304 fMCMCVariancex.clear();
02305 fMCMCx.clear();
02306 fMCMCLogProbx.clear();
02307 fMCMCMaximumPoints.clear();
02308 fMCMCMaximumLogProb.clear();
02309
02310 fMCMCNumericalPrecisionModeValues.clear();
02311
02312 fMCMCNIterationsConvergenceGlobal = -1;
02313 fMCMCFlagConvergenceGlobal = false;
02314
02315 fMCMCRValueParameters.clear();
02316
02317 for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
02318 if (fMCMCH1Marginalized[i])
02319 delete fMCMCH1Marginalized[i];
02320
02321 for (int i = 0; i < int(fMCMCH2Marginalized.size()); ++i)
02322 if (fMCMCH2Marginalized[i])
02323 delete fMCMCH2Marginalized[i];
02324
02325
02326
02327 fMCMCH1Marginalized.clear();
02328 fMCMCH2Marginalized.clear();
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338 fMCMCNIterationsConvergenceLocal.assign(fMCMCNChains, -1);
02339 fMCMCNIterations.assign(fMCMCNChains, 0);
02340 fMCMCMean.assign(fMCMCNChains, 0);
02341 fMCMCVariance.assign(fMCMCNChains, 0);
02342 fMCMCLogProbx.assign(fMCMCNChains, -1.0);
02343 fMCMCMaximumLogProb.assign(fMCMCNChains, -1.0);
02344
02345 fMCMCNumericalPrecisionModeValues.assign(fMCMCNParameters, 0.0);
02346
02347 fMCMCNTrialsTrue.assign(fMCMCNChains * fMCMCNParameters, 0);
02348 fMCMCNTrialsFalse.assign(fMCMCNChains * fMCMCNParameters, 0);
02349 fMCMCMaximumPoints.assign(fMCMCNChains * fMCMCNParameters, 0.0);
02350 fMCMCMeanx.assign(fMCMCNChains * fMCMCNParameters, 0);
02351 fMCMCVariancex.assign(fMCMCNChains * fMCMCNParameters, 0);
02352
02353 fMCMCRValueParameters.assign(fMCMCNParameters, 0.0);
02354
02355 if (fMCMCTrialFunctionScaleFactorStart.size() == 0)
02356 fMCMCTrialFunctionScaleFactor.assign(fMCMCNChains * fMCMCNParameters, 1.0);
02357 else
02358 for (int i = 0; i < fMCMCNChains; ++i)
02359 for (int j = 0; j < fMCMCNParameters; ++j)
02360 fMCMCTrialFunctionScaleFactor.push_back(fMCMCTrialFunctionScaleFactorStart.at(j));
02361
02362
02363
02364 for (int j = 0; j < fMCMCNChains; ++j)
02365 for (int i = 0; i < fMCMCNParameters; ++i)
02366 switch(fMCMCFlagInitialPosition)
02367 {
02368
02369
02370 case 0 :
02371 fMCMCx.push_back(fMCMCBoundaryMin[i] + .5 * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
02372 break;
02373
02374
02375 case 1 :
02376 fMCMCx.push_back(fMCMCBoundaryMin[i] + fMCMCRandom -> Rndm() * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
02377 break;
02378
02379
02380 case 2 :
02381 if (int(fMCMCInitialPosition.size()) == fMCMCNParameters * fMCMCNChains)
02382 fMCMCx.push_back(fMCMCInitialPosition[j * fMCMCNParameters + i]);
02383 else
02384 fMCMCx.push_back(fMCMCBoundaryMin[i] + .5 * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
02385 break;
02386
02387
02388 default:
02389 fMCMCx.push_back(fMCMCBoundaryMin[i] + 0.5 * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
02390 break;
02391 }
02392
02393
02394 fMCMCxLocal.clear();
02395
02396 for (int i = 0; i < fMCMCNParameters; ++i)
02397 fMCMCxLocal.push_back(fMCMCx[i]);
02398
02399
02400
02401 for(int i = 0; i < fMCMCNParameters; ++i)
02402 {
02403 double hmin1 = fMCMCBoundaryMin.at(i);
02404 double hmax1 = fMCMCBoundaryMax.at(i);
02405
02406 TH1D * h1 = new TH1D(Form("h1_parameter_%i", i), "",
02407 fMCMCH1NBins, hmin1, hmax1);
02408
02409 fMCMCH1Marginalized.push_back(h1);
02410 }
02411
02412 for(int i = 0; i < fMCMCNParameters; ++i)
02413 for (int k = 0; k < i; ++k)
02414 {
02415 double hmin1 = fMCMCBoundaryMin.at(k);
02416 double hmax1 = fMCMCBoundaryMax.at(k);
02417
02418 double hmin2 = fMCMCBoundaryMin.at(i);
02419 double hmax2 = fMCMCBoundaryMax.at(i);
02420
02421 TH2D * h2 = new TH2D(Form("h2_parameters_%i_vs_%i", i, k), "",
02422 fMCMCH2NBinsX, hmin1, hmax1,
02423 fMCMCH2NBinsY, hmin2, hmax2);
02424
02425 fMCMCH2Marginalized.push_back(h2);
02426 }
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441 return 1;
02442
02443 }
02444
02445
02446
02447 int BCEngineMCMC::SetMarginalized(int index, TH1D * h)
02448 {
02449 if((int)fMCMCH1Marginalized.size()<=index)
02450 return 0;
02451
02452 if(h==0)
02453 return 0;
02454
02455 if((int)fMCMCH1Marginalized.size()==index)
02456 fMCMCH1Marginalized.push_back(h);
02457 else
02458 fMCMCH1Marginalized[index]=h;
02459
02460 return index;
02461 }
02462
02463
02464
02465 int BCEngineMCMC::SetMarginalized(int index1, int index2, TH2D * h)
02466 {
02467 int counter = 0;
02468 int index = 0;
02469
02470
02471 for(int i = 0; i < fMCMCNParameters; i++)
02472 for (int j = 0; j < i; ++j)
02473 {
02474 if(j == index1 && i == index2)
02475 index = counter;
02476 counter++;
02477 }
02478
02479 if((int)fMCMCH2Marginalized.size()<=index)
02480 return 0;
02481
02482 if(h==0)
02483 return 0;
02484
02485 if((int)fMCMCH2Marginalized.size()==index)
02486 fMCMCH2Marginalized.push_back(h);
02487 else
02488 fMCMCH2Marginalized[index]=h;
02489
02490 return index;
02491 }
02492
02493
02494