11 #include "gsl/gsl_errno.h"
12 #include "gsl/gsl_integration.h"
16 #include "GaudiKernel/GaudiException.h"
20 #include "GaudiMath/NumericalDefiniteIntegral.h"
21 #include "GaudiMath/NumericalDerivative.h"
32 #pragma warning(disable:1572)
38 #pragma warning(disable:4996)
43 namespace GaudiMathImplementation
47 { gsl_function*
fn ; };
107 ( const AbsFunction& function ,
113 const
double epsabs ,
114 const
double epsrel ,
117 , m_function ( function.clone () )
128 , m_epsabs ( epsabs )
129 , m_epsrel ( epsrel )
130 , m_result ( GSL_NEGINF )
131 , m_error ( GSL_POSINF )
138 if (
function.dimensionality() < 2 )
139 { Exception(
"::constructor: invalid dimensionality ") ; }
140 if ( m_index >=
function.dimensionality() )
141 { Exception(
"::constructor: invalid variable index") ; }
143 m_DIM =
function.dimensionality() - 1 ;
144 m_argument = Argument( m_DIM ) ;
145 m_argF = Argument( m_DIM + 1 ) ;
160 (
const AbsFunction&
function ,
165 const double epsabs ,
166 const double epsrel ,
169 , m_function (
function.clone() )
179 , m_points ( points )
180 , m_epsabs ( epsabs )
181 , m_epsrel ( epsrel )
183 , m_result ( GSL_NEGINF )
184 , m_error ( GSL_POSINF )
190 if (
function.dimensionality() < 2 )
191 { Exception(
"::constructor: invalid dimensionality ") ; }
192 if ( m_index >=
function.dimensionality() )
193 { Exception(
"::constructor: invalid variable index") ; }
195 m_DIM =
function.dimensionality() - 1 ;
196 m_argument = Argument( m_DIM ) ;
197 m_argF = Argument( m_DIM + 1 ) ;
199 const double l1 = std::min ( a , b ) ;
200 const double l2 = std::max ( a , b ) ;
201 m_points.push_back ( l1 ) ;
202 m_points.push_back ( l2 ) ;
203 std::sort ( m_points.begin() , m_points.end() ) ;
204 m_points.erase( std::unique( m_points.begin () ,
208 Points::iterator lower =
209 std::lower_bound ( m_points.begin () , m_points.end () , l1 ) ;
210 m_points.erase ( m_points.begin () , lower ) ;
211 Points::iterator upper =
212 std::upper_bound ( m_points.begin () , m_points.end () , l2 ) ;
213 m_points.erase ( upper , m_points.end () ) ;
215 m_pdata.reset(
new double[ m_points.size() ] );
216 std::copy( m_points.begin() , m_points.end() , m_pdata.get() );
245 (
const AbsFunction&
function ,
249 const double epsabs ,
250 const double epsrel ,
253 , m_function (
function.clone() )
264 , m_epsabs ( epsabs )
265 , m_epsrel ( epsrel )
267 , m_result ( GSL_NEGINF )
268 , m_error ( GSL_POSINF )
274 if (
function.dimensionality() < 2 )
275 { Exception(
"::constructor: invalid dimensionality ") ; }
276 if ( m_index >=
function.dimensionality() )
277 { Exception(
"::constructor: invalid variable index") ; }
279 m_DIM =
function.dimensionality() - 1 ;
280 m_argument = Argument( m_DIM ) ;
281 m_argF = Argument( m_DIM + 1 ) ;
312 (
const AbsFunction&
function ,
316 const double epsabs ,
317 const double epsrel ,
320 , m_function (
function.clone() )
331 , m_epsabs ( epsabs )
332 , m_epsrel ( epsrel )
334 , m_result ( GSL_NEGINF )
335 , m_error ( GSL_POSINF )
341 if (
function.dimensionality() < 2 )
342 { Exception(
"::constructor: invalid dimensionality ") ; }
343 if ( m_index >=
function.dimensionality() )
344 { Exception(
"::constructor: invalid variable index") ; }
346 m_DIM =
function.dimensionality() - 1 ;
347 m_argument = Argument( m_DIM ) ;
348 m_argF = Argument( m_DIM + 1 ) ;
375 (
const AbsFunction&
function ,
381 , m_function (
function.clone() )
392 , m_epsabs ( epsabs )
393 , m_epsrel ( epsrel )
395 , m_result ( GSL_NEGINF )
396 , m_error ( GSL_POSINF )
402 if (
function.dimensionality() < 2 )
403 { Exception(
"::constructor: invalid dimensionality ") ; }
404 if ( m_index >=
function.dimensionality() )
405 { Exception(
"::constructor: invalid variable index") ; }
407 m_DIM =
function.dimensionality() - 1 ;
408 m_argument = Argument( m_DIM ) ;
409 m_argF = Argument( m_DIM + 1 ) ;
418 , m_DIM ( right.
m_DIM )
422 , m_ia ( right.
m_ia )
423 , m_ib ( right.
m_ib )
430 , m_result ( GSL_NEGINF )
431 , m_error ( GSL_POSINF )
438 m_pdata.reset(
new double[m_points.size()] );
439 std::copy( m_points.begin() , m_points.end() , m_pdata.get() );
447 (
const std::string& message ,
451 "*GaudiMath*" , sc ) ;
459 double NumericalDefiniteIntegral::operator()
460 (
const double argument )
const
463 m_result = GSL_NEGINF ;
464 m_error = GSL_POSINF ;
467 if( 1 != m_DIM ) { Exception (
"operator(): invalid argument size " ) ; };
469 m_argument[0] = argument ;
470 return (*
this) ( m_argument );
481 {
Exception (
"::partial(i): invalid variable index " ) ; };
484 return Genfun::FunctionNoop( &aux ) ;
492 double NumericalDefiniteIntegral::operator()
493 (
const Argument& argument )
const
496 m_result = GSL_NEGINF ;
497 m_error = GSL_POSINF ;
500 if( argument.dimension() != m_DIM )
501 { Exception (
"operator(): invalid argument size " ) ; };
505 for(
size_t i = 0 ;
i < m_DIM ; ++
i )
507 m_argument [
i] = argument [
i] ;
508 const size_t j =
i < m_index ?
i :
i + 1 ;
509 m_argF [j] = argument [
i] ;
513 GSL_Helper helper( *m_function , m_argF , m_index );
523 {
return QAGI ( &F1 ) ; }
527 m_result = 0 ; m_error = 0 ;
532 {
return QAGP ( &F1 ) ; }
535 {
return QNG ( &F1 ) ; }
537 {
return QAG ( &F1 ) ; }
539 {
return QAGS ( &F1 ) ; }
541 { Exception (
"::operator(): invalid type " ); }
543 { Exception (
"::operator(): invalid category " ); }
557 m_ws->ws = gsl_integration_workspace_alloc( size () );
558 if ( !
m_ws->ws ) {
Exception (
"allocate()::invalid workspace" ) ; };
570 if ( 0 == F ) {
Exception(
"::QAGI: invalid function"); }
579 ierror = gsl_integration_qagi ( F->
fn ,
586 ierror = gsl_integration_qagil ( F->
fn ,
m_b ,
593 ierror = gsl_integration_qagiu ( F->
fn ,
m_a ,
599 {
Exception (
"::QAGI: invalid mode" ) ; };
601 if( ierror ) { gsl_error(
"NumericalDefiniteIntegral::QAGI" ,
602 __FILE__ , __LINE__ , ierror ) ;}
613 if( 0 == F ) {
Exception(
"QAGP::invalid function") ; }
618 const size_t npts =
points().size();
622 gsl_integration_qagp ( F->
fn ,
628 if( ierror ) { gsl_error(
"NumericalDefiniteIntegral::QAGI " ,
629 __FILE__ , __LINE__ , ierror ) ; }
643 if( 0 == F ) {
Exception(
"QNG::invalid function") ; }
646 const double low = std::min (
m_a ,
m_b ) ;
647 const double high = std::max (
m_a ,
m_b ) ;
651 gsl_integration_qng ( F->
fn ,
656 if( ierror ) { gsl_error(
"NumericalIndefiniteIntegral::QNG " ,
657 __FILE__ , __LINE__ , ierror ) ; }
672 if( 0 == F ) {
Exception(
"QAG::invalid function") ; }
678 const double low = std::min (
m_a ,
m_b ) ;
679 const double high = std::max (
m_a ,
m_b ) ;
682 gsl_integration_qag ( F->
fn ,
685 size () , (
int)
rule() ,
ws ()->
ws ,
688 if( ierror ) { gsl_error(
"NumericalDefiniteIntegral::QAG " ,
689 __FILE__ , __LINE__ , ierror ) ; }
703 if( 0 == F ) {
Exception(
"QAG::invalid function") ; }
716 const double low = std::min (
m_a ,
m_b ) ;
717 const double high = std::max (
m_a ,
m_b ) ;
720 gsl_integration_qags ( F->
fn ,
726 if( ierror ) { gsl_error(
"NumericalDefiniteIntegral::QAGS " ,
727 __FILE__ , __LINE__ , ierror ) ; }
StatusCode Exception(const std::string &message, const StatusCode &sc=StatusCode::FAILURE) const
Define general base for Gaudi exception.
std::unique_ptr< _Workspace, gsl_ws_deleter > m_ws
GaudiMath::Integration::Category m_category
NumericalDefiniteIntegral()
Genfun::GaudiMathImplementation::NumericalDerivative Derivative
GaudiMath::Integration::KronrodRule m_rule
This class is used for returning status codes from appropriate routines.
double QAG(_Function *fun) const
std::unique_ptr< const AbsFunction > m_function
double GSL_Adaptor(double x, void *params)
Numerical derivative (using GSL adaptive numerical differentiation)
_Workspace * allocate() const
allocate the integration workspace
GaudiMath::Integration::Type m_type
std::vector< double > Points
typedef for vector of singular points
const Points & points() const
known singularities
std::unique_ptr< double[]> m_pdata
virtual Genfun::Derivative partial(unsigned int index) const
Derivatives.
double QAGP(_Function *fun) const
GaudiMath.h GaudiMath/GaudiMath.h.
KronrodRule
integration rule
double QNG(_Function *fun) const
double QAGI(_Function *fun) const
gsl_integration_workspace * ws
the simple structure to be used for adaption interface Genfun::AbsFunction to gsl_function structure ...
Type
the list of available types for ntuples
GaudiMath::Integration::KronrodRule rule() const
integration rule
collection of common types for classes NumericalIndefiniteIntegral and NumericalDefiniteIntegral ...
double QAGS(_Function *fun) const
This class allows the numerical evaluation of the following functions: