![]() |
|
|||
File indexing completed on 2025-09-16 09:08:10
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 private: 0095 0096 /// Implementation of the evaluation function. Must be implemented by derived classes. 0097 virtual T DoEval(const T *x) const = 0; 0098 }; 0099 0100 0101 //___________________________________________________________________________________ 0102 /** 0103 Interface (abstract class) for generic functions objects of one-dimension 0104 Provides a method to evaluate the function given a value (simple double) 0105 by implementing operator() (const double ). 0106 In addition it defines the interface for copying functions via the pure virtual method Clone(). 0107 Derived classes must implement the pure virtual private method DoEval(double ) for the 0108 function evaluation in addition to Clone(). 0109 An interface for evaluating the function passing a vector (like for multidim functions) is also 0110 provided 0111 0112 @ingroup GenFunc 0113 */ 0114 class IBaseFunctionOneDim { 0115 0116 public: 0117 0118 typedef IBaseFunctionOneDim BaseFunc; 0119 0120 virtual ~IBaseFunctionOneDim() = default; 0121 0122 /// Clone a function. 0123 /// Each derived class will implement their version of the private DoClone method. 0124 virtual IBaseFunctionOneDim *Clone() const = 0; 0125 0126 /// Evaluate the function at a point x. 0127 /// Use the a pure virtual private method DoEval which must be implemented by sub-classes. 0128 double operator()(double x) const { return DoEval(x); } 0129 0130 /// Evaluate the function at a point x[]. 0131 /// Compatible method with multi-dimensional functions. 0132 double operator()(const double *x) const { return DoEval(*x); } 0133 0134 // Indicate whether this class supports gradient calculations, i.e., 0135 // if it inherits from ROOT::Math::IGradientFunctionOneDim. 0136 virtual bool HasGradient() const { return false; } 0137 0138 private: 0139 0140 /// implementation of the evaluation function. Must be implemented by derived classes 0141 virtual double DoEval(double x) const = 0; 0142 }; 0143 0144 0145 //-------- GRAD functions--------------------------- 0146 0147 0148 0149 //___________________________________________________________________________________ 0150 /** 0151 Interface (abstract class) for multi-dimensional functions providing a gradient calculation. 0152 The method ROOT::Math::IFunction::Gradient calculates the full gradient vector, 0153 ROOT::Math::IFunction::Derivative calculates the partial derivative for each coordinate and 0154 ROOT::Math::Fdf calculates the gradient and the function value at the same time. 0155 The pure private virtual method DoDerivative() must be implemented by the derived classes, while 0156 Gradient and FdF are by default implemented using DoDerivative, butthey can be overloaded by the 0157 derived classes to improve the efficiency in the derivative calculation. 0158 0159 Gradient interface (abstract class) defining the signature for calculating the gradient of a 0160 multi-dimensional function. 0161 Three methods are provided: 0162 - Gradient(const double *x, double * grad) evaluate the full gradient vector at the vector value x 0163 - Derivative(const double * x, int icoord) evaluate the partial derivative for the icoord coordinate 0164 - FdF(const double *x, double &f, double * g) evaluate at the same time gradient and function/ 0165 0166 @ingroup GenFunc 0167 */ 0168 0169 template <class T> 0170 class IGradientFunctionMultiDimTempl : virtual public IBaseFunctionMultiDimTempl<T> { 0171 0172 public: 0173 typedef IBaseFunctionMultiDimTempl<T> BaseFunc; 0174 typedef IGradientFunctionMultiDimTempl<T> BaseGrad; 0175 0176 0177 /// Evaluate all the vector of function derivatives (gradient) at a point x. 0178 /// Derived classes must re-implement it if more efficient than evaluating one at a time 0179 virtual void Gradient(const T *x, T *grad) const 0180 { 0181 unsigned int ndim = NDim(); 0182 for (unsigned int icoord = 0; icoord < ndim; ++icoord) { 0183 grad[icoord] = Derivative(x, icoord); 0184 } 0185 } 0186 0187 /// In some cases, the gradient algorithm will use information from the previous step, these can be passed 0188 /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size 0189 /// so that these can be passed forward again as well at the call site, if necessary. 0190 virtual void GradientWithPrevResult(const T *x, T *grad, T *previous_grad, T *previous_g2, T *previous_gstep) const 0191 { 0192 unsigned int ndim = NDim(); 0193 for (unsigned int icoord = 0; icoord < ndim; ++icoord) { 0194 grad[icoord] = Derivative(x, icoord, previous_grad, previous_g2, previous_gstep); 0195 } 0196 } 0197 0198 using BaseFunc::NDim; 0199 0200 /// Optimized method to evaluate at the same time the function value and derivative at a point x. 0201 /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. 0202 /// Derived class should implement this method if performances play an important role and if it is faster to 0203 /// evaluate value and derivative at the same time 0204 virtual void FdF(const T *x, T &f, T *df) const 0205 { 0206 f = BaseFunc::operator()(x); 0207 Gradient(x, df); 0208 } 0209 0210 /// Return the partial derivative with respect to the passed coordinate. 0211 T Derivative(const T *x, unsigned int icoord = 0) const { return DoDerivative(x, icoord); } 0212 0213 /// In some cases, the derivative algorithm will use information from the previous step, these can be passed 0214 /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size 0215 /// so that these can be passed forward again as well at the call site, if necessary. 0216 T Derivative(const T *x, unsigned int icoord, T *previous_grad, T *previous_g2, 0217 T *previous_gstep) const 0218 { 0219 return DoDerivativeWithPrevResult(x, icoord, previous_grad, previous_g2, previous_gstep); 0220 } 0221 0222 bool HasGradient() const { return true; } 0223 0224 virtual bool returnsInMinuit2ParameterSpace() const { return false; } 0225 0226 private: 0227 /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. 0228 virtual T DoDerivative(const T *x, unsigned int icoord) const = 0; 0229 0230 /// In some cases, the derivative algorithm will use information from the previous step, these can be passed 0231 /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size 0232 /// so that these can be passed forward again as well at the call site, if necessary. 0233 virtual T DoDerivativeWithPrevResult(const T *x, unsigned int icoord, T * /*previous_grad*/, 0234 T * /*previous_g2*/, T * /*previous_gstep*/) const 0235 { 0236 return DoDerivative(x, icoord); 0237 } 0238 }; 0239 0240 0241 //___________________________________________________________________________________ 0242 /** 0243 Interface (abstract class) for one-dimensional functions providing a gradient calculation. 0244 The method ROOT::Math::IFunction::Derivative calculates the derivative and 0245 ROOT::Math::Fdf calculates the derivative and the function values at the same time. 0246 The pure private virtual method DoDerivative() must be implemented by the derived classes, while 0247 FdF is by default implemented using DoDerivative, but it can be overloaded by the 0248 derived classes to improve the efficiency in the derivative calculation. 0249 0250 Specialized Gradient interface(abstract class) for one dimensional functions 0251 It provides a method to evaluate the derivative of the function, Derivative and a 0252 method to evaluate at the same time the function and the derivative FdF 0253 0254 @ingroup GenFunc 0255 */ 0256 class IGradientFunctionOneDim : virtual public IBaseFunctionOneDim { 0257 0258 public: 0259 0260 typedef IBaseFunctionOneDim BaseFunc; 0261 typedef IGradientFunctionOneDim BaseGrad; 0262 0263 /// Return the derivative of the function at a point x 0264 /// Use the private method DoDerivative 0265 double Derivative(double x) const { return DoDerivative(x); } 0266 0267 /// Compatibility method with multi-dimensional interface for partial derivative. 0268 double Derivative(const double *x) const { return DoDerivative(*x); } 0269 0270 /// Compatibility method with multi-dimensional interface for Gradient. 0271 void Gradient(const double *x, double *g) const { g[0] = DoDerivative(*x); } 0272 0273 /// Optimized method to evaluate at the same time the function value and derivative at a point x. 0274 /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. 0275 /// Derived class should implement this method if performances play an important role and if it is faster to 0276 /// evaluate value and derivative at the same time. 0277 virtual void FdF(double x, double &f, double &df) const 0278 { 0279 f = operator()(x); 0280 df = Derivative(x); 0281 } 0282 0283 /// Compatibility method with multi-dimensional interface for Gradient and function evaluation. 0284 void FdF(const double *x, double &f, double *df) const { FdF(*x, f, *df); } 0285 0286 bool HasGradient() const override { return true; } 0287 0288 private: 0289 0290 /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. 0291 virtual double DoDerivative(double x) const = 0; 0292 }; 0293 0294 0295 0296 } // namespace Math 0297 } // namespace ROOT 0298 0299 #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 |
![]() ![]() |