12 #include "BCIntegrate.h"
15 #include "BCParameter.h"
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),
104 fMinuitArglist[0] = 20000;
105 fMinuitArglist[1] = 0.01;
127 fBestFitParameters = other.fBestFitParameters;
128 fBestFitParameterErrors = other.fBestFitParameterErrors;
129 fLogMaximum = other.fLogMaximum;
130 fMinuit =
new TMinuit();
131 fMinuitArglist[0] = other.fMinuitArglist[0];
132 fMinuitArglist[1] = other.fMinuitArglist[1];
133 fMinuitErrorFlag = other.fMinuitErrorFlag;
134 fFlagIgnorePrevOptimization = other.fFlagIgnorePrevOptimization;
136 fSATmin = other.fSATmin;
138 fFlagWriteSAToFile = other.fFlagWriteSAToFile;
139 fSANIterations = other.fSANIterations;
140 fSATemperature = other.fSATemperature;
141 fSALogProb = other.fSALogProb;
143 fMarginalized1D = other.fMarginalized1D;
144 fMarginalized2D = other.fMarginalized2D;
145 fOptimizationMethodCurrent= other.fOptimizationMethodCurrent;
146 fOptimizationMethodUsed = other.fOptimizationMethodUsed;
147 fIntegrationMethodCurrent = other.fIntegrationMethodCurrent;
148 fIntegrationMethodUsed = other.fIntegrationMethodUsed;
149 fMarginalizationMethodCurrent = other.fMarginalizationMethodCurrent;
150 fMarginalizationMethodUsed= other.fMarginalizationMethodUsed;
151 fSASchedule = other.fSASchedule;
152 fNIterationsMin = other.fNIterationsMin;
153 fNIterationsMax = other.fNIterationsMax;
154 fNIterationsPrecisionCheck= other.fNIterationsPrecisionCheck;
155 fNIterationsOutput = other.fNIterationsOutput;
156 fNIterations = other.fNIterations;
157 fIntegral = other.fIntegral;
158 fRelativePrecision = other.fRelativePrecision;
159 fAbsolutePrecision = other.fAbsolutePrecision;
160 fError = other.fError;
161 fCubaIntegrationMethod = other.fCubaIntegrationMethod;
162 fCubaVegasOptions = other.fCubaVegasOptions;
163 fCubaSuaveOptions = other.fCubaSuaveOptions;
164 fCubaDivonneOptions = other.fCubaDivonneOptions;
165 fCubaCuhreOptions = other.fCubaCuhreOptions;
166 fFlagMarginalized = other.fFlagMarginalized;
170 BCIntegrate::~BCIntegrate()
176 double BCIntegrate::GetBestFitParameter(
unsigned index)
const
178 if( ! fParameters.ValidIndex(index))
181 if(fBestFitParameters.empty()) {
182 BCLog::OutError(
"BCIntegrate::GetBestFitParameter : Mode finding not yet run, returning center of the range.");
183 return (fParameters[index]->GetUpperLimit() + fParameters[index]->GetLowerLimit() ) / 2.;
186 return fBestFitParameters[index];
190 double BCIntegrate::GetBestFitParameterError(
unsigned index)
const
192 if( ! fParameters.ValidIndex(index)) {
193 BCLog::OutError(
"BCIntegrate::GetBestFitParameterError : Parameter index out of range, returning -1.");
207 return fBestFitParameterErrors[index];
211 double BCIntegrate::Eval(
const std::vector<double> & )
213 BCLog::OutWarning(
"BCIntegrate::Eval. No function. Function needs to be overloaded.");
218 double BCIntegrate::LogEval(
const std::vector<double> &x)
225 void BCIntegrate::ResetResults()
229 fBestFitParameterErrors.clear();
230 fBestFitParameters.clear();
231 fLogMaximum = -std::numeric_limits<double>::max();
235 fFlagMarginalized =
false;
239 unsigned BCIntegrate::GetNIntegrationVariables() {
241 for(
unsigned i = 0; i < fParameters.Size(); ++i)
242 if ( ! fParameters[i]->Fixed())
248 double BCIntegrate::CalculateIntegrationVolume() {
249 double integrationVolume = -1.;
251 for(
unsigned i = 0; i < fParameters.Size(); i++)
252 if ( ! fParameters[i]->Fixed()) {
253 if (integrationVolume<0)
254 integrationVolume = 1;
255 integrationVolume *= fParameters[i]->GetRangeWidth();
258 if (integrationVolume<0)
259 integrationVolume = 0;
261 return integrationVolume;
265 double BCIntegrate::Integrate()
268 if (fParameters.Size() < 1) {
269 BCLog::OutError(
"BCIntegrate::Integrate : No parameters defined. Aborting.");
274 if (!(fIntegrationMethodCurrent == BCIntegrate::kIntDefault) && !(fIntegrationMethodCurrent == BCIntegrate::kIntEmpty))
275 BCLog::OutSummary(Form(
"Integrate using %s", DumpCurrentIntegrationMethod().c_str()));
277 switch(fIntegrationMethodCurrent)
281 case BCIntegrate::kIntEmpty:
283 BCLog::OutWarning(
"BCIntegrate::Integrate : No integration method chosen.");
289 case BCIntegrate::kIntMonteCarlo:
291 std::vector<double> sums (2,0.0);
292 sums.push_back(CalculateIntegrationVolume());
293 fIntegral = Integrate(kIntMonteCarlo,
294 &BCIntegrate::GetRandomVectorInParameterSpace,
295 &BCIntegrate::EvaluatorMC,
300 fIntegrationMethodUsed = BCIntegrate::kIntMonteCarlo;
307 case BCIntegrate::kIntCuba:
309 fIntegral = IntegrateCuba();
312 fIntegrationMethodUsed = BCIntegrate::kIntCuba;
319 case BCIntegrate::kIntGrid:
321 fIntegral = IntegrateSlice();
324 fIntegrationMethodUsed = BCIntegrate::kIntGrid;
331 case BCIntegrate::kIntDefault:
333 if (GetNFreeParameters() <= 2)
334 SetIntegrationMethod(BCIntegrate::kIntGrid);
337 SetIntegrationMethod(BCIntegrate::kIntCuba);
339 SetIntegrationMethod(BCIntegrate::kIntMonteCarlo);
345 BCLog::OutError(TString::Format(
"BCIntegrate::Integrate : Invalid integration method: %d", fIntegrationMethodCurrent));
353 double BCIntegrate::Integrate(BCIntegrationMethod intmethod)
356 BCIntegrationMethod method_temp = fIntegrationMethodCurrent;
359 SetIntegrationMethod(intmethod);
362 double integral = Integrate();
365 SetIntegrationMethod(method_temp);
373 void BCIntegrate::SetBestFitParameters(
const std::vector<double> &x,
const double &new_value,
double &old_value) {
374 if (new_value < old_value)
376 old_value = new_value;
377 SetBestFitParameters(x);
381 unsigned BCIntegrate::IntegrationOutputFrequency()
const
383 if (fNIterationsOutput > 0)
384 return fNIterationsOutput;
385 const unsigned nwrite = fNIterationsMax / 10;
396 void BCIntegrate::LogOutputAtStartOfIntegration(BCIntegrationMethod type, BCCubaMethod cubatype)
398 const unsigned NVarNow = GetNIntegrationVariables();
402 if(fParameters.Size() != NVarNow) {
404 level = BCLog::detail;
405 bool printed =
false;
409 BCLog::OutDetail(TString::Format(
"Running %s (%s) integration over %i dimensions out of %i.",
410 DumpIntegrationMethod(type).c_str(),
411 DumpCubaIntegrationMethod(cubatype).c_str(),
412 NVarNow, fParameters.Size()));
417 BCLog::OutDetail(TString::Format(
"Running %s integration over %i dimensions out of %i.",
418 DumpIntegrationMethod(type).c_str(),
419 NVarNow, fParameters.Size()));
421 BCLog::OutDetail(
" --> Fixed parameters:");
422 for(
unsigned i = 0; i < fParameters.Size(); i++)
423 if(fParameters[i]->Fixed())
424 BCLog::OutDetail(TString::Format(
" %3i : %g", i, fParameters[i]->GetFixedValue()));
427 bool printed =
false;
429 if (type==kIntCuba) {
430 BCLog::OutDetail(TString::Format(
"Running %s (%s) integration over %i dimensions.",
431 DumpIntegrationMethod(type).c_str(),
432 DumpCubaIntegrationMethod(cubatype).c_str(),
438 BCLog::OutDetail(TString::Format(
"Running %s integration over %i dimensions.",
439 DumpIntegrationMethod(type).c_str(),
443 if (GetNIterationsMin() > 0 && GetNIterationsMax() > 0 ) {
444 BCLog::Out(level, TString::Format(
" --> Minimum number of iterations: %i", GetNIterationsMin()));
445 BCLog::Out(level, TString::Format(
" --> Maximum number of iterations: %i", GetNIterationsMax()));
447 BCLog::Out(level, TString::Format(
" --> Target relative precision: %e", GetRelativePrecision()));
448 BCLog::Out(level, TString::Format(
" --> Target absolute precision: %e", GetAbsolutePrecision()));
452 void BCIntegrate::LogOutputAtEndOfIntegration(
double integral,
double absprecision,
double relprecision,
int nIterations)
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));
461 void BCIntegrate::LogOutputAtIntegrationStatusUpdate(BCIntegrationMethod type,
double integral,
double absprecision,
int nIterations)
463 BCLog::OutDetail(TString::Format(
"%s. Iteration %i, integral: %e +- %e.", DumpIntegrationMethod(type).c_str(), nIterations, integral, absprecision));
467 double BCIntegrate::Integrate(BCIntegrationMethod type, tRandomizer randomizer, tEvaluator evaluator, tIntegralUpdater updater,
468 std::vector<double> &sums)
470 LogOutputAtStartOfIntegration(type, NCubaMethods);
474 double integral = 0.;
475 double absprecision = 2.*fAbsolutePrecision;
476 double relprecision = 2.*fRelativePrecision;
478 std::vector<double> randx (fParameters.Size(), 0.);
481 int nwrite = IntegrationOutputFrequency();
489 while ((GetRelativePrecision() < relprecision and GetAbsolutePrecision() < absprecision and GetNIterations() < GetNIterationsMax())
490 or GetNIterations() < GetNIterationsMin())
494 (this->*randomizer)(randx);
499 SetBestFitParameters(randx, (this->*evaluator)(sums,randx,accepted), pmax);
506 if (fNIterations % fNIterationsPrecisionCheck == 0) {
507 (*updater)(sums, fNIterations, integral, absprecision);
508 relprecision = absprecision / integral;
512 if (fNIterations % nwrite == 0) {
513 double temp_integral;
514 double temp_absprecision;
515 (*updater)(sums, fNIterations, temp_integral, temp_absprecision);
516 LogOutputAtIntegrationStatusUpdate(type, temp_integral, temp_absprecision, fNIterations);
521 (*updater)(sums, fNIterations, integral, absprecision);
522 relprecision = absprecision / integral;
524 if (
unsigned(fNIterations) >= fMCMCNIterationsMax)
525 BCLog::OutWarning(
"BCIntegrate::Integrate: Did not converge within maximum number of iterations");
528 LogOutputAtEndOfIntegration(integral, absprecision, relprecision, fNIterations);
530 fError = absprecision;
535 double BCIntegrate::EvaluatorMC(std::vector<double> &sums,
const std::vector<double> &point,
bool &accepted) {
536 const double value = Eval(point);
543 sums[1] += value * value;
549 void BCIntegrate::IntegralUpdaterMC(
const std::vector<double> &sums,
const int &nIterations,
double &integral,
double &absprecision) {
551 integral = sums[2] * sums[0] / nIterations;
554 absprecision = sqrt((1.0 / (nIterations - 1)) * (sums[2] * sums[2] * sums[1] /
double(nIterations) - integral * integral));
558 bool BCIntegrate::CheckMarginalizationAvailability(BCMarginalizationMethod type) {
561 case BCIntegrate::kMargMonteCarlo:
563 case BCIntegrate::kMargMetropolis:
565 case BCIntegrate::kMargGrid:
567 case BCIntegrate::kMargDefault:
570 BCLog::OutError(TString::Format(
"BCIntegrate::CheckMarginalizationAvailability. Invalid marginalization method: %d.", type));
577 bool BCIntegrate::CheckMarginalizationIndices(TH1* hist,
const std::vector<unsigned> &index) {
578 if (index.size()==0) {
579 BCLog::OutError(
"BCIntegrate::Marginalize : No marginalization parameters chosen.");
583 if (index.size() >= 4 or index.size() > fParameters.Size()) {
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++) {
595 if ( ! fParameters.ValidIndex(index[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)
661 if (!CheckMarginalizationIndices(hist,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());
677 BCLog::OutDebug(TString::Format(
" --> Marginalizing model w/r/t parameter%s using %s.",parnames, DumpCurrentMarginalizationMethod().c_str()));
679 BCLog::OutDebug(TString::Format(
" --> Marginalizing model w/r/t parameters%s using %s.",parnames, DumpCurrentMarginalizationMethod().c_str()));
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());
695 for (
unsigned i=0; i < fParameters.Size(); ++i)
696 if (fParameters[i]->Fixed()) {
697 title += TString::Format(
" (%s=%e)", fParameters[i]->GetName().data(), fParameters[i]->GetFixedValue());
699 if ( ! title.empty())
701 hist -> SetTitle((
"Fixed: "+title).data());
705 int N = hist->GetNbinsX() * hist->GetNbinsY() * hist->GetNbinsZ();
708 int nIterationsMax = fNIterationsMax;
709 fNIterationsMax = fNIterationsMax / N;
710 if (fNIterationsMax<fNIterationsMin)
711 fNIterationsMax = fNIterationsMin;
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++) {
745 fParameters[index[i]]->SetLowerLimit(origMins[i]);
746 fParameters[index[i]]->SetUpperLimit(origMaxs[i]);
747 fParameters[index[i]]->Fix(origFix[i]);
751 fNIterationsMax = nIterationsMax;
758 int BCIntegrate::MarginalizeAll()
761 if (fParameters.Size() < 1) {
762 BCLog::OutError(
"BCIntegrate::MarginalizeAll : No parameters defined. Aborting.");
767 if (!CheckMarginalizationAvailability(GetMarginalizationMethod())) {
768 BCLog::OutError(Form(
"BCIntegrate::MarginalizeAll : Marginalization method not implemented \'%s\'. Aborting.", DumpCurrentMarginalizationMethod().c_str()));
773 if (!(fMarginalizationMethodCurrent == BCIntegrate::kMargDefault) && !(fMarginalizationMethodCurrent == BCIntegrate::kMargEmpty))
774 BCLog::OutSummary(Form(
"Marginalize using %s", DumpCurrentMarginalizationMethod().c_str()));
776 switch (GetMarginalizationMethod())
780 case BCIntegrate::kMargEmpty:
782 BCLog::OutWarning(
"BCIntegrate::MarginalizeAll : No marginalization method chosen.");
787 case BCIntegrate::kMargMetropolis:
790 MarginalizePreprocess();
796 MarginalizePostprocess();
799 unsigned int npar = GetNParameters();
801 fMarginalized1D.clear();
802 for (
unsigned int i = 0; i < npar; ++i) {
803 fMarginalized1D.push_back(MCMCGetH1Marginalized(i));
806 fMarginalized2D.clear();
808 for (
unsigned int i = 0; i < npar; ++i) {
809 for (
unsigned int j = 0; j < npar; ++j) {
811 fMarginalized2D.push_back(MCMCGetH2Marginalized(i, j));
817 fMarginalizationMethodUsed = BCIntegrate::kMargMetropolis;
820 if ( (!fFlagIgnorePrevOptimization) && (fLogMaximum < fMCMCLogMaximum) ) {
821 fBestFitParameters = fMCMCBestFitParameters;
822 fBestFitParameterErrors.assign(fParameters.Size(),-1.);
823 fLogMaximum = fMCMCLogMaximum;
824 fOptimizationMethodUsed = BCIntegrate::kOptMetropolis;
831 case BCIntegrate::kMargMonteCarlo:
837 case BCIntegrate::kMargGrid:
839 std::vector<double> fixpoint(GetNParameters());
840 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
841 if (fParameters[i]->Fixed())
842 fixpoint[i] = fParameters[i]->GetFixedValue();
848 MarginalizePreprocess();
851 double probmax = -std::numeric_limits<double>::infinity();
852 std::vector<double> bestfit_parameters(fParameters.Size(), -std::numeric_limits<double>::infinity());
855 for (
unsigned i = 0; i < fParameters.Size(); ++i)
856 if (fParameters[i]->Fixed())
857 bestfit_parameters[i] = fParameters[i]->GetFixedValue();
859 fMarginalized1D.clear();
860 if (GetNFreeParameters() == 1) {
861 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
862 if (!fParameters[i]->Fixed()) {
864 BCH1D* hist_temp = GetSlice(fParameters[i], fixpoint, 0);
865 fMarginalized1D.push_back(hist_temp);
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);
876 fMarginalized1D.push_back(0);
879 fMarginalized2D.clear();
880 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
881 for (
unsigned int j = 0; j < GetNParameters(); ++j) {
885 fMarginalized2D.push_back(0);
889 else if (GetNFreeParameters() == 2) {
892 BCH2D* hist2d_temp = 0;
894 fMarginalized2D.clear();
895 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
896 for (
unsigned int j = 0; j < GetNParameters(); ++j) {
899 if (!fParameters[i]->Fixed() && !fParameters[j]->Fixed()) {
901 hist2d_temp = GetSlice(GetParameter(i), GetParameter(j), fixpoint, 0);
902 fMarginalized2D.push_back(hist2d_temp);
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);
915 fMarginalized2D.push_back(0);
920 fMarginalized1D.clear();
921 for (
unsigned int i = 0; i < GetNParameters(); ++i)
922 fMarginalized1D.push_back(0);
923 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
924 for (
unsigned int j = 0; j < GetNParameters(); ++j) {
927 if (!fParameters[i]->Fixed() && !fParameters[j]->Fixed()) {
931 fMarginalized1D[i] = hist_x;
935 fMarginalized1D[j] = hist_y;
941 BCLog::OutWarning(
"BCIntegrate::MarginalizeAll : Option works for 1D and 2D problems.");
947 if (fBestFitParameters.empty() || probmax > fMCMCLogMaximum) {
948 fLogMaximum = probmax;
949 fBestFitParameters = bestfit_parameters;
950 fBestFitParameterErrors.assign(fBestFitParameters.size(), std::numeric_limits<double>::infinity());
955 BCLog::OutDetail(
" --> Global mode from Grid:");
956 BCLog::OutDebug(Form(
" --> Posterior value: %g", probmax));
957 int ndigits = (int) log10(fParameters.Size());
958 for (
unsigned i = 0; i < fParameters.Size(); ++i)
959 BCLog::OutDetail(TString::Format(
" --> parameter %*i: %.4g", ndigits+1, i, bestfit_parameters[i]));
962 MarginalizePostprocess();
965 fMarginalizationMethodUsed = BCIntegrate::kMargGrid;
971 case BCIntegrate::kMargDefault:
973 if ( GetNFreeParameters() <= 2 ) {
974 SetMarginalizationMethod(BCIntegrate::kMargGrid);
977 SetMarginalizationMethod(BCIntegrate::kMargMetropolis);
981 return MarginalizeAll();
987 BCLog::OutError(TString::Format(
"BCIntegrate::MarginalizeAll : Invalid marginalization method: %d", GetMarginalizationMethod()));
993 fFlagMarginalized =
true;
999 int BCIntegrate::MarginalizeAll(BCIntegrate::BCMarginalizationMethod margmethod)
1002 BCMarginalizationMethod method_temp = fMarginalizationMethodCurrent;
1005 SetMarginalizationMethod(margmethod);
1008 int result = MarginalizeAll();
1011 SetMarginalizationMethod(method_temp);
1018 BCH1D * BCIntegrate::GetSlice(
const BCParameter* parameter,
const std::vector<double> parameters,
int nbins,
bool flag_norm)
1022 BCLog::OutError(
"BCIntegrate::GetSlice : Parameter does not exist.");
1027 if (parameter->Fixed())
1031 std::vector<double> parameters_temp;
1032 parameters_temp = parameters;
1035 if (parameters_temp.empty() && GetNParameters() == 1) {
1036 parameters_temp.push_back(0);
1038 else if (parameters_temp.empty() && GetNParameters() != 1) {
1039 BCLog::OutError(
"BCIntegrate::GetSlice : No parameters defined.");
1045 nbins = parameter->GetNbins();
1049 hist->UseCurrentStyle();
1053 if (GetNParameters() == 1)
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);
1062 parameters_temp[fParameters.Index(parameter->
GetName())] = par_temp;
1063 double prob = Eval(parameters_temp);
1064 hist->SetBinContent(i, prob);
1069 hist->Scale(1.0/hist->Integral());
1079 BCH2D* BCIntegrate::GetSlice(
const BCParameter* parameter1,
const BCParameter* parameter2,
const std::vector<double> parameters,
int nbins,
bool flag_norm)
1081 return GetSlice(parameter1->
GetName().c_str(), parameter2->
GetName().c_str(), parameters, nbins, flag_norm);
1085 BCH2D* BCIntegrate::GetSlice(
const char* name1,
const char* name2,
const std::vector<double> parameters,
int nbins,
bool flag_norm)
1087 return GetSlice(fParameters.Index(name1), fParameters.Index(name2), parameters, nbins, flag_norm);
1091 BCH2D* BCIntegrate::GetSlice(
unsigned index1,
unsigned index2,
const std::vector<double> parameters,
int nbins,
bool flag_norm)
1094 if (!fParameters.ValidIndex(index1) || !fParameters.ValidIndex(index2)) {
1095 BCLog::OutError(
"BCIntegrate::GetSlice : Parameter does not exist.");
1100 if (fParameters[index1]->Fixed() || fParameters[index2]->Fixed())
1104 std::vector<double> parameters_temp;
1105 parameters_temp = parameters;
1108 if (GetNParameters() < 2) {
1109 BCLog::OutError(
"BCIntegrate::GetSlice : Number of parameters need to be at least 2.");
1113 if (parameters_temp.size()==0 && GetNParameters()==2) {
1114 parameters_temp.push_back(0);
1115 parameters_temp.push_back(0);
1117 else if (parameters_temp.size()==0 && GetNParameters()>2) {
1118 BCLog::OutError(
"BCIntegrate::GetSlice : No parameters defined.");
1125 unsigned nbins1, nbins2;
1127 nbins1 = p1->GetNbins();
1128 nbins2 = p2->GetNbins();
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"));
1174 double BCIntegrate::GetRandomPoint(std::vector<double> &x)
1176 GetRandomVectorInParameterSpace(x);
1181 void BCIntegrate::GetRandomVectorUnitHypercube(std::vector<double> &x)
const
1183 fRandom->RndmArray(x.size(), &x.front());
1187 void BCIntegrate::GetRandomVectorInParameterSpace(std::vector<double> &x)
const
1189 GetRandomVectorUnitHypercube(x);
1191 for (
unsigned i = 0; i < fParameters.Size(); i++){
1192 if (fParameters[i]->Fixed())
1193 x[i] = fParameters[i]->GetFixedValue();
1195 x[i] = fParameters[i]->GetLowerLimit() + x[i] * fParameters[i]->GetRangeWidth();
1204 return GetMarginalized(fParameters.Index(parameter->
GetName()));
1208 BCH1D * BCIntegrate::GetMarginalized(
unsigned index)
1211 if (fMarginalized1D.size() <= index)
1215 BCH1D * htemp = fMarginalized1D.at(index);
1222 if (fBestFitParameters.size() == GetNParameters())
1226 htemp->
GetHistogram()->SetName(Form(
"hist_%i_%s", fID, fParameters[index]->GetName().data()));
1227 htemp->
GetHistogram()->SetYTitle(Form(
"p(%s|data)", fParameters[index]->GetLatexName().data()));
1234 int BCIntegrate::ReadMarginalizedFromFile(
const char * file)
1236 TFile * froot = TFile::Open(file);
1237 if (!froot->IsOpen()) {
1238 BCLog::OutError(Form(
"BCIntegrate::ReadMarginalizedFromFile : Couldn't open file %s.", file));
1251 int n = GetNParameters();
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);
1258 if (SetMarginalized(i, h1))
1263 Form(
"BCIntegrate::ReadMarginalizedFromFile : Couldn't read histogram \"hist_%i_%s\" from file %s.",
1264 fID, a->
GetName().data(), file));
1267 for (
int i = 0; i < n - 1; i++) {
1268 for (
int j = i + 1; j < n; j++) {
1271 TKey * key = froot->GetKey(
1272 TString::Format(
"hist_%i_%s_%s",fID, a->
GetName().data(),b->
GetName().data()));
1274 TH2D * h2 = (TH2D*) key->ReadObjectAny(TH2D::Class());
1275 h2->SetDirectory(0);
1276 if (SetMarginalized(i, j, h2))
1281 Form(
"BCIntegrate::ReadMarginalizedFromFile : Couldn't read histogram \"hist_%i_%s_%s\" from file %s.",
1293 int BCIntegrate::PrintAllMarginalized1D(
const char * filebase)
1295 if (fMCMCH1Marginalized.size() == 0) {
1296 BCLog::OutError(
"BCIntegrate::PrintAllMarginalized : Marginalized distributions not available.");
1300 int n = GetNParameters();
1301 for (
int i = 0; i < n; i++) {
1303 if (GetMarginalized(a))
1304 GetMarginalized(a)->Print(Form(
"%s_1D_%s.pdf", filebase, a->
GetName().data()));
1311 int BCIntegrate::PrintAllMarginalized2D(
const char * filebase)
1313 if (fMCMCH2Marginalized.size() == 0) {
1314 BCLog::OutError(
"BCIntegrate::PrintAllMarginalized : Marginalized distributions not available.");
1319 int n = GetNParameters();
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)
1335 if (GetMarginalized(a, b))
1336 GetMarginalized(a, b)->Print(
1337 Form(
"%s_2D_%s_%s.pdf",filebase, a->
GetName().data(), b->
GetName().data()));
1346 int BCIntegrate::PrintAllMarginalized(
const char * file, std::string options1d, std::string options2d,
unsigned int hdiv,
unsigned int vdiv)
1348 if (fMarginalized1D.size() == 0 and fMarginalized2D.size() == 0) {
1349 BCLog::OutError(
"BCIntegrate::PrintAllMarginalized : Marginalized distributions not available.");
1357 for (
unsigned i = 0 ; i < fMarginalized1D.size() ; ++i) {
1358 if (
BCH1D * h = fMarginalized1D[i])
1359 if (h->GetHistogram())
1363 for (
unsigned i = 0 ; i < fMarginalized2D.size() ; ++i) {
1364 if (
BCH2D * h = fMarginalized2D[i])
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()));
1409 BCLog::OutDetail(
"This can take a while...");
1412 TCanvas c(
"c",
"canvas", c_width, c_height);
1413 c.Divide(hdiv, vdiv);
1416 std::vector<BCH1D *> h1;
1422 c.Print(std::string( filename +
"[").c_str());
1424 for (
unsigned i = 0; i < fParameters.Size(); ++i) {
1425 BCH1D * h = GetMarginalized(i);
1433 if (n != 0 && n % (hdiv * vdiv) == 0) {
1434 c.Print(filename.c_str());
1439 c.cd(n % (hdiv * vdiv) + 1);
1444 BCLog::OutDetail(Form(
" --> %d plots done", n));
1449 c.Print(filename.c_str());
1454 std::vector<BCH2D *> h2;
1458 for (
unsigned i = 0; i < fParameters.Size() - 1; ++i) {
1459 for (
unsigned j = i + 1; j < fParameters.Size(); ++j) {
1461 h2.push_back(GetMarginalized(i, j));
1470 if ((k != 0 && k % (hdiv * vdiv) == 0)) {
1471 c.Print(filename.c_str());
1476 c.cd(k % (hdiv * vdiv) + 1);
1486 h2.back()->Draw(options2d);
1489 if ((n + k) % 100 == 0)
1490 BCLog::OutDetail(Form(
" --> %d plots done", n + k));
1495 c.Print(filename.c_str());
1498 if ((n + k) > 100 && (n + k) % 100 != 0)
1499 BCLog::OutDetail(Form(
" --> %d plots done", n + k));
1501 c.Print(std::string( filename +
"]").c_str());
1510 if ( !par1 or !par2 or (par1 == par2) )
1513 return GetMarginalized(fParameters.Index(par1->
GetName()), fParameters.Index(par2->
GetName()));
1517 BCH2D * BCIntegrate::GetMarginalized(
unsigned index1,
unsigned index2)
1520 if (index1 > index2) {
1521 unsigned indexTemp = index1;
1527 if (fMarginalized2D.size() <= GetNParameters() * index1 - (index1 * index1 + 3 * index1) / 2 + index2 - 1)
1531 BCH2D * htemp = fMarginalized2D.at(GetNParameters() * index1 - (index1 * index1 + 3 * index1) / 2 + index2 - 1);
1538 if (fBestFitParameters.size() == GetNParameters()) {
1539 double gmode[] = { fBestFitParameters.at(index1), fBestFitParameters.at(index2) };
1544 htemp->
GetHistogram()->SetName(Form(
"hist_%i_%s_%s", fID,
1545 fParameters[index1]->GetName().data(),
1546 fParameters[index2]->GetName().data()));
1553 std::vector<double> BCIntegrate::FindMode(std::vector<double> start)
1555 if (fParameters.Size() < 1) {
1556 BCLog::OutError(
"FindMode : No parameters defined. Aborting.");
1557 return std::vector<double>();
1560 if (start.empty() && fBestFitParameters.size() == fParameters.Size())
1561 start = fBestFitParameters;
1563 std::vector<double> mode_temp(GetNParameters());
1564 std::vector<double> errors_temp(GetNParameters());
1565 BCIntegrate::BCOptimizationMethod method_temp = fOptimizationMethodCurrent;
1568 if (!(fOptimizationMethodCurrent == BCIntegrate::kOptDefault) && !(fOptimizationMethodCurrent == BCIntegrate::kOptEmpty))
1569 BCLog::OutSummary(Form(
"Finding mode using %s", DumpCurrentOptimizationMethod().c_str()));
1571 switch (fOptimizationMethodCurrent)
1573 case BCIntegrate::kOptEmpty:
1575 BCLog::OutWarning(
"BCIntegrate::FindMode : No optimization method chosen.");
1576 return std::vector<double>();
1578 case BCIntegrate::kOptSimAnn:
1580 FindModeSA(mode_temp, errors_temp, start);
1585 case BCIntegrate::kOptMinuit:
1587 int printlevel = -1;
1593 BCIntegrate::FindModeMinuit(mode_temp, errors_temp, start, printlevel);
1598 case BCIntegrate::kOptMetropolis:
1600 FindModeMCMC(mode_temp, errors_temp);
1604 case BCIntegrate::kOptDefault:
1606 SetOptimizationMethod(BCIntegrate::kOptMinuit);
1608 return FindMode(start);
1612 BCLog::OutError(Form(
"BCIntegrate::FindMode : Invalid mode finding method: %d", GetOptimizationMethod()));
1613 return std::vector<double>();
1617 double fcnatmode_temp = Eval(mode_temp);
1620 if ( (!fFlagIgnorePrevOptimization) && (fcnatmode_temp < fLogMaximum) ) {
1622 if (mode_temp.size() == fBestFitParameters.size())
1623 mode_temp = fBestFitParameters;
1625 BCLog::OutError(
"BCIntegrate::FindMode : previous mode has a different number of parameters than current.");
1627 if (errors_temp.size() == fBestFitParameterErrors.size())
1628 errors_temp = fBestFitParameterErrors;
1630 BCLog::OutError(
"BCIntegrate::FindMode : previous error estimate has a different number of parameters than current.");
1632 fcnatmode_temp = fLogMaximum;
1633 method_temp = fOptimizationMethodUsed;
1637 fBestFitParameters = mode_temp;
1638 fBestFitParameterErrors = errors_temp;
1639 fLogMaximum = fcnatmode_temp;
1642 fOptimizationMethodUsed = method_temp;
1650 std::vector<double> BCIntegrate::FindMode(BCIntegrate::BCOptimizationMethod optmethod, std::vector<double> start)
1653 BCOptimizationMethod method_temp = fOptimizationMethodCurrent;
1656 SetOptimizationMethod(optmethod);
1659 std::vector<double> mode = FindMode(start);
1662 SetOptimizationMethod(method_temp);
1669 TMinuit * BCIntegrate::GetMinuit()
1672 fMinuit =
new TMinuit();
1678 std::vector<double> BCIntegrate::FindModeMinuit(std::vector<double> &mode, std::vector<double> &errors, std::vector<double> start,
int printlevel)
1680 if (fParameters.Size() < 1) {
1681 BCLog::OutError(
"BCIntegrate::FindModeMinuit : No parameters defined. Aborting.");
1682 return std::vector<double>();
1685 bool have_start =
true;
1688 if (start.size() == 0)
1690 else if (start.size() != fParameters.Size()) {
1692 BCLog::OutWarning(
"BCIntegrate::FindModeMinuit : Start point not valid (mismatch of dimensions), set to center.");
1697 for (
unsigned int i = 0; i <fParameters.Size(); ++i) {
1698 if (!fParameters[i]->IsValid(start[i]))
1700 if (fParameters[i]->Fixed() && start[i] != fParameters[i]->GetFixedValue())
1704 BCLog::OutWarning(
"BCIntegrate::FindModeMinuit : Start point not valid (parameter not inside valid range), set to center.");
1708 ::BCIntegrateHolder::instance(
this);
1713 fMinuit =
new TMinuit(fParameters.Size());
1716 fMinuit->SetPrintLevel(printlevel);
1719 fMinuit->SetFCN(&BCIntegrate::FCNLikelihood);
1722 fMinuit->SetErrorDef(0.5);
1726 for (
unsigned i = 0; i < fParameters.Size(); i++) {
1727 double starting_point = (fParameters[i]->GetUpperLimit() + fParameters[i]->GetLowerLimit()) / 2.;
1729 starting_point = start[i];
1730 if (fParameters[i]->Fixed())
1731 starting_point = fParameters[i]->GetFixedValue();
1733 fParameters[i]->GetName().data(),
1735 fParameters[i]->GetRangeWidth() / 100.,
1736 fParameters[i]->GetLowerLimit(),
1737 fParameters[i]->GetUpperLimit(),
1741 for (
unsigned i = 0; i < fParameters.Size(); i++)
1742 if (fParameters[i]->Fixed())
1743 fMinuit->FixParameter(i);
1749 fMinuit->mnexcm(
"MIGRAD", fMinuitArglist, 2, flag);
1755 fMinuitErrorFlag = flag;
1758 for (
unsigned i = 0; i < fParameters.Size(); i++) {
1759 fMinuit->GetParameter(i, mode[i], errors[i]);
1770 void BCIntegrate::InitializeSATree()
1774 fTreeSA =
new TTree(
"SATree",
"SATree");
1776 fTreeSA->Branch(
"Iteration", &fSANIterations,
"iteration/I");
1780 fTreeSA->Branch(
"Temperature", &fSATemperature,
"temperature/D");
1781 fTreeSA->Branch(
"LogProbability", &fSALogProb,
"log(probability)/D");
1783 for (
unsigned i = 0; i < fParameters.Size(); ++i)
1784 fTreeSA->Branch(TString::Format(
"Parameter%i", i), &fSAx[i], TString::Format(
"parameter %i/D", i));
1788 std::vector<double> BCIntegrate::FindModeSA(std::vector<double> &mode, std::vector<double> &errors, std::vector<double> start)
1793 bool have_start =
true;
1794 std::vector<double> x, y;
1795 double fval_x, fval_y, fval_mode;
1799 if (start.size() == 0)
1801 else if (start.size() != fParameters.Size()) {
1803 BCLog::OutWarning(
"BCIntegrate::FindModeSA : Start point not valid (mismatch of dimensions), set to center.");
1808 for (
unsigned int i = 0; i <fParameters.Size(); ++i) {
1809 if (!fParameters[i]->IsValid(start[i]))
1811 if (fParameters[i]->Fixed() && start[i] != fParameters[i]->GetFixedValue())
1815 BCLog::OutWarning(
"BCIntegrate::FindModeSA : Start point not valid (parameter not inside valid range), set to center.");
1819 if ( !have_start ) {
1821 for (
unsigned i=0; i<fParameters.Size(); i++)
1822 if (fParameters[i]->Fixed())
1823 start.push_back(fParameters[i]->GetFixedValue());
1825 start.push_back((fParameters[i]->GetLowerLimit() + fParameters[i]->GetUpperLimit()) / 2.);
1833 fval_x = fval_mode = LogEval(x);
1836 while ( SATemperature(t) > fSATmin ) {
1838 y = GetProposalPointSA(x, t);
1842 bool in_range =
true;
1844 for (
unsigned i = 0; i < fParameters.Size(); i++)
1845 if ( !fParameters[i]->IsValid(y[i]))
1850 fval_y = LogEval(y);
1854 if (fval_y >= fval_x) {
1859 if (fval_y > fval_mode) {
1866 if (fRandom->Rndm() <= exp( (fval_y - fval_x) / SATemperature(t) )) {
1875 fSATemperature = SATemperature(t);
1876 fSALogProb = fval_x;
1880 if (fFlagWriteSAToFile && fTreeSA)
1888 errors.assign(fParameters.Size(),-1);
1894 double BCIntegrate::SATemperature(
double t)
1897 if (fSASchedule == BCIntegrate::kSABoltzmann)
1898 return SATemperatureBoltzmann(t);
1899 else if (fSASchedule == BCIntegrate::kSACauchy)
1900 return SATemperatureCauchy(t);
1902 return SATemperatureCustom(t);
1906 double BCIntegrate::SATemperatureBoltzmann(
double t)
1908 return fSAT0 / log((
double)(t + 1));
1912 double BCIntegrate::SATemperatureCauchy(
double t)
1914 return fSAT0 / (double)t;
1918 double BCIntegrate::SATemperatureCustom(
double )
1920 BCLog::OutError(
"BCIntegrate::SATemperatureCustom : No custom temperature schedule defined");
1925 std::vector<double> BCIntegrate::GetProposalPointSA(
const std::vector<double> &x,
int t)
1928 if (fSASchedule == BCIntegrate::kSABoltzmann)
1929 return GetProposalPointSABoltzmann(x, t);
1930 else if (fSASchedule == BCIntegrate::kSACauchy)
1931 return GetProposalPointSACauchy(x, t);
1933 return GetProposalPointSACustom(x, t);
1937 std::vector<double> BCIntegrate::GetProposalPointSABoltzmann(
const std::vector<double> &x,
int t)
1939 std::vector<double> y;
1941 double new_val, norm;
1943 for (
unsigned i = 0; i < fParameters.Size(); i++) {
1944 if (fParameters[i]->Fixed()) {
1945 y.push_back(fParameters[i]->GetFixedValue());
1948 norm = fParameters[i]->GetRangeWidth() * SATemperature(t) / 2.;
1949 new_val = x[i] + norm * fRandom->Gaus();
1950 y.push_back(new_val);
1958 std::vector<double> BCIntegrate::GetProposalPointSACauchy(
const std::vector<double> &x,
int t)
1960 std::vector<double> y;
1963 if (fParameters.Size() == 1) {
1964 double cauchy, new_val, norm;
1966 if (fParameters[0]->Fixed()) {
1967 y.push_back(fParameters[0]->GetFixedValue());
1970 norm = fParameters[0]->GetRangeWidth() * SATemperature(t) / 2.;
1971 cauchy = tan(3.14159 * (fRandom->Rndm() - 0.5));
1972 new_val = x[0] + norm * cauchy;
1973 y.push_back(new_val);
1981 y = SAHelperGetRandomPointOnHypersphere();
1985 double radial = SATemperature(t) * SAHelperGetRadialCauchy();
1989 for (
unsigned i = 0; i < fParameters.Size(); i++) {
1990 if (fParameters[i]->Fixed()) {
1991 y[i] = fParameters[i]->GetFixedValue(); }
1993 y[i] = fParameters[i]->GetRangeWidth() * y[i] * radial / 2. + x[i];
2002 std::vector<double> BCIntegrate::GetProposalPointSACustom(
const std::vector<double> & ,
int )
2004 BCLog::OutError(
"BCIntegrate::GetProposalPointSACustom : No custom proposal function defined");
2005 return std::vector<double>(fParameters.Size());
2009 std::vector<double> BCIntegrate::SAHelperGetRandomPointOnHypersphere()
2011 std::vector<double> rand_point(fParameters.Size());
2019 if (fParameters.Size() == 2) {
2022 x1 = fRandom->Rndm() * 2. - 1.;
2023 x2 = fRandom->Rndm() * 2. - 1.;
2028 rand_point[0] = (x1*x1 - x2*x2) / s;
2029 rand_point[1] = (2.*x1*x2) / s;
2031 else if (fParameters.Size() == 3) {
2032 fRandom->Sphere(rand_point[0], rand_point[1], rand_point[2], 1.0);
2038 for (
unsigned i = 0; i < fParameters.Size(); i++) {
2039 gauss_num = fRandom->Gaus();
2040 rand_point[i] = gauss_num;
2041 s += gauss_num * gauss_num;
2045 for (
unsigned i = 0; i < fParameters.Size(); i++)
2046 rand_point[i] = rand_point[i] / s;
2053 double BCIntegrate::SAHelperGetRadialCauchy()
2062 static double map_u[10001];
2063 static double map_theta[10001];
2064 static bool initialized =
false;
2065 static unsigned map_dimension = 0;
2068 if (!initialized or map_dimension != fParameters.Size()) {
2070 double beta = SAHelperSinusToNIntegral(fParameters.Size() - 1, 1.57079632679);
2072 for (
int i = 0; i <= 10000; i++) {
2073 init_theta = 3.14159265 * (double)i / 5000.;
2074 map_theta[i] = init_theta;
2076 map_u[i] = SAHelperSinusToNIntegral(fParameters.Size() - 1, init_theta) / beta;
2079 map_dimension = fParameters.Size();
2084 double u = fRandom->Rndm();
2093 mid = ((up - lo + 1) / 2) + lo;
2095 if (u >= map_u[mid])
2103 theta = map_theta[lo] + (u - map_u[lo]) / (map_u[up] - map_u[lo]) * (map_theta[up] - map_theta[lo]);
2109 double BCIntegrate::SAHelperSinusToNIntegral(
int dim,
double theta)
2114 return (1. - cos(theta));
2116 return 0.5 * (theta - sin(theta) * cos(theta));
2118 return (2. - sin(theta) * sin(theta) * cos(theta) - 2. * cos(theta)) / 3.;
2120 return - pow(sin(theta), (
double)(dim - 1)) * cos(theta) / (double)dim
2121 + (
double)(dim - 1) / (
double)dim
2122 * SAHelperSinusToNIntegral(dim - 2, theta);
2126 void BCIntegrate::FCNLikelihood(
int & ,
double * ,
double &fval,
double * par,
int )
2129 static std::vector<double> parameters;
2134 int nparameters = ::BCIntegrateHolder::instance()->GetNParameters();
2137 parameters.resize(nparameters, 0.0);
2140 std::copy(par, par + nparameters, parameters.begin());
2143 fval = - ::BCIntegrateHolder::instance()->LogEval(parameters);
2147 std::vector<double> BCIntegrate::FindModeMCMC(std::vector<double> &mode, std::vector<double> &errors)
2150 MCMCMetropolisPreRun();
2153 double logProb = -std::numeric_limits<double>::max();
2155 for (
unsigned i = 0; i < fMCMCNChains; ++i) {
2156 if (MCMCGetMaximumLogProb().at(i) > logProb){
2158 logProb = MCMCGetMaximumLogProb().at(i);
2162 mode = MCMCGetMaximumPoint(index);
2163 errors.assign(fParameters.Size(),-1.);
2169 void BCIntegrate::SetIntegrationMethod(BCIntegrate::BCIntegrationMethod method)
2171 if (method >= BCIntegrate::NIntMethods) {
2172 BCLog::OutError(Form(
"BCIntegrate::SetIntegrationMethod: Invalid method '%d' ", method));
2175 if (method == BCIntegrate::kIntCuba) {
2177 BCLog::OutError(
"BCIntegrate::SetIntegrationMethod: Cuba not enabled during configure");
2180 fIntegrationMethodCurrent = method;
2184 void BCIntegrate::SetCubaIntegrationMethod(BCIntegrate::BCCubaMethod type)
2188 case BCIntegrate::kCubaVegas:
2189 case BCIntegrate::kCubaSuave:
2190 case BCIntegrate::kCubaDivonne:
2191 case BCIntegrate::kCubaCuhre:
2192 fCubaIntegrationMethod = type;
2195 BCLog::OutError(TString::Format(
"Integration method of type %d is not defined for Cuba",type));
2200 BCLog::OutError(
"SetCubaIntegrationMethod: Cuba not enabled during configure");
2205 int BCIntegrate::CubaIntegrand(
const int * ndim,
const double xx[],
2206 const int * ,
double ff[],
void * userdata)
2211 double jacobian = 1.0;
2215 std::vector<double> scaled_parameters(local_this->fParameters.Size());
2219 unsigned cubaIndex = 0;
2220 unsigned batIndex = 0;
2221 for (batIndex = 0; batIndex < local_this->fParameters.Size(); ++batIndex) {
2222 const BCParameter * p = local_this->fParameters[batIndex];
2226 scaled_parameters[batIndex] = p->GetFixedValue();
2239 if (cubaIndex !=
unsigned(*ndim))
2240 BCLog::OutError(Form(
"BCIntegrate::CubaIntegrand: mismatch between variable parameters"
2241 "in BAT (%d) and Cuba(%d)", batIndex, cubaIndex));
2244 ff[0] = local_this->Eval(scaled_parameters);
2253 double BCIntegrate::IntegrateCuba(BCCubaMethod cubatype) {
2255 LogOutputAtStartOfIntegration(kIntCuba, cubatype);
2258 static const int ncomp = 1;
2261 static const int gridno = -1;
2264 static const char * statefile =
"";
2267 static const int nvec = 1;
2269 #ifdef CUBAVERSION_40
2277 std::vector<double> integral(ncomp, -1);
2278 std::vector<double> error(ncomp, -1);
2279 std::vector<double> prob(ncomp, -1);
2285 int nIntegrationVariables = GetNIntegrationVariables();
2289 case BCIntegrate::kCubaVegas:
2290 Vegas(nIntegrationVariables, ncomp,
2291 &BCIntegrate::CubaIntegrand, static_cast<void *>(
this),
2293 fRelativePrecision, fAbsolutePrecision,
2294 fCubaVegasOptions.flags, fRandom->GetSeed(),
2295 fNIterationsMin, fNIterationsMax,
2296 fCubaVegasOptions.nstart, fCubaVegasOptions.nincrease, fCubaVegasOptions.nbatch,
2298 #ifdef CUBAVERSION_40
2301 &fNIterations, &fail,
2302 &integral[0], &error[0], &prob[0]);
2305 case BCIntegrate::kCubaSuave:
2306 Suave(nIntegrationVariables, ncomp,
2307 &BCIntegrate::CubaIntegrand, static_cast<void *>(
this),
2309 fRelativePrecision, fAbsolutePrecision,
2310 fCubaSuaveOptions.flags, fRandom->GetSeed(),
2311 fNIterationsMin, fNIterationsMax,
2312 fCubaSuaveOptions.nnew, fCubaSuaveOptions.flatness,
2314 #ifdef CUBAVERSION_40
2317 &nregions, &fNIterations, &fail,
2318 &integral[0], &error[0], &prob[0]);
2321 case BCIntegrate::kCubaDivonne:
2322 if (nIntegrationVariables < 2 or nIntegrationVariables > 33)
2323 BCLog::OutError(
"BCIntegrate::IntegrateCuba(Divonne): Divonne only works in 1 < d < 34");
2326 static const int ngiven = 0;
2327 static const int nextra = ngiven;
2328 Divonne(nIntegrationVariables, ncomp,
2329 &BCIntegrate::CubaIntegrand, static_cast<void *>(
this),
2331 fRelativePrecision, fAbsolutePrecision,
2332 fCubaDivonneOptions.flags, fRandom->GetSeed(),
2333 fNIterationsMin, fNIterationsMax,
2334 fCubaDivonneOptions.key1, fCubaDivonneOptions.key2, fCubaDivonneOptions.key3,
2335 fCubaDivonneOptions.maxpass, fCubaDivonneOptions.border,
2336 fCubaDivonneOptions.maxchisq, fCubaDivonneOptions.mindeviation,
2337 ngiven, nIntegrationVariables , NULL, nextra, NULL,
2339 #ifdef CUBAVERSION_40
2342 &nregions, &fNIterations, &fail,
2343 &integral[0], &error[0], &prob[0]);
2347 case BCIntegrate::kCubaCuhre:
2348 if (nIntegrationVariables < 2)
2349 BCLog::OutError(
"BCIntegrate::IntegrateCuba(Cuhre): Cuhre(cubature) only works in d > 1");
2351 Cuhre(nIntegrationVariables, ncomp,
2352 &BCIntegrate::CubaIntegrand, static_cast<void *>(
this),
2354 fRelativePrecision, fAbsolutePrecision,
2355 fCubaCuhreOptions.flags, fNIterationsMin, fNIterationsMax,
2356 fCubaCuhreOptions.key,
2358 #ifdef CUBAVERSION_40
2361 &nregions, &fNIterations, &fail,
2362 &integral[0], &error[0], &prob[0]);
2365 case BCIntegrate::NCubaMethods:
2367 BCLog::OutError(
"Cuba integration method not set.");
2374 double result = integral[0];
2377 BCLog::OutWarning(
" Warning, integral did not converge with the given set of parameters. ");
2378 BCLog::OutWarning(TString::Format(
" neval = %d", fNIterations));
2379 BCLog::OutWarning(TString::Format(
" fail = %d", fail));
2380 BCLog::OutWarning(TString::Format(
" integral = %e", result));
2381 BCLog::OutWarning(TString::Format(
" error = %e", fError));
2382 BCLog::OutWarning(TString::Format(
" prob = %e", prob[0]));
2385 if (fNIterations == 0)
2392 LogOutputAtEndOfIntegration(result,fError,fError/result,fNIterations);
2397 BCLog::OutError(
"IntegrateCuba: Cuba not enabled during configure");
2403 double BCIntegrate::IntegrateSlice()
2406 LogOutputAtStartOfIntegration(fIntegrationMethodCurrent, NCubaMethods);
2408 double integral = -1;
2409 double absprecision = -1;
2410 double relprecision = -1;
2414 std::vector<double> fixpoint(GetNParameters());
2415 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
2416 if (fParameters[i]->Fixed())
2417 fixpoint[i] = fParameters[i]->GetFixedValue();
2422 if (GetNFreeParameters() == 1) {
2423 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
2424 if (!fParameters[i]->Fixed()) {
2426 BCH1D* hist_temp = GetSlice(fParameters[i], fixpoint, 0,
false);
2429 integral = hist_temp->
GetHistogram()->Integral(
"width");
2436 else if (GetNFreeParameters() == 2) {
2437 for (
unsigned int i = 0; i < GetNParameters(); ++i) {
2438 for (
unsigned int j = 0; j < GetNParameters(); ++j) {
2441 if (!fParameters[i]->Fixed() && !fParameters[j]->Fixed()) {
2443 BCH2D* hist_temp = GetSlice(GetParameter(i), GetParameter(j), fixpoint, 0,
false);
2446 integral = hist_temp->
GetHistogram()->Integral(
"width");
2455 BCLog::OutWarning(
"BCIntegrate::IntegrateSlice: Method only implemented for 1D and 2D problems. Return -1.");
2461 LogOutputAtEndOfIntegration(integral, absprecision, relprecision, -1);
2467 void BCIntegrate::SAInitialize()
2470 fSAx.assign(fParameters.Size(), 0.0);
2474 std::string BCIntegrate::DumpIntegrationMethod(BCIntegrate::BCIntegrationMethod type)
2477 case BCIntegrate::kIntEmpty:
2479 case BCIntegrate::kIntMonteCarlo:
2480 return "Sample Mean Monte Carlo";
2481 case BCIntegrate::kIntCuba:
2483 case BCIntegrate::kIntGrid:
2491 std::string BCIntegrate::DumpMarginalizationMethod(BCIntegrate::BCMarginalizationMethod type)
2494 case BCIntegrate::kMargEmpty:
2496 case BCIntegrate::kMargMonteCarlo:
2497 return "Sample Mean Monte Carlo";
2498 case BCIntegrate::kMargMetropolis:
2499 return "Metropolis";
2500 case BCIntegrate::kMargGrid:
2502 case BCIntegrate::kMargDefault:
2510 std::string BCIntegrate::DumpOptimizationMethod(BCIntegrate::BCOptimizationMethod type)
2513 case BCIntegrate::kOptEmpty:
2515 case BCIntegrate::kOptSimAnn:
2516 return "Simulated Annealing";
2517 case BCIntegrate::kOptMetropolis:
2518 return "Metropolis MCMC";
2519 case BCIntegrate::kOptMinuit:
2521 case BCIntegrate::kOptDefault:
2529 std::string BCIntegrate::DumpCubaIntegrationMethod(BCIntegrate::BCCubaMethod type)
2532 case BCIntegrate::kCubaVegas:
2534 case BCIntegrate::kCubaSuave:
2536 case BCIntegrate::kCubaDivonne:
2538 case BCIntegrate::kCubaCuhre:
2545 namespace BCCubaOptions
2547 General::General() :
2579 Divonne::Divonne() :
virtual void ResetResults()
double GetLowerLimit() const
A class for handling numerical operations for models.
double GetRangeWidth() const
A class for handling 2D distributions.
void SetGlobalMode(double mode[2])
void SetHistogram(TH2D *hist)
void Copy(const BCEngineMCMC &enginemcmc)
void SetHistogram(TH1D *hist)
A class representing a parameter of a model.
An engine class for Markov Chain Monte Carlo.
static void Out(BCLog::LogLevel loglevelfile, BCLog::LogLevel loglevelscreen, const char *message)
const std::string & GetLatexName() const
double GetUpperLimit() const
A class for handling 1D distributions.
void SetGlobalMode(double mode)
const std::string & GetName() const
static BCLog::LogLevel GetLogLevelScreen()
void Draw(std::string options="BTsiB3CS1D0Lmeanmode", std::vector< double > intervals=std::vector< double >(0))
A class for managing log messages.