13 #include "Minuit2/FunctionMinimum.h" 14 #include "Minuit2/MinosError.h" 15 #include "Minuit2/MnHesse.h" 16 #include "Minuit2/MnMigrad.h" 17 #include "Minuit2/MnMinos.h" 18 #include "Minuit2/MnPrint.h" 19 #include "Minuit2/MnStrategy.h" 20 #include "Minuit2/MnUserParameters.h" 38 for (
auto &FinalPar : FinalParameters) {
43 double val = minState.Value(FinalPar.Name);
44 double err = minState.Error(FinalPar.Name);
47 if (FinalPar.Name.find(
"phase") != FinalPar.Name.npos)
50 FinalPar.Error = std::make_pair(err, err);
52 return FinalParameters;
55 std::vector<std::vector<double>>
57 std::vector<std::vector<double>> CovarianceMatrix;
59 if (minState.HasCovariance()) {
60 auto NumFreeParameter = minState.Parameters().Trafo().VariableParameters();
61 ROOT::Minuit2::MnUserCovariance minuitCovMatrix = minState.Covariance();
66 assert(minuitCovMatrix.Nrow() == NumFreeParameter);
67 CovarianceMatrix = std::vector<std::vector<double>>(
68 NumFreeParameter, std::vector<double>(NumFreeParameter));
69 for (
unsigned i = 0; i < NumFreeParameter; ++i)
70 for (
unsigned j = i; j < NumFreeParameter; ++j) {
71 CovarianceMatrix.at(i).at(j) = minuitCovMatrix(j, i);
72 CovarianceMatrix.at(j).at(i) = minuitCovMatrix(j, i);
77 <<
"MinuitIF::createResult(): no valid covariance matrix available!";
79 return CovarianceMatrix;
84 if (strategy ==
"low")
85 strat.SetLowStrategy();
86 else if (strategy ==
"medium")
87 strat.SetMediumStrategy();
88 else if (strategy ==
"high")
89 strat.SetHighStrategy();
91 LOG(INFO) <<
"MinuitIF::setStrategy() | Minuit strategy must be " 92 "set to 'low', 'medium' or 'high'";
94 GradientNCycles = strat.GradientNCycles();
95 GradientStepTolerance = strat.GradientStepTolerance();
96 GradientTolerance = strat.GradientTolerance();
97 HessianNCycles = strat.HessianNCycles();
98 HessianGradientNCycles = strat.HessianGradientNCycles();
99 HessianStepTolerance = strat.HessianStepTolerance();
100 HessianG2Tolerance = strat.HessianG2Tolerance();
106 strat.SetLowStrategy();
107 if (strat.GradientNCycles() == GradientNCycles &&
108 strat.GradientStepTolerance() == GradientStepTolerance &&
109 strat.GradientTolerance() == GradientTolerance &&
110 strat.HessianNCycles() == HessianNCycles &&
111 strat.HessianGradientNCycles() == HessianGradientNCycles &&
112 strat.HessianStepTolerance() == HessianStepTolerance &&
113 strat.HessianG2Tolerance() == HessianG2Tolerance)
116 strat.SetMediumStrategy();
117 if (strat.GradientNCycles() == GradientNCycles &&
118 strat.GradientStepTolerance() == GradientStepTolerance &&
119 strat.GradientTolerance() == GradientTolerance &&
120 strat.HessianNCycles() == HessianNCycles &&
121 strat.HessianGradientNCycles() == HessianGradientNCycles &&
122 strat.HessianStepTolerance() == HessianStepTolerance &&
123 strat.HessianG2Tolerance() == HessianG2Tolerance)
126 strat.SetHighStrategy();
127 if (strat.GradientNCycles() == GradientNCycles &&
128 strat.GradientStepTolerance() == GradientStepTolerance &&
129 strat.GradientTolerance() == GradientTolerance &&
130 strat.HessianNCycles() == HessianNCycles &&
131 strat.HessianGradientNCycles() == HessianGradientNCycles &&
132 strat.HessianStepTolerance() == HessianStepTolerance &&
133 strat.HessianG2Tolerance() == HessianG2Tolerance)
141 LOG(DEBUG) <<
"MinuitIF::optimize() | Start";
142 std::chrono::steady_clock::time_point StartTime =
143 std::chrono::steady_clock::now();
145 double InitialEstimatorValue(Estimator.
evaluate());
147 MnUserParameters upar;
148 unsigned int FreeParameters = 0;
149 for (
auto Param : InitialParameters) {
150 if (Param.Name ==
"")
151 throw BadParameter(
"MinuitIF::optimize() | FitParameter without name in " 152 "list. Since FitParameter names are unique we stop " 156 double Error(0.5 * (Param.Error.first + Param.Error.second));
158 if (Param.Value != 0.0)
159 Error = Param.Value * 0.1;
164 if (Param.HasBounds) {
165 bool rt = upar.Add(Param.Name, Param.Value, Error, Param.Bounds.first,
166 Param.Bounds.second);
169 "MinuitIF::optimize() | FitParameter " + Param.Name +
170 " can not be added to Minuit2 (internal) parameters.");
172 bool rt = upar.Add(Param.Name, Param.Value, Error);
175 "MinuitIF::optimize() | FitParameter " + Param.Name +
176 " can not be added to Minuit2 (internal) parameters.");
181 upar.Fix(Param.Name);
184 ROOT::Minuit2::MinuitFcn
Function(Estimator);
186 LOG(INFO) <<
"MinuitIF::optimize() | Number of parameters (free): " 187 << InitialParameters.size() <<
" (" << FreeParameters <<
")";
192 strat.SetGradientNCycles(GradientNCycles);
193 strat.SetGradientStepTolerance(GradientStepTolerance);
194 strat.SetGradientTolerance(GradientTolerance);
195 strat.SetHessianNCycles(HessianNCycles);
196 strat.SetHessianGradientNCycles(HessianGradientNCycles);
197 strat.SetHessianStepTolerance(HessianStepTolerance);
198 strat.SetHessianG2Tolerance(HessianG2Tolerance);
200 LOG(INFO) <<
"Minuit2 strategy: " << checkStrategy()
201 <<
"\n GradientNCycles: " << GradientNCycles
202 <<
"\n GradientStepTolerance: " << GradientStepTolerance
203 <<
"\n GradientTolerance: " << GradientTolerance
204 <<
"\n HessianNCycles: " << HessianNCycles
205 <<
"\n HessianGradientNCycles: " << HessianGradientNCycles
206 <<
"\n HessianStepTolerance: " << HessianStepTolerance
207 <<
"\n HessianG2Tolerance: " << HessianG2Tolerance;
210 MnMigrad migrad(Function, upar, strat);
212 double tolerance = 0.1;
222 LOG(INFO) <<
"MinuitIF::optimize() | Starting migrad: " 224 << maxfcn <<
" tolerance=" << tolerance;
226 FunctionMinimum minMin = migrad(maxfcn, tolerance);
228 LOG(INFO) <<
"MinuitIF::optimize() | Migrad finished! " 229 "Minimum is valid = " 233 MnHesse hesse(strat);
234 if (minMin.IsValid() && UseHesse) {
235 LOG(INFO) <<
"MinuitIF::optimize() | Starting hesse";
236 hesse(Function, minMin);
237 LOG(INFO) <<
"MinuitIF::optimize() | Hesse finished";
239 LOG(INFO) <<
"MinuitIF::optimize() | Migrad failed to " 240 "find minimum! Skip hesse and minos!";
242 LOG(INFO) <<
"MinuitIF::optimize() | Minimization finished! " 244 << std::setprecision(10) << minMin.Fval();
246 std::chrono::steady_clock::time_point EndTime =
247 std::chrono::steady_clock::now();
251 auto MinState = minMin.UserState();
257 InitialEstimatorValue,
259 std::chrono::duration_cast<std::chrono::seconds>(EndTime - StartTime),
264 if (minMin.IsValid() && UseMinos) {
266 MnMinos minos(Function, minMin, strat);
269 if (FinalPar.IsFixed)
273 LOG(INFO) <<
"MinuitIF::optimize() | Run minos " 275 <<
id <<
"] " << FinalPar.Name <<
"...";
276 MinosError err = minos.Minos(
id);
277 FinalPar.Error = err();
MinuitResult optimize(ComPWA::Estimator::Estimator< double > &Estimator, ComPWA::FitParameterList InitialParameters)
Finds the optimal value of the Estimator, by varying its parameters.
double shiftAngle(double value)
std::vector< FitParameter< double > > FitParameterList
std::string checkStrategy()
Check if a pre-defined strategy is set or if custom settings are used.
virtual OutputType evaluate(const InputTypes &... args) noexcept=0
FitParameterList getFinalParameters(const ROOT::Minuit2::MnUserParameterState &minState, FitParameterList InitialParameters)
Data structure which resembles a general fit result.
FitParameterList FinalParameters
std::vector< std::vector< double > > getCovarianceMatrix(const ROOT::Minuit2::MnUserParameterState &minState)
void setStrategy(std::string strategy)
Minuit strategy (low, medium(default), high) See https://root.cern.ch/root/htmldoc/guides/minuit2/Min...
Interface template for a general Function of the form OutputType Function(InputTypes) The concept clo...