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