Logo ROOT  
Reference Guide
AnalyticalGradientCalculator.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
15#include "Minuit2/MnMatrix.h"
16#include "Minuit2/MnPrint.h"
17#include <cassert>
18
19namespace ROOT {
20namespace Minuit2 {
21
23{
24 // evaluate analytical gradient. take care of parameter transformations
25
26 std::vector<double> grad = fGradFunc.Gradient(fTransformation(par.Vec()));
27 assert(grad.size() == fTransformation.Parameters().size());
28
29 MnAlgebraicVector v(par.Vec().size());
30 for (unsigned int i = 0; i < par.Vec().size(); i++) {
31 unsigned int ext = fTransformation.ExtOfInt(i);
33 double dd = fTransformation.DInt2Ext(i, par.Vec()(i));
34 v(i) = dd * grad[ext];
35 } else {
36 v(i) = grad[ext];
37 }
38 }
39
40 MnPrint print("AnalyticalGradientCalculator");
41 print.Debug("User given gradient in Minuit2", v);
42
43 // in case we can compute Hessian do not waste re-computing G2 here
45 return FunctionGradient(v);
46
47 // compute G2 if possible
48 MnAlgebraicVector g2(par.Vec().size());
49 if (!this->G2(par, g2)) {
50 print.Error("Error computing G2");
51 return FunctionGradient(v);
52 }
53 return FunctionGradient(v,g2);
54}
55
57{
58 // needed from base class
59 return (*this)(par);
60}
61
63{
64 // check to be sure FCN implements analytical gradient
65 return fGradFunc.CheckGradient();
66}
67
68// G2 can be computed directly without Hessian or via the Hessian
70 return fGradFunc.HasG2() || fGradFunc.HasHessian();
71}
72
74 return fGradFunc.HasHessian();
75}
76
77
79{
80 // compute Hessian using external gradient
81 unsigned int n = par.Vec().size();
82 assert(hmat.size() == n *(n+1)/2);
83 // compute external Hessian and then transform
84 std::vector<double> extHessian = fGradFunc.Hessian(fTransformation(par.Vec()));
85 if (extHessian.empty()) {
86 MnPrint print("AnalyticalGradientCalculator::Hessian");
87 print.Info("FCN cannot compute Hessian matrix");
88 return false;
89 }
90 unsigned int next = sqrt(extHessian.size());
91 // we need now to transform the matrix from external to internal coordinates
92 for (unsigned int i = 0; i < n; i++) {
93 unsigned int iext = fTransformation.ExtOfInt(i);
94 double dxdi = 1.;
95 if (fTransformation.Parameters()[iext].HasLimits()) {
96 dxdi = fTransformation.DInt2Ext(i, par.Vec()(i));
97 }
98 for (unsigned int j = i; j < n; j++) {
99 double dxdj = 1.;
100 unsigned int jext = fTransformation.ExtOfInt(j);
101 if (fTransformation.Parameters()[jext].HasLimits()) {
102 dxdj = fTransformation.DInt2Ext(j, par.Vec()(j));
103 }
104 hmat(i, j) = dxdi * extHessian[i*next+ j] * dxdj;
105 }
106 }
107 return true;
108}
109
111 // compute G2 using external calculator
112 unsigned int n = par.Vec().size(); // n is size of internal parameters
113 assert(g2.size() == n );
114 std::vector<double> extG2 = fGradFunc.G2(fTransformation(par.Vec()));
115 if (extG2.empty()) {
116 MnPrint print("AnalyticalGradientCalculator::G2");
117 print.Info("FCN cannot compute the 2nd derivatives vector (G2)");
118 return false;
119 }
120 assert(extG2.size() == fTransformation.Parameters().size());
121 // we need now to transform the matrix from external to internal coordinates
122 for (unsigned int i = 0; i < n; i++) {
123 unsigned int iext = fTransformation.ExtOfInt(i);
124 if (fTransformation.Parameters()[iext].HasLimits()) {
125 double dxdi = fTransformation.DInt2Ext(i, par.Vec()(i));
126 g2(i) = dxdi * dxdi * extG2[iext];
127 } else {
128 g2(i) = extG2[iext];
129 }
130 }
131 return true;
132}
133
134} // namespace Minuit2
135
136} // namespace ROOT
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
FunctionGradient operator()(const MinimumParameters &) const override
virtual bool G2(const MinimumParameters &, MnAlgebraicVector &) const
compute second derivatives (diagonal of Hessian)
bool Hessian(const MinimumParameters &, MnAlgebraicSymMatrix &) const override
compute Hessian matrix
virtual std::vector< double > G2(const std::vector< double > &) const
return second derivatives (diagonal of the Hessian matrix)
virtual std::vector< double > Gradient(const std::vector< double > &) const =0
virtual std::vector< double > Hessian(const std::vector< double > &) const
return Hessian
virtual bool HasHessian() const
virtual bool CheckGradient() const
virtual bool HasG2() const
Class describing a symmetric matrix of size n.
Definition: LASymMatrix.h:45
unsigned int size() const
Definition: LASymMatrix.h:271
unsigned int size() const
Definition: LAVector.h:231
const MnAlgebraicVector & Vec() const
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
unsigned int ExtOfInt(unsigned int internal) const
double DInt2Ext(unsigned int, double) const
const std::vector< MinuitParameter > & Parameters() const
const MinuitParameter & Parameter(unsigned int) const
const Int_t n
Definition: legend1.C:16
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.