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"
24#include "Minuit2/MnMigrad.h"
25#include "Minuit2/MnMinos.h"
26#include "Minuit2/MinosError.h"
27#include "Minuit2/MnHesse.h"
29#include "Minuit2/MnPrint.h"
36#include "Minuit2/MnContours.h"
39
40#include <cassert>
41#include <iostream>
42#include <algorithm>
43#include <functional>
44
45#ifdef USE_ROOT_ERROR
46#include "TError.h"
47#include "TROOT.h"
48#include "TMinuit2TraceObject.h"
49#endif
50
51namespace ROOT {
52
53namespace Minuit2 {
54
55// functions needed to control siwthc off of Minuit2 printing level
56#ifdef USE_ROOT_ERROR
58{
59 // switch off Minuit2 printing of INFO message (cut off is 1001)
61 if (prevErrorIgnoreLevel < 1001) {
62 gErrorIgnoreLevel = 1001;
64 }
65 return -2; // no op in this case
66}
67
69{
71}
72#else
73// dummy functions
75{
76 return -1;
77}
79{
80 return -1;
81}
83#endif
84
86 : fDim(0), fMinimizer(nullptr), fMinuitFCN(nullptr), fMinimum(nullptr)
87{
88 // Default constructor implementation depending on minimizer type
90}
91
92Minuit2Minimizer::Minuit2Minimizer(const char *type) : fDim(0), fMinimizer(nullptr), fMinuitFCN(nullptr), fMinimum(nullptr)
93{
94 // constructor from a string
95
96 std::string algoname(type);
97 // tolower() is not an std function (Windows)
98 std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int (*)(int))tolower);
99
101 if (algoname == "simplex")
103 if (algoname == "minimize")
105 if (algoname == "scan")
106 algoType = kScan;
107 if (algoname == "fumili" || algoname == "fumili2")
109 if (algoname == "bfgs")
111
113}
114
116{
117 // Set minimizer algorithm type
118 fUseFumili = false;
119 switch (type) {
121 // std::cout << "Minuit2Minimizer: minimize using MIGRAD " << std::endl;
123 return;
125 // std::cout << "Minuit2Minimizer: minimize using MIGRAD " << std::endl;
127 return;
129 // std::cout << "Minuit2Minimizer: minimize using SIMPLEX " << std::endl;
131 return;
136 fUseFumili = true;
137 return;
138 default:
139 // migrad minimizer
141 }
142}
143
145{
146 // Destructor implementation.
147 if (fMinimizer)
148 delete fMinimizer;
149 if (fMinuitFCN)
150 delete fMinuitFCN;
151 if (fMinimum)
152 delete fMinimum;
153}
154
156{
157 // delete the state in case of consecutive minimizations
159 // clear also the function minimum
160 if (fMinimum)
161 delete fMinimum;
162 fMinimum = nullptr;
163}
164
165// set variables
166
167bool Minuit2Minimizer::SetVariable(unsigned int ivar, const std::string &name, double val, double step)
168{
169 // set a free variable.
170 // Add the variable if not existing otherwise set value if exists already
171 // this is implemented in MnUserParameterState::Add
172 // if index is wrong (i.e. variable already exists but with a different index return false) but
173 // value is set for corresponding variable name
174
175 // std::cout << " add parameter " << name << " " << val << " step " << step << std::endl;
176 MnPrint print("Minuit2Minimizer::SetVariable", PrintLevel());
177
178 if (step <= 0) {
179 print.Info("Parameter", name, "has zero or invalid step size - consider it as constant");
180 fState.Add(name, val);
181 } else
182 fState.Add(name, val, step);
183
184 unsigned int minuit2Index = fState.Index(name);
185 if (minuit2Index != ivar) {
186 print.Warn("Wrong index", minuit2Index, "used for the variable", name);
188 return false;
189 }
191
192 return true;
193}
194
195/** set initial second derivatives
196 */
197bool Minuit2Minimizer::SetCovarianceDiag(std::span<const double> d2, unsigned int n)
198{
199 MnPrint print("Minuit2Minimizer::SetCovarianceDiag", PrintLevel());
200
201 std::vector<double> cov(n * (n + 1) / 2);
202
203 for (unsigned int i = 0; i < n; i++) {
204 for (unsigned int j = i; j < n; j++)
205 cov[i + j * (j + 1) / 2] = (i == j) ? d2[i] : 0.;
206 }
207
209}
210
211bool Minuit2Minimizer::SetCovariance(std::span<const double> cov, unsigned int nrow)
212{
213 MnPrint print("Minuit2Minimizer::SetCovariance", PrintLevel());
214
216
217 return true;
218}
219
220bool Minuit2Minimizer::SetLowerLimitedVariable(unsigned int ivar, const std::string &name, double val, double step,
221 double lower)
222{
223 // add a lower bounded variable
224 if (!SetVariable(ivar, name, val, step))
225 return false;
227 return true;
228}
229
230bool Minuit2Minimizer::SetUpperLimitedVariable(unsigned int ivar, const std::string &name, double val, double step,
231 double upper)
232{
233 // add a upper bounded variable
234 if (!SetVariable(ivar, name, val, step))
235 return false;
237 return true;
238}
239
240bool Minuit2Minimizer::SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step,
241 double lower, double upper)
242{
243 // add a double bound variable
244 if (!SetVariable(ivar, name, val, step))
245 return false;
247 return true;
248}
249
250bool Minuit2Minimizer::SetFixedVariable(unsigned int ivar, const std::string &name, double val)
251{
252 // add a fixed variable
253 // need a step size otherwise treated as a constant
254 // use 10%
255 double step = (val != 0) ? 0.1 * std::abs(val) : 0.1;
256 if (!SetVariable(ivar, name, val, step)) {
258 }
259 fState.Fix(ivar);
260 return true;
261}
262
263std::string Minuit2Minimizer::VariableName(unsigned int ivar) const
264{
265 // return the variable name
266 if (ivar >= fState.MinuitParameters().size())
267 return std::string();
268 return fState.GetName(ivar);
269}
270
271int Minuit2Minimizer::VariableIndex(const std::string &name) const
272{
273 // return the variable index
274 // check if variable exist
275 return fState.Trafo().FindIndex(name);
276}
277
278bool Minuit2Minimizer::SetVariableValue(unsigned int ivar, double val)
279{
280 // set value for variable ivar (only for existing parameters)
281 if (ivar >= fState.MinuitParameters().size())
282 return false;
283 fState.SetValue(ivar, val);
284 return true;
285}
286
288{
289 // set value for variable ivar (only for existing parameters)
290 unsigned int n = fState.MinuitParameters().size();
291 if (n == 0)
292 return false;
293 for (unsigned int ivar = 0; ivar < n; ++ivar)
295 return true;
296}
297
298bool Minuit2Minimizer::SetVariableStepSize(unsigned int ivar, double step)
299{
300 // set the step-size of an existing variable
301 // parameter must exist or return false
302 if (ivar >= fState.MinuitParameters().size())
303 return false;
304 fState.SetError(ivar, step);
305 return true;
306}
307
309{
310 // set the limits of an existing variable
311 // parameter must exist or return false
312 if (ivar >= fState.MinuitParameters().size())
313 return false;
315 return true;
316}
318{
319 // set the limits of an existing variable
320 // parameter must exist or return false
321 if (ivar >= fState.MinuitParameters().size())
322 return false;
324 return true;
325}
326
327bool Minuit2Minimizer::SetVariableLimits(unsigned int ivar, double lower, double upper)
328{
329 // set the limits of an existing variable
330 // parameter must exist or return false
331 if (ivar >= fState.MinuitParameters().size())
332 return false;
334 return true;
335}
336
338{
339 // Fix an existing variable
340 if (ivar >= fState.MinuitParameters().size())
341 return false;
342 fState.Fix(ivar);
343 return true;
344}
345
347{
348 // Release an existing variable
349 if (ivar >= fState.MinuitParameters().size())
350 return false;
352 return true;
353}
354
356{
357 // query if variable is fixed
358 if (ivar >= fState.MinuitParameters().size()) {
359 MnPrint print("Minuit2Minimizer", PrintLevel());
360 print.Error("Wrong variable index");
361 return false;
362 }
363 return (fState.Parameter(ivar).IsFixed() || fState.Parameter(ivar).IsConst());
364}
365
367{
368 // retrieve variable settings (all set info on the variable)
369 if (ivar >= fState.MinuitParameters().size()) {
370 MnPrint print("Minuit2Minimizer", PrintLevel());
371 print.Error("Wrong variable index");
372 return false;
373 }
374 const MinuitParameter &par = fState.Parameter(ivar);
375 varObj.Set(par.Name(), par.Value(), par.Error());
376 if (par.HasLowerLimit()) {
377 if (par.HasUpperLimit()) {
378 varObj.SetLimits(par.LowerLimit(), par.UpperLimit());
379 } else {
380 varObj.SetLowerLimit(par.LowerLimit());
381 }
382 } else if (par.HasUpperLimit()) {
383 varObj.SetUpperLimit(par.UpperLimit());
384 }
385 if (par.IsConst() || par.IsFixed())
386 varObj.Fix();
387 return true;
388}
389
391{
392 // set function to be minimized
393 if (fMinuitFCN)
394 delete fMinuitFCN;
395 fDim = func.NDim();
396 const bool hasGrad = func.HasGradient();
397 if (!fUseFumili) {
400 } else {
401 if(hasGrad) {
402 // for Fumili the fit method function interface is required
403 auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodGradFunction *>(&func);
404 if (!fcnfunc) {
405 MnPrint print("Minuit2Minimizer", PrintLevel());
406 print.Error("Wrong Fit method function for Fumili");
407 return;
408 }
410 } else {
411 // for Fumili the fit method function interface is required
412 auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodFunction *>(&func);
413 if (!fcnfunc) {
414 MnPrint print("Minuit2Minimizer", PrintLevel());
415 print.Error("Wrong Fit method function for Fumili");
416 return;
417 }
419 }
420 }
421}
422
423void Minuit2Minimizer::SetHessianFunction(std::function<bool(std::span<const double>, double *)> hfunc)
424{
425 // for Fumili not supported for the time being
426 if (fUseFumili) return;
428 if (!fcn) return;
429 fcn->SetHessianFunction(hfunc);
430}
431
432namespace {
433
435{
437 // set strategy and add extra options if needed
439 if (!minuit2Opt) {
441 }
442 if (!minuit2Opt) {
443 return st;
444 }
445 auto customize = [&minuit2Opt](const char *name, auto val) {
446 minuit2Opt->GetValue(name, val);
447 return val;
448 };
449 // set extra options
450 st.SetGradientNCycles(customize("GradientNCycles", int(st.GradientNCycles())));
451 st.SetHessianNCycles(customize("HessianNCycles", int(st.HessianNCycles())));
452 st.SetHessianGradientNCycles(customize("HessianGradientNCycles", int(st.HessianGradientNCycles())));
453
454 st.SetGradientTolerance(customize("GradientTolerance", st.GradientTolerance()));
455 st.SetGradientStepTolerance(customize("GradientStepTolerance", st.GradientStepTolerance()));
456 st.SetHessianStepTolerance(customize("HessianStepTolerance", st.HessianStepTolerance()));
457 st.SetHessianG2Tolerance(customize("HessianG2Tolerance", st.HessianG2Tolerance()));
458
459 return st;
460}
461
462} // namespace
463
465{
466 // perform the minimization
467 // store a copy of FunctionMinimum
468
469 MnPrint print("Minuit2Minimizer::Minimize", PrintLevel());
470
471 if (!fMinuitFCN) {
472 print.Error("FCN function has not been set");
473 return false;
474 }
475
476 assert(GetMinimizer() != nullptr);
477
478 // delete result of previous minimization
479 if (fMinimum)
480 delete fMinimum;
481 fMinimum = nullptr;
482
483 const int maxfcn = MaxFunctionCalls();
484 const double tol = Tolerance();
485 const int strategyLevel = Strategy();
487
488 const int printLevel = PrintLevel();
489 print.Debug("Minuit print level is", printLevel);
490 if (PrintLevel() >= 1) {
491 // print the real number of maxfcn used (defined in ModularFunctionMinimizer)
492 int maxfcn_used = maxfcn;
493 if (maxfcn_used == 0) {
494 int nvar = fState.VariableParameters();
495 maxfcn_used = 200 + 100 * nvar + 5 * nvar * nvar;
496 }
497 std::cout << "Minuit2Minimizer: Minimize with max-calls " << maxfcn_used << " convergence for edm < " << tol
498 << " strategy " << strategyLevel << std::endl;
499 }
500
501 // internal minuit messages
502 fMinimizer->Builder().SetPrintLevel(printLevel);
503
504 // switch off Minuit2 printing
505 const int prev_level = (printLevel <= 0) ? TurnOffPrintInfoLevel() : -2;
507
508 // set the precision if needed
509 if (Precision() > 0)
511
512 // add extra options if needed
514 if (!minuit2Opt) {
516 }
517 if (minuit2Opt) {
518 // set extra options
519 int storageLevel = 1;
520 bool ret = minuit2Opt->GetValue("StorageLevel", storageLevel);
521 if (ret)
523
524 // fumili options
525 if (fUseFumili) {
526 std::string fumiliMethod;
527 ret = minuit2Opt->GetValue("FumiliMethod", fumiliMethod);
528 if (ret) {
530 if (fumiliMinimizer)
531 fumiliMinimizer->SetMethod(fumiliMethod);
532 }
533 }
534
535 if (printLevel > 0) {
536 std::cout << "Minuit2Minimizer::Minuit - Changing default options" << std::endl;
537 minuit2Opt->Print();
538 }
539 }
540
541 // set a minimizer tracer object (default for printlevel=10, from gROOT for printLevel=11)
542 // use some special print levels
543 MnTraceObject *traceObj = nullptr;
544#ifdef USE_ROOT_ERROR
545 if (printLevel == 10 && gROOT) {
546 TObject *obj = gROOT->FindObject("Minuit2TraceObject");
547 traceObj = dynamic_cast<ROOT::Minuit2::MnTraceObject *>(obj);
548 if (traceObj) {
549 // need to remove from the list
550 gROOT->Remove(obj);
551 }
552 }
553 if (printLevel == 20 || printLevel == 30 || printLevel == 40 || (printLevel >= 20000 && printLevel < 30000)) {
554 int parNumber = printLevel - 20000;
555 if (printLevel == 20)
556 parNumber = -1;
557 if (printLevel == 30)
558 parNumber = -2;
559 if (printLevel == 40)
560 parNumber = 0;
562 }
563#endif
564 if (printLevel == 100 || (printLevel >= 10000 && printLevel < 20000)) {
565 int parNumber = printLevel - 10000;
567 }
568 if (traceObj) {
569 traceObj->Init(fState);
571 }
572
574
577
578 // check if Hesse needs to be run. We do it when is requested (IsValidError() == true , set by SetParabError(true) in fitConfig)
579 // (IsValidError() means the flag to get correct error from the Minimizer is set (Minimizer::SetValidError())
580 // AND when we have a valid minimum,
581 // AND when the the current covariance matrix is estimated using the iterative approximation (Dcovar != 0 , i.e. Hesse has not computed before)
582 if (fMinimum->IsValid() && IsValidError() && fMinimum->State().Error().Dcovar() != 0) {
583 // run Hesse (Hesse will add results in the last state of fMinimum
585 hesse(*fMinuitFCN, *fMinimum, maxfcn);
586 }
587
588 // -2 is the highest low invalid value for gErrorIgnoreLevel
589 if (prev_level > -2)
592
593 // copy minimum state (parameter values and errors)
595 bool ok = ExamineMinimum(*fMinimum);
596 // fMinimum = 0;
597
598 // delete trace object if it was constructed
599 if (traceObj) {
600 delete traceObj;
601 }
602 return ok;
603}
604
606{
607 /// study the function minimum
608
609 // debug ( print all the states)
610 int debugLevel = PrintLevel();
611 if (debugLevel >= 3) {
612
613 std::span<const ROOT::Minuit2::MinimumState> iterationStates = min.States();
614 std::cout << "Number of iterations " << iterationStates.size() << std::endl;
615 for (unsigned int i = 0; i < iterationStates.size(); ++i) {
616 // std::cout << iterationStates[i] << std::endl;
618 std::cout << "----------> Iteration " << i << std::endl;
619 int pr = std::cout.precision(12);
620 std::cout << " FVAL = " << st.Fval() << " Edm = " << st.Edm() << " Nfcn = " << st.NFcn()
621 << std::endl;
622 std::cout.precision(pr);
623 if (st.HasCovariance())
624 std::cout << " Error matrix change = " << st.Error().Dcovar() << std::endl;
625 if (st.HasParameters()) {
626 std::cout << " Parameters : ";
627 // need to transform from internal to external
628 for (int j = 0; j < st.size(); ++j)
629 std::cout << " p" << j << " = " << fState.Int2ext(j, st.Vec()(j));
630 std::cout << std::endl;
631 }
632 }
633 }
634
635 fStatus = 0;
636 std::string txt;
637 if (!min.HasPosDefCovar()) {
638 // this happens normally when Hesse failed
639 // it can happen in case MnSeed failed (see ROOT-9522)
640 txt = "Covar is not pos def";
641 fStatus = 5;
642 }
643 if (min.HasMadePosDefCovar()) {
644 txt = "Covar was made pos def";
645 fStatus = 1;
646 }
647 if (min.HesseFailed()) {
648 txt = "Hesse is not valid";
649 fStatus = 2;
650 }
651 if (min.IsAboveMaxEdm()) {
652 txt = "Edm is above max";
653 fStatus = 3;
654 }
655 if (min.HasReachedCallLimit()) {
656 txt = "Reached call limit";
657 fStatus = 4;
658 }
659
660 MnPrint print("Minuit2Minimizer::Minimize", debugLevel);
661 bool validMinimum = min.IsValid();
662 if (validMinimum) {
663 // print a warning message in case something is not ok
664 // this for example is case when Covar was made posdef and fStatus=3
665 if (fStatus != 0 && debugLevel > 0)
666 print.Warn(txt);
667 } else {
668 // minimum is not valid when state is not valid and edm is over max or has passed call limits
669 if (fStatus == 0) {
670 // this should not happen
671 txt = "unknown failure";
672 fStatus = 6;
673 }
674 print.Warn("Minimization did NOT converge,", txt);
675 }
676
677 if (debugLevel >= 1)
678 PrintResults();
679
680 // set the minimum values in the fValues vector
681 std::span<const MinuitParameter> paramsObj = fState.MinuitParameters();
682 if (paramsObj.empty())
683 return false;
684 assert(fDim == paramsObj.size());
685 // re-size vector if it has changed after a new minimization
686 if (fValues.size() != fDim)
687 fValues.resize(fDim);
688 for (unsigned int i = 0; i < fDim; ++i) {
689 fValues[i] = paramsObj[i].Value();
690 }
691
692 return validMinimum;
693}
694
696{
697 // print results of minimization
698 if (!fMinimum)
699 return;
700 if (fMinimum->IsValid()) {
701 // valid minimum
702 std::cout << "Minuit2Minimizer : Valid minimum - status = " << fStatus << std::endl;
703 int pr = std::cout.precision(18);
704 std::cout << "FVAL = " << fState.Fval() << std::endl;
705 std::cout << "Edm = " << fState.Edm() << std::endl;
706 std::cout.precision(pr);
707 std::cout << "Nfcn = " << fState.NFcn() << std::endl;
708 for (unsigned int i = 0; i < fState.MinuitParameters().size(); ++i) {
709 const MinuitParameter &par = fState.Parameter(i);
710 std::cout << par.Name() << "\t = " << par.Value() << "\t ";
711 if (par.IsFixed())
712 std::cout << "(fixed)" << std::endl;
713 else if (par.IsConst())
714 std::cout << "(const)" << std::endl;
715 else if (par.HasLimits())
716 std::cout << "+/- " << par.Error() << "\t(limited)" << std::endl;
717 else
718 std::cout << "+/- " << par.Error() << std::endl;
719 }
720 } else {
721 std::cout << "Minuit2Minimizer : Invalid minimum - status = " << fStatus << std::endl;
722 std::cout << "FVAL = " << fState.Fval() << std::endl;
723 std::cout << "Edm = " << fState.Edm() << std::endl;
724 std::cout << "Nfcn = " << fState.NFcn() << std::endl;
725 }
726}
727
728const double *Minuit2Minimizer::Errors() const
729{
730 // return error at minimum (set to zero for fixed and constant params)
731 std::span<const MinuitParameter> paramsObj = fState.MinuitParameters();
732 if (paramsObj.empty())
733 return nullptr;
734 assert(fDim == paramsObj.size());
735 // be careful for multiple calls of this function. I will redo an allocation here
736 // only when size of vectors has changed (e.g. after a new minimization)
737 if (fErrors.size() != fDim)
738 fErrors.resize(fDim);
739 for (unsigned int i = 0; i < fDim; ++i) {
740 const MinuitParameter &par = paramsObj[i];
741 if (par.IsFixed() || par.IsConst())
742 fErrors[i] = 0;
743 else
744 fErrors[i] = par.Error();
745 }
746
747 return &fErrors.front();
748}
749
750double Minuit2Minimizer::CovMatrix(unsigned int i, unsigned int j) const
751{
752 // get value of covariance matrices (transform from external to internal indices)
753 if (i >= fDim || j >= fDim)
754 return 0;
755 if (!fState.HasCovariance())
756 return 0; // no info available when minimization has failed
757 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
758 return 0;
759 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
760 return 0;
761 unsigned int k = fState.IntOfExt(i);
762 unsigned int l = fState.IntOfExt(j);
763 return fState.Covariance()(k, l);
764}
765
767{
768 // get value of covariance matrices
769 if (!fState.HasCovariance())
770 return false; // no info available when minimization has failed
771 for (unsigned int i = 0; i < fDim; ++i) {
772 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst()) {
773 for (unsigned int j = 0; j < fDim; ++j) {
774 cov[i * fDim + j] = 0;
775 }
776 } else {
777 unsigned int l = fState.IntOfExt(i);
778 for (unsigned int j = 0; j < fDim; ++j) {
779 // could probably speed up this loop (if needed)
780 int k = i * fDim + j;
781 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
782 cov[k] = 0;
783 else {
784 // need to transform from external to internal indices)
785 // for taking care of the removed fixed row/columns in the Minuit2 representation
786 unsigned int m = fState.IntOfExt(j);
787 cov[k] = fState.Covariance()(l, m);
788 }
789 }
790 }
791 }
792 return true;
793}
794
796{
797 // get value of Hessian matrix
798 // this is the second derivative matrices
799 if (!fState.HasCovariance())
800 return false; // no info available when minimization has failed
801 for (unsigned int i = 0; i < fDim; ++i) {
802 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst()) {
803 for (unsigned int j = 0; j < fDim; ++j) {
804 hess[i * fDim + j] = 0;
805 }
806 } else {
807 unsigned int l = fState.IntOfExt(i);
808 for (unsigned int j = 0; j < fDim; ++j) {
809 // could probably speed up this loop (if needed)
810 int k = i * fDim + j;
811 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
812 hess[k] = 0;
813 else {
814 // need to transform from external to internal indices)
815 // for taking care of the removed fixed row/columns in the Minuit2 representation
816 unsigned int m = fState.IntOfExt(j);
817 hess[k] = fState.Hessian()(l, m);
818 }
819 }
820 }
821 }
822
823 return true;
824}
825
826double Minuit2Minimizer::Correlation(unsigned int i, unsigned int j) const
827{
828 // get correlation between parameter i and j
829 if (i >= fDim || j >= fDim)
830 return 0;
831 if (!fState.HasCovariance())
832 return 0; // no info available when minimization has failed
833 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
834 return 0;
835 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
836 return 0;
837 unsigned int k = fState.IntOfExt(i);
838 unsigned int l = fState.IntOfExt(j);
839 double cij = fState.IntCovariance()(k, l);
840 double tmp = std::sqrt(std::abs(fState.IntCovariance()(k, k) * fState.IntCovariance()(l, l)));
841 if (tmp > 0)
842 return cij / tmp;
843 return 0;
844}
845
846double Minuit2Minimizer::GlobalCC(unsigned int i) const
847{
848 // get global correlation coefficient for the parameter i. This is a number between zero and one which gives
849 // the correlation between the i-th parameter and that linear combination of all other parameters which
850 // is most strongly correlated with i.
851
852 if (i >= fDim)
853 return 0;
854 // no info available when minimization has failed or has some problems
855 if (!fState.HasGlobalCC())
856 return 0;
857 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
858 return 0;
859 unsigned int k = fState.IntOfExt(i);
860 return fState.GlobalCC().GlobalCC()[k];
861}
862
863bool Minuit2Minimizer::GetMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
864{
865 // return the minos error for parameter i
866 // if a minimum does not exist an error is returned
867 // runopt is a flag which specifies if only lower or upper error needs to be run
868 // if runopt = 0 both, = 1 only lower, + 2 only upper errors
869 errLow = 0;
870 errUp = 0;
871
873
874 // need to know if parameter is const or fixed
875 if (fState.Parameter(i).IsConst() || fState.Parameter(i).IsFixed()) {
876 return false;
877 }
878
879 MnPrint print("Minuit2Minimizer::GetMinosError", PrintLevel());
880
881 // to run minos I need function minimum class
882 // redo minimization from current state
883 // ROOT::Minuit2::FunctionMinimum min =
884 // GetMinimizer()->Minimize(*GetFCN(),fState, ROOT::Minuit2::MnStrategy(strategy), MaxFunctionCalls(),
885 // Tolerance());
886 // fState = min.UserState();
887 if (fMinimum == nullptr) {
888 print.Error("Failed - no function minimum existing");
889 return false;
890 }
891
892 if (!fMinimum->IsValid()) {
893 print.Error("Failed - invalid function minimum");
894 return false;
895 }
896
898 // if error def has been changed update it in FunctionMinimum
899 if (ErrorDef() != fMinimum->Up())
901
903
904 // run again the Minimization in case of a new minimum
905 // bit 8 is set
906 if ((mstatus & 8) != 0) {
907 print.Info([&](std::ostream &os) {
908 os << "Found a new minimum: run again the Minimization starting from the new point";
909 os << "\nFVAL = " << fState.Fval();
910 for (auto &par : fState.MinuitParameters()) {
911 os << '\n' << par.Name() << "\t = " << par.Value();
912 }
913 });
914 // release parameter that was fixed in the returned state from Minos
916 bool ok = Minimize();
917 if (!ok)
918 return false;
919 // run again Minos from new Minimum (also lower error needs to be re-computed)
920 print.Info("Run now again Minos from the new found Minimum");
922
923 // do not reset new minimum bit to flag for other parameters
924 mstatus |= 8;
925 }
926
927 fStatus += 10 * mstatus;
929
930 bool isValid = ((mstatus & 1) == 0) && ((mstatus & 2) == 0);
931 return isValid;
932}
933
934int Minuit2Minimizer::RunMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
935{
936
937 bool runLower = runopt != 2;
938 bool runUpper = runopt != 1;
939
940 const int debugLevel = PrintLevel();
941 // switch off Minuit2 printing
942 const int prev_level = (debugLevel <= 0) ? TurnOffPrintInfoLevel() : -2;
944
945 // set the precision if needed
946 if (Precision() > 0)
948
950
951 // run MnCross
952 MnCross low;
953 MnCross up;
954 int maxfcn = MaxFunctionCalls();
955 double tol = Tolerance();
956
957 const char *par_name = fState.Name(i);
958
959 // now input tolerance for migrad calls inside Minos (MnFunctionCross)
960 // before it was fixed to 0.05
961 // cut off too small tolerance (they are not needed)
962 tol = std::max(tol, 0.01);
963
964 // get the real number of maxfcn used (defined in MnMinos) to be printed
965 int maxfcn_used = maxfcn;
966 if (maxfcn_used == 0) {
967 int nvar = fState.VariableParameters();
968 maxfcn_used = 2 * (nvar + 1) * (200 + 100 * nvar + 5 * nvar * nvar);
969 }
970
971 if (runLower) {
972 if (debugLevel >= 1) {
973 std::cout << "************************************************************************************************"
974 "******\n";
975 std::cout << "Minuit2Minimizer::GetMinosError - Run MINOS LOWER error for parameter #" << i << " : "
976 << par_name << " using max-calls " << maxfcn_used << ", tolerance " << tol << std::endl;
977 }
978 low = minos.Loval(i, maxfcn, tol);
979 }
980 if (runUpper) {
981 if (debugLevel >= 1) {
982 std::cout << "************************************************************************************************"
983 "******\n";
984 std::cout << "Minuit2Minimizer::GetMinosError - Run MINOS UPPER error for parameter #" << i << " : "
985 << par_name << " using max-calls " << maxfcn_used << ", tolerance " << tol << std::endl;
986 }
987 up = minos.Upval(i, maxfcn, tol);
988 }
989
990 ROOT::Minuit2::MinosError me(i, fMinimum->UserState().Value(i), low, up);
991
992 // restore global print level
993 if (prev_level > -2)
996
997 // debug result of Minos
998 // print error message in Minos
999 // Note that the only invalid condition can happen when the (npar-1) minimization fails
1000 // The error is also invalid when the maximum number of calls is reached or a new function minimum is found
1001 // in case of the parameter at the limit the error is not invalid.
1002 // When the error is invalid the returned error is the Hessian error.
1003
1004 if (debugLevel > 0) {
1005 if (runLower) {
1006 if (!me.LowerValid())
1007 std::cout << "Minos: Invalid lower error for parameter " << par_name << std::endl;
1008 if (me.AtLowerLimit())
1009 std::cout << "Minos: Parameter : " << par_name << " is at Lower limit; error is " << me.Lower()
1010 << std::endl;
1011 if (me.AtLowerMaxFcn())
1012 std::cout << "Minos: Maximum number of function calls exceeded when running for lower error for parameter "
1013 << par_name << std::endl;
1014 if (me.LowerNewMin())
1015 std::cout << "Minos: New Minimum found while running Minos for lower error for parameter " << par_name
1016 << std::endl;
1017
1018 if (debugLevel >= 1 && me.LowerValid())
1019 std::cout << "Minos: Lower error for parameter " << par_name << " : " << me.Lower() << std::endl;
1020 }
1021 if (runUpper) {
1022 if (!me.UpperValid())
1023 std::cout << "Minos: Invalid upper error for parameter " << par_name << std::endl;
1024 if (me.AtUpperLimit())
1025 std::cout << "Minos: Parameter " << par_name << " is at Upper limit; error is " << me.Upper() << std::endl;
1026 if (me.AtUpperMaxFcn())
1027 std::cout << "Minos: Maximum number of function calls exceeded when running for upper error for parameter "
1028 << par_name << std::endl;
1029 if (me.UpperNewMin())
1030 std::cout << "Minos: New Minimum found while running Minos for upper error for parameter " << par_name
1031 << std::endl;
1032
1033 if (debugLevel >= 1 && me.UpperValid())
1034 std::cout << "Minos: Upper error for parameter " << par_name << " : " << me.Upper() << std::endl;
1035 }
1036 }
1037
1038 MnPrint print("RunMinosError", PrintLevel());
1039 bool lowerInvalid = (runLower && !me.LowerValid());
1040 bool upperInvalid = (runUpper && !me.UpperValid());
1041 // print message in case of invalid error also in printLevel0
1042 if (lowerInvalid) {
1043 print.Warn("Invalid lower error for parameter", fMinimum->UserState().Name(i));
1044 }
1045 if (upperInvalid) {
1046 print.Warn("Invalid upper error for parameter", fMinimum->UserState().Name(i));
1047 }
1048 // print also case it is lower/upper limit
1049 if (me.AtLowerLimit()) {
1050 print.Warn("Lower error for parameter", fMinimum->UserState().Name(i), "is at the Lower limit!");
1051 }
1052 if (me.AtUpperLimit()) {
1053 print.Warn("Upper error for parameter", fMinimum->UserState().Name(i), "is at the Upper limit!");
1054 }
1055
1056 int mstatus = 0;
1057 if (lowerInvalid || upperInvalid) {
1058 // set status according to bit
1059 // bit 1: lower invalid Minos errors
1060 // bit 2: upper invalid Minos error
1061 // bit 3: invalid because max FCN
1062 // bit 4 : invalid because a new minimum has been found
1063 if (lowerInvalid) {
1064 mstatus |= 1;
1065 if (me.AtLowerMaxFcn())
1066 mstatus |= 4;
1067 if (me.LowerNewMin())
1068 mstatus |= 8;
1069 }
1070 if (upperInvalid) {
1071 mstatus |= 2;
1072 if (me.AtUpperMaxFcn())
1073 mstatus |= 4;
1074 if (me.UpperNewMin())
1075 mstatus |= 8;
1076 }
1077 }
1078 // case upper/lower limit
1079 if (me.AtUpperLimit() || me.AtLowerLimit())
1080 mstatus |= 16;
1081
1082 if (runLower)
1083 errLow = me.Lower();
1084 if (runUpper)
1085 errUp = me.Upper();
1086
1087 // in case of new minimum found update also the minimum state
1088 if ((runLower && me.LowerNewMin()) && (runUpper && me.UpperNewMin())) {
1089 // take state with lower function value
1090 fState = (low.State().Fval() < up.State().Fval()) ? low.State() : up.State();
1091 } else if (runLower && me.LowerNewMin()) {
1092 fState = low.State();
1093 } else if (runUpper && me.UpperNewMin()) {
1094 fState = up.State();
1095 }
1096
1097 return mstatus;
1098}
1099
1100bool Minuit2Minimizer::Scan(unsigned int ipar, unsigned int &nstep, double *x, double *y, double xmin, double xmax)
1101{
1102 // scan a parameter (variable) around the minimum value
1103 // the parameters must have been set before
1104 // if xmin=0 && xmax == 0 by default scan around 2 sigma of the error
1105 // if the errors are also zero then scan from min and max of parameter range
1106
1107 MnPrint print("Minuit2Minimizer::Scan", PrintLevel());
1108 if (!fMinuitFCN) {
1109 print.Error("Function must be set before using Scan");
1110 return false;
1111 }
1112
1113 if (ipar > fState.MinuitParameters().size()) {
1114 print.Error("Invalid number; minimizer variables must be set before using Scan");
1115 return false;
1116 }
1117
1118 // switch off Minuit2 printing
1119 const int prev_level = (PrintLevel() <= 0) ? TurnOffPrintInfoLevel() : -2;
1121
1122 // set the precision if needed
1123 if (Precision() > 0)
1125
1127 double amin = scan.Fval(); // fcn value of the function before scan
1128
1129 // first value is param value
1130 std::vector<std::pair<double, double>> result = scan(ipar, nstep - 1, xmin, xmax);
1131
1132 // restore global print level
1133 if (prev_level > -2)
1136
1137 if (result.size() != nstep) {
1138 print.Error("Invalid result from MnParameterScan");
1139 return false;
1140 }
1141 // sort also the returned points in x
1142 std::sort(result.begin(), result.end());
1143
1144 for (unsigned int i = 0; i < nstep; ++i) {
1145 x[i] = result[i].first;
1146 y[i] = result[i].second;
1147 }
1148
1149 // what to do if a new minimum has been found ?
1150 // use that as new minimum
1151 if (scan.Fval() < amin) {
1152 print.Info("A new minimum has been found");
1153 fState.SetValue(ipar, scan.Parameters().Value(ipar));
1154 }
1155
1156 return true;
1157}
1158
1159bool Minuit2Minimizer::Contour(unsigned int ipar, unsigned int jpar, unsigned int &npoints, double *x, double *y)
1160{
1161 // contour plot for parameter i and j
1162 // need a valid FunctionMinimum otherwise exits
1163
1164 MnPrint print("Minuit2Minimizer::Contour", PrintLevel());
1165
1166 if (fMinimum == nullptr) {
1167 print.Error("No function minimum existing; must minimize function before");
1168 return false;
1169 }
1170
1171 if (!fMinimum->IsValid()) {
1172 print.Error("Invalid function minimum");
1173 return false;
1174 }
1176
1178 // if error def has been changed update it in FunctionMinimum
1179 if (ErrorDef() != fMinimum->Up()) {
1181 }
1182
1183 print.Info("Computing contours at level -", ErrorDef());
1184
1185 // switch off Minuit2 printing (for level of 0,1)
1186 const int prev_level = (PrintLevel() <= 1) ? TurnOffPrintInfoLevel() : -2;
1188
1189 // set the precision if needed
1190 if (Precision() > 0)
1192
1193 // eventually one should specify tolerance in contours
1194 MnContours contour(*fMinuitFCN, *fMinimum, Strategy());
1195
1196 // restore global print level
1197 if (prev_level > -2)
1200
1201 // compute the contour
1202 std::vector<std::pair<double, double>> result = contour(ipar, jpar, npoints);
1203 if (result.size() != npoints) {
1204 print.Error("Invalid result from MnContours");
1205 return false;
1206 }
1207 for (unsigned int i = 0; i < npoints; ++i) {
1208 x[i] = result[i].first;
1209 y[i] = result[i].second;
1210 }
1211 print.Info([&](std::ostream &os) {
1212 os << " Computed " << npoints << " points at level " << ErrorDef();
1213 for (unsigned int i = 0; i < npoints; i++) {
1214 if (i %5 == 0) os << std::endl;
1215 os << "( " << x[i] << ", " << y[i] << ") ";
1216 }
1217 os << std::endl << std::endl;
1218 });
1219
1220 return true;
1221}
1222
1224{
1225 // find Hessian (full second derivative calculations)
1226 // the contained state will be updated with the Hessian result
1227 // in case a function minimum exists and is valid the result will be
1228 // appended in the function minimum
1229
1230 MnPrint print("Minuit2Minimizer::Hesse", PrintLevel());
1231
1232 if (!fMinuitFCN) {
1233 print.Error("FCN function has not been set");
1234 return false;
1235 }
1236
1237 const int maxfcn = MaxFunctionCalls();
1238 print.Info("Using max-calls", maxfcn);
1239
1240 // switch off Minuit2 printing
1241 const int prev_level = (PrintLevel() <= 0) ? TurnOffPrintInfoLevel() : -2;
1243
1244 // set the precision if needed
1245 if (Precision() > 0)
1247
1249
1250 // case when function minimum exists
1251 if (fMinimum) {
1252
1253 // if (PrintLevel() >= 3) {
1254 // std::cout << "Minuit2Minimizer::Hesse - State before running Hesse " << std::endl;
1255 // std::cout << fState << std::endl;
1256 // }
1257
1258 // run hesse and function minimum will be updated with Hesse result
1259 hesse(*fMinuitFCN, *fMinimum, maxfcn);
1260 // update user state
1262 }
1263
1264 else {
1265 // run Hesse on point stored in current state (independent of function minimum validity)
1266 // (x == 0)
1267 fState = hesse(*fMinuitFCN, fState, maxfcn);
1268 }
1269
1270 // restore global print level
1271 if (prev_level > -2)
1274
1275 if (PrintLevel() >= 3) {
1276 std::cout << "Minuit2Minimizer::Hesse - State returned from Hesse " << std::endl;
1277 std::cout << fState << std::endl;
1278 }
1279
1281 std::string covStatusType = "not valid";
1282 if (covStatus == 1)
1283 covStatusType = "approximate";
1284 if (covStatus == 2)
1285 covStatusType = "full but made positive defined";
1286 if (covStatus == 3)
1287 covStatusType = "accurate";
1288 if (covStatus == 0)
1289 covStatusType = "full but not positive defined";
1290
1291 if (!fState.HasCovariance()) {
1292 // if false means error is not valid and this is due to a failure in Hesse
1293 // update minimizer error status
1294 int hstatus = 4;
1295 // information on error state can be retrieved only if fMinimum is available
1296 if (fMinimum) {
1297 if (fMinimum->Error().HesseFailed())
1298 hstatus = 1;
1299 if (fMinimum->Error().InvertFailed())
1300 hstatus = 2;
1301 else if (!(fMinimum->Error().IsPosDef()))
1302 hstatus = 3;
1303 }
1304
1305 print.Warn("Hesse failed - matrix is", covStatusType);
1306 print.Warn(hstatus);
1307
1308 fStatus += 100 * hstatus;
1309 return false;
1310 }
1311
1312 print.Info("Hesse is valid - matrix is", covStatusType);
1313
1314 return true;
1315}
1316
1318{
1319 // return status of covariance matrix
1320 //-1 - not available (inversion failed or Hesse failed)
1321 // 0 - available but not positive defined
1322 // 1 - covariance only approximate
1323 // 2 full matrix but forced pos def
1324 // 3 full accurate matrix
1325
1326 if (fMinimum) {
1327 // case a function minimum is available
1329 return 3;
1330 else if (fMinimum->HasMadePosDefCovar())
1331 return 2;
1332 else if (fMinimum->HasValidCovariance())
1333 return 1;
1334 else if (fMinimum->HasCovariance())
1335 return 0;
1336 return -1;
1337 } else {
1338 // case fMinimum is not available - use state information
1339 return fState.CovarianceStatus();
1340 }
1341 return 0;
1342}
1343
1345{
1346 // set trace object
1347 if (fMinimizer)
1348 fMinimizer->Builder().SetTraceObject(obj);
1349}
1350
1352{
1353 // set storage level
1354 if (fMinimizer)
1355 fMinimizer->Builder().SetStorageLevel(level);
1356}
1357
1358} // end namespace Minuit2
1359
1360} // 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
Error handling routines.
Definition TError.cxx:31
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:406
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:170
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:314
unsigned int MaxFunctionCalls() const
Max number of function calls.
Definition Minimizer.h:308
double Precision() const
Precision of minimizer in the evaluation of the objective function.
Definition Minimizer.h:318
int fStatus
status of minimizer
Definition Minimizer.h:385
int Strategy() const
Strategy.
Definition Minimizer.h:321
double ErrorDef() const
Definition Minimizer.h:331
MinimizerOptions fOptions
minimizer options
Definition Minimizer.h:384
bool IsValidError() const
Definition Minimizer.h:334
int PrintLevel() const
Set print level.
Definition Minimizer.h:305
Combined minimizer: combination of Migrad and Simplex.
template wrapped class for adapting to FCNBase signature
Definition FCNAdapter.h:35
Interface (abstract class) defining the function to be minimized, which has to be implemented by the ...
Definition FCNBase.h:49
virtual void SetErrorDef(double)
add interface to set dynamically a new error definition Re-implement this function if needed.
Definition FCNBase.h:111
template wrapped class for adapting to FCNBase signature a IGradFunction
template wrapped class for adapting to FumiliFCNBase signature
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) ...
const MinimumError & Error() const
const MnUserParameterState & UserState() const
const MinimumState & State() const
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
double GlobalCC(unsigned int i) const override
get global correlation coefficient for the variable i.
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 ...
ROOT::Minuit2::ModularFunctionMinimizer * fMinimizer
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)
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
virtual void SetMinimizer(ROOT::Minuit2::ModularFunctionMinimizer *m)
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.
ROOT::Minuit2::FunctionMinimum * fMinimum
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...
ROOT::Minuit2::FCNBase * fMinuitFCN
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)
int CovMatrixStatus() const override
return the status of the covariance matrix status = -1 : not available (inversion failed or Hesse fai...
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
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:205
MnCross Upval(unsigned int, unsigned int maxcalls=0, double toler=0.1) const
Definition MnMinos.cxx:199
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
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
virtual const MinimumBuilder & Builder() const =0
Class implementing the required methods for a minimization using SCAN API is provided in the upper RO...
Class implementing the required methods for a minimization using Simplex.
Instantiates the SeedGenerator and MinimumBuilder for Variable Metric Minimization method.
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)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4