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