Splines
Learning Objectives
- Explain why many low-degree pieces avoid the oscillation of one high-degree polynomial, and measure the difference on Runge's function.
- Count the conditions that define a cubic spline, and derive the tridiagonal system for its second derivatives.
- Compare natural, clamped and not-a-knot boundaries, and predict the order of each from what it assumes at the ends.
- Implement a cubic spline and check it against
scipy.interpolate.CubicSpline. - Recognize where a spline misleads (overshoot, extrapolation, noisy data) and reach for a shape-preserving alternative.
Context & Motivation
polynomial-interpolation-lagrange-and-newton left an open problem: Chebyshev nodes rescue a high-degree polynomial, but real data usually arrives on a grid someone else chose, and there the polynomial diverges. Splines keep the grid and give up the single formula. They use a low-degree polynomial on each interval between nodes and join the pieces smoothly. The degree stays fixed while the number of pieces grows, so accuracy comes from getting small rather than from the degree getting large, and the effect of one data value fades quickly with distance.
The name comes from the flexible strip draftsmen bent through fixed points. Cubic splines are a common default for smooth curves through data because they are cheap to build, with one tridiagonal solve, and cheap to evaluate.
Core Theory
Linear splines
Joining the points with straight segments gives the linear spline. If and is the largest gap between nodes, the error formula for two nodes gives
because on each interval. The map from data to interpolant has absolute condition number 1 in the max norm: a change of size in the data changes by exactly in that norm. The price is a corner at every node.
Counting the conditions of a cubic spline
A cubic spline on nodes is a function that is a cubic on each interval, lies in , and interpolates the data. With intervals there are coefficients. Matching the data at both ends of each interval gives conditions. Continuity of and at the interior nodes gives more. That is , so exactly two conditions remain free, and they are the boundary conditions.
The system for the second derivatives
Let , and . On each interval is linear from to . Integrating twice and imposing the data gives, on ,
Values and now match by construction. Requiring to agree from both sides at an interior node gives, for ,
This system is the reason splines are practical. It is tridiagonal, so it is solved in operations, not . With natural or clamped ends it is strictly diagonally dominant by rows on any mesh, since , so it is invertible and needs no pivoting (compare lu-decomposition-and-partial-pivoting and the dominance condition in iterative-methods-jacobi-and-gauss-seidel). On a uniform mesh with natural ends it is times the matrix with 4 on the diagonal and 1 beside it, whose eigenvalues lie in , so : measured , , for . Compare that with the Vandermonde matrices of the previous lesson.
Boundary conditions
- Natural: . It needs no extra data, and it asserts that has no curvature at the ends.
- Clamped: and for given slopes. The added equations are and .
- Not-a-knot: is continuous at and , so the first two pieces are one cubic, and likewise the last two. It needs no extra data and is the default in
CubicSpline. - Periodic: and match between the two ends, for data with .
Order. If on a uniform mesh, the not-a-knot spline satisfies for small enough . Clamped splines with the true slopes reach the same order (Example 4). The natural spline forces at the ends, so when there it is only , and the loss sits at the ends.
Minimum curvature
Among all that interpolate the data, the natural spline minimizes . With both end slopes fixed, the clamped spline minimizes it among interpolants with those slopes. This integral only approximates the bending energy of a physical strip: true curvature is , so the two agree only for small slopes.
Worked Examples
Example 1: a natural spline by hand
Take nodes with values . Then and , and with the system is
so and . With , the pieces are
At : and , but and . The third derivative jumps, as it must, or the pieces would be one cubic. The midpoint values are , and CubicSpline(x, y, bc_type="natural") returns with exactly these coefficients.
The curvature integral is for this spline. It is for the not-a-knot spline, which on four points is the single cubic through them, and for the spline clamped to zero slope. The natural spline has the smallest, as the theorem requires.
Example 2: implementation, checked against SciPy
plaintextimport numpy as np from scipy.linalg import solve_banded def moments(t, y, slopes=None): """Second derivatives at the knots: natural, or clamped if slopes=(s0, sn).""" n, h = len(t) - 1, np.diff(t) d = np.diff(y) / h up, main, lo, r = np.zeros((4, n + 1)) main[1:n] = 2 * (h[:-1] + h[1:]) lo[:n - 1] = h[:-1] up[2:] = h[1:] r[1:n] = 6 * (d[1:] - d[:-1]) main[[0, n]] = 1.0 if slopes is not None: main[0], up[1], r[0] = 2 * h[0], h[0], 6 * (d[0] - slopes[0]) main[n], lo[n - 1], r[n] = 2 * h[-1], h[-1], 6 * (slopes[1] - d[-1]) return solve_banded((1, 1), np.vstack([up, main, lo]), r)
On 40 random nodes in (gaps from to ) with , evaluating the piecewise formula above on 20001 points differs from CubicSpline by at most , both for natural ends and for clamped ends with the true slopes.
Example 3: Runge's function
Max errors for on with nodes, on a grid of 20001 points. All columns but the last use equispaced nodes.
textn polynomial linear cubic not-a-knot Chebyshev polynomial 10 1.92e+00 6.74e-02 2.20e-02 1.09e-01 20 5.98e+01 4.18e-02 3.18e-03 1.53e-02 40 1.05e+05 1.40e-02 2.78e-04 2.89e-04 80 6.31e+14 3.80e-03 1.61e-05 1.02e-07
The polynomial diverges on the same data for which the spline converges. Observed orders of the cubic, from doubling , are , , , then and at and : "order 4" appears only once resolves the peak of width about . Splines are not simply better than Chebyshev interpolation. Up to the spline wins, at they tie, and at the polynomial on chosen nodes is about 160 times better, because this is analytic and geometric convergence overtakes .
The reason for the stability is locality. Set at the central node and at the others, , and record the largest value in each interval:
textinterval from the bump natural spline polynomial 1 1.37e-01 2.65e-01 2 3.66e-02 2.32e-01 3 9.81e-03 3.01e-01 5 7.05e-04 1.25e+00 9 4.41e-06 1.82e+03
Each interval multiplies the spline by a factor of about , the size of the decaying root of the recurrence . The polynomial grows toward the ends. The Lebesgue constant at is for the natural spline and for not-a-knot, against for the polynomial. With , adding to the central value changes the spline by and the polynomial by .
Example 4: the boundary condition sets the order
Max error for on , where at both ends:
textn natural clamped not-a-knot 10 1.33e-03 6.96e-07 6.93e-06 20 3.34e-04 4.39e-08 4.56e-07 40 8.34e-05 2.75e-09 2.92e-08 80 2.09e-05 1.73e-10 1.85e-09 160 5.21e-06 1.08e-11 1.17e-10 ord 2.00 4.00 3.99
The natural error sits next to the right end, at for , where the false assumption costs most. On over , where really is at both ends, the natural spline recovers order . Here the clamped error times is , close to , for this . The linear spline's bound is nearly attained: measured against at .
Example 5: when is not smooth
For on , is unbounded at , so the hypothesis fails.
textn uniform linear uniform cubic graded cubic, x_i = (i/n)^4 20 5.59e-02 3.94e-02 7.20e-03 80 2.80e-02 1.97e-02 4.50e-04 320 1.40e-02 9.85e-03 2.81e-05
On a uniform mesh both orders fall to , and the extra degree buys almost nothing. Splines accept any mesh, so nodes can be moved toward the singularity, which gives order with the same node count.
Example 6: overshoot and extrapolation
Take data at and at . CubicSpline ranges from to . Smoothness forces it past the data. Now take an illustrative latency distribution, with ms and cumulative fractions . On this uneven grid the cubic reaches near ms, an impossible probability, and decreases on about a third of the range. PchipInterpolator stays monotone, between and , at the cost of being only .
Outside the data a spline is just its last cubic, and CubicSpline extrapolates by default. For on 11 nodes in , the value at is against , and at it is against . Pass extrapolate=False to get nan there.
Common Misconceptions & Pitfalls
- "Splines never oscillate." They avoid Runge's growth, not overshoot: Example 6 overshoots by about of the step.
- "The natural spline is the most natural choice." The name refers to the condition, not to accuracy. It is order 2 unless vanishes at the ends (Example 4).
- "
bc_type='clamped'means the slopes are matched." In SciPy that string means zero slope at both ends. On with it gives error , against forbc_type=((1, 1.0), (1, np.e)). - "An interpolating spline removes noise." It passes through every data point, noise included. For noisy data use a fit: see
least-squares-curve-fitting, orscipy.interpolate.make_smoothing_spline. - "Splines always beat global polynomials." On smooth functions with chosen nodes, Chebyshev interpolation wins eventually (Example 3).
- "Book vs today." Older code uses
scipy.interpolate.interp1d, which SciPy now calls legacy. New code should useCubicSpline,PchipInterpolatorormake_interp_spline. With the default boundary,make_interp_spline(t, y, k=3)agrees withCubicSplineto on the step data of Example 6.
Summary
A cubic spline has coefficients and matching conditions, so two boundary conditions complete it. The second derivatives solve a tridiagonal, strictly diagonally dominant system in , with on a uniform natural mesh. For , not-a-knot and clamped splines reach order 4, and natural ones fall to order 2 unless vanishes at the ends. On Runge's function the error goes from to between and while the equispaced polynomial explodes, because a spline's response to one value is multiplied by a factor of per interval. Cubic splines still overshoot and extrapolate badly: use a monotone interpolant such as PCHIP when shape matters, and a fit when the data is noisy.
Documentation Links
- Driscoll and Braun: Fundamentals of Numerical Computation, 5.2 Piecewise linear interpolation
- Driscoll and Braun: Fundamentals of Numerical Computation, 5.3 Cubic splines
- Demanet (2012): MIT OpenCourseWare 18.330, Chapter 3: Interpolation
- SciPy documentation: CubicSpline
- SciPy documentation: PchipInterpolator
- SciPy documentation: interp1d
- SciPy documentation: make_interp_spline
- SciPy documentation: make_smoothing_spline