00001
00002
00003 #ifndef GAUDIMATH_SPLINES_H
00004 #define GAUDIMATH_SPLINES_H 1
00005
00006
00007
00008
00009
00010 #include <vector>
00011 #include <utility>
00012 #include <algorithm>
00013
00014
00015
00016 #include "CLHEP/GenericFunctions/GenericFunctions.hh"
00017 #include "CLHEP/GenericFunctions/Argument.hh"
00018 #include "CLHEP/GenericFunctions/AbsFunction.hh"
00019
00020
00021
00022 #include "GaudiMath/Interpolation.h"
00023
00024
00025
00026 #include "gsl/gsl_interp.h"
00027 #include "gsl/gsl_spline.h"
00028
00029 #include "GaudiKernel/Kernel.h"
00030
00031 namespace Genfun
00032 {
00033 namespace GaudiMathImplementation
00034 {
00035
00036 class GAUDI_API SplineBase
00037 {
00038 public:
00039 typedef std::vector<double> Data1D ;
00040 typedef std::vector<std::pair<double,double> > Data2D ;
00041 public:
00047 SplineBase
00048 ( const Data1D& x ,
00049 const Data1D& y ,
00050 const GaudiMath::Interpolation::Type type ) ;
00055 SplineBase
00056 ( const Data2D& data ,
00057 const GaudiMath::Interpolation::Type type ) ;
00064 template <class DATAX, class DATAY>
00065 SplineBase
00066 ( const GaudiMath::Interpolation::Type type ,
00067 DATAX begin_x ,
00068 DATAX end_x ,
00069 DATAY begin_y )
00070 : m_init ( false )
00071 , m_dim ( end_x - begin_x )
00072 , m_x ( new double[ end_x - begin_x ] )
00073 , m_y ( new double[ end_x - begin_x ] )
00074 , m_spline ( 0 )
00075 , m_accel ( 0 )
00076 , m_type ( type )
00077 {
00078 std::copy ( begin_x , end_x , m_x ) ;
00079 std::copy ( begin_y , begin_y + ( end_x - begin_x ) , m_y ) ;
00080 }
00088 template <class DATA>
00089 SplineBase
00090 ( const GaudiMath::Interpolation::Type type ,
00091 DATA begin ,
00092 DATA end )
00093 : m_init ( false )
00094 , m_dim ( end - begin )
00095 , m_x ( new double[ end - begin ] )
00096 , m_y ( new double[ end - begin ] )
00097 , m_spline ( 0 )
00098 , m_accel ( 0 )
00099 , m_type ( type )
00100 {
00101 double* _x = m_x ;
00102 double* _y = m_y ;
00103 for ( DATA it = begin ; end != it ; ++ it )
00104 {
00105 *_x = it -> first ; ++_x ;
00106 *_y = it -> second ; ++_y ;
00107 };
00108 }
00110 SplineBase( const SplineBase& ) ;
00112 virtual ~SplineBase();
00113 public:
00115 double eval ( const double x ) const ;
00117 double deriv ( const double x ) const ;
00119 double deriv2 ( const double x ) const ;
00121 double integ ( const double a , const double b ) const ;
00122 protected:
00123
00124 void initialize () const ;
00125 private:
00126
00127 SplineBase() ;
00128
00129 SplineBase& operator=( const SplineBase& ) ;
00130 private:
00131 mutable bool m_init ;
00132 size_t m_dim ;
00133 double* m_x ;
00134 double* m_y ;
00135 mutable gsl_spline* m_spline ;
00136 mutable gsl_interp_accel* m_accel ;
00137 GaudiMath::Interpolation::Type m_type ;
00138 };
00139
00140 class GAUDI_API GSLSpline : public AbsFunction
00141 {
00142 public:
00143 typedef SplineBase::Data1D Data1D ;
00144 typedef SplineBase::Data2D Data2D ;
00145 public:
00147 FUNCTION_OBJECT_DEF( GSLSpline )
00148 public:
00169 GSLSpline
00170 ( const Data1D& x ,
00171 const Data1D& y ,
00172 const GaudiMath::Interpolation::Type type ) ;
00191 GSLSpline
00192 ( const Data2D& data ,
00193 const GaudiMath::Interpolation::Type type ) ;
00220 template <class DATAX, class DATAY>
00221 GSLSpline
00222 ( const GaudiMath::Interpolation::Type type ,
00223 DATAX begin_x ,
00224 DATAX end_x ,
00225 DATAY begin_y )
00226 : AbsFunction ( )
00227 , m_spline( type , begin_x , end_x , begin_y )
00228 {}
00240 template <class DATA>
00241 GSLSpline
00242 ( const GaudiMath::Interpolation::Type type ,
00243 DATA begin ,
00244 DATA end )
00245 : AbsFunction ( )
00246 , m_spline( type , begin , end )
00247 {}
00249 GSLSpline ( const SplineBase& ) ;
00251 GSLSpline ( const GSLSpline& ) ;
00253 virtual ~GSLSpline() ;
00254 public:
00256 virtual double operator() ( double a ) const ;
00258 virtual double operator() ( const Argument& x ) const ;
00259 virtual unsigned int dimensionality () const { return 1 ; }
00261 virtual bool hasAnalyticDerivative() const { return true ; }
00263 virtual Genfun::Derivative partial( unsigned int i ) const ;
00264 public:
00266 inline const SplineBase& spline() const { return m_spline ; }
00268 operator const SplineBase& () const { return spline() ; }
00269 private:
00271 GSLSpline() ;
00273 GSLSpline& operator=( const GSLSpline& ) ;
00274 private:
00275
00276 SplineBase m_spline ;
00277 };
00278
00279 class GAUDI_API GSLSplineDeriv : public AbsFunction
00280 {
00281 public:
00282 typedef SplineBase::Data1D Data1D ;
00283 typedef SplineBase::Data2D Data2D ;
00284 public:
00286 FUNCTION_OBJECT_DEF( GSLSplineDeriv )
00287 public:
00308 GSLSplineDeriv
00309 ( const Data1D& x ,
00310 const Data1D& y ,
00311 const GaudiMath::Interpolation::Type type ) ;
00330 GSLSplineDeriv
00331 ( const Data2D& data ,
00332 const GaudiMath::Interpolation::Type type ) ;
00359 template <class DATAX, class DATAY>
00360 GSLSplineDeriv
00361 ( const GaudiMath::Interpolation::Type type ,
00362 DATAX begin_x ,
00363 DATAX end_x ,
00364 DATAY begin_y )
00365 : AbsFunction ( )
00366 , m_spline( type , begin_x , end_x , begin_y )
00367 {}
00379 template <class DATA>
00380 GSLSplineDeriv
00381 ( const GaudiMath::Interpolation::Type type ,
00382 DATA begin ,
00383 DATA end )
00384 : AbsFunction ( )
00385 , m_spline( type , begin , end )
00386 {}
00388 GSLSplineDeriv ( const SplineBase& ) ;
00390 GSLSplineDeriv ( const GSLSplineDeriv& ) ;
00392 virtual ~GSLSplineDeriv() ;
00393 public:
00395 virtual double operator() ( double a ) const ;
00397 virtual double operator() ( const Argument& x ) const ;
00398 virtual unsigned int dimensionality () const { return 1 ; }
00400 virtual bool hasAnalyticDerivative() const { return true ; }
00402 virtual Genfun::Derivative partial( unsigned int i ) const ;
00403 public:
00405 inline const SplineBase& spline() const { return m_spline ; }
00407 operator const SplineBase& () const { return spline() ; }
00408 private:
00410 GSLSplineDeriv() ;
00412 GSLSplineDeriv& operator=( const GSLSplineDeriv& ) ;
00413 private:
00414
00415 SplineBase m_spline ;
00416 };
00417
00418 class GAUDI_API GSLSplineDeriv2 : public AbsFunction
00419 {
00420 public:
00421 typedef SplineBase::Data1D Data1D ;
00422 typedef SplineBase::Data2D Data2D ;
00423 public:
00425 FUNCTION_OBJECT_DEF( GSLSplineDeriv2 )
00426 public:
00447 GSLSplineDeriv2
00448 ( const Data1D& x ,
00449 const Data1D& y ,
00450 const GaudiMath::Interpolation::Type type ) ;
00469 GSLSplineDeriv2
00470 ( const Data2D& data ,
00471 const GaudiMath::Interpolation::Type type ) ;
00498 template <class DATAX, class DATAY>
00499 GSLSplineDeriv2
00500 ( const GaudiMath::Interpolation::Type type ,
00501 DATAX begin_x ,
00502 DATAX end_x ,
00503 DATAY begin_y )
00504 : AbsFunction ( )
00505 , m_spline( type , begin_x , end_x , begin_y )
00506 {}
00518 template <class DATA>
00519 GSLSplineDeriv2
00520 ( const GaudiMath::Interpolation::Type type ,
00521 DATA begin ,
00522 DATA end )
00523 : AbsFunction ( )
00524 , m_spline( type , begin , end )
00525 {}
00527 GSLSplineDeriv2 ( const SplineBase& ) ;
00529 GSLSplineDeriv2 ( const GSLSplineDeriv2& ) ;
00531 virtual ~GSLSplineDeriv2() ;
00532 public:
00534 virtual double operator() ( double a ) const ;
00536 virtual double operator() ( const Argument& x ) const ;
00537 virtual unsigned int dimensionality () const { return 1 ; }
00539 virtual bool hasAnalyticDerivative() const { return true ; }
00541 virtual Genfun::Derivative partial( unsigned int i ) const ;
00542 public:
00544 inline const SplineBase& spline() const { return m_spline ; }
00546 operator const SplineBase& () const { return spline() ; }
00547 private:
00549 GSLSplineDeriv2() ;
00551 GSLSplineDeriv2& operator=( const GSLSplineDeriv2& ) ;
00552 private:
00553
00554 SplineBase m_spline ;
00555 };
00556
00557
00558 class GAUDI_API GSLSplineInteg : public AbsFunction
00559 {
00560 public:
00561 typedef SplineBase::Data1D Data1D ;
00562 typedef SplineBase::Data2D Data2D ;
00563 public:
00565 FUNCTION_OBJECT_DEF( GSLSplineInteg )
00566 public:
00587 GSLSplineInteg
00588 ( const Data1D& x ,
00589 const Data1D& y ,
00590 const GaudiMath::Interpolation::Type type ,
00591 const double low = 0 ) ;
00611 GSLSplineInteg
00612 ( const Data2D& data ,
00613 const GaudiMath::Interpolation::Type type ,
00614 const double low = 0 ) ;
00642 template <class DATAX, class DATAY>
00643 GSLSplineInteg
00644 ( const GaudiMath::Interpolation::Type type ,
00645 DATAX begin_x ,
00646 DATAX end_x ,
00647 DATAY begin_y ,
00648 const double low )
00649 : AbsFunction ( )
00650 , m_spline ( type , begin_x , end_x , begin_y )
00651 , m_low ( low )
00652 {}
00665 template <class DATA>
00666 GSLSplineInteg
00667 ( const GaudiMath::Interpolation::Type type ,
00668 DATA begin ,
00669 DATA end ,
00670 const double low )
00671 : AbsFunction ( )
00672 , m_spline ( type , begin , end )
00673 , m_low ( low )
00674 {}
00676 GSLSplineInteg ( const SplineBase& ,
00677 const double low = 0 ) ;
00679 GSLSplineInteg ( const GSLSplineInteg& ) ;
00681 virtual ~GSLSplineInteg () ;
00682 public:
00684 virtual double operator() ( double a ) const ;
00686 virtual double operator() ( const Argument& x ) const ;
00687 virtual unsigned int dimensionality () const { return 1 ; }
00689 virtual bool hasAnalyticDerivative() const { return true ; }
00691 virtual Genfun::Derivative partial( unsigned int i ) const ;
00692 public:
00694 inline const SplineBase& spline() const { return m_spline ; }
00696 operator const SplineBase& () const { return spline() ; }
00697 private:
00699 GSLSplineInteg () ;
00701 GSLSplineInteg& operator=( const GSLSplineInteg& ) ;
00702 private:
00703
00704 SplineBase m_spline ;
00705 double m_low ;
00706 };
00707
00708 }
00709 }
00710
00711
00712 #endif // GAUDIMATH_SPLINES_H
00713