Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:16

0001 // @(#)root/mathcore:$Id$
0002 // Author: L. Moneta Thu Aug 16 15:40:28 2007
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2007  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for class FitMethodFunction
0012 
0013 #ifndef ROOT_Math_FitMethodFunction
0014 #define ROOT_Math_FitMethodFunction
0015 
0016 #include "Math/IFunction.h"
0017 #include <vector>
0018 #include <limits>
0019 
0020 // #ifndef ROOT_Math_IParamFunctionfwd
0021 // #include "Math/IParamFunctionfwd.h"
0022 // #endif
0023 
0024 namespace ROOT {
0025 
0026    namespace Math {
0027 
0028 //______________________________________________________________________________________
0029 /**
0030    FitMethodFunction class
0031    Interface for objective functions (like chi2 and likelihood used in the fit)
0032    In addition to normal function interface provide interface for calculating each
0033    data contribution to the function which is required by some algorithm (like Fumili)
0034 
0035    @ingroup  FitMethodFunc
0036 */
0037 template<class FunctionType>
0038 class BasicFitMethodFunction : public FunctionType {
0039 
0040 public:
0041 
0042 
0043    typedef  typename FunctionType::BaseFunc BaseFunction;
0044 
0045    /// enumeration specifying the possible fit method types
0046    enum Type_t { kUndefined  = 0, kLeastSquare, kLogLikelihood, kPoissonLikelihood };
0047 
0048 
0049    BasicFitMethodFunction(int dim, int npoint) :
0050       fNDim(dim),
0051       fNPoints(npoint),
0052       fNCalls(0)
0053    {}
0054 
0055    /**
0056       Virtual Destructor (no operations)
0057    */
0058    ~BasicFitMethodFunction () override  {}
0059 
0060    /**
0061       Number of dimension (parameters) . From IGenMultiFunction interface
0062     */
0063    unsigned int NDim() const override { return fNDim; }
0064 
0065    /**
0066       method returning the data i-th contribution to the fit objective function
0067       For example the residual for the least square functions or the pdf element for the
0068       likelihood functions.
0069       Estimating also the gradient of the data element if the passed pointer  is not null
0070       and the Hessian. The flag fullHessian is set when one needs to compute the full Hessian (not the approximated one)
0071       and should be used when the full second derivatives of the model functions are available
0072     */
0073    virtual double DataElement(const double *x, unsigned int i, double *g = nullptr, double *h = nullptr, bool fullHessian = false) const = 0;
0074 
0075    // flag to indicate if full Hessian computation is supported
0076    virtual bool HasHessian() const { return false;}
0077 
0078    /**
0079     * Computes the full Hessian. Return false if Hessian is not supported
0080     */
0081    virtual bool Hessian(const double * x, double * hess) const {
0082       //return full Hessian of  the objective function which is Sum(F(i))
0083       unsigned int np = NPoints();
0084       unsigned int ndim = NDim();
0085       unsigned int nh = ndim*(ndim+1)/2;
0086       for (unsigned int k = 0; k < nh;  ++k) {
0087          hess[k] = 0;
0088       }
0089       std::vector<double> g(np);  // gradient of the F(i)
0090       std::vector<double> h(nh);  // hessian of F(i)
0091       for (unsigned int i = 0; i < np; i++) {
0092          double f = DataElement(x,i,g.data(),h.data(),true);
0093          if (f == std::numeric_limits<double>::quiet_NaN() ) return false;
0094          for (unsigned int j = 0; j < nh; j++) {
0095             hess[j] += h[j];
0096          }
0097       }
0098       return true;
0099    }
0100 
0101    /**
0102     * Computes the Second derivatives. Return false if this is not supported
0103     */
0104    virtual bool G2(const double * , double * ) const { return false; }
0105 
0106    /**
0107       return the number of data points used in evaluating the function
0108     */
0109    virtual unsigned int NPoints() const { return fNPoints; }
0110 
0111    /**
0112       return the type of method, override if needed
0113     */
0114    virtual Type_t Type() const { return kUndefined; }
0115 
0116    /**
0117       return the total number of function calls (override if needed)
0118     */
0119    virtual unsigned int NCalls() const { return fNCalls; }
0120 
0121    /**
0122       update number of calls
0123     */
0124    virtual void UpdateNCalls() const { fNCalls++; }
0125 
0126    /**
0127       reset number of function calls
0128     */
0129    virtual void ResetNCalls() { fNCalls = 0; }
0130 
0131 
0132    /**
0133       Static function to indicate if a function is supporting gradient
0134    */
0135    static bool IsAGradFCN() {
0136      return false;
0137   }
0138 
0139 private:
0140 
0141    unsigned int fNDim;      // function dimension
0142    unsigned int fNPoints;   // size of the data
0143    mutable unsigned int fNCalls; // number of function calls
0144 
0145 
0146 };
0147 
0148 template<>
0149 inline bool BasicFitMethodFunction<ROOT::Math::IMultiGradFunction>::IsAGradFCN() {
0150    return true;
0151 }
0152 
0153 // define the normal and gradient function
0154 typedef BasicFitMethodFunction<ROOT::Math::IMultiGenFunction>  FitMethodFunction;
0155 typedef BasicFitMethodFunction<ROOT::Math::IMultiGradFunction> FitMethodGradFunction;
0156 
0157 
0158 
0159 } // end namespace Math
0160 
0161 } // end namespace ROOT
0162 
0163 
0164 
0165 
0166 
0167 
0168 #endif /* ROOT_Math_FitMethodFunction */