// @(#)root/mathmore:$Id$
// Authors: L. Moneta, A. Zsenei   08/2005

 /**********************************************************************
  *                                                                    *
  * Copyright (c) 2004 ROOT Foundation,  CERN/PH-SFT                   *
  *                                                                    *
  * This library is free software; you can redistribute it and/or      *
  * modify it under the terms of the GNU General Public License        *
  * as published by the Free Software Foundation; either version 2     *
  * of the License, or (at your option) any later version.             *
  *                                                                    *
  * This library is distributed in the hope that it will be useful,    *
  * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
  * General Public License for more details.                           *
  *                                                                    *
  * You should have received a copy of the GNU General Public License  *
  * along with this library (see file COPYING); if not, write          *
  * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
  * 330, Boston, MA 02111-1307 USA, or contact the author.             *
  *                                                                    *
  **********************************************************************/

// Header file for class Derivator
//
// class for calculating Derivative of functions
//
// Created by: moneta  at Sat Nov 13 14:46:00 2004
//
// Last update: Sat Nov 13 14:46:00 2004
//
#ifndef ROOT_Math_Derivator
#define ROOT_Math_Derivator

/**
    @defgroup Deriv Numerical Differentiation
    @ingroup NumAlgo
*/

#ifndef ROOT_Math_IFunctionfwd
#include "Math/IFunctionfwd.h"
#endif

#ifndef ROOT_Math_IParamFunctionfwd
#include "Math/IParamFunctionfwd.h"
#endif


namespace ROOT {
namespace Math {



class GSLDerivator;

//_______________________________________________________________________
/**
    Class for computing numerical derivative of a function.
    Presently this class is implemented only using the numerical derivatives
    algorithms provided by GSL
    using the implementation class ROOT::Math::GSLDerivator

    This class does not support copying

    @ingroup Deriv
*/

class Derivator {

public:

   /**
      signature for function pointers used by GSL
   */
   typedef double ( * GSLFuncPointer ) ( double, void * );

   /**
      Empty Construct for a Derivator class
      Need to set the function afterwards with Derivator::SetFunction
   */
   Derivator();
   /**
      Construct using a ROOT::Math::IGenFunction interface
    */
   explicit Derivator(const IGenFunction &f);
   /**
      Construct using a GSL function pointer type
       @param f :  free function pointer of the GSL required type
       @param p :  pointer to the object carrying the function state
                    (for example the function object itself)
    */
   explicit Derivator(const GSLFuncPointer &f, void * p = 0);

   /// destructor
   virtual ~Derivator();

   // disable copying
private:

   Derivator(const Derivator &);
   Derivator & operator = (const Derivator &);

public:


#ifdef LATER
   /**
       Template methods for generic functions
       Set the function f for evaluating the derivative.
       The function type must implement the assigment operator,
       <em>  double  operator() (  double  x ) </em>
   */
   template <class UserFunc>
   inline void SetFunction(const UserFunc &f) {
      const void * p = &f;
      SetFunction(  &GSLFunctionAdapter<UserFunc>::F, const_cast<void *>(p) );
   }
#endif

   /**
      Set the function for calculating the derivatives.
      The function must implement the ROOT::Math::IGenFunction signature
   */
   void SetFunction(const IGenFunction &f);


   /**
       Set the function f for evaluating the derivative using a GSL function pointer type
       @param f :  free function pointer of the GSL required type
       @param p :  pointer to the object carrying the function state
                    (for example the function object itself)
   */
   void SetFunction( const GSLFuncPointer &f, void * p = 0);



   /**
       Computes the numerical derivative of a function f at a point x.
       It uses Derivator::EvalCentral to compute the derivative using an
       adaptive central difference algorithm with a step size h
   */

   double Eval(double x, double h = 1E-8) const;



   /**
       Computes the numerical derivative at a point x using an adaptive central
       difference algorithm with a step size h.
   */
   double EvalCentral( double x, double h = 1E-8) const;

   /**
       Computes the numerical derivative at a point x using an adaptive forward
       difference algorithm with a step size h.
       The function is evaluated only at points greater than x and at x itself.
   */
   double EvalForward( double x, double h = 1E-8) const;

   /**
       Computes the numerical derivative at a point x using an adaptive backward
       difference algorithm with a step size h.
       The function is evaluated only at points less than x and at x itself.
   */
   double EvalBackward( double x, double h = 1E-8) const;

