Function diff

Calculate the derivative of a function.

Result!real diff(Func) (
  scope Func f,
  real x,
  real scale = 1.00000,
  size_t tableauSize = 10
);

This function uses Ridders' method of extrapolating the results of finite difference formulas for consecutively smaller step sizes, with an improved stopping criterion described in the Numerical Recipes books by Press et al.

This method gives a much higher degree of accuracy in the answer compared to a single finite difference calculation, but requires more function evaluations; typically 6 to 12. The maximum number of function evaluations is 2*tableauSize.

Parameters

NameDescription
f The function of which to take the derivative.
x The point at which to take the derivative.
scale A "characteristic scale" over which the function changes. (optional)
tableauSize The values of the consecutive approximations are stored in a tableauSize-by-tableauSize triangular matrix. Sometimes this number can be reduced to limit the possible number of function evaluations (see above) and thus greater speed, and sometimes it can be increased to allow for higher accuracy. (optional)

Example

This example is from Ridders' paper:

// Let's take the derivative of
//                 x
//                e
//     f(x) = ----------
//                     2
//            sin x - x
// at x=1.
real f(real x) { return exp(x)/(sin(x)-x*x); }
real dfdxAt1 = 140.73773557129660339;

// scale=0.01 is appropriate for this function.
auto r = diff(&f, 1.0, 0.01);
assert (abs(r.value - dfdxAt1) <= r.error);

// Note that if we use the default scale, it won't work:
auto s = diff(&f, 1.0);
writeln(s.error);           // prints "inf"

References