`spline`

GNU `spline`

is a program for interpolating between the data points
in one or more datasets. Each dataset would consist of values for an
independent variable and a dependent variable, which may be a vector of
specified fixed length. When discussing interpolation, we call these
variables `*t*' and `*y*', respectively. To emphasize:
*t* is a scalar, but in general the dependent variable
*y* may be a vector.

The simplest case is when there is a single input file, which is in
ASCII format, and the vector *y* is one-dimensional. This is
the default. For example, the input file could contain the dataset

0.0 0.0 1.0 1.0 2.0 0.0

which are the coordinates *(t,y)* of the data points (0,0), (1,1),
and (2,0). Data points do not need to be on different lines, nor do the
*t* and *y* coordinates of a data point need to be on the
same line. However, there should be no blank lines in the input if it
is to be viewed as forming a single dataset. Also, by default the
*t* coordinate should be monotonically increasing, so that
*y* may be viewed as a function of *t*.

You would construct a spline (the graph of an `interpolating function') passing through the points in this dataset by doing

spline input_file > output_file

To produce a Postscript plot of the spline with the `graph`

utility, you would do

spline input_file | graph -T ps > output.ps

To display a spline on an X Window System display, you could do

echo 0 0 1 1 2 0 | spline | graph -T X

Notice that the last example avoids the use of the input file
altogether. `spline`

will read from standard input if no files are
specified on the command line, or if the special file name ``-'`
is specified.

What exactly does `spline`

do? First, it fits a curve (the graph
of an interpolating function) through the points in the dataset. Then
it splits the interval over which the independent variable *t*
ranges into 100 sub-intervals, and computes the *y* values at
each of the 101 subdivision points. It then outputs each of the
pairs *(t, y)*. These are the coordinates of 101 points that lie
along a curve that interpolates between the points in the dataset. If
there is more than one dataset in the input (separated by blank lines),
each dataset is interpolated separately.

You may use the ``-n'` option to replace `100' by any other positive
integer. You may also use the ``-t'` option to specify an
interpolation interval that differs from the default (the interval over
which the independent variable ranges). For example, the command

echo 0 0 1 1 2 0 | spline -n 20 -t 1.0 1.5 > output_file

will produce a dataset consisting of 21 (rather than 101) data points,
with *t* values spaced regularly between 1.0 and 1.5 (rather
than between 0.0 and 2.0). The data points will lie along a curve
passing through (0,0), (1,1), and (2,0). This curve will be a parabola.

In general, the interpolating function will be a piecewise cubic spline.
That is, between each pair of adjacent `knots' (points in the input
dataset), *y* will be a cubic function of *t*. This
function will differ, depending on which pair of knots *y* lies
between. At each knot, both the slope and curvature of the cubic pieces
to either side will match. In mathematical terms, the interpolating
curve will be twice continuously differentiable.

`spline`

supports `adding tension' to the interpolating curve.
A nonzero value for the tension can be specified with the ``-T'`
option. For example, a spline under considerable tension can be
computed and displayed by doing

echo 0 0 1 0 2 0 | spline -T 10 | graph -T X

As the tension parameter is increased to positive infinity, the spline will converge to a polygonal line. You are meant to think of the spline as being drawn taut. Actually, tension may be negative as well as positive. A spline with negative tension will tend to bow outward, in fact to oscillate sinusoidally. But as the tension decreases to negative infinity, the spline, though oscillatory, will again converge to a polygonal line.

If the tension is positive, its reciprocal will be the maximum range of
the independent variable *t* over which the spline will `like
to curve'. Increasing the tension far above zero will accordingly force
the spline to consist of short curved sections, centered on the data
points, and sections that are almost straight. It follows that tension
is a `dimensionful' quantity. If the tension is nonzero, then when
the values of the independent variable are multiplied by some common
positive factor, the tension should be divided by the same factor to
obtain a scaled version of the original spline. If the tension is
zero (the default, or cubic spline case), then the computation of the
spline will be unaffected by linear scaling of the data.

In mathematical terms, a spline under tension will satisfy the
differential equation
@ifnottex
*y""=sgn(tension)*(tension^2)y"*
between each successive pair of knots. If the tension equals zero,
which is the default, the fourth derivative of *y* with respect
to *t* will equal zero at every point. In this case, *y*
as a function of *t* will reduce to a cubic polynomial between
each successive pair of knots. But if the tension is nonzero, *y*
will not be a polynomial function of *t*. It may be expressed
in terms of exponential functions, however.

Irrespective of whether or not the spline is under tension, you may
specify the ``-p'` option if you wish the spline to be a periodic
function of *t*. This will only work if the *y* values for
the first and last points in the dataset are equal. Otherwise, it would
make no sense to compute a periodic interpolation.

It is sometimes useful to interpolate between data points at the same
time as they are generated by an auxiliary program. That is, it
is useful for `spline`

to function as a real-time filter.
`spline`

does not normally act as a filter, since computing an
interpolating curve that is as smooth as possible is a global task. But
if the ``-f'` option is specified, `spline`

will indeed function
as a filter. A different interpolation algorithm (cubic Bessel
interpolation, which is local rather than global) will be used. If
``-f'` is specified, ``-p'` may not be specified. Also, if
``-f'` is specified then an interpolation interval (a range of
*t* values) must be requested explicitly with the ``-t'`
option.

Cubic Bessel interpolation is inherently less smooth than the
construction of a global cubic spline. If the ``-f'` option is
specified, the slope of the spline at each knot will be chosen by
fitting a parabola through that knot, and the two adjacent knots. The
slopes of the two interpolating segments to either side of each interior
knot will match at that knot, but typically their curvatures will not.
In mathematical terms, the interpolating curve will be continuously
differentiable, but in general not twice continuously differentiable.
This loss of differentiability is the price that is paid for functioning
as a real-time filter.

Go to the first, previous, next, last section, table of contents.