   /** @name --- Static methods ---
       This methods don't require to use a Derivator object, and are designed to be used in
       fast calculation. Error and status code cannot be retrieved in this case
    */

   /**
       Computes the numerical derivative of a function f at a point x.
       It uses Derivator::EvalCentral to compute the derivative using an
       adaptive central difference algorithm with a step size h
   */
   static double Eval(const IGenFunction & f, double x, double h = 1E-8);

   /**
       Computes the numerical derivative of a function f at a point x using an adaptive central
       difference algorithm with a step size h
   */
   static double EvalCentral(const IGenFunction & f, double x, double h = 1E-8);


   /**
       Computes the numerical derivative of a function f at a point x using an adaptive forward
       difference algorithm with a step size h.
       The function is evaluated only at points greater than x and at x itself
   */
   static double EvalForward(const IGenFunction & f, double x, double h = 1E-8);

   /**
       Computes the numerical derivative of a function f at a point x using an adaptive backward
       difference algorithm with a step size h.
       The function is evaluated only at points less than x and at x itself
   */
   static double EvalBackward(const IGenFunction & f, double x, double h = 1E-8);

   // Derivatives for multi-dimension functions
   /**
      Evaluate the partial derivative of a multi-dim function
      with respect coordinate x_icoord at the point x[]
    */
   static double Eval(const IMultiGenFunction & f, const double * x, unsigned int icoord = 0, double h = 1E-8);

   /**
      Evaluate the derivative with respect a parameter for one-dim parameteric function
      at the point ( x,p[]) with respect the parameter p_ipar
    */
   static double Eval(IParamFunction & f, double x, const double * p, unsigned int ipar = 0, double h = 1E-8);

   /**
      Evaluate the derivative with respect a parameter for a multi-dim parameteric function
      at the point ( x[],p[]) with respect the parameter p_ipar
    */
   static double Eval(IParamMultiFunction & f, const double * x, const double * p, unsigned int ipar = 0, double h = 1E-8);


   /**
      return the error status of the last derivative calculation
   */
   int Status() const;

   /**
      return  the result of the last derivative calculation
   */
   double Result() const;

   /**
      return the estimate of the absolute error of the last derivative calculation
   */
   double Error() const;


private:


   mutable GSLDerivator * fDerivator;

};




} // namespace Math
} // namespace ROOT


