00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "BCIntegrate.h"
00011 #include "BCLog.h"
00012
00013 #include <TRandom3.h>
00014
00015 #include "cuba.h"
00016
00017
00018
00019 class BCIntegrate * global_this;
00020
00021
00022 BCIntegrate::BCIntegrate() : BCEngineMCMC()
00023 {
00024 fNvar=0;
00025 fNiterPerDimension = 100;
00026 fNSamplesPer2DBin = 100;
00027 fRandom = new TRandom3(0);
00028
00029 fNIterationsMax = 1000000;
00030 fRelativePrecision = 1e-3;
00031
00032 fIntegrationMethod = BCIntegrate::kIntMonteCarlo;
00033 fMarginalizationMethod = BCIntegrate::kMargMetropolis;
00034 fOptimizationMethod = BCIntegrate::kOptMinuit;
00035
00036 fNbins=100;
00037
00038 fDataPointLowerBoundaries = 0;
00039 fDataPointUpperBoundaries = 0;
00040
00041 fFitFunctionIndexX = -1;
00042 fFitFunctionIndexY = -1;
00043
00044 fErrorBandNbinsX = 100;
00045 fErrorBandNbinsY = 500;
00046
00047 fErrorBandContinuous = true;
00048
00049 fMinuit = 0;
00050 fMinuitArglist[0] = 20000;
00051 fMinuitArglist[1] = 0.01;
00052
00053 fFlagWriteMarkovChain = false;
00054 fMarkovChainTree = 0;
00055
00056 fMarkovChainStepSize = 0.1;
00057
00058 fMarkovChainAutoN = true;
00059
00060 }
00061
00062
00063 BCIntegrate::BCIntegrate(BCParameterSet * par) : BCEngineMCMC(1)
00064 {
00065 fNvar=0;
00066 fNiterPerDimension = 100;
00067 fNSamplesPer2DBin = 100;
00068 fRandom = new TRandom3(0);
00069
00070 fNbins=100;
00071
00072 this->SetParameters(par);
00073
00074 fDataPointLowerBoundaries = 0;
00075 fDataPointUpperBoundaries = 0;
00076
00077 fFitFunctionIndexX = -1;
00078 fFitFunctionIndexY = -1;
00079
00080 fErrorBandNbinsX = 100;
00081 fErrorBandNbinsY = 200;
00082
00083 fErrorBandContinuous = true;
00084
00085 fMinuit = 0;
00086 fMinuitArglist[0] = 20000;
00087 fMinuitArglist[1] = 0.01;
00088
00089 fFlagWriteMarkovChain = false;
00090 fMarkovChainTree = 0;
00091
00092 fMarkovChainStepSize = 0.1;
00093
00094 fMarkovChainAutoN = true;
00095
00096 }
00097
00098
00099 BCIntegrate::~BCIntegrate()
00100 {
00101 DeleteVarList();
00102
00103 fx=0;
00104
00105 delete fRandom;
00106 fRandom=0;
00107
00108 if (fMinuit)
00109 delete fMinuit;
00110
00111 int n1 = fHProb1D.size();
00112 if(n1>0)
00113 {
00114 for (int i=0;i<n1;i++)
00115 delete fHProb1D.at(i);
00116 }
00117
00118 int n2 = fHProb2D.size();
00119 if(n2>0)
00120 {
00121 for (int i=0;i<n2;i++)
00122 delete fHProb2D.at(i);
00123 }
00124 }
00125
00126
00127 void BCIntegrate::SetParameters(BCParameterSet * par)
00128 {
00129 DeleteVarList();
00130
00131 fx = par;
00132 fNvar = fx->size();
00133 fMin = new double[fNvar];
00134 fMax = new double[fNvar];
00135 fVarlist = new int[fNvar];
00136
00137 this->ResetVarlist(1);
00138
00139 for(int i=0;i<fNvar;i++)
00140 {
00141 fMin[i]=(fx->at(i))->GetLowerLimit();
00142 fMax[i]=(fx->at(i))->GetUpperLimit();
00143 }
00144
00145 fXmetro0.clear();
00146 for(int i=0;i<fNvar;i++)
00147 fXmetro0.push_back((fMin[i]+fMax[i])/2.0);
00148
00149 fXmetro1.clear();
00150 fXmetro1.assign(fNvar,0.);
00151
00152 fMCMCBoundaryMin.clear();
00153 fMCMCBoundaryMax.clear();
00154
00155 for(int i=0;i<fNvar;i++)
00156 {
00157 fMCMCBoundaryMin.push_back(fMin[i]);
00158 fMCMCBoundaryMax.push_back(fMax[i]);
00159 }
00160
00161 fMCMCNParameters = fNvar;
00162
00163 }
00164
00165
00166 void BCIntegrate::SetMarkovChainInitialPosition(std::vector<double> position)
00167 {
00168
00169 int n = position.size();
00170
00171 fXmetro0.clear();
00172
00173 for (int i = 0; i < n; ++i)
00174 fXmetro0.push_back(position.at(i));
00175
00176 }
00177
00178
00179 void BCIntegrate::DeleteVarList()
00180 {
00181 if(fNvar)
00182 {
00183 delete[] fVarlist;
00184 fVarlist=0;
00185
00186 delete[] fMin;
00187 fMin=0;
00188
00189 delete[] fMax;
00190 fMax=0;
00191
00192 fx=0;
00193 fNvar=0;
00194 }
00195 }
00196
00197
00198 void BCIntegrate::SetNbins(int n)
00199 {
00200 if(n<2)
00201 {
00202 BCLog::Out(BCLog::warning, BCLog::warning,"BCIntegrate::SetNbins. Number of bins less than 2 makes no sense. Setting to 2.");
00203 n=2;
00204 }
00205 fNbins=n;
00206
00207 fMCMCH1NBins = n;
00208 fMCMCH2NBinsX = n;
00209 fMCMCH2NBinsY = n;
00210 }
00211
00212
00213 void BCIntegrate::SetNbinsX(int n)
00214 {
00215 if(n<2)
00216 {
00217 BCLog::Out(BCLog::warning, BCLog::warning,"BCIntegrate::SetNbins. Number of bins less than 2 makes no sense. Setting to 2.");
00218 n=2;
00219 }
00220 fMCMCH2NBinsX = n;
00221 }
00222
00223
00224 void BCIntegrate::SetNbinsY(int n)
00225 {
00226 if(n<2)
00227 {
00228 BCLog::Out(BCLog::warning, BCLog::warning,"BCIntegrate::SetNbins. Number of bins less than 2 makes no sense. Setting to 2.");
00229 n=2;
00230 }
00231 fNbins=n;
00232
00233 fMCMCH2NBinsY = n;
00234 }
00235
00236
00237 void BCIntegrate::SetVarList(int * varlist)
00238 {
00239 for(int i=0;i<fNvar;i++)
00240 fVarlist[i]=varlist[i];
00241 }
00242
00243
00244 void BCIntegrate::ResetVarlist(int v)
00245 {
00246 for(int i=0;i<fNvar;i++)
00247 fVarlist[i]=v;
00248 }
00249
00250
00251 double BCIntegrate::Eval(std::vector <double> x)
00252 {
00253 BCLog::Out(BCLog::warning, BCLog::warning, "BCIntegrate::Eval. No function. Function needs to be overloaded.");
00254 return 0;
00255 }
00256
00257
00258 double BCIntegrate::LogEval(std::vector <double> x)
00259 {
00260
00261 return log(this->Eval(x));
00262 }
00263
00264
00265 double BCIntegrate::EvalSampling(std::vector <double> x)
00266 {
00267 BCLog::Out(BCLog::warning, BCLog::warning, "BCIntegrate::EvalSampling. No function. Function needs to be overloaded.");
00268 return 0;
00269 }
00270
00271
00272 double BCIntegrate::LogEvalSampling(std::vector <double> x)
00273 {
00274 return log(this->EvalSampling(x));
00275 }
00276
00277
00278 double BCIntegrate::EvalPrint(std::vector <double> x)
00279 {
00280 double val=this->Eval(x);
00281
00282 BCLog::Out(BCLog::detail, BCLog::detail, Form("BCIntegrate::EvalPrint. Value: %d.", val));
00283
00284 return val;
00285 }
00286
00287
00288 double BCIntegrate::Integrate()
00289 {
00290 std::vector <double> parameter;
00291 parameter.assign(fNvar, 0.0);
00292
00293 switch(fIntegrationMethod)
00294 {
00295 case BCIntegrate::kIntMonteCarlo:
00296 return IntegralMC(parameter);
00297
00298 case BCIntegrate::kIntMetropolis:
00299 return this -> IntegralMetro(parameter);
00300
00301 case BCIntegrate::kIntImportance:
00302 return this -> IntegralImportance(parameter);
00303
00304 case BCIntegrate::kIntCuba:
00305 return this -> CubaIntegrate();
00306 }
00307
00308 BCLog::Out(BCLog::warning, BCLog::warning, Form("BCIntegrate::Integrate. Invalid integration method: %d. Return 0.",
00309 fIntegrationMethod));
00310
00311 return 0;
00312 }
00313
00314
00315 double BCIntegrate::IntegralMC(std::vector <double> x, int * varlist)
00316 {
00317 this->SetVarList(varlist);
00318 return IntegralMC(x);
00319 }
00320
00321
00322 double BCIntegrate::IntegralMC(std::vector <double> x)
00323 {
00324
00325 int NvarNow=0;
00326
00327 for(int i = 0; i < fNvar; i++)
00328 if(fVarlist[i])
00329 NvarNow++;
00330
00331
00332 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Running MC integation over %i dimensions.", NvarNow));
00333 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Maximum number of iterations: %i", this->GetNIterationsMax()));
00334 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Aimed relative precision: %e", this->GetRelativePrecision()));
00335
00336
00337 double D = 1.0;
00338 for(int i = 0; i < fNvar; i++)
00339 if (fVarlist[i])
00340 D = D * (fMax[i] - fMin[i]);
00341
00342
00343 double pmax = 0.0;
00344 double sumW = 0.0;
00345 double sumW2 = 0.0;
00346 double integral = 0.0;
00347 double variance = 0.0;
00348 double relprecision = 1.0;
00349
00350 std::vector <double> randx;
00351 randx.assign(fNvar, 0.0);
00352
00353
00354 fNIterations = 0;
00355
00356
00357 while ((fRelativePrecision < relprecision && fNIterationsMax > fNIterations) || fNIterations < 10)
00358 {
00359
00360 fNIterations++;
00361
00362
00363 this -> GetRandomVector(randx);
00364
00365
00366 for(int i = 0; i < fNvar; i++)
00367 {
00368 if(fVarlist[i])
00369 randx[i]=fMin[i]+randx[i]*(fMax[i]-fMin[i]);
00370 else
00371 randx[i]=x[i];
00372 }
00373
00374
00375 double value = this->Eval(randx);
00376
00377
00378 sumW += value;
00379 sumW2 += value * value;
00380
00381
00382 if (value > pmax)
00383 {
00384
00385 pmax = value;
00386
00387
00388 fBestFitParameters.clear();
00389
00390
00391 for(int i = 0; i < fNvar; i++)
00392 fBestFitParameters.push_back(randx.at(i));
00393 }
00394
00395
00396 integral = D * sumW / fNIterations;
00397
00398 if (fNIterations%10000 == 0)
00399 {
00400 variance = (1.0 / double(fNIterations)) * (D * D * sumW2 / double(fNIterations) - integral * integral);
00401 double error = sqrt(variance);
00402 relprecision = error / integral;
00403
00404 BCLog::Out(BCLog::debug, BCLog::debug,
00405 Form("BCIntegrate::IntegralMC. Iteration %i, integral: %e +- %e.", fNIterations, integral, error));
00406 }
00407 }
00408
00409 fError = variance / fNIterations;
00410
00411
00412 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Result of integration: %e +- %e in %i iterations.", integral, sqrt(variance), fNIterations));
00413 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Obtained relative precision: %e. ", sqrt(variance) / integral));
00414
00415 return integral;
00416 }
00417
00418
00419
00420 double BCIntegrate::IntegralMetro(std::vector <double> x)
00421 {
00422
00423 BCLog::Out(BCLog::debug, BCLog::debug, Form("BCIntegrate::IntegralMetro. Integate over %i dimensions.", fNvar));
00424
00425
00426 double Niter = pow(fNiterPerDimension, fNvar);
00427
00428
00429 if(Niter>1e5)
00430 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Total number of iterations in Metropolis: %d.", Niter));
00431
00432
00433 double sumI = 0;
00434
00435
00436 std::vector <double> randx;
00437 randx.assign(fNvar,0.);
00438 InitMetro();
00439
00440
00441 double pmax = 0.0;
00442
00443
00444 for(int i = 0; i <= Niter; i++)
00445 {
00446
00447 this -> GetRandomPointSamplingMetro(randx);
00448
00449
00450 double val_f = this -> Eval(randx);
00451
00452
00453 double val_g = this -> EvalSampling(randx);
00454
00455
00456 if (val_g > 0)
00457 sumI += val_f / val_g;
00458
00459
00460 if (val_f > pmax)
00461 {
00462
00463 pmax = val_f;
00464
00465
00466 fBestFitParameters.clear();
00467
00468
00469 for(int i = 0; i < fNvar; i++)
00470 fBestFitParameters.push_back(randx.at(i));
00471 }
00472
00473
00474 if((i+1)%100000 == 0)
00475 BCLog::Out(BCLog::debug, BCLog::debug,
00476 Form("BCIntegrate::IntegralMetro. Iteration %d, integral: %d.", i+1, sumI/(i+1)));
00477 }
00478
00479
00480 double result=sumI/Niter;
00481
00482
00483 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Integral is %f in %i iterations. ", result, Niter));
00484
00485 return result;
00486 }
00487
00488
00489 double BCIntegrate::IntegralImportance(std::vector <double> x)
00490 {
00491
00492 BCLog::Out(BCLog::debug, BCLog::debug, Form("BCIntegrate::IntegralImportance. Integate over %i dimensions.", fNvar));
00493
00494
00495 double Niter = pow(fNiterPerDimension, fNvar);
00496
00497
00498 if(Niter>1e5)
00499 BCLog::Out(BCLog::detail, BCLog::detail, Form("BCIntegrate::IntegralImportance. Total number of iterations: %d.", Niter));
00500
00501
00502 double sumI = 0;
00503
00504 std::vector <double> randx;
00505 randx.assign(fNvar,0.);
00506
00507
00508 double pmax = 0.0;
00509
00510
00511 for(int i = 0; i <= Niter; i++)
00512 {
00513
00514 this -> GetRandomPointImportance(randx);
00515
00516
00517 double val_f = this -> Eval(randx);
00518
00519
00520 double val_g = this -> EvalSampling(randx);
00521
00522
00523 if (val_g > 0)
00524 sumI += val_f / val_g;
00525
00526
00527 if (val_f > pmax)
00528 {
00529
00530 pmax = val_f;
00531
00532
00533 fBestFitParameters.clear();
00534
00535
00536 for(int i = 0; i < fNvar; i++)
00537 fBestFitParameters.push_back(randx.at(i));
00538 }
00539
00540
00541 if((i+1)%100000 == 0)
00542 BCLog::Out(BCLog::debug, BCLog::debug,
00543 Form("BCIntegrate::IntegralImportance. Iteration %d, integral: %d.", i+1, sumI/(i+1)));
00544 }
00545
00546
00547 double result=sumI/Niter;
00548
00549
00550 BCLog::Out(BCLog::debug, BCLog::debug, Form("BCIntegrate::IntegralImportance. Integral %f in %i iterations. ", result, Niter));
00551
00552 return result;
00553 }
00554
00555
00556 TH1D* BCIntegrate::Marginalize(BCParameter * parameter)
00557 {
00558 BCLog::Out(BCLog::detail, BCLog::detail,
00559 Form(" --> Marginalizing model wrt. parameter %s using method %d.", parameter->GetName().data(), fMarginalizationMethod));
00560
00561 switch(fMarginalizationMethod)
00562 {
00563 case BCIntegrate::kMargMonteCarlo:
00564 return MarginalizeByIntegrate(parameter);
00565
00566 case BCIntegrate::kMargMetropolis:
00567 return MarginalizeByMetro(parameter);
00568 }
00569
00570 BCLog::Out(BCLog::warning, BCLog::warning,
00571 Form("BCIntegrate::Marginalize. Invalid marginalization method: %d. Return 0.", fMarginalizationMethod));
00572
00573 return 0;
00574 }
00575
00576
00577 TH2D * BCIntegrate::Marginalize(BCParameter * parameter1, BCParameter * parameter2)
00578 {
00579 switch(fMarginalizationMethod)
00580 {
00581 case BCIntegrate::kMargMonteCarlo:
00582 return MarginalizeByIntegrate(parameter1,parameter2);
00583
00584 case BCIntegrate::kMargMetropolis:
00585 return MarginalizeByMetro(parameter1,parameter2);
00586 }
00587
00588 BCLog::Out(BCLog::warning, BCLog::warning,
00589 Form("BCIntegrate::Marginalize. Invalid marginalization method: %d. Return 0.", fMarginalizationMethod));
00590
00591 return 0;
00592 }
00593
00594
00595 TH1D* BCIntegrate::MarginalizeByIntegrate(BCParameter * parameter)
00596 {
00597
00598 this->ResetVarlist(1);
00599 int index = parameter->GetIndex();
00600 this->UnsetVar(index);
00601
00602
00603 double hmin = parameter -> GetLowerLimit();
00604 double hmax = parameter -> GetUpperLimit();
00605 double hdx = (hmax - hmin) / double(fNbins);
00606 TH1D * hist = new TH1D("hist","", fNbins, hmin, hmax);
00607
00608
00609 std::vector <double> randx;
00610 randx.assign(fNvar, 0.0);
00611
00612 for(int i=0;i<=fNbins;i++)
00613 {
00614 randx[index] = hmin + (double)i * hdx;
00615
00616 double val = IntegralMC(randx);
00617 hist->Fill(randx[index], val);
00618 }
00619
00620
00621 hist -> Scale( 1./hist->Integral("width") );
00622
00623 return hist;
00624 }
00625
00626
00627 TH2D * BCIntegrate::MarginalizeByIntegrate(BCParameter * parameter1, BCParameter * parameter2)
00628 {
00629
00630 this->ResetVarlist(1);
00631 int index1 = parameter1->GetIndex();
00632 this->UnsetVar(index1);
00633 int index2 = parameter2->GetIndex();
00634 this->UnsetVar(index2);
00635
00636
00637 double hmin1 = parameter1 -> GetLowerLimit();
00638 double hmax1 = parameter1 -> GetUpperLimit();
00639 double hdx1 = (hmax1 - hmin1) / double(fNbins);
00640
00641 double hmin2 = parameter2 -> GetLowerLimit();
00642 double hmax2 = parameter2 -> GetUpperLimit();
00643 double hdx2 = (hmax2 - hmin2) / double(fNbins);
00644
00645 TH2D * hist = new TH2D(Form("hist_%s_%s", parameter1 -> GetName().data(), parameter2 -> GetName().data()),"",
00646 fNbins, hmin1, hmax1,
00647 fNbins, hmin2, hmax2);
00648
00649
00650 std::vector <double> randx;
00651 randx.assign(fNvar, 0.0);
00652
00653 for(int i=0;i<=fNbins;i++)
00654 {
00655 randx[index1] = hmin1 + (double)i * hdx1;
00656 for(int j=0;j<=fNbins;j++)
00657 {
00658 randx[index2] = hmin2 + (double)j * hdx2;
00659
00660 double val = IntegralMC(randx);
00661 hist->Fill(randx[index1],randx[index2], val);
00662 }
00663 }
00664
00665
00666 hist -> Scale(1.0/hist->Integral("width"));
00667
00668 return hist;
00669 }
00670
00671
00672 TH1D * BCIntegrate::MarginalizeByMetro(BCParameter * parameter)
00673 {
00674 int niter = fMarkovChainNIterations;
00675
00676 if (fMarkovChainAutoN == true)
00677 niter = fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00678
00679 BCLog::Out(BCLog::detail, BCLog::detail,
00680 Form(" --> Number of samples in Metropolis marginalization: %d.", niter));
00681
00682
00683 int index = parameter->GetIndex();
00684
00685
00686 double hmin = parameter -> GetLowerLimit();
00687 double hmax = parameter -> GetUpperLimit();
00688 TH1D * hist = new TH1D("hist","", fNbins, hmin, hmax);
00689
00690
00691 std::vector <double> randx;
00692 randx.assign(fNvar, 0.0);
00693 InitMetro();
00694
00695 for(int i=0;i<=niter;i++)
00696 {
00697 GetRandomPointMetro(randx);
00698 hist->Fill(randx[index]);
00699 }
00700
00701
00702 hist -> Scale(1.0/hist->Integral("width"));
00703
00704 return hist;
00705 }
00706
00707
00708 TH2D * BCIntegrate::MarginalizeByMetro(BCParameter * parameter1, BCParameter * parameter2)
00709 {
00710 int niter=fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00711
00712
00713 int index1 = parameter1->GetIndex();
00714 int index2 = parameter2->GetIndex();
00715
00716
00717 double hmin1 = parameter1 -> GetLowerLimit();
00718 double hmax1 = parameter1 -> GetUpperLimit();
00719
00720 double hmin2 = parameter2 -> GetLowerLimit();
00721 double hmax2 = parameter2 -> GetUpperLimit();
00722
00723 TH2D * hist = new TH2D(Form("hist_%s_%s", parameter1 -> GetName().data(), parameter2 -> GetName().data()),"",
00724 fNbins, hmin1, hmax1,
00725 fNbins, hmin2, hmax2);
00726
00727
00728 std::vector <double> randx;
00729 randx.assign(fNvar, 0.0);
00730 InitMetro();
00731
00732 for(int i=0;i<=niter;i++)
00733 {
00734 GetRandomPointMetro(randx);
00735 hist->Fill(randx[index1],randx[index2]);
00736 }
00737
00738
00739 hist -> Scale(1.0/hist->Integral("width"));
00740
00741 return hist;
00742 }
00743
00744
00745 int BCIntegrate::MarginalizeAllByMetro(const char * name="")
00746 {
00747 int niter=fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00748
00749 BCLog::Out(BCLog::detail, BCLog::detail,
00750 Form(" --> Number of samples in Metropolis marginalization: %d.", niter));
00751
00752
00753 for(int i=0;i<fNvar;i++)
00754 {
00755 double hmin1 = fx->at(i) -> GetLowerLimit();
00756 double hmax1 = fx->at(i) -> GetUpperLimit();
00757
00758 TH1D * h1 = new TH1D(Form("h%s_%s", name, fx->at(i) -> GetName().data()),"",
00759 fNbins, hmin1, hmax1);
00760
00761 fHProb1D.push_back(h1);
00762 }
00763
00764
00765 for(int i=0;i<fNvar-1;i++)
00766 for(int j=i+1;j<fNvar;j++)
00767 {
00768 double hmin1 = fx->at(i) -> GetLowerLimit();
00769 double hmax1 = fx->at(i) -> GetUpperLimit();
00770
00771 double hmin2 = fx->at(j) -> GetLowerLimit();
00772 double hmax2 = fx->at(j) -> GetUpperLimit();
00773
00774 TH2D * h2 = new TH2D(Form("h%s_%s_%s", name, fx->at(i) -> GetName().data(), fx->at(j) -> GetName().data()),"",
00775 fNbins, hmin1, hmax1,
00776 fNbins, hmin2, hmax2);
00777
00778 fHProb2D.push_back(h2);
00779 }
00780
00781
00782 int nh2d = fHProb2D.size();
00783
00784 BCLog::Out(BCLog::detail, BCLog::detail,
00785 Form(" --> Marginalizing %d 1D distributions and %d 2D distributions.", fNvar, nh2d));
00786
00787
00788
00789 double dx = 0.0;
00790 double dy = 0.0;
00791
00792 if (fFitFunctionIndexX >= 0)
00793 {
00794 dx = (fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexX) -
00795 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexX))
00796 / double(fErrorBandNbinsX);
00797
00798 dx = (fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexY) -
00799 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexY))
00800 / double(fErrorBandNbinsY);
00801
00802 fErrorBandXY = new TH2D("errorbandxy", "",
00803 fErrorBandNbinsX + 1,
00804 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexX) -
00805 0.5 * dx,
00806 fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexX) +
00807 0.5 * dx,
00808 fErrorBandNbinsY + 1,
00809 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexY) -
00810 0.5 * dy,
00811 fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexY) +
00812 0.5 * dy);
00813 fErrorBandXY -> SetStats(kFALSE);
00814
00815 for (int ix = 1; ix <= fErrorBandNbinsX; ++ix)
00816 for (int iy = 1; iy <= fErrorBandNbinsX; ++iy)
00817 fErrorBandXY -> SetBinContent(ix, iy, 0.0);
00818 }
00819
00820
00821 std::vector <double> randx;
00822
00823 randx.assign(fNvar, 0.0);
00824 InitMetro();
00825
00826
00827
00828 fNacceptedMCMC = 0;
00829
00830
00831 for(int i=0;i<=niter;i++)
00832 {
00833 GetRandomPointMetro(randx);
00834
00835
00836 if (fFlagWriteMarkovChain)
00837 {
00838 fMCMCIteration = i;
00839 fMarkovChainTree -> Fill();
00840 }
00841
00842 for(int j=0;j<fNvar;j++)
00843 fHProb1D[j] -> Fill( randx[j] );
00844
00845 int ih=0;
00846 for(int j=0;j<fNvar-1;j++)
00847 for(int k=j+1;k<fNvar;k++)
00848 {
00849 fHProb2D[ih] -> Fill(randx[j],randx[k]);
00850 ih++;
00851 }
00852
00853 if((i+1)%100000==0)
00854 BCLog::Out(BCLog::debug, BCLog::debug,
00855 Form("BCIntegrate::MarginalizeAllByMetro. %d samples done.",i+1));
00856
00857
00858
00859 if (fFitFunctionIndexX >= 0)
00860 {
00861
00862
00863
00864 if (fErrorBandContinuous)
00865 {
00866 double x = 0;
00867
00868 for (int ix = 0; ix < fErrorBandNbinsX; ix++)
00869 {
00870
00871
00872 x = fErrorBandXY -> GetXaxis() -> GetBinCenter(ix + 1);
00873
00874
00875
00876 std::vector <double> xvec;
00877 xvec.push_back(x);
00878
00879 double y = this -> FitFunction(xvec, randx);
00880
00881 xvec.clear();
00882
00883
00884
00885 fErrorBandXY -> Fill(x, y);
00886 }
00887 }
00888
00889
00890
00891 else
00892 {
00893
00894 int ndatapoints = int(fErrorBandX.size());
00895
00896 double x = 0;
00897
00898 for (int ix = 0; ix < ndatapoints; ++ix)
00899 {
00900
00901
00902 x = fErrorBandX.at(ix);
00903
00904
00905
00906 std::vector <double> xvec;
00907 xvec.push_back(x);
00908
00909 double y = this -> FitFunction(xvec, randx);
00910
00911 xvec.clear();
00912
00913
00914
00915 fErrorBandXY -> Fill(x, y);
00916 }
00917
00918 }
00919 }
00920 }
00921
00922
00923
00924 for(int i=0;i<fNvar;i++)
00925 fHProb1D[i] -> Scale( 1./fHProb1D[i]->Integral("width") );
00926
00927 for (int i=0;i<nh2d;i++)
00928 fHProb2D[i] -> Scale( 1./fHProb2D[i]->Integral("width") );
00929
00930 if (fFitFunctionIndexX >= 0)
00931 fErrorBandXY -> Scale(1.0/fErrorBandXY -> Integral() * fErrorBandXY -> GetNbinsX());
00932
00933 if (fFitFunctionIndexX >= 0)
00934 {
00935 for (int ix = 1; ix <= fErrorBandNbinsX; ix++)
00936 {
00937 double sum = 0;
00938
00939 for (int iy = 1; iy <= fErrorBandNbinsY; iy++)
00940 sum += fErrorBandXY -> GetBinContent(ix, iy);
00941
00942 for (int iy = 1; iy <= fErrorBandNbinsY; iy++)
00943 {
00944 double newvalue = fErrorBandXY -> GetBinContent(ix, iy) / sum;
00945 fErrorBandXY -> SetBinContent(ix, iy, newvalue);
00946 }
00947 }
00948 }
00949
00950 BCLog::Out(BCLog::detail, BCLog::detail,
00951 Form("BCIntegrate::MarginalizeAllByMetro done with %i trials and %i accepted trials. Efficiency is %f",fNmetro, fNacceptedMCMC, double(fNacceptedMCMC)/double(fNmetro)));
00952
00953 return fNvar+nh2d;
00954
00955 }
00956
00957
00958 TH1D * BCIntegrate::GetH1D(int parIndex)
00959 {
00960 if(fHProb1D.size()==0)
00961 {
00962 BCLog::Out(BCLog::warning, BCLog::warning,
00963 "BCModel::GetH1D. MarginalizeAll() has to be run prior to this to fill the distributions.");
00964 return 0;
00965 }
00966
00967 if(parIndex<0 || parIndex>fNvar)
00968 {
00969 BCLog::Out(BCLog::warning, BCLog::warning,
00970 Form("BCIntegrate::GetH1D. Parameter index %d is invalid.",parIndex));
00971 return 0;
00972 }
00973
00974 return fHProb1D[parIndex];
00975 }
00976
00977
00978 int BCIntegrate::GetH2DIndex(int parIndex1, int parIndex2)
00979 {
00980 if(parIndex1>fNvar-1 || parIndex1<0)
00981 {
00982 BCLog::Out(BCLog::warning, BCLog::warning,
00983 Form("BCIntegrate::GetH2DIndex. Parameter index %d is invalid", parIndex1));
00984 return -1;
00985 }
00986
00987 if(parIndex2>fNvar-1 || parIndex2<0)
00988 {
00989 BCLog::Out(BCLog::warning, BCLog::warning,
00990 Form("BCIntegrate::GetH2DIndex. Parameter index %d is invalid", parIndex2));
00991 return -1;
00992 }
00993
00994 if(parIndex1==parIndex2)
00995 {
00996 BCLog::Out(BCLog::warning, BCLog::warning,
00997 Form("BCIntegrate::GetH2DIndex. Parameters have equal indeces: %d , %d", parIndex1, parIndex2));
00998 return -1;
00999 }
01000
01001 if(parIndex1>parIndex2)
01002 {
01003 BCLog::Out(BCLog::warning, BCLog::warning,
01004 "BCIntegrate::GetH2DIndex. First parameters must be smaller than second (sorry).");
01005 return -1;
01006 }
01007
01008 int index=0;
01009 for(int i=0;i<fNvar-1;i++)
01010 for(int j=i+1;j<fNvar;j++)
01011 {
01012 if(i==parIndex1 && j==parIndex2)
01013 return index;
01014 index++;
01015 }
01016
01017 BCLog::Out(BCLog::warning, BCLog::warning,
01018 "BCIntegrate::GetH2DIndex. Invalid index combination.");
01019
01020 return -1;
01021 }
01022
01023
01024 TH2D * BCIntegrate::GetH2D(int parIndex1, int parIndex2)
01025 {
01026 if(fHProb2D.size()==0)
01027 {
01028 BCLog::Out(BCLog::warning, BCLog::warning,
01029 "BCModel::GetH2D. MarginalizeAll() has to be run prior to this to fill the distributions.");
01030 return 0;
01031 }
01032
01033 int hindex = this -> GetH2DIndex(parIndex1, parIndex2);
01034 if(hindex==-1)
01035 return 0;
01036
01037 if(hindex>(int)fHProb2D.size()-1)
01038 {
01039 BCLog::Out(BCLog::warning, BCLog::warning,
01040 "BCIntegrate::GetH2D. Got invalid index from GetH2DIndex(). Something went wrong.");
01041 return 0;
01042 }
01043
01044 return fHProb2D[hindex];
01045 }
01046
01047
01048 double BCIntegrate::GetRandomPoint(std::vector <double> &x)
01049 {
01050 this->GetRandomVector(x);
01051
01052 for(int i=0;i<fNvar;i++)
01053 x[i]=fMin[i]+x[i]*(fMax[i]-fMin[i]);
01054
01055 return this->Eval(x);
01056 }
01057
01058
01059 double BCIntegrate::GetRandomPointImportance(std::vector <double> &x)
01060 {
01061 double p = 1.1;
01062 double g = 1.0;
01063
01064 while (p>g)
01065 {
01066 this->GetRandomVector(x);
01067
01068 for(int i=0;i<fNvar;i++)
01069 x[i] = fMin[i] + x[i] * (fMax[i]-fMin[i]);
01070
01071 p = fRandom->Rndm();
01072
01073 g = this -> EvalSampling(x);
01074 }
01075
01076 return this->Eval(x);
01077 }
01078
01079
01080 void BCIntegrate::InitMetro()
01081 {
01082 fNmetro=0;
01083
01084 if (fXmetro0.size() <= 0)
01085 {
01086
01087 for(int i=0;i<fNvar;i++)
01088 fXmetro0.push_back((fMin[i]+fMax[i])/2.0);
01089 }
01090
01091 fMarkovChainValue = this -> LogEval(fXmetro0);
01092
01093
01094 std::vector <double> x;
01095 x.assign(fNvar,0.);
01096
01097 for(int i=0;i<1000;i++)
01098 GetRandomPointMetro(x);
01099
01100 fNmetro = 0;
01101
01102 }
01103
01104
01105 void BCIntegrate::GetRandomPointMetro(std::vector <double> &x)
01106 {
01107
01108 this->GetRandomVectorMetro(fXmetro1);
01109
01110
01111 int in=1;
01112 for(int i=0;i<fNvar;i++)
01113 {
01114 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * (fMax[i]-fMin[i]);
01115
01116
01117 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01118 in=0;
01119 }
01120
01121
01122
01123 double p0 = fMarkovChainValue;
01124 double p1 = 0;
01125 int accept=0;
01126
01127 if(in)
01128 {
01129 p1 = this -> LogEval(fXmetro1);
01130
01131 if(p1>=p0)
01132 accept=1;
01133 else
01134 {
01135 double r=log(fRandom->Rndm());
01136 if(r<p1-p0)
01137 accept=1;
01138 }
01139 }
01140
01141
01142 if(accept)
01143 {
01144
01145 fNacceptedMCMC++;
01146
01147 for(int i=0;i<fNvar;i++)
01148 {
01149 fXmetro0[i]=fXmetro1[i];
01150 x[i]=fXmetro1[i];
01151 fMarkovChainValue = p1;
01152 }
01153
01154 }
01155 else
01156 for(int i=0;i<fNvar;i++)
01157 {
01158 x[i]=fXmetro0[i];
01159 fXmetro1[i] = x[i];
01160 fMarkovChainValue = p0;
01161 }
01162
01163 fNmetro++;
01164
01165 }
01166
01167
01168 void BCIntegrate::GetRandomPointSamplingMetro(std::vector <double> &x)
01169 {
01170
01171 this->GetRandomVectorMetro(fXmetro1);
01172
01173
01174 int in=1;
01175 for(int i=0;i<fNvar;i++)
01176 {
01177 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * (fMax[i]-fMin[i]);
01178
01179
01180 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01181 in=0;
01182 }
01183
01184
01185 double p0 = this -> LogEvalSampling(fXmetro0);
01186 double p1=0;
01187 if(in)
01188 p1= this -> LogEvalSampling(fXmetro1);
01189
01190
01191 int accept=0;
01192 if(in)
01193 {
01194 if(p1>=p0)
01195 accept=1;
01196 else
01197 {
01198 double r=log(fRandom->Rndm());
01199 if(r<p1-p0)
01200 accept=1;
01201 }
01202 }
01203
01204
01205 if(accept)
01206 for(int i=0;i<fNvar;i++)
01207 {
01208 fXmetro0[i]=fXmetro1[i];
01209 x[i]=fXmetro1[i];
01210 }
01211 else
01212 for(int i=0;i<fNvar;i++)
01213 x[i]=fXmetro0[i];
01214
01215 fNmetro++;
01216 }
01217
01218
01219 void BCIntegrate::GetRandomVector(std::vector <double> &x)
01220 {
01221 double * randx = new double[fNvar];
01222
01223 fRandom -> RndmArray(fNvar, randx);
01224
01225 for(int i=0;i<fNvar;i++)
01226 x[i] = randx[i];
01227
01228 delete[] randx;
01229 randx = 0;
01230 }
01231
01232
01233 void BCIntegrate::GetRandomVectorMetro(std::vector <double> &x)
01234 {
01235 double * randx = new double[fNvar];
01236
01237 fRandom -> RndmArray(fNvar, randx);
01238
01239 for(int i=0;i<fNvar;i++)
01240 x[i] = 2.0 * (randx[i] - 0.5) * fMarkovChainStepSize;
01241
01242 delete[] randx;
01243 randx = 0;
01244 }
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 TMinuit * BCIntegrate::GetMinuit()
01285 {
01286
01287 if (!fMinuit)
01288 fMinuit = new TMinuit();
01289
01290 return fMinuit;
01291
01292 }
01293
01294
01295
01296 void BCIntegrate::FindModeMinuit()
01297 {
01298
01299
01300
01301 global_this = this;
01302
01303
01304
01305
01306 if (fMinuit)
01307 delete fMinuit;
01308
01309 fMinuit = new TMinuit(fNvar);
01310
01311
01312
01313 fMinuit -> SetFCN(&BCIntegrate::FCNLikelihood);
01314
01315
01316
01317 int flag;
01318
01319 for (int i = 0; i < fNvar; i++)
01320 fMinuit -> mnparm(i,
01321 fx -> at(i) -> GetName().data(),
01322 (fMin[i]+fMax[i])/2.0,
01323 (fMax[i]-fMin[i])/100.0,
01324 fMin[i],
01325 fMax[i],
01326 flag);
01327
01328
01329 fMinuit -> mnexcm("MIGRAD", fMinuitArglist, 2, flag);
01330
01331
01332 fMinuitErrorFlag = flag;
01333
01334
01335 fBestFitParameters.clear();
01336
01337 for (int i = 0; i < fNvar; i++)
01338 {
01339 double par;
01340 double parerr;
01341
01342 fMinuit -> GetParameter(i, par, parerr);
01343
01344 fBestFitParameters.push_back(par);
01345 }
01346
01347
01348
01349
01350
01351
01352
01353 return;
01354
01355 }
01356
01357
01358
01359 void BCIntegrate::SetMode(std::vector <double> mode)
01360 {
01361 if((int)mode.size() == fNvar)
01362 {
01363 fBestFitParameters.clear();
01364 for (int i = 0; i < fNvar; i++)
01365 fBestFitParameters.push_back(mode[i]);
01366 }
01367 }
01368
01369
01370
01371 void BCIntegrate::FCNLikelihood(int &npar, double * grad, double &fval, double * par, int flag)
01372 {
01373
01374
01375
01376 std::vector <double> parameters;
01377
01378 for (int i = 0; i < npar; i++)
01379 parameters.push_back(par[i]);
01380
01381 fval = - global_this -> LogEval(parameters);
01382
01383
01384
01385 parameters.clear();
01386
01387 }
01388
01389
01390 void BCIntegrate::FindModeSA()
01391 {
01392
01393 int npresamples = fNvar*100000;
01394
01395
01396 std::vector <double> xmax;
01397 xmax.assign(fNvar, 0.0);
01398
01399
01400 double lastmax = -log(this->GetRandomPoint(xmax));
01401
01402 std::vector <double> x;
01403 x.assign(fNvar, 0.0);
01404
01405
01406 double mean=0;
01407 for(int i=0;i<npresamples;i++)
01408 {
01409 this->GetRandomPoint(x);
01410 double val = -this->LogEval(x);
01411 mean += val;
01412
01413
01414 if(val < lastmax)
01415 {
01416 lastmax=val;
01417 xmax.clear();
01418 for(int j=0;j<fNvar;j++)
01419 xmax.push_back(x[j]);
01420 }
01421 }
01422 mean /= (double)npresamples;
01423
01424
01425 for(int i=0;i<fNvar;i++)
01426 fXmetro0[i]=xmax[i];
01427
01428 double T = mean/2.;
01429 double xstep = .1;
01430 int nSmin = fNvar*10000;
01431 int nSmax = fNvar*100000;
01432
01433
01434 double factorT = 1.2;
01435
01436 BCLog::Out(BCLog::debug, BCLog::debug,
01437 Form("BCIntegrate::FindModeSA. Starting SA mode finding after %d initial iterations with T=%f",npresamples,T));
01438
01439 int nsave=1000;
01440
01441 double * ysave = new double[nsave];
01442
01443
01444 xmax.clear();
01445
01446 double maxval=0.;
01447
01448
01449
01450 double Tmin=.1;
01451
01452
01453 double lastrms=2.*T;
01454
01455 int j=0;
01456
01457
01458 int stage=0;
01459
01460
01461 int niter=0;
01462
01463
01464 while(T>Tmin)
01465 {
01466 stage++;
01467
01468 int i=0;
01469 j=0;
01470
01471
01472
01473 while( i<nSmax && (i<nSmin || (i>=nSmin && lastrms>T) ) )
01474 {
01475 niter++;
01476
01477
01478 this->GetRandomPointSA(x,T,xstep);
01479
01480
01481 double val = - this->LogEval(x);
01482
01483
01484 if(i>nSmin-nsave-1)
01485 {
01486
01487 ysave[j%nsave] = val;
01488 j++;
01489 }
01490
01491 if(i>=nSmin-1)
01492
01493 lastrms = BCMath::rms(nsave,ysave);
01494
01495
01496
01497 if(val<maxval)
01498 {
01499 maxval=val;
01500 for(int k=0;k<fNvar;k++)
01501 xmax.push_back(x[k]);
01502 }
01503
01504 i++;
01505 }
01506
01507 BCLog::Out(BCLog::debug, BCLog::debug,
01508 Form("BCIntegrate::FindModeSA. Stage %d finished at T=%f after %d samples with RMS = %f",stage,T,i,lastrms));
01509
01510 if(i>=nSmax && lastrms>T)
01511 BCLog::Out(BCLog::detail, BCLog::detail,
01512 Form(" --> SA not converged in stage %d for T=%f in %d iterations (RMS reached is %f)",stage,T,nSmax,lastrms));
01513
01514
01515 T /= factorT;
01516 }
01517
01518
01519 fBestFitParameters.clear();
01520 for(int i=0;i<fNvar;i++)
01521 fBestFitParameters.push_back(xmax[i]);
01522
01523 BCLog::Out(BCLog::detail, BCLog::detail,
01524 Form(" --> SA mode finding finished in %d stages after %d iterations",stage,niter));
01525
01526 delete[] ysave;
01527 }
01528
01529
01530
01531
01532 void BCIntegrate::FindModeMCMC()
01533 {
01534
01535
01536
01537
01538
01539
01540
01541 double probmax = (this -> MCMCGetMaximumLogProb()).at(0);
01542 fBestFitParameters = this -> MCMCGetMaximumPoint(0);
01543
01544
01545 for (int i = 1; i < fMCMCNChains; ++i)
01546 {
01547 double prob = (this -> MCMCGetMaximumLogProb()).at(i);
01548
01549
01550 if (prob > probmax)
01551 {
01552 probmax = prob;
01553
01554 fBestFitParameters.clear();
01555
01556 fBestFitParameters = this -> MCMCGetMaximumPoint(i);
01557 }
01558 }
01559
01560 }
01561
01562
01563 void BCIntegrate::GetRandomPointSA(std::vector <double> &x, double T, double step)
01564 {
01565
01566 this->GetRandomVectorMetro(fXmetro1);
01567
01568
01569 int in=1;
01570 for(int i=0;i<fNvar;i++)
01571 {
01572 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * step * (fMax[i]-fMin[i]);
01573
01574
01575 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01576 in=0;
01577 }
01578
01579
01580 double p0 = - this->LogEval(fXmetro0);
01581 double p1 = 0;
01582
01583
01584 int accept=0;
01585 if(in)
01586 {
01587 p1 = - this->LogEval(fXmetro1);
01588
01589 if(p1<=p0)
01590 accept=1;
01591 else
01592 {
01593 double pval = exp(-(p1-p0)/T);
01594 double r=fRandom->Rndm();
01595 if(r<pval)
01596 accept=1;
01597 }
01598 }
01599
01600
01601 if(accept)
01602 for(int i=0;i<fNvar;i++)
01603 {
01604 fXmetro0[i]=fXmetro1[i];
01605 x[i]=fXmetro1[i];
01606 }
01607 else
01608 for(int i=0;i<fNvar;i++)
01609 x[i]=fXmetro0[i];
01610
01611 fNmetro++;
01612 }
01613
01614
01615 void BCIntegrate::CubaIntegrand(const int *ndim, const double xx[],
01616 const int *ncomp, double ff[])
01617 {
01618
01619 double jacobian = 1.0;
01620
01621 std::vector<double> scaled_parameters;
01622
01623 for (int i = 0; i < *ndim; i++)
01624 {
01625 double range = global_this -> fx -> at(i) -> GetUpperLimit() - global_this -> fx -> at(i) -> GetLowerLimit();
01626
01627
01628 jacobian *= range;
01629
01630
01631 scaled_parameters.push_back(global_this -> fx -> at(i) -> GetLowerLimit() + xx[i] * range);
01632 }
01633
01634
01635 ff[0] = global_this -> Eval(scaled_parameters);
01636
01637
01638 ff[0] *= jacobian;
01639
01640
01641 ff[0] *= 1e99;
01642
01643
01644 scaled_parameters.clear();
01645 }
01646
01647
01648 double BCIntegrate::CubaIntegrate()
01649 {
01650 double EPSREL = 1e-3;
01651 double EPSABS = 1e-12;
01652 double VERBOSE = 0;
01653 double MINEVAL = 0;
01654 double MAXEVAL = 2000000;
01655 double NSTART = 25000;
01656 double NINCREASE = 25000;
01657
01658 std::vector<double> parameters_double;
01659 std::vector<double> parameters_int;
01660
01661 parameters_double.push_back(EPSREL);
01662 parameters_double.push_back(EPSABS);
01663
01664 parameters_int.push_back(VERBOSE);
01665 parameters_int.push_back(MINEVAL);
01666 parameters_int.push_back(MAXEVAL);
01667 parameters_int.push_back(NSTART);
01668 parameters_int.push_back(NINCREASE);
01669
01670 return this -> CubaIntegrate(0, parameters_double, parameters_int);
01671 }
01672
01673
01674 double BCIntegrate::CubaIntegrate(int method, std::vector<double> parameters_double, std::vector<double> parameters_int)
01675 {
01676 const int NDIM = int(fx ->size());
01677 const int NCOMP = 1;
01678
01679 const double EPSREL = parameters_double[0];
01680 const double EPSABS = parameters_double[1];
01681 const int VERBOSE = int(parameters_int[0]);
01682 const int MINEVAL = int(parameters_int[1]);
01683 const int MAXEVAL = int(parameters_int[2]);
01684
01685 int neval;
01686 int fail;
01687 int nregions;
01688 double integral[NCOMP];
01689 double error[NCOMP];
01690 double prob[NCOMP];
01691
01692 global_this = this;
01693
01694 integrand_t an_integrand = &BCIntegrate::CubaIntegrand;
01695
01696 if (method == 0)
01697 {
01698
01699 const int NSTART = int(parameters_int[3]);
01700 const int NINCREASE = int(parameters_int[4]);
01701
01702
01703 Vegas(NDIM, NCOMP, an_integrand,
01704 EPSREL, EPSABS, VERBOSE, MINEVAL, MAXEVAL,
01705 NSTART, NINCREASE,
01706 &neval, &fail, integral, error, prob);
01707 }
01708 else if (method == 1)
01709 {
01710
01711 const int LAST = int(parameters_int[3]);
01712 const int NNEW = int(parameters_int[4]);
01713 const int FLATNESS = int(parameters_int[5]);
01714
01715
01716 Suave(NDIM, NCOMP, an_integrand,
01717 EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
01718 NNEW, FLATNESS,
01719 &nregions, &neval, &fail, integral, error, prob);
01720 }
01721 else if (method == 2)
01722 {
01723
01724 const int KEY1 = int(parameters_int[3]);
01725 const int KEY2 = int(parameters_int[4]);
01726 const int KEY3 = int(parameters_int[5]);
01727 const int MAXPASS = int(parameters_int[6]);
01728 const int BORDER = int(parameters_int[7]);
01729 const int MAXCHISQ = int(parameters_int[8]);
01730 const int MINDEVIATION = int(parameters_int[9]);
01731 const int NGIVEN = int(parameters_int[10]);
01732 const int LDXGIVEN = int(parameters_int[11]);
01733 const int NEXTRA = int(parameters_int[12]);
01734
01735
01736 Divonne(NDIM, NCOMP, an_integrand,
01737 EPSREL, EPSABS, VERBOSE, MINEVAL, MAXEVAL,
01738 KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION,
01739 NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
01740 &nregions, &neval, &fail, integral, error, prob);
01741 }
01742 else if (method == 3)
01743 {
01744
01745 const int LAST = int(parameters_int[3]);
01746 const int KEY = int(parameters_int[4]);
01747
01748
01749 Cuhre(NDIM, NCOMP, an_integrand,
01750 EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, KEY,
01751 &nregions, &neval, &fail, integral, error, prob);
01752 }
01753 else
01754 {
01755 std::cout << " Integration method not available. " << std::endl;
01756 integral[0] = -1e99;
01757 }
01758
01759 if (fail != 0)
01760 {
01761 std::cout << " Warning, integral did not converge with the given set of parameters. "<< std::endl;
01762 std::cout << " neval = " << neval << std::endl;
01763 std::cout << " fail = " << fail << std::endl;
01764 std::cout << " integral = " << integral[0] << std::endl;
01765 std::cout << " error = " << error[0] << std::endl;
01766 std::cout << " prob = " << prob[0] << std::endl;
01767 }
01768
01769 return integral[0] / 1e99;
01770 }
01771
01772
01773
01774 void BCIntegrate::MCMCUpdateFunctionFitting()
01775 {
01776
01777
01778
01779 if (fFitFunctionIndexX < 0)
01780 return;
01781
01782 else
01783 {
01784
01785
01786 if (fErrorBandContinuous)
01787 {
01788 double x = 0;
01789
01790 for (int ix = 0; ix < fErrorBandNbinsX; ix++)
01791 {
01792
01793
01794 x = fErrorBandXY -> GetXaxis() -> GetBinCenter(ix + 1);
01795
01796
01797
01798 std::vector <double> xvec;
01799 xvec.push_back(x);
01800
01801
01802
01803 for (int ichain = 0; ichain < this -> MCMCGetNChains(); ++ichain)
01804 {
01805
01806
01807 double y = this -> FitFunction(xvec, this -> MCMCGetx(ichain));
01808
01809
01810
01811 fErrorBandXY -> Fill(x, y);
01812 }
01813
01814 xvec.clear();
01815 }
01816 }
01817
01818
01819
01820 else
01821 {
01822
01823 int ndatapoints = int(fErrorBandX.size());
01824
01825 double x = 0;
01826
01827 for (int ix = 0; ix < ndatapoints; ++ix)
01828 {
01829
01830
01831 x = fErrorBandX.at(ix);
01832
01833
01834
01835 std::vector <double> xvec;
01836 xvec.push_back(x);
01837
01838
01839
01840 for (int ichain = 0; ichain < this -> MCMCGetNChains(); ++ichain)
01841 {
01842
01843
01844 double y = this -> FitFunction(xvec, this -> MCMCGetx(ichain));
01845
01846
01847
01848 fErrorBandXY -> Fill(x, y);
01849 }
01850
01851 xvec.clear();
01852 }
01853
01854 }
01855 }
01856
01857 }
01858
01859
01860