|
|
|||
File indexing completed on 2025-12-15 10:28:18
0001 // @(#)root/mathcore:$Id$ 0002 // Authors: L. Moneta 11/2006 0003 0004 /********************************************************************** 0005 * * 0006 * Copyright (c) 2006 , LCG ROOT MathLib Team * 0007 * * 0008 * * 0009 **********************************************************************/ 0010 0011 // Header file for function interfaces 0012 // 0013 // Generic Interfaces for one or multi-dimensional functions 0014 // 0015 // Created by: Lorenzo Moneta : Wed Nov 13 2006 0016 // 0017 // 0018 #ifndef ROOT_Math_IFunction 0019 #define ROOT_Math_IFunction 0020 0021 /** 0022 @defgroup CppFunctions Function Classes and Interfaces 0023 0024 Interfaces (abstract classes) and Base classes used in MathCore and MathMore numerical methods 0025 for describing function classes. They define function and gradient evaluation and as well the 0026 functionality for dealing with parameters in the case of parametric functions which are used for 0027 fitting and data modeling. 0028 Included are also adapter classes, such as functors, to wrap generic callable C++ objects 0029 in the desired interface. 0030 0031 @ingroup MathCore 0032 */ 0033 0034 #include "Math/IFunctionfwd.h" 0035 0036 0037 namespace ROOT { 0038 namespace Math { 0039 0040 /** 0041 @defgroup GenFunc Generic Function Evaluation Interfaces 0042 Interface classes for evaluation of function object classes in one or multi-dimensions. 0043 @ingroup CppFunctions 0044 */ 0045 0046 //___________________________________________________________________________________ 0047 /** 0048 Documentation for the abstract class IBaseFunctionMultiDim. 0049 Interface (abstract class) for generic functions objects of multi-dimension 0050 Provides a method to evaluate the function given a vector of coordinate values, 0051 by implementing operator() (const double *). 0052 In addition it defines the interface for copying functions via the pure virtual method Clone() 0053 and the interface for getting the function dimension via the NDim() method. 0054 Derived classes must implement the pure private virtual method DoEval(const double *) for the 0055 function evaluation in addition to NDim() and Clone(). 0056 0057 @note ROOT::Math::Functor is the recommended way to use one's own function with the fitting framework. 0058 0059 @ingroup GenFunc 0060 */ 0061 0062 template<class T> 0063 class IBaseFunctionMultiDimTempl { 0064 0065 public: 0066 0067 typedef T BackendType; 0068 typedef IBaseFunctionMultiDimTempl<T> BaseFunc; 0069 0070 virtual ~IBaseFunctionMultiDimTempl() = default; 0071 0072 /// Clone a function. 0073 /// Each derived class must implement their version of the Clone method. 0074 virtual IBaseFunctionMultiDimTempl<T> *Clone() const = 0; 0075 0076 /// Retrieve the dimension of the function. 0077 virtual unsigned int NDim() const = 0; 0078 0079 /// Evaluate the function at a point x[]. 0080 /// Use the pure virtual private method DoEval which must be implemented by the sub-classes. 0081 T operator()(const T *x) const { return DoEval(x); } 0082 0083 #ifdef LATER 0084 /// Template method to evaluate the function using the begin of an iterator. 0085 /// User is responsible to provide correct size for the iterator. 0086 template <class Iterator> 0087 T operator()(const Iterator it) const { return DoEval(&(*it)); } 0088 #endif 0089 0090 // Indicate whether this class supports gradient calculations, i.e., 0091 // if it inherits from ROOT::Math::IGradientFunctionMultiDim. 0092 virtual bool HasGradient() const { return false; } 0093 0094 /// Evaluate all the vector of function derivatives (gradient) at a point x. 0095 /// Derived classes must re-implement it if more efficient than evaluating one at a time 0096 virtual void Gradient(const T *x, T *grad) const 0097 { 0098 unsigned int ndim = NDim(); 0099 for (unsigned int icoord = 0; icoord < ndim; ++icoord) { 0100 grad[icoord] = Derivative(x, icoord); 0101 } 0102 } 0103 0104 /// Optimized method to evaluate at the same time the function value and derivative at a point x. 0105 /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. 0106 /// Derived class should implement this method if performances play an important role and if it is faster to 0107 /// evaluate value and derivative at the same time 0108 virtual void FdF(const T *x, T &f, T *df) const 0109 { 0110 f = operator()(x); 0111 Gradient(x, df); 0112 } 0113 0114 /// Return the partial derivative with respect to the passed coordinate. 0115 T Derivative(const T *x, unsigned int icoord = 0) const { return DoDerivative(x, icoord); } 0116 0117 /// In some cases, the derivative algorithm will use information from the previous step, these can be passed 0118 /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size 0119 /// so that these can be passed forward again as well at the call site, if necessary. 0120 T Derivative(const T *x, unsigned int icoord, T *previous_grad, T *previous_g2, 0121 T *previous_gstep) const 0122 { 0123 return DoDerivativeWithPrevResult(x, icoord, previous_grad, previous_g2, previous_gstep); 0124 } 0125 0126 private: 0127 /// Implementation of the evaluation function. Must be implemented by derived classes. 0128 virtual T DoEval(const T *x) const = 0; 0129 0130 /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. 0131 virtual T DoDerivative(const T * /*x*/, unsigned int /*icoord*/) const { return {}; } 0132 0133 /// In some cases, the derivative algorithm will use information from the previous step, these can be passed 0134 /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size 0135 /// so that these can be passed forward again as well at the call site, if necessary. 0136 virtual T DoDerivativeWithPrevResult(const T *x, unsigned int icoord, T * /*previous_grad*/, 0137 T * /*previous_g2*/, T * /*previous_gstep*/) const 0138 { 0139 return DoDerivative(x, icoord); 0140 } 0141 }; 0142 0143 0144 //___________________________________________________________________________________ 0145 /** 0146 Interface (abstract class) for generic functions objects of one-dimension 0147 Provides a method to evaluate the function given a value (simple double) 0148 by implementing operator() (const double ). 0149 In addition it defines the interface for copying functions via the pure virtual method Clone(). 0150 Derived classes must implement the pure virtual private method DoEval(double ) for the 0151 function evaluation in addition to Clone(). 0152 An interface for evaluating the function passing a vector (like for multidim functions) is also 0153 provided 0154 0155 @ingroup GenFunc 0156 */ 0157 class IBaseFunctionOneDim { 0158 0159 public: 0160 0161 typedef IBaseFunctionOneDim BaseFunc; 0162 0163 virtual ~IBaseFunctionOneDim() = default; 0164 0165 /// Clone a function. 0166 /// Each derived class will implement their version of the private DoClone method. 0167 virtual IBaseFunctionOneDim *Clone() const = 0; 0168 0169 /// Evaluate the function at a point x. 0170 /// Use the a pure virtual private method DoEval which must be implemented by sub-classes. 0171 double operator()(double x) const { return DoEval(x); } 0172 0173 /// Evaluate the function at a point x[]. 0174 /// Compatible method with multi-dimensional functions. 0175 double operator()(const double *x) const { return DoEval(*x); } 0176 0177 // Indicate whether this class supports gradient calculations, i.e., 0178 // if it inherits from ROOT::Math::IGradientFunctionOneDim. 0179 virtual bool HasGradient() const { return false; } 0180 0181 /// Return the derivative of the function at a point x 0182 /// Use the private method DoDerivative 0183 double Derivative(double x) const { return DoDerivative(x); } 0184 0185 /// Compatibility method with multi-dimensional interface for partial derivative. 0186 double Derivative(const double *x) const { return DoDerivative(*x); } 0187 0188 /// Compatibility method with multi-dimensional interface for Gradient. 0189 void Gradient(const double *x, double *g) const { g[0] = DoDerivative(*x); } 0190 0191 /// Optimized method to evaluate at the same time the function value and derivative at a point x. 0192 /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. 0193 /// Derived class should implement this method if performances play an important role and if it is faster to 0194 /// evaluate value and derivative at the same time. 0195 virtual void FdF(double x, double &f, double &df) const 0196 { 0197 f = operator()(x); 0198 df = Derivative(x); 0199 } 0200 0201 /// Compatibility method with multi-dimensional interface for Gradient and function evaluation. 0202 void FdF(const double *x, double &f, double *df) const { FdF(*x, f, *df); } 0203 0204 private: 0205 0206 /// implementation of the evaluation function. Must be implemented by derived classes 0207 virtual double DoEval(double x) const = 0; 0208 0209 /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. 0210 virtual double DoDerivative(double) const { return 0.; } 0211 }; 0212 0213 0214 //-------- GRAD functions--------------------------- 0215 0216 0217 0218 //___________________________________________________________________________________ 0219 /** 0220 Interface (abstract class) for multi-dimensional functions providing a gradient calculation. 0221 The method ROOT::Math::IFunction::Gradient calculates the full gradient vector, 0222 ROOT::Math::IFunction::Derivative calculates the partial derivative for each coordinate and 0223 ROOT::Math::Fdf calculates the gradient and the function value at the same time. 0224 The pure private virtual method DoDerivative() must be implemented by the derived classes, while 0225 Gradient and FdF are by default implemented using DoDerivative, butthey can be overloaded by the 0226 derived classes to improve the efficiency in the derivative calculation. 0227 0228 Gradient interface (abstract class) defining the signature for calculating the gradient of a 0229 multi-dimensional function. 0230 Three methods are provided: 0231 - Gradient(const double *x, double * grad) evaluate the full gradient vector at the vector value x 0232 - Derivative(const double * x, int icoord) evaluate the partial derivative for the icoord coordinate 0233 - FdF(const double *x, double &f, double * g) evaluate at the same time gradient and function/ 0234 0235 @ingroup GenFunc 0236 */ 0237 0238 template <class T> 0239 class IGradientFunctionMultiDimTempl : virtual public IBaseFunctionMultiDimTempl<T> { 0240 0241 public: 0242 0243 bool HasGradient() const override { return true; } 0244 }; 0245 0246 0247 //___________________________________________________________________________________ 0248 /** 0249 Interface (abstract class) for one-dimensional functions providing a gradient calculation. 0250 The method ROOT::Math::IFunction::Derivative calculates the derivative and 0251 ROOT::Math::Fdf calculates the derivative and the function values at the same time. 0252 The pure private virtual method DoDerivative() must be implemented by the derived classes, while 0253 FdF is by default implemented using DoDerivative, but it can be overloaded by the 0254 derived classes to improve the efficiency in the derivative calculation. 0255 0256 Specialized Gradient interface(abstract class) for one dimensional functions 0257 It provides a method to evaluate the derivative of the function, Derivative and a 0258 method to evaluate at the same time the function and the derivative FdF 0259 0260 @ingroup GenFunc 0261 */ 0262 class IGradientFunctionOneDim : virtual public IBaseFunctionOneDim { 0263 0264 public: 0265 0266 bool HasGradient() const override { return true; } 0267 }; 0268 0269 0270 0271 } // namespace Math 0272 } // namespace ROOT 0273 0274 #endif /* ROOT_Math_IFunction */
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|