Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

NumericalDerivative.cpp

Go to the documentation of this file.
00001 // $Id: NumericalDerivative.cpp,v 1.1 2003/11/19 16:56:00 mato Exp $
00002 // ============================================================================
00003 // Include files
00004 // ============================================================================
00005 // GaudiKernel
00006 // ============================================================================
00007 #include "GaudiKernel/GaudiException.h"
00008 // ============================================================================
00009 // local
00010 // ============================================================================
00011 #include "GaudiMath/NumericalDerivative.h"
00012 #include "GaudiMath/Constant.h"
00013 // ============================================================================
00014 // GSL 
00015 // ============================================================================
00016 #include "gsl/gsl_errno.h"
00017 #include "gsl/gsl_diff.h"
00018 #include "gsl/gsl_math.h"
00019 // ============================================================================
00020 // local
00021 // ============================================================================
00022 #include "Helpers.h"
00023 // ============================================================================
00024 
00025 // ============================================================================
00032 // ============================================================================
00033 
00034 namespace Genfun
00035 {
00036   namespace GaudiMathImplementation
00037   {
00038     // ========================================================================
00040     // ========================================================================
00041     FUNCTION_OBJECT_IMP( NumericalDerivative )
00042     // ========================================================================
00043     
00044     // ========================================================================
00051     // ========================================================================
00052     NumericalDerivative::NumericalDerivative
00053     ( const AbsFunction&               function , 
00054       const size_t                     index    , 
00055       const NumericalDerivative::Type& type     )
00056       : AbsFunction () 
00057       , m_function  ( function.clone()          )  
00058       , m_index     ( index                     ) 
00059       , m_DIM       ( function.dimensionality() )
00060       , m_type      ( type                      )
00061       , m_argument  ( function.dimensionality() )
00062       , m_result    ( GSL_NEGINF                )
00063       , m_error     ( GSL_POSINF                )
00064     {
00065       if( m_index >= m_DIM ) 
00066         { Exception ( "::constructor invalid variable index " ) ; };
00067     }
00068     // ========================================================================
00069     
00070     // ========================================================================
00072     // ========================================================================
00073     NumericalDerivative::NumericalDerivative 
00074     ( const NumericalDerivative&   right    ) 
00075       : AbsFunction () 
00076       , m_function  ( right.m_function->clone() )  
00077       , m_index     ( right.m_index             ) 
00078       , m_DIM       ( right.m_DIM               )
00079       , m_type      ( right.m_type              ) 
00080       , m_argument  ( right.m_DIM               )
00081       , m_result    ( GSL_NEGINF                )
00082       , m_error     ( GSL_POSINF                )
00083     {}
00084     // ========================================================================
00085     
00086     // ========================================================================
00088     // ========================================================================
00089     NumericalDerivative::~NumericalDerivative()
00090     { if( 0 != m_function ) { delete m_function ; m_function = 0 ; } }
00091     // ========================================================================
00092     
00093     // ========================================================================
00095     // ========================================================================
00096     const NumericalDerivative::Type&
00097     NumericalDerivative::setType  ( const NumericalDerivative::Type& value ) 
00098     { m_type = value ; return type() ; }
00099     // ========================================================================
00100     
00101     // ========================================================================
00103     // ========================================================================
00104     Genfun::Derivative NumericalDerivative::partial( unsigned int idx ) const 
00105     {
00106       if( idx >= m_DIM ) 
00107         { Exception ( "::partial(i): invalid variable index" ) ; }
00108       const  AbsFunction& aux = 
00109         NumericalDerivative( *this , idx , type() ) ;
00110       return FunctionNoop( &aux ) ;
00111     }
00112     // ========================================================================
00113     
00114     // ========================================================================
00116     // ========================================================================
00117     double NumericalDerivative::operator() 
00118       ( const Argument& argument ) const
00119     {
00120       // reset the result and the error  
00121       m_result = GSL_NEGINF ;
00122       m_error  = GSL_POSINF ;
00123       
00124       // check the argument 
00125       if( argument.dimension() != m_DIM ) 
00126         { Exception ( "::operator():invalid argument size" ) ; };
00127       
00129       {for( size_t i  = 0 ; i < m_DIM ; ++i ){ m_argument[i] = argument[i];}}
00130       
00131       // create the helper object 
00132       GSL_Helper helper( *m_function , m_argument , m_index );
00133       
00135       gsl_function F ;
00136       F.function = &GSL_Adaptor ;
00137       F.params   = &helper                 ;
00138       
00139       double x       = argument[m_index];
00140       int    ierrno  = 0                   ;
00141       switch ( type() ) 
00142         {
00143         case Central  : 
00144           ierrno = gsl_diff_central  ( &F , x , &m_result , &m_error ) ; break ;
00145         case Forward  : 
00146           ierrno = gsl_diff_forward  ( &F , x , &m_result , &m_error ) ; break ;
00147         case Backward :
00148           ierrno = gsl_diff_backward ( &F , x , &m_result , &m_error ) ; break ;
00149         default:
00150           Exception ( "::operator(): invalid diffrentiation type " ) ;          
00151         }
00152       
00153       if( ierrno ) 
00154         { gsl_error ( " NumericalDerivative:: the error from gsl_diff_XXXX" ,
00155                       __FILE__ , __LINE__ , ierrno ) ; }
00156       
00157       return result() ;
00158     }
00159     // ========================================================================
00160     
00161     // ========================================================================
00163     // ========================================================================
00164     double NumericalDerivative::operator() ( const double  argument ) const
00165     {
00166       // reset the result and the error  
00167       m_result = GSL_NEGINF ;
00168       m_error  = GSL_POSINF ;
00169       
00170       // check the argument 
00171       if( 1 != m_DIM ) { Exception ( "operator(): invalid argument size " ); }
00172 
00173       Argument arg(1) ;
00174       arg[0] = argument ;
00175       return (*this)( arg ) ;
00176     }
00177     // ========================================================================
00178     
00179     // ========================================================================
00181     // ========================================================================
00182     StatusCode NumericalDerivative::Exception 
00183     ( const std::string& message ,  
00184       const StatusCode&  sc      ) const 
00185     {
00186       throw GaudiException( "NumericalDerivative" + message , 
00187                             "*GaudiMath*"         , sc      ) ;
00188       return sc ;
00189     }
00190     // ========================================================================
00191     
00192  
00193   } // end of namespace GaudiMathImplementation 
00194 
00195 } // end of namespace Genfun (due to GSL) 
00196  
00197 // ============================================================================
00198 // The END 
00199 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 9 16:24:49 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004