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