diff --git a/mathcore/Module.mk b/mathcore/Module.mk index f259b166594b90529753d6506156ef253be1c48a..f58f016fb590d54f938e57e0f9cbaaaa99e29660 100644 --- a/mathcore/Module.mk +++ b/mathcore/Module.mk @@ -46,7 +46,9 @@ MATHCOREDH1 := $(MODDIRI)/Math/Vector3D.h \ $(MODDIRI)/Math/SpecFuncMathCore.h \ $(MODDIRI)/Math/ProbFuncMathCore.h \ $(MODDIRI)/Math/DistFunc.h \ - $(MODDIRI)/Math/VectorUtil_Cint.h + $(MODDIRI)/Math/VectorUtil_Cint.h \ + $(MODDIRI)/Math/IParamFunction.h \ + $(MODDIRI)/Math/IFunction.h MATHCOREDH132:= $(MODDIRI)/Math/Vector3D.h \ $(MODDIRI)/Math/Point3D.h \ diff --git a/mathcore/inc/Math/Functor.h b/mathcore/inc/Math/Functor.h new file mode 100644 index 0000000000000000000000000000000000000000..25f844d3baf2b59c98f690aeeac268a2f549e0ee --- /dev/null +++ b/mathcore/inc/Math/Functor.h @@ -0,0 +1,538 @@ +// @(#)root/mathcore:$Name: $:$Id: inc/Math/Functor.h,v 1.0 2006/01/01 12:00:00 moneta Exp $ +// Author: L. Moneta Mon Nov 13 15:58:13 2006 + +/********************************************************************** + * * + * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * + * * + * * + **********************************************************************/ + +// Heaer file for Functor classes. +// designed is inspired by the Loki Functor + +#ifndef ROOT_Math_Functor +#define ROOT_Math_Functor + +#ifndef ROOT_Math_IFunction +#include "Math/IFunction.h" +#endif + +// #ifndef Root_Math_StaticCheck +// #include "Math/StaticCheck.h" +// #endif + +#include <memory> + +#include <vector> + +namespace ROOT { + +namespace Math { + + +/** + Functor Handler class is responsible for wrapping any other functor and pointer to + free C functions. + It can be created from any function implementing the correct signature + corresponding to the requested type +*/ +template<class ParentFunctor, class Func > +class FunctorHandler : public ParentFunctor::Impl { + + typedef typename ParentFunctor::Impl Base; + +public: + + // constructor for 1d functions + FunctorHandler(const Func & fun) : fDim(1), fFunc(fun) {} + + // constructor for multi-dimensional functions w/0 NDim() + FunctorHandler(unsigned int dim, const Func & fun ) : + fDim(dim), + fFunc(fun) + {} + + // clone of the function handler (use copy-ctor) + FunctorHandler * Clone() const { return new FunctorHandler(*this); } + + // constructor for multi-dimensional functions + unsigned int NDim() const { + return fDim; + } + +private : + + inline double DoEval (double x) const { + return fFunc(x); + } + + inline double DoEval (const double * x) const { + return fFunc(x); + } + + inline double DoDerivative (double x) const { + return fFunc.Derivative(x); + } + + inline double DoDerivative (const double * x, unsigned int icoord ) const { + return fFunc.Derivative(x,icoord); + } + + + unsigned int fDim; + Func fFunc; + +}; + + +/** + Functor Handler class for gradient functions where the gradient is provided as + an additional functor. + It can be created from any function implementing the correct signature + corresponding to the requested type +*/ +template<class ParentFunctor, class Func, class GradFunc = Func > +class FunctorGradHandler : public ParentFunctor::Impl { + + typedef typename ParentFunctor::Impl Base; + +public: + + // constructor for 1d functions + FunctorGradHandler(const Func & fun, const GradFunc & gfun) : + fDim(1), + fFunc(fun), + fGradient(std::vector<GradFunc>(1)) + { + fGradient[0] = gfun; + } + + // constructor for multi-dimensional functions + template<class GradFuncIterator> + FunctorGradHandler(const Func & fun, GradFuncIterator begin, GradFuncIterator end) : + fFunc(fun), + fGradient(std::vector<GradFunc>(begin,end) ) + { + fDim = fGradient.size(); + } + + // clone of the function handler (use copy-ctor) + FunctorGradHandler * Clone() const { return new FunctorGradHandler(*this); } + + // constructor for multi-dimensional functions + unsigned int NDim() const { + return fDim; + } + +private : + + inline double DoEval (double x) const { + return fFunc(x); + } + + inline double DoEval (const double * x) const { + return fFunc(x); + } + + inline double DoDerivative (double x) const { + return fGradient[0](x); + } + + inline double DoDerivative (const double * x, unsigned int icoord ) const { + return fGradient[icoord](x); + } + + + unsigned int fDim; + Func fFunc; + std::vector<GradFunc> fGradient; + +}; + + +/** + Functor Handler to Wrap pointers to member functions of Base type +*/ +template <class ParentFunctor, typename PointerToObj, + typename PointerToMemFn> +class MemFunHandler : public ParentFunctor::Impl +{ + typedef typename ParentFunctor::Impl Base; + +public: + + /// constructor from a pointer to the class and a pointer to the function + MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) + : fDim(1), fObj(pObj), fMemFn(pMemFn) + {} + + /// constructor from a pointer to the class and a pointer to the function + MemFunHandler(unsigned int dim, const PointerToObj& pObj, PointerToMemFn pMemFn) + : fDim(dim), fObj(pObj), fMemFn(pMemFn) + {} + + + // clone of the function handler (use copy-ctor) + MemFunHandler * Clone() const { return new MemFunHandler(*this); } + + // constructor for multi-dimensional functions + unsigned int NDim() const { + return fDim; + } + +private : + + inline double DoEval (double x) const { + return ((*fObj).*fMemFn)(x); + } + + inline double DoEval (const double * x) const { + return ((*fObj).*fMemFn)(x); + } + + unsigned int fDim; + PointerToObj fObj; + PointerToMemFn fMemFn; + +}; + +/** + Functor Handler to Wrap pointers to member functions of Grad type +*/ +template <class ParentFunctor, typename PointerToObj, + typename PointerToMemFn, typename PointerToGradMemFn> +class MemGradFunHandler : public ParentFunctor::Impl +{ + typedef typename ParentFunctor::Impl Base; + +public: + + /// constructor from a pointer to the class and a pointer to the function + MemGradFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn, PointerToGradMemFn pGradMemFn) + : fDim(1), + fObj(pObj), + fMemFn(pMemFn), + fGradMemFn(pGradMemFn) + {} + + /// constructor from a pointer to the class and a pointer to the function + MemGradFunHandler(unsigned int dim, + const PointerToObj& pObj, + PointerToMemFn pMemFn, + PointerToGradMemFn pGradMemFn ) + : fDim(dim), + fObj(pObj), + fMemFn(pMemFn), + fGradMemFn(pGradMemFn) + {} + + + // clone of the function handler (use copy-ctor) + MemGradFunHandler * Clone() const { return new MemGradFunHandler(*this); } + + // constructor for multi-dimensional functions + unsigned int NDim() const { + return fDim; + } + +private : + + inline double DoEval (double x) const { + return ((*fObj).*fMemFn)(x); + } + + inline double DoEval (const double * x) const { + return ((*fObj).*fMemFn)(x); + } + + inline double DoDerivative (double x) const { + return ((*fObj).*fGradMemFn)(x); + } + + inline double DoDerivative (const double * x, unsigned int icoord ) const { + return ((*fObj).*fGradMemFn)(x,icoord); + } + + unsigned int fDim; + PointerToObj fObj; + PointerToMemFn fMemFn; + PointerToGradMemFn fGradMemFn; +}; + + +#ifdef CHECK +/** + Functor helper class to check on function dimension + */ +//template<class DimensionType> +struct FunctorDimHelper { + static void CheckDimension(OneDim ) {} +}; +// template <> +// struct FunctorDimHelper<MultiDim> { +// static void CheckDimension() { +// STATIC_CHECK(0==1, Wrong_method_called_Multidimensional_functions); +// } +// }; +/** + Functor helper class to check on function capability type + */ +//template<class CapabilityType> +struct FunctorCapHelper { + static void CheckType(Gradient ) {} +}; +// template <> +// struct FunctorCapHelper<Base> { +// static void CheckType() { +// STATIC_CHECK(0==1, Wrong_method_called_Base_Type_functions); +// } +// }; + +#endif + +/** + Functor clas for Multidimensional functions + */ +template<class IFuncType> +class Functor : public IFuncType { + + +public: + + typedef IFuncType Impl; + typedef typename IFuncType::BaseFunc ImplBase; +// typedef typename Impl::DimType DimType; +// typedef typename Impl::CapType CapType; + + + /** + Default constructor + */ + Functor () : fImpl(0) {} + + + /** + construct from a pointer to member function (multi-dim type) + */ + template <class PtrObj, typename MemFn> + Functor(const PtrObj& p, MemFn memFn, unsigned int dim ) + : fImpl(new MemFunHandler<Functor, PtrObj, MemFn>(dim, p, memFn)) + {} + + + /** + construct from a pointer to member function (grad type multi-dim) + */ + template <class PtrObj, typename MemFn, typename GradMemFn> + Functor(const PtrObj& p, MemFn memFn, GradMemFn gradFn, unsigned int dim = 0) + : fImpl(new MemGradFunHandler<Functor, PtrObj, MemFn, GradMemFn>(dim, p, memFn, gradFn)) + {} + + + /** + construct from another generic Functor of multi-dimension + */ + template <typename Func> + Functor( Func f, unsigned int dim ) : + fImpl(new FunctorHandler<Functor,Func>(dim,f) ) + {} + + + /** + construct for Analytical Gradient Functions of multi-dimension + */ + template <typename Func, typename FuncIterator> + Functor(Func f, FuncIterator begin, FuncIterator end ) : + fImpl(new FunctorGradHandler<Functor,Func>(f, begin, end) ) + { + // to impl a check if FuncType provides gradient + //FunctorCapHelper::CheckType(CapabilityType()); + } + + + + /** + Destructor (no operations) + */ + virtual ~Functor () {} + + /** + Copy constructor + */ + Functor(const Functor<ROOT::Math::IMultiGenFunction> & rhs) : + Impl() + { + if (rhs.fImpl.get() != 0) + fImpl = std::auto_ptr<Impl>( (rhs.fImpl)->Clone() ); + } + // need a specialization in order to call base classes + Functor(const Functor<ROOT::Math::IMultiGradFunction> & rhs) : + ImplBase(), + Impl() + { + if (rhs.fImpl.get() != 0) + fImpl = std::auto_ptr<Impl>( dynamic_cast<ROOT::Math::IMultiGradFunction *>( (rhs.fImpl)->Clone()) ); + } + + /** + Assignment operator + */ + Functor & operator = (const Functor & rhs) { + Functor copy(rhs); + // swap auto_ptr by hand + Impl * p = fImpl.release(); + fImpl.reset(copy.fImpl.release()); + copy.fImpl.reset(p); + return *this; + } + + + // clone of the function handler (use copy-ctor) + IMultiGenFunction * Clone() const { return new Functor(*this); } + + // for multi-dimensional functions + unsigned int NDim() const { return fImpl->NDim(); } + +private : + + + inline double DoEval (const double * x) const { + return (*fImpl)(x); + } + + + inline double DoDerivative (const double * x, unsigned int icoord ) const { + return fImpl->Derivative(x,icoord); + } + + std::auto_ptr<Impl> fImpl; + + +}; + + +/** + Functor clas for Onedimensional functions + */ +template<class IFuncType > +class Functor1D : public IFuncType { + + +public: + + typedef IFuncType Impl; + typedef typename IFuncType::BaseFunc ImplBase; +// typedef typename Impl::DimType DimType; +// typedef typename Impl::CapType CapType; + + + /** + Default constructor + */ + Functor1D () : fImpl(0) {} + + + /** + construct from a pointer to member function (1D type) + */ + template <class PtrObj, typename MemFn> + Functor1D(const PtrObj& p, MemFn memFn) + : fImpl(new MemFunHandler<Functor1D, PtrObj, MemFn>(p, memFn)) + {} + + /** + construct from a pointer to member function (grad type of 1D) + */ + template <class PtrObj, typename MemFn, typename GradMemFn> + Functor1D(unsigned int dim, const PtrObj& p, MemFn memFn, GradMemFn gradFn) + : fImpl(new MemGradFunHandler<Functor1D, PtrObj, MemFn, GradMemFn>(p, memFn, gradFn)) + {} + + + /** + construct from another generic Functor of 1D + */ + template <typename Func> + Functor1D(Func f) : + fImpl(new FunctorHandler<Functor1D,Func>(f) ) + {} + + + /** + construct for Analytical Gradient Functions (of 1 dimension) + */ + template <typename Func> + Functor1D(Func f, Func g ) : + fImpl(new FunctorGradHandler<Functor1D,Func>(f, g) ) + { + // need s to check if provides grad + //FunctorCapHelper::CheckType(CapabilityType()); + } + + /** + Destructor (no operations) + */ + virtual ~Functor1D () {} + + /** + Copy constructor + */ + Functor1D(const Functor1D<ROOT::Math::IGenFunction> & rhs) : + // strange that this is required eventhough Impl is an abstract class + Impl() + { + if (rhs.fImpl.get() != 0) + fImpl = std::auto_ptr<Impl>( (rhs.fImpl)->Clone() ); + } + Functor1D(const Functor1D<ROOT::Math::IGradFunction> & rhs) : + // strange that this is required eventhough Impl is an abstract class + ImplBase(), + Impl() + { + if (rhs.fImpl.get() != 0) + fImpl = std::auto_ptr<Impl>( dynamic_cast<ROOT::Math::IGradFunction *>( (rhs.fImpl)->Clone() ) ); + } + + + /** + Assignment operator + */ + Functor1D & operator = (const Functor1D & rhs) { + Functor1D copy(rhs); + // swap auto_ptr by hand + Impl * p = fImpl.release(); + fImpl.reset(copy.fImpl.release()); + copy.fImpl.reset(p); + return *this; + } + + + // clone of the function handler (use copy-ctor) + IGenFunction * Clone() const { return new Functor1D(*this); } + + +private : + + inline double DoEval (double x) const { + return (*fImpl)(x); + } + + + inline double DoDerivative (double x) const { + return fImpl->Derivative(x); + } + + std::auto_ptr<Impl> fImpl; + + +}; + + + + } // end namespace Math + +} // end namespace ROOT + + +#endif /* ROOT_Math_Functor */ diff --git a/mathcore/inc/Math/IFunction.h b/mathcore/inc/Math/IFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..56272ec9f39ada29e4a994728feb3c202a98c770 --- /dev/null +++ b/mathcore/inc/Math/IFunction.h @@ -0,0 +1,376 @@ +// @(#)root/mathcore:$Name: $:$Id: IGenFunction.h,v 1.2 2005/09/19 13:06:53 brun Exp $ +// Authors: L. Moneta, A. Zsenei 08/2005 + + +// Header file for funciton interfaces +// +// Generic interface for one or multi-dimensional functions +// +// Created by: Lorenzo Moneta : Wed Nov 13 2006 +// +// +#ifndef ROOT_Math_IFunction +#define ROOT_Math_IFunction + +/** +@defgroup CppFunctions Function Classes and Interfaces +*/ + +//typedefs definition +#ifndef ROOT_Math_IFunctionfwd +#include "Math/IFunctionfwd.h" +#endif + + +namespace ROOT { +namespace Math { + + + /// tag for multi-dimensional functions + struct MultiDim {}; + + /// tag for one-dimensional functions + struct OneDim {}; + +// /// tag for functions with minimal capabilities +// struct Base {}; + +// /// tag for functions with gradient capabbilities +// struct Gradient {}; + + // struct required for defining BaseFunc + struct NullFunc {}; + + /** + Template Interface for generic functions objects: + A template parameter, DimensionType specify the DimensionType which can be + single-dimension or multi-dimension onother parameter specify the + function capabilities. + Default case is function with multidimension and default capability + (no gradient calculation) + - + @ingroup CppFunctions + */ + template<class DimensionType = MultiDim> + class IBaseFunction { + + public: + + typedef IBaseFunction BaseFunc; + + + IBaseFunction() {} + + /** + virtual destructor + */ + virtual ~IBaseFunction() {} + + /** + Clone a function. + Each derived class will implement his version of the Clone method + */ + virtual IBaseFunction * Clone() const = 0; + + /** + Retrieve the dimension of the function + */ + virtual unsigned int NDim() const = 0; + + /** + Evaluate the function at a point x[]. + Use the a pure virtual private method Evaluate which must be implemented by sub-classes + */ + double operator() (const double* x) const { + return DoEval(x); + } + +#ifdef LATER + /** + Template method to eveluate the function using the begin of an iterator + User is responsible to provide correct size for the iterator + */ + template <class Iterator> + double operator() (const Iterator it ) const { + return DoEval( &(*it) ); + } +#endif + + + private: + + // use private virtual inheritance + + /** + Implementation of the evaluation function. Must be implemented by derived classes + */ + virtual double DoEval(const double * x) const = 0; + + + }; + + + /** + Interface for single-dimensional functions with minimal capabilities (no gradient) + + @ingroup CppFunctions + */ + template <> + class IBaseFunction<OneDim> { + + public: + + typedef IBaseFunction BaseFunc; + + IBaseFunction() {} + + /** + virtual destructor + */ + virtual ~IBaseFunction() {} + + /** + Clone a function. + Each derived class will implement his version of the provate DoClone method + */ + virtual IBaseFunction * Clone() const = 0; + + /** + Evaluate the function at a point x + Use the a pure virtual private method DoEval which must be implemented by sub-classes + */ + double operator() (double x) const { + return DoEval(x); + } + + /** + Evaluate the function at a point x[]. + Compatible method with multi-dimensional functions + */ + double operator() (const double * x) const { + return DoEval(*x); + } + + + + private: + + // use private virtual inheritance + + /// implementation of the evaluation function. Must be implemented by derived classes + virtual double DoEval(double x) const = 0; + + }; + + +//-------- GRAD functions--------------------------- + /** + Generic Gradient interface + */ + template <class DimensionType = MultiDim> + class IGradient { + + public: + + /// virual destructor + virtual ~IGradient() {} + + /** + Evaluate all the vector of function derivatives (gradient) at a point x. + Derived classes must re-implement it if more efficient than evaluting one at a time + */ + virtual void Gradient(const double *x, double * grad) const = 0; + + /** + Return the partial derivative with respect to the passed coordinate + */ + double Derivative(const double * x, unsigned int icoord = 0) const { + return DoDerivative(x, icoord); + } + + + /** + Optimized method to evaluate at the same time the function value and derivative at a point x. + Often both value and derivatives are needed and it is often more efficient to compute them at the same time. + Derived class should implement this method if performances play an important role and if it is faster to + evaluate value and derivative at the same time + + */ + virtual void FdF (const double * x, double & f, double * df) const = 0; + + + private: + + + /** + function to evaluate the derivative with respect each coordinate. To be implemented by the derived class + */ + virtual double DoDerivative(const double * x, unsigned int icoord ) const = 0; + + }; + + /** + One Dimensional Gradient interface + */ + template <> + class IGradient<OneDim> { + + public: + + /// virual destructor + virtual ~IGradient() {} + + /** + Return the derivative of the funcition at a point x + Use the private method DoDerivative + */ + double Derivative(double x ) const { + return DoDerivative(x ); + } + + + /** + Optimized method to evaluate at the same time the function value and derivative at a point x. + Often both value and derivatives are needed and it is often more efficient to compute them at the same time. + Derived class should implement this method if performances play an important role and if it is faster to + evaluate value and derivative at the same time + + */ + virtual void FdF (double x, double & f, double & df) const = 0; + + + + + private: + + + /** + function to evaluate the derivative with respect each coordinate. To be implemented by the derived class + */ + virtual double DoDerivative(double x ) const = 0; + + }; + +/** + Interface for multi-dimensional functions providing a gradient calculation. + A method ROOT::Math::IFunction::Gradient provides the full gradient vector while + ROOT::Math::IFunction::Derivative provides the partial derivatives. + The latter bust be implemented (using ROOT::Math::IFunction::Derivative by the derived classes, + while the former can be overloaded if for the particular function can be implemented more efficiently. +*/ + template<class DimensionType = MultiDim> + class IGradientFunction : + virtual public IBaseFunction<DimensionType> , + public IGradient<DimensionType> { + + + public: + + typedef IBaseFunction<DimensionType> BaseFunc; + typedef IGradient<DimensionType> BaseGrad; + +// // need default constructor with initialization of parent classes +// IGradientFunction() : +// BaseFunc(), +// BaseGrad() +// {} + + + /** + Virtual Destructor (no operations) + */ + virtual ~IGradientFunction () {} + + /** + Evaluate all the vector of function derivatives (gradient) at a point x. + Derived classes must re-implement it if more efficient than evaluting one at a time + */ + virtual void Gradient(const double *x, double * grad) const { + unsigned int ndim = NDim(); + for (unsigned int icoord = 0; icoord < ndim; ++icoord) + grad[icoord] = BaseGrad::Derivative(x,icoord); + } + using BaseFunc::NDim; + + /** + Return the partial derivative with respect to the passed coordinate + */ +// double Derivative(const double * x, unsigned int icoord = 0) const { +// if (icoord < NDim() ) +// return DoDerivative(x, icoord); +// else +// return 0; +// } + + + /** + Optimized method to evaluate at the same time the function value and derivative at a point x. + Often both value and derivatives are needed and it is often more efficient to compute them at the same time. + Derived class should implement this method if performances play an important role and if it is faster to + evaluate value and derivative at the same time + + */ + virtual void FdF (const double * x, double & f, double * df) const { + f = BaseFunc::operator()(x); + Gradient(x,df); + } + + + }; + + +/** + Interface for one-dimensional functions providing a gradient calculation. + A method ROOT::Math::IFunction::Gradient provides the full gradient vector while + ROOT::Math::IFunction::Derivative provides the partial derivatives. + The latter bust be implemented (using ROOT::Math::IFunction::Derivative by the derived classes, + while the former can be overloaded if for the particular function can be implemented more efficiently. +*/ + template <> + class IGradientFunction<OneDim> : + virtual public IBaseFunction<OneDim> , + public IGradient<OneDim> { + + + public: + + typedef IBaseFunction<ROOT::Math::OneDim> BaseFunc; + typedef IGradient<ROOT::Math::OneDim> BaseGrad; + +// // need default constructor with initialization of parent classes +// IGradientFunction() : +// BaseFunc(), +// BaseGrad() +// {} + + + /** + Virtual Destructor (no operations) + */ + virtual ~IGradientFunction () {} + + + /** + Optimized method to evaluate at the same time the function value and derivative at a point x. + Often both value and derivatives are needed and it is often more efficient to compute them at the same time. + Derived class should implement this method if performances play an important role and if it is faster to + evaluate value and derivative at the same time + + */ + virtual void FdF (double x, double & f, double & df) const { + f = operator()(x); + df = Derivative(x); + } + + + + }; + + + + + +} // namespace Math +} // namespace ROOT + +#endif /* ROOT_Math_IGenFunction */ diff --git a/mathcore/inc/Math/IFunctionfwd.h b/mathcore/inc/Math/IFunctionfwd.h new file mode 100644 index 0000000000000000000000000000000000000000..5ab24e79898f1fca87b9d1c539174abe5f315f6a --- /dev/null +++ b/mathcore/inc/Math/IFunctionfwd.h @@ -0,0 +1,47 @@ +// @(#)root/mathcore:$Name: $:$Id: inc/Math/IFunctionfwd.h,v 1.0 2006/01/01 12:00:00 moneta Exp $ +// Author: L. Moneta Tue Nov 14 14:38:48 2006 + +/********************************************************************** + * * + * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * + * * + * * + **********************************************************************/ + +// Defines Forward declaration for template IFunction class and useful typedefs + +#ifndef ROOT_Math_IFunctionfwd +#define ROOT_Math_IFunctionfwd + + +namespace ROOT { + + namespace Math { + + template<class DimensionType> class IBaseFunction; + template<class DimensionType> class IGradientFunction; + + class OneDim; + class MultiDim; +// class Base; +// class Gradient; + +// typedef IFunction<OneDim, Base> IGenFunction; +// typedef IFunction<MultiDim, Base> IMultiGenFunction; + +// typedef IFunction<OneDim, Gradient> IGradFunction; +// typedef IFunction<MultiDim, Gradient> IMultiGradFunction; + + typedef IBaseFunction<OneDim> IGenFunction; + typedef IBaseFunction<MultiDim> IMultiGenFunction; + + typedef IGradientFunction<OneDim> IGradFunction; + typedef IGradientFunction<MultiDim> IMultiGradFunction; + + + } // end namespace Math + +} // end namespace ROOT + + +#endif /* ROOT_Math_IFunctionfwd */ diff --git a/mathcore/inc/Math/IParamFunction.h b/mathcore/inc/Math/IParamFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..04d5350dea2a122674fc0238a1f58ce29d50554b --- /dev/null +++ b/mathcore/inc/Math/IParamFunction.h @@ -0,0 +1,297 @@ +// @(#)root/mathcore:$Name: $:$Id: inc/Math/IParamFunction.h,v 1.0 2006/01/01 12:00:00 moneta Exp $ +// Author: L. Moneta Tue Nov 14 14:20:07 2006 + +/********************************************************************** + * * + * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * + * * + * * + **********************************************************************/ + +// Header file for class IParamFunction + +#ifndef ROOT_Math_IParamFunction +#define ROOT_Math_IParamFunction + +#ifndef ROOT_Math_IFunction +#include "Math/IFunction.h" +#endif + +#ifndef ROOT_Math_Util +#include "Math/Util.h" +#endif + +#include <vector> + +#include <cassert> + + +namespace ROOT { + + namespace Math { + + +/** + IParamFunction interface for generic parameteric function + It is a derived class from IFunction + @ingroup CppFunctions +*/ + +template <class DimensionType> +class IParamFunctionBase : virtual public IBaseFunction<DimensionType> { + +public: + + typedef IBaseFunction<DimensionType> BaseFunc; + +// /// default constructor (needed to initialize parent classes) +// IParamFunctionBase() : +// BaseFunc() +// {} + + + /** + Virtual Destructor (no operations) + */ + virtual ~IParamFunctionBase () {} + + + /** + Access the parameter values + */ + virtual const double * Parameters() const = 0; + + // set params values (can user change number of params ? ) + /** + Set the parameter values + @param p vector of doubles containing the parameter values. + */ + virtual void SetParameters(const double * p ) = 0; + +// /** +// Set the parameters values using an iterator +// */ +// template <class ParIterator> +// bool SetParameters(ParIterator begin, ParIterator end) { +// std::vector<double> p(begin.end); +// if (p.size()!= NPar() ) return false; +// SetParameters(&p.front()); +// } + + /** + Return the number of Parameters + */ + virtual unsigned int NPar() const = 0; + + /** + Return the name of the i-th parameter (starting from zero) + Overwrite if want to avoid the default name ("Par_0, Par_1, ...") + */ + virtual std::string ParameterName(unsigned int i) const { + assert(i < NPar() ); + return "Par_" + Util::ToString(i); + } + + using BaseFunc::operator(); + +}; + +/** + IParamFunction interface for generic parameteric function + It is a derived class from IFunction + @ingroup CppFunctions +*/ +template<class DimensionType = MultiDim> +class IParamFunction : public IParamFunctionBase<DimensionType> { + +public: + + typedef IParamFunctionBase<DimensionType> BaseParamFunc; + typedef typename IParamFunctionBase<DimensionType>::BaseFunc BaseFunc; + + /// default constructor (needed to initialize parent classes) +// IParamFunction() : +// BaseParamFunc() +// {} + + + // user may re-implement this for better efficiency + // this method is NOT required to change internal values of parameters. confusing ?? + /** + Evaluate function at a point x and for parameters p. + This method mey be needed for better efficiencies when for each function evaluation the parameters are changed. + */ + virtual double operator() (const double * x, const double * p ) + { + SetParameters(p); + return operator() (x); + } + + using BaseParamFunc::SetParameters; + + using BaseParamFunc::operator(); + +}; +/** + IParamFunction interface for one-dimensional function + @ingroup CppFunctions +*/ +template<> +class IParamFunction<ROOT::Math::OneDim> : public IParamFunctionBase<ROOT::Math::OneDim> { + +public: + + typedef IParamFunctionBase<ROOT::Math::OneDim> BaseParamFunc; + typedef IParamFunctionBase<ROOT::Math::OneDim>::BaseFunc BaseFunc; + + /// default constructor (needed to initialize parent classes) +// IParamFunction() : +// BaseParamFunc() +// {} + + using BaseParamFunc::operator(); + + // user may re-implement this for better efficiency + // this method is NOT required to change internal values of parameters. confusing ?? + /** + Evaluate function at a point x and for parameters p. + This method mey be needed for better efficiencies when for each function evaluation the parameters are changed. + */ + virtual double operator() (double x, const double * p ) + { + SetParameters(p); + return operator() (x); + } + + + +}; + + + + +/** + IParamGradFunction interface for parametric functions providing + the gradient + @ingroup CppFunctions +*/ +template<class DimensionType=MultiDim> +class IParamGradFunction : + public IParamFunction<DimensionType>, + public IGradientFunction<DimensionType> { + +public: + + typedef IParamFunction<DimensionType> BaseParamFunc; + typedef IGradientFunction<DimensionType> BaseGradFunc; + typedef typename IParamFunction<DimensionType>::BaseFunc BaseFunc; + + /// default constructor (needed to initialize parent classes) +// IParamGradFunction() : +// BaseParamFunc(), +// BaseGradFunc() +// {} + + + /** + Virtual Destructor (no operations) + */ + virtual ~IParamGradFunction () {} + + + //using BaseFunc::operator(); + using BaseParamFunc::operator(); + + /** + Evaluate the derivatives of the function with respect to the parameters at a point x. + It is optional to be implemented by the derived classes + */ + void ParameterGradient(const double * x , double * grad ) const { + return DoParameterGradient(x, grad); + } + + +private: + + +// /** +// Set the parameter values +// @param p vector of doubles containing the parameter values. +// */ +// virtual void DoSetParameters(const double * p ) = 0; + + /** + Evaluate the gradient, to be implemented by the derived classes + */ + virtual void DoParameterGradient(const double * x, double * grad) const = 0; + + +}; + +/** + IParamGradFunction interface for one-dimensional function + + @ingroup CppFunctions +*/ +template<> +class IParamGradFunction<ROOT::Math::OneDim> : + public IParamFunction<ROOT::Math::OneDim>, + public IGradientFunction<ROOT::Math::OneDim> { + +public: + + typedef IParamFunction<ROOT::Math::OneDim> BaseParamFunc; + typedef IGradientFunction<ROOT::Math::OneDim> BaseGradFunc; + typedef IParamFunction<ROOT::Math::OneDim>::BaseFunc BaseFunc; + + /// default constructor (needed to initialize parent classes) +// IParamGradFunction() : +// BaseParamFunc(), +// BaseGradFunc() +// {} + + /** + Virtual Destructor (no operations) + */ + virtual ~IParamGradFunction () {} + + + //using BaseFunc::operator(); + using BaseParamFunc::operator(); + + /** + Evaluate the derivatives of the function with respect to the parameters at a point x. + It is optional to be implemented by the derived classes + */ + void ParameterGradient(double x , double * grad ) const { + return DoParameterGradient(x, grad); + } + + +private: + + +// /** +// Set the parameter values +// @param p vector of doubles containing the parameter values. +// */ +// virtual void DoSetParameters(const double * p ) = 0; + + /** + Evaluate the gradient, to be implemented by the derived classes + */ + virtual void DoParameterGradient(double x, double * grad) const = 0; + + +}; + + + + + } // end namespace Math + +} // end namespace ROOT + + + +#endif /* ROOT_Math_IParamFunction */ diff --git a/mathcore/inc/Math/IParamFunctionfwd.h b/mathcore/inc/Math/IParamFunctionfwd.h new file mode 100644 index 0000000000000000000000000000000000000000..1da44488a81e47db7fac93bbfef85a05bf5c1115 --- /dev/null +++ b/mathcore/inc/Math/IParamFunctionfwd.h @@ -0,0 +1,40 @@ +// @(#)root/mathcore:$Name: $:$Id: inc/Math/IParamFunctionfwd.h,v 1.0 2006/01/01 12:00:00 moneta Exp $ +// Author: L. Moneta Tue Nov 14 14:38:52 2006 + +/********************************************************************** + * * + * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * + * * + * * + **********************************************************************/ + +// Forward declarations for template class IParamFunction class + +#ifndef ROOT_Math_IParamFunctionfwd +#define ROOT_Math_IParamFunctionfwd + +#ifndef ROOT_Math_IFunctionfwd +#include "Math/IFunctionfwd.h" +#endif + +namespace ROOT { + + namespace Math { + + + template<class DimensionType, class CapabilityType> class IParamFunction; + + typedef IParamFunction<OneDim, Base> IParam1DFunction; + typedef IParamFunction<MultiDim, Base> IParamMultiFunction; + + typedef IParamFunction<OneDim, Gradient> IParam1DGradFunction; + typedef IParamFunction<MultiDim, Gradient> IParamMultiGradFunction; + + + + } // end namespace Math + +} // end namespace ROOT + + +#endif /* ROOT_Math_IParamFunctionfwd */ diff --git a/mathcore/inc/Math/LinkDef_Func.h b/mathcore/inc/Math/LinkDef_Func.h index 2cfce1840167da58bed95ff997823fb7e1571df5..2aeba06e5aa87ef6eca4334d0501c77afe1c2e72 100644 --- a/mathcore/inc/Math/LinkDef_Func.h +++ b/mathcore/inc/Math/LinkDef_Func.h @@ -1,4 +1,4 @@ -// @(#)root/mathcore:$Name: $:$Id: LinkDef_Func.h,v 1.2 2005/06/28 09:55:13 brun Exp $ +// @(#)root/mathcore:$Name: $:$Id: LinkDef_Func.h,v 1.1 2005/09/18 17:33:47 brun Exp $ // Authors: Andras Zsenei & Lorenzo Moneta 06/2005 /********************************************************************** @@ -15,6 +15,31 @@ #pragma link C++ namespace ROOT; #pragma link C++ namespace ROOT::Math; +#ifdef OLD +#pragma link C++ class ROOT::Math::IFunction<ROOT::Math::OneDim,ROOT::Math::Base>+; +#pragma link C++ class ROOT::Math::IFunction<ROOT::Math::OneDim,ROOT::Math::Gradient>+; +#pragma link C++ class ROOT::Math::IFunction<ROOT::Math::MultiDim,ROOT::Math::Base>+; +#pragma link C++ class ROOT::Math::IFunction<ROOT::Math::MultiDim,ROOT::Math::Gradient>+; + +#pragma link C++ class ROOT::Math::IParamFunction<ROOT::Math::OneDim,ROOT::Math::Base>+; +#pragma link C++ class ROOT::Math::IParamFunction<ROOT::Math::OneDim,ROOT::Math::Gradient>+; +#pragma link C++ class ROOT::Math::IParamFunction<ROOT::Math::MultiDim,ROOT::Math::Base>+; +#pragma link C++ class ROOT::Math::IParamFunction<ROOT::Math::MultiDim,ROOT::Math::Gradient>+; + +#endif + +#pragma link C++ class ROOT::Math::IBaseFunction<ROOT::Math::OneDim>+; +#pragma link C++ class ROOT::Math::IGradientFunction<ROOT::Math::OneDimt>+; +#pragma link C++ class ROOT::Math::IBaseFunction<ROOT::Math::MultiDim>+; +#pragma link C++ class ROOT::Math::IGradientFunction<ROOT::Math::MultiDim>+; + +#pragma link C++ class ROOT::Math::IParamFunction<ROOT::Math::OneDim>+; +#pragma link C++ class ROOT::Math::IParamGradFunction<ROOT::Math::OneDim>+; +#pragma link C++ class ROOT::Math::IParamFunction<ROOT::Math::MultiDim>+; +#pragma link C++ class ROOT::Math::IParamGradFunction<ROOT::Math::MultiDim>+; + + + #pragma link C++ function ROOT::Math::erf( double ); #pragma link C++ function ROOT::Math::erfc( double ); #pragma link C++ function ROOT::Math::tgamma( double ); diff --git a/mathcore/inc/Math/Util.h b/mathcore/inc/Math/Util.h new file mode 100644 index 0000000000000000000000000000000000000000..e99af785ad460f6fe82ecd41d450e6c56e5ae4b1 --- /dev/null +++ b/mathcore/inc/Math/Util.h @@ -0,0 +1,50 @@ +// @(#)root/mathcore:$Name: $:$Id: inc/Math/Util.h,v 1.0 2006/01/01 12:00:00 moneta Exp $ +// Author: L. Moneta Tue Nov 14 15:44:38 2006 + +/********************************************************************** + * * + * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * + * * + * * + **********************************************************************/ + +// Utility functions for all ROOT Math + +#ifndef ROOT_Math_Util +#define ROOT_Math_Util + +#include <string> +#include <sstream> + +namespace ROOT { + + namespace Math { + + +/** + namespace definining Utility funciton needed in mathcore +*/ +namespace Util { + +/** + Utility function for conversion to strings +*/ +template<class T> +std::string ToString(const T& val) +{ + std::ostringstream buf; + buf << val; + + std::string ret = buf.str(); + return ret; +} + +} // end namespace Util + + + } // end namespace Math + +} // end namespace ROOT + + +#endif /* ROOT_Math_Util */