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 #ifndef ROOT_Minuit2_FumiliFCNBase
11 #define ROOT_Minuit2_FumiliFCNBase
12 
13 #include "Minuit2/FCNBase.h"
14 #include <cassert>
15 #include <vector>
16 
17 namespace ROOT {
18 
19 namespace Minuit2 {
20 
21 //____________________________________________________________________________________________
22 /**
23 
24 Extension of the FCNBase for the Fumili method. Fumili applies only to
25 minimization problems used for fitting. The method is based on a
26 linearization of the model function negleting second derivatives.
27 User needs to provide the model function. The figure-of-merit describing
28 the difference between the model function and the actual measurements
29 has to be implemented by the user in a subclass of FumiliFCNBase.
30 For an example see the FumiliChi2FCN and FumiliStandardChi2FCN classes.
31 
32 
33 @author  Andras Zsenei and Lorenzo Moneta, Creation date: 23 Aug 2004
34 
35 @see <A HREF="http://www.cern.ch/winkler/minuit/tutorial/mntutorial.pdf">MINUIT Tutorial</A> on function minimization,
36 section 5
37 
38 @see FumiliChi2FCN
39 
40 @see FumiliStandardChi2FCN
41 
42 @ingroup Minuit
43 
44  */
45 
46 class FumiliFCNBase : public FCNBase {
47 
48 public:
49    /**
50       Default Constructor. Need in this case to create when implementing EvaluateAll the Gradient and Hessian vectors
51       with the right size
52    */
53 
FumiliFCNBase()54    FumiliFCNBase() : fNumberOfParameters(0), fValue(0) {}
55 
56    /**
57 
58       Constructor which initializes the class with the function provided by the
59       user for modeling the data.
60 
61       @param npar the number of parameters
62 
63    */
64 
FumiliFCNBase(unsigned int npar)65    FumiliFCNBase(unsigned int npar)
66       : fNumberOfParameters(npar), fValue(0), fGradient(std::vector<double>(npar)),
67         fHessian(std::vector<double>(static_cast<int>(0.5 * npar * (npar + 1))))
68    {
69    }
70 
71    //   FumiliFCNBase(const ParametricFunction& modelFCN) { fModelFunction = &modelFCN; }
72 
~FumiliFCNBase()73    virtual ~FumiliFCNBase() {}
74 
75    /**
76 
77       Evaluate function Value, Gradient and Hessian using Fumili approximation, for values of parameters p
78       The resul is cached inside and is return from the FumiliFCNBase::Value ,  FumiliFCNBase::Gradient and
79       FumiliFCNBase::Hessian methods
80 
81       @param par vector of parameters
82 
83    **/
84 
85    virtual void EvaluateAll(const std::vector<double> &par) = 0;
86 
87    /**
88       Return cached Value of objective function estimated previously using the  FumiliFCNBase::EvaluateAll method
89 
90    **/
91 
Value()92    virtual double Value() const { return fValue; }
93 
94    /**
95       Return cached Value of function Gradient estimated previously using the  FumiliFCNBase::EvaluateAll method
96    **/
97 
Gradient()98    virtual const std::vector<double> &Gradient() const { return fGradient; }
99 
100    /**
101       Return Value of the i-th j-th element of the Hessian matrix estimated previously using the
102    FumiliFCNBase::EvaluateAll method
103       @param row row Index of the matrix
104       @param col col Index of the matrix
105    **/
106 
Hessian(unsigned int row,unsigned int col)107    virtual double Hessian(unsigned int row, unsigned int col) const
108    {
109       assert(row < fGradient.size() && col < fGradient.size());
110       if (row > col)
111          return fHessian[col + row * (row + 1) / 2];
112       else
113          return fHessian[row + col * (col + 1) / 2];
114    }
115 
116    /**
117       return number of function variable (parameters) , i.e. function dimension
118    */
119 
Dimension()120    virtual unsigned int Dimension() { return fNumberOfParameters; }
121 
122 protected:
123    /**
124       initialize and reset values of gradien and Hessian
125    */
126 
InitAndReset(unsigned int npar)127    virtual void InitAndReset(unsigned int npar)
128    {
129       fNumberOfParameters = npar;
130       fGradient = std::vector<double>(npar);
131       fHessian = std::vector<double>(static_cast<int>(0.5 * npar * (npar + 1)));
132    }
133 
134    // methods to be used by the derived classes to set the values
SetFCNValue(double value)135    void SetFCNValue(double value) { fValue = value; }
136 
Gradient()137    std::vector<double> &Gradient() { return fGradient; }
138 
Hessian()139    std::vector<double> &Hessian() { return fHessian; }
140 
141 private:
142    unsigned int fNumberOfParameters;
143    double fValue;
144    std::vector<double> fGradient;
145    std::vector<double> fHessian;
146 };
147 
148 } // namespace Minuit2
149 
150 } // namespace ROOT
151 
152 #endif // ROOT_Minuit2_FumiliFCNBase
153