Class deriv_gsl (o2scl)

O2scl : Class List

template<class func_t = funct, class fp_t = double>
class deriv_gsl : public o2scl::deriv_base<funct, double>

Numerical differentiation (GSL)

This class computes the numerical derivative of a function. The stepsize h should be specified before use. If similar functions are being differentiated in succession, the user may be able to increase the speed of later derivatives by setting the new stepsize equal to the optimized stepsize from the previous differentiation, by setting h to h_opt.

The results will be incorrect for sufficiently difficult functions or if the step size is not properly chosen.

Some successive derivative computations can be made more efficient by using the optimized stepsize in deriv_gsl::h_opt , which is set by the most recent last derivative computation.

If the function returns a non-finite value, or if func_max is greater than zero and the absolute value of the function is larger than func_max, then this class attempts to decrease the step size by a factor of 10 in order to compute the derivative. The class gives up after 20 reductions of the step size.

If h is negative or zero, the initial step size is chosen to be \( 10^{-4} |x| \) or if \(x=0\), then the initial step size is chosen to be \( 10^{-4} \) .

Setting deriv_base::verbose to a number greater than zero results in output for each call to central_deriv() which looks like:

deriv_gsl: 
step: 1.000000e-04
abscissas: 4.999500e-01 4.999000e-01 5.000500e-01 5.001000e-01
ordinates: 4.793377e-01 4.793816e-01 4.794694e-01 4.795132e-01
res: 8.775825e-01 trc: 1.462163e-09 rnd: 7.361543e-12
where the last line contains the result (res), the truncation error (trc) and the rounding error (rnd). If deriv_base::verbose is greater than 1, a keypress is required after each iteration.

If the function always returns a finite value, then computing first derivatives requires either 1 or 2 calls to central_deriv() and thus either 4 or 8 function calls.

The multiprecision version uses funct_multip to ensure the function evaluations are sufficiently accurate and then ensures that the derivative evaluation is below the requested relative tolerance. If the relative tolerance is not specified, then \( 10^{-d} \) is used where \( d \) is the value reported by numeric_limits::digits10 for the input floating point type.

An example demonstrating the usage of this class is given in the Differentiation example.

Idea for Future:

Include the forward and backward GSL derivatives. These would be useful for EOS classes which run in to trouble for negative densities.

Note

Second and third derivatives are computed by naive nested applications of the formula for the first derivative. No uncertainty for these derivatives is provided.

Note

Derivatives near zero can be particularly troublesome, even for simple functions, since this class only uses relative tolerances.

Public Functions

inline deriv_gsl()
inline virtual ~deriv_gsl()
inline deriv_gsl(const deriv_gsl &f)

Copy constructor.

inline deriv_gsl &operator=(const deriv_gsl &f)

Copy construction with operator=()

inline virtual int deriv_err(fp_t x, func_t &func, fp_t &dfdx, fp_t &err)

Calculate the first derivative of func w.r.t. x and uncertainty.

template<typename func2_t, class fp2_t>
inline int deriv_err_multip(fp2_t x, func2_t &&f, fp2_t &dfdx, fp2_t &err, double tol_loc = -1.0)

Calculate the first derivative of func w.r.t. x and uncertainty (adaptive multiprecision)

inline virtual const char *type()

Return string denoting type (“deriv_gsl”)

Public Members

fp_t h

Initial stepsize.

This should be specified before a call to deriv() or deriv_err(). If it is less than or equal to zero, then \( x 10^{-4} \) will used, or if x is zero, then \( 10^{-4} \) will be used.

This quantity is not currently used for the adaptive
multiprecision derivatives.

fp_t func_max

Maximum absolute value of function, or a negative value for no maximum (default -1)

fp_t h_opt

The last value of the optimized stepsize.

This is initialized to zero in the constructor and set by deriv_err() to the most recent value of the optimized stepsize.

This optimal stepsize is not modified for the adaptive
multiprecision derivatives.

double pow_tol_func

Power for tolerance of function evaluations with adaptive multiprecision (default 1.33)

Protected Functions

template<typename func2_t, class fp2_t>
inline int deriv_err_int_multip(func2_t &&f, fp2_t x, fp2_t &dfdx, fp2_t &err, double tol, double hh = 0.0)

Calculate the derivative of f w.r.t. x (internal multiprecision version)

The error estimate is placed in err, the desired tolerance should be specified in tol and the initial step size in hh.

template<typename func2_t, class fp2_t>
inline int central_deriv_multip(func2_t &&func, fp2_t x, double hh, fp2_t &result, fp2_t &abserr_round, fp2_t &abserr_trunc, double func_tol)

Compute derivative using 5-point rule (multiprecision version)

Compute the derivative using the 5-point rule (x-h, x-h/2, x, x+h/2, x+h) and the error using the difference between the 5-point and the 3-point rule (x-h,x,x+h). Note that the central point is not used for either.

The value \c func_tol is the error tolerance for the
function evaluations.

template<class func2_t>
inline int deriv_tlate(fp_t x, func2_t &func, fp_t &dfdx, fp_t &err)

Calculate the derivative of func w.r.t. x (internal version)

inline virtual int deriv_err_int(fp_t x, typename deriv_base<func_t, fp_t>::internal_func_t &func, fp_t &dfdx, fp_t &err)

Internal version of deriv_err() for second and third derivatives.

template<class func2_t>
inline int central_deriv(fp_t x, fp_t hh, fp_t &result, fp_t &abserr_round, fp_t &abserr_trunc, func2_t &func)

Compute derivative using 5-point rule.

Compute the derivative using the 5-point rule (x-h, x-h/2, x, x+h/2, x+h) and the error using the difference between the 5-point and the 3-point rule (x-h,x,x+h). Note that the central point is not used for either.