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