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
464/// Perform the minimization and store a copy of FunctionMinimum.
465/// The maximum number of function calls used can be checked via `this->MaxFunctionCalls()`,
466/// if this value is 0 (the default), then it is replaced with
467/// `2 * (nvar + 1) * (200 + 100 * nvar + 5 * nvar * nvar` where `nvar` is number of variable parameters.
468/// \see MnMinos::FindCrossValue
469/// Other minimization settings can be retrieved via `Tolerance()`, `Strategy()`, `ErrorDef()`, `Precision()`
470/// \see ROOT::Math::MinimizerOptions::PrintDefault()
472{
473
474
475 MnPrint print("Minuit2Minimizer::Minimize", PrintLevel());
476
477 if (!fMinuitFCN) {
478 print.Error("FCN function has not been set");
479 return false;
480 }
481
482 assert(GetMinimizer() != nullptr);
483
484 // delete result of previous minimization
485 if (fMinimum)
486 delete fMinimum;
487 fMinimum = nullptr;
488
489 const int maxfcn = MaxFunctionCalls();
490 const double tol = Tolerance();
491 const int strategyLevel = Strategy();
493
494 const int printLevel = PrintLevel();
495 print.Debug("Minuit print level is", printLevel);
496 if (PrintLevel() >= 1) {
497 // print the real number of maxfcn used (defined in ModularFunctionMinimizer)
498 int maxfcn_used = maxfcn;
499 if (maxfcn_used == 0) {
500 int nvar = fState.VariableParameters();
501 maxfcn_used = 200 + 100 * nvar + 5 * nvar * nvar;
502 }
503 std::cout << "Minuit2Minimizer: Minimize with max-calls " << maxfcn_used << " convergence for edm < " << tol
504 << " strategy " << strategyLevel << std::endl;
505 }
506
507 // internal minuit messages
508 fMinimizer->Builder().SetPrintLevel(printLevel);
509
510 // switch off Minuit2 printing
511 const int prev_level = (printLevel <= 0) ? TurnOffPrintInfoLevel() : -2;
513
514 // set the precision if needed
515 if (Precision() > 0)
517
518 // add extra options if needed
520 if (!minuit2Opt) {
522 }
523 if (minuit2Opt) {
524 // set extra options
525 int storageLevel = 1;
526 bool ret = minuit2Opt->GetValue("StorageLevel", storageLevel);
527 if (ret)
529
530 // fumili options
531 if (fUseFumili) {
532 std::string fumiliMethod;
533 ret = minuit2Opt->GetValue("FumiliMethod", fumiliMethod);
534 if (ret) {
536 if (fumiliMinimizer)
537 fumiliMinimizer->SetMethod(fumiliMethod);
538 }
539 }
540
541 if (printLevel > 0) {
542 std::cout << "Minuit2Minimizer::Minuit - Changing default options" << std::endl;
543 minuit2Opt->Print();
544 }
545 }
546
547 // set a minimizer tracer object (default for printlevel=10, from gROOT for printLevel=11)
548 // use some special print levels
549 MnTraceObject *traceObj = nullptr;
550#ifdef USE_ROOT_ERROR
551 if (printLevel == 10 && gROOT) {
552 TObject *obj = gROOT->FindObject("Minuit2TraceObject");
553 traceObj = dynamic_cast<ROOT::Minuit2::MnTraceObject *>(obj);
554 if (traceObj) {
555 // need to remove from the list
556 gROOT->Remove(obj);
557 }
558 }
559 if (printLevel == 20 || printLevel == 30 || printLevel == 40 || (printLevel >= 20000 && printLevel < 30000)) {
560 int parNumber = printLevel - 20000;
561 if (printLevel == 20)
562 parNumber = -1;
563 if (printLevel == 30)
564 parNumber = -2;
565 if (printLevel == 40)
566 parNumber = 0;
568 }
569#endif
570 if (printLevel == 100 || (printLevel >= 10000 && printLevel < 20000)) {
571 int parNumber = printLevel - 10000;
573 }
574 if (traceObj) {
575 traceObj->Init(fState);
577 }
578
580
583
584 // check if Hesse needs to be run. We do it when is requested (IsValidError() == true , set by SetParabError(true) in fitConfig)
585 // (IsValidError() means the flag to get correct error from the Minimizer is set (Minimizer::SetValidError())
586 // AND when we have a valid minimum,
587 // AND when the the current covariance matrix is estimated using the iterative approximation (Dcovar != 0 , i.e. Hesse has not computed before)
588 if (fMinimum->IsValid() && IsValidError() && fMinimum->State().Error().Dcovar() != 0) {
589 // run Hesse (Hesse will add results in the last state of fMinimum
591 hesse(*fMinuitFCN, *fMinimum, maxfcn);
592 }
593
594 // -2 is the highest low invalid value for gErrorIgnoreLevel
595 if (prev_level > -2)
598
599 // copy minimum state (parameter values and errors)
601 bool ok = ExamineMinimum(*fMinimum);
602 // fMinimum = 0;
603
604 // delete trace object if it was constructed
605 if (traceObj) {
606 delete traceObj;
607 }
608 return ok;
609}
610
612{
613 /// study the function minimum
614
615 // debug ( print all the states)
616 int debugLevel = PrintLevel();
617 if (debugLevel >= 3) {
618
619 std::span<const ROOT::Minuit2::MinimumState> iterationStates = min.States();
620 std::cout << "Number of iterations " << iterationStates.size() << std::endl;
621 for (unsigned int i = 0; i < iterationStates.size(); ++i) {
622 // std::cout << iterationStates[i] << std::endl;
624 std::cout << "----------> Iteration " << i << std::endl;
625 int pr = std::cout.precision(12);
626 std::cout << " FVAL = " << st.Fval() << " Edm = " << st.Edm() << " Nfcn = " << st.NFcn()
627 << std::endl;
628 std::cout.precision(pr);
629 if (st.HasCovariance())
630 std::cout << " Error matrix change = " << st.Error().Dcovar() << std::endl;
631 if (st.HasParameters()) {
632 std::cout << " Parameters : ";
633 // need to transform from internal to external
634 for (int j = 0; j < st.size(); ++j)
635 std::cout << " p" << j << " = " << fState.Int2ext(j, st.Vec()(j));
636 std::cout << std::endl;
637 }
638 }
639 }
640
641 fStatus = 0;
642 std::string txt;
643 if (!min.HasPosDefCovar()) {
644 // this happens normally when Hesse failed
645 // it can happen in case MnSeed failed (see ROOT-9522)
646 txt = "Covar is not pos def";
647 fStatus = 5;
648 }
649 if (min.HasMadePosDefCovar()) {
650 txt = "Covar was made pos def";
651 fStatus = 1;
652 }
653 if (min.HesseFailed()) {
654 txt = "Hesse is not valid";
655 fStatus = 2;
656 }
657 if (min.IsAboveMaxEdm()) {
658 txt = "Edm is above max";
659 fStatus = 3;
660 }
661 if (min.HasReachedCallLimit()) {
662 txt = "Reached call limit";
663 fStatus = 4;
664 }
665
666 MnPrint print("Minuit2Minimizer::Minimize", debugLevel);
667 bool validMinimum = min.IsValid();
668 if (validMinimum) {
669 // print a warning message in case something is not ok
670 // this for example is case when Covar was made posdef and fStatus=3
671 if (fStatus != 0 && debugLevel > 0)
672 print.Warn(txt);
673 } else {
674 // minimum is not valid when state is not valid and edm is over max or has passed call limits
675 if (fStatus == 0) {
676 // this should not happen
677 txt = "unknown failure";
678 fStatus = 6;
679 }
680 print.Warn("Minimization did NOT converge,", txt);
681 }
682
683 if (debugLevel >= 1)
684 PrintResults();
685
686 // set the minimum values in the fValues vector
687 std::span<const MinuitParameter> paramsObj = fState.MinuitParameters();
688 if (paramsObj.empty())
689 return false;
690 assert(fDim == paramsObj.size());
691 // re-size vector if it has changed after a new minimization
692 if (fValues.size() != fDim)
693 fValues.resize(fDim);
694 for (unsigned int i = 0; i < fDim; ++i) {
695 fValues[i] = paramsObj[i].Value();
696 }
697
698 return validMinimum;
699}
700
702{
703 // print results of minimization
704 if (!fMinimum)
705 return;
706 if (fMinimum->IsValid()) {
707 // valid minimum
708 std::cout << "Minuit2Minimizer : Valid minimum - status = " << fStatus << std::endl;
709 int pr = std::cout.precision(18);
710 std::cout << "FVAL = " << fState.Fval() << std::endl;
711 std::cout << "Edm = " << fState.Edm() << std::endl;
712 std::cout.precision(pr);
713 std::cout << "Nfcn = " << fState.NFcn() << std::endl;
714 for (unsigned int i = 0; i < fState.MinuitParameters().size(); ++i) {
715 const MinuitParameter &par = fState.Parameter(i);
716 std::cout << par.Name() << "\t = " << par.Value() << "\t ";
717 if (par.IsFixed())
718 std::cout << "(fixed)" << std::endl;
719 else if (par.IsConst())
720 std::cout << "(const)" << std::endl;
721 else if (par.HasLimits())
722 std::cout << "+/- " << par.Error() << "\t(limited)" << std::endl;
723 else
724 std::cout << "+/- " << par.Error() << std::endl;
725 }
726 } else {
727 std::cout << "Minuit2Minimizer : Invalid minimum - status = " << fStatus << std::endl;
728 std::cout << "FVAL = " << fState.Fval() << std::endl;
729 std::cout << "Edm = " << fState.Edm() << std::endl;
730 std::cout << "Nfcn = " << fState.NFcn() << std::endl;
731 }
732}
733
734const double *Minuit2Minimizer::Errors() const
735{
736 // return error at minimum (set to zero for fixed and constant params)
737 std::span<const MinuitParameter> paramsObj = fState.MinuitParameters();
738 if (paramsObj.empty())
739 return nullptr;
740 assert(fDim == paramsObj.size());
741 // be careful for multiple calls of this function. I will redo an allocation here
742 // only when size of vectors has changed (e.g. after a new minimization)
743 if (fErrors.size() != fDim)
744 fErrors.resize(fDim);
745 for (unsigned int i = 0; i < fDim; ++i) {
746 const MinuitParameter &par = paramsObj[i];
747 if (par.IsFixed() || par.IsConst())
748 fErrors[i] = 0;
749 else
750 fErrors[i] = par.Error();
751 }
752
753 return &fErrors.front();
754}
755
756double Minuit2Minimizer::CovMatrix(unsigned int i, unsigned int j) const
757{
758 // get value of covariance matrices (transform from external to internal indices)
759 if (i >= fDim || j >= fDim)
760 return 0;
761 if (!fState.HasCovariance())
762 return 0; // no info available when minimization has failed
763 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
764 return 0;
765 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
766 return 0;
767 unsigned int k = fState.IntOfExt(i);
768 unsigned int l = fState.IntOfExt(j);
769 return fState.Covariance()(k, l);
770}
771
773{
774 // get value of covariance matrices
775 if (!fState.HasCovariance())
776 return false; // no info available when minimization has failed
777 for (unsigned int i = 0; i < fDim; ++i) {
778 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst()) {
779 for (unsigned int j = 0; j < fDim; ++j) {
780 cov[i * fDim + j] = 0;
781 }
782 } else {
783 unsigned int l = fState.IntOfExt(i);
784 for (unsigned int j = 0; j < fDim; ++j) {
785 // could probably speed up this loop (if needed)
786 int k = i * fDim + j;
787 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
788 cov[k] = 0;
789 else {
790 // need to transform from external to internal indices)
791 // for taking care of the removed fixed row/columns in the Minuit2 representation
792 unsigned int m = fState.IntOfExt(j);
793 cov[k] = fState.Covariance()(l, m);
794 }
795 }
796 }
797 }
798 return true;
799}
800
802{
803 // get value of Hessian matrix
804 // this is the second derivative matrices
805 if (!fState.HasCovariance())
806 return false; // no info available when minimization has failed
807 for (unsigned int i = 0; i < fDim; ++i) {
808 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst()) {
809 for (unsigned int j = 0; j < fDim; ++j) {
810 hess[i * fDim + j] = 0;
811 }
812 } else {
813 unsigned int l = fState.IntOfExt(i);
814 for (unsigned int j = 0; j < fDim; ++j) {
815 // could probably speed up this loop (if needed)
816 int k = i * fDim + j;
817 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
818 hess[k] = 0;
819 else {
820 // need to transform from external to internal indices)
821 // for taking care of the removed fixed row/columns in the Minuit2 representation
822 unsigned int m = fState.IntOfExt(j);
823 hess[k] = fState.Hessian()(l, m);
824 }
825 }
826 }
827 }
828
829 return true;
830}
831
832double Minuit2Minimizer::Correlation(unsigned int i, unsigned int j) const
833{
834 // get correlation between parameter i and j
835 if (i >= fDim || j >= fDim)
836 return 0;
837 if (!fState.HasCovariance())
838 return 0; // no info available when minimization has failed
839 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
840 return 0;
841 if (fState.Parameter(j).IsFixed() || fState.Parameter(j).IsConst())
842 return 0;
843 unsigned int k = fState.IntOfExt(i);
844 unsigned int l = fState.IntOfExt(j);
845 double cij = fState.IntCovariance()(k, l);
846 double tmp = std::sqrt(std::abs(fState.IntCovariance()(k, k) * fState.IntCovariance()(l, l)));
847 if (tmp > 0)
848 return cij / tmp;
849 return 0;
850}
851
852double Minuit2Minimizer::GlobalCC(unsigned int i) const
853{
854 // get global correlation coefficient for the parameter i. This is a number between zero and one which gives
855 // the correlation between the i-th parameter and that linear combination of all other parameters which
856 // is most strongly correlated with i.
857
858 if (i >= fDim)
859 return 0;
860 // no info available when minimization has failed or has some problems
861 if (!fState.HasGlobalCC())
862 return 0;
863 if (fState.Parameter(i).IsFixed() || fState.Parameter(i).IsConst())
864 return 0;
865 unsigned int k = fState.IntOfExt(i);
866 return fState.GlobalCC().GlobalCC()[k];
867}
868
869bool Minuit2Minimizer::GetMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
870{
871 // return the minos error for parameter i
872 // if a minimum does not exist an error is returned
873 // runopt is a flag which specifies if only lower or upper error needs to be run
874 // if runopt = 0 both, = 1 only lower, + 2 only upper errors
875 errLow = 0;
876 errUp = 0;
877
879
880 // need to know if parameter is const or fixed
881 if (fState.Parameter(i).IsConst() || fState.Parameter(i).IsFixed()) {
882 return false;
883 }
884
885 MnPrint print("Minuit2Minimizer::GetMinosError", PrintLevel());
886
887 // to run minos I need function minimum class
888 // redo minimization from current state
889 // ROOT::Minuit2::FunctionMinimum min =
890 // GetMinimizer()->Minimize(*GetFCN(),fState, ROOT::Minuit2::MnStrategy(strategy), MaxFunctionCalls(),
891 // Tolerance());
892 // fState = min.UserState();
893 if (fMinimum == nullptr) {
894 print.Error("Failed - no function minimum existing");
895 return false;
896 }
897
898 if (!fMinimum->IsValid()) {
899 print.Error("Failed - invalid function minimum");
900 return false;
901 }
902
904 // if error def has been changed update it in FunctionMinimum
905 if (ErrorDef() != fMinimum->Up())
907
909
910 // run again the Minimization in case of a new minimum
911 // bit 8 is set
912 if ((mstatus & 8) != 0) {
913 print.Info([&](std::ostream &os) {
914 os << "Found a new minimum: run again the Minimization starting from the new point";
915 os << "\nFVAL = " << fState.Fval();
916 for (auto &par : fState.MinuitParameters()) {
917 os << '\n' << par.Name() << "\t = " << par.Value();
918 }
919 });
920 // release parameter that was fixed in the returned state from Minos
922 bool ok = Minimize();
923 if (!ok)
924 return false;
925 // run again Minos from new Minimum (also lower error needs to be re-computed)
926 print.Info("Run now again Minos from the new found Minimum");
928
929 // do not reset new minimum bit to flag for other parameters
930 mstatus |= 8;
931 }
932
933 fStatus += 10 * mstatus;
935
936 bool isValid = ((mstatus & 1) == 0) && ((mstatus & 2) == 0);
937 return isValid;
938}
939
940int Minuit2Minimizer::RunMinosError(unsigned int i, double &errLow, double &errUp, int runopt)
941{
942
943 bool runLower = runopt != 2;
944 bool runUpper = runopt != 1;
945
946 const int debugLevel = PrintLevel();
947 // switch off Minuit2 printing
948 const int prev_level = (debugLevel <= 0) ? TurnOffPrintInfoLevel() : -2;
950
951 // set the precision if needed
952 if (Precision() > 0)
954
956
957 // run MnCross
958 MnCross low;
959 MnCross up;
960 int maxfcn = MaxFunctionCalls();
961 double tol = Tolerance();
962
963 const char *par_name = fState.Name(i);
964
965 // now input tolerance for migrad calls inside Minos (MnFunctionCross)
966 // before it was fixed to 0.05
967 // cut off too small tolerance (they are not needed)
968 tol = std::max(tol, 0.01);
969
970 // get the real number of maxfcn used (defined in MnMinos) to be printed
971 int maxfcn_used = maxfcn;
972 if (maxfcn_used == 0) {
973 int nvar = fState.VariableParameters();
974 maxfcn_used = 2 * (nvar + 1) * (200 + 100 * nvar + 5 * nvar * nvar);
975 }
976
977 if (runLower) {
978 if (debugLevel >= 1) {
979 std::cout << "************************************************************************************************"
980 "******\n";
981 std::cout << "Minuit2Minimizer::GetMinosError - Run MINOS LOWER error for parameter #" << i << " : "
982 << par_name << " using max-calls " << maxfcn_used << ", tolerance " << tol << std::endl;
983 }
984 low = minos.Loval(i, maxfcn, tol);
985 }
986 if (runUpper) {
987 if (debugLevel >= 1) {
988 std::cout << "************************************************************************************************"
989 "******\n";
990 std::cout << "Minuit2Minimizer::GetMinosError - Run MINOS UPPER error for parameter #" << i << " : "
991 << par_name << " using max-calls " << maxfcn_used << ", tolerance " << tol << std::endl;
992 }
993 up = minos.Upval(i, maxfcn, tol);
994 }
995
996 ROOT::Minuit2::MinosError me(i, fMinimum->UserState().Value(i), low, up);
997
998 // restore global print level
999 if (prev_level > -2)
1002
1003 // debug result of Minos
1004 // print error message in Minos
1005 // Note that the only invalid condition can happen when the (npar-1) minimization fails
1006 // The error is also invalid when the maximum number of calls is reached or a new function minimum is found
1007 // in case of the parameter at the limit the error is not invalid.
1008 // When the error is invalid the returned error is the Hessian error.
1009
1010 if (debugLevel > 0) {
1011 if (runLower) {
1012 if (!me.LowerValid())
1013 std::cout << "Minos: Invalid lower error for parameter " << par_name << std::endl;
1014 if (me.AtLowerLimit())
1015 std::cout << "Minos: Parameter : " << par_name << " is at Lower limit; error is " << me.Lower()
1016 << std::endl;
1017 if (me.AtLowerMaxFcn())
1018 std::cout << "Minos: Maximum number of function calls exceeded when running for lower error for parameter "
1019 << par_name << std::endl;
1020 if (me.LowerNewMin())
1021 std::cout << "Minos: New Minimum found while running Minos for lower error for parameter " << par_name
1022 << std::endl;
1023
1024 if (debugLevel >= 1 && me.LowerValid())
1025 std::cout << "Minos: Lower error for parameter " << par_name << " : " << me.Lower() << std::endl;
1026 }
1027 if (runUpper) {
1028 if (!me.UpperValid())
1029 std::cout << "Minos: Invalid upper error for parameter " << par_name << std::endl;
1030 if (me.AtUpperLimit())
1031 std::cout << "Minos: Parameter " << par_name << " is at Upper limit; error is " << me.Upper() << std::endl;
1032 if (me.AtUpperMaxFcn())
1033 std::cout << "Minos: Maximum number of function calls exceeded when running for upper error for parameter "
1034 << par_name << std::endl;
1035 if (me.UpperNewMin())
1036 std::cout << "Minos: New Minimum found while running Minos for upper error for parameter " << par_name
1037 << std::endl;
1038
1039 if (debugLevel >= 1 && me.UpperValid())
1040 std::cout << "Minos: Upper error for parameter " << par_name << " : " << me.Upper() << std::endl;
1041 }
1042 }
1043
1044 MnPrint print("RunMinosError", PrintLevel());
1045 bool lowerInvalid = (runLower && !me.LowerValid());
1046 bool upperInvalid = (runUpper && !me.UpperValid());
1047 // print message in case of invalid error also in printLevel0
1048 if (lowerInvalid) {
1049 print.Warn("Invalid lower error for parameter", fMinimum->UserState().Name(i));
1050 }
1051 if (upperInvalid) {
1052 print.Warn("Invalid upper error for parameter", fMinimum->UserState().Name(i));
1053 }
1054 // print also case it is lower/upper limit
1055 if (me.AtLowerLimit()) {
1056 print.Warn("Lower error for parameter", fMinimum->UserState().Name(i), "is at the Lower limit!");
1057 }
1058 if (me.AtUpperLimit()) {
1059 print.Warn("Upper error for parameter", fMinimum->UserState().Name(i), "is at the Upper limit!");
1060 }
1061
1062 int mstatus = 0;
1063 if (lowerInvalid || upperInvalid) {
1064 // set status according to bit
1065 // bit 1: lower invalid Minos errors
1066 // bit 2: upper invalid Minos error
1067 // bit 3: invalid because max FCN
1068 // bit 4 : invalid because a new minimum has been found
1069 if (lowerInvalid) {
1070 mstatus |= 1;
1071 if (me.AtLowerMaxFcn())
1072 mstatus |= 4;
1073 if (me.LowerNewMin())
1074 mstatus |= 8;
1075 }
1076 if (upperInvalid) {
1077 mstatus |= 2;
1078 if (me.AtUpperMaxFcn())
1079 mstatus |= 4;
1080 if (me.UpperNewMin())
1081 mstatus |= 8;
1082 }
1083 }
1084 // case upper/lower limit
1085 if (me.AtUpperLimit() || me.AtLowerLimit())
1086 mstatus |= 16;
1087
1088 if (runLower)
1089 errLow = me.Lower();
1090 if (runUpper)
1091 errUp = me.Upper();
1092
1093 // in case of new minimum found update also the minimum state
1094 if ((runLower && me.LowerNewMin()) && (runUpper && me.UpperNewMin())) {
1095 // take state with lower function value
1096 fState = (low.State().Fval() < up.State().Fval()) ? low.State() : up.State();
1097 } else if (runLower && me.LowerNewMin()) {
1098 fState = low.State();
1099 } else if (runUpper && me.UpperNewMin()) {
1100 fState = up.State();
1101 }
1102
1103 return mstatus;
1104}
1105
1106bool Minuit2Minimizer::Scan(unsigned int ipar, unsigned int &nstep, double *x, double *y, double xmin, double xmax)
1107{
1108 // scan a parameter (variable) around the minimum value
1109 // the parameters must have been set before
1110 // if xmin=0 && xmax == 0 by default scan around 2 sigma of the error
1111 // if the errors are also zero then scan from min and max of parameter range
1112
1113 MnPrint print("Minuit2Minimizer::Scan", PrintLevel());
1114 if (!fMinuitFCN) {
1115 print.Error("Function must be set before using Scan");
1116 return false;
1117 }
1118
1119 if (ipar > fState.MinuitParameters().size()) {
1120 print.Error("Invalid number; minimizer variables must be set before using Scan");
1121 return false;
1122 }
1123
1124 // switch off Minuit2 printing
1125 const int prev_level = (PrintLevel() <= 0) ? TurnOffPrintInfoLevel() : -2;
1127
1128 // set the precision if needed
1129 if (Precision() > 0)
1131
1133 double amin = scan.Fval(); // fcn value of the function before scan
1134
1135 // first value is param value
1136 std::vector<std::pair<double, double>> result = scan(ipar, nstep - 1, xmin, xmax);
1137
1138 // restore global print level
1139 if (prev_level > -2)
1142
1143 if (result.size() != nstep) {
1144 print.Error("Invalid result from MnParameterScan");
1145 return false;
1146 }
1147 // sort also the returned points in x
1148 std::sort(result.begin(), result.end());
1149
1150 for (unsigned int i = 0; i < nstep; ++i) {
1151 x[i] = result[i].first;
1152 y[i] = result[i].second;
1153 }
1154
1155 // what to do if a new minimum has been found ?
1156 // use that as new minimum
1157 if (scan.Fval() < amin) {
1158 print.Info("A new minimum has been found");
1159 fState.SetValue(ipar, scan.Parameters().Value(ipar));
1160 }
1161
1162 return true;
1163}
1164
1165bool Minuit2Minimizer::Contour(unsigned int ipar, unsigned int jpar, unsigned int &npoints, double *x, double *y)
1166{
1167 // contour plot for parameter i and j
1168 // need a valid FunctionMinimum otherwise exits
1169
1170 MnPrint print("Minuit2Minimizer::Contour", PrintLevel());
1171
1172 if (fMinimum == nullptr) {
1173 print.Error("No function minimum existing; must minimize function before");
1174 return false;
1175 }
1176
1177 if (!fMinimum->IsValid()) {
1178 print.Error("Invalid function minimum");
1179 return false;
1180 }
1182
1184 // if error def has been changed update it in FunctionMinimum
1185 if (ErrorDef() != fMinimum->Up()) {
1187 }
1188
1189 print.Info("Computing contours at level -", ErrorDef());
1190
1191 // switch off Minuit2 printing (for level of 0,1)
1192 const int prev_level = (PrintLevel() <= 1) ? TurnOffPrintInfoLevel() : -2;
1194
1195 // set the precision if needed
1196 if (Precision() > 0)
1198
1199 // eventually one should specify tolerance in contours
1200 MnContours contour(*fMinuitFCN, *fMinimum, Strategy());
1201
1202 // restore global print level
1203 if (prev_level > -2)
1206
1207 // compute the contour
1208 std::vector<std::pair<double, double>> result = contour(ipar, jpar, npoints);
1209 if (result.size() != npoints) {
1210 print.Error("Invalid result from MnContours");
1211 return false;
1212 }
1213 for (unsigned int i = 0; i < npoints; ++i) {
1214 x[i] = result[i].first;
1215 y[i] = result[i].second;
1216 }
1217 print.Info([&](std::ostream &os) {
1218 os << " Computed " << npoints << " points at level " << ErrorDef();
1219 for (unsigned int i = 0; i < npoints; i++) {
1220 if (i %5 == 0) os << std::endl;
1221 os << "( " << x[i] << ", " << y[i] << ") ";
1222 }
1223 os << std::endl << std::endl;
1224 });
1225
1226 return true;
1227}
1228
1230{
1231 // find Hessian (full second derivative calculations)
1232 // the contained state will be updated with the Hessian result
1233 // in case a function minimum exists and is valid the result will be
1234 // appended in the function minimum
1235
1236 MnPrint print("Minuit2Minimizer::Hesse", PrintLevel());
1237
1238 if (!fMinuitFCN) {
1239 print.Error("FCN function has not been set");
1240 return false;
1241 }
1242
1243 const int maxfcn = MaxFunctionCalls();
1244 print.Info("Using max-calls", maxfcn);
1245
1246 // switch off Minuit2 printing
1247 const int prev_level = (PrintLevel() <= 0) ? TurnOffPrintInfoLevel() : -2;
1249
1250 // set the precision if needed
1251 if (Precision() > 0)
1253
1255
1256 // case when function minimum exists
1257 if (fMinimum) {
1258
1259 // if (PrintLevel() >= 3) {
1260 // std::cout << "Minuit2Minimizer::Hesse - State before running Hesse " << std::endl;
1261 // std::cout << fState << std::endl;
1262 // }
1263
1264 // run hesse and function minimum will be updated with Hesse result
1265 hesse(*fMinuitFCN, *fMinimum, maxfcn);
1266 // update user state
1268 }
1269
1270 else {
1271 // run Hesse on point stored in current state (independent of function minimum validity)
1272 // (x == 0)
1273 fState = hesse(*fMinuitFCN, fState, maxfcn);
1274 }
1275
1276 // restore global print level
1277 if (prev_level > -2)
1280
1281 if (PrintLevel() >= 3) {
1282 std::cout << "Minuit2Minimizer::Hesse - State returned from Hesse " << std::endl;
1283 std::cout << fState << std::endl;
1284 }
1285
1287 std::string covStatusType = "not valid";
1288 if (covStatus == 1)
1289 covStatusType = "approximate";
1290 if (covStatus == 2)
1291 covStatusType = "full but made positive defined";
1292 if (covStatus == 3)
1293 covStatusType = "accurate";
1294 if (covStatus == 0)
1295 covStatusType = "full but not positive defined";
1296
1297 if (!fState.HasCovariance()) {
1298 // if false means error is not valid and this is due to a failure in Hesse
1299 // update minimizer error status
1300 int hstatus = 4;
1301 // information on error state can be retrieved only if fMinimum is available
1302 if (fMinimum) {
1303 if (fMinimum->Error().HesseFailed())
1304 hstatus = 1;
1305 if (fMinimum->Error().InvertFailed())
1306 hstatus = 2;
1307 else if (!(fMinimum->Error().IsPosDef()))
1308 hstatus = 3;
1309 }
1310
1311 print.Warn("Hesse failed - matrix is", covStatusType);
1312 print.Warn(hstatus);
1313
1314 fStatus += 100 * hstatus;
1315 return false;
1316 }
1317
1318 print.Info("Hesse is valid - matrix is", covStatusType);
1319
1320 return true;
1321}
1322
1324{
1325 // return status of covariance matrix
1326 //-1 - not available (inversion failed or Hesse failed)
1327 // 0 - available but not positive defined
1328 // 1 - covariance only approximate
1329 // 2 full matrix but forced pos def
1330 // 3 full accurate matrix
1331
1332 if (fMinimum) {
1333 // case a function minimum is available
1335 return 3;
1336 else if (fMinimum->HasMadePosDefCovar())
1337 return 2;
1338 else if (fMinimum->HasValidCovariance())
1339 return 1;
1340 else if (fMinimum->HasCovariance())
1341 return 0;
1342 return -1;
1343 } else {
1344 // case fMinimum is not available - use state information
1345 return fState.CovarianceStatus();
1346 }
1347 return 0;
1348}
1349
1351{
1352 // set trace object
1353 if (fMinimizer)
1354 fMinimizer->Builder().SetTraceObject(obj);
1355}
1356
1358{
1359 // set storage level
1360 if (fMinimizer)
1361 fMinimizer->Builder().SetStorageLevel(level);
1362}
1363
1364} // end namespace Minuit2
1365
1366} // 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:252
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
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: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
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:422
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)
Namespace for new ROOT classes and functions.
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4