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