The Gaudi Framework  v29r0 (ff2e7097)
NumericalDerivative.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // GaudiKernel
5 // ============================================================================
7 // ============================================================================
8 // local
9 // ============================================================================
10 #include "GaudiMath/Constant.h"
12 // ============================================================================
13 // GSL
14 // ============================================================================
15 #include "gsl/gsl_diff.h"
16 #include "gsl/gsl_errno.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  // ========================================================================
38 
39  // ========================================================================
46  // ========================================================================
47  NumericalDerivative::NumericalDerivative( const AbsFunction& function, const size_t index,
49  : AbsFunction()
50  , m_function( function.clone() )
51  , m_index( index )
52  , m_DIM( function.dimensionality() )
53  , m_type( type )
54  , m_argument( function.dimensionality() )
55  , m_result( GSL_NEGINF )
56  , m_error( GSL_POSINF )
57  {
58  if ( m_index >= m_DIM ) {
59  Exception( "::constructor invalid variable index " );
60  };
61  }
62  // ========================================================================
63 
64  // ========================================================================
66  // ========================================================================
68  : AbsFunction()
69  , m_function( right.m_function->clone() )
70  , m_index( right.m_index )
71  , m_DIM( right.m_DIM )
72  , m_type( right.m_type )
73  , m_argument( right.m_DIM )
74  , m_result( GSL_NEGINF )
75  , m_error( GSL_POSINF )
76  {
77  }
78  // ========================================================================
79 
80  // ========================================================================
82  // ========================================================================
84  {
85  m_type = value;
86  return type();
87  }
88  // ========================================================================
89 
90  // ========================================================================
92  // ========================================================================
94  {
95  if ( idx >= m_DIM ) {
96  Exception( "::partial(i): invalid variable index" );
97  }
98  const AbsFunction& aux = NumericalDerivative( *this, idx, type() );
99  return FunctionNoop( &aux );
100  }
101  // ========================================================================
102 
103  // ========================================================================
105  // ========================================================================
106  double NumericalDerivative::operator()( const Argument& argument ) const
107  {
108  // reset the result and the error
109  m_result = GSL_NEGINF;
110  m_error = GSL_POSINF;
111 
112  // check the argument
113  if ( argument.dimension() != m_DIM ) {
114  Exception( "::operator():invalid argument size" );
115  };
116 
118  {
119  for ( size_t i = 0; i < m_DIM; ++i ) {
120  m_argument[i] = argument[i];
121  }
122  }
123 
124  // create the helper object
126 
128  gsl_function F;
129  F.function = &GSL_Adaptor;
130  F.params = &helper;
131 
132  double x = argument[m_index];
133  int ierrno = 0;
134  switch ( type() ) {
135  case Central:
136  ierrno = gsl_diff_central( &F, x, &m_result, &m_error );
137  break;
138  case Forward:
139  ierrno = gsl_diff_forward( &F, x, &m_result, &m_error );
140  break;
141  case Backward:
142  ierrno = gsl_diff_backward( &F, x, &m_result, &m_error );
143  break;
144  default:
145  Exception( "::operator(): invalid diffrentiation type " );
146  }
147 
148  if ( ierrno ) {
149  gsl_error( " NumericalDerivative:: the error from gsl_diff_XXXX", __FILE__, __LINE__, ierrno );
150  }
151 
152  return result();
153  }
154  // ========================================================================
155 
156  // ========================================================================
158  // ========================================================================
159  double NumericalDerivative::operator()( const double argument ) const
160  {
161  // reset the result and the error
162  m_result = GSL_NEGINF;
163  m_error = GSL_POSINF;
164 
165  // check the argument
166  if ( 1 != m_DIM ) {
167  Exception( "operator(): invalid argument size " );
168  }
169 
170  Argument arg( 1 );
171  arg[0] = argument;
172  return ( *this )( arg );
173  }
174  // ========================================================================
175 
176  // ========================================================================
178  // ========================================================================
180  {
181  throw GaudiException( "NumericalDerivative" + message, "*GaudiMath*", sc );
182  return sc;
183  }
184  // ========================================================================
185 
186  } // end of namespace GaudiMathImplementation
187 
188 } // end of namespace Genfun (due to GSL)
189 
190 // ============================================================================
191 // The END
192 // ============================================================================
Define general base for Gaudi exception.
Genfun::GaudiMathImplementation::NumericalDerivative Derivative
Definition: GaudiMath.h:27
double operator()(double argument) const override
Function value.
Derivative partial(unsigned int index) const override
Derivatives.
STL class.
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:28
double GSL_Adaptor(double x, void *params)
Definition: Helpers.cpp:31
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:25
double result() const
the result of the last call