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