All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
NumericalDerivative.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // GaudiKernel
5 // ============================================================================
6 #include "GaudiKernel/GaudiException.h"
7 // ============================================================================
8 // local
9 // ============================================================================
10 #include "GaudiMath/NumericalDerivative.h"
11 #include "GaudiMath/Constant.h"
12 // ============================================================================
13 // GSL
14 // ============================================================================
15 #include "gsl/gsl_errno.h"
16 #include "gsl/gsl_diff.h"
17 #include "gsl/gsl_math.h"
18 // ============================================================================
19 // local
20 // ============================================================================
21 #include "Helpers.h"
22 // ============================================================================
23 
24 // ============================================================================
31 // ============================================================================
32 
33 namespace Genfun
34 {
35  namespace GaudiMathImplementation
36  {
37  // ========================================================================
39  // ========================================================================
40  FUNCTION_OBJECT_IMP( NumericalDerivative )
41  // ========================================================================
42 
43  // ========================================================================
50  // ========================================================================
51  NumericalDerivative::NumericalDerivative
52  ( const AbsFunction& function ,
53  const size_t index ,
54  const NumericalDerivative::Type& type )
55  : AbsFunction ()
56  , m_function ( function.clone() )
57  , m_index ( index )
58  , m_DIM ( function.dimensionality() )
59  , m_type ( type )
60  , m_argument ( function.dimensionality() )
61  , m_result ( GSL_NEGINF )
62  , m_error ( GSL_POSINF )
63  {
64  if( m_index >= m_DIM )
65  { Exception ( "::constructor invalid variable index " ) ; };
66  }
67  // ========================================================================
68 
69  // ========================================================================
71  // ========================================================================
73  ( const NumericalDerivative& right )
74  : AbsFunction ()
75  , m_function ( right.m_function->clone() )
76  , m_index ( right.m_index )
77  , m_DIM ( right.m_DIM )
78  , m_type ( right.m_type )
79  , m_argument ( right.m_DIM )
80  , m_result ( GSL_NEGINF )
81  , m_error ( GSL_POSINF )
82  {}
83  // ========================================================================
84 
85  // ========================================================================
87  // ========================================================================
90  { m_type = value ; return type() ; }
91  // ========================================================================
92 
93  // ========================================================================
95  // ========================================================================
97  {
98  if( idx >= m_DIM )
99  { Exception ( "::partial(i): invalid variable index" ) ; }
100  const AbsFunction& aux =
101  NumericalDerivative( *this , idx , type() ) ;
102  return FunctionNoop( &aux ) ;
103  }
104  // ========================================================================
105 
106  // ========================================================================
108  // ========================================================================
109  double NumericalDerivative::operator()
110  ( const Argument& argument ) const
111  {
112  // reset the result and the error
113  m_result = GSL_NEGINF ;
114  m_error = GSL_POSINF ;
115 
116  // check the argument
117  if( argument.dimension() != m_DIM )
118  { Exception ( "::operator():invalid argument size" ) ; };
119 
121  {for( size_t i = 0 ; i < m_DIM ; ++i ){ m_argument[i] = argument[i];}}
122 
123  // create the helper object
124  GSL_Helper helper( *m_function , m_argument , m_index );
125 
127  gsl_function F ;
128  F.function = &GSL_Adaptor ;
129  F.params = &helper ;
130 
131  double x = argument[m_index];
132  int ierrno = 0 ;
133  switch ( type() )
134  {
135  case Central :
136  ierrno = gsl_diff_central ( &F , x , &m_result , &m_error ) ; break ;
137  case Forward :
138  ierrno = gsl_diff_forward ( &F , x , &m_result , &m_error ) ; break ;
139  case Backward :
140  ierrno = gsl_diff_backward ( &F , x , &m_result , &m_error ) ; break ;
141  default:
142  Exception ( "::operator(): invalid diffrentiation type " ) ;
143  }
144 
145  if( ierrno )
146  { gsl_error ( " NumericalDerivative:: the error from gsl_diff_XXXX" ,
147  __FILE__ , __LINE__ , ierrno ) ; }
148 
149  return result() ;
150  }
151  // ========================================================================
152 
153  // ========================================================================
155  // ========================================================================
156  double NumericalDerivative::operator() ( const double argument ) const
157  {
158  // reset the result and the error
159  m_result = GSL_NEGINF ;
160  m_error = GSL_POSINF ;
161 
162  // check the argument
163  if( 1 != m_DIM ) { Exception ( "operator(): invalid argument size " ); }
164 
165  Argument arg(1) ;
166  arg[0] = argument ;
167  return (*this)( arg ) ;
168  }
169  // ========================================================================
170 
171  // ========================================================================
173  // ========================================================================
175  ( const std::string& message ,
176  const StatusCode& sc ) const
177  {
178  throw GaudiException( "NumericalDerivative" + message ,
179  "*GaudiMath*" , sc ) ;
180  return sc ;
181  }
182  // ========================================================================
183 
184 
185  } // end of namespace GaudiMathImplementation
186 
187 } // end of namespace Genfun (due to GSL)
188 
189 // ============================================================================
190 // The END
191 // ============================================================================
Define general base for Gaudi exception.
virtual double operator()(double argument) const
Function value.
Genfun::GaudiMathImplementation::NumericalDerivative Derivative
Definition: GaudiMath.h:29
const Type & setType(const Type &value)
change the type of the adaptive differentiation
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual Derivative partial(unsigned int index) const
Derivatives.
double GSL_Adaptor(double x, void *params)
Definition: Helpers.cpp:37
Numerical derivative (using GSL adaptive numerical differentiation)
StatusCode Exception(const std::string &message, const StatusCode &sc=StatusCode::FAILURE) const
Exception.
CLHEP.
Definition: IEqSolver.h:13
the simple structure to be used for adaption interface Genfun::AbsFunction to gsl_function structure ...
Definition: Helpers.h:26
list i
Definition: ana.py:128
string type
Definition: gaudirun.py:151