Next: Search Bounds and Guesses, Previous: Initializing the Solver, Up: One dimensional Root-Finding
You must provide a continuous function of one variable for the root finders to operate on, and, sometimes, its first derivative. In order to allow for general parameters the functions are defined by the following data types:
This data type defines a general function with parameters.
double (* function) (double
x, void *
params)
- this function should return the value f(x,params) for argument x and parameters params
void * params
- a pointer to the parameters of the function
Here is an example for the general quadratic function,
f(x) = a x^2 + b x + c
with a = 3, b = 2, c = 1. The following code
defines a gsl_function
F
which you could pass to a root
finder:
struct my_f_params { double a; double b; double c; }; double my_f (double x, void * p) { struct my_f_params * params = (struct my_f_params *)p; double a = (params->a); double b = (params->b); double c = (params->c); return (a * x + b) * x + c; } gsl_function F; struct my_f_params params = { 3.0, 2.0, 1.0 }; F.function = &my_f; F.params = ¶ms;
The function f(x) can be evaluated using the following macro,
#define GSL_FN_EVAL(F,x) (*((F)->function))(x,(F)->params)
This data type defines a general function with parameters and its first derivative.
double (* f) (double
x, void *
params)
- this function should return the value of f(x,params) for argument x and parameters params
double (* df) (double
x, void *
params)
- this function should return the value of the derivative of f with respect to x, f'(x,params), for argument x and parameters params
void (* fdf) (double
x, void *
params, double *
f, double *
df)
- this function should set the values of the function f to f(x,params) and its derivative df to f'(x,params) for argument x and parameters params. This function provides an optimization of the separate functions for f(x) and f'(x)—it is always faster to compute the function and its derivative at the same time.
void * params
- a pointer to the parameters of the function
Here is an example where f(x) = 2\exp(2x):
double my_f (double x, void * params) { return exp (2 * x); } double my_df (double x, void * params) { return 2 * exp (2 * x); } void my_fdf (double x, void * params, double * f, double * df) { double t = exp (2 * x); *f = t; *df = 2 * t; /* uses existing value */ } gsl_function_fdf FDF; FDF.f = &my_f; FDF.df = &my_df; FDF.fdf = &my_fdf; FDF.params = 0;
The function f(x) can be evaluated using the following macro,
#define GSL_FN_FDF_EVAL_F(FDF,x) (*((FDF)->f))(x,(FDF)->params)
The derivative f'(x) can be evaluated using the following macro,
#define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params)
and both the function y = f(x) and its derivative dy = f'(x) can be evaluated at the same time using the following macro,
#define GSL_FN_FDF_EVAL_F_DF(FDF,x,y,dy) (*((FDF)->fdf))(x,(FDF)->params,(y),(dy))
The macro stores f(x) in its y argument and f'(x) in
its dy argument—both of these should be pointers to
double
.