00001
00002
00003
00004
00005
00006
00007 #include "gsl/gsl_interp.h"
00008 #include "gsl/gsl_spline.h"
00009
00010
00011
00012 #include "GaudiMath/Splines.h"
00013 #include "GaudiMath/GaudiMath.h"
00014
00015 #include <cstring>
00016
00017
00024 namespace Genfun
00025 {
00026 namespace GaudiMathImplementation
00027 {
00033 SplineBase::SplineBase
00034 ( const SplineBase::Data1D& x ,
00035 const SplineBase::Data1D& y ,
00036 const GaudiMath::Interpolation::Type type )
00037 : m_init ( false )
00038 , m_dim ( x.size() )
00039 , m_x ( new double[ x.size() ] )
00040 , m_y ( new double[ y.size() ] )
00041 , m_spline ( 0 )
00042 , m_accel ( 0 )
00043 , m_type ( type )
00044 {
00045 #ifdef WIN32
00046
00047
00048
00049 #pragma warning(push)
00050 #pragma warning(disable:4996)
00051 #endif
00052 std::copy( x.begin() , x.end() , m_x ) ;
00053 std::copy( y.begin() , y.end() , m_y ) ;
00054 #ifdef WIN32
00055 #pragma warning(pop)
00056 #endif
00057
00058 }
00059
00060
00061
00066
00067 SplineBase::SplineBase
00068 ( const SplineBase::Data2D& data ,
00069 const GaudiMath::Interpolation::Type type )
00070 : m_init ( false )
00071 , m_dim ( data.size() )
00072 , m_x ( new double[ data.size() ] )
00073 , m_y ( new double[ data.size() ] )
00074 , m_spline ( 0 )
00075 , m_accel ( 0 )
00076 , m_type ( type )
00077 {
00078 double* _x = m_x ;
00079 double* _y = m_y ;
00080 for( Data2D::const_iterator it =
00081 data.begin() ; data.end() != it ; ++it )
00082 {
00083 *_x = it -> first ; ++_x ;
00084 *_y = it -> second ; ++_y ;
00085 }
00086 }
00087
00088
00089
00091
00092 SplineBase::SplineBase ( const SplineBase& right )
00093 : m_init ( false )
00094 , m_dim ( right.m_dim )
00095 , m_x ( new double[ right.m_dim ] )
00096 , m_y ( new double[ right.m_dim ] )
00097 , m_spline ( 0 )
00098 , m_accel ( 0 )
00099 , m_type ( right.m_type )
00100 {
00101 std::memcpy(m_x, right.m_x, m_dim);
00102 std::memcpy(m_y, right.m_y, m_dim);
00103 }
00104
00105
00106
00108
00109 SplineBase::~SplineBase()
00110 {
00111 if ( 0 != m_spline ) { gsl_spline_free ( m_spline ) ; }
00112 if ( 0 != m_accel ) { gsl_interp_accel_free ( m_accel ) ; }
00113
00114 if ( 0 != m_x ) { delete[] m_x ; }
00115 if ( 0 != m_y ) { delete[] m_y ; }
00116 }
00117
00118
00119
00120 void SplineBase::initialize() const
00121 {
00122 if ( m_init ) { return ; }
00123
00124 const gsl_interp_type* T = 0 ;
00125
00126 switch ( m_type )
00127 {
00128 case GaudiMath::Interpolation::Linear :
00129 T = gsl_interp_linear ; break ;
00130 case GaudiMath::Interpolation::Polynomial :
00131 T = gsl_interp_polynomial ; break ;
00132 case GaudiMath::Interpolation::Cspline :
00133 T = gsl_interp_cspline ; break ;
00134 case GaudiMath::Interpolation::Cspline_Periodic :
00135 T = gsl_interp_cspline_periodic ; break ;
00136 case GaudiMath::Interpolation::Akima :
00137 T = gsl_interp_akima ; break ;
00138 case GaudiMath::Interpolation::Akima_Periodic :
00139 T = gsl_interp_akima_periodic ; break ;
00140 default :
00141 T = gsl_interp_cspline ; break ;
00142 };
00143
00144 m_spline = gsl_spline_alloc( T , m_dim ) ;
00145
00146 gsl_spline_init( m_spline , m_x , m_y , m_dim ) ;
00147
00148 m_accel = gsl_interp_accel_alloc() ;
00149
00150 m_init = true ;
00151
00152 }
00153
00154
00155
00156 double SplineBase::eval ( const double x ) const
00157 {
00158 if ( !m_init ) { initialize() ; }
00159 return gsl_spline_eval ( m_spline , x , m_accel );
00160 }
00161
00162
00163
00164 double SplineBase::deriv ( const double x ) const
00165 {
00166 if ( !m_init ) { initialize() ; }
00167 return gsl_spline_eval_deriv ( m_spline , x , m_accel );
00168 }
00169
00170
00171
00172 double SplineBase::deriv2 ( const double x ) const
00173 {
00174 if ( !m_init ) { initialize() ; }
00175 return gsl_spline_eval_deriv2 ( m_spline , x , m_accel );
00176 }
00177
00178
00179
00180 double SplineBase::integ ( const double a ,
00181 const double b ) const
00182 {
00183 if ( !m_init ) { initialize() ; }
00184 return gsl_spline_eval_integ ( m_spline , a , b , m_accel ) ;
00185 }
00186
00187
00188
00189
00190 FUNCTION_OBJECT_IMP( GSLSpline )
00191
00192
00193
00214
00215 GSLSpline::GSLSpline
00216 ( const GSLSpline::Data1D& x ,
00217 const GSLSpline::Data1D& y ,
00218 const GaudiMath::Interpolation::Type type )
00219 : AbsFunction ()
00220 , m_spline ( x , y , type )
00221 {}
00222
00223
00224
00243
00244 GSLSpline::GSLSpline
00245 ( const GSLSpline::Data2D& data ,
00246 const GaudiMath::Interpolation::Type type )
00247 : AbsFunction ()
00248 , m_spline ( data , type )
00249 {}
00250
00251
00252
00254
00255 GSLSpline::GSLSpline
00256 ( const SplineBase& right )
00257 : AbsFunction ()
00258 , m_spline ( right )
00259 {}
00260
00261
00262
00264
00265 GSLSpline::GSLSpline
00266 ( const GSLSpline& right )
00267 : AbsFunction ()
00268 , m_spline ( right )
00269 {}
00270
00271
00272
00274
00275 GSLSpline::~GSLSpline(){}
00276
00277
00278
00279 double GSLSpline::operator() ( double x ) const
00280 { return m_spline.eval( x ) ; }
00281
00282 double GSLSpline::operator() ( const Argument& x ) const
00283 { return m_spline.eval( x[0] ) ; }
00284
00285
00286
00288
00289 Genfun::Derivative GSLSpline::partial( unsigned int i ) const
00290 {
00291 if ( i >= 1 )
00292 {
00293 const AbsFunction& aux = GaudiMath::Constant( 0.0 , 1 ) ;
00294 return Genfun::FunctionNoop( &aux ) ;
00295 }
00296 const AbsFunction& aux = GSLSplineDeriv( *this ) ;
00297 return Genfun::FunctionNoop( &aux ) ;
00298 }
00299
00300
00301
00302 FUNCTION_OBJECT_IMP( GSLSplineDeriv )
00303
00304
00305
00326
00327 GSLSplineDeriv::GSLSplineDeriv
00328 ( const GSLSplineDeriv::Data1D& x ,
00329 const GSLSplineDeriv::Data1D& y ,
00330 const GaudiMath::Interpolation::Type type )
00331 : AbsFunction ()
00332 , m_spline ( x , y , type )
00333 {}
00334
00335
00336
00355
00356 GSLSplineDeriv::GSLSplineDeriv
00357 ( const GSLSplineDeriv::Data2D& data ,
00358 const GaudiMath::Interpolation::Type type )
00359 : AbsFunction ()
00360 , m_spline ( data , type )
00361 {}
00362
00363
00364
00366
00367 GSLSplineDeriv::GSLSplineDeriv
00368 ( const SplineBase& right )
00369 : AbsFunction ()
00370 , m_spline ( right )
00371 {}
00372
00373
00374
00376
00377 GSLSplineDeriv::GSLSplineDeriv
00378 ( const GSLSplineDeriv& right )
00379 : AbsFunction ()
00380 , m_spline ( right )
00381 {}
00382
00383
00384
00386
00387 GSLSplineDeriv::~GSLSplineDeriv(){}
00388
00389
00390
00391 double GSLSplineDeriv::operator() ( double x ) const
00392 { return m_spline.deriv ( x ) ; }
00393
00394 double GSLSplineDeriv::operator() ( const Argument& x ) const
00395 { return m_spline.deriv ( x[0] ) ; }
00396
00397
00398
00400
00401 Genfun::Derivative GSLSplineDeriv::partial( unsigned int i ) const
00402 {
00403 if ( i >= 1 )
00404 {
00405 const AbsFunction& aux = GaudiMath::Constant( 0.0 , 1 ) ;
00406 return Genfun::FunctionNoop( &aux ) ;
00407 }
00408 const AbsFunction& aux = GSLSplineDeriv2( *this ) ;
00409 return Genfun::FunctionNoop( &aux ) ;
00410 }
00411
00412
00413
00414 FUNCTION_OBJECT_IMP( GSLSplineDeriv2 )
00415
00416
00417
00438
00439 GSLSplineDeriv2::GSLSplineDeriv2
00440 ( const GSLSplineDeriv2::Data1D& x ,
00441 const GSLSplineDeriv2::Data1D& y ,
00442 const GaudiMath::Interpolation::Type type )
00443 : AbsFunction ()
00444 , m_spline ( x , y , type )
00445 {}
00446
00447
00448
00467
00468 GSLSplineDeriv2::GSLSplineDeriv2
00469 ( const GSLSplineDeriv2::Data2D& data ,
00470 const GaudiMath::Interpolation::Type type )
00471 : AbsFunction ()
00472 , m_spline ( data , type )
00473 {}
00474
00475
00476
00478
00479 GSLSplineDeriv2::GSLSplineDeriv2
00480 ( const SplineBase& right )
00481 : AbsFunction ()
00482 , m_spline ( right )
00483 {}
00484
00485
00486
00488
00489 GSLSplineDeriv2::GSLSplineDeriv2
00490 ( const GSLSplineDeriv2& right )
00491 : AbsFunction ()
00492 , m_spline ( right )
00493 {}
00494
00495
00496
00498
00499 GSLSplineDeriv2::~GSLSplineDeriv2(){}
00500
00501
00502
00503 double GSLSplineDeriv2::operator() ( double x ) const
00504 { return m_spline.deriv2 ( x ) ; }
00505
00506 double GSLSplineDeriv2::operator() ( const Argument& x ) const
00507 { return m_spline.deriv2 ( x[0] ) ; }
00508
00509
00510
00512
00513 Genfun::Derivative GSLSplineDeriv2::partial( unsigned int i ) const
00514 {
00515 if ( i >= 1 )
00516 {
00517 const AbsFunction& aux = GaudiMath::Constant( 0.0 , 1 ) ;
00518 return Genfun::FunctionNoop( &aux ) ;
00519 }
00520 const AbsFunction& aux = GaudiMath::Derivative( *this , i ) ;
00521 return Genfun::FunctionNoop( &aux ) ;
00522 }
00523
00524
00525
00526
00527 FUNCTION_OBJECT_IMP( GSLSplineInteg )
00528
00529
00530
00551
00552 GSLSplineInteg::GSLSplineInteg
00553 ( const GSLSplineInteg::Data1D& x ,
00554 const GSLSplineInteg::Data1D& y ,
00555 const GaudiMath::Interpolation::Type type ,
00556 const double low )
00557 : AbsFunction ( )
00558 , m_spline ( x , y , type )
00559 , m_low ( low )
00560 {}
00561
00562
00563
00582
00583 GSLSplineInteg::GSLSplineInteg
00584 ( const GSLSplineInteg::Data2D& data ,
00585 const GaudiMath::Interpolation::Type type ,
00586 const double low )
00587 : AbsFunction ()
00588 , m_spline ( data , type )
00589 , m_low ( low )
00590 {}
00591
00592
00593
00595
00596 GSLSplineInteg::GSLSplineInteg
00597 ( const SplineBase& right ,
00598 const double low )
00599 : AbsFunction ()
00600 , m_spline ( right )
00601 , m_low ( low )
00602 {}
00603
00604
00605
00607
00608 GSLSplineInteg::GSLSplineInteg
00609 ( const GSLSplineInteg& right )
00610 : AbsFunction ()
00611 , m_spline ( right )
00612 , m_low ( right.m_low )
00613 {}
00614
00615
00616
00618
00619 GSLSplineInteg::~GSLSplineInteg(){}
00620
00621
00622
00623 double GSLSplineInteg::operator() ( double x ) const
00624 { return m_spline.integ ( m_low , x ) ; }
00625
00626 double GSLSplineInteg::operator() ( const Argument& x ) const
00627 { return m_spline.integ ( m_low , x[0] ) ; }
00628
00629
00630
00632
00633 Genfun::Derivative GSLSplineInteg::partial( unsigned int i ) const
00634 {
00635 if ( i >= 1 )
00636 {
00637 const AbsFunction& aux = GaudiMath::Constant( 0.0 , 1 ) ;
00638 return Genfun::FunctionNoop( &aux ) ;
00639 }
00640 const AbsFunction& aux = GSLSpline( *this ) ;
00641 return Genfun::FunctionNoop( &aux ) ;
00642 }
00643
00644
00645 }
00646 }