This chapter describes functions for the computation of smoothing basis splines (B-splines). The header file gsl_bspline.h contains prototypes for the bspline functions and related declarations.

Overview
========

B-splines are commonly used as basis functions to fit smoothing curves to large data sets. To do this, the abscissa axis is broken up into some number of intervals, where the endpoints of each interval are called breakpoints. These breakpoints are then converted to knots by imposing various continuity and smoothness conditions at each interface. Given a nondecreasing knot vector t = \t_0, t_1, \dots, t_n+k-1\, the n basis splines of order k are defined by

     B_(i,1)(x) = (1, t_i <= x < t_(i+1)
                  (0, else
     B_(i,k)(x) = [(x - t_i)/(t_(i+k-1) - t_i)] B_(i,k-1)(x) + [(t_(i+k) - x)/(t_(i+k) - t_(i+1))] B_(i+1,k-1)(x)

for i = 0, \dots, n-1. The common case of cubic B-splines is given by k = 4. The above recurrence relation can be evaluated in a numerically stable way by the de Boor algorithm.

If we define appropriate knots on an interval [a,b] then the B-spline basis functions form a complete set on that interval. Therefore we can expand a smoothing function as

     f(x) = \sum_i c_i B_(i,k)(x)

given enough (x_j, f(x_j)) data pairs. The c_i can be readily obtained from a least-squares fit.

Initializing the B-splines solver
=================================

 -- Function: gsl_bspline_workspace * gsl_bspline_alloc (const size_t K, const size_t NBREAK)
     This function allocates a workspace for computing B-splines of order K. The number of breakpoints is given by NBREAK. This leads to n = nbreak + k - 2 basis functions. Cubic B-splines are specified by k = 4. The size of the workspace is O(5k + nbreak).

 -- Function: void gsl_bspline_free (gsl_bspline_workspace * W)
     This function frees the memory associated with the workspace W.

Constructing the knots vector
=============================

 -- Function: int gsl_bspline_knots (const gsl_vector * BREAKPTS, gsl_bspline_workspace * W)
     This function computes the knots associated with the given breakpoints and stores them internally in w->knots.

 -- Function: int gsl_bspline_knots_uniform (const double a, const double b, gsl_bspline_workspace * W)
     This function assumes uniformly spaced breakpoints on [a,b] and constructs the corresponding knot vector using the previously specified NBREAK parameter. The knots are stored in w->knots.

Evaluation of B-splines
=======================

 -- Function: int gsl_bspline_eval (const double X, gsl_vector * B, gsl_bspline_workspace * W)
     This function evaluates all B-spline basis functions at the position X and stores them in B, so that the ith element of B is B_i(x). B must be of length n = nbreak + k - 2. This value is also stored in w->n. It is far more efficient to compute all of the basis functions at once than to compute them individually, due to the nature of the defining recurrence relation.

Example programs for B-splines
==============================

The following program computes a linear least squares fit to data using cubic B-spline basis functions with uniform breakpoints. The data is generated from the curve y(x) = \cos(x) \exp(-0.1 x) on [0, 15] with gaussian noise added.

          [file bspline.c not included]

The output can be plotted with GNU graph.

     $ ./a.out > bspline.dat
     $ graph -T ps -X x -Y y -x 0 15 -y -1 1.3 < bspline.dat > bspline.ps

References and Further Reading
==============================

Further information on the algorithms described in this section can be found in the following book,

     C. de Boor, A Practical Guide to Splines (1978), Springer-Verlag, ISBN 0-387-90356-9.

A large collection of B-spline routines is available in the PPPACK library available at http://www.netlib.org/pppack.