#endif /* ROOT_Math_Derivator */
 Derivator.h:1
 Derivator.h:2
 Derivator.h:3
 Derivator.h:4
 Derivator.h:5
 Derivator.h:6
 Derivator.h:7
 Derivator.h:8
 Derivator.h:9
 Derivator.h:10
 Derivator.h:11
 Derivator.h:12
 Derivator.h:13
 Derivator.h:14
 Derivator.h:15
 Derivator.h:16
 Derivator.h:17
 Derivator.h:18
 Derivator.h:19
 Derivator.h:20
 Derivator.h:21
 Derivator.h:22
 Derivator.h:23
 Derivator.h:24
 Derivator.h:25
 Derivator.h:26
 Derivator.h:27
 Derivator.h:28
 Derivator.h:29
 Derivator.h:30
 Derivator.h:31
 Derivator.h:32
 Derivator.h:33
 Derivator.h:34
 Derivator.h:35
 Derivator.h:36
 Derivator.h:37
 Derivator.h:38
 Derivator.h:39
 Derivator.h:40
 Derivator.h:41
 Derivator.h:42
 Derivator.h:43
 Derivator.h:44
 Derivator.h:45
 Derivator.h:46
 Derivator.h:47
 Derivator.h:48
 Derivator.h:49
 Derivator.h:50
 Derivator.h:51
 Derivator.h:52
 Derivator.h:53
 Derivator.h:54
 Derivator.h:55
 Derivator.h:56
 Derivator.h:57
 Derivator.h:58
 Derivator.h:59
 Derivator.h:60
 Derivator.h:61
 Derivator.h:62
 Derivator.h:63
 Derivator.h:64
 Derivator.h:65
 Derivator.h:66
 Derivator.h:67
 Derivator.h:68
 Derivator.h:69
 Derivator.h:70
 Derivator.h:71
 Derivator.h:72
 Derivator.h:73
 Derivator.h:74
 Derivator.h:75
 Derivator.h:76
 Derivator.h:77
 Derivator.h:78
 Derivator.h:79
 Derivator.h:80
 Derivator.h:81
 Derivator.h:82
 Derivator.h:83
 Derivator.h:84
 Derivator.h:85
 Derivator.h:86
 Derivator.h:87
 Derivator.h:88
 Derivator.h:89
 Derivator.h:90
 Derivator.h:91
 Derivator.h:92
 Derivator.h:93
 Derivator.h:94
 Derivator.h:95
 Derivator.h:96
 Derivator.h:97
 Derivator.h:98
 Derivator.h:99
 Derivator.h:100
 Derivator.h:101
 Derivator.h:102
 Derivator.h:103
 Derivator.h:104
 Derivator.h:105
 Derivator.h:106
 Derivator.h:107
 Derivator.h:108
 Derivator.h:109
 Derivator.h:110
 Derivator.h:111
 Derivator.h:112
 Derivator.h:113
 Derivator.h:114
 Derivator.h:115
 Derivator.h:116
 Derivator.h:117
 Derivator.h:118
 Derivator.h:119
 Derivator.h:120
 Derivator.h:121
 Derivator.h:122
 Derivator.h:123
 Derivator.h:124
 Derivator.h:125
 Derivator.h:126
 Derivator.h:127
 Derivator.h:128
 Derivator.h:129
 Derivator.h:130
 Derivator.h:131
 Derivator.h:132
 Derivator.h:133
 Derivator.h:134
 Derivator.h:135
 Derivator.h:136
 Derivator.h:137
 Derivator.h:138
 Derivator.h:139
 Derivator.h:140
 Derivator.h:141
 Derivator.h:142
 Derivator.h:143
 Derivator.h:144
 Derivator.h:145
 Derivator.h:146
 Derivator.h:147
 Derivator.h:148
 Derivator.h:149
 Derivator.h:150
 Derivator.h:151
 Derivator.h:152
 Derivator.h:153
 Derivator.h:154
 Derivator.h:155
 Derivator.h:156
 Derivator.h:157
 Derivator.h:158
 Derivator.h:159
 Derivator.h:160
 Derivator.h:161
 Derivator.h:162
 Derivator.h:163
 Derivator.h:164
 Derivator.h:165
 Derivator.h:166
 Derivator.h:167
 Derivator.h:168
 Derivator.h:169
 Derivator.h:170
 Derivator.h:171
 Derivator.h:172
 Derivator.h:173
 Derivator.h:174
 Derivator.h:175
 Derivator.h:176
 Derivator.h:177
 Derivator.h:178
 Derivator.h:179
 Derivator.h:180
 Derivator.h:181
 Derivator.h:182
 Derivator.h:183
 Derivator.h:184
 Derivator.h:185
 Derivator.h:186
 Derivator.h:187
 Derivator.h:188
 Derivator.h:189
 Derivator.h:190
 Derivator.h:191
 Derivator.h:192
 Derivator.h:193
 Derivator.h:194
 Derivator.h:195
 Derivator.h:196
 Derivator.h:197
 Derivator.h:198
 Derivator.h:199
 Derivator.h:200
 Derivator.h:201
 Derivator.h:202
 Derivator.h:203
 Derivator.h:204
 Derivator.h:205
 Derivator.h:206
 Derivator.h:207
 Derivator.h:208
 Derivator.h:209
 Derivator.h:210
 Derivator.h:211
 Derivator.h:212
 Derivator.h:213
 Derivator.h:214
 Derivator.h:215
 Derivator.h:216
 Derivator.h:217
 Derivator.h:218
 Derivator.h:219
 Derivator.h:220
 Derivator.h:221
 Derivator.h:222
 Derivator.h:223
 Derivator.h:224
 Derivator.h:225
 Derivator.h:226
 Derivator.h:227
 Derivator.h:228
 Derivator.h:229
 Derivator.h:230
 Derivator.h:231
 Derivator.h:232
 Derivator.h:233
 Derivator.h:234
 Derivator.h:235
 Derivator.h:236
 Derivator.h:237
 Derivator.h:238
 Derivator.h:239
 Derivator.h:240
 Derivator.h:241
 Derivator.h:242
 Derivator.h:243
 Derivator.h:244
 Derivator.h:245
 Derivator.h:246
 Derivator.h:247
 Derivator.h:248
 Derivator.h:249
 Derivator.h:250
 Derivator.h:251