Introduction
============

This chapter describes functions for performing interpolation. All the interpolation methods conform to a model which tries to factor out the various subtasks for creation, lookup and evaluation. The state of an interpolation object is stored in a gsl_interp_obj; these are created by special purpose factories, one for each interpolation method. State for searches is stored in a gsl_interp_accel, which is a kind of iterator for interpolation lookups.

The interpolation library provides five interpolation object factories:

gsl_interp_factory_linear   linear interpolation
gsl_interp_factory_cspline_natural   cubic spline with natural BC
gsl_interp_factory_cspline_periodic   cubic spline with periodic BC
gsl_interp_factory_akima_natural   Akima spline with natural BC
gsl_interp_factory_akima_periodic   Akima spline with periodic BC

The interpolation object (gsl_interp_obj) does not copy the data arrays but stores all static state computed from the data. The "x" data array is always assumed to be strictly ordered; the behaviour for other arrangements is not defined.

Functions
=========

 -- Function: gsl_interp_accel * gsl_interp_accel_new (void)
     Create an accelerator object, which is a kind of iterator for interpolation lookups. It tracks the state of lookups, thus allowing for application of various acceleration strategies.

 -- Function: size_t gsl_interp_accel_find (gsl_interp_accel * A, const double x_array[], size_t SIZE, double X)
     Perform a lookup action on a data array, using the given accelerator. This is how lookups are performed during evaluation of an interpolation. Returns an index such that xarray[index] <= x < xarray[index+1].

 -- Function: int gsl_interp_eval_impl (const gsl_interp_obj * OBJ, const double xa[], const double ya[], double X, gsl_interp_accel * A, double * Y)
 -- Function: int gsl_interp_eval_e (const gsl_interp_obj * OBJ, const double xa[], const double ya[], double X, gsl_interp_accel * A, double * Y)
 -- Function: double gsl_interp_eval (const gsl_interp_obj * OBJ, const double xa[], const double ya[], double X, gsl_interp_accel * A)
     Evaluate an interpolation at a given point, doing lookup with the given accelerator state.

 -- Function: int gsl_interp_eval_deriv_impl (const gsl_interp_obj * OBJ, const double xa[], const double ya[], double X, gsl_interp_accel * A, double * Y)
 -- Function: int gsl_interp_eval_deriv_e (const gsl_interp_obj * OBJ, const double xa[], const double ya[], double X, gsl_interp_accel * A, double * Y)
 -- Function: double gsl_interp_eval_deriv (const gsl_interp_obj * OBJ, const double xa[], const double ya[], double X, gsl_interp_accel * A)
     Evaluate the derivative of an interpolation at a given point.

 -- Function: void gsl_interp_obj_free (gsl_interp_obj * INTERP_OBJ)
     Free an interpolation object.

 -- Function: void gsl_interp_accel_free (gsl_interp_accel* A)
     Free an accelerator object.

Examples
========

Creating and Using a Linear Interpolation
-----------------------------------------

The steps are to obtain a factory reference, create an interpolation object from given data, create an accelerator object (iterator), use the interpolation object and accelerator, and finally free resources.

       double x[64];
       double y[64];
       double x0;
       double y0;
       ...
       gsl_interp_factory f = gsl_interp_factory_linear;
       gsl_interp_obj * interp = f.create(x, y, 64);
       gsl_interp_accel * a = gsl_interp_accel_new ();
       ...
       x0 = 5.7;
       gsl_interp_eval_impl(interp, x, y, x0, a, &y0);
       ...
       gsl_interp_accel_free (a);
       gsl_interp_obj_free (interp);

Creating and Using Other Interpolations
---------------------------------------

To change the above code to use, say cubic splines with periodic boundary conditions, the only statement that would be changed is the one which obtains the reference to the factory. We would do

       ...
       /* gsl_interp_factory f = gsl_interp_factory_linear; */
       gsl_interp_factory f = gsl_interp_factory_cspline_periodic
       ...

With this design, the interplation method can be changed dynamically, at runtime if desired, since the main block of code is unchanging and will work with any valid factory reference.