11 #include "gsl/gsl_errno.h"
12 #include "gsl/gsl_integration.h"
16 #include "GaudiMath/NumericalIndefiniteIntegral.h"
17 #include "GaudiMath/NumericalDerivative.h"
21 #include "GaudiKernel/GaudiException.h"
38 #pragma warning(disable:1572)
44 #pragma warning(disable:4996)
49 namespace GaudiMathImplementation
53 { gsl_function*
fn ; };
78 ( const AbsFunction& function ,
88 , m_function ( function.clone() )
89 , m_DIM ( function.dimensionality() )
100 , m_epsrel ( epsrel )
102 , m_result ( GSL_NEGINF )
103 , m_error ( GSL_POSINF )
106 , m_argument ( function.dimensionality() )
110 if ( m_index >= m_DIM )
111 { Exception(
"::constructor: invalid variable index") ; }
126 (
const AbsFunction&
function ,
131 const double epsabs ,
132 const double epsrel ,
135 , m_function (
function.clone() )
136 , m_DIM (
function.dimensionality() )
143 , m_points ( points )
144 , m_epsabs ( epsabs )
145 , m_epsrel ( epsrel )
147 , m_result ( GSL_NEGINF )
148 , m_error ( GSL_POSINF )
151 , m_argument (
function.dimensionality() )
153 if ( m_index >= m_DIM )
154 { Exception(
"::constructor: invalid variable index") ; }
155 m_pdata.reset(
new double[ 2 + m_points.size() ] );
156 m_points.push_back( a ) ;
157 std::sort( m_points.begin() , m_points.end() ) ;
158 m_points.erase ( std::unique( m_points.begin () ,
159 m_points.end () ) , m_points.end() );
172 (
const AbsFunction&
function ,
175 const double epsabs ,
176 const double epsrel ,
179 , m_function (
function.clone() )
180 , m_DIM (
function.dimensionality() )
188 , m_epsabs ( epsabs )
189 , m_epsrel ( epsrel )
190 , m_result ( GSL_NEGINF )
191 , m_error ( GSL_POSINF )
193 , m_argument (
function.dimensionality() )
195 if ( m_index >= m_DIM )
196 { Exception(
"::constructor: invalid variable index") ; }
207 , m_function ( right.m_function->clone() )
208 , m_DIM ( right.m_DIM )
209 , m_index ( right.m_index )
211 , m_limit ( right.m_limit )
212 , m_type ( right.m_type )
213 , m_category ( right.m_category )
214 , m_rule ( right.m_rule )
215 , m_points ( right.m_points )
216 , m_epsabs ( right.m_epsabs )
217 , m_epsrel ( right.m_epsrel )
218 , m_result ( GSL_NEGINF )
219 , m_error ( GSL_POSINF )
220 , m_size ( right.m_size )
221 , m_argument ( right.m_argument )
232 (
const std::string& message ,
236 "*GaudiMath*" , sc ) ;
244 double NumericalIndefiniteIntegral::operator()
245 (
const double argument )
const
248 m_result = GSL_NEGINF ;
249 m_error = GSL_POSINF ;
252 if( 1 != m_DIM ) { Exception (
"operator(): invalid argument size " ) ; };
254 m_argument[0] = argument ;
255 return (*
this) ( m_argument );
266 {
Exception (
"::partial(i): invalid variable index " ) ; };
270 return Genfun::FunctionNoop( &aux ) ;
274 const AbsFunction& aux = -1 *
function() ;
275 return Genfun::FunctionNoop( &aux ) ;
277 const AbsFunction& aux =
function() ;
278 return Genfun::FunctionNoop( &aux ) ;
284 double NumericalIndefiniteIntegral::operator()
285 (
const Argument& argument )
const
288 m_result = GSL_NEGINF ;
289 m_error = GSL_POSINF ;
292 if( argument.dimension() != m_DIM )
293 { Exception (
"operator(): invalid argument size " ) ; };
296 {
for(
size_t i = 0 ;
i < m_DIM ; ++
i ){ m_argument[
i] = argument[
i];}}
299 GSL_Helper helper( *m_function , m_argument , m_index );
309 {
return QAGI ( &F1 ) ; }
311 {
return QAGP ( &F1 ) ; }
314 {
return QNG ( &F1 ) ; }
316 {
return QAG ( &F1 ) ; }
318 {
return QAGS ( &F1 ) ; }
320 { Exception (
"::operator(): invalid type " ); }
322 { Exception (
"::operator(): invalid category " ); }
336 m_ws->ws = gsl_integration_workspace_alloc( size () );
337 if ( !
m_ws->ws ) {
Exception (
"allocate()::invalid workspace" ) ; };
349 if( !F ) {
Exception(
"::QAGI: invalid function"); }
360 ierror = gsl_integration_qagiu ( F->
fn , x ,
365 ierror = gsl_integration_qagil ( F->
fn , x ,
373 if( ierror ) { gsl_error(
"NumericalIndefiniteIntegral::QAGI" ,
374 __FILE__ , __LINE__ , ierror ) ;}
385 if( !F ) {
Exception(
"QAGP::invalid function") ; }
399 const double a = std::min (
m_a , x ) ;
400 const double b = std::max (
m_a , x ) ;
406 Points pnts ( upper - lower ) ;
407 std::copy( lower , upper , pnts.begin() );
408 if ( *lower != a ) { pnts.insert( pnts.begin () ,
a ) ; }
409 if ( *upper != b ) { pnts.insert( pnts.end () , b ) ; }
410 std::copy( pnts.begin() , pnts.end() ,
m_pdata.get() );
411 const size_t npts = pnts.size() ;
415 gsl_integration_qagp ( F->
fn ,
421 if( ierror ) { gsl_error(
"NumericalIndefiniteIntegral::QAGI " ,
422 __FILE__ , __LINE__ , ierror ) ; }
439 if( !F ) {
Exception(
"QNG::invalid function") ; }
450 const double a = std::min (
m_a , x ) ;
451 const double b = std::max (
m_a , x ) ;
455 gsl_integration_qng ( F->
fn ,
460 if( ierror ) { gsl_error(
"NumericalIndefiniteIntegral::QNG " ,
461 __FILE__ , __LINE__ , ierror ) ; }
477 if( !F ) {
Exception(
"QAG::invalid function") ; }
491 const double a = std::min (
m_a , x ) ;
492 const double b = std::max (
m_a , x ) ;
495 gsl_integration_qag ( F->
fn ,
498 size () , (
int)
rule() ,
ws ()->
ws ,
501 if( ierror ) { gsl_error(
"NumericalIndefiniteIntegral::QAG " ,
502 __FILE__ , __LINE__ , ierror ) ; }
519 if( !F ) {
Exception(
"QAG::invalid function") ; }
533 const double a = std::min (
m_a , x ) ;
534 const double b = std::max (
m_a , x ) ;
537 gsl_integration_qags ( F->
fn ,
543 if( ierror ) { gsl_error(
"NumericalIndefiniteIntegral::QAGS " ,
544 __FILE__ , __LINE__ , ierror ) ; }
Define general base for Gaudi exception.
auto begin(reverse_wrapper< T > &w)
StatusCode Exception(const std::string &message, const StatusCode &sc=StatusCode::FAILURE) const
double QAGI(_Function *fun) const
GaudiMath::Integration::Limit limit() const
integration limit
Genfun::GaudiMathImplementation::NumericalDerivative Derivative
std::unique_ptr< _Workspace, gsl_ws_deleter > m_ws
double QAGS(_Function *fun) const
GaudiMath::Integration::KronrodRule rule() const
integration rule
auto end(reverse_wrapper< T > &w)
This class is used for returning status codes from appropriate routines.
_Workspace * allocate() const
allocate the integration workspace
std::unique_ptr< double[]> m_pdata
double QNG(_Function *fun) const
double GSL_Adaptor(double x, void *params)
double QAG(_Function *fun) const
Numerical derivative (using GSL adaptive numerical differentiation)
double a() const
integration limit
Limit
how to distinguish variable low and variable high limits
GaudiMath.h GaudiMath/GaudiMath.h.
KronrodRule
integration rule
std::vector< double > Points
typedef for vector of singular points
gsl_integration_workspace * ws
double QAGP(_Function *fun) const
the simple structure to be used for adaption interface Genfun::AbsFunction to gsl_function structure ...
NumericalIndefiniteIntegral()
The simple class for numerical integrations.
Type
the list of available types for ntuples
virtual Genfun::Derivative partial(unsigned int index) const
Derivatives.
const Points & points() const
known singularities
collection of common types for classes NumericalIndefiniteIntegral and NumericalDefiniteIntegral ...