Providing the function to solve - GNU Scientific Library -- Reference Manual
Description: GNU Scientific Library -- Reference Manual

Next: Search Bounds and Guesses, Previous: Initializing the Solver, Up: One dimensional Root-Finding

### 33.4 Providing the function to solve

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:

— Data Type: gsl_function

> 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 = &params;

The function f(x) can be evaluated using the following macro,

         #define GSL_FN_EVAL(F,x)
             (*((F)->function))(x,(F)->params)

— Data Type: gsl_function_fdf

> 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`.

The GNU Scientific Library - a free numerical library licensed under the GNU GPL
Back to the GNU Scientific Library Homepage