/spline

c++ cubic spline library

Primary LanguageC++GNU General Public License v2.0GPL-2.0

C++ cubic spline interpolation

cubic C2 spline

This is a lightweight implementation of cubic splines to interpolate points f(xi) = yi with the following features.

  • available spline types:
    • cubic C2 splines: global, twice continuously differentiable
    • cubic Hermite splines: local, continuously differentiable (C1)
  • boundary conditions: first and second order derivatives can be specified, not-a-knot condition, periodic condition is not implemented
  • extrapolation
    • linear: if first order derivatives are specified or 2nd order = 0
    • quadratic: if 2nd order derivatives not equal to zero specified
  • monotonicity can be enforced (when input is monotonic as well)

Usage

The library is a header-only file with no external dependencies and can be used like this:

#include <vector>
#include "spline.h"
...
    std::vector<double> X, Y;
    ...
    // default cubic spline (C^2) with natural boundary conditions (f''=0)
    tk::spline s(X,Y);			// X needs to be strictly increasing
    double value=s(1.3);		// interpolated value at 1.3
    double deriv=s.deriv(1,1.3);	// 1st order derivative at 1.3
    std::vector<double> solutions = s.solve(0.0);	// solves s(x)=0.0
    ...

The constructor can take more arguments to define the spline, e.g.:

    // cubic Hermite splines (C^1) with enforced monotonicity and
    // left curvature equal to 0.0 and right slope equal 1.0
    tk::spline s(X,Y,tk::spline::cspline_hermite, true,
                 tk::spline::second_deriv, 0.0,
                 tk::spline::first_deriv, 1.0);

This is identical to (must be called in that order):

    tk::spline s;
    s.set_boundary(tk::spline::second_deriv, 0.0,
                   tk::spline::first_deriv, 1.0);
    s.set_points(X,Y);
    s.make_monotonic();

Spline types

Splines are piecewise polynomial functions to interpolate points (xi, yi). In particular, cubic splines can be represented as

  • f(x) = ai + bi (x-xi) + ci (x-xi)2 + di (x-xi)3, for all x in [xi, xi+1)
  • f(xi)=yi

The following splines are available.

  • tk::spline::cspline: cubic C2 spline
    • twice continuously differentiable, e.g. f'(xi) and f''(xi) exist
    • this, together with boundary conditions uniquely determines the spline
    • requires solving a sparse equation system
    • is a global spline in the sense that changing an input point will impact the spline everywhere
    • setting first order derivatives at the boundary will break C2 at the boundary
  • tk::spline::cspline_hermite: cubic Hermite spline
    • once continuously differentiable (C1)
    • first order derivatives are specified by finite differences, e.g. on a uniform x-grid:
      • f'(xi) = (yi+1-yi-1)/(xi+1-xi-1)
    • is a local spline in the sense that changing grid points will only affect the spline around that grid point in a few adjacent segments

A function to enforce monotonicity is available as well:

  • tk::spline::make_monotonic(): will make the spline monotonic if input grid points are monotonic
    • this function can only be called after set_points(...) has been called
    • it will break C2 if the original spline was C2 and not already monotonic
    • it will break boundary conditions if it was not monotonic in the first or last segment

References

https://kluge.in-chemnitz.de/opensource/spline/