• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

BCEngineMCMC.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2011, Daniel Kollar and Kevin Kroeninger.
00003  * All rights reserved.
00004  *
00005  * For the licensing terms see doc/COPYING.
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    // set default parameters for the mcmc
00027    MCMCSetValuesDefault();
00028 
00029    // initialize random number generator
00030    fRandom = new TRandom3(0);
00031 }
00032 
00033 // ---------------------------------------------------------
00034 BCEngineMCMC::BCEngineMCMC(int n)
00035 {
00036    // set number of chains to n
00037    fMCMCNChains = n;
00038 
00039    // call default constructor
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    // re-initialize
00159    MCMCInitialize();
00160 }
00161 
00162 // ---------------------------------------------------------
00163 BCEngineMCMC::~BCEngineMCMC()
00164 {
00165    // delete random number generator
00166    if (fRandom)
00167       delete fRandom;
00168 
00169    // delete 1-d marginalized distributions
00170    for (int i = 0; i < int(fMCMCH1Marginalized.size()); ++i)
00171       if (fMCMCH1Marginalized[i])
00172          delete fMCMCH1Marginalized[i];
00173    fMCMCH1Marginalized.clear();
00174 
00175    // delete 2-d marginalized distributions
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       // debugKK
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       // debugKK
00330       fMCMCTrees.push_back(0);
00331    }
00332 
00333    // return this
00334    return *this;
00335 }
00336 
00337 
00338 // --------------------------------------------------------
00339 TH1D * BCEngineMCMC::MCMCGetH1Marginalized(int index)
00340 {
00341       // check index
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    // search for correct combination
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    // check index
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    // create a new vector with the lenght of fMCMCNParameters
00380    std::vector <double> x;
00381 
00382    // check if i is in range
00383    if (i < 0 || i >= fMCMCNChains)
00384       return x;
00385 
00386    // copy the point in the ith chain into the temporary vector
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    // re-initialize
00399    MCMCInitialize();
00400 }
00401 
00402 // --------------------------------------------------------
00403 void BCEngineMCMC::MCMCSetInitialPositions(std::vector<double> x0s)
00404 {
00405    // clear the existing initial position vector
00406    fMCMCInitialPosition.clear();
00407 
00408    // copy the initial positions
00409    int n = int(x0s.size());
00410 
00411    for (int i = 0; i < n; ++i)
00412       fMCMCInitialPosition.push_back(x0s.at(i));
00413 
00414    // use these intial positions for the Markov chain
00415    MCMCSetFlagInitialPosition(2);
00416 }
00417 
00418 // --------------------------------------------------------
00419 void BCEngineMCMC::MCMCSetInitialPositions(std::vector< std::vector<double> > x0s)
00420 {
00421    // create new vector
00422    std::vector <double> y0s;
00423 
00424    // loop over vector elements
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    // check if index is within range
00445    if (index < 0 || index > fMCMCNParameters)
00446    {
00447       BCLog::OutWarning("BCEngineMCMC :MCMCSetFlagFillHistograms. Index out of range.");
00448       return;
00449    }
00450 
00451    // set flag
00452    fMCMCFlagsFillHistograms[index] = flag;
00453 }
00454 
00455 // --------------------------------------------------------
00456 void BCEngineMCMC::MCMCSetMarkovChainTrees(std::vector <TTree *> trees)
00457 {
00458 // clear vector
00459    fMCMCTrees.clear();
00460 
00461    // copy tree
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 // clear vector
00470    fMCMCTrees.clear();
00471 
00472 // create new trees
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    // call MCMCTrialFunctionSingle() for all parameters by default
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    // no check of range for performance reasons
00500 
00501    // use uniform distribution
00502 // return = fMCMCTrialFunctionScaleFactor[ichain * fMCMCNParameters + iparameter] * 2.0 * (0.5 - fRandom->Rndm());
00503 
00504    // Breit-Wigner width adjustable width
00505    return fRandom->BreitWigner(0.0, fMCMCTrialFunctionScaleFactor[ichain * fMCMCNParameters + iparameter]);
00506 }
00507 
00508 // --------------------------------------------------------
00509 std::vector <double> BCEngineMCMC::MCMCGetTrialFunctionScaleFactor(int ichain)
00510 {
00511    // create a new vector with the length of fMCMCNParameters
00512    std::vector <double> x;
00513 
00514    // check if ichain is in range
00515    if (ichain < 0 || ichain >= fMCMCNChains)
00516       return x;
00517 
00518    // copy the scale factors into the temporary vector
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    // check if ichain is in range
00529    if (ichain < 0 || ichain >= fMCMCNChains)
00530       return 0;
00531 
00532    // check if ipar is in range
00533    if (ipar < 0 || ipar >= fMCMCNParameters)
00534       return 0;
00535 
00536    // return component of ipar point in the ichain chain
00537    return fMCMCTrialFunctionScaleFactor.at(ichain *  fMCMCNChains + ipar);
00538 }
00539 
00540 // --------------------------------------------------------
00541 std::vector <double> BCEngineMCMC::MCMCGetx(int ichain)
00542 {
00543    // create a new vector with the length of fMCMCNParameters
00544    std::vector <double> x;
00545 
00546    // check if ichain is in range
00547    if (ichain < 0 || ichain >= fMCMCNChains)
00548       return x;
00549 
00550    // copy the point in the ichain chain into the temporary vector
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    // check if ichain is in range
00561    if (ichain < 0 || ichain >= fMCMCNChains)
00562       return 0;
00563 
00564    // check if ipar is in range
00565    if (ipar < 0 || ipar >= fMCMCNParameters)
00566       return 0;
00567 
00568    // return component of jth point in the ith chain
00569    return fMCMCx.at(ichain *  fMCMCNParameters + ipar);
00570 }
00571 
00572 // --------------------------------------------------------
00573 double BCEngineMCMC::MCMCGetLogProbx(int ichain)
00574 {
00575    // check if ichain is in range
00576    if (ichain < 0 || ichain >= fMCMCNChains)
00577       return -1;
00578 
00579    // return log of the probability at the current point in the ith chain
00580    return fMCMCprob.at(ichain);
00581 }
00582 
00583 // --------------------------------------------------------
00584 bool BCEngineMCMC::MCMCGetProposalPointMetropolis(int chain, std::vector <double> &x)
00585 {
00586    // get unscaled random point. this point might not be in the correct volume.
00587    MCMCTrialFunction(chain, x);
00588 
00589    // get a proposal point from the trial function and scale it
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    // check if the point is in the correct volume.
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    // get unscaled random point in the dimension of the chosen
00605    // parameter. this point might not be in the correct volume.
00606    double proposal = MCMCTrialFunctionSingle(ichain, ipar);
00607 
00608    // copy the old point into the new
00609    for (int i = 0; i < fMCMCNParameters; ++i)
00610       x[i] = fMCMCx[ichain * fMCMCNParameters + i];
00611 
00612    // modify the parameter under study
00613    x[ipar] += proposal * (fMCMCBoundaryMax[ipar] - fMCMCBoundaryMin[ipar]);
00614 
00615    // check if the point is in the correct volume.
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    // calculate index
00626    int index = chain * fMCMCNParameters;
00627 
00628    fMCMCCurrentChain = chain;
00629 
00630    // increase counter
00631    fMCMCNIterations[chain]++;
00632 
00633    // get proposal point
00634    if (!MCMCGetProposalPointMetropolis(chain, parameter, fMCMCxLocal))
00635    {
00636       // increase counter
00637       fMCMCNTrialsFalse[chain * fMCMCNParameters + parameter]++;
00638 
00639       // execute user code for every point
00640       MCMCCurrentPointInterface(fMCMCxLocal, chain, false);
00641 
00642       return false;
00643    }
00644 
00645    // calculate probabilities of the old and new points
00646    double p0 = fMCMCprob[chain];
00647    double p1 = LogEval(fMCMCxLocal);
00648 
00649    // flag for accept
00650    bool accept = false;
00651 
00652    // if the new point is more probable, keep it ...
00653    if (p1 >= p0)
00654       accept = true;
00655    // ... or else throw dice.
00656    else
00657    {
00658       double r = log(fRandom->Rndm());
00659 
00660       if(r < p1 - p0)
00661          accept = true;
00662    }
00663 
00664    // fill the new point
00665    if(accept)
00666    {
00667       // increase counter
00668       fMCMCNTrialsTrue[chain * fMCMCNParameters + parameter]++;
00669 
00670       // copy the point
00671       for(int i = 0; i < fMCMCNParameters; ++i)
00672       {
00673          // save the point
00674          fMCMCx[index + i] = fMCMCxLocal[i];
00675 
00676          // save the probability of the point
00677          fMCMCprob[chain] = p1;
00678       }
00679    }
00680    else
00681    {
00682       // increase counter
00683       fMCMCNTrialsFalse[chain * fMCMCNParameters + parameter]++;
00684    }
00685 
00686    // execute user code for every point
00687    MCMCCurrentPointInterface(fMCMCxLocal, chain, accept);
00688 
00689    return accept;
00690 }
00691 
00692 // --------------------------------------------------------
00693 bool BCEngineMCMC::MCMCGetNewPointMetropolis(int chain)
00694 {
00695    // calculate index
00696    int index = chain * fMCMCNParameters;
00697 
00698    fMCMCCurrentChain = chain;
00699 
00700    // increase counter
00701    fMCMCNIterations[chain]++;
00702 
00703    // get proposal point
00704    if (!MCMCGetProposalPointMetropolis(chain, fMCMCxLocal))
00705    {
00706       // increase counter
00707       for (int i = 0; i < fMCMCNParameters; ++i)
00708          fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00709 
00710       // execute user code for every point
00711       MCMCCurrentPointInterface(fMCMCxLocal, chain, false);
00712 
00713       return false;
00714    }
00715 
00716    // calculate probabilities of the old and new points
00717    double p0 = fMCMCprob[chain];
00718    double p1 = LogEval(fMCMCxLocal);
00719 
00720    // flag for accept
00721    bool accept = false;
00722 
00723    // if the new point is more probable, keep it ...
00724    if (p1 >= p0)
00725       accept = true;
00726 
00727    // ... or else throw dice.
00728    else
00729    {
00730       double r = log(fRandom->Rndm());
00731 
00732       if(r < p1 - p0)
00733          accept = true;
00734    }
00735 
00736    // fill the new point
00737    if(accept)
00738    {
00739       // increase counter
00740       for (int i = 0; i < fMCMCNParameters; ++i)
00741          fMCMCNTrialsTrue[chain * fMCMCNParameters + i]++;
00742 
00743       // copy the point
00744       for(int i = 0; i < fMCMCNParameters; ++i)
00745       {
00746          // save the point
00747          fMCMCx[index + i] = fMCMCxLocal[i];
00748 
00749          // save the probability of the point
00750          fMCMCprob[chain] = p1;
00751       }
00752    }
00753    else
00754    {
00755       // increase counter
00756       for (int i = 0; i < fMCMCNParameters; ++i)
00757          fMCMCNTrialsFalse[chain * fMCMCNParameters + i]++;
00758    }
00759 
00760    // execute user code for every point
00761    MCMCCurrentPointInterface(fMCMCxLocal, chain, accept);
00762 
00763    return accept;
00764 }
00765 
00766 // --------------------------------------------------------
00767 void BCEngineMCMC::MCMCInChainCheckMaximum()
00768 {
00769    // loop over all chains
00770    for (int i = 0; i < fMCMCNChains; ++i)
00771    {
00772       // check if new maximum is found or chain is at the beginning
00773       if (fMCMCprob[i] > fMCMCprobMax[i] || fMCMCNIterations[i] == 1)
00774       {
00775          // copy maximum value
00776          fMCMCprobMax[i] = fMCMCprob[i];
00777 
00778          // copy mode of chain
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    // calculate number of entries in this part of the chain
00789    int npoints = fMCMCNTrialsTrue[0] + fMCMCNTrialsFalse[0];
00790 
00791    // length of vectors
00792    int nentries = fMCMCNParameters * fMCMCNChains; 
00793 
00794    // loop over all parameters of all chains
00795    for (int i = 0; i < nentries; ++i) {
00796       // calculate mean value of each parameter in the chain for this part
00797       fMCMCxMean[i] += (fMCMCx[i] - fMCMCxMean[i]) / double(npoints);
00798 
00799       // calculate variance of each chain for this part
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    // loop over chains
00806    for (int i = 0; i < fMCMCNChains; ++i) {
00807       // calculate mean value of each chain for this part
00808       fMCMCprobMean[i] += (fMCMCprob[i] - fMCMCprobMean[i]) / double(npoints);
00809          
00810       // calculate variance of each chain for this part
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    // check if histograms are supposed to be filled
00822    if (!fMCMCFlagFillHistograms)
00823       return;
00824 
00825    // loop over chains
00826    for (int i = 0; i < fMCMCNChains; ++i)
00827    {
00828       // fill each 1-dimensional histogram (if supposed to be filled)
00829       for (int j = 0; j < fMCMCNParameters; ++j)
00830          if (fMCMCFlagsFillHistograms.at(j))
00831             fMCMCH1Marginalized[j]->Fill(fMCMCx[i * fMCMCNParameters + j]);
00832 
00833       // fill each 2-dimensional histogram (if supposed to be filled)
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    // calculate number of entries in this part of the chain
00850    int npoints = fMCMCNTrialsTrue[0] + fMCMCNTrialsFalse[0];
00851 
00852    if (fMCMCNChains > 1 && npoints > 1)
00853    {
00854       // define flag for convergence
00855       bool flag_convergence = true;
00856 
00857       // loop over parameters
00858       for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
00859       {
00860          double sum = 0;
00861          double sum2 = 0;
00862          double sumv = 0;
00863 
00864          // loop over chains
00865          for (int ichains = 0; ichains < fMCMCNChains; ++ichains) {
00866             // get parameter index
00867             int index = ichains * fMCMCNParameters + iparameters;
00868 
00869             // add to sums
00870             sum  += fMCMCxMean[index];
00871             sum2 += fMCMCxMean[index] * fMCMCxMean[index];
00872             sumv += fMCMCxVar[index];
00873          }
00874 
00875          // calculate r-value for each parameter
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          // check denominator and convergence
00881          if (W > 0) {
00882 
00883             fMCMCRValueParameters[iparameters] = MCMCCalculateRValue(
00884                   fMCMCxMean, fMCMCxVar, mean, B, W, npoints, iparameters);
00885             
00886 
00887             // set flag to false if convergence criterion is not fulfilled for the parameter
00888             if (! ((fMCMCRValueParameters[iparameters]-1.0) < fMCMCRValueParametersCriterion))
00889                flag_convergence = false;
00890          }
00891          // else: leave convergence flag true for that parameter
00892       }
00893       // convergence criterion applied on the log-likelihood
00894       double sum = 0;
00895       double sum2 = 0;
00896       double sumv = 0;
00897 
00898       // loop over chains
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       // calculate r-value for log-posterior
00907 
00908       //target mean
00909       double mean = sum / double(fMCMCNChains);
00910       //variance between the sequence means
00911       double B = (sum2 / double(fMCMCNChains) - mean * mean) * double(fMCMCNChains) / double(fMCMCNChains-1) * double(npoints);
00912       //average of within-sequence variances
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          // set flag to false if convergence criterion is not fulfilled for the log-likelihood
00921          if (!((fMCMCRValue - 1.0) < fMCMCRValueCriterion))
00922             flag_convergence = false;
00923       }
00924       // else: leave convergence flag true for the posterior
00925 
00926       // remember number of iterations needed to converge
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    //estimated scale reduction
00939    double r = 0;
00940 
00941    //relaxed R definition
00942    if (!fMCMCRValueUseStrict){
00943       r = sqrt(((1 - 1 / double(nPoints)) * W + 1 / double(nPoints)
00944             * B) / W);
00945       return r;
00946    }
00947    //else: strict R value
00948 
00949    //(co)variances of the chains
00950    double varS = 0;
00951    double cov1 = 0;
00952    double cov2 = 0;
00953 
00954    // loop over chains to estimate (co)variances
00955    for (int i = 0; i < fMCMCNChains; ++i) {
00956       //where is the i-th element? Trickier for parameters
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    //number of chains
00968    double m = double(fMCMCNChains);
00969 
00970    //number of points in each chain
00971    double n = double(nPoints);
00972 
00973    // only m-1 degrees of freedom => unbiased estimators!
00974    varS = (varS / m - W * W) * m / (m - 1);
00975    cov1 = cov1 / (m - 1);
00976    cov2 = cov2 / (m - 1);
00977 
00978    //scale of t-distribution
00979    double V = 1 / n * ((n - 1) * W + (1 + 1 / m) * B);
00980 
00981    //estimate of scale variance
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    //degrees of freedom of t-distribution
00987    double df = 2 * V * V / varV;
00988 
00989    //sqrt of estimated scale reduction if sampling were continued
00990    r = sqrt(V / W * df / (df - 2));
00991 
00992    return r;
00993 }
00994 
00995 // --------------------------------------------------------
00996 void BCEngineMCMC::MCMCInChainWriteChains()
00997 {
00998    // loop over all chains
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    // test function for now
01007    // this will be overloaded by the user
01008    return 0.0;
01009 }
01010 
01011 // --------------------------------------------------------
01012 int BCEngineMCMC::MCMCMetropolisPreRun()
01013 {
01014    // print on screen
01015    BCLog::OutSummary("Pre-run Metropolis MCMC...");
01016 
01017    // initialize Markov chain
01018    MCMCInitialize();
01019    MCMCInitializeMarkovChains();
01020 
01021    // helper variable containing number of digits in the number of parameters
01022    int ndigits = (int)log10(fMCMCNParameters) +1;
01023    if(ndigits<4)
01024       ndigits=4;
01025 
01026    // reset run statistics
01027    MCMCResetRunStatistics();
01028    fMCMCNIterationsConvergenceGlobal = -1;
01029 
01030    // perform run
01031    BCLog::OutSummary(Form(" --> Perform MCMC pre-run with %i chains, each with maximum %i iterations", fMCMCNChains, fMCMCNIterationsMax));
01032 
01033 
01034    // don't write to file during pre run
01035    bool tempflag_writetofile = fMCMCFlagWriteChainToFile;
01036    fMCMCFlagWriteChainToFile = false;
01037 
01038    // initialize counter variables and flags
01039    fMCMCCurrentIteration = 1;   // counts the number of iterations 
01040    int counterupdate = 1;        // after how many iterations is an update needed?
01041    bool convergence = false;     // convergence reached?
01042    bool flagefficiency = false;  // efficiency reached?
01043 
01044    // array of efficiencies
01045    std::vector <double> efficiency;
01046    efficiency.assign(fMCMCNParameters * fMCMCNChains, 0.0);
01047 
01048    // how often to check convergence and efficiencies?
01049    // it's either every fMCMCNParameters*nMCMCNIterationsUpdate (for 5 parameters the default would be 5000)
01050    // or it's fMCMCNIterationsUpdateMax (10000 by default)
01051    // whichever of the two is smaller
01052    int updateLimit = ( fMCMCNIterationsUpdateMax<fMCMCNIterationsUpdate*(fMCMCNParameters)  && fMCMCNIterationsUpdateMax>0 ) ?
01053          fMCMCNIterationsUpdateMax : fMCMCNIterationsUpdate*(fMCMCNParameters);
01054 
01055    // loop over chains
01056    for (int ichains = 0; ichains < fMCMCNChains; ++ichains) {
01057       // loop over parameters
01058       for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter){
01059          // global index of the parameter (throughout all the chains)
01060          int index = ichains * fMCMCNParameters + iparameter;
01061          // reset counters
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    // set phase and cycle number
01072    fMCMCPhase = 1; 
01073    fMCMCCycle = 0;
01074 
01075    // run chain ...
01076    // (a) for at least a minimum number of iterations,
01077    // (b) until a maximum number of iterations is reached,
01078    // (c) or until convergence is reached and the efficiency is in the
01079    //     specified region
01080    while (fMCMCCurrentIteration < fMCMCNIterationsPreRunMin || (fMCMCCurrentIteration < fMCMCNIterationsMax && !(convergence && flagefficiency)))
01081    {
01082       //-------------------------------------------
01083       // reset flags and counters
01084       //-------------------------------------------
01085 
01086       // set convergence to false by default
01087       convergence = false;
01088 
01089       // set number of iterations needed to converge to negative
01090       fMCMCNIterationsConvergenceGlobal = -1;
01091 
01092       //-------------------------------------------
01093       // get new point in n-dim space
01094       //-------------------------------------------
01095 
01096       // if the flag is set then run over the parameters one after the other.
01097       if (fMCMCFlagOrderParameters)
01098       {
01099          // loop over parameters
01100          for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01101          {
01102             // loop over chains
01103             for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01104                MCMCGetNewPointMetropolis(ichains, iparameters);
01105 
01106             // search for global maximum
01107             MCMCInChainCheckMaximum();
01108          } 
01109       } 
01110 
01111       // if the flag is not set then run over the parameters at the same time.
01112       else
01113       {
01114          // loop over chains
01115          for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01116             // get new point
01117             MCMCGetNewPointMetropolis(ichains);
01118 
01119          // search for global maximum
01120          MCMCInChainCheckMaximum();
01121       }
01122 
01123       //-------------------------------------------
01124       // print out message to log
01125       //-------------------------------------------
01126 
01127       // progress printout
01128       if ( fMCMCCurrentIteration > 0 && fMCMCCurrentIteration % fMCMCNIterationsUpdate == 0 )
01129          BCLog::OutDetail(Form(" --> Iteration %i", fMCMCNIterations[0]/fMCMCNParameters));
01130 
01131       //-------------------------------------------
01132       // update statistics
01133       //-------------------------------------------
01134 
01135       if (counterupdate > 1) 
01136          MCMCInChainUpdateStatistics(); 
01137 
01138       //-------------------------------------------
01139       // update scale factors and check convergence
01140       //-------------------------------------------
01141 
01142       // debugKK 
01143       // check if this line makes sense
01144       if ( counterupdate % updateLimit == 0 && counterupdate > 0 && fMCMCCurrentIteration >= fMCMCNIterationsPreRunMin)
01145 //    if ( fMCMCCurrentIteration % fMCMCNIterationsUpdate == 0 && counterupdate > 1 && fMCMCCurrentIteration >= fMCMCNIterationsPreRunMin)
01146       {
01147          // -----------------------------
01148          // reset flags and counters
01149          // -----------------------------
01150 
01151          bool rvalues_ok = true;
01152 
01153          static bool has_converged = false;
01154 
01155          // reset the number of iterations needed for convergence to
01156          // negative
01157          fMCMCNIterationsConvergenceGlobal = -1;
01158 
01159          // -----------------------------
01160          // check convergence status
01161          // -----------------------------
01162 
01163          // test convergence 
01164          MCMCInChainTestConvergenceAllChains();
01165 
01166          // set convergence flag
01167          if (fMCMCNIterationsConvergenceGlobal > 0)
01168             convergence = true;
01169 
01170          // print convergence status:
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          // set convergence flag
01198          if(!has_converged)
01199             if(rvalues_ok)
01200                has_converged = true;
01201 
01202          // -----------------------------
01203          // check efficiency status
01204          // -----------------------------
01205 
01206          // set flag
01207          flagefficiency = true;
01208 
01209          bool flagprintefficiency = true;
01210 
01211          // loop over chains
01212          for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01213          {
01214             // loop over parameters
01215             for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter)
01216             {
01217                // global index of the parameter (throughout all the chains)
01218                int index = ichains * fMCMCNParameters + iparameter;
01219 
01220                // calculate efficiency
01221                efficiency[index] = double(fMCMCNTrialsTrue[index]) / double(fMCMCNTrialsTrue[index] + fMCMCNTrialsFalse[index]);
01222 
01223                // adjust scale factors if efficiency is too low
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                // adjust scale factors if efficiency is too high
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                // check flag
01259                if ((efficiency[index] < fMCMCEfficiencyMin && fMCMCTrialFunctionScaleFactor[index] > .01)
01260                      || (efficiency[index] > fMCMCEfficiencyMax && fMCMCTrialFunctionScaleFactor[index] < 1.))
01261                   flagefficiency = false;
01262             } // end of running over all parameters
01263          } // end of running over all chains
01264          
01265          // print to screen
01266          if (flagefficiency)
01267             BCLog::OutDetail(Form("     * Efficiency status: Efficiencies within pre-defined ranges."));
01268 
01269          // -----------------------------
01270          // reset counters
01271          // -----------------------------
01272          
01273          counterupdate = 0; 
01274 
01275          // loop over chains
01276          for (int ichains = 0; ichains < fMCMCNChains; ++ichains) {
01277             // loop over parameters
01278             for (int iparameter = 0; iparameter < fMCMCNParameters; ++iparameter){
01279                // global index of the parameter (throughout all the chains)
01280                int index = ichains * fMCMCNParameters + iparameter;
01281                // reset counters
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       } // end if update scale factors and check convergence
01291 
01292       //-------------------------------------------
01293       // write chain to file
01294       //-------------------------------------------
01295 
01296       // write chain to file
01297       if (fMCMCFlagWritePreRunToFile)
01298          MCMCInChainWriteChains();
01299 
01300       //-------------------------------------------
01301       // increase counters
01302       //-------------------------------------------
01303 
01304       if (counterupdate == 0 && fMCMCCurrentIteration > 1)
01305         fMCMCCycle++;
01306       fMCMCCurrentIteration++;
01307       counterupdate++;
01308 
01309    } // end of running
01310 
01311    // decrease counter by one since it didn't really run that long
01312    // fMCMCCurrentIteration--;
01313    // counterupdate--;
01314 
01315    // did we check convergence at least once ?
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    // after chain run
01325    // ---------------
01326 
01327    // define convergence status
01328    if (fMCMCNIterationsConvergenceGlobal > 0)
01329       fMCMCFlagConvergenceGlobal = true;
01330    else
01331       fMCMCFlagConvergenceGlobal = false;
01332 
01333    // print convergence status
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    // print efficiencies
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    // print scale factors
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    // reset flag
01387    fMCMCFlagWriteChainToFile = tempflag_writetofile;
01388 
01389    // reset current iteration
01390    fMCMCCurrentIteration = -1;
01391 
01392    // reset current chain
01393    fMCMCCurrentChain = -1;
01394 
01395    // no error
01396    return 1;
01397 }
01398 
01399 // --------------------------------------------------------
01400 int BCEngineMCMC::MCMCMetropolis()
01401 {
01402    // check if prerun should be performed
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    // print to screen
01409    BCLog::OutSummary( "Run Metropolis MCMC...");
01410 
01411    // reset run statistics
01412    MCMCResetRunStatistics();
01413 
01414    // set phase and cycle number
01415    fMCMCPhase = 2; 
01416    fMCMCCycle = 0;
01417       
01418    // perform run
01419    BCLog::OutSummary(Form(" --> Perform MCMC run with %i chains, each with %i iterations.", fMCMCNChains, fMCMCNIterationsRun));
01420 
01421 // int counterupdate = 0;
01422 // bool convergence = false;
01423 // bool flagefficiency = false;
01424 
01425 // std::vector <double> efficiency;
01426 
01427 // for (int i = 0; i < fMCMCNParameters; ++i)
01428 //    for (int j = 0; j < fMCMCNChains; ++j)
01429 //       efficiency.push_back(0.0);
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    // start the run
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       // if the flag is set then run over the parameters one after the other.
01448       if (fMCMCFlagOrderParameters)
01449       {
01450          // loop over parameters
01451          for (int iparameters = 0; iparameters < fMCMCNParameters; ++iparameters)
01452          {
01453             // loop over chains
01454             for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01455                MCMCGetNewPointMetropolis(ichains, iparameters);
01456 
01457             // reset current chain
01458             fMCMCCurrentChain = -1;
01459 
01460             // update search for maximum
01461             MCMCInChainCheckMaximum();
01462 
01463          } // end loop over all parameters
01464 
01465          // check if the current iteration is consistent with the lag
01466          if ( fMCMCCurrentIteration % fMCMCNLag == 0)
01467          {
01468             // fill histograms
01469             MCMCInChainFillHistograms();
01470                
01471             // write chain to file
01472             if (fMCMCFlagWriteChainToFile)
01473                MCMCInChainWriteChains();
01474 
01475             // do anything interface
01476             MCMCIterationInterface();
01477          }
01478       }
01479       // if the flag is not set then run over the parameters at the same time.
01480       else
01481       {
01482          // loop over chains
01483          for (int ichains = 0; ichains < fMCMCNChains; ++ichains)
01484             // get new point
01485             MCMCGetNewPointMetropolis(ichains);
01486 
01487          // reset current chain
01488          fMCMCCurrentChain = -1;
01489                
01490          // update search for maximum
01491          MCMCInChainCheckMaximum();
01492 
01493          // check if the current iteration is consistent with the lag
01494          if (fMCMCCurrentIteration % fMCMCNLag == 0)
01495          {
01496             // fill histograms
01497             MCMCInChainFillHistograms();
01498 
01499             // write chain to file
01500             if (fMCMCFlagWriteChainToFile)
01501                MCMCInChainWriteChains();
01502 
01503             // do anything interface
01504             MCMCIterationInterface();
01505          }
01506       }
01507 
01508    } // end run
01509 
01510    // print convergence status
01511    BCLog::OutSummary(Form(" --> Markov chains ran for %i iterations.", fMCMCNIterationsRun));
01512 
01513    // print modes
01514 
01515    // find global maximum
01516    double probmax = fMCMCprobMax.at(0);
01517    int probmaxindex = 0;
01518 
01519    // loop over all chains and find the maximum point
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    // reset coutner
01536    fMCMCCurrentIteration = -1;
01537 
01538    // reset current chain
01539    fMCMCCurrentChain = -1;
01540 
01541    // set flags
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    // reset marginalized distributions
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    // add the boundaries to the corresponding vectors
01581    fMCMCBoundaryMin.push_back(min);
01582    fMCMCBoundaryMax.push_back(max);
01583 
01584    // set flag for individual parameters
01585    fMCMCFlagsFillHistograms.push_back(true);
01586 
01587    // increase the number of parameters by one
01588    fMCMCNParameters++;
01589 
01590    // return the number of parameters
01591    return fMCMCNParameters;
01592 }
01593 
01594 // --------------------------------------------------------
01595 void BCEngineMCMC::MCMCInitializeMarkovChains()
01596 {
01597    // evaluate function at the starting point
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    // reset variables
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    // clear plots
01639    fMCMCH1Marginalized.clear();
01640    fMCMCH2Marginalized.clear();
01641 
01642    // reset flags
01643    fMCMCFlagPreRun = true;
01644    fMCMCFlagRun = false;
01645    fMCMCFlagConvergenceGlobal = false;
01646 
01647    // no errors
01648    return 1;
01649 }
01650 
01651 // --------------------------------------------------------
01652 int BCEngineMCMC::MCMCInitialize()
01653 {
01654    // reset values
01655    MCMCResetResults(); 
01656 
01657    // free memory for vectors
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    // set initial position
01680    if (fMCMCFlagInitialPosition == 2) // user defined points
01681    {
01682       // define flag
01683       bool flag = true;
01684 
01685       // check the length of the array of initial positions
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       // check the boundaries
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       // check flag
01706       if (!flag)
01707          fMCMCFlagInitialPosition = 1;
01708    }
01709 
01710    if (fMCMCFlagInitialPosition == 0) // center of the interval
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) // user defined
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) // random number (default)
01724          for (int i = 0; i < fMCMCNParameters; ++i)
01725             fMCMCx.push_back(fMCMCBoundaryMin[i] + fRandom->Rndm() * (fMCMCBoundaryMax[i] - fMCMCBoundaryMin[i]));
01726 
01727    // copy the point of the first chain
01728    fMCMCxLocal.clear();
01729    for (int i = 0; i < fMCMCNParameters; ++i)
01730       fMCMCxLocal.push_back(fMCMCx[i]);
01731 
01732    // define 1-dimensional histograms for marginalization
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    // search for correct combination
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 

Generated by  doxygen 1.7.1