Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // @(#)root/mathcore:$Id$
0002 // Author: L. Moneta Tue Nov 14 14:20:07 2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  CERN                                           *
0007  * All rights reserved.                                               *
0008  *                                                                    *
0009  * For the licensing terms see $ROOTSYS/LICENSE.                      *
0010  * For the list of contributors see $ROOTSYS/README/CREDITS.          *
0011  *                                                                    *
0012  **********************************************************************/
0013 
0014 // Header file for class IParamFunction
0015 
0016 #ifndef ROOT_Math_IParamFunction
0017 #define ROOT_Math_IParamFunction
0018 
0019 #include "Math/IFunction.h"
0020 
0021 #include "Math/IParamFunctionfwd.h"
0022 
0023 #include "Math/Util.h"
0024 
0025 #include <cassert>
0026 #include <string>
0027 
0028 /**
0029    @defgroup ParamFunc Parametric Function Evaluation Interfaces.
0030    Interfaces classes for evaluation of parametric functions
0031    @ingroup CppFunctions
0032 */
0033 
0034 
0035 namespace ROOT {
0036 
0037    namespace Math {
0038 
0039 
0040 //___________________________________________________________________
0041       /**
0042           Documentation for the abstract class IBaseParam.
0043           It defines the interface for dealing with the function parameters
0044           This is used only for internal convenience, to avoid redefining the Parameter API
0045           for the one and the multi-dim functions.
0046           Concrete class should derive from ROOT::Math::IParamFunction and not from this class.
0047 
0048           @ingroup  ParamFunc
0049       */
0050 
0051       class IBaseParam  {
0052 
0053       public:
0054 
0055 
0056          /**
0057             Virtual Destructor (no operations)
0058          */
0059          virtual ~IBaseParam()  {}
0060 
0061 
0062          /**
0063             Access the parameter values
0064          */
0065          virtual const double *Parameters() const = 0;
0066 
0067          /**
0068             Set the parameter values
0069             @param p vector of doubles containing the parameter values.
0070 
0071             to be defined:  can user change number of params ? At the moment no.
0072 
0073          */
0074          virtual void SetParameters(const double *p) = 0;
0075 
0076 
0077          /**
0078             Return the number of Parameters
0079          */
0080          virtual unsigned int NPar() const = 0;
0081 
0082          /**
0083             Return the name of the i-th parameter (starting from zero)
0084             Overwrite if want to avoid the default name ("Par_0, Par_1, ...")
0085           */
0086          virtual std::string ParameterName(unsigned int i) const
0087          {
0088             assert(i < NPar());
0089             return "Par_" + Util::ToString(i);
0090          }
0091 
0092 
0093       };
0094 
0095 //___________________________________________________________________
0096       /**
0097          IParamFunction interface (abstract class) describing multi-dimensional parametric functions
0098          It is a derived class from ROOT::Math::IBaseFunctionMultiDim and
0099          ROOT::Math::IBaseParam
0100 
0101          Provides the interface for evaluating a function passing a coordinate vector and a parameter vector.
0102 
0103          @ingroup  ParamFunc
0104       */
0105 
0106       template<class T>
0107       class IParametricFunctionMultiDimTempl: virtual public IBaseFunctionMultiDimTempl<T>,
0108          virtual public IBaseParam {
0109       public:
0110 
0111          typedef IBaseFunctionMultiDimTempl<T>  BaseFunc;
0112 
0113          /**
0114          Evaluate function at a point x and for given parameters p.
0115          This method does not change the internal status of the function (internal parameter values).
0116          If for some reason one prefers caching the parameter values, SetParameters(p) and then operator()(x) should be
0117          called.
0118          Use the pure virtual function DoEvalPar to implement it
0119          */
0120 
0121          /* Reimplementation instead of using BaseParamFunc::operator();
0122          until the bug in VS is fixed */
0123          T operator()(const T *x, const double   *p) const
0124          {
0125             return DoEvalPar(x, p);
0126          }
0127 
0128          T operator()(const T *x) const
0129          {
0130             return DoEval(x);
0131          }
0132 
0133       private:
0134          /**
0135             Implementation of the evaluation function using the x values and the parameters.
0136             Must be implemented by derived classes
0137          */
0138          virtual T DoEvalPar(const T *x, const double *p) const = 0;
0139 
0140          /**
0141             Implement the ROOT::Math::IBaseFunctionMultiDim interface DoEval(x) using the cached parameter values
0142          */
0143          virtual T DoEval(const T *x) const
0144          {
0145             return DoEvalPar(x, Parameters());
0146          }
0147       };
0148 
0149 
0150 //___________________________________________________________________
0151       /**
0152          Specialized IParamFunction interface (abstract class) for one-dimensional parametric functions
0153          It is a derived class from ROOT::Math::IBaseFunctionOneDim and
0154          ROOT::Math::IBaseParam
0155 
0156          @ingroup  ParamFunc
0157       */
0158 
0159       class IParametricFunctionOneDim :
0160          virtual public IBaseFunctionOneDim,
0161          public IBaseParam {
0162 
0163 
0164       public:
0165 
0166          typedef IBaseFunctionOneDim   BaseFunc;
0167 
0168 
0169          using BaseFunc::operator();
0170 
0171          /**
0172             Evaluate function at a point x and for given parameters p.
0173             This method does not change the internal status of the function (internal parameter values).
0174             If for some reason one prefers caching the parameter values, SetParameters(p) and then operator()(x) should be
0175             called.
0176             Use the pure virtual function DoEvalPar to implement it
0177          */
0178          double operator()(double x, const double   *p) const
0179          {
0180             return DoEvalPar(x, p);
0181          }
0182 
0183 
0184          /**
0185             multidim-like interface
0186          */
0187          double operator()(const double *x, const double   *p) const
0188          {
0189             return DoEvalPar(*x, p);
0190          }
0191 
0192       private:
0193 
0194          /**
0195             Implementation of the evaluation function using the x value and the parameters.
0196             Must be implemented by derived classes
0197          */
0198          virtual double DoEvalPar(double x, const double *p) const = 0;
0199 
0200          /**
0201             Implement the ROOT::Math::IBaseFunctionOneDim interface DoEval(x) using the cached parameter values
0202          */
0203          double DoEval(double x) const override
0204          {
0205             return DoEvalPar(x, Parameters());
0206          }
0207 
0208       };
0209 
0210 
0211 
0212 //_______________________________________________________________________________
0213       /**
0214          Interface (abstract class) for parametric gradient multi-dimensional functions providing
0215          in addition to function evaluation with respect to the coordinates
0216          also the gradient with respect to the parameters, via the method ParameterGradient.
0217 
0218          It is a derived class from ROOT::Math::IParametricFunctionMultiDim.
0219 
0220          The pure private virtual method DoParameterGradient must be implemented by the derived classes
0221          in addition to those inherited by the base abstract classes.
0222 
0223          @ingroup  ParamFunc
0224       */
0225 
0226       template<class T>
0227       class IParametricGradFunctionMultiDimTempl: virtual public IParametricFunctionMultiDimTempl<T>, virtual public IBaseParam {
0228       public:
0229 
0230          using  BaseParamFunc = IParametricFunctionMultiDimTempl<T>;
0231          using BaseGradFunc = IGradientFunctionMultiDimTempl<T>;
0232          using BaseFunc = typename IParametricFunctionMultiDimTempl<T>::BaseFunc;
0233 
0234 
0235          /**
0236             Virtual Destructor (no operations)
0237          */
0238          ~IParametricGradFunctionMultiDimTempl() override  {}
0239 
0240 
0241          /* Reimplementation instead of using BaseParamFunc::operator();
0242          until the bug in VS is fixed */
0243          T operator()(const T *x, const double   *p) const
0244          {
0245             return DoEvalPar(x, p);
0246          }
0247 
0248          T operator()(const T *x) const
0249          {
0250             return DoEval(x);
0251          }
0252 
0253          /**
0254             Evaluate the all the derivatives (gradient vector) of the function with respect to the parameters at a point x.
0255             It is optional to be implemented by the derived classes for better efficiency
0256          */
0257          virtual void ParameterGradient(const T *x, const double *p, T *grad) const
0258          {
0259             unsigned int npar = NPar();
0260             for (unsigned int ipar  = 0; ipar < npar; ++ipar)
0261                grad[ipar] = DoParameterDerivative(x, p, ipar);
0262          }
0263 
0264          // Return true if this function provides computation of the Hessian matrix with respect to the parameters
0265          virtual bool HasParameterHessian() const { return false;}
0266 
0267          /**
0268             Evaluate the all the Hessian (second derivatives matrix) of the function with respect to the parameters at a point x.
0269             It is optional to be implemented by the derived classes if needed. If it is not implemented return a false.
0270             h must be dimensioned as a n x (n+1)/2 matrix (since it is a symmetric matrix)
0271          */
0272          virtual bool ParameterHessian(const T * /* x */, const double * /* p */, T * /* h */) const { return false;}
0273 
0274          /**
0275             Evaluate all the second derivatives (diagonal ones) of the function with respect to the parameters at a point x.
0276             g2 is a vector of dimension npar
0277          */
0278          virtual bool ParameterG2(const T * /* x */, const double * /* p */, T * /* g2 */) const { return false;}
0279 
0280          /**
0281             Evaluate the partial derivative w.r.t a parameter ipar from values and parameters
0282           */
0283          T ParameterDerivative(const T *x, const double *p, unsigned int ipar = 0) const
0284          {
0285             return DoParameterDerivative(x, p, ipar);
0286          }
0287 
0288          /**
0289             Evaluate all derivatives using cached parameter values
0290          */
0291          void ParameterGradient(const T *x, T *grad) const { return ParameterGradient(x, Parameters(), grad); }
0292          /**
0293             Evaluate partial derivative using cached parameter values
0294          */
0295          T ParameterDerivative(const T *x, unsigned int ipar = 0) const
0296          {
0297             return DoParameterDerivative(x, Parameters() , ipar);
0298          }
0299 
0300       private:
0301 
0302          /**
0303             Evaluate the partial derivative w.r.t a parameter ipar , to be implemented by the derived classes
0304           */
0305          virtual T DoParameterDerivative(const T *x, const double *p, unsigned int ipar) const = 0;
0306          T DoEvalPar(const T *x, const double *p) const override = 0;
0307          T DoEval(const T *x) const override
0308          {
0309             return DoEvalPar(x, Parameters());
0310          }
0311       };
0312 
0313 //_______________________________________________________________________________
0314       /**
0315          Interface (abstract class) for parametric one-dimensional gradient functions providing
0316          in addition to function evaluation with respect the coordinates
0317          also the gradient with respect to the parameters, via the method ParameterGradient.
0318 
0319          It is a derived class from ROOT::Math::IParametricFunctionOneDim.
0320 
0321          The pure private virtual method DoParameterGradient must be implemented by the derived classes
0322          in addition to those inherited by the base abstract classes.
0323 
0324          @ingroup  ParamFunc
0325       */
0326 
0327       class IParametricGradFunctionOneDim :
0328          public IParametricFunctionOneDim
0329 //         ,public IGradientFunctionOneDim
0330       {
0331 
0332       public:
0333 
0334          typedef IParametricFunctionOneDim            BaseParamFunc;
0335          typedef IGradientFunctionOneDim              BaseGradFunc;
0336          typedef IParametricFunctionOneDim::BaseFunc  BaseFunc;
0337 
0338 
0339          /**
0340             Virtual Destructor (no operations)
0341          */
0342          ~IParametricGradFunctionOneDim() override  {}
0343 
0344 
0345          using BaseParamFunc::operator();
0346 
0347          /**
0348             Evaluate the derivatives of the function with respect to the parameters at a point x.
0349             It is optional to be implemented by the derived classes for better efficiency if needed
0350          */
0351          virtual void ParameterGradient(double x , const double *p, double *grad) const
0352          {
0353             unsigned int npar = NPar();
0354             for (unsigned int ipar  = 0; ipar < npar; ++ipar)
0355                grad[ipar] = DoParameterDerivative(x, p, ipar);
0356          }
0357 
0358          /**
0359             Evaluate all derivatives using cached parameter values
0360          */
0361          void ParameterGradient(double  x , double *grad) const
0362          {
0363             return ParameterGradient(x, Parameters(), grad);
0364          }
0365 
0366          /**
0367             Compatibility interface with multi-dimensional functions
0368          */
0369          void ParameterGradient(const double *x , const double *p, double *grad) const
0370          {
0371             ParameterGradient(*x, p, grad);
0372          }
0373 
0374          /**
0375             Evaluate all derivatives using cached parameter values (multi-dim like interface)
0376          */
0377          void ParameterGradient(const double *x , double *grad) const
0378          {
0379             return ParameterGradient(*x, Parameters(), grad);
0380          }
0381 
0382 
0383          /**
0384             Partial derivative with respect a parameter
0385           */
0386          double ParameterDerivative(double x, const double *p, unsigned int ipar = 0) const
0387          {
0388             return DoParameterDerivative(x, p, ipar);
0389          }
0390 
0391          /**
0392             Evaluate partial derivative using cached parameter values
0393          */
0394          double ParameterDerivative(double x, unsigned int ipar = 0) const
0395          {
0396             return DoParameterDerivative(x, Parameters() , ipar);
0397          }
0398 
0399          /**
0400             Partial derivative with respect a parameter
0401             Compatibility interface with multi-dimensional functions
0402          */
0403          double ParameterDerivative(const double *x, const double *p, unsigned int ipar = 0) const
0404          {
0405             return DoParameterDerivative(*x, p, ipar);
0406          }
0407 
0408 
0409          /**
0410             Evaluate partial derivative using cached parameter values (multi-dim like interface)
0411          */
0412          double ParameterDerivative(const double *x, unsigned int ipar = 0) const
0413          {
0414             return DoParameterDerivative(*x, Parameters() , ipar);
0415          }
0416 
0417 
0418 
0419       private:
0420 
0421 
0422          /**
0423             Evaluate the gradient, to be implemented by the derived classes
0424           */
0425          virtual double DoParameterDerivative(double x, const double *p, unsigned int ipar) const = 0;
0426 
0427 
0428       };
0429 
0430 
0431 
0432 
0433    } // end namespace Math
0434 
0435 } // end namespace ROOT
0436 
0437 
0438 
0439 #endif /* ROOT_Math_IParamFunction */