Logo ROOT  
Reference Guide
MnHesse.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
10#include "Minuit2/MnHesse.h"
12#include "Minuit2/MnUserFcn.h"
13#include "Minuit2/FCNBase.h"
15#include "Minuit2/MnPosDef.h"
24#include "Minuit2/MnPrint.h"
25#include "Minuit2/MPIProcess.h"
26
27namespace ROOT {
28
29namespace Minuit2 {
30
31MnUserParameterState MnHesse::operator()(const FCNBase &fcn, const std::vector<double> &par,
32 const std::vector<double> &err, unsigned int maxcalls) const
33{
34 // interface from vector of params and errors
35 return (*this)(fcn, MnUserParameterState(par, err), maxcalls);
36}
37
38MnUserParameterState MnHesse::operator()(const FCNBase &fcn, const std::vector<double> &par, unsigned int nrow,
39 const std::vector<double> &cov, unsigned int maxcalls) const
40{
41 // interface from vector of params and covariance
42 return (*this)(fcn, MnUserParameterState(par, cov, nrow), maxcalls);
43}
44
45MnUserParameterState MnHesse::operator()(const FCNBase &fcn, const std::vector<double> &par,
46 const MnUserCovariance &cov, unsigned int maxcalls) const
47{
48 // interface from vector of params and covariance
49 return (*this)(fcn, MnUserParameterState(par, cov), maxcalls);
50}
51
52MnUserParameterState MnHesse::operator()(const FCNBase &fcn, const MnUserParameters &par, unsigned int maxcalls) const
53{
54 // interface from MnUserParameters
55 return (*this)(fcn, MnUserParameterState(par), maxcalls);
56}
57
59 unsigned int maxcalls) const
60{
61 // interface from MnUserParameters and MnUserCovariance
62 return (*this)(fcn, MnUserParameterState(par, cov), maxcalls);
63}
64
66MnHesse::operator()(const FCNBase &fcn, const MnUserParameterState &state, unsigned int maxcalls) const
67{
68 // interface from MnUserParameterState
69 // create a new Minimum state and use that interface
70 unsigned int n = state.VariableParameters();
71 MnUserFcn mfcn(fcn, state.Trafo(), state.NFcn());
73 for (unsigned int i = 0; i < n; i++)
74 x(i) = state.IntParameters()[i];
75 double amin = mfcn(x);
76 MinimumParameters par(x, amin);
77 // check if we can use analytical gradient
78 auto * gradFCN = dynamic_cast<const FCNGradientBase *>(&(fcn));
79 if (gradFCN) {
80 // no need to compute gradient here
82 state.Edm(), state.NFcn()), state.Trafo());
83 return MnUserParameterState(tmp, fcn.Up(), state.Trafo());
84 }
85 // case of numerical gradient
87 FunctionGradient gra = gc(par);
88 MinimumState tmp = ComputeNumerical(mfcn, MinimumState(par, MinimumError(MnAlgebraicSymMatrix(n), 1.), gra, state.Edm(), state.NFcn()),
89 state.Trafo(), maxcalls);
90 return MnUserParameterState(tmp, fcn.Up(), state.Trafo());
91}
92
93void MnHesse::operator()(const FCNBase &fcn, FunctionMinimum &min, unsigned int maxcalls) const
94{
95 // interface from FunctionMinimum to be used after minimization
96 // use last state from the minimization without the need to re-create a new state
97 // do not reset function calls and keep updating them
98 MnUserFcn mfcn(fcn, min.UserState().Trafo(), min.NFcn());
99 MinimumState st = (*this)(mfcn, min.State(), min.UserState().Trafo(), maxcalls);
100 min.Add(st);
101}
102
104 unsigned int maxcalls) const
105{
106 // check first if we have an analytical gradient
107 if (st.Gradient().IsAnalytical()) {
108 // check if we can compute analytical Hessian
109 auto * gradFCN = dynamic_cast<const FCNGradientBase *>(&(mfcn.Fcn()));
110 if (gradFCN && gradFCN->HasHessian()) {
111 return ComputeAnalytical(*gradFCN, st, trafo);
112 }
113 }
114 // case of numerical computation or only analytical first derivatives
115 return ComputeNumerical(mfcn, st, trafo, maxcalls);
116}
118{
119 unsigned int n = st.Parameters().Vec().size();
120 MnAlgebraicSymMatrix vhmat(n);
121
122 MnPrint print("MnHesse");
123
124 const MnMachinePrecision &prec = trafo.Precision();
125
126 std::unique_ptr<AnalyticalGradientCalculator> hc;
128 hc = std::unique_ptr<AnalyticalGradientCalculator> (new ExternalInternalGradientCalculator(fcn,trafo));
129 } else {
130 hc = std::make_unique<AnalyticalGradientCalculator>(fcn,trafo);
131 }
132
133 bool ret = hc->Hessian(st.Parameters(), vhmat);
134 if (!ret) {
135 print.Error("Error computing analytical Hessian. MnHesse fails and will return a null matrix");
137 st.NFcn());
138 }
140 for (unsigned int i = 0; i < n; i++)
141 g2(i) = vhmat(i,i);
142
143 // update Function gradient with new G2 found
144 FunctionGradient gr(st.Gradient().Grad(), g2);
145
146 // verify if matrix pos-def (still 2nd derivative)
147 print.Debug("Original error matrix", vhmat);
148
149 MinimumError tmpErr = MnPosDef()(MinimumError(vhmat, 1.), prec);
150 vhmat = tmpErr.InvHessian();
151
152 print.Debug("PosDef error matrix", vhmat);
153
154 int ifail = Invert(vhmat);
155 if (ifail != 0) {
156
157 print.Warn("Matrix inversion fails; will return diagonal matrix");
158
159 MnAlgebraicSymMatrix tmpsym(vhmat.Nrow());
160 for (unsigned int j = 0; j < n; j++) {
161 tmpsym(j,j) = 1. / g2(j);
162 }
163
164 return MinimumState(st.Parameters(), MinimumError(tmpsym, MinimumError::MnInvertFailed), gr, st.Edm(), st.NFcn());
165 }
166
168
169 // if matrix is made pos def returns anyway edm
170 if (tmpErr.IsMadePosDef()) {
172 double edm = estim.Estimate(gr, err);
173 return MinimumState(st.Parameters(), err, gr, edm, st.NFcn());
174 }
175
176 // calculate edm for good errors
177 MinimumError err(vhmat, 0.);
178 // this use only grad values
179 double edm = estim.Estimate(gr, err);
180
181 print.Debug("Hessian is ACCURATE. New state:", "\n First derivative:", st.Gradient().Grad(),
182 "\n Covariance matrix:", vhmat, "\n Edm:", edm);
183
184 return MinimumState(st.Parameters(), err, gr, edm, st.NFcn());
185}
186
187
189 unsigned int maxcalls) const
190{
191 // internal interface from MinimumState and MnUserTransformation
192 // Function who does the real Hessian calculations
193 MnPrint print("MnHesse");
194
195 const MnMachinePrecision &prec = trafo.Precision();
196 // make sure starting at the right place
197 double amin = mfcn(st.Vec());
198 double aimsag = std::sqrt(prec.Eps2()) * (std::fabs(amin) + mfcn.Up());
199
200 // diagonal Elements first
201
202 unsigned int n = st.Parameters().Vec().size();
203 if (maxcalls == 0)
204 maxcalls = 200 + 100 * n + 5 * n * n;
205
206 MnAlgebraicSymMatrix vhmat(n);
207 MnAlgebraicVector g2 = st.Gradient().G2();
208 MnAlgebraicVector gst = st.Gradient().Gstep();
209 MnAlgebraicVector grd = st.Gradient().Grad();
210 MnAlgebraicVector dirin = st.Gradient().Gstep();
212
213 // case gradient is not numeric (could be analytical or from FumiliGradientCalculator)
214
215 if (st.Gradient().IsAnalytical()) {
216 print.Info("Using analytical gradient but a numerical Hessian calculator - it could be not optimal");
218 // should we check here if numerical gradient is compatible with analytical one ?
219 FunctionGradient tmp = igc(st.Parameters());
220 gst = tmp.Gstep();
221 dirin = tmp.Gstep();
222 g2 = tmp.G2();
223 print.Warn("Analytical calculator ",grd," numerical ",tmp.Grad()," g2 ",g2);
224 }
225
227
228 print.Debug("Gradient is", st.Gradient().IsAnalytical() ? "analytical" : "numerical", "\n point:", x,
229 "\n fcn :", amin, "\n grad :", grd, "\n step :", gst, "\n g2 :", g2);
230
231 for (unsigned int i = 0; i < n; i++) {
232
233 double xtf = x(i);
234 double dmin = 8. * prec.Eps2() * (std::fabs(xtf) + prec.Eps2());
235 double d = std::fabs(gst(i));
236 if (d < dmin)
237 d = dmin;
238
239 print.Debug("Derivative parameter", i, "d =", d, "dmin =", dmin);
240
241 for (unsigned int icyc = 0; icyc < Ncycles(); icyc++) {
242 double sag = 0.;
243 double fs1 = 0.;
244 double fs2 = 0.;
245 for (unsigned int multpy = 0; multpy < 5; multpy++) {
246 x(i) = xtf + d;
247 fs1 = mfcn(x);
248 x(i) = xtf - d;
249 fs2 = mfcn(x);
250 x(i) = xtf;
251 sag = 0.5 * (fs1 + fs2 - 2. * amin);
252
253 print.Debug("cycle", icyc, "mul", multpy, "\tsag =", sag, "d =", d);
254
255 // Now as F77 Minuit - check that sag is not zero
256 if (sag != 0)
257 goto L30; // break
258 if (trafo.Parameter(i).HasLimits()) {
259 if (d > 0.5)
260 goto L26;
261 d *= 10.;
262 if (d > 0.5)
263 d = 0.51;
264 continue;
265 }
266 d *= 10.;
267 }
268
269 L26:
270 // get parameter name for i
271 // (need separate scope for avoiding compl error when declaring name)
272 print.Warn("2nd derivative zero for parameter", trafo.Name(trafo.ExtOfInt(i)),
273 "; MnHesse fails and will return diagonal matrix");
274
275 for (unsigned int j = 0; j < n; j++) {
276 double tmp = g2(j) < prec.Eps2() ? 1. : 1. / g2(j);
277 vhmat(j, j) = tmp < prec.Eps2() ? 1. : tmp;
278 }
279
281 mfcn.NumOfCalls());
282
283 L30:
284 double g2bfor = g2(i);
285 g2(i) = 2. * sag / (d * d);
286 grd(i) = (fs1 - fs2) / (2. * d);
287 gst(i) = d;
288 dirin(i) = d;
289 yy(i) = fs1;
290 double dlast = d;
291 d = std::sqrt(2. * aimsag / std::fabs(g2(i)));
292 if (trafo.Parameter(i).HasLimits())
293 d = std::min(0.5, d);
294 if (d < dmin)
295 d = dmin;
296
297 print.Debug("g1 =", grd(i), "g2 =", g2(i), "step =", gst(i), "d =", d, "diffd =", std::fabs(d - dlast) / d,
298 "diffg2 =", std::fabs(g2(i) - g2bfor) / g2(i));
299
300 // see if converged
301 if (std::fabs((d - dlast) / d) < Tolerstp())
302 break;
303 if (std::fabs((g2(i) - g2bfor) / g2(i)) < TolerG2())
304 break;
305 d = std::min(d, 10. * dlast);
306 d = std::max(d, 0.1 * dlast);
307 }
308 vhmat(i, i) = g2(i);
309 if (mfcn.NumOfCalls() > maxcalls) {
310
311 // std::cout<<"maxcalls " << maxcalls << " " << mfcn.NumOfCalls() << " " << st.NFcn() << std::endl;
312 print.Warn("Maximum number of allowed function calls exhausted; will return diagonal matrix");
313
314 for (unsigned int j = 0; j < n; j++) {
315 double tmp = g2(j) < prec.Eps2() ? 1. : 1. / g2(j);
316 vhmat(j, j) = tmp < prec.Eps2() ? 1. : tmp;
317 }
318
320 st.Edm(), mfcn.NumOfCalls());
321 }
322 }
323
324 print.Debug("Second derivatives", g2);
325
326 if (fStrategy.Strategy() > 0) {
327 // refine first derivative
328 HessianGradientCalculator hgc(mfcn, trafo, fStrategy);
329 FunctionGradient gr = hgc(st.Parameters(), FunctionGradient(grd, g2, gst));
330 // update gradient and step values
331 grd = gr.Grad();
332 gst = gr.Gstep();
333 }
334
335 // off-diagonal Elements
336 // initial starting values
337 if (n > 0) {
338 MPIProcess mpiprocOffDiagonal(n * (n - 1) / 2, 0);
339 unsigned int startParIndexOffDiagonal = mpiprocOffDiagonal.StartElementIndex();
340 unsigned int endParIndexOffDiagonal = mpiprocOffDiagonal.EndElementIndex();
341
342 unsigned int offsetVect = 0;
343 for (unsigned int in = 0; in < startParIndexOffDiagonal; in++)
344 if ((in + offsetVect) % (n - 1) == 0)
345 offsetVect += (in + offsetVect) / (n - 1);
346
347 for (unsigned int in = startParIndexOffDiagonal; in < endParIndexOffDiagonal; in++) {
348
349 int i = (in + offsetVect) / (n - 1);
350 if ((in + offsetVect) % (n - 1) == 0)
351 offsetVect += i;
352 int j = (in + offsetVect) % (n - 1) + 1;
353
354 if ((i + 1) == j || in == startParIndexOffDiagonal)
355 x(i) += dirin(i);
356
357 x(j) += dirin(j);
358
359 double fs1 = mfcn(x);
360 double elem = (fs1 + amin - yy(i) - yy(j)) / (dirin(i) * dirin(j));
361 vhmat(i, j) = elem;
362
363 x(j) -= dirin(j);
364
365 if (j % (n - 1) == 0 || in == endParIndexOffDiagonal - 1)
366 x(i) -= dirin(i);
367 }
368
369 mpiprocOffDiagonal.SyncSymMatrixOffDiagonal(vhmat);
370 }
371
372 // verify if matrix pos-def (still 2nd derivative)
373
374 print.Debug("Original error matrix", vhmat);
375
376 MinimumError tmpErr = MnPosDef()(MinimumError(vhmat, 1.), prec);
377 vhmat = tmpErr.InvHessian();
378
379 print.Debug("PosDef error matrix", vhmat);
380
381 int ifail = Invert(vhmat);
382 if (ifail != 0) {
383
384 print.Warn("Matrix inversion fails; will return diagonal matrix");
385
386 MnAlgebraicSymMatrix tmpsym(vhmat.Nrow());
387 for (unsigned int j = 0; j < n; j++) {
388 double tmp = g2(j) < prec.Eps2() ? 1. : 1. / g2(j);
389 tmpsym(j, j) = tmp < prec.Eps2() ? 1. : tmp;
390 }
391
393 mfcn.NumOfCalls());
394 }
395
396 FunctionGradient gr(grd, g2, gst);
398
399 // if matrix is made pos def returns anyway edm
400 if (tmpErr.IsMadePosDef()) {
402 double edm = estim.Estimate(gr, err);
403 return MinimumState(st.Parameters(), err, gr, edm, mfcn.NumOfCalls());
404 }
405
406 // calculate edm for good errors
407 MinimumError err(vhmat, 0.);
408 double edm = estim.Estimate(gr, err);
409
410 print.Debug("Hessian is ACCURATE. New state:", "\n First derivative:", grd, "\n Second derivative:", g2,
411 "\n Gradient step:", gst, "\n Covariance matrix:", vhmat, "\n Edm:", edm);
412
413 return MinimumState(st.Parameters(), err, gr, edm, mfcn.NumOfCalls());
414}
415
416/*
417 MinimumError MnHesse::Hessian(const MnFcn& mfcn, const MinimumState& st, const MnUserTransformation& trafo) const {
418
419 const MnMachinePrecision& prec = trafo.Precision();
420 // make sure starting at the right place
421 double amin = mfcn(st.Vec());
422 // if(std::fabs(amin - st.Fval()) > prec.Eps2()) std::cout<<"function Value differs from amin by "<<amin -
423 st.Fval()<<std::endl;
424
425 double aimsag = std::sqrt(prec.Eps2())*(std::fabs(amin)+mfcn.Up());
426
427 // diagonal Elements first
428
429 unsigned int n = st.Parameters().Vec().size();
430 MnAlgebraicSymMatrix vhmat(n);
431 MnAlgebraicVector g2 = st.Gradient().G2();
432 MnAlgebraicVector gst = st.Gradient().Gstep();
433 MnAlgebraicVector grd = st.Gradient().Grad();
434 MnAlgebraicVector dirin = st.Gradient().Gstep();
435 MnAlgebraicVector yy(n);
436 MnAlgebraicVector x = st.Parameters().Vec();
437
438 for(unsigned int i = 0; i < n; i++) {
439
440 double xtf = x(i);
441 double dmin = 8.*prec.Eps2()*std::fabs(xtf);
442 double d = std::fabs(gst(i));
443 if(d < dmin) d = dmin;
444 for(int icyc = 0; icyc < Ncycles(); icyc++) {
445 double sag = 0.;
446 double fs1 = 0.;
447 double fs2 = 0.;
448 for(int multpy = 0; multpy < 5; multpy++) {
449 x(i) = xtf + d;
450 fs1 = mfcn(x);
451 x(i) = xtf - d;
452 fs2 = mfcn(x);
453 x(i) = xtf;
454 sag = 0.5*(fs1+fs2-2.*amin);
455 if(sag > prec.Eps2()) break;
456 if(trafo.Parameter(i).HasLimits()) {
457 if(d > 0.5) {
458 std::cout<<"second derivative zero for Parameter "<<i<<std::endl;
459 std::cout<<"return diagonal matrix "<<std::endl;
460 for(unsigned int j = 0; j < n; j++) {
461 vhmat(j,j) = (g2(j) < prec.Eps2() ? 1. : 1./g2(j));
462 return MinimumError(vhmat, 1., false);
463 }
464 }
465 d *= 10.;
466 if(d > 0.5) d = 0.51;
467 continue;
468 }
469 d *= 10.;
470 }
471 if(sag < prec.Eps2()) {
472 std::cout<<"MnHesse: internal loop exhausted, return diagonal matrix."<<std::endl;
473 for(unsigned int i = 0; i < n; i++)
474 vhmat(i,i) = (g2(i) < prec.Eps2() ? 1. : 1./g2(i));
475 return MinimumError(vhmat, 1., false);
476 }
477 double g2bfor = g2(i);
478 g2(i) = 2.*sag/(d*d);
479 grd(i) = (fs1-fs2)/(2.*d);
480 gst(i) = d;
481 dirin(i) = d;
482 yy(i) = fs1;
483 double dlast = d;
484 d = std::sqrt(2.*aimsag/std::fabs(g2(i)));
485 if(trafo.Parameter(i).HasLimits()) d = std::min(0.5, d);
486 if(d < dmin) d = dmin;
487
488 // see if converged
489 if(std::fabs((d-dlast)/d) < Tolerstp()) break;
490 if(std::fabs((g2(i)-g2bfor)/g2(i)) < TolerG2()) break;
491 d = std::min(d, 10.*dlast);
492 d = std::max(d, 0.1*dlast);
493 }
494 vhmat(i,i) = g2(i);
495 }
496
497 //off-diagonal Elements
498 for(unsigned int i = 0; i < n; i++) {
499 x(i) += dirin(i);
500 for(unsigned int j = i+1; j < n; j++) {
501 x(j) += dirin(j);
502 double fs1 = mfcn(x);
503 double elem = (fs1 + amin - yy(i) - yy(j))/(dirin(i)*dirin(j));
504 vhmat(i,j) = elem;
505 x(j) -= dirin(j);
506 }
507 x(i) -= dirin(i);
508 }
509
510 return MinimumError(vhmat, 0.);
511 }
512 */
513
514} // namespace Minuit2
515
516} // namespace ROOT
#define d(i)
Definition: RSha256.hxx:102
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void gc
Similar to the AnalyticalGradientCalculator, the ExternalInternalGradientCalculator supplies Minuit w...
Interface (abstract class) defining the function to be minimized, which has to be implemented by the ...
Definition: FCNBase.h:45
virtual double Up() const =0
Error definition of the function.
virtual GradientParameterSpace gradParameterSpace() const
const MnAlgebraicVector & Gstep() const
const MnAlgebraicVector & Grad() const
const MnAlgebraicVector & G2() const
class holding the full result of the minimization; both internal and external (MnUserParameterState) ...
void Add(const MinimumState &state, Status status=MnValid)
add latest minimization state (for example add Hesse result after Migrad)
const MnUserParameterState & UserState() const
const MinimumState & State() const
HessianGradientCalculator: class to calculate Gradient for Hessian.
Class describing a symmetric matrix of size n.
Definition: LASymMatrix.h:45
unsigned int Nrow() const
Definition: LASymMatrix.h:273
unsigned int size() const
Definition: LAVector.h:231
unsigned int StartElementIndex() const
Definition: MPIProcess.h:55
bool SyncSymMatrixOffDiagonal(ROOT::Minuit2::MnAlgebraicSymMatrix &mnmatrix)
Definition: MPIProcess.cxx:193
unsigned int EndElementIndex() const
Definition: MPIProcess.h:61
MinimumError keeps the inv.
Definition: MinimumError.h:28
const MnAlgebraicSymMatrix & InvHessian() const
Definition: MinimumError.h:50
const MnAlgebraicVector & Vec() const
MinimumState keeps the information (position, Gradient, 2nd deriv, etc) after one minimization step (...
Definition: MinimumState.h:27
const MnAlgebraicVector & Vec() const
Definition: MinimumState.h:58
const MinimumParameters & Parameters() const
Definition: MinimumState.h:57
const FunctionGradient & Gradient() const
Definition: MinimumState.h:62
Wrapper class to FCNBase interface used internally by Minuit.
Definition: MnFcn.h:30
double Up() const
Definition: MnFcn.cxx:39
const FCNBase & Fcn() const
Definition: MnFcn.h:47
unsigned int NumOfCalls() const
Definition: MnFcn.h:39
double Tolerstp() const
Definition: MnHesse.h:90
unsigned int Ncycles() const
forward interface of MnStrategy
Definition: MnHesse.h:89
MnUserParameterState operator()(const FCNBase &, const std::vector< double > &, const std::vector< double > &, unsigned int maxcalls=0) const
low-level API
Definition: MnHesse.cxx:31
MinimumState ComputeNumerical(const MnFcn &, const MinimumState &, const MnUserTransformation &, unsigned int maxcalls) const
internal function to compute the Hessian using numerical derivative computation
Definition: MnHesse.cxx:188
MnStrategy fStrategy
Definition: MnHesse.h:101
MinimumState ComputeAnalytical(const FCNGradientBase &, const MinimumState &, const MnUserTransformation &) const
internal function to compute the Hessian using an analytical computation or externally provided in th...
Definition: MnHesse.cxx:117
double TolerG2() const
Definition: MnHesse.h:91
Sets the relative floating point (double) arithmetic precision.
double Eps2() const
eps2 returns 2*sqrt(eps)
Force the covariance matrix to be positive defined by adding extra terms in the diagonal.
Definition: MnPosDef.h:25
void Debug(const Ts &... args)
Definition: MnPrint.h:147
void Error(const Ts &... args)
Definition: MnPrint.h:129
void Info(const Ts &... args)
Definition: MnPrint.h:141
void Warn(const Ts &... args)
Definition: MnPrint.h:135
unsigned int Strategy() const
Definition: MnStrategy.h:38
Class containing the covariance matrix data represented as a vector of size n*(n+1)/2 Used to hide in...
Wrapper used by Minuit of FCN interface containing a reference to the transformation object.
Definition: MnUserFcn.h:25
class which holds the external user and/or internal Minuit representation of the parameters and error...
const std::vector< double > & IntParameters() const
const MnUserTransformation & Trafo() const
API class for the user interaction with the parameters; serves as input to the minimizer as well as o...
class dealing with the transformation between user specified parameters (external) and internal param...
unsigned int ExtOfInt(unsigned int internal) const
const char * Name(unsigned int) const
const MnMachinePrecision & Precision() const
forwarded interface
const MinuitParameter & Parameter(unsigned int) const
class performing the numerical gradient calculation
double Estimate(const FunctionGradient &, const MinimumError &) const
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
TGraphErrors * gr
Definition: legend1.C:25
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
int Invert(LASymMatrix &)
Definition: LaInverse.cxx:21
LASymMatrix MnAlgebraicSymMatrix
Definition: MnMatrixfwd.h:21
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.