43 class BCIntegrateHolder
60 static BCIntegrateHolder result;
62 result.global_this = obj;
64 return result.global_this;
71 fID(
BCLog::GetHIndex()),
74 fFlagIgnorePrevOptimization(false),
78 fFlagWriteSAToFile(false),
84 fFlagMarginalized(false),
85 fOptimizationMethodCurrent(
BCIntegrate::kOptDefault),
87 fIntegrationMethodCurrent(
BCIntegrate::kIntDefault),
89 fMarginalizationMethodCurrent(
BCIntegrate::kMargDefault),
90 fMarginalizationMethodUsed(
BCIntegrate::kMargEmpty),
93 fNIterationsMax(1000000),
94 fNIterationsPrecisionCheck(1000),
95 fNIterationsOutput(0),
97 fLogMaximum(-std::numeric_limits<double>::max()),
99 fRelativePrecision(1e-2),
100 fAbsolutePrecision(1e-6),
182 BCLog::OutError(
"BCIntegrate::GetBestFitParameter : Mode finding not yet run, returning center of the range.");
193 BCLog::OutError(
"BCIntegrate::GetBestFitParameterError : Parameter index out of range, returning -1.");
213 BCLog::OutWarning(
"BCIntegrate::Eval. No function. Function needs to be overloaded.");
249 double integrationVolume = -1.;
253 if (integrationVolume<0)
254 integrationVolume = 1;
255 integrationVolume *=
fParameters[i]->GetRangeWidth();
258 if (integrationVolume<0)
259 integrationVolume = 0;
261 return integrationVolume;
269 BCLog::OutError(
"BCIntegrate::Integrate : No parameters defined. Aborting.");
291 std::vector<double> sums (2,0.0);
374 if (new_value < old_value)
376 old_value = new_value;
405 bool printed =
false;
409 BCLog::OutDetail(TString::Format(
"Running %s (%s) integration over %i dimensions out of %i.",
417 BCLog::OutDetail(TString::Format(
"Running %s integration over %i dimensions out of %i.",
427 bool printed =
false;
430 BCLog::OutDetail(TString::Format(
"Running %s (%s) integration over %i dimensions.",
438 BCLog::OutDetail(TString::Format(
"Running %s integration over %i dimensions.",
454 BCLog::OutSummary(TString::Format(
" --> Result of integration: %e +- %e", integral, absprecision));
455 BCLog::OutSummary(TString::Format(
" --> Obtained relative precision: %e. ", relprecision));
456 if (nIterations >= 0)
457 BCLog::OutSummary(TString::Format(
" --> Number of iterations: %i", nIterations));
468 std::vector<double> &sums)
474 double integral = 0.;
494 (this->*randomizer)(randx);
508 relprecision = absprecision / integral;
513 double temp_integral;
514 double temp_absprecision;
515 (*updater)(sums,
fNIterations, temp_integral, temp_absprecision);
522 relprecision = absprecision / integral;
525 BCLog::OutWarning(
"BCIntegrate::Integrate: Did not converge within maximum number of iterations");
536 const double value =
Eval(point);
543 sums[1] += value * value;
551 integral = sums[2] * sums[0] / nIterations;
554 absprecision = sqrt((1.0 / (nIterations - 1)) * (sums[2] * sums[2] * sums[1] /
double(nIterations) - integral * integral));
570 BCLog::OutError(TString::Format(
"BCIntegrate::CheckMarginalizationAvailability. Invalid marginalization method: %d.", type));
578 if (index.size()==0) {
579 BCLog::OutError(
"BCIntegrate::Marginalize : No marginalization parameters chosen.");
584 BCLog::OutError(
"BCIntegrate::Marginalize : Too many marginalization parameters.");
588 if ((
int)index.size()<hist->GetDimension()) {
589 BCLog::OutError(TString::Format(
"BCIntegrate::Marginalize : Too few (%d) indices supplied for histogram dimension (%d)",(
int)index.size(),hist->GetDimension()));
593 for (
unsigned i=0; i<index.size(); i++) {
596 BCLog::OutError(TString::Format(
"BCIntegrate::Marginalize : Parameter index (%d) out of bound.",index[i]));
600 for (
unsigned j=0; j<index.size(); j++)
601 if (i!=j and index[i]==index[j]) {
602 BCLog::OutError(TString::Format(
"BCIntegrate::Marginalize : Parameter index (%d) appears more than once",index[i]));
610 TH1D* BCIntegrate::Marginalize(BCIntegrationMethod type,
unsigned index)
617 TH1D * hist =
new TH1D(TString::Format(
"h1_%s", par->
GetName().data()),
618 TString::Format(
";%s;(unit %s)^{-1};", par->
GetName().data(), par->
GetName().data()),
622 std::vector<unsigned> indices(1, index);
623 Marginalize(hist, type, indices);
629 TH2D* BCIntegrate::Marginalize(BCIntegrationMethod type,
unsigned index1,
unsigned index2)
637 TH2D * hist =
new TH2D(TString::Format(
"h2_%s_%s", par1->
GetName().data(), par2->
GetName().data()),
638 TString::Format(
";%s;%s;(unit %s)^{-1}(unit %s)^{-1}",
645 std::vector<unsigned> indices;
646 indices.push_back(index1);
647 indices.push_back(index2);
648 Marginalize(hist,type,indices);
654 bool BCIntegrate::Marginalize(TH1* hist, BCIntegrationMethod type,
const std::vector<unsigned> &index)
666 if (type==
kIntCuba and hist->GetDimension()>1) {
667 BCLog::OutError(
"BCIntegrate::Marginalize : Cuba integration currently only functions for 1D marginalization.");
672 char * parnames =
new char;
673 for (
unsigned i=0; i<index.size(); i++) {
674 parnames = Form(
"%s %d (%s),",parnames,index[i],
fParameters[i]->GetName().data());
683 std::vector<double> origMins, origMaxs;
684 std::vector<bool> origFix;
685 for (
unsigned i=0; i<index.size(); i++) {
689 origFix.push_back(par->
Fixed());
699 if ( ! title.empty())
701 hist -> SetTitle((
"Fixed: "+title).data());
705 int N = hist->GetNbinsX() * hist->GetNbinsY() * hist->GetNbinsZ();
715 for (
int i=1; i<=hist->GetNbinsX(); i++) {
716 fParameters[index[0]]->SetLowerLimit(hist->GetXaxis()->GetBinLowEdge(i));
717 fParameters[index[0]]->SetUpperLimit(hist->GetXaxis()->GetBinLowEdge(i+1));
718 double binwidth1d = hist -> GetXaxis() -> GetBinWidth(i);
719 if (hist->GetDimension()>1)
720 for (
int j=1; j<=hist->GetNbinsY(); j++) {
721 fParameters[index[1]]->SetLowerLimit(hist -> GetYaxis() -> GetBinLowEdge(j));
722 fParameters[index[1]]->SetUpperLimit(hist -> GetYaxis() -> GetBinLowEdge(j+1));
723 double binwidth2d = binwidth1d * hist->GetYaxis()->GetBinWidth(j);
724 if (hist->GetDimension()>2)
725 for (
int k=1; k<=hist->GetNbinsZ(); k++) {
726 fParameters[index[2]]->SetLowerLimit(hist -> GetZaxis() -> GetBinLowEdge(k));
727 fParameters[index[2]]->SetUpperLimit(hist -> GetZaxis() -> GetBinLowEdge(k+1));
728 double binwidth3d = binwidth2d * hist->GetZaxis()->GetBinWidth(k);
729 hist -> SetBinContent(i, j, k,
Integrate(type)/binwidth3d);
730 hist -> SetBinError (i, j, k,
GetError()/binwidth3d);
733 hist -> SetBinContent(i, j,
Integrate(type)/binwidth2d);
734 hist -> SetBinError (i, j,
GetError()/binwidth2d);
738 hist -> SetBinContent(i,
Integrate(type)/binwidth1d);
739 hist -> SetBinError (i,
GetError()/binwidth1d);
744 for (
unsigned i=0; i<index.size(); i++) {
762 BCLog::OutError(
"BCIntegrate::MarginalizeAll : No parameters defined. Aborting.");
782 BCLog::OutWarning(
"BCIntegrate::MarginalizeAll : No marginalization method chosen.");
802 for (
unsigned int i = 0; i < npar; ++i) {
808 for (
unsigned int i = 0; i < npar; ++i) {
809 for (
unsigned int j = 0; j < npar; ++j) {
851 double probmax = -std::numeric_limits<double>::infinity();
852 std::vector<double> bestfit_parameters(
fParameters.
Size(), -std::numeric_limits<double>::infinity());
857 bestfit_parameters[i] =
fParameters[i]->GetFixedValue();
868 const int index = hist_temp->
GetHistogram()->GetMaximumBin();
869 probmax = hist_temp->
GetHistogram()->GetBinContent(index);
870 bestfit_parameters.at(i) = hist_temp->
GetHistogram()->GetBinCenter(index);
892 BCH2D* hist2d_temp = 0;
905 int index1, index2, useless_index;
906 hist2d_temp->
GetHistogram()->GetMaximumBin(index1, index2, useless_index);
907 probmax = hist2d_temp->
GetHistogram()->GetBinContent(index1, index2, useless_index);
908 bestfit_parameters.at(i) = hist2d_temp->
GetHistogram()->GetXaxis()->GetBinCenter(index1);
909 bestfit_parameters.at(j) = hist2d_temp->
GetHistogram()->GetYaxis()->GetBinCenter(index2);
941 BCLog::OutWarning(
"BCIntegrate::MarginalizeAll : Option works for 1D and 2D problems.");
959 BCLog::OutDetail(TString::Format(
" --> parameter %*i: %.4g", ndigits+1, i, bestfit_parameters[i]));
1027 if (parameter->
Fixed())
1031 std::vector<double> parameters_temp;
1032 parameters_temp = parameters;
1036 parameters_temp.push_back(0);
1049 hist->UseCurrentStyle();
1054 hist->SetYTitle(Form(
"p(%s|data)", parameter->
GetLatexName().data()));
1056 hist->SetYTitle(Form(
"p(%s|data, all other parameters fixed)", parameter->
GetLatexName().data()));
1057 hist->SetStats(kFALSE);
1060 for (
int i = 1; i <= nbins; ++i) {
1061 double par_temp = hist->GetBinCenter(i);
1063 double prob =
Eval(parameters_temp);
1064 hist->SetBinContent(i, prob);
1069 hist->Scale(1.0/hist->Integral());
1081 return GetSlice(parameter1->
GetName().c_str(), parameter2->
GetName().c_str(), parameters, nbins, flag_norm);
1104 std::vector<double> parameters_temp;
1105 parameters_temp = parameters;
1109 BCLog::OutError(
"BCIntegrate::GetSlice : Number of parameters need to be at least 2.");
1114 parameters_temp.push_back(0);
1115 parameters_temp.push_back(0);
1125 unsigned nbins1, nbins2;
1130 nbins1 = nbins2 = nbins;
1136 hist->UseCurrentStyle();
1139 hist->SetXTitle(Form(
"%s", p1->
GetLatexName().data()));
1140 hist->SetYTitle(Form(
"%s", p2->
GetLatexName().data()));
1141 hist->SetStats(kFALSE);
1144 for (
unsigned int ix = 1; ix <= nbins1; ++ix) {
1145 for (
unsigned int iy = 1; iy <= nbins2; ++iy) {
1146 double par_temp1 = hist->GetXaxis()->GetBinCenter(ix);
1147 double par_temp2 = hist->GetYaxis()->GetBinCenter(iy);
1149 parameters_temp[index1] = par_temp1;
1150 parameters_temp[index2] = par_temp2;
1152 double prob =
Eval(parameters_temp);
1153 hist->SetBinContent(ix, iy, prob);
1158 double norm = hist->Integral(
"width");
1162 hist->Scale(1.0/norm);
1169 hist->Scale(norm / hist->Integral(
"width"));
1183 fRandom->RndmArray(x.size(), &x.front());
1236 TFile * froot = TFile::Open(file);
1237 if (!froot->IsOpen()) {
1238 BCLog::OutError(Form(
"BCIntegrate::ReadMarginalizedFromFile : Couldn't open file %s.", file));
1252 for (
int i = 0; i < n; i++) {
1254 TKey * key = froot->GetKey(TString::Format(
"hist_%i_%s",
fID, a->
GetName().data()));
1256 TH1D * h1 = (TH1D*) key->ReadObjectAny(TH1D::Class());
1257 h1->SetDirectory(0);
1263 Form(
"BCIntegrate::ReadMarginalizedFromFile : Couldn't read histogram \"hist_%i_%s\" from file %s.",
1267 for (
int i = 0; i < n - 1; i++) {
1268 for (
int j = i + 1; j < n; j++) {
1271 TKey * key = froot->GetKey(
1274 TH2D * h2 = (TH2D*) key->ReadObjectAny(TH2D::Class());
1275 h2->SetDirectory(0);
1281 Form(
"BCIntegrate::ReadMarginalizedFromFile : Couldn't read histogram \"hist_%i_%s_%s\" from file %s.",
1296 BCLog::OutError(
"BCIntegrate::PrintAllMarginalized : Marginalized distributions not available.");
1301 for (
int i = 0; i < n; i++) {
1314 BCLog::OutError(
"BCIntegrate::PrintAllMarginalized : Marginalized distributions not available.");
1320 for (
int i = 0; i < n - 1; i++) {
1321 for (
int j = i + 1; j < n; j++) {
1327 if (deltaa <= 1e-7 * meana)
1332 if (deltab <= 1e-7 * meanb)
1337 Form(
"%s_2D_%s_%s.pdf",filebase, a->
GetName().data(), b->
GetName().data()));
1349 BCLog::OutError(
"BCIntegrate::PrintAllMarginalized : Marginalized distributions not available.");
1359 if (h->GetHistogram())
1365 if (h->GetHistogram())
1369 std::string filename(file);
1372 if ( (filename.find_last_of(
".") == std::string::npos) or
1373 ((filename.substr(filename.find_last_of(
".")+1) !=
"pdf") and
1374 (filename.substr(filename.find_last_of(
".")+1) !=
"ps"))) {
1379 int c_width = gStyle->GetCanvasDefW();
1380 int c_height = gStyle->GetCanvasDefH();
1392 else if (hdiv < vdiv) {
1403 const unsigned nplots = nvalid1D + nvalid2D;
1406 BCLog::OutSummary(Form(
"Printing all marginalized distributions (%d x 1D + %d x 2D = %d) into file %s",
1407 nvalid1D, nvalid2D, nplots, filename.c_str()));
1412 TCanvas c(
"c",
"canvas", c_width, c_height);
1413 c.Divide(hdiv, vdiv);
1416 std::vector<BCH1D *> h1;
1429 if (n != 0 && n % (hdiv * vdiv) == 0) {
1430 if ( n <= (hdiv * vdiv)) {
1431 c.Print(std::string( filename +
"(").c_str());
1434 c.Print(filename.c_str());
1439 c.cd(n % (hdiv * vdiv) + 1);
1448 std::vector<BCH2D *> h2;
1464 if ((k != 0 && k % (hdiv * vdiv) == 0) || k == 0) {
1465 c.Print(filename.c_str());
1469 c.cd(k % (hdiv * vdiv) + 1);
1479 h2.back()->Draw(options2d);
1482 if ((n + k) % 100 == 0)
1487 if ((n + k) > 100 && (n + k) % 100 != 0)
1490 c.Print(std::string( filename +
")").c_str());
1499 if ( !par1 or !par2 or (par1 == par2) )
1509 if (index1 > index2) {
1510 unsigned indexTemp = index1;
1546 return std::vector<double>();
1565 return std::vector<double>();
1576 int printlevel = -1;
1602 return std::vector<double>();
1606 double fcnatmode_temp =
Eval(mode_temp);
1614 BCLog::OutError(
"BCIntegrate::FindMode : previous mode has a different number of parameters than current.");
1619 BCLog::OutError(
"BCIntegrate::FindMode : previous error estimate has a different number of parameters than current.");
1648 std::vector<double> mode =
FindMode(start);
1670 BCLog::OutError(
"BCIntegrate::FindModeMinuit : No parameters defined. Aborting.");
1671 return std::vector<double>();
1674 bool have_start =
true;
1677 if (start.size() == 0)
1681 BCLog::OutWarning(
"BCIntegrate::FindModeMinuit : Start point not valid (mismatch of dimensions), set to center.");
1693 BCLog::OutWarning(
"BCIntegrate::FindModeMinuit : Start point not valid (parameter not inside valid range), set to center.");
1697 ::BCIntegrateHolder::instance(
this);
1705 fMinuit->SetPrintLevel(printlevel);
1718 starting_point = start[i];
1748 fMinuit->GetParameter(i, mode[i], errors[i]);
1763 fTreeSA =
new TTree(
"SATree",
"SATree");
1773 fTreeSA->Branch(TString::Format(
"Parameter%i", i), &
fSAx[i], TString::Format(
"parameter %i/D", i));
1782 bool have_start =
true;
1783 std::vector<double> x, y;
1784 double fval_x, fval_y, fval_mode;
1788 if (start.size() == 0)
1792 BCLog::OutWarning(
"BCIntegrate::FindModeSA : Start point not valid (mismatch of dimensions), set to center.");
1804 BCLog::OutWarning(
"BCIntegrate::FindModeSA : Start point not valid (parameter not inside valid range), set to center.");
1808 if ( !have_start ) {
1822 fval_x = fval_mode =
LogEval(x);
1831 bool in_range =
true;
1843 if (fval_y >= fval_x) {
1848 if (fval_y > fval_mode) {
1897 return fSAT0 / log((
double)(t + 1));
1903 return fSAT0 / (double)t;
1909 BCLog::OutError(
"BCIntegrate::SATemperatureCustom : No custom temperature schedule defined");
1928 std::vector<double> y;
1930 double new_val, norm;
1938 new_val = x[i] + norm *
fRandom->Gaus();
1939 y.push_back(new_val);
1949 std::vector<double> y;
1953 double cauchy, new_val, norm;
1960 cauchy = tan(3.14159 * (
fRandom->Rndm() - 0.5));
1961 new_val = x[0] + norm * cauchy;
1962 y.push_back(new_val);
1982 y[i] =
fParameters[i]->GetRangeWidth() * y[i] * radial / 2. + x[i];
1993 BCLog::OutError(
"BCIntegrate::GetProposalPointSACustom : No custom proposal function defined");
2011 x1 =
fRandom->Rndm() * 2. - 1.;
2012 x2 =
fRandom->Rndm() * 2. - 1.;
2017 rand_point[0] = (x1*x1 - x2*x2) / s;
2018 rand_point[1] = (2.*x1*x2) / s;
2021 fRandom->Sphere(rand_point[0], rand_point[1], rand_point[2], 1.0);
2029 rand_point[i] = gauss_num;
2030 s += gauss_num * gauss_num;
2035 rand_point[i] = rand_point[i] / s;
2051 static double map_u[10001];
2052 static double map_theta[10001];
2053 static bool initialized =
false;
2054 static unsigned map_dimension = 0;
2061 for (
int i = 0; i <= 10000; i++) {
2062 init_theta = 3.14159265 * (double)i / 5000.;
2063 map_theta[i] = init_theta;
2082 mid = ((up - lo + 1) / 2) + lo;
2084 if (u >= map_u[mid])
2092 theta = map_theta[lo] + (u - map_u[lo]) / (map_u[up] - map_u[lo]) * (map_theta[up] - map_theta[lo]);
2103 return (1. - cos(theta));
2105 return 0.5 * (theta - sin(theta) * cos(theta));
2107 return (2. - sin(theta) * sin(theta) * cos(theta) - 2. * cos(theta)) / 3.;
2109 return - pow(sin(theta), (
double)(dim - 1)) * cos(theta) / (double)dim
2110 + (
double)(dim - 1) / (
double)dim
2118 static std::vector<double> parameters;
2123 int nparameters = ::BCIntegrateHolder::instance()->GetNParameters();
2126 parameters.resize(nparameters, 0.0);
2129 std::copy(par, par + nparameters, parameters.begin());
2132 fval = - ::BCIntegrateHolder::instance()->LogEval(parameters);
2142 double logProb = -std::numeric_limits<double>::max();
2161 BCLog::OutError(Form(
"BCIntegrate::SetIntegrationMethod: Invalid method '%d' ", method));
2166 BCLog::OutError(
"BCIntegrate::SetIntegrationMethod: Cuba not enabled during configure");
2184 BCLog::OutError(TString::Format(
"Integration method of type %d is not defined for Cuba",type));
2189 BCLog::OutError(
"SetCubaIntegrationMethod: Cuba not enabled during configure");
2195 const int * ,
double ff[],
void * userdata)
2200 double jacobian = 1.0;
2204 std::vector<double> scaled_parameters(local_this->
fParameters.
Size());
2208 unsigned cubaIndex = 0;
2209 unsigned batIndex = 0;
2210 for (batIndex = 0; batIndex < local_this->
fParameters.
Size(); ++batIndex) {
2228 if (cubaIndex !=
unsigned(*ndim))
2229 BCLog::OutError(Form(
"BCIntegrate::CubaIntegrand: mismatch between variable parameters"
2230 "in BAT (%d) and Cuba(%d)", batIndex, cubaIndex));
2233 ff[0] = local_this->
Eval(scaled_parameters);
2247 static const int ncomp = 1;
2250 static const int gridno = -1;
2253 static const char * statefile =
"";
2258 std::vector<double> integral(ncomp, -1);
2259 std::vector<double> error(ncomp, -1);
2260 std::vector<double> prob(ncomp, -1);
2271 Vegas(nIntegrationVariables, ncomp,
2279 &integral[0], &error[0], &prob[0]);
2283 Suave(nIntegrationVariables, ncomp,
2291 &integral[0], &error[0], &prob[0]);
2295 if (nIntegrationVariables < 2 or nIntegrationVariables > 33)
2296 BCLog::OutError(
"BCIntegrate::IntegrateCuba(Divonne): Divonne only works in 1 < d < 34");
2299 static const int ngiven = 0;
2300 static const int nextra = ngiven;
2301 Divonne(nIntegrationVariables, ncomp,
2309 ngiven, nIntegrationVariables , NULL, nextra, NULL,
2312 &integral[0], &error[0], &prob[0]);
2317 if (nIntegrationVariables < 2)
2318 BCLog::OutError(
"BCIntegrate::IntegrateCuba(Cuhre): Cuhre(cubature) only works in d > 1");
2320 Cuhre(nIntegrationVariables, ncomp,
2326 &nregions, &fNIterations, &fail,
2327 &integral[0], &error[0], &prob[0]);
2339 double result = integral[0];
2342 BCLog::OutWarning(
" Warning, integral did not converge with the given set of parameters. ");
2373 double integral = -1;
2374 double absprecision = -1;
2375 double relprecision = -1;
2394 integral = hist_temp->
GetHistogram()->Integral(
"width");
2411 integral = hist_temp->
GetHistogram()->Integral(
"width");
2420 BCLog::OutWarning(
"BCIntegrate::IntegrateSlice: Method only implemented for 1D and 2D problems. Return -1.");
2445 return "Sample Mean Monte Carlo";
2462 return "Sample Mean Monte Carlo";
2464 return "Metropolis";
2481 return "Simulated Annealing";
2483 return "Metropolis MCMC";
2510 namespace BCCubaOptions