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