```// @(#)root/mathcore:\$Id\$
// Authors: David Gonzalez Maline    01/2008

/**********************************************************************
*                                                                    *
* Copyright (c) 2006 , LCG ROOT MathLib Team                         *
*                                                                    *
*                                                                    *
**********************************************************************/

// Header file for RichardsonDerivator
//
// Created by: David Gonzalez Maline  : Mon Feb 4 2008
//

#ifndef ROOT_Math_RichardsonDerivator
#define ROOT_Math_RichardsonDerivator

#include <Math/IFunction.h>

namespace ROOT {
namespace Math {

//___________________________________________________________________________________________
/**
User class for calculating the derivatives of a function. It can calculate first (method Derivative1),
second (method Derivative2) and third (method Derivative3) of a function.

It uses the Richardson extrapolation method for function derivation in a given interval.
The method use 2 derivative estimates (one computed with step h and one computed with step h/2)
to compute a third, more accurate estimation. It is equivalent to the
<a href = http://en.wikipedia.org/wiki/Five-point_stencil>5-point method</a>,
which can be obtained with a Taylor expansion.
A step size should be given, depending on x and f(x).
An optimal step size value minimizes the truncation error of the expansion and the rounding
error in evaluating x+h and f(x+h). A too small h will yield a too large rounding error while a too large
h will give a large truncation error in the derivative approximation.
A good discussion can be found in discussed in
<a href=http://www.nrbook.com/a/bookcpdf/c5-7.pdf>Chapter 5.7</a>  of Numerical Recipes in C.
By default a value of 0.001 is uses, acceptable in many cases.

This class is implemented using code previosuly in  TF1::Derivate{,2,3}(). Now TF1 uses this class.

@ingroup Deriv

*/

class RichardsonDerivator {
public:

/** Destructor: Removes function if needed. */
~RichardsonDerivator();

/** Default Constructor.
Give optionally the step size for derivation. By default is 0.001, which is fine for x ~ 1
Increase if x is in averga larger or decrease if x is smaller
*/
RichardsonDerivator(double h = 0.001);

/** Construct from function and step size
*/
RichardsonDerivator(const ROOT::Math::IGenFunction & f, double h = 0.001, bool copyFunc = false);

/**
Copy constructor
*/
RichardsonDerivator(const RichardsonDerivator & rhs);

/**
Assignment operator
*/
RichardsonDerivator & operator= ( const RichardsonDerivator & rhs);

/** Returns the estimate of the absolute Error of the last derivative calculation. */
double Error () const {  return fLastError; }

/**
Returns the first derivative of the function at point x,
computed by Richardson's extrapolation method (use 2 derivative estimates
to compute a third, more accurate estimation)
first, derivatives with steps h and h/2 are computed by central difference formulas
Begin_Latex
D(h) = #frac{f(x+h) - f(x-h)}{2h}
End_Latex
the final estimate Begin_Latex D = #frac{4D(h/2) - D(h)}{3} End_Latex
"Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"

the argument eps may be specified to control the step size (precision).
the step size is taken as eps*(xmax-xmin).
the default value (0.001) should be good enough for the vast majority
of functions. Give a smaller value if your function has many changes
of the second derivative in the function range.

Getting the error via TF1::DerivativeError:
(total error = roundoff error + interpolation error)
the estimate of the roundoff error is taken as follows:
Begin_Latex
err = k#sqrt{f(x)^{2} + x^{2}deriv^{2}}#sqrt{#sum ai^{2}},
End_Latex
where k is the double precision, ai are coefficients used in
central difference formulas
interpolation error is decreased by making the step size h smaller.
*/
double Derivative1 (double x);
double operator() (double x) { return Derivative1(x); }

/**
First Derivative calculation passing function and step-size
*/
double Derivative1(const IGenFunction & f, double x, double h) {
fFunction = &f;
fStepSize = h;
return Derivative1(x);
}

/**
Returns the second derivative of the function at point x,
computed by Richardson's extrapolation method (use 2 derivative estimates
to compute a third, more accurate estimation)
first, derivatives with steps h and h/2 are computed by central difference formulas
Begin_Latex
D(h) = #frac{f(x+h) - 2f(x) + f(x-h)}{h^{2}}
End_Latex
the final estimate Begin_Latex D = #frac{4D(h/2) - D(h)}{3} End_Latex
"Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"

the argument eps may be specified to control the step size (precision).
the step size is taken as eps*(xmax-xmin).
the default value (0.001) should be good enough for the vast majority
of functions. Give a smaller value if your function has many changes
of the second derivative in the function range.

Getting the error via TF1::DerivativeError:
(total error = roundoff error + interpolation error)
the estimate of the roundoff error is taken as follows:
Begin_Latex
err = k#sqrt{f(x)^{2} + x^{2}deriv^{2}}#sqrt{#sum ai^{2}},
End_Latex
where k is the double precision, ai are coefficients used in
central difference formulas
interpolation error is decreased by making the step size h smaller.
*/
double Derivative2 (double x);

/**
Second Derivative calculation passing function and step-size
*/
double Derivative2(const IGenFunction & f, double x, double h) {
fFunction = &f;
fStepSize = h;
return Derivative2(x);
}

/**
Returns the third derivative of the function at point x,
computed by Richardson's extrapolation method (use 2 derivative estimates
to compute a third, more accurate estimation)
first, derivatives with steps h and h/2 are computed by central difference formulas
Begin_Latex
D(h) = #frac{f(x+2h) - 2f(x+h) + 2f(x-h) - f(x-2h)}{2h^{3}}
End_Latex
the final estimate Begin_Latex D = #frac{4D(h/2) - D(h)}{3} End_Latex
"Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"

the argument eps may be specified to control the step size (precision).
the step size is taken as eps*(xmax-xmin).
the default value (0.001) should be good enough for the vast majority
of functions. Give a smaller value if your function has many changes
of the second derivative in the function range.

Getting the error via TF1::DerivativeError:
(total error = roundoff error + interpolation error)
the estimate of the roundoff error is taken as follows:
Begin_Latex
err = k#sqrt{f(x)^{2} + x^{2}deriv^{2}}#sqrt{#sum ai^{2}},
End_Latex
where k is the double precision, ai are coefficients used in
central difference formulas
interpolation error is decreased by making the step size h smaller.
*/
double Derivative3 (double x);

/**
Third Derivative calculation passing function and step-size
*/
double Derivative3(const IGenFunction & f, double x, double h) {
fFunction = &f;
fStepSize = h;
return Derivative3(x);
}

/** Set function for derivative calculation (copy the function if option has been enabled in the constructor)

\@param f Function to be differentiated
*/
void SetFunction (const IGenFunction & f);

/** Set step size for derivative calculation

\@param h step size for calculation
*/
void SetStepSize (double h) { fStepSize = h; }

protected:

bool fFunctionCopied;     // flag to control if function is copied in the class
double fStepSize;         // step size used for derivative calculation
double fLastError;        //  error estimate of last derivative calculation
const IGenFunction* fFunction;  // pointer to function

};

} // end namespace Math

} // end namespace ROOT

#endif /* ROOT_Math_RichardsonDerivator */

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