Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
FumiliErrorUpdator.cxx
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT *
7 * *
8 **********************************************************************/
9
11#include "Minuit2/MnFcn.h"
12#include "Minuit2/MnStrategy.h"
17#include "Minuit2/MnMatrix.h"
20#include "Minuit2/MnPrint.h"
21
22#include <limits>
23
24namespace ROOT {
25
26namespace Minuit2 {
27
30{
31 // dummy methods to suppress unused variable warnings
32 // this member function should never be called within
33 // the Fumili method...
34 s0.Fval();
35 p1.Fval();
36 g1.IsValid();
37 return MinimumError(2);
38}
39
41 const GradientCalculator &gc, double lambda) const
42{
43 // calculate the error matrix using approximation of Fumili
44 // use only first derivatives (see tutorial par. 5.1,5.2)
45 // The Fumili Hessian is provided by the FumiliGradientCalculator class
46 // we apply also the Marquard lambda factor to increase weight of diagonal term
47 // as suggester in Numerical Receipt for Marquard method
48
49 MnPrint print("FumiliErrorUpdator");
50 print.Debug("Compute covariance matrix using Fumili method");
51
52 // need to downcast to FumiliGradientCalculator
53 FumiliGradientCalculator *fgc = dynamic_cast<FumiliGradientCalculator *>(const_cast<GradientCalculator *>(&gc));
54 assert(fgc != nullptr);
55
56
57 // get Hessian from Gradient calculator
58
60
61 int nvar = p1.Vec().size();
62
63 // apply Marquard lambda factor
64 double eps = 8 * std::numeric_limits<double>::min();
65 for (int j = 0; j < nvar; j++) {
66 h(j, j) *= (1. + lambda);
67 // if h(j,j) is zero what to do ?
68 if (std::fabs(h(j, j)) < eps) { // should use DBL_MIN
69 // put a cut off to avoid zero on diagonals
70 if (lambda > 1)
71 h(j, j) = lambda * eps;
72 else
73 h(j, j) = eps;
74 }
75 }
76
78 int ifail = Invert(cov);
79 if (ifail != 0) {
80 print.Warn("inversion fails; return diagonal matrix");
81
82 for (unsigned int i = 0; i < cov.Nrow(); i++) {
83 cov(i, i) = 1. / cov(i, i);
84 }
85
86 // shiould we return the Hessian in addition to cov in this case?
88 }
89
90 double dcov = -1;
91 if (s0.IsValid()) {
92
93 const MnAlgebraicSymMatrix &v0 = s0.Error().InvHessian();
94
95 // calculate by how much did the covariance matrix changed
96 // (if it changed a lot since the last step, probably we
97 // are not yet near the Minimum)
98 dcov = 0.5 * (s0.Error().Dcovar() + sum_of_elements(cov - v0) / sum_of_elements(cov));
99 }
100
101 return MinimumError(cov, h, dcov);
102}
103
104} // namespace Minuit2
105
106} // namespace ROOT
#define s0(x)
Definition RSha256.hxx:90
#define h(i)
Definition RSha256.hxx:106
virtual MinimumError Update(const MinimumState &fMinimumState, const MinimumParameters &fMinimumParameters, const GradientCalculator &fGradientCalculator, double lambda) const
Member function that calculates the Error matrix (or the Hessian matrix containing the (approximate) ...
Fumili gradient calculator using external gradient provided by FCN Note that the computed Hessian and...
const MnAlgebraicSymMatrix & GetHessian() const
interface class for gradient calculators
unsigned int Nrow() const
Definition MnMatrix.h:683
unsigned int size() const
Definition MnMatrix.h:1032
MinimumError keeps the inv.
const MnAlgebraicVector & Vec() const
MinimumState keeps the information (position, Gradient, 2nd deriv, etc) after one minimization step (...
void Debug(const Ts &... args)
Definition MnPrint.h:135
void Warn(const Ts &... args)
Definition MnPrint.h:123
int Invert(LASymMatrix &)
Definition MnMatrix.cxx:296
double sum_of_elements(const LASymMatrix &)
Definition MnMatrix.cxx:98
LASymMatrix MnAlgebraicSymMatrix
Definition MnMatrixfwd.h:21