IFunction.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: IFunction.h 24482 2008-06-23 15:33:08Z moneta $
00002 // Authors: L. Moneta    11/2006 
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006 , LCG ROOT MathLib Team                         *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Header file for function interfaces 
00012 // 
00013 // Generic Interfaces for one or  multi-dimensional functions
00014 //
00015 // Created by: Lorenzo Moneta  : Wed Nov 13 2006
00016 // 
00017 // 
00018 #ifndef ROOT_Math_IFunction
00019 #define ROOT_Math_IFunction
00020 
00021 /** 
00022 @defgroup CppFunctions Function Classes and Interfaces
00023 
00024  Interfaces (abstract classes) and Base classes used in MathCore and MathMore numerical methods 
00025  for describing function classes. They define function and gradient evaluation and as well the 
00026  functionality for dealing with parameters in the case of parametric functions which are used for 
00027  fitting and data modeling. 
00028  Included are also adapter classes, such as  functors, to wrap generic callable C++ objects 
00029  in the desired interface. 
00030 */
00031 
00032 //typedefs and tags definitions 
00033 #ifndef ROOT_Math_IFunctionfwd
00034 #include "Math/IFunctionfwd.h"
00035 #endif
00036 
00037 
00038 namespace ROOT {
00039 namespace Math {
00040 
00041 /**
00042    @defgroup GenFunc Interfaces for generic function evaluation
00043    @ingroup CppFunctions
00044 */
00045 
00046 //___________________________________________________________________________________
00047    /** 
00048        Documentation for the abstract class IBaseFunctionMultiDim.
00049        Interface (abstract class) for generic functions objects of multi-dimension 
00050        Provides a method to evaluate the function given a vector of coordinate values, 
00051        by implementing operator() (const double *).
00052        In addition it defines the interface for copying functions via the pure virtual method Clone()  
00053        and the interface for getting the function dimension via the NDim() method. 
00054        Derived classes must implement the pure private virtual method DoEval(const double *) for the 
00055        function evaluation in addition to NDim() and Clone(). 
00056         
00057        @ingroup  GenFunc
00058    */
00059 
00060    class IBaseFunctionMultiDim {
00061            
00062    public: 
00063 
00064       typedef  IBaseFunctionMultiDim BaseFunc; 
00065 
00066 
00067       IBaseFunctionMultiDim() {}
00068 
00069       /**
00070          virtual destructor 
00071        */
00072       virtual ~IBaseFunctionMultiDim() {}
00073 
00074       /** 
00075           Clone a function. 
00076           Each derived class must implement his version of the Clone method
00077       */
00078       virtual IBaseFunctionMultiDim * Clone() const = 0;  
00079 
00080       /**
00081          Retrieve the dimension of the function
00082        */
00083       virtual unsigned int NDim() const = 0; 
00084 
00085       /** 
00086           Evaluate the function at a point x[]. 
00087           Use the pure virtual private method DoEval which must be implemented by the sub-classes
00088       */      
00089       double operator() (const double* x) const { 
00090          return DoEval(x); 
00091       }
00092 
00093 #ifdef LATER
00094       /**
00095          Template method to eveluate the function using the begin of an iterator
00096          User is responsible to provide correct size for the iterator
00097       */
00098       template <class Iterator>
00099       double operator() (const Iterator it ) const { 
00100          return DoEval( &(*it) ); 
00101       }
00102 #endif
00103 
00104 
00105    private: 
00106 
00107 
00108       /**
00109          Implementation of the evaluation function. Must be implemented by derived classes
00110       */
00111       virtual double DoEval(const double * x) const = 0; 
00112 
00113 
00114   }; 
00115 
00116 
00117 //___________________________________________________________________________________
00118    /** 
00119        Interface (abstract class) for generic functions objects of one-dimension 
00120        Provides a method to evaluate the function given a value (simple double) 
00121        by implementing operator() (const double ).
00122        In addition it defines the interface for copying functions via the pure virtual method Clone(). 
00123        Derived classes must implement the pure virtual private method DoEval(double ) for the 
00124        function evaluation in addition to  Clone(). 
00125        An interface for evaluating the function passing a vector (like for multidim functions) is also 
00126        provided
00127         
00128        @ingroup  GenFunc
00129    */
00130    class IBaseFunctionOneDim { 
00131 
00132    public: 
00133 
00134       typedef  IBaseFunctionOneDim BaseFunc; 
00135 
00136       IBaseFunctionOneDim() {}
00137 
00138       /**
00139          virtual destructor 
00140        */
00141       virtual ~IBaseFunctionOneDim() {}
00142 
00143       /** 
00144           Clone a function. 
00145           Each derived class will implement his version of the provate DoClone method
00146       */
00147       virtual IBaseFunctionOneDim * Clone() const = 0;  
00148 
00149       /** 
00150           Evaluate the function at a point x 
00151           Use the  a pure virtual private method DoEval which must be implemented by sub-classes
00152       */      
00153       double operator() (double x) const { 
00154          return DoEval(x); 
00155       }
00156 
00157       /** 
00158           Evaluate the function at a point x[]. 
00159           Compatible method with multi-dimensional functions
00160       */      
00161       double operator() (const double * x) const { 
00162          return DoEval(*x); 
00163       }
00164 
00165 
00166 
00167    private: 
00168 
00169       // use private virtual inheritance 
00170 
00171       /// implementation of the evaluation function. Must be implemented by derived classes
00172       virtual double DoEval(double x) const = 0; 
00173 
00174    };
00175 
00176 
00177 //-------- GRAD  functions---------------------------
00178 
00179 //___________________________________________________________________________________
00180    /**
00181       Gradient interface (abstract class) defining the signature for calculating the gradient of a 
00182       multi-dimensional function. 
00183       Three methods are provided: 
00184       - Gradient(const double *x, double * grad) evaluate the full gradient vector at the vector value x
00185       - Derivative(const double * x, int icoord) evaluate the partial derivative for the icoord coordinate
00186       - FdF(const double *x, double &f, double * g) evaluate at the same time gradient and function/ 
00187 
00188       Concrete classes should derive from ROOT::Math::IGradientFunctionMultiDim and not from this class.  
00189 
00190       @ingroup  GenFunc
00191     */
00192 
00193    class IGradientMultiDim { 
00194 
00195       public: 
00196 
00197       /// virual destructor 
00198       virtual ~IGradientMultiDim() {}
00199 
00200       /** 
00201           Evaluate all the vector of function derivatives (gradient)  at a point x.
00202           Derived classes must re-implement if it is more efficient than evaluting one at a time
00203       */
00204       virtual void  Gradient(const double *x, double * grad) const = 0; 
00205 
00206       /**
00207          Return the partial derivative with respect to the passed coordinate 
00208       */
00209       double Derivative(const double * x, unsigned int icoord = 0) const  { 
00210          return DoDerivative(x, icoord); 
00211       }
00212 
00213  
00214       /** 
00215           Optimized method to evaluate at the same time the function value and derivative at a point x.
00216           Often both value and derivatives are needed and it is often more efficient to compute them at the same time.
00217           Derived class should implement this method if performances play an important role and if it is faster to 
00218           evaluate value and derivative at the same time
00219        
00220       */
00221       virtual void FdF (const double * x, double & f, double * df) const  = 0; 
00222 
00223 
00224    private: 
00225 
00226 
00227       /**
00228          function to evaluate the derivative with respect each coordinate. To be implemented by the derived class 
00229       */ 
00230       virtual  double  DoDerivative(const double * x, unsigned int icoord ) const = 0; 
00231 
00232    };
00233 
00234 //___________________________________________________________________________________
00235    /**
00236       Specialized Gradient interface(abstract class)  for one dimensional functions
00237       It provides a method to evaluate the derivative of the function, Derivative and a 
00238       method to evaluate at the same time the function and the derivative FdF 
00239 
00240       Concrete classes should derive from ROOT::Math::IGradientFunctionOneDim and not from this class.  
00241 
00242       @ingroup  GenFunc
00243     */
00244    class IGradientOneDim { 
00245 
00246    public: 
00247 
00248       /// virtual destructor 
00249       virtual ~IGradientOneDim() {}
00250 
00251       /**
00252          Return the derivative of the function at a point x 
00253          Use the private method DoDerivative 
00254       */
00255       double Derivative(double x ) const  { 
00256          return DoDerivative(x ); 
00257       }
00258 
00259  
00260       /** 
00261           Optimized method to evaluate at the same time the function value and derivative at a point x.
00262           Often both value and derivatives are needed and it is often more efficient to compute them at the same time.
00263           Derived class should implement this method if performances play an important role and if it is faster to 
00264           evaluate value and derivative at the same time
00265        
00266       */
00267       virtual void FdF (double x, double & f, double & df) const = 0; 
00268 
00269 
00270       /**
00271          Compatibility method with multi-dimensional interface for partial derivative
00272        */
00273       double Derivative(const double * x) const  { 
00274          return DoDerivative( *x); 
00275       }
00276 
00277       /**
00278          Compatibility method with multi-dimensional interface for Gradient
00279        */
00280       void Gradient(const double * x, double *g) const  { 
00281          g[0] = DoDerivative( *x); 
00282       }
00283 
00284       /**
00285          Compatibility method with multi-dimensional interface for Gradient and function evaluation
00286        */
00287       void FdF(const double * x, double & f, double * df) const  {
00288          FdF(*x, f, *df);
00289       }
00290       
00291 
00292 
00293    private: 
00294 
00295 
00296       /**
00297          function to evaluate the derivative with respect each coordinate. To be implemented by the derived class 
00298       */ 
00299       virtual  double  DoDerivative(double x ) const = 0; 
00300 
00301    };
00302 
00303 //___________________________________________________________________________________
00304 /** 
00305    Interface (abstract class) for multi-dimensional functions providing a gradient calculation. 
00306    It implements both the ROOT::Math::IBaseFunctionMultiDim and  
00307    ROOT::Math::IGradientMultiDim interfaces.
00308    The method ROOT::Math::IFunction::Gradient calculates the full gradient vector, 
00309    ROOT::Math::IFunction::Derivative calculates the partial derivative for each coordinate and 
00310    ROOT::Math::Fdf calculates the gradient and the function value at the same time. 
00311    The pure private virtual method DoDerivative() must be implemented by the derived classes, while 
00312    Gradient and FdF are by default implemented using DoDerivative, butthey  can be overloaded by the 
00313    derived classes to improve the efficiency in the derivative calculation. 
00314 
00315    @ingroup  GenFunc
00316 */ 
00317 
00318    class IGradientFunctionMultiDim : 
00319       virtual public IBaseFunctionMultiDim , 
00320       public IGradientMultiDim { 
00321      
00322 
00323    public: 
00324 
00325       typedef IBaseFunctionMultiDim BaseFunc; 
00326       typedef IGradientMultiDim BaseGrad; 
00327 
00328 
00329       /** 
00330           Virtual Destructor (no operations)
00331       */ 
00332       virtual ~IGradientFunctionMultiDim () {}
00333 
00334       /** 
00335           Evaluate all the vector of function derivatives (gradient)  at a point x.
00336           Derived classes must re-implement it if more efficient than evaluting one at a time
00337       */
00338       virtual void  Gradient(const double *x, double * grad) const { 
00339          unsigned int ndim = NDim(); 
00340          for (unsigned int icoord  = 0; icoord < ndim; ++icoord) 
00341             grad[icoord] = BaseGrad::Derivative(x,icoord); 
00342       }
00343 
00344       using  BaseFunc::NDim;
00345 
00346  
00347       /** 
00348           Optimized method to evaluate at the same time the function value and derivative at a point x.
00349           Often both value and derivatives are needed and it is often more efficient to compute them at the same time.
00350           Derived class should implement this method if performances play an important role and if it is faster to 
00351           evaluate value and derivative at the same time
00352        
00353       */
00354       virtual void FdF (const double * x, double & f, double * df) const { 
00355          f = BaseFunc::operator()(x); 
00356          Gradient(x,df);
00357       }
00358 
00359 
00360    }; 
00361 
00362 
00363 //___________________________________________________________________________________
00364 /** 
00365    Interface (abstract class) for one-dimensional functions providing a gradient calculation. 
00366    It implements both the ROOT::Math::IBaseFunctionOneDim and  
00367    ROOT::Math::IGradientOneDim interfaces.
00368    The method  ROOT::Math::IFunction::Derivative calculates the derivative  and 
00369    ROOT::Math::Fdf calculates the derivative and the function values at the same time. 
00370    The pure private virtual method DoDerivative() must be implemented by the derived classes, while 
00371    FdF is by default implemented using DoDerivative, but it can be overloaded by the 
00372    derived classes to improve the efficiency in the derivative calculation. 
00373 
00374 
00375    @ingroup  GenFunc
00376 */ 
00377    //template <>
00378    class IGradientFunctionOneDim : 
00379       virtual public IBaseFunctionOneDim , 
00380       public IGradientOneDim { 
00381      
00382 
00383    public: 
00384 
00385       typedef IBaseFunctionOneDim BaseFunc; 
00386       typedef IGradientOneDim BaseGrad; 
00387 
00388 
00389       /** 
00390           Virtual Destructor (no operations)
00391       */ 
00392       virtual ~IGradientFunctionOneDim () {}
00393 
00394 
00395       /** 
00396           Optimized method to evaluate at the same time the function value and derivative at a point x.
00397            Often both value and derivatives are needed and it is often more efficient to compute them at the same time.
00398           Derived class should implement this method if performances play an important role and if it is faster to 
00399           evaluate value and derivative at the same time
00400        
00401       */
00402       virtual void FdF (double x, double & f, double & df) const { 
00403          f = operator()(x); 
00404          df = Derivative(x);
00405       }
00406 
00407 
00408 
00409    }; 
00410 
00411 
00412 
00413  
00414 
00415 } // namespace Math
00416 } // namespace ROOT
00417 
00418 #endif /* ROOT_Math_IGenFunction */

Generated on Tue Jul 5 14:25:28 2011 for ROOT_528-00b_version by  doxygen 1.5.1