00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "config.h"
00011
00012 #include "BCIntegrate.h"
00013 #include "BCLog.h"
00014 #include "BCMath.h"
00015
00016 #include <TH1D.h>
00017 #include <TH2D.h>
00018 #include <TMinuit.h>
00019 #include <TRandom3.h>
00020 #include <TTree.h>
00021
00022 #ifdef HAVE_CUBA_H
00023 #include "cuba.h"
00024 #endif
00025
00026
00027
00028 class BCIntegrate * global_this;
00029
00030
00031 BCIntegrate::BCIntegrate()
00032 : BCEngineMCMC()
00033 , fNvar(0)
00034 , fNbins(100)
00035 , fNSamplesPer2DBin(100)
00036 , fMarkovChainStepSize(0.1)
00037 , fMarkovChainAutoN(true)
00038 , fDataPointLowerBoundaries(0)
00039 , fDataPointUpperBoundaries(0)
00040 , fFillErrorBand(false)
00041 , fFitFunctionIndexX(-1)
00042 , fFitFunctionIndexY(-1)
00043 , fErrorBandContinuous(true)
00044 , fErrorBandNbinsX(100)
00045 , fErrorBandNbinsY(500)
00046 , fMinuit(0)
00047 , fFlagIgnorePrevOptimization(false)
00048 , fFlagWriteMarkovChain(false)
00049 , fMarkovChainTree(0)
00050 , fSAT0(100)
00051 , fSATmin(0.1)
00052 , fTreeSA(0)
00053 , fFlagWriteSAToFile(false)
00054
00055 , fNiterPerDimension(100)
00056 #ifdef HAVE_CUBA_H
00057 , fIntegrationMethod(BCIntegrate::kIntCuba)
00058 #else
00059 , fIntegrationMethod(BCIntegrate::kIntMonteCarlo)
00060 #endif
00061 , fMarginalizationMethod(BCIntegrate::kMargMetropolis)
00062 , fOptimizationMethod(BCIntegrate::kOptMinuit)
00063 , fOptimizationMethodMode(BCIntegrate::kOptMinuit)
00064 , fSASchedule(BCIntegrate::kSACauchy)
00065 , fNIterationsMax(1000000)
00066 , fNIterations(0)
00067 , fRelativePrecision(1e-3)
00068 , fAbsolutePrecision(1e-12)
00069 , fCubaIntegrationMethod(BCIntegrate::kCubaVegas)
00070 , fCubaMinEval(0)
00071 , fCubaMaxEval(2000000)
00072 , fCubaVerbosity(0)
00073 , fCubaVegasNStart(25000)
00074 , fCubaVegasNIncrease(25000)
00075 , fCubaSuaveNNew(10000)
00076 , fCubaSuaveFlatness(50)
00077 , fError(-999.)
00078 {
00079 fMinuitArglist[0] = 20000;
00080 fMinuitArglist[1] = 0.01;
00081 }
00082
00083
00084 BCIntegrate::BCIntegrate(BCParameterSet * par)
00085 : BCEngineMCMC()
00086 , fNvar(0)
00087 , fNbins(100)
00088 , fNSamplesPer2DBin(100)
00089 , fMarkovChainStepSize(0.1)
00090 , fMarkovChainAutoN(true)
00091 , fDataPointLowerBoundaries(0)
00092 , fDataPointUpperBoundaries(0)
00093 , fFillErrorBand(false)
00094 , fFitFunctionIndexX(-1)
00095 , fFitFunctionIndexY(-1)
00096 , fErrorBandContinuous(true)
00097 , fErrorBandNbinsX(100)
00098 , fErrorBandNbinsY(500)
00099 , fMinuit(0)
00100 , fFlagIgnorePrevOptimization(false)
00101 , fFlagWriteMarkovChain(false)
00102 , fMarkovChainTree(0)
00103 , fSAT0(100)
00104 , fSATmin(0.1)
00105 , fTreeSA(0)
00106 , fFlagWriteSAToFile(false)
00107
00108 , fNiterPerDimension(100)
00109 #ifdef HAVE_CUBA_H
00110 , fIntegrationMethod(BCIntegrate::kIntCuba)
00111 #else
00112 , fIntegrationMethod(BCIntegrate::kIntMonteCarlo)
00113 #endif
00114 , fMarginalizationMethod(BCIntegrate::kMargMetropolis)
00115 , fOptimizationMethod(BCIntegrate::kOptMinuit)
00116 , fOptimizationMethodMode(BCIntegrate::kOptMinuit)
00117 , fSASchedule(BCIntegrate::kSACauchy)
00118 , fNIterationsMax(1000000)
00119 , fNIterations(0)
00120 , fRelativePrecision(1e-3)
00121 , fAbsolutePrecision(1e-12)
00122 , fCubaIntegrationMethod(BCIntegrate::kCubaVegas)
00123 , fCubaMinEval(0)
00124 , fCubaMaxEval(2000000)
00125 , fCubaVerbosity(0)
00126 , fCubaVegasNStart(25000)
00127 , fCubaVegasNIncrease(25000)
00128 , fCubaSuaveNNew(10000)
00129 , fCubaSuaveFlatness(50)
00130 , fError(-999.)
00131 {
00132 SetParameters(par);
00133
00134 fMinuitArglist[0] = 20000;
00135 fMinuitArglist[1] = 0.01;
00136 }
00137
00138
00139 BCIntegrate::BCIntegrate(const BCIntegrate & bcintegrate) : BCEngineMCMC(bcintegrate)
00140 {
00141 fNvar = bcintegrate.fNvar;
00142 fNbins = bcintegrate.fNbins;
00143 fNSamplesPer2DBin = bcintegrate.fNSamplesPer2DBin;
00144 fMarkovChainStepSize = bcintegrate.fMarkovChainStepSize;
00145 fMarkovChainNIterations = bcintegrate.fMarkovChainNIterations;
00146 fMarkovChainAutoN = bcintegrate.fMarkovChainAutoN;
00147 if (bcintegrate.fDataPointLowerBoundaries)
00148 fDataPointLowerBoundaries = new BCDataPoint(*bcintegrate.fDataPointLowerBoundaries);
00149 else
00150 fDataPointLowerBoundaries = 0;
00151 if (bcintegrate.fDataPointUpperBoundaries)
00152 fDataPointUpperBoundaries = new BCDataPoint(*bcintegrate.fDataPointUpperBoundaries);
00153 else
00154 fDataPointUpperBoundaries = 0;
00155 fDataFixedValues = bcintegrate.fDataFixedValues;
00156 fBestFitParameters = bcintegrate.fBestFitParameters;
00157 fBestFitParameterErrors = bcintegrate.fBestFitParameterErrors;
00158 fBestFitParametersMarginalized = bcintegrate.fBestFitParametersMarginalized;
00159 for (int i = 0; i < int(bcintegrate.fHProb1D.size()); ++i) {
00160 if (bcintegrate.fHProb1D.at(i))
00161 fHProb1D.push_back(new TH1D(*(bcintegrate.fHProb1D.at(i))));
00162 else
00163 fHProb1D.push_back(0);
00164 }
00165 for (int i = 0; i < int(bcintegrate.fHProb2D.size()); ++i) {
00166 if (bcintegrate.fHProb2D.at(i))
00167 fHProb2D.push_back(new TH2D(*(fHProb2D.at(i))));
00168 else
00169 fHProb2D.push_back(0);
00170 }
00171 fFillErrorBand = bcintegrate.fFillErrorBand;
00172 fFitFunctionIndexX = bcintegrate.fFitFunctionIndexX;
00173 fFitFunctionIndexY = bcintegrate.fFitFunctionIndexY;
00174 fErrorBandX = bcintegrate.fErrorBandX;
00175 if (bcintegrate.fErrorBandXY)
00176 fErrorBandXY = new TH2D(*(bcintegrate.fErrorBandXY));
00177 else
00178 fErrorBandXY = 0;
00179 fErrorBandNbinsX = bcintegrate.fErrorBandNbinsX;
00180 fErrorBandNbinsY = bcintegrate.fErrorBandNbinsY;
00181 fMinuit = new TMinuit();
00182
00183
00184 fMinuitArglist[0] = bcintegrate.fMinuitArglist[0];
00185 fMinuitArglist[1] = bcintegrate.fMinuitArglist[1];
00186 fMinuitErrorFlag = bcintegrate.fMinuitErrorFlag;
00187 fFlagIgnorePrevOptimization = bcintegrate.fFlagIgnorePrevOptimization;
00188 fFlagWriteMarkovChain = bcintegrate.fFlagWriteMarkovChain;
00189 fMarkovChainTree = bcintegrate.fMarkovChainTree;
00190 fMCMCIteration = bcintegrate.fMCMCIteration;
00191 fSAT0 = bcintegrate.fSAT0;
00192 fSATmin = bcintegrate.fSATmin;
00193
00194 fTreeSA = 0;
00195 fFlagWriteSAToFile = bcintegrate.fFlagWriteSAToFile;
00196 fSANIterations = bcintegrate.fSANIterations;
00197 fSATemperature = bcintegrate.fSATemperature;
00198 fSALogProb = bcintegrate.fSALogProb;
00199 fSAx = bcintegrate.fSAx;
00200 if (bcintegrate.fx)
00201 fx = new BCParameterSet(*(bcintegrate.fx));
00202 else
00203 fx = 0;
00204 fMin = new double[fNvar];
00205 fMax = new double[fNvar];
00206 fVarlist = new int[fNvar];
00207 fMin = bcintegrate.fMin;
00208 fMax = bcintegrate.fMax;
00209 fVarlist = bcintegrate.fVarlist;
00210 fNiterPerDimension = bcintegrate.fNiterPerDimension;
00211 fIntegrationMethod = bcintegrate.fIntegrationMethod;
00212 fMarginalizationMethod = bcintegrate.fMarginalizationMethod;
00213 fOptimizationMethod = bcintegrate.fOptimizationMethod;
00214 fOptimizationMethodMode = bcintegrate.fOptimizationMethodMode;
00215 fSASchedule = bcintegrate.fSASchedule;
00216 fNIterationsMax = bcintegrate.fNIterationsMax;
00217 fNIterations = bcintegrate.fNIterations;
00218 fRelativePrecision = bcintegrate.fRelativePrecision;
00219 fAbsolutePrecision = bcintegrate.fAbsolutePrecision;
00220 fCubaIntegrationMethod = bcintegrate.fCubaIntegrationMethod;
00221 fCubaMinEval = bcintegrate.fCubaMinEval;
00222 fCubaMaxEval = bcintegrate.fCubaMaxEval;
00223 fCubaVerbosity = bcintegrate.fCubaVerbosity;
00224 fCubaVegasNStart = bcintegrate.fCubaVegasNStart;
00225 fCubaVegasNIncrease = bcintegrate.fCubaVegasNIncrease;
00226 fCubaSuaveNNew = bcintegrate.fCubaSuaveNNew;
00227 fCubaSuaveFlatness = bcintegrate.fCubaSuaveFlatness;
00228 fError = bcintegrate.fError;
00229 fNmetro = bcintegrate.fNmetro;
00230 fNacceptedMCMC = bcintegrate.fNacceptedMCMC;
00231 fXmetro0 = bcintegrate.fXmetro0;
00232 fXmetro1 = bcintegrate.fXmetro1;
00233 fMarkovChainValue = bcintegrate.fMarkovChainValue;
00234 }
00235
00236
00237 BCIntegrate & BCIntegrate::operator = (const BCIntegrate & bcintegrate)
00238 {
00239 BCEngineMCMC::operator=(bcintegrate);
00240
00241 fNvar = bcintegrate.fNvar;
00242 fNbins = bcintegrate.fNbins;
00243 fNSamplesPer2DBin = bcintegrate.fNSamplesPer2DBin;
00244 fMarkovChainStepSize = bcintegrate.fMarkovChainStepSize;
00245 fMarkovChainNIterations = bcintegrate.fMarkovChainNIterations;
00246 fMarkovChainAutoN = bcintegrate.fMarkovChainAutoN;
00247 if (bcintegrate.fDataPointLowerBoundaries)
00248 fDataPointLowerBoundaries = new BCDataPoint(*bcintegrate.fDataPointLowerBoundaries);
00249 else
00250 fDataPointLowerBoundaries = 0;
00251 if (bcintegrate.fDataPointUpperBoundaries)
00252 fDataPointUpperBoundaries = new BCDataPoint(*bcintegrate.fDataPointUpperBoundaries);
00253 else
00254 fDataPointUpperBoundaries = 0;
00255 fDataFixedValues = bcintegrate.fDataFixedValues;
00256 fBestFitParameters = bcintegrate.fBestFitParameters;
00257 fBestFitParameterErrors = bcintegrate.fBestFitParameterErrors;
00258 fBestFitParametersMarginalized = bcintegrate.fBestFitParametersMarginalized;
00259 for (int i = 0; i < int(bcintegrate.fHProb1D.size()); ++i) {
00260 if (bcintegrate.fHProb1D.at(i))
00261 fHProb1D.push_back(new TH1D(*(bcintegrate.fHProb1D.at(i))));
00262 else
00263 fHProb1D.push_back(0);
00264 }
00265 for (int i = 0; i < int(bcintegrate.fHProb2D.size()); ++i) {
00266 if (bcintegrate.fHProb2D.at(i))
00267 fHProb2D.push_back(new TH2D(*(fHProb2D.at(i))));
00268 else
00269 fHProb2D.push_back(0);
00270 }
00271 fFillErrorBand = bcintegrate.fFillErrorBand;
00272 fFitFunctionIndexX = bcintegrate.fFitFunctionIndexX;
00273 fFitFunctionIndexY = bcintegrate.fFitFunctionIndexY;
00274 fErrorBandX = bcintegrate.fErrorBandX;
00275 if (bcintegrate.fErrorBandXY)
00276 fErrorBandXY = new TH2D(*(bcintegrate.fErrorBandXY));
00277 else
00278 fErrorBandXY = 0;
00279 fErrorBandNbinsX = bcintegrate.fErrorBandNbinsX;
00280 fErrorBandNbinsY = bcintegrate.fErrorBandNbinsY;
00281 fMinuit = new TMinuit();
00282
00283
00284 fMinuitArglist[0] = bcintegrate.fMinuitArglist[0];
00285 fMinuitArglist[1] = bcintegrate.fMinuitArglist[1];
00286 fMinuitErrorFlag = bcintegrate.fMinuitErrorFlag;
00287 fFlagIgnorePrevOptimization = bcintegrate.fFlagIgnorePrevOptimization;
00288 fFlagWriteMarkovChain = bcintegrate.fFlagWriteMarkovChain;
00289 fMarkovChainTree = bcintegrate.fMarkovChainTree;
00290 fMCMCIteration = bcintegrate.fMCMCIteration;
00291 fSAT0 = bcintegrate.fSAT0;
00292 fSATmin = bcintegrate.fSATmin;
00293
00294 fTreeSA = 0;
00295 fFlagWriteSAToFile = bcintegrate.fFlagWriteSAToFile;
00296 fSANIterations = bcintegrate.fSANIterations;
00297 fSATemperature = bcintegrate.fSATemperature;
00298 fSALogProb = bcintegrate.fSALogProb;
00299 fSAx = bcintegrate.fSAx;
00300 if (bcintegrate.fx)
00301 fx = new BCParameterSet(*(bcintegrate.fx));
00302 else
00303 fx = 0;
00304 fMin = new double[fNvar];
00305 fMax = new double[fNvar];
00306 fVarlist = new int[fNvar];
00307 fNiterPerDimension = bcintegrate.fNiterPerDimension;
00308 fIntegrationMethod = bcintegrate.fIntegrationMethod;
00309 fMarginalizationMethod = bcintegrate.fMarginalizationMethod;
00310 fOptimizationMethod = bcintegrate.fOptimizationMethod;
00311 fOptimizationMethodMode = bcintegrate.fOptimizationMethodMode;
00312 fSASchedule = bcintegrate.fSASchedule;
00313
00314 fNIterationsMax = bcintegrate.fNIterationsMax;
00315 fNIterations = bcintegrate.fNIterations;
00316 fRelativePrecision = bcintegrate.fRelativePrecision;
00317 fAbsolutePrecision = bcintegrate.fAbsolutePrecision;
00318 fCubaIntegrationMethod = bcintegrate.fCubaIntegrationMethod;
00319 fCubaMinEval = bcintegrate.fCubaMinEval;
00320 fCubaMaxEval = bcintegrate.fCubaMaxEval;
00321 fCubaVerbosity = bcintegrate.fCubaVerbosity;
00322 fCubaVegasNStart = bcintegrate.fCubaVegasNStart;
00323 fCubaVegasNIncrease = bcintegrate.fCubaVegasNIncrease;
00324 fCubaSuaveNNew = bcintegrate.fCubaSuaveNNew;
00325 fCubaSuaveFlatness = bcintegrate.fCubaSuaveFlatness;
00326 fError = bcintegrate.fError;
00327 fNmetro = bcintegrate.fNmetro;
00328 fNacceptedMCMC = bcintegrate.fNacceptedMCMC;
00329 fXmetro0 = bcintegrate.fXmetro0;
00330 fXmetro1 = bcintegrate.fXmetro1;
00331 fMarkovChainValue = bcintegrate.fMarkovChainValue;
00332
00333
00334 return *this;
00335 }
00336
00337
00338 BCIntegrate::~BCIntegrate()
00339 {
00340 DeleteVarList();
00341
00342 fx=0;
00343
00344 if (fMinuit)
00345 delete fMinuit;
00346
00347 int n1 = fHProb1D.size();
00348 if(n1>0) {
00349 for (int i=0;i<n1;i++)
00350 delete fHProb1D.at(i);
00351 }
00352
00353 int n2 = fHProb2D.size();
00354 if(n2>0) {
00355 for (int i=0;i<n2;i++)
00356 delete fHProb2D.at(i);
00357 }
00358 }
00359
00360
00361 void BCIntegrate::SetParameters(BCParameterSet * par)
00362 {
00363 DeleteVarList();
00364
00365 fx = par;
00366 fNvar = fx->size();
00367 fMin = new double[fNvar];
00368 fMax = new double[fNvar];
00369 fVarlist = new int[fNvar];
00370
00371 ResetVarlist(1);
00372
00373 for(int i=0;i<fNvar;i++) {
00374 fMin[i]=(fx->at(i))->GetLowerLimit();
00375 fMax[i]=(fx->at(i))->GetUpperLimit();
00376 }
00377
00378 fXmetro0.clear();
00379 for(int i=0;i<fNvar;i++)
00380 fXmetro0.push_back((fMin[i]+fMax[i])/2.0);
00381
00382 fXmetro1.clear();
00383 fXmetro1.assign(fNvar,0.);
00384
00385 fMCMCBoundaryMin.clear();
00386 fMCMCBoundaryMax.clear();
00387
00388 for(int i=0;i<fNvar;i++) {
00389 fMCMCBoundaryMin.push_back(fMin[i]);
00390 fMCMCBoundaryMax.push_back(fMax[i]);
00391 fMCMCFlagsFillHistograms.push_back(true);
00392 }
00393
00394 for (int i = int(fMCMCH1NBins.size()); i<fNvar; ++i)
00395 fMCMCH1NBins.push_back(100);
00396
00397 fMCMCNParameters = fNvar;
00398 }
00399
00400
00401 void BCIntegrate::SetMarkovChainInitialPosition(std::vector<double> position)
00402 {
00403 int n = position.size();
00404
00405 fXmetro0.clear();
00406
00407 for (int i = 0; i < n; ++i)
00408 fXmetro0.push_back(position.at(i));
00409 }
00410
00411
00412 void BCIntegrate::DeleteVarList()
00413 {
00414 if(fNvar) {
00415 delete[] fVarlist;
00416 fVarlist=0;
00417
00418 delete[] fMin;
00419 fMin=0;
00420
00421 delete[] fMax;
00422 fMax=0;
00423
00424 fx=0;
00425 fNvar=0;
00426 }
00427 }
00428
00429
00430 void BCIntegrate::SetNbins(int nbins, int index)
00431 {
00432 if (fNvar == 0)
00433 return;
00434
00435
00436 if (index >= fNvar) {
00437 BCLog::OutWarning("BCIntegrate::SetNbins : Index out of range.");
00438 return;
00439 }
00440
00441 else if (index < 0) {
00442 for (int i = 0; i < fNvar; ++i)
00443 SetNbins(nbins, i);
00444 return;
00445 }
00446
00447
00448 if (nbins <= 0)
00449 nbins = 10;
00450
00451 fMCMCH1NBins[index] = nbins;
00452
00453 return;
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 void BCIntegrate::SetVarList(int * varlist)
00492 {
00493 for(int i=0;i<fNvar;i++)
00494 fVarlist[i]=varlist[i];
00495 }
00496
00497
00498 void BCIntegrate::ResetVarlist(int v)
00499 {
00500 for(int i=0;i<fNvar;i++)
00501 fVarlist[i]=v;
00502 }
00503
00504
00505 double BCIntegrate::Eval(std::vector <double> x)
00506 {
00507 BCLog::OutWarning( "BCIntegrate::Eval. No function. Function needs to be overloaded.");
00508 return 0;
00509 }
00510
00511
00512 double BCIntegrate::LogEval(std::vector <double> x)
00513 {
00514
00515 return log(Eval(x));
00516 }
00517
00518
00519 double BCIntegrate::EvalSampling(std::vector <double> x)
00520 {
00521 BCLog::OutWarning( "BCIntegrate::EvalSampling. No function. Function needs to be overloaded.");
00522 return 0;
00523 }
00524
00525
00526 double BCIntegrate::LogEvalSampling(std::vector <double> x)
00527 {
00528 return log(EvalSampling(x));
00529 }
00530
00531
00532 double BCIntegrate::EvalPrint(std::vector <double> x)
00533 {
00534 double val=Eval(x);
00535 BCLog::OutDebug(Form("BCIntegrate::EvalPrint. Value: %g.", val));
00536
00537 return val;
00538 }
00539
00540
00541 void BCIntegrate::SetIntegrationMethod(BCIntegrate::BCIntegrationMethod method)
00542 {
00543 #ifdef HAVE_CUBA_H
00544 fIntegrationMethod = method;
00545 #else
00546 BCLog::OutWarning("!!! This version of BAT is compiled without Cuba.");
00547 BCLog::OutWarning(" Monte Carlo Sampled Mean integration method will be used.");
00548 BCLog::OutWarning(" To be able to use Cuba integration, install Cuba and recompile BAT.");
00549 #endif
00550 }
00551
00552
00553 int BCIntegrate::IntegrateResetResults()
00554 {
00555 fBestFitParameters.clear();
00556 fBestFitParameterErrors.clear();
00557 fBestFitParametersMarginalized.clear();
00558
00559
00560 return 1;
00561 }
00562
00563
00564 double BCIntegrate::Integrate()
00565 {
00566 std::vector <double> parameter;
00567 parameter.assign(fNvar, 0.0);
00568
00569 BCLog::OutSummary(
00570 Form("Running numerical integration using %s (%s)",
00571 DumpIntegrationMethod().c_str(),
00572 DumpCubaIntegrationMethod().c_str()));
00573
00574 switch(fIntegrationMethod)
00575 {
00576 case BCIntegrate::kIntMonteCarlo:
00577 return IntegralMC(parameter);
00578
00579 case BCIntegrate::kIntMetropolis:
00580 return IntegralMetro(parameter);
00581
00582 case BCIntegrate::kIntImportance:
00583 return IntegralImportance(parameter);
00584
00585 case BCIntegrate::kIntCuba:
00586 #ifdef HAVE_CUBA_H
00587 return CubaIntegrate();
00588 #else
00589 BCLog::OutError("!!! This version of BAT is compiled without Cuba.");
00590 BCLog::OutError(" Use other integration methods or install Cuba and recompile BAT.");
00591 #endif
00592 default:
00593 BCLog::OutError(
00594 Form("BCIntegrate::Integrate : Invalid integration method: %d", fIntegrationMethod));
00595 }
00596
00597 return 0;
00598 }
00599
00600
00601 double BCIntegrate::IntegralMC(std::vector <double> x, int * varlist)
00602 {
00603 SetVarList(varlist);
00604 return IntegralMC(x);
00605 }
00606
00607
00608 double BCIntegrate::IntegralMC(std::vector <double> x)
00609 {
00610
00611 int NvarNow=0;
00612
00613 for(int i = 0; i < fNvar; i++)
00614 if(fVarlist[i])
00615 NvarNow++;
00616
00617
00618 BCLog::OutDebug(Form(" --> Running MC integation over %i dimensions.", NvarNow));
00619 BCLog::OutDebug(Form(" --> Maximum number of iterations: %i", GetNIterationsMax()));
00620 BCLog::OutDebug(Form(" --> Aimed relative precision: %e", GetRelativePrecision()));
00621
00622
00623 double D = 1.0;
00624 for(int i = 0; i < fNvar; i++)
00625 if (fVarlist[i])
00626 D = D * (fMax[i] - fMin[i]);
00627
00628
00629 double pmax = 0.0;
00630 double sumW = 0.0;
00631 double sumW2 = 0.0;
00632 double integral = 0.0;
00633 double variance = 0.0;
00634 double relprecision = 1.0;
00635
00636 std::vector <double> randx;
00637 randx.assign(fNvar, 0.0);
00638
00639
00640 fNIterations = 0;
00641
00642
00643 while ((fRelativePrecision < relprecision && fNIterationsMax > fNIterations) || fNIterations < 10) {
00644
00645 fNIterations++;
00646
00647
00648 GetRandomVector(randx);
00649
00650
00651 for(int i = 0; i < fNvar; i++) {
00652 if(fVarlist[i])
00653 randx[i]=fMin[i]+randx[i]*(fMax[i]-fMin[i]);
00654 else
00655 randx[i]=x[i];
00656 }
00657
00658
00659 double value = Eval(randx);
00660
00661
00662 sumW += value;
00663 sumW2 += value * value;
00664
00665
00666 if (value > pmax) {
00667
00668 pmax = value;
00669
00670
00671 fBestFitParameters.clear();
00672
00673
00674 for(int i = 0; i < fNvar; i++)
00675 fBestFitParameters.push_back(randx.at(i));
00676 }
00677
00678
00679 integral = D * sumW / fNIterations;
00680
00681 if (fNIterations%10000 == 0) {
00682 variance = (1.0 / double(fNIterations)) * (D * D * sumW2 / double(fNIterations) - integral * integral);
00683 double error = sqrt(variance);
00684 relprecision = error / integral;
00685
00686 BCLog::OutDebug(Form("BCIntegrate::IntegralMC. Iteration %i, integral: %e +- %e.", fNIterations, integral, error));
00687 }
00688 }
00689
00690 fError = variance / fNIterations;
00691
00692
00693 BCLog::OutDebug(Form(" --> Result of integration: %e +- %e in %i iterations.", integral, sqrt(variance), fNIterations));
00694 BCLog::OutDebug(Form(" --> Obtained relative precision: %e. ", sqrt(variance) / integral));
00695
00696 return integral;
00697 }
00698
00699
00700
00701 double BCIntegrate::IntegralMetro(std::vector <double> x)
00702 {
00703
00704 BCLog::OutDebug(Form("BCIntegrate::IntegralMetro. Integate over %i dimensions.", fNvar));
00705
00706
00707 double Niter = pow(fNiterPerDimension, fNvar);
00708
00709
00710 if(Niter>1e5)
00711 BCLog::OutDebug(Form(" --> Total number of iterations in Metropolis: %d.", (int)Niter));
00712
00713
00714 double sumI = 0;
00715
00716
00717 std::vector <double> randx;
00718 randx.assign(fNvar,0.);
00719 InitMetro();
00720
00721
00722 double pmax = 0.0;
00723
00724
00725 for(int i = 0; i <= Niter; i++) {
00726
00727 GetRandomPointSamplingMetro(randx);
00728
00729
00730 double val_f = Eval(randx);
00731
00732
00733 double val_g = EvalSampling(randx);
00734
00735
00736 if (val_g > 0)
00737 sumI += val_f / val_g;
00738
00739
00740 if (val_f > pmax) {
00741
00742 pmax = val_f;
00743
00744
00745 fBestFitParameters.clear();
00746
00747
00748 for(int i = 0; i < fNvar; i++)
00749 fBestFitParameters.push_back(randx.at(i));
00750 }
00751
00752
00753 if((i+1)%100000 == 0)
00754 BCLog::OutDebug(Form("BCIntegrate::IntegralMetro. Iteration %d, integral: %g.", i+1, sumI/double(i+1)));
00755 }
00756
00757
00758 double result=sumI/Niter;
00759
00760
00761 BCLog::OutDebug(Form(" --> Integral is %g in %g iterations.", result, Niter));
00762
00763 return result;
00764 }
00765
00766
00767 double BCIntegrate::IntegralImportance(std::vector <double> x)
00768 {
00769
00770 BCLog::OutDebug(Form("BCIntegrate::IntegralImportance. Integate over %i dimensions.", fNvar));
00771
00772
00773 double Niter = pow(fNiterPerDimension, fNvar);
00774
00775
00776 if(Niter>1e5)
00777 BCLog::OutDebug(Form("BCIntegrate::IntegralImportance. Total number of iterations: %d.", (int)Niter));
00778
00779
00780 double sumI = 0;
00781
00782 std::vector <double> randx;
00783 randx.assign(fNvar,0.);
00784
00785
00786 double pmax = 0.0;
00787
00788
00789 for(int i = 0; i <= Niter; i++) {
00790
00791 GetRandomPointImportance(randx);
00792
00793
00794 double val_f = Eval(randx);
00795
00796
00797 double val_g = EvalSampling(randx);
00798
00799
00800 if (val_g > 0)
00801 sumI += val_f / val_g;
00802
00803
00804 if (val_f > pmax) {
00805
00806 pmax = val_f;
00807
00808
00809 fBestFitParameters.clear();
00810
00811
00812 for(int i = 0; i < fNvar; i++)
00813 fBestFitParameters.push_back(randx.at(i));
00814 }
00815
00816
00817 if((i+1)%100000 == 0)
00818 BCLog::OutDebug(Form("BCIntegrate::IntegralImportance : Iteration %d, integral: %g.", i+1, sumI/double(i+1)));
00819 }
00820
00821
00822 double result=sumI/Niter;
00823
00824
00825 BCLog::OutDebug(Form("BCIntegrate::IntegralImportance : Integral %g in %i iterations.", result, (int)Niter));
00826
00827 return result;
00828 }
00829
00830
00831 TH1D* BCIntegrate::Marginalize(BCParameter * parameter)
00832 {
00833 BCLog::OutDebug(Form(" --> Marginalizing model wrt. parameter %s using %s.", parameter->GetName().data(), DumpMarginalizationMethod().c_str()));
00834
00835 switch(fMarginalizationMethod)
00836 {
00837 case BCIntegrate::kMargMonteCarlo:
00838 return MarginalizeByIntegrate(parameter);
00839
00840 case BCIntegrate::kMargMetropolis:
00841 return MarginalizeByMetro(parameter);
00842
00843 default:
00844 BCLog::OutError(
00845 Form("BCIntegrate::Marginalize. Invalid marginalization method: %d. Return 0.", fMarginalizationMethod));
00846
00847 }
00848
00849 return 0;
00850 }
00851
00852
00853 TH2D * BCIntegrate::Marginalize(BCParameter * parameter1, BCParameter * parameter2)
00854 {
00855 switch(fMarginalizationMethod)
00856 {
00857 case BCIntegrate::kMargMonteCarlo:
00858 return MarginalizeByIntegrate(parameter1,parameter2);
00859
00860 case BCIntegrate::kMargMetropolis:
00861 return MarginalizeByMetro(parameter1,parameter2);
00862
00863 default:
00864 BCLog::OutError(
00865 Form("BCIntegrate::Marginalize. Invalid marginalization method: %d. Return 0.", fMarginalizationMethod));
00866 }
00867
00868 return 0;
00869 }
00870
00871
00872 TH1D* BCIntegrate::MarginalizeByIntegrate(BCParameter * parameter)
00873 {
00874
00875 ResetVarlist(1);
00876 int index = parameter->GetIndex();
00877 UnsetVar(index);
00878
00879
00880 double hmin = parameter->GetLowerLimit();
00881 double hmax = parameter->GetUpperLimit();
00882 double hdx = (hmax - hmin) / double(fNbins);
00883 TH1D * hist = new TH1D("hist","", fNbins, hmin, hmax);
00884
00885
00886 std::vector <double> randx;
00887 randx.assign(fNvar, 0.);
00888
00889 for(int i=0;i<=fNbins;i++) {
00890 randx[index] = hmin + (double)i * hdx;
00891
00892 double val = IntegralMC(randx);
00893 hist->Fill(randx[index], val);
00894 }
00895
00896
00897 hist->Scale( 1./hist->Integral("width") );
00898
00899 return hist;
00900 }
00901
00902
00903 TH2D * BCIntegrate::MarginalizeByIntegrate(BCParameter * parameter1, BCParameter * parameter2)
00904 {
00905
00906 ResetVarlist(1);
00907 int index1 = parameter1->GetIndex();
00908 UnsetVar(index1);
00909 int index2 = parameter2->GetIndex();
00910 UnsetVar(index2);
00911
00912
00913 double hmin1 = parameter1->GetLowerLimit();
00914 double hmax1 = parameter1->GetUpperLimit();
00915 double hdx1 = (hmax1 - hmin1) / double(fNbins);
00916
00917 double hmin2 = parameter2->GetLowerLimit();
00918 double hmax2 = parameter2->GetUpperLimit();
00919 double hdx2 = (hmax2 - hmin2) / double(fNbins);
00920
00921 TH2D * hist = new TH2D(Form("hist_%s_%s", parameter1->GetName().data(), parameter2->GetName().data()),"",
00922 fNbins, hmin1, hmax1,
00923 fNbins, hmin2, hmax2);
00924
00925
00926 std::vector <double> randx;
00927 randx.assign(fNvar, 0.0);
00928
00929 for(int i=0;i<=fNbins;i++) {
00930 randx[index1] = hmin1 + (double)i * hdx1;
00931 for(int j=0;j<=fNbins;j++) {
00932 randx[index2] = hmin2 + (double)j * hdx2;
00933
00934 double val = IntegralMC(randx);
00935 hist->Fill(randx[index1],randx[index2], val);
00936 }
00937 }
00938
00939
00940 hist->Scale(1.0/hist->Integral("width"));
00941
00942 return hist;
00943 }
00944
00945
00946 TH1D * BCIntegrate::MarginalizeByMetro(BCParameter * parameter)
00947 {
00948 int niter = fMarkovChainNIterations;
00949
00950 if (fMarkovChainAutoN == true)
00951 niter = fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00952
00953 BCLog::OutDetail(Form(" --> Number of samples in Metropolis marginalization: %d.", niter));
00954
00955
00956 int index = parameter->GetIndex();
00957
00958
00959 double hmin = parameter->GetLowerLimit();
00960 double hmax = parameter->GetUpperLimit();
00961 TH1D * hist = new TH1D("hist","", fNbins, hmin, hmax);
00962
00963
00964 std::vector <double> randx;
00965 randx.assign(fNvar, 0.0);
00966 InitMetro();
00967
00968 for(int i=0;i<=niter;i++) {
00969 GetRandomPointMetro(randx);
00970 hist->Fill(randx[index]);
00971 }
00972
00973
00974 hist->Scale(1.0/hist->Integral("width"));
00975
00976 return hist;
00977 }
00978
00979
00980 TH2D * BCIntegrate::MarginalizeByMetro(BCParameter * parameter1, BCParameter * parameter2)
00981 {
00982 int niter=fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00983
00984
00985 int index1 = parameter1->GetIndex();
00986 int index2 = parameter2->GetIndex();
00987
00988
00989 double hmin1 = parameter1->GetLowerLimit();
00990 double hmax1 = parameter1->GetUpperLimit();
00991
00992 double hmin2 = parameter2->GetLowerLimit();
00993 double hmax2 = parameter2->GetUpperLimit();
00994
00995 TH2D * hist = new TH2D(Form("hist_%s_%s", parameter1->GetName().data(), parameter2->GetName().data()),"",
00996 fNbins, hmin1, hmax1,
00997 fNbins, hmin2, hmax2);
00998
00999
01000 std::vector <double> randx;
01001 randx.assign(fNvar, 0.0);
01002 InitMetro();
01003
01004 for(int i=0;i<=niter;i++) {
01005 GetRandomPointMetro(randx);
01006 hist->Fill(randx[index1],randx[index2]);
01007 }
01008
01009
01010 hist->Scale(1.0/hist->Integral("width"));
01011
01012 return hist;
01013 }
01014
01015
01016 int BCIntegrate::MarginalizeAllByMetro(const char * name="")
01017 {
01018 int niter=fNbins*fNbins*fNSamplesPer2DBin*fNvar;
01019
01020 BCLog::OutDetail(Form(" --> Number of samples in Metropolis marginalization: %d.", niter));
01021
01022
01023 for(int i=0;i<fNvar;i++)
01024 {
01025 double hmin1 = fx->at(i)->GetLowerLimit();
01026 double hmax1 = fx->at(i)->GetUpperLimit();
01027
01028 TH1D * h1 = new TH1D(
01029 TString::Format("h%s_%s", name, fx->at(i)->GetName().data()),"",
01030 fNbins, hmin1, hmax1);
01031
01032 fHProb1D.push_back(h1);
01033 }
01034
01035
01036 for(int i=0;i<fNvar-1;i++)
01037 for(int j=i+1;j<fNvar;j++) {
01038 double hmin1 = fx->at(i)->GetLowerLimit();
01039 double hmax1 = fx->at(i)->GetUpperLimit();
01040
01041 double hmin2 = fx->at(j)->GetLowerLimit();
01042 double hmax2 = fx->at(j)->GetUpperLimit();
01043
01044 TH2D * h2 = new TH2D(
01045 TString::Format("h%s_%s_%s", name, fx->at(i)->GetName().data(), fx->at(j)->GetName().data()),"",
01046 fNbins, hmin1, hmax1,
01047 fNbins, hmin2, hmax2);
01048
01049 fHProb2D.push_back(h2);
01050 }
01051
01052
01053 int nh2d = fHProb2D.size();
01054
01055 BCLog::OutDetail(Form(" --> Marginalizing %d 1D distributions and %d 2D distributions.", fNvar, nh2d));
01056
01057
01058 double dx = 0.;
01059 double dy = 0.;
01060
01061 if (fFitFunctionIndexX >= 0) {
01062 dx = (fDataPointUpperBoundaries->GetValue(fFitFunctionIndexX) -
01063 fDataPointLowerBoundaries->GetValue(fFitFunctionIndexX))
01064 / double(fErrorBandNbinsX);
01065
01066 dx = (fDataPointUpperBoundaries->GetValue(fFitFunctionIndexY) -
01067 fDataPointLowerBoundaries->GetValue(fFitFunctionIndexY))
01068 / double(fErrorBandNbinsY);
01069
01070 fErrorBandXY = new TH2D(
01071 TString::Format("errorbandxy_%d",BCLog::GetHIndex()), "",
01072 fErrorBandNbinsX,
01073 fDataPointLowerBoundaries->GetValue(fFitFunctionIndexX) - 0.5 * dx,
01074 fDataPointUpperBoundaries->GetValue(fFitFunctionIndexX) + 0.5 * dx,
01075 fErrorBandNbinsY,
01076 fDataPointLowerBoundaries->GetValue(fFitFunctionIndexY) - 0.5 * dy,
01077 fDataPointUpperBoundaries->GetValue(fFitFunctionIndexY) + 0.5 * dy);
01078 fErrorBandXY->SetStats(kFALSE);
01079
01080 for (int ix = 1; ix <= fErrorBandNbinsX; ++ix)
01081 for (int iy = 1; iy <= fErrorBandNbinsX; ++iy)
01082 fErrorBandXY->SetBinContent(ix, iy, 0.0);
01083 }
01084
01085
01086 std::vector <double> randx;
01087
01088 randx.assign(fNvar, 0.0);
01089 InitMetro();
01090
01091
01092 fNacceptedMCMC = 0;
01093
01094
01095 for(int i=0;i<=niter;i++) {
01096 GetRandomPointMetro(randx);
01097
01098
01099 if (fFlagWriteMarkovChain) {
01100 fMCMCIteration = i;
01101 fMarkovChainTree->Fill();
01102 }
01103
01104 for(int j=0;j<fNvar;j++)
01105 fHProb1D[j]->Fill( randx[j] );
01106
01107 int ih=0;
01108 for(int j=0;j<fNvar-1;j++)
01109 for(int k=j+1;k<fNvar;k++) {
01110 fHProb2D[ih]->Fill(randx[j],randx[k]);
01111 ih++;
01112 }
01113
01114 if((i+1)%100000==0)
01115 BCLog::OutDebug(Form("BCIntegrate::MarginalizeAllByMetro. %d samples done.",i+1));
01116
01117
01118
01119 if (fFitFunctionIndexX >= 0) {
01120
01121 if (fErrorBandContinuous) {
01122 double x = 0;
01123
01124 for (int ix = 0; ix < fErrorBandNbinsX; ix++) {
01125
01126 x = fErrorBandXY->GetXaxis()->GetBinCenter(ix + 1);
01127
01128
01129 std::vector <double> xvec;
01130 xvec.push_back(x);
01131 double y = FitFunction(xvec, randx);
01132 xvec.clear();
01133
01134
01135 fErrorBandXY->Fill(x, y);
01136 }
01137 }
01138
01139
01140 else {
01141 int ndatapoints = int(fErrorBandX.size());
01142 double x = 0;
01143
01144 for (int ix = 0; ix < ndatapoints; ++ix) {
01145
01146 x = fErrorBandX.at(ix);
01147
01148
01149 std::vector <double> xvec;
01150 xvec.push_back(x);
01151 double y = FitFunction(xvec, randx);
01152 xvec.clear();
01153
01154
01155 fErrorBandXY->Fill(x, y);
01156 }
01157 }
01158 }
01159 }
01160
01161
01162 for(int i=0;i<fNvar;i++)
01163 fHProb1D[i]->Scale( 1./fHProb1D[i]->Integral("width") );
01164
01165 for (int i=0;i<nh2d;i++)
01166 fHProb2D[i]->Scale( 1./fHProb2D[i]->Integral("width") );
01167
01168 if (fFitFunctionIndexX >= 0)
01169 fErrorBandXY->Scale(1.0/fErrorBandXY->Integral() * fErrorBandXY->GetNbinsX());
01170
01171 if (fFitFunctionIndexX >= 0) {
01172 for (int ix = 1; ix <= fErrorBandNbinsX; ix++) {
01173 double sum = 0;
01174
01175 for (int iy = 1; iy <= fErrorBandNbinsY; iy++)
01176 sum += fErrorBandXY->GetBinContent(ix, iy);
01177
01178 for (int iy = 1; iy <= fErrorBandNbinsY; iy++) {
01179 double newvalue = fErrorBandXY->GetBinContent(ix, iy) / sum;
01180 fErrorBandXY->SetBinContent(ix, iy, newvalue);
01181 }
01182 }
01183 }
01184
01185 BCLog::OutDebug(Form("BCIntegrate::MarginalizeAllByMetro done with %i trials and %i accepted trials. Efficiency is %f",fNmetro, fNacceptedMCMC, double(fNacceptedMCMC)/double(fNmetro)));
01186
01187 return fNvar+nh2d;
01188 }
01189
01190
01191 TH1D * BCIntegrate::GetH1D(int parIndex)
01192 {
01193 if(fHProb1D.size()==0) {
01194 BCLog::OutWarning("BCModel::GetH1D. MarginalizeAll() has to be run prior to this to fill the distributions.");
01195 return 0;
01196 }
01197
01198 if(parIndex<0 || parIndex>fNvar) {
01199 BCLog::OutWarning(Form("BCIntegrate::GetH1D. Parameter index %d is invalid.",parIndex));
01200 return 0;
01201 }
01202
01203 return fHProb1D[parIndex];
01204 }
01205
01206
01207 int BCIntegrate::GetH2DIndex(int parIndex1, int parIndex2)
01208 {
01209 if(parIndex1>fNvar-1 || parIndex1<0) {
01210 BCLog::OutWarning(Form("BCIntegrate::GetH2DIndex. Parameter index %d is invalid", parIndex1));
01211 return -1;
01212 }
01213
01214 if(parIndex2>fNvar-1 || parIndex2<0) {
01215 BCLog::OutWarning(Form("BCIntegrate::GetH2DIndex. Parameter index %d is invalid", parIndex2));
01216 return -1;
01217 }
01218
01219 if(parIndex1==parIndex2) {
01220 BCLog::OutWarning(Form("BCIntegrate::GetH2DIndex. Parameters have equal indeces: %d , %d", parIndex1, parIndex2));
01221 return -1;
01222 }
01223
01224 if(parIndex1>parIndex2) {
01225 BCLog::OutWarning("BCIntegrate::GetH2DIndex. First parameters must be smaller than second (sorry).");
01226 return -1;
01227 }
01228
01229 int index=0;
01230 for(int i=0;i<fNvar-1;i++)
01231 for(int j=i+1;j<fNvar;j++) {
01232 if(i==parIndex1 && j==parIndex2)
01233 return index;
01234 index++;
01235 }
01236
01237 BCLog::OutWarning("BCIntegrate::GetH2DIndex. Invalid index combination.");
01238
01239 return -1;
01240 }
01241
01242
01243 TH2D * BCIntegrate::GetH2D(int parIndex1, int parIndex2)
01244 {
01245 if(fHProb2D.size()==0) {
01246 BCLog::OutWarning("BCModel::GetH2D. MarginalizeAll() has to be run prior to this to fill the distributions.");
01247 return 0;
01248 }
01249
01250 int hindex = GetH2DIndex(parIndex1, parIndex2);
01251 if(hindex==-1)
01252 return 0;
01253
01254 if(hindex>(int)fHProb2D.size()-1) {
01255 BCLog::OutWarning("BCIntegrate::GetH2D. Got invalid index from GetH2DIndex(). Something went wrong.");
01256 return 0;
01257 }
01258
01259 return fHProb2D[hindex];
01260 }
01261
01262
01263 double BCIntegrate::GetRandomPoint(std::vector <double> &x)
01264 {
01265 GetRandomVector(x);
01266
01267 for(int i=0;i<fNvar;i++)
01268 x[i]=fMin[i]+x[i]*(fMax[i]-fMin[i]);
01269
01270 return Eval(x);
01271 }
01272
01273
01274 double BCIntegrate::GetRandomPointImportance(std::vector <double> &x)
01275 {
01276 double p = 1.1;
01277 double g = 1.0;
01278
01279 while (p>g) {
01280 GetRandomVector(x);
01281
01282 for(int i=0;i<fNvar;i++)
01283 x[i] = fMin[i] + x[i] * (fMax[i]-fMin[i]);
01284
01285 p = fRandom->Rndm();
01286
01287 g = EvalSampling(x);
01288 }
01289
01290 return Eval(x);
01291 }
01292
01293
01294 void BCIntegrate::InitMetro()
01295 {
01296 fNmetro=0;
01297
01298 if (fXmetro0.size() <= 0) {
01299
01300 for(int i=0;i<fNvar;i++)
01301 fXmetro0.push_back((fMin[i]+fMax[i])/2.0);
01302 }
01303
01304 fMarkovChainValue = LogEval(fXmetro0);
01305
01306
01307 std::vector <double> x;
01308 x.assign(fNvar,0.);
01309
01310 for(int i=0;i<1000;i++)
01311 GetRandomPointMetro(x);
01312
01313 fNmetro = 0;
01314 }
01315
01316
01317 void BCIntegrate::GetRandomPointMetro(std::vector <double> &x)
01318 {
01319
01320 GetRandomVectorMetro(fXmetro1);
01321
01322
01323 int in=1;
01324 for(int i=0;i<fNvar;i++) {
01325 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * (fMax[i]-fMin[i]);
01326
01327
01328 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01329 in=0;
01330 }
01331
01332
01333
01334 double p0 = fMarkovChainValue;
01335 double p1 = 0;
01336 int accept=0;
01337
01338 if(in) {
01339 p1 = LogEval(fXmetro1);
01340
01341 if(p1>=p0)
01342 accept=1;
01343 else {
01344 double r=log(fRandom->Rndm());
01345 if(r<p1-p0)
01346 accept=1;
01347 }
01348 }
01349
01350
01351 if(accept) {
01352
01353 fNacceptedMCMC++;
01354
01355 for(int i=0;i<fNvar;i++) {
01356 fXmetro0[i]=fXmetro1[i];
01357 x[i]=fXmetro1[i];
01358 fMarkovChainValue = p1;
01359 }
01360 }
01361 else
01362 for(int i=0;i<fNvar;i++) {
01363 x[i]=fXmetro0[i];
01364 fXmetro1[i] = x[i];
01365 fMarkovChainValue = p0;
01366 }
01367
01368 fNmetro++;
01369 }
01370
01371
01372 void BCIntegrate::GetRandomPointSamplingMetro(std::vector <double> &x)
01373 {
01374
01375 GetRandomVectorMetro(fXmetro1);
01376
01377
01378 int in=1;
01379 for(int i=0;i<fNvar;i++) {
01380 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * (fMax[i]-fMin[i]);
01381
01382
01383 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01384 in=0;
01385 }
01386
01387
01388 double p0 = LogEvalSampling(fXmetro0);
01389 double p1=0;
01390 if(in)
01391 p1= LogEvalSampling(fXmetro1);
01392
01393
01394 int accept=0;
01395 if(in) {
01396 if(p1>=p0)
01397 accept=1;
01398 else {
01399 double r=log(fRandom->Rndm());
01400 if(r<p1-p0)
01401 accept=1;
01402 }
01403 }
01404
01405
01406 if(accept)
01407 for(int i=0;i<fNvar;i++) {
01408 fXmetro0[i]=fXmetro1[i];
01409 x[i]=fXmetro1[i];
01410 }
01411 else
01412 for(int i=0;i<fNvar;i++)
01413 x[i]=fXmetro0[i];
01414
01415 fNmetro++;
01416 }
01417
01418
01419 void BCIntegrate::GetRandomVector(std::vector <double> &x)
01420 {
01421 double * randx = new double[fNvar];
01422
01423 fRandom->RndmArray(fNvar, randx);
01424
01425 for(int i=0;i<fNvar;i++)
01426 x[i] = randx[i];
01427
01428 delete[] randx;
01429 randx = 0;
01430 }
01431
01432
01433 void BCIntegrate::GetRandomVectorMetro(std::vector <double> &x)
01434 {
01435 double * randx = new double[fNvar];
01436
01437 fRandom->RndmArray(fNvar, randx);
01438
01439 for(int i=0;i<fNvar;i++)
01440 x[i] = 2.0 * (randx[i] - 0.5) * fMarkovChainStepSize;
01441
01442 delete[] randx;
01443 randx = 0;
01444 }
01445
01446
01447 TMinuit * BCIntegrate::GetMinuit()
01448 {
01449 if (!fMinuit)
01450 fMinuit = new TMinuit();
01451
01452 return fMinuit;
01453 }
01454
01455
01456
01457 void BCIntegrate::FindModeMinuit(std::vector<double> start, int printlevel)
01458 {
01459 bool have_start = true;
01460
01461
01462 if (int(start.size()) != fNvar)
01463 have_start = false;
01464
01465
01466 global_this = this;
01467
01468
01469 if (fMinuit)
01470 delete fMinuit;
01471 fMinuit = new TMinuit(fNvar);
01472
01473
01474 fMinuit->SetPrintLevel(printlevel);
01475
01476
01477 fMinuit->SetFCN(&BCIntegrate::FCNLikelihood);
01478
01479
01480 fMinuit->SetErrorDef(0.5);
01481
01482
01483 int flag;
01484 for (int i = 0; i < fNvar; i++) {
01485 double starting_point = (fMin[i]+fMax[i])/2.;
01486 if(have_start)
01487 starting_point = start[i];
01488 fMinuit->mnparm(i,
01489 fx->at(i)->GetName().data(),
01490 starting_point,
01491 (fMax[i]-fMin[i])/100.,
01492 fMin[i],
01493 fMax[i],
01494 flag);
01495 }
01496
01497
01498
01499
01500
01501 fMinuit->mnexcm("MIGRAD", fMinuitArglist, 2, flag);
01502
01503
01504
01505
01506
01507 fMinuitErrorFlag = flag;
01508
01509
01510 double probmax = 0;
01511 bool valid = false;
01512
01513 if ( int(fBestFitParameters.size()) == fNvar) {
01514 valid = true;
01515 for (int i = 0; i < fNvar; ++i)
01516 if (fBestFitParameters.at(i) < fMin[i] || fBestFitParameters.at(i) > fMax[i])
01517 valid= false;
01518
01519 if (valid)
01520 probmax = Eval( fBestFitParameters );
01521 }
01522
01523 std::vector<double> tempvec;
01524 for (int i = 0; i < fNvar; i++) {
01525 double par;
01526 double parerr;
01527 fMinuit->GetParameter(i, par, parerr);
01528 tempvec.push_back(par);
01529 }
01530 double probmaxminuit = Eval( tempvec );
01531
01532
01533 if ( (probmaxminuit > probmax && !fFlagIgnorePrevOptimization) || !valid || fFlagIgnorePrevOptimization) {
01534 fBestFitParameters.clear();
01535 fBestFitParameterErrors.clear();
01536
01537 for (int i = 0; i < fNvar; i++) {
01538 double par;
01539 double parerr;
01540 fMinuit->GetParameter(i, par, parerr);
01541 fBestFitParameters.push_back(par);
01542 fBestFitParameterErrors.push_back(parerr);
01543 }
01544
01545
01546 fOptimizationMethodMode = BCIntegrate::kOptMinuit;
01547 }
01548
01549
01550 delete fMinuit;
01551 fMinuit = 0;
01552
01553 return;
01554 }
01555
01556
01557 void BCIntegrate::InitializeSATree()
01558 {
01559 if (fTreeSA)
01560 delete fTreeSA;
01561 fTreeSA = new TTree("SATree", "SATree");
01562
01563 fTreeSA->Branch("Iteration", &fSANIterations, "iteration/I");
01564 fTreeSA->Branch("NParameters", &fNvar, "parameters/I");
01565 fTreeSA->Branch("Temperature", &fSATemperature, "temperature/D");
01566 fTreeSA->Branch("LogProbability", &fSALogProb, "log(probability)/D");
01567
01568 for (int i = 0; i < fNvar; ++i)
01569 fTreeSA->Branch(TString::Format("Parameter%i", i), &fSAx[i], TString::Format("parameter %i/D", i));
01570 }
01571
01572
01573 void BCIntegrate::FindModeSA(std::vector<double> start)
01574 {
01575
01576
01577
01578 bool have_start = true;
01579 std::vector<double> x, y, best_fit;
01580 double fval_x, fval_y, fval_best_fit;
01581 int t = 1;
01582
01583
01584 if (int(start.size()) != fNvar)
01585 have_start = false;
01586
01587
01588 if ( !have_start ) {
01589 start.clear();
01590 for (int i = 0; i < fNvar; i++)
01591 start.push_back((fMin[i]+fMax[i])/2.);
01592 }
01593
01594
01595 x.clear();
01596 best_fit.clear();
01597 for (int i = 0; i < fNvar; i++) {
01598 x.push_back(start[i]);
01599 best_fit.push_back(start[i]);
01600 }
01601
01602 fval_x = fval_best_fit = LogEval(x);
01603
01604
01605 while ( SATemperature(t) > fSATmin ) {
01606
01607 y = GetProposalPointSA(x, t);
01608
01609
01610
01611 bool is_in_ranges = true;
01612
01613 for (int i = 0; i < fNvar; i++)
01614 if (y[i] > fMax[i] || y[i] < fMin[i])
01615 is_in_ranges = false;
01616
01617 if ( !is_in_ranges )
01618 ;
01619 else {
01620
01621 fval_y = LogEval(y);
01622
01623
01624
01625 if (fval_y >= fval_x) {
01626 x.clear();
01627 for (int i = 0; i < fNvar; i++)
01628 x.push_back(y[i]);
01629
01630 fval_x = fval_y;
01631
01632 if (fval_y > fval_best_fit) {
01633 best_fit.clear();
01634 for (int i = 0; i < fNvar; i++)
01635 best_fit.push_back(y[i]);
01636
01637 fval_best_fit = fval_y;
01638 }
01639 }
01640
01641 else {
01642 if (fRandom->Rndm() <= exp( (fval_y - fval_x) / SATemperature(t) )) {
01643 x.clear();
01644 for (int i = 0; i < fNvar; i++)
01645 x.push_back(y[i]);
01646
01647 fval_x = fval_y;
01648 }
01649 }
01650 }
01651
01652
01653 fSANIterations = t;
01654 fSATemperature = SATemperature(t);
01655 fSALogProb = fval_x;
01656 fSAx.clear();
01657 for (int i = 0; i < fNvar; ++i)
01658 fSAx.push_back(x[i]);
01659
01660
01661 if (fFlagWriteSAToFile)
01662 fTreeSA->Fill();
01663
01664
01665 t++;
01666 }
01667
01668
01669 double probmax = 0;
01670 bool valid = false;
01671
01672 if ( int(fBestFitParameters.size()) == fNvar) {
01673 valid = true;
01674 for (int i = 0; i < fNvar; ++i)
01675 if (fBestFitParameters.at(i) < fMin[i] || fBestFitParameters.at(i) > fMax[i])
01676 valid= false;
01677
01678 if (valid)
01679 probmax = Eval( fBestFitParameters );
01680 }
01681
01682 double probmaxsa = Eval( best_fit);
01683
01684 if ( (probmaxsa > probmax && !fFlagIgnorePrevOptimization) || !valid || fFlagIgnorePrevOptimization) {
01685
01686 fBestFitParameters.clear();
01687 fBestFitParameterErrors.clear();
01688
01689 for (int i = 0; i < fNvar; i++) {
01690 fBestFitParameters.push_back(best_fit[i]);
01691 fBestFitParameterErrors.push_back(-1.);
01692 }
01693
01694
01695 fOptimizationMethodMode = BCIntegrate::kOptSA;
01696 }
01697
01698 return;
01699 }
01700
01701
01702
01703 double BCIntegrate::SATemperature(double t)
01704 {
01705
01706 if (fSASchedule == BCIntegrate::kSABoltzmann)
01707 return SATemperatureBoltzmann(t);
01708 else if (fSASchedule == BCIntegrate::kSACauchy)
01709 return SATemperatureCauchy(t);
01710 else
01711 return SATemperatureCustom(t);
01712 }
01713
01714
01715
01716 double BCIntegrate::SATemperatureBoltzmann(double t)
01717 {
01718 return fSAT0 / log((double)(t + 1));
01719 }
01720
01721
01722
01723 double BCIntegrate::SATemperatureCauchy(double t)
01724 {
01725 return fSAT0 / (double)t;
01726 }
01727
01728
01729
01730 double BCIntegrate::SATemperatureCustom(double t)
01731 {
01732 BCLog::OutError("BCIntegrate::SATemperatureCustom : No custom temperature schedule defined");
01733 return 0.;
01734 }
01735
01736
01737
01738 std::vector<double> BCIntegrate::GetProposalPointSA(std::vector<double> x, int t)
01739 {
01740
01741 if (fSASchedule == BCIntegrate::kSABoltzmann)
01742 return GetProposalPointSABoltzmann(x, t);
01743 else if (fSASchedule == BCIntegrate::kSACauchy)
01744 return GetProposalPointSACauchy(x, t);
01745 else
01746 return GetProposalPointSACustom(x, t);
01747 }
01748
01749
01750
01751 std::vector<double> BCIntegrate::GetProposalPointSABoltzmann(std::vector<double> x, int t)
01752 {
01753 std::vector<double> y;
01754 y.clear();
01755 double new_val, norm;
01756
01757 for (int i = 0; i < fNvar; i++) {
01758 norm = (fMax[i] - fMin[i]) * SATemperature(t) / 2.;
01759 new_val = x[i] + norm * fRandom->Gaus();
01760 y.push_back(new_val);
01761 }
01762
01763 return y;
01764 }
01765
01766
01767
01768 std::vector<double> BCIntegrate::GetProposalPointSACauchy(std::vector<double> x, int t)
01769 {
01770 std::vector<double> y;
01771 y.clear();
01772
01773 if (fNvar == 1) {
01774 double cauchy, new_val, norm;
01775
01776 norm = (fMax[0] - fMin[0]) * SATemperature(t) / 2.;
01777 cauchy = tan(3.14159 * (fRandom->Rndm() - 0.5));
01778 new_val = x[0] + norm * cauchy;
01779 y.push_back(new_val);
01780 }
01781 else {
01782
01783
01784
01785
01786 y = SAHelperGetRandomPointOnHypersphere();
01787
01788
01789
01790 double radial = SATemperature(t) * SAHelperGetRadialCauchy();
01791
01792
01793
01794 for (int i = 0; i < fNvar; i++)
01795 y[i] = (fMax[i] - fMin[i]) * y[i] * radial / 2. + x[i];
01796 }
01797
01798 return y;
01799 }
01800
01801
01802
01803 std::vector<double> BCIntegrate::GetProposalPointSACustom(std::vector<double> x, int t)
01804 {
01805 BCLog::OutError("BCIntegrate::GetProposalPointSACustom : No custom proposal function defined");
01806 return std::vector<double>(fNvar);
01807 }
01808
01809
01810
01811 std::vector<double> BCIntegrate::SAHelperGetRandomPointOnHypersphere()
01812 {
01813 std::vector<double> rand_point(fNvar);
01814
01815
01816
01817
01818
01819
01820
01821 if (fNvar == 2) {
01822 double x1, x2, s;
01823 do {
01824 x1 = fRandom->Rndm() * 2. - 1.;
01825 x2 = fRandom->Rndm() * 2. - 1.;
01826 s = x1*x1 + x2*x2;
01827 }
01828 while (s >= 1);
01829
01830 rand_point[0] = (x1*x1 - x2*x2) / s;
01831 rand_point[1] = (2.*x1*x2) / s;
01832 }
01833 else if (fNvar == 3) {
01834 fRandom->Sphere(rand_point[0], rand_point[1], rand_point[2], 1.0);
01835 }
01836 else {
01837 double s = 0.,
01838 gauss_num;
01839
01840 for (int i = 0; i < fNvar; i++) {
01841 gauss_num = fRandom->Gaus();
01842 rand_point[i] = gauss_num;
01843 s += gauss_num * gauss_num;
01844 }
01845 s = sqrt(s);
01846
01847 for (int i = 0; i < fNvar; i++)
01848 rand_point[i] = rand_point[i] / s;
01849 }
01850
01851 return rand_point;
01852 }
01853
01854
01855
01856 double BCIntegrate::SAHelperGetRadialCauchy()
01857 {
01858
01859
01860
01861
01862 double theta;
01863
01864
01865 static double map_u[10001];
01866 static double map_theta[10001];
01867 static bool initialized = false;
01868 static int map_dimension = 0;
01869
01870
01871 if (!initialized || map_dimension != fNvar) {
01872 double init_theta;
01873 double beta = SAHelperSinusToNIntegral(fNvar - 1, 1.57079632679);
01874
01875 for (int i = 0; i <= 10000; i++) {
01876 init_theta = 3.14159265 * (double)i / 5000.;
01877 map_theta[i] = init_theta;
01878
01879 map_u[i] = SAHelperSinusToNIntegral(fNvar - 1, init_theta) / beta;
01880 }
01881
01882 map_dimension = fNvar;
01883 initialized = true;
01884 }
01885
01886
01887 double u = fRandom->Rndm();
01888
01889
01890
01891 int lo = 0;
01892 int up = 10000;
01893 int mid;
01894
01895 while (up != lo) {
01896 mid = ((up - lo + 1) / 2) + lo;
01897
01898 if (u >= map_u[mid])
01899 lo = mid;
01900 else
01901 up = mid - 1;
01902 }
01903 up++;
01904
01905
01906 theta = map_theta[lo] + (u - map_u[lo]) / (map_u[up] - map_u[lo]) * (map_theta[up] - map_theta[lo]);
01907
01908 return tan(theta);
01909 }
01910
01911
01912
01913 double BCIntegrate::SAHelperSinusToNIntegral(int dim, double theta)
01914 {
01915 if (dim < 1)
01916 return theta;
01917 else if (dim == 1)
01918 return (1. - cos(theta));
01919 else if (dim == 2)
01920 return 0.5 * (theta - sin(theta) * cos(theta));
01921 else if (dim == 3)
01922 return (2. - sin(theta) * sin(theta) * cos(theta) - 2. * cos(theta)) / 3.;
01923 else
01924 return - pow(sin(theta), (double)(dim - 1)) * cos(theta) / (double)dim
01925 + (double)(dim - 1) / (double)dim
01926 * SAHelperSinusToNIntegral(dim - 2, theta);
01927 }
01928
01929
01930
01931 void BCIntegrate::SetMode(std::vector <double> mode)
01932 {
01933 if((int)mode.size() == fNvar) {
01934 fBestFitParameters.clear();
01935 for (int i = 0; i < fNvar; i++)
01936 fBestFitParameters.push_back(mode[i]);
01937 }
01938 }
01939
01940
01941
01942 void BCIntegrate::FCNLikelihood(int &npar, double * grad, double &fval, double * par, int flag)
01943 {
01944
01945 std::vector <double> parameters;
01946
01947 int n = global_this->GetNvar();
01948
01949 for (int i = 0; i < n; i++)
01950 parameters.push_back(par[i]);
01951
01952 fval = - global_this->LogEval(parameters);
01953
01954
01955 parameters.clear();
01956 }
01957
01958
01959
01960
01961 void BCIntegrate::FindModeMCMC()
01962 {
01963
01964
01965 if (!fMCMCFlagPreRun)
01966 MCMCMetropolisPreRun();
01967
01968
01969
01970
01971 double probmax = 0;
01972
01973 if ( int(fBestFitParameters.size()) == fNvar) {
01974 probmax = Eval( fBestFitParameters );
01975
01976 }
01977
01978
01979 for (int i = 0; i < fMCMCNChains; ++i) {
01980 double prob = exp( (MCMCGetMaximumLogProb()).at(i));
01981
01982
01983 if ( (prob >= probmax && !fFlagIgnorePrevOptimization) || fFlagIgnorePrevOptimization) {
01984 probmax = prob;
01985
01986 fBestFitParameters.clear();
01987 fBestFitParameterErrors.clear();
01988 fBestFitParameters = MCMCGetMaximumPoint(i);
01989
01990 for (int j = 0; j < fNvar; ++j)
01991 fBestFitParameterErrors.push_back(-1.);
01992
01993 fOptimizationMethodMode = BCIntegrate::kOptMetropolis;
01994 }
01995 }
01996 }
01997
01998
01999 void BCIntegrate::SetCubaIntegrationMethod(BCIntegrate::BCCubaMethod type)
02000 {
02001 #ifdef HAVE_CUBA_H
02002 switch(type) {
02003 case BCIntegrate::kCubaVegas:
02004 case BCIntegrate::kCubaSuave:
02005 fCubaIntegrationMethod = type;
02006 return;
02007 case BCIntegrate::kCubaDivonne:
02008 case BCIntegrate::kCubaCuhre:
02009 BCLog::OutError(TString::Format(
02010 "BAT does not yet support global setting of Cuba integration method to %s. "
02011 "To use this method use explicit call to CubaIntegrate() with arguments.",
02012 DumpCubaIntegrationMethod(type).c_str()));
02013 return;
02014 default:
02015 BCLog::OutError(TString::Format("Integration method of type %d is not defined for Cuba",type));
02016 return;
02017 }
02018 #else
02019 BCLog::OutWarning("!!! This version of BAT is compiled without Cuba.");
02020 BCLog::OutWarning(" Setting Cuba integration method will have no effect.");
02021 #endif
02022 }
02023
02024
02025 int BCIntegrate::CubaIntegrand(const int *ndim, const double xx[],
02026 const int *ncomp, double ff[], void *userdata)
02027 {
02028 #ifdef HAVE_CUBA_H
02029
02030 double jacobian = 1.0;
02031
02032 std::vector<double> scaled_parameters;
02033
02034 for (int i = 0; i < *ndim; i++) {
02035 double range = global_this->fx->at(i)->GetUpperLimit() - global_this->fx->at(i)->GetLowerLimit();
02036
02037
02038 jacobian *= range;
02039
02040
02041 scaled_parameters.push_back(global_this->fx->at(i)->GetLowerLimit() + xx[i] * range);
02042 }
02043
02044
02045 ff[0] = global_this->Eval(scaled_parameters);
02046
02047
02048 ff[0] *= jacobian;
02049
02050
02051 ff[0] *= 1e99;
02052
02053
02054 scaled_parameters.clear();
02055 #else
02056 BCLog::OutError("!!! This version of BAT is compiled without Cuba.");
02057 BCLog::OutError(" Use other integration methods or install Cuba and recompile BAT.");
02058 #endif
02059
02060 return 0;
02061 }
02062
02063
02064 double BCIntegrate::CubaIntegrate()
02065 {
02066 #ifdef HAVE_CUBA_H
02067 std::vector<double> parameters_double;
02068 std::vector<double> parameters_int;
02069
02070 parameters_double.push_back(fRelativePrecision);
02071 parameters_double.push_back(fAbsolutePrecision);
02072
02073 parameters_int.push_back(fCubaVerbosity);
02074 parameters_int.push_back(fCubaMinEval);
02075 parameters_int.push_back(fCubaMaxEval);
02076
02077 switch (fCubaIntegrationMethod) {
02078 case BCIntegrate::kCubaSuave:
02079 parameters_int.push_back(fCubaSuaveNNew);
02080 parameters_double.push_back(fCubaSuaveFlatness);
02081 break;
02082 case BCIntegrate::kCubaDivonne:
02083 break;
02084 case BCIntegrate::kCubaCuhre:
02085 break;
02086 default:
02087 case BCIntegrate::kCubaVegas:
02088 parameters_int.push_back(fCubaVegasNStart);
02089 parameters_int.push_back(fCubaVegasNIncrease);
02090 }
02091
02092
02093 BCLog::OutDebug( Form(" --> Running Cuba/%s integation over %i dimensions.", DumpCubaIntegrationMethod().c_str(), fNvar));
02094 BCLog::OutDebug( Form(" --> Maximum number of iterations: %i", fCubaMaxEval));
02095 BCLog::OutDebug( Form(" --> Aimed relative precision: %e", fRelativePrecision));
02096
02097 return CubaIntegrate(fCubaIntegrationMethod, parameters_double, parameters_int);
02098 #else
02099 BCLog::OutError("!!! This version of BAT is compiled without Cuba.");
02100 BCLog::OutError(" Use other integration methods or install Cuba and recompile BAT.");
02101 return 0.;
02102 #endif
02103 }
02104
02105
02106 double BCIntegrate::CubaIntegrate(BCIntegrate::BCCubaMethod method, std::vector<double> parameters_double, std::vector<double> parameters_int)
02107 {
02108 #ifdef HAVE_CUBA_H
02109 const int NDIM = int(fx ->size());
02110 const int NCOMP = 1;
02111 const int USERDATA = 0;
02112 const int SEED = 0;
02113 const int NBATCH = 1000;
02114 const int GRIDNO = -1;
02115 const char*STATEFILE = "";
02116
02117 const double EPSREL = parameters_double[0];
02118 const double EPSABS = parameters_double[1];
02119 const int VERBOSE = int(parameters_int[0]);
02120 const int MINEVAL = int(parameters_int[1]);
02121 const int MAXEVAL = int(parameters_int[2]);
02122
02123 int neval;
02124 int fail;
02125 int nregions;
02126 double integral[NCOMP];
02127 double error[NCOMP];
02128 double prob[NCOMP];
02129
02130 global_this = this;
02131
02132 integrand_t an_integrand = &BCIntegrate::CubaIntegrand;
02133
02134 if (method == 0) {
02135
02136 const int NSTART = int(parameters_int[3]);
02137 const int NINCREASE = int(parameters_int[4]);
02138
02139
02140 Vegas(NDIM, NCOMP, an_integrand, USERDATA,
02141 EPSREL, EPSABS, VERBOSE, SEED,
02142 MINEVAL, MAXEVAL, NSTART, NINCREASE, NBATCH,
02143 GRIDNO, STATEFILE,
02144 &neval, &fail, integral, error, prob);
02145
02146
02147
02148
02149
02150
02151
02152
02153 }
02154 else if (method == 1) {
02155
02156
02157 const int NNEW = int(parameters_int[3]);
02158 const double FLATNESS = parameters_double[2];
02159
02160
02161 Suave(NDIM, NCOMP, an_integrand,
02162 USERDATA, EPSREL, EPSABS, VERBOSE, SEED,
02163 MINEVAL, MAXEVAL,
02164 NNEW, FLATNESS,
02165 &nregions, &neval, &fail, integral, error, prob);
02166
02167
02168
02169
02170
02171
02172
02173
02174 }
02175 else if (method == 2) {
02176
02177 const int KEY1 = int(parameters_int[3]);
02178 const int KEY2 = int(parameters_int[4]);
02179 const int KEY3 = int(parameters_int[5]);
02180 const int MAXPASS = int(parameters_int[6]);
02181 const int BORDER = int(parameters_int[7]);
02182 const int MAXCHISQ = int(parameters_int[8]);
02183 const int MINDEVIATION = int(parameters_int[9]);
02184 const int NGIVEN = int(parameters_int[10]);
02185 const int LDXGIVEN = int(parameters_int[11]);
02186 const int NEXTRA = int(parameters_int[12]);
02187 const int FLAGS = 0;
02188
02189
02190 Divonne(NDIM, NCOMP, an_integrand, USERDATA,
02191 EPSREL, EPSABS, FLAGS, SEED, MINEVAL, MAXEVAL,
02192 KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION,
02193 NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
02194 &nregions, &neval, &fail, integral, error, prob);
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 }
02206 else if (method == 3) {
02207
02208
02209 const int KEY = int(parameters_int[4]);
02210 const int FLAGS = 0;
02211
02212
02213 Cuhre(NDIM, NCOMP, an_integrand, USERDATA,
02214 EPSREL, EPSABS, FLAGS, MINEVAL, MAXEVAL, KEY,
02215 &nregions, &neval, &fail, integral, error, prob);
02216
02217
02218
02219
02220
02221
02222
02223 }
02224 else {
02225 std::cout << " Integration method not available. " << std::endl;
02226 integral[0] = -1e99;
02227 }
02228
02229 if (fail != 0) {
02230 std::cout << " Warning, integral did not converge with the given set of parameters. "<< std::endl;
02231 std::cout << " neval = " << neval << std::endl;
02232 std::cout << " fail = " << fail << std::endl;
02233 std::cout << " integral = " << integral[0] << std::endl;
02234 std::cout << " error = " << error[0] << std::endl;
02235 std::cout << " prob = " << prob[0] << std::endl;
02236 }
02237
02238 return integral[0] / 1e99;
02239 #else
02240 BCLog::OutError("!!! This version of BAT is compiled without Cuba.");
02241 BCLog::OutError(" Use other integration methods or install Cuba and recompile BAT.");
02242 return 0.;
02243 #endif
02244 }
02245
02246
02247 void BCIntegrate::MCMCIterationInterface()
02248 {
02249
02250
02251
02252
02253 MCMCFillErrorBand();
02254
02255
02256 MCMCUserIterationInterface();
02257 }
02258
02259
02260 void BCIntegrate::MCMCFillErrorBand()
02261 {
02262 if (!fFillErrorBand)
02263 return;
02264
02265
02266 if (fFitFunctionIndexX < 0)
02267 return;
02268
02269
02270 if (fErrorBandContinuous) {
02271 double x = 0;
02272 for (int ix = 0; ix < fErrorBandNbinsX; ix++) {
02273
02274 x = fErrorBandXY->GetXaxis()->GetBinCenter(ix + 1);
02275
02276
02277 std::vector <double> xvec;
02278 xvec.push_back(x);
02279
02280
02281 for (int ichain = 0; ichain < MCMCGetNChains(); ++ichain) {
02282
02283 double y = FitFunction(xvec, MCMCGetx(ichain));
02284
02285
02286 fErrorBandXY->Fill(x, y);
02287 }
02288
02289 xvec.clear();
02290 }
02291 }
02292
02293 else {
02294 int ndatapoints = int(fErrorBandX.size());
02295 double x = 0;
02296
02297 for (int ix = 0; ix < ndatapoints; ++ix) {
02298
02299 x = fErrorBandX.at(ix);
02300
02301
02302 std::vector <double> xvec;
02303 xvec.push_back(x);
02304
02305
02306 for (int ichain = 0; ichain < MCMCGetNChains(); ++ichain) {
02307
02308 double y = FitFunction(xvec, MCMCGetx(ichain));
02309
02310
02311 fErrorBandXY->Fill(x, y);
02312 }
02313
02314 xvec.clear();
02315 }
02316 }
02317 }
02318
02319
02320 void BCIntegrate::SAInitialize()
02321 {
02322 fSAx.clear();
02323 fSAx.assign(fNvar, 0.0);
02324 }
02325
02326
02327 std::string BCIntegrate::DumpIntegrationMethod(BCIntegrate::BCIntegrationMethod type)
02328 {
02329 switch(type) {
02330 case BCIntegrate::kIntMonteCarlo:
02331 return "Sampled Mean Monte Carlo";
02332 case BCIntegrate::kIntImportance:
02333 return "Importance Sampling";
02334 case BCIntegrate::kIntMetropolis:
02335 return "Metropolis";
02336 case BCIntegrate::kIntCuba:
02337 return "Cuba";
02338 default:
02339 return "Undefined";
02340 }
02341 }
02342
02343
02344 std::string BCIntegrate::DumpMarginalizationMethod(BCIntegrate::BCMarginalizationMethod type)
02345 {
02346 switch(type) {
02347 case BCIntegrate::kMargMonteCarlo:
02348 return "Monte Carlo Integration";
02349 case BCIntegrate::kMargMetropolis:
02350 return "Metropolis MCMC";
02351 default:
02352 return "Undefined";
02353 }
02354 }
02355
02356
02357 std::string BCIntegrate::DumpOptimizationMethod(BCIntegrate::BCOptimizationMethod type)
02358 {
02359 switch(type) {
02360 case BCIntegrate::kOptSA:
02361 return "Simulated Annealing";
02362 case BCIntegrate::kOptMetropolis:
02363 return "Metropolis MCMC";
02364 case BCIntegrate::kOptMinuit:
02365 return "Minuit";
02366 default:
02367 return "Undefined";
02368 }
02369 }
02370
02371
02372 std::string BCIntegrate::DumpCubaIntegrationMethod(BCIntegrate::BCCubaMethod type)
02373 {
02374 switch(type) {
02375 case BCIntegrate::kCubaVegas:
02376 return "Vegas";
02377 case BCIntegrate::kCubaSuave:
02378 return "Suave";
02379 case BCIntegrate::kCubaDivonne:
02380 return "Divonne";
02381 case BCIntegrate::kCubaCuhre:
02382 return "Cuhre";
02383 default:
02384 return "Undefined";
02385 }
02386 }
02387
02388
02389