Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Minuit2Minimizer.cxx
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Author: L. Moneta Wed Oct 18 11:48:00 2006
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7 * *
8 * *
9 **********************************************************************/
10
11// Implementation file for class Minuit2Minimizer
12
14
15#include "Math/IFunction.h"
16#include "Math/IOptions.h"
17
19
20#include "Minuit2/FCNAdapter.h"
23#include "Minuit2/MnMigrad.h"
24#include "Minuit2/MnMinos.h"
25#include "Minuit2/MinosError.h"
26#include "Minuit2/MnHesse.h"
28#include "Minuit2/MnPrint.h"
35#include "Minuit2/MnContours.h"
38
39#include <cassert>
40#include <iostream>
41#include <algorithm>
42#include <functional>
43
44#ifdef USE_ROOT_ERROR
45#include "TError.h"
46#include "TROOT.h"
47#include "TMinuit2TraceObject.h"
48#endif
49
50namespace ROOT {
51
52namespace Minuit2 {
53
54// functions needed to control siwthc off of Minuit2 printing level
55#ifdef USE_ROOT_ERROR
57{
58 // switch off Minuit2 printing of INFO message (cut off is 1001)
60 if (prevErrorIgnoreLevel < 1001) {
61 gErrorIgnoreLevel = 1001;
63 }
64 return -2; // no op in this case
65}
66
68{
70}
71#else
72// dummy functions
74{
75 return -1;
76}
78{
79 return -1;
80}
82#endif
83
85{
86 // Default constructor implementation depending on minimizer type
88}
89
91{
92 // constructor from a string
93
94 std::string algoname(type);
95 // tolower() is not an std function (Windows)
96 std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int (*)(int))tolower);
97
99 if (algoname == "simplex")
101 if (algoname == "minimize")
103 if (algoname == "scan")
104 algoType = kScan;
105 if (algoname == "fumili" || algoname == "fumili2")
107 if (algoname == "bfgs")
109
111}
112
114{
115 // Set minimizer algorithm type
116 fUseFumili = false;
117 switch (type) {
118 case ROOT::Minuit2::kMigrad: fMinimizer = std::make_unique<ROOT::Minuit2::VariableMetricMinimizer>(); return;
120 fMinimizer = std::make_unique<ROOT::Minuit2::VariableMetricMinimizer>(VariableMetricMinimizer::BFGSType());
121 return;
122 case ROOT::Minuit2::kSimplex: fMinimizer = std::make_unique<ROOT::Minuit2::SimplexMinimizer>(); return;
123 case ROOT::Minuit2::kCombined: fMinimizer = std::make_unique<ROOT::Minuit2::CombinedMinimizer>(); return;
124 case ROOT::Minuit2::kScan: fMinimizer = std::make_unique<ROOT::Minuit2::ScanMinimizer>(); return;
126 fMinimizer = std::make_unique<ROOT::Minuit2::FumiliMinimizer>();
127 fUseFumili = true;
128 return;
129 default:
130 // migrad minimizer
131 fMinimizer = std::make_unique<ROOT::Minuit2::VariableMetricMinimizer>();
132 }
133}
134
136
138{
139 // delete the state in case of consecutive minimizations
141 // clear also the function minimum
142 fMinimum.reset();
143}
144
145// set variables
146
147bool Minuit2Minimizer::SetVariable(unsigned int ivar, const std::string &name, double val, double step)
148{
149 // set a free variable.
150 // Add the variable if not existing otherwise set value if exists already
151 // this is implemented in MnUserParameterState::Add
152 // if index is wrong (i.e. variable already exists but with a different index return false) but
153 // value is set for corresponding variable name
154
155 // std::cout << " add parameter " << name << " " << val << " step " << step << std::endl;
156 MnPrint print("Minuit2Minimizer::SetVariable", PrintLevel());
157
158 if (step <= 0) {
159 print.Info("Parameter", name, "has zero or invalid step size - consider it as constant");
160 fState.Add(name, val);
161 } else
162 fState.Add(name, val, step);
163
164 unsigned int minuit2Index = fState.Index(name);
165 if (minuit2Index != ivar) {
166 print.Warn("Wrong index", minuit2Index, "used for the variable", name);
168 return false;
169 }
171
172 return true;
173}
174
175/** set initial second derivatives
176 */
177bool Minuit2Minimizer::SetCovarianceDiag(std::span<const double> d2, unsigned int n)
178{
179 MnPrint print("Minuit2Minimizer::SetCovarianceDiag", PrintLevel());
180
181 std::vector<double> cov(n * (n + 1) / 2);
182
183 for (unsigned int i = 0; i < n; i++) {
184 for (unsigned int j = i; j < n; j++)
185 cov[i + j * (j + 1) / 2] = (i == j) ? d2[i] : 0.;
186 }
187
189}
190
191bool Minuit2Minimizer::SetCovariance(std::span<const double> cov, unsigned int nrow)
192{
193 MnPrint print("Minuit2Minimizer::SetCovariance", PrintLevel());
194
196
197 return true;
198}
199
200bool Minuit2Minimizer::SetLowerLimitedVariable(unsigned int ivar, const std::string &name, double val, double step,
201 double lower)
202{
203 // add a lower bounded variable
204 if (!SetVariable(ivar, name, val, step))
205 return false;
207 return true;
208}
209
210bool Minuit2Minimizer::SetUpperLimitedVariable(unsigned int ivar, const std::string &name, double val, double step,
211 double upper)
212{
213 // add a upper bounded variable
214 if (!SetVariable(ivar, name, val, step))
215 return false;
217 return true;
218}
219
220bool Minuit2Minimizer::SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step,
221 double lower, double upper)
222{
223 // add a double bound variable
224 if (!SetVariable(ivar, name, val, step))
225 return false;
227 return true;
228}
229
230bool Minuit2Minimizer::SetFixedVariable(unsigned int ivar, const std::string &name, double val)
231{
232 // add a fixed variable
233 // need a step size otherwise treated as a constant
234 // use 10%
235 double step = (val != 0) ? 0.1 * std::abs(val) : 0.1;
236 if (!SetVariable(ivar, name, val, step)) {
238 }
239 fState.Fix(ivar);
240 return true;
241}
242
243std::string Minuit2Minimizer::VariableName(unsigned int ivar) const
244{
245 // return the variable name
246 if (ivar >= fState.MinuitParameters().size())
247 return std::string();
248 return fState.GetName(ivar);
249}
250
251int Minuit2Minimizer::VariableIndex(const std::string &name) const
252{
253 // return the variable index
254 // check if variable exist
255 return fState.Trafo().FindIndex(name);
256}
257
258bool Minuit2Minimizer::SetVariableValue(unsigned int ivar, double val)
259{
260 // set value for variable ivar (only for existing parameters)
261 if (ivar >= fState.MinuitParameters().size())
262 return false;
263 fState.SetValue(ivar, val);
264 return true;
265}
266
268{
269 // set value for variable ivar (only for existing parameters)
270 unsigned int n = fState.MinuitParameters().size();
271 if (n == 0)
272 return false;
273 for (unsigned int ivar = 0; ivar < n; ++ivar)
275 return true;
276}
277
278bool Minuit2Minimizer::SetVariableStepSize(unsigned int ivar, double step)
279{
280 // set the step-size of an existing variable
281 // parameter must exist or return false
282 if (ivar >= fState.MinuitParameters().size())
283 return false;
284 fState.SetError(ivar, step);
285 return true;
286}
287
289{
290 // set the limits of an existing variable
291 // parameter must exist or return false
292 if (ivar >= fState.MinuitParameters().size())
293 return false;
295 return true;
296}
298{
299 // set the limits of an existing variable
300 // parameter must exist or return false
301 if (ivar >= fState.MinuitParameters().size())
302 return false;
304 return true;
305}
306
307bool Minuit2Minimizer::SetVariableLimits(unsigned int ivar, double lower, double upper)
308{
309 // set the limits of an existing variable
310 // parameter must exist or return false
311 if (ivar >= fState.MinuitParameters().size())
312 return false;
314 return true;
315}
316
318{
319 // Fix an existing variable
320 if (ivar >= fState.MinuitParameters().size())
321 return false;
322 fState.Fix(ivar);
323 return true;
324}
325
327{
328 // Release an existing variable
329 if (ivar >= fState.MinuitParameters().size())
330 return false;
332 return true;
333}
334
336{
337 // query if variable is fixed
338 if (ivar >= fState.MinuitParameters().size()) {
339 MnPrint print("Minuit2Minimizer", PrintLevel());
340 print.Error("Wrong variable index");
341 return false;
342 }
343 return (fState.Parameter(ivar).IsFixed() || fState.Parameter(ivar).IsConst());
344}
345
347{
348 // retrieve variable settings (all set info on the variable)
349 if (ivar >= fState.MinuitParameters().size()) {
350 MnPrint print("Minuit2Minimizer", PrintLevel());
351 print.Error("Wrong variable index");
352 return false;
353 }
354 const MinuitParameter &par = fState.Parameter(ivar);
355 varObj.Set(par.Name(), par.Value(), par.Error());
356 if (par.HasLowerLimit()) {
357 if (par.HasUpperLimit()) {
358 varObj.SetLimits(par.LowerLimit(), par.UpperLimit());
359 } else {
360 varObj.SetLowerLimit(par.LowerLimit());
361 }
362 } else if (par.HasUpperLimit()) {
363 varObj.SetUpperLimit(par.UpperLimit());
364 }
365 if (par.IsConst() || par.IsFixed())
366 varObj.Fix();
367 return true;
368}
369
371{
372 // set function to be minimized
373 fMinuitFCN.reset();
374 fDim = func.NDim();
375 const bool hasGrad = func.HasGradient();
376 if (!fUseFumili) {
377 auto lambdaFunc = [&func](double const *params) { return func(params); };
378 auto adapter = std::make_unique<ROOT::Minuit2::FCNAdapter>(lambdaFunc, ErrorDef());
379 if (hasGrad) {
380 auto const &gradFunc = dynamic_cast<ROOT::Math::IMultiGradFunction const &>(func);
381 auto lambdaGrad = [&gradFunc](double const *params, double *grad) { return gradFunc.Gradient(params, grad); };
382 adapter->SetGradientFunction(lambdaGrad);
383 }
384 fMinuitFCN = std::move(adapter);
385 return;
386 }
387 if (hasGrad) {
388 // for Fumili the fit method function interface is required
389 auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodGradFunction *>(&func);
390 if (!fcnfunc) {
391 MnPrint print("Minuit2Minimizer", PrintLevel());
392 print.Error("Wrong Fit method function for Fumili");
393 return;
394 }
395 fMinuitFCN = std::make_unique<ROOT::Minuit2::FumiliFCNAdapter<ROOT::Math::FitMethodGradFunction>>(*fcnfunc, fDim,
396 ErrorDef());
397 } else {
398 // for Fumili the fit method function interface is required
399 auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodFunction *>(&func);
400 if (!fcnfunc) {
401 MnPrint print("Minuit2Minimizer", PrintLevel());
402 print.Error("Wrong Fit method function for Fumili");
403 return;
404 }
405 fMinuitFCN =
406 std::make_unique<ROOT::Minuit2::FumiliFCNAdapter<ROOT::Math::FitMethodFunction>>(*fcnfunc, fDim, ErrorDef());
407 }
408}
409
410void Minuit2Minimizer::SetHessianFunction(std::function<bool(std::span<const double>, double *)> hfunc)
411{
412 // for Fumili not supported for the time being
413 if (fUseFumili) return;
414 auto fcn = static_cast<ROOT::Minuit2::FCNAdapter *>(fMinuitFCN.get());
415 if (!fcn) return;
416 fcn->SetHessianFunction(hfunc);
417}
418
419namespace {
420
422{
424 // set strategy and add extra options if needed
426 if (!minuit2Opt) {
428 }
429 if (!minuit2Opt) {
430 return st;
431 }
432 auto customize = [&minuit2Opt](const char *name, auto val) {
433 minuit2Opt->GetValue(name, val);
434 return val;
435 };
436 // set extra options
437 st.SetGradientNCycles(customize("GradientNCycles", int(st.GradientNCycles())));
438 st.SetHessianNCycles(customize("HessianNCycles", int(st.HessianNCycles())));
439 st.SetHessianGradientNCycles(customize("HessianGradientNCycles", int(st.HessianGradientNCycles())));
440
441 st.SetGradientTolerance(customize("GradientTolerance", st.GradientTolerance()));
442 st.SetGradientStepTolerance(customize("GradientStepTolerance", st.GradientStepTolerance()));
443 st.SetHessianStepTolerance(customize("HessianStepTolerance", st.HessianStepTolerance()));
444 st.SetHessianG2Tolerance(customize("HessianG2Tolerance", st.HessianG2Tolerance()));
445
446 return st;
447}
448
449} // namespace
450
451/// Perform the minimization and store a copy of FunctionMinimum.
452/// The maximum number of function calls used can be checked via `this->MaxFunctionCalls()`,
453/// if this value is 0 (the default), then it is replaced with
454/// `2 * (nvar + 1) * (200 + 100 * nvar + 5 * nvar * nvar` where `nvar` is number of variable parameters.
455/// \see MnMinos::FindCrossValue
456/// Other minimization settings can be retrieved via `Tolerance()`, `Strategy()`, `ErrorDef()`, `Precision()`
457/// \see ROOT::Math::MinimizerOptions::PrintDefault()
459{
460
461
462 MnPrint print("Minuit2Minimizer::Minimize", PrintLevel());
463
464 if (!fMinuitFCN) {
465 print.Error("FCN function has not been set");
466 return false;
467 }
468
469 assert(GetMinimizer() != nullptr);
470
471 // delete result of previous minimization
472 fMinimum.reset();
473
474 const int maxfcn = MaxFunctionCalls();
475 const double tol = Tolerance();
476 const int strategyLevel = Strategy();
477 fMinuitFCN->SetErrorDef(ErrorDef());
478
479 const int printLevel = PrintLevel();
480 print.Debug("Minuit print level is", printLevel);
481 if (PrintLevel() >= 1) {
482 // print the real number of maxfcn used (defined in ModularFunctionMinimizer)
483 int maxfcn_used = maxfcn;
484 if (maxfcn_used == 0) {
485 int nvar = fState.VariableParameters();
486 maxfcn_used = 200 + 100 * nvar + 5 * nvar * nvar;
487 }
488 std::cout << "Minuit2Minimizer: Minimize with max-calls " << maxfcn_used << " convergence for edm < " << tol
489 << " strategy " << strategyLevel << std::endl;
490 }
491
492 // internal minuit messages
493 fMinimizer->Builder().SetPrintLevel(printLevel);
494
495 // switch off Minuit2 printing
496 const int prev_level = (printLevel <= 0) ? TurnOffPrintInfoLevel() : -2;
498
499 // set the precision if needed
500 if (Precision() > 0)
502
503 // add extra options if needed
505 if (!minuit2Opt) {
507 }
508 if (minuit2Opt) {
509 // set extra options
510 int storageLevel = 1;
511 bool ret = minuit2Opt->GetValue("StorageLevel", storageLevel);
512 if (ret)
514
515 // fumili options
516 if (fUseFumili) {
517 std::string fumiliMethod;
518 ret = minuit2Opt->GetValue("FumiliMethod", fumiliMethod);
519 if (ret) {
520 auto fumiliMinimizer = dynamic_cast<ROOT::Minuit2::FumiliMinimizer *>(fMinimizer.get());
521 if (fumiliMinimizer)
522 fumiliMinimizer->SetMethod(fumiliMethod);
523 }
524 }
525
526 if (printLevel > 0) {
527 std::cout << "Minuit2Minimizer::Minuit - Changing default options" << std::endl;
528 minuit2Opt->Print();
529 }
530 }
531
532 // set a minimizer tracer object (default for printlevel=10, from gROOT for printLevel=11)
533 // use some special print levels
534 MnTraceObject *traceObj = nullptr;
535#ifdef USE_ROOT_ERROR
536 if (printLevel == 10 && gROOT) {
537 TObject *obj = gROOT->FindObject("Minuit2TraceObject");
538 traceObj = dynamic_cast<ROOT::Minuit2::MnTraceObject *>(obj);
539 if (traceObj) {
540 // need to remove from the list
541 gROOT->Remove(obj);
542 }
543 }
544 if (printLevel == 20 || printLevel == 30 || printLevel == 40 || (printLevel >= 20000 && printLevel < 30000)) {
545 int parNumber = printLevel - 20000;
546 if (printLevel == 20)
547 parNumber = -1;
548 if (printLevel == 30)
549 parNumber = -2;
550 if (printLevel == 40)
551 parNumber = 0;
553 }
554#endif
555 if (printLevel == 100 || (printLevel >= 10000 && printLevel < 20000)) {
556 int parNumber = printLevel - 10000;
558 }
559 if (traceObj) {
560 traceObj->Init(fState);
562 }
563
565
567 fMinimum = std::make_unique<ROOT::Minuit2::FunctionMinimum>(min);
568
569 // check if Hesse needs to be run. We do it when is requested (IsValidError() == true , set by SetParabError(true) in fitConfig)
570 // (IsValidError() means the flag to get correct error from the Minimizer is set (Minimizer::SetValidError())
571 // AND when we have a valid minimum,
572 // AND when the the current covariance matrix is estimated using the iterative approximation (Dcovar != 0 , i.e. Hesse has not computed before)
573 if (fMinimum->IsValid() && IsValidError() && fMinimum->State().Error().Dcovar() != 0) {
574 // run Hesse (Hesse will add results in the last state of fMinimum
576 hesse(*fMinuitFCN, *fMinimum, maxfcn);
577 }
578
579 // -2 is the highest low invalid value for gErrorIgnoreLevel
580 if (prev_level > -2)
583
584 // copy minimum state (parameter values and errors)
585 fState = fMinimum->UserState();
586 bool ok = ExamineMinimum(*fMinimum);
587 // fMinimum = 0;
588
589 // delete trace object if it was constructed
590 if (traceObj) {
591 delete traceObj;
592 }
593 return ok;
594}
595
597{
598 /// study the function minimum
599
600 // debug ( print all the states)
601 int debugLevel = PrintLevel();
602 if (debugLevel >= 3) {
603
604 std::span<const ROOT::Minuit2::MinimumState> iterationStates = min.States();
605 std::cout << "Number of iterations " << iterationStates.size() << std::endl;
606 for (unsigned int i = 0; i < iterationStates.size(); ++i) {
607 // std::cout << iterationStates[i] << std::endl;
609 std::cout << "----------> Iteration " << i << std::endl;
610 int pr = std::cout.precision(12);
611 std::cout << " FVAL = " << st.Fval() << " Edm = " << st.Edm() << " Nfcn = " << st.NFcn()
612 << std::endl;
613 std::cout.precision(pr);
614 if (st.HasCovariance())
615 std::cout << " Error matrix change = " << st.Error().Dcovar() << std::endl;
616 if (st.HasParameters()) {
617 std::cout << " Parameters : ";
618 // need to transform from internal to external
619 for (int j = 0; j < st.size(); ++j)
620 std::cout << " p" << j << " = " << fState.Int2ext(j, st.Vec()(j));
621 std::cout << std::endl;
622 }
623 }
624 }
625
626 fStatus = 0;
627 std::string txt;
628 if (!min.HasPosDefCovar()) {
629 // this happens normally when Hesse failed
630 // it can happen in case MnSeed failed (see ROOT-9522)
631 txt = "Covar is not pos def";
632 fStatus = 5;
633 }
634 if (min.HasMadePosDefCovar()) {
635 txt = "Covar was made pos def";
636 fStatus = 1;
637 }
638 if (min.HesseFailed()) {
639 txt = "Hesse is not valid";
640 fStatus = 2;
641 }
642 if (min.IsAboveMaxEdm()) {
643 txt = "Edm is above max";
644 fStatus = 3;
645 }
646 if (min.HasReachedCallLimit()) {
647 txt = "Reached call limit";
648 fStatus = 4;
649 }
650
651 MnPrint print("Minuit2Minimizer::Minimize", debugLevel);
652 bool validMinimum = min.IsValid();
653 if (validMinimum) {
654 // print a warning message in case something is not ok
655 // this for example is case when Covar was made posdef and fStatus=3
656 if (fStatus != 0 && debugLevel > 0)
657 print.Warn(txt);
658 } else {
659 // minimum is not valid when state is not valid and edm is over max or has passed call limits
660 if (fStatus == 0) {
661 // this should not happen
662 txt = "unknown failure";
663 fStatus = 6;
664 }
665 print.Warn("Minimization did NOT converge,", txt);
666 }
667
668 if (debugLevel >= 1)
669 PrintResults();
670
671 // set the minimum values in the fValues vector
672 std::span<const MinuitParameter> paramsObj = fState.MinuitParameters();
673 if (paramsObj.empty())
674 return false;
675 assert(fDim == paramsObj.size());
676 // re-size vector if it has changed after a new minimization
677 if (fValues.size() != fDim)
678 fValues.resize(fDim);
679 for (unsigned int i = 0; i < fDim; ++i) {
680 fValues[i] = paramsObj[i].Value();
681 }
682
683 return validMinimum;
684}
685
687{
688 // print results of minimization
689 if (!fMinimum)
690 return;
691 if (fMinimum->IsValid()) {
692 // valid minimum
693 std::cout << "Minuit2Minimizer : Valid minimum - status = " << fStatus << std::endl;
694 int pr = std::cout.precision(18);
695 std::cout << "FVAL = " << fState.Fval() << std::endl;
696 std::cout << "Edm = " << fState.Edm() << std::endl;
697 std::cout.precision(pr);
698 std::cout << "Nfcn = " << fState.NFcn() << std::endl;
699 for (unsigned int i = 0; i < fState.MinuitParameters().size(); ++i) {
700 const MinuitParameter &par = fState.Parameter(i);
701 std::cout << par.Name() << "\t = " << par.Value() << "\t ";
702 if (par.IsFixed())
703 std::cout << "(fixed)" << std::endl;
704 else if (par.IsConst())
705 std::cout << "(const)" << std::endl;
706 else if (par.HasLimits())
707 std::cout << "+/- " << par.Error() << "\t(limited)" << std::endl;
708 else
709 std::cout << "+/- " << par.Error() << std::endl;
710 }
711 } else {
712 std::cout << "Minuit2Minimizer : Invalid minimum - status = " << fStatus << std::endl;
713 std::cout << "FVAL = " << fState.Fval() << std::endl;
714 std::cout << "Edm = " << fState.Edm() << std::endl;
715 std::cout << "Nfcn = " << fState.NFcn() << std::endl;
716 }
717}
718
719const double *Minuit2Minimizer::Errors() const
720{
721 // return error at minimum (set to zero for fixed and constant params)
722 std::span<const MinuitParameter> paramsObj = fState.MinuitParameters();
723 if (paramsObj.empty())
724 return nullptr;
725 assert(fDim == paramsObj.size());
726 // be careful for multiple calls of this function. I will redo an allocation here
727 // only when size of vectors has changed (e.g. after a new minimization)
728 if (fErrors.size() != fDim)
729 fErrors.resize(fDim);
730 for (unsigned int i = 0; i < fDim; ++i) {
731 const MinuitParameter &par = paramsObj[i];
732 if (par.IsFixed() || par.IsConst())
733 fErrors[i] = 0;
734 else
735 fErrors[i] = par.Error();
736 }
737
738 return &fErrors.front();
739}
740
741double Minuit2Minimizer::CovMatrix(unsigned int i, unsigned int j) const
742{
743 // get value of covariance matrices (transform from external to internal indices)
744 if (i >= fDim || j >= fDim)
745 return 0;
746 if (!fState.HasCovariance())
747 return 0; // no info available when minimization has failed
748 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
749 return 0;
750 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
751 return 0;
752 unsigned int k = fState.IntOfExt(i);
753 unsigned int l = fState.IntOfExt(j);
754 return fState.Covariance()(k, l);
755}
756
758{
759 // get value of covariance matrices
760 if (!fState.HasCovariance())
761 return false; // no info available when minimization has failed
762 for (unsigned int i = 0; i < fDim; ++i) {
763 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst()) {
764 for (unsigned int j = 0; j < fDim; ++j) {
765 cov[i * fDim + j] = 0;
766 }
767 } else {
768 unsigned int l = fState.IntOfExt(i);
769 for (unsigned int j = 0; j < fDim; ++j) {
770 // could probably speed up this loop (if needed)
771 int k = i * fDim + j;
772 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
773 cov[k] = 0;
774 else {
775 // need to transform from external to internal indices)
776 // for taking care of the removed fixed row/columns in the Minuit2 representation
777 unsigned int m = fState.IntOfExt(j);
778 cov[k] = fState.Covariance()(l, m);
779 }
780 }
781 }
782 }
783 return true;
784}
785
787{
788 // get value of Hessian matrix
789 // this is the second derivative matrices
790 if (!fState.HasCovariance())
791 return false; // no info available when minimization has failed
792 for (unsigned int i = 0; i < fDim; ++i) {
793 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst()) {
794 for (unsigned int j = 0; j < fDim; ++j) {
795 hess[i * fDim + j] = 0;
796 }
797 } else {
798 unsigned int l = fState.IntOfExt(i);
799 for (unsigned int j = 0; j < fDim; ++j) {
800 // could probably speed up this loop (if needed)
801 int k = i * fDim + j;
802 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
803 hess[k] = 0;
804 else {
805 // need to transform from external to internal indices)
806 // for taking care of the removed fixed row/columns in the Minuit2 representation
807 unsigned int m = fState.IntOfExt(j);
808 hess[k] = fState.Hessian()(l, m);
809 }
810 }
811 }
812 }
813
814 return true;
815}
816
817double Minuit2Minimizer::Correlation(unsigned int i, unsigned int j) const
818{
819 // get correlation between parameter i and j
820 if (i >= fDim || j >= fDim)
821 return 0;
822 if (!fState.HasCovariance())
823 return 0; // no info available when minimization has failed
824 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
825 return 0;
826 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
827 return 0;
828 unsigned int k = fState.IntOfExt(i);
829 unsigned int l = fState.IntOfExt(j);
830 double cij = fState.IntCovariance()(k, l);
831 double tmp = std::sqrt(std::abs(fState.IntCovariance()(k, k) * fState.IntCovariance()(l, l)));
832 if (tmp > 0)
833 return cij / tmp;
834 return 0;
835}
836
837std::vector<double> Minuit2Minimizer::GlobalCC() const
838{
839 // get global correlation coefficient for the parameter i. This is a number between zero and one which gives
840 // the correlation between the i-th parameter and that linear combination of all other parameters which
841 // is most strongly correlated with i.
842
843 std::vector<double> out;
845 // no info available when minimization has failed or has some problems
846 if (!globalCC.IsValid())
847 return out;
848 out.resize(fDim);
849 for (unsigned int i = 0; i < fDim; ++i) {
850 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
851 out[i] = 0;
852 else {
853 unsigned int k = fState.IntOfExt(i);
854 out[i] = globalCC.GlobalCC()[k];
855 }
856 }
857 return out;
858}
859
860bool Minuit2Minimizer::GetMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
861{
862 // return the minos error for parameter i
863 // if a minimum does not exist an error is returned
864 // runopt is a flag which specifies if only lower or upper error needs to be run
865 // if runopt = 0 both, = 1 only lower, + 2 only upper errors
866 errLow = 0;
867 errUp = 0;
868
870
871 // need to know if parameter is const or fixed
872 if (fState.Parameter(i).IsConst() || fState.Parameter(i).IsFixed()) {
873 return false;
874 }
875
876 MnPrint print("Minuit2Minimizer::GetMinosError", PrintLevel());
877
878 // to run minos I need function minimum class
879 // redo minimization from current state
880 // ROOT::Minuit2::FunctionMinimum min =
881 // GetMinimizer()->Minimize(*GetFCN(),fState, ROOT::Minuit2::MnStrategy(strategy), MaxFunctionCalls(),
882 // Tolerance());
883 // fState = min.UserState();
884 if (fMinimum == nullptr) {
885 print.Error("Failed - no function minimum existing");
886 return false;
887 }
888
889 if (!fMinimum->IsValid()) {
890 print.Error("Failed - invalid function minimum");
891 return false;
892 }
893
894 fMinuitFCN->SetErrorDef(ErrorDef());
895 // if error def has been changed update it in FunctionMinimum
896 if (ErrorDef() != fMinimum->Up())
897 fMinimum->SetErrorDef(ErrorDef());
898
900
901 // run again the Minimization in case of a new minimum
902 // bit 8 is set
903 if ((mstatus & 8) != 0) {
904 print.Info([&](std::ostream &os) {
905 os << "Found a new minimum: run again the Minimization starting from the new point";
906 os << "\nFVAL = " << fState.Fval();
907 for (auto &par : fState.MinuitParameters()) {
908 os << '\n' << par.Name() << "\t = " << par.Value();
909 }
910 });
911 // release parameter that was fixed in the returned state from Minos
913 bool ok = Minimize();
914 if (!ok)
915 return false;
916 // run again Minos from new Minimum (also lower error needs to be re-computed)
917 print.Info("Run now again Minos from the new found Minimum");
919
920 // do not reset new minimum bit to flag for other parameters
921 mstatus |= 8;
922 }
923
924 fStatus += 10 * mstatus;
926
927 bool isValid = ((mstatus & 1) == 0) && ((mstatus & 2) == 0);
928 return isValid;
929}
930
931int Minuit2Minimizer::RunMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
932{
933
934 bool runLower = runopt != 2;
935 bool runUpper = runopt != 1;
936
937 const int debugLevel = PrintLevel();
938 // switch off Minuit2 printing
939 const int prev_level = (debugLevel <= 0) ? TurnOffPrintInfoLevel() : -2;
941
942 // set the precision if needed
943 if (Precision() > 0)
945
947
948 // run MnCross
949 MnCross low;
950 MnCross up;
951 int maxfcn = MaxFunctionCalls();
952 double tol = Tolerance();
953
954 const char *par_name = fState.Name(i);
955
956 // now input tolerance for migrad calls inside Minos (MnFunctionCross)
957 // before it was fixed to 0.05
958 // cut off too small tolerance (they are not needed)
959 tol = std::max(tol, 0.01);
960
961 // get the real number of maxfcn used (defined in MnMinos) to be printed
962 int maxfcn_used = maxfcn;
963 if (maxfcn_used == 0) {
964 int nvar = fState.VariableParameters();
965 maxfcn_used = 2 * (nvar + 1) * (200 + 100 * nvar + 5 * nvar * nvar);
966 }
967
968 if (runLower) {
969 if (debugLevel >= 1) {
970 std::cout << "************************************************************************************************"
971 "******\n";
972 std::cout << "Minuit2Minimizer::GetMinosError - Run MINOS LOWER error for parameter #" << i << " : "
973 << par_name << " using max-calls " << maxfcn_used << ", tolerance " << tol << std::endl;
974 }
975 low = minos.Loval(i, maxfcn, tol);
976 }
977 if (runUpper) {
978 if (debugLevel >= 1) {
979 std::cout << "************************************************************************************************"
980 "******\n";
981 std::cout << "Minuit2Minimizer::GetMinosError - Run MINOS UPPER error for parameter #" << i << " : "
982 << par_name << " using max-calls " << maxfcn_used << ", tolerance " << tol << std::endl;
983 }
984 up = minos.Upval(i, maxfcn, tol);
985 }
986
987 ROOT::Minuit2::MinosError me(i, fMinimum->UserState().Value(i), low, up);
988
989 // restore global print level
990 if (prev_level > -2)
993
994 // debug result of Minos
995 // print error message in Minos
996 // Note that the only invalid condition can happen when the (npar-1) minimization fails
997 // The error is also invalid when the maximum number of calls is reached or a new function minimum is found
998 // in case of the parameter at the limit the error is not invalid.
999 // When the error is invalid the returned error is the Hessian error.
1000
1001 if (debugLevel > 0) {
1002 if (runLower) {
1003 if (!me.LowerValid())
1004 std::cout << "Minos: Invalid lower error for parameter " << par_name << std::endl;
1005 if (me.AtLowerLimit())
1006 std::cout << "Minos: Parameter : " << par_name << " is at Lower limit; error is " << me.Lower()
1007 << std::endl;
1008 if (me.AtLowerMaxFcn())
1009 std::cout << "Minos: Maximum number of function calls exceeded when running for lower error for parameter "
1010 << par_name << std::endl;
1011 if (me.LowerNewMin())
1012 std::cout << "Minos: New Minimum found while running Minos for lower error for parameter " << par_name
1013 << std::endl;
1014
1015 if (debugLevel >= 1 && me.LowerValid())
1016 std::cout << "Minos: Lower error for parameter " << par_name << " : " << me.Lower() << std::endl;
1017 }
1018 if (runUpper) {
1019 if (!me.UpperValid())
1020 std::cout << "Minos: Invalid upper error for parameter " << par_name << std::endl;
1021 if (me.AtUpperLimit())
1022 std::cout << "Minos: Parameter " << par_name << " is at Upper limit; error is " << me.Upper() << std::endl;
1023 if (me.AtUpperMaxFcn())
1024 std::cout << "Minos: Maximum number of function calls exceeded when running for upper error for parameter "
1025 << par_name << std::endl;
1026 if (me.UpperNewMin())
1027 std::cout << "Minos: New Minimum found while running Minos for upper error for parameter " << par_name
1028 << std::endl;
1029
1030 if (debugLevel >= 1 && me.UpperValid())
1031 std::cout << "Minos: Upper error for parameter " << par_name << " : " << me.Upper() << std::endl;
1032 }
1033 }
1034
1035 MnPrint print("RunMinosError", PrintLevel());
1036 bool lowerInvalid = (runLower && !me.LowerValid());
1037 bool upperInvalid = (runUpper && !me.UpperValid());
1038 // print message in case of invalid error also in printLevel0
1039 if (lowerInvalid) {
1040 print.Warn("Invalid lower error for parameter", fMinimum->UserState().Name(i));
1041 }
1042 if (upperInvalid) {
1043 print.Warn("Invalid upper error for parameter", fMinimum->UserState().Name(i));
1044 }
1045 // print also case it is lower/upper limit
1046 if (me.AtLowerLimit()) {
1047 print.Warn("Lower error for parameter", fMinimum->UserState().Name(i), "is at the Lower limit!");
1048 }
1049 if (me.AtUpperLimit()) {
1050 print.Warn("Upper error for parameter", fMinimum->UserState().Name(i), "is at the Upper limit!");
1051 }
1052
1053 int mstatus = 0;
1054 if (lowerInvalid || upperInvalid) {
1055 // set status according to bit
1056 // bit 1: lower invalid Minos errors
1057 // bit 2: upper invalid Minos error
1058 // bit 3: invalid because max FCN
1059 // bit 4 : invalid because a new minimum has been found
1060 if (lowerInvalid) {
1061 mstatus |= 1;
1062 if (me.AtLowerMaxFcn())
1063 mstatus |= 4;
1064 if (me.LowerNewMin())
1065 mstatus |= 8;
1066 }
1067 if (upperInvalid) {
1068 mstatus |= 2;
1069 if (me.AtUpperMaxFcn())
1070 mstatus |= 4;
1071 if (me.UpperNewMin())
1072 mstatus |= 8;
1073 }
1074 }
1075 // case upper/lower limit
1076 if (me.AtUpperLimit() || me.AtLowerLimit())
1077 mstatus |= 16;
1078
1079 if (runLower)
1080 errLow = me.Lower();
1081 if (runUpper)
1082 errUp = me.Upper();
1083
1084 // in case of new minimum found update also the minimum state
1085 if ((runLower && me.LowerNewMin()) && (runUpper && me.UpperNewMin())) {
1086 // take state with lower function value
1087 fState = (low.State().Fval() < up.State().Fval()) ? low.State() : up.State();
1088 } else if (runLower && me.LowerNewMin()) {
1089 fState = low.State();
1090 } else if (runUpper && me.UpperNewMin()) {
1091 fState = up.State();
1092 }
1093
1094 return mstatus;
1095}
1096
1097bool Minuit2Minimizer::Scan(unsigned int ipar, unsigned int &nstep, double *x, double *y, double xmin, double xmax)
1098{
1099 // scan a parameter (variable) around the minimum value
1100 // the parameters must have been set before
1101 // if xmin=0 && xmax == 0 by default scan around 2 sigma of the error
1102 // if the errors are also zero then scan from min and max of parameter range
1103
1104 MnPrint print("Minuit2Minimizer::Scan", PrintLevel());
1105 if (!fMinuitFCN) {
1106 print.Error("Function must be set before using Scan");
1107 return false;
1108 }
1109
1110 if (ipar > fState.MinuitParameters().size()) {
1111 print.Error("Invalid number; minimizer variables must be set before using Scan");
1112 return false;
1113 }
1114
1115 // switch off Minuit2 printing
1116 const int prev_level = (PrintLevel() <= 0) ? TurnOffPrintInfoLevel() : -2;
1118
1119 // set the precision if needed
1120 if (Precision() > 0)
1122
1124 double amin = scan.Fval(); // fcn value of the function before scan
1125
1126 // first value is param value
1127 std::vector<std::pair<double, double>> result = scan(ipar, nstep - 1, xmin, xmax);
1128
1129 // restore global print level
1130 if (prev_level > -2)
1133
1134 if (result.size() != nstep) {
1135 print.Error("Invalid result from MnParameterScan");
1136 return false;
1137 }
1138 // sort also the returned points in x
1139 std::sort(result.begin(), result.end());
1140
1141 for (unsigned int i = 0; i < nstep; ++i) {
1142 x[i] = result[i].first;
1143 y[i] = result[i].second;
1144 }
1145
1146 // what to do if a new minimum has been found ?
1147 // use that as new minimum
1148 if (scan.Fval() < amin) {
1149 print.Info("A new minimum has been found");
1150 fState.SetValue(ipar, scan.Parameters().Value(ipar));
1151 }
1152
1153 return true;
1154}
1155
1156bool Minuit2Minimizer::Contour(unsigned int ipar, unsigned int jpar, unsigned int &npoints, double *x, double *y)
1157{
1158 // contour plot for parameter i and j
1159 // need a valid FunctionMinimum otherwise exits
1160
1161 MnPrint print("Minuit2Minimizer::Contour", PrintLevel());
1162
1163 if (fMinimum == nullptr) {
1164 print.Error("No function minimum existing; must minimize function before");
1165 return false;
1166 }
1167
1168 if (!fMinimum->IsValid()) {
1169 print.Error("Invalid function minimum");
1170 return false;
1171 }
1173
1174 fMinuitFCN->SetErrorDef(ErrorDef());
1175 // if error def has been changed update it in FunctionMinimum
1176 if (ErrorDef() != fMinimum->Up()) {
1177 fMinimum->SetErrorDef(ErrorDef());
1178 }
1179
1180 print.Info("Computing contours at level -", ErrorDef());
1181
1182 // switch off Minuit2 printing (for level of 0,1)
1183 const int prev_level = (PrintLevel() <= 1) ? TurnOffPrintInfoLevel() : -2;
1185
1186 // set the precision if needed
1187 if (Precision() > 0)
1189
1190 // eventually one should specify tolerance in contours
1191 MnContours contour(*fMinuitFCN, *fMinimum, Strategy());
1192
1193 // restore global print level
1194 if (prev_level > -2)
1197
1198 // compute the contour
1199 std::vector<std::pair<double, double>> result = contour(ipar, jpar, npoints);
1200 if (result.size() != npoints) {
1201 print.Error("Invalid result from MnContours");
1202 return false;
1203 }
1204 for (unsigned int i = 0; i < npoints; ++i) {
1205 x[i] = result[i].first;
1206 y[i] = result[i].second;
1207 }
1208 print.Info([&](std::ostream &os) {
1209 os << " Computed " << npoints << " points at level " << ErrorDef();
1210 for (unsigned int i = 0; i < npoints; i++) {
1211 if (i %5 == 0) os << std::endl;
1212 os << "( " << x[i] << ", " << y[i] << ") ";
1213 }
1214 os << std::endl << std::endl;
1215 });
1216
1217 return true;
1218}
1219
1221{
1222 // find Hessian (full second derivative calculations)
1223 // the contained state will be updated with the Hessian result
1224 // in case a function minimum exists and is valid the result will be
1225 // appended in the function minimum
1226
1227 MnPrint print("Minuit2Minimizer::Hesse", PrintLevel());
1228
1229 if (!fMinuitFCN) {
1230 print.Error("FCN function has not been set");
1231 return false;
1232 }
1233
1234 const int maxfcn = MaxFunctionCalls();
1235 print.Info("Using max-calls", maxfcn);
1236
1237 // switch off Minuit2 printing
1238 const int prev_level = (PrintLevel() <= 0) ? TurnOffPrintInfoLevel() : -2;
1240
1241 // set the precision if needed
1242 if (Precision() > 0)
1244
1246
1247 // case when function minimum exists
1248 if (fMinimum) {
1249
1250 // if (PrintLevel() >= 3) {
1251 // std::cout << "Minuit2Minimizer::Hesse - State before running Hesse " << std::endl;
1252 // std::cout << fState << std::endl;
1253 // }
1254
1255 // run hesse and function minimum will be updated with Hesse result
1256 hesse(*fMinuitFCN, *fMinimum, maxfcn);
1257 // update user state
1258 fState = fMinimum->UserState();
1259 }
1260
1261 else {
1262 // run Hesse on point stored in current state (independent of function minimum validity)
1263 // (x == 0)
1264 fState = hesse(*fMinuitFCN, fState, maxfcn);
1265 }
1266
1267 // restore global print level
1268 if (prev_level > -2)
1271
1272 if (PrintLevel() >= 3) {
1273 std::cout << "Minuit2Minimizer::Hesse - State returned from Hesse " << std::endl;
1274 std::cout << fState << std::endl;
1275 }
1276
1278 std::string covStatusType = "not valid";
1279 if (covStatus == 1)
1280 covStatusType = "approximate";
1281 if (covStatus == 2)
1282 covStatusType = "full but made positive defined";
1283 if (covStatus == 3)
1284 covStatusType = "accurate";
1285 if (covStatus == 0)
1286 covStatusType = "full but not positive defined";
1287
1288 if (!fState.HasCovariance()) {
1289 // if false means error is not valid and this is due to a failure in Hesse
1290 // update minimizer error status
1291 int hstatus = 4;
1292 // information on error state can be retrieved only if fMinimum is available
1293 if (fMinimum) {
1294 if (fMinimum->Error().HesseFailed())
1295 hstatus = 1;
1296 if (fMinimum->Error().InvertFailed())
1297 hstatus = 2;
1298 else if (!(fMinimum->Error().IsPosDef()))
1299 hstatus = 3;
1300 }
1301
1302 print.Warn("Hesse failed - matrix is", covStatusType);
1303 print.Warn(hstatus);
1304
1305 fStatus += 100 * hstatus;
1306 return false;
1307 }
1308
1309 print.Info("Hesse is valid - matrix is", covStatusType);
1310
1311 return true;
1312}
1313
1315{
1316 // return status of covariance matrix
1317 //-1 - not available (inversion failed or Hesse failed)
1318 // 0 - available but not positive defined
1319 // 1 - covariance only approximate
1320 // 2 full matrix but forced pos def
1321 // 3 full accurate matrix
1322
1323 if (fMinimum) {
1324 // case a function minimum is available
1325 if (fMinimum->HasAccurateCovar())
1326 return 3;
1327 else if (fMinimum->HasMadePosDefCovar())
1328 return 2;
1329 else if (fMinimum->HasValidCovariance())
1330 return 1;
1331 else if (fMinimum->HasCovariance())
1332 return 0;
1333 return -1;
1334 } else {
1335 // case fMinimum is not available - use state information
1336 return fState.CovarianceStatus();
1337 }
1338 return 0;
1339}
1340
1342{
1343 // set trace object
1344 if (fMinimizer)
1345 fMinimizer->Builder().SetTraceObject(obj);
1346}
1347
1349{
1350 // set storage level
1351 if (fMinimizer)
1352 fMinimizer->Builder().SetStorageLevel(level);
1353}
1354
1355void Minuit2Minimizer::SetFCN(unsigned int nDim, std::unique_ptr<ROOT::Minuit2::FCNBase> fcn)
1356{
1357 fDim = nDim;
1358 fMinuitFCN = std::move(fcn);
1359}
1360
1361} // end namespace Minuit2
1362
1363} // end namespace ROOT
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Int_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.cxx:33
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
float xmin
float xmax
#define gROOT
Definition TROOT.h:411
Class, describing value, limits and step size of the parameters Provides functionality also to set/re...
FitMethodFunction class Interface for objective functions (like chi2 and likelihood used in the fit) ...
Documentation for the abstract class IBaseFunctionMultiDim.
Definition IFunction.h:63
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
Interface (abstract class) for multi-dimensional functions providing a gradient calculation.
Definition IFunction.h:239
Generic interface for defining configuration options of a numerical algorithm.
Definition IOptions.h:28
const IOptions * ExtraOptions() const
return extra options (NULL pointer if they are not present)
static ROOT::Math::IOptions * FindDefault(const char *name)
Find an extra options and return a nullptr if it is not existing.
double Tolerance() const
Absolute tolerance.
Definition Minimizer.h:317
unsigned int MaxFunctionCalls() const
Max number of function calls.
Definition Minimizer.h:311
double Precision() const
Precision of minimizer in the evaluation of the objective function.
Definition Minimizer.h:321
int fStatus
status of minimizer
Definition Minimizer.h:388
int Strategy() const
Strategy.
Definition Minimizer.h:324
double ErrorDef() const
Definition Minimizer.h:334
MinimizerOptions fOptions
minimizer options
Definition Minimizer.h:387
bool IsValidError() const
Definition Minimizer.h:337
int PrintLevel() const
Set print level.
Definition Minimizer.h:308
Adapter class to wrap user-provided functions into the FCNBase interface.
Definition FCNAdapter.h:37
Instantiates the seed generator and Minimum builder for the Fumili minimization method.
class holding the full result of the minimization; both internal and external (MnUserParameterState) ...
MinimumState keeps the information (position, Gradient, 2nd deriv, etc) after one minimization step (...
Class holding the result of Minos (lower and upper values) for a specific parameter.
Definition MinosError.h:25
bool AtUpperLimit() const
Definition MinosError.h:90
bool AtLowerMaxFcn() const
Definition MinosError.h:91
bool AtUpperMaxFcn() const
Definition MinosError.h:92
bool AtLowerLimit() const
Definition MinosError.h:89
bool ExamineMinimum(const ROOT::Minuit2::FunctionMinimum &min)
examine the minimum result
Minuit2Minimizer(ROOT::Minuit2::EMinimizerType type=ROOT::Minuit2::kMigrad)
Default constructor.
void SetStorageLevel(int level)
set storage level = 1 : store all iteration states (default) = 0 : store only first and last state to...
bool SetCovariance(std::span< const double > cov, unsigned int nrow) override
set initial covariance matrix
bool SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double, double) override
set upper/lower limited variable (override if minimizer supports them )
bool Contour(unsigned int i, unsigned int j, unsigned int &npoints, double *xi, double *xj) override
find the contour points (xi,xj) of the function for parameter i and j around the minimum The contour ...
virtual bool SetCovarianceDiag(std::span< const double > d2, unsigned int n) override
set initial second derivatives
bool IsFixedVariable(unsigned int ivar) const override
query if an existing variable is fixed (i.e.
bool SetVariableUpperLimit(unsigned int ivar, double upper) override
set the upper-limit of an already existing variable
bool SetVariableValues(const double *val) override
Set the values of all existing variables (array must be dimensioned to the size of the existing param...
bool SetVariable(unsigned int ivar, const std::string &name, double val, double step) override
set free variable
const double * Errors() const override
return errors at the minimum
void SetFunction(const ROOT::Math::IMultiGenFunction &func) override
set the function to minimize
bool SetVariableStepSize(unsigned int ivar, double step) override
set the step size of an already existing variable
bool GetCovMatrix(double *cov) const override
Fill the passed array with the covariance matrix elements if the variable is fixed or const the value...
bool ReleaseVariable(unsigned int ivar) override
release an existing variable
bool GetVariableSettings(unsigned int ivar, ROOT::Fit::ParameterSettings &varObj) const override
get variable settings in a variable object (like ROOT::Fit::ParamsSettings)
bool Hesse() override
perform a full calculation of the Hessian matrix for error calculation If a valid minimum exists the ...
bool GetMinosError(unsigned int i, double &errLow, double &errUp, int=0) override
get the minos error for parameter i, return false if Minos failed A minimizaiton must be performed be...
std::string VariableName(unsigned int ivar) const override
get name of variables (override if minimizer support storing of variable names)
int RunMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
bool SetVariableLimits(unsigned int ivar, double lower, double upper) override
set the limits of an already existing variable
double Correlation(unsigned int i, unsigned int j) const override
return correlation coefficient between variable i and j.
bool SetLowerLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double lower) override
set lower limit variable (override if minimizer supports them )
void SetTraceObject(MnTraceObject &obj)
set an object to trace operation for each iteration The object must be a (or inherit from) ROOT::Minu...
virtual const ROOT::Minuit2::ModularFunctionMinimizer * GetMinimizer() const
double CovMatrix(unsigned int i, unsigned int j) const override
return covariance matrix elements if the variable is fixed or const the value is zero The ordering of...
void SetMinimizerType(ROOT::Minuit2::EMinimizerType type)
std::unique_ptr< ROOT::Minuit2::ModularFunctionMinimizer > fMinimizer
bool SetVariableValue(unsigned int ivar, double val) override
set variable
bool Scan(unsigned int i, unsigned int &nstep, double *x, double *y, double xmin=0, double xmax=0) override
scan a parameter i around the minimum.
int VariableIndex(const std::string &name) const override
get index of variable given a variable given a name return -1 if variable is not found
bool SetUpperLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double upper) override
set upper limit variable (override if minimizer supports them )
ROOT::Minuit2::MnUserParameterState fState
bool SetVariableLowerLimit(unsigned int ivar, double lower) override
set the lower-limit of an already existing variable
bool FixVariable(unsigned int ivar) override
fix an existing variable
void SetHessianFunction(std::function< bool(std::span< const double >, double *)> hfunc) override
set the function implementing Hessian computation
bool Minimize() override
method to perform the minimization.
bool SetFixedVariable(unsigned int, const std::string &, double) override
set fixed variable (override if minimizer supports them )
bool GetHessianMatrix(double *h) const override
Fill the passed array with the Hessian matrix elements The Hessian matrix is the matrix of the second...
void PrintResults() override
return reference to the objective function virtual const ROOT::Math::IGenFunction & Function() const;
void Clear() override
Reset for consecutive minimization - implement if needed.
~Minuit2Minimizer() override
Destructor (no operations)
std::vector< double > GlobalCC() const override
get global correlation coefficient for the variable i.
void SetFCN(unsigned int nDim, std::unique_ptr< ROOT::Minuit2::FCNBase > fcn)
To set the function directly to a Minuit 2 function.
int CovMatrixStatus() const override
return the status of the covariance matrix status = -1 : not available (inversion failed or Hesse fai...
std::unique_ptr< ROOT::Minuit2::FCNBase > fMinuitFCN
std::unique_ptr< ROOT::Minuit2::FunctionMinimum > fMinimum
class for the individual Minuit Parameter with Name and number; contains the input numbers for the mi...
API class for Contours Error analysis (2-dim errors); minimization has to be done before and Minimum ...
Definition MnContours.h:35
const MnUserParameterState & State() const
Definition MnCross.h:88
class for global correlation coefficient
API class for calculating the numerical covariance matrix (== 2x Inverse Hessian == 2x Inverse 2nd de...
Definition MnHesse.h:41
API class for Minos Error analysis (asymmetric errors); minimization has to be done before and Minimu...
Definition MnMinos.h:33
MnCross Loval(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
Definition MnMinos.cxx:206
MnCross Upval(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
Definition MnMinos.cxx:200
Scans the values of FCN as a function of one Parameter and retains the best function and Parameter va...
const MnUserParameters & Parameters() const
void Debug(const Ts &... args)
Definition MnPrint.h:135
void Error(const Ts &... args)
Definition MnPrint.h:117
void Info(const Ts &... args)
Definition MnPrint.h:129
static int SetGlobalLevel(int level)
Definition MnPrint.cxx:111
void Warn(const Ts &... args)
Definition MnPrint.h:123
API class for defining four levels of strategies: low (0), medium (1), high (2), very high (>=3); act...
Definition MnStrategy.h:27
class which holds the external user and/or internal Minuit representation of the parameters and error...
void SetLimits(unsigned int, double, double)
const MnUserParameters & Parameters() const
unsigned int Index(const std::string &) const
const std::string & GetName(unsigned int) const
double Int2ext(unsigned int, double) const
MnGlobalCorrelationCoeff GlobalCC() const
const MinuitParameter & Parameter(unsigned int i) const
void Add(const std::string &name, double val, double err)
const char * Name(unsigned int) const
void AddCovariance(const MnUserCovariance &)
const std::vector< ROOT::Minuit2::MinuitParameter > & MinuitParameters() const
facade: forward interface of MnUserParameters and MnUserTransformation
unsigned int IntOfExt(unsigned int) const
const MnUserTransformation & Trafo() const
const MnUserCovariance & IntCovariance() const
const MnUserCovariance & Covariance() const
const_iterator begin() const
const_iterator end() const
Mother of all ROOT objects.
Definition TObject.h:41
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:421
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
void RestoreGlobalPrintLevel(int)
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4