5.3. Cubic splines#
A piecewise linear interpolant is continuous but has discontinuities in its derivative. We often desire a smoother interpolant, i.e., one that has some continuous derivatives. By far the most popular choice is piecewise cubic.
A cubic spline is a piecewise cubic function that has two continuous derivatives everywhere.
We use
where
Smoothness conditions#
We are able to ensure that
1. Interpolation by
Algebraically we require
where we have used the definition
The values of
with
where we have defined the diagonal matrix
Collectively, (5.3.5) and (5.3.6) express
2. Continuity of
We do not know what the slope of the interpolant should be at the nodes, but we do want the same slope whether a node is approached from the left or the right. Thus we obtain constraints at the nodes that sit between two neighboring piecewise definitions, so that
Moving the unknowns to the left side, as a system these become
where now we have defined
and
Left-multiplying by
3. Continuity of
These again apply only at the interior nodes
In system form (after canceling a factor of 2 from each side) we get
End conditions#
So far the equations (5.3.5), (5.3.6), (5.3.9), and (5.3.13) form
Natural spline:
Not-a-knot spline:
While natural splines have important theoretical properties, not-a-knot splines give better pointwise accuracy, and they are the only type we consider further.
In the not-a-knot spline, the values and first three derivatives of the cubic polynomials
Collectively, (5.3.5), (5.3.6), (5.3.9), (5.3.13), and (5.3.14) comprise a square linear system of size
Implementation#
Cubic not-a-knot spline interpolation
1"""
2 spinterp(t,y)
3
4Construct a cubic not-a-knot spline interpolating function for data
5values in `y` given at nodes in `t`.
6"""
7function spinterp(t,y)
8 n = length(t)-1
9 h = [ t[k+1]-t[k] for k in 1:n ]
10
11 # Preliminary definitions.
12 Z = zeros(n,n);
13 In = I(n); E = In[1:n-1,:];
14 J = diagm(0=>ones(n),1=>-ones(n-1))
15 H = diagm(0=>h)
16
17 # Left endpoint interpolation:
18 AL = [ In Z Z Z ]
19 vL = y[1:n]
20
21 # Right endpoint interpolation:
22 AR = [ In H H^2 H^3 ];
23 vR = y[2:n+1]
24
25 # Continuity of first derivative:
26 A1 = E*[ Z J 2*H 3*H^2 ]
27 v1 = zeros(n-1)
28
29 # Continuity of second derivative:
30 A2 = E*[ Z Z J 3*H ]
31 v2 = zeros(n-1)
32
33 # Not-a-knot conditions:
34 nakL = [ zeros(1,3*n) [1 -1 zeros(1,n-2)] ]
35 nakR = [ zeros(1,3*n) [zeros(1,n-2) 1 -1] ]
36
37 # Assemble and solve the full system.
38 A = [ AL; AR; A1; A2; nakL; nakR ]
39 v = [ vL; vR; v1; v2; 0; 0 ]
40 z = A\v
41
42 # Break the coefficients into separate vectors.
43 rows = 1:n
44 a = z[rows]
45 b = z[n.+rows]; c = z[2*n.+rows]; d = z[3*n.+rows]
46 S = [ Polynomial([a[k],b[k],c[k],d[k]]) for k in 1:n ]
47
48 # This function evaluates the spline when called with a value
49 # for x.
50 return function (x)
51 if x < t[1] || x > t[n+1] # outside the interval
52 return NaN
53 elseif x==t[1]
54 return y[1]
55 else
56 k = findlast(x .> t) # last node to the left of x
57 return S[k](x-t[k])
58 end
59 end
60end
Function 5.3.2 gives an implementation of cubic not-a-knot spline interpolation. For clarity it stays very close to the description given above. There are some possible shortcuts—for example, one could avoid using
Conditioning and convergence#
For illustration, here is a spline interpolant using just a few nodes.
f = x -> exp(sin(7*x))
plot(f,0,1,label="function",xlabel=L"x",ylabel=L"y")
t = [0, 0.075, 0.25, 0.55, 0.7, 1] # nodes
y = f.(t) # values at nodes
scatter!(t,y,label="values at nodes")
S = FNC.spinterp(t,y)
plot!(S,0,1,label="spline")
Now we look at the convergence rate as the number of nodes increases.
x = (0:10000)/1e4 # sample the difference at many points
n = @. round(Int,2^(3:0.5:7)) # numbers of nodes
err = zeros(0)
for n in n
t = (0:n)/n
S = FNC.spinterp(t,f.(t))
dif = @. f(x)-S(x)
push!(err,norm(dif,Inf))
end
pretty_table((;n, err), header=["n","error"])
┌─────┬─────────────┐
│ n │ error │
├─────┼─────────────┤
│ 8 │ 0.0305634 │
│ 11 │ 0.0207562 │
│ 16 │ 0.00590761 │
│ 23 │ 0.00134587 │
│ 32 │ 0.000367049 │
│ 45 │ 9.17785e-5 │
│ 64 │ 2.15306e-5 │
│ 91 │ 5.04292e-6 │
│ 128 │ 1.24012e-6 │
└─────┴─────────────┘
Since we expect convergence that is
order4 = @. (n/n[1])^(-4)
plot(n,[err order4],m=[:o :none],l=[:solid :dash],
label=["error" "4th order"],
xaxis=(:log10,"n"), yaxis=(:log10,L"|| f-S\,||_\infty"),
title="Convergence of spline interpolation")
Besides having more smoothness than a piecewise linear interpolant, the not-a-knot cubic spline improves the order of accuracy to 4.
Suppose that
The conditioning of spline interpolation is much more complicated than for the piecewise linear case. First, the fact that the coefficients of all the cubics must be solved for simultaneously implies that each data value in
Exercises#
✍ In each case, write out the entries of the matrix and right-hand side of the linear system that determines the coefficients for the cubic not-a-knot spline interpolant of the given function and node vector.
(a)
(b)
(c)
(d)
⌨ (continuation) For each case in the preceding problem, use Julia to solve the linear system you wrote down. Then plot the resulting cubic spline over the interval between the second and third nodes.
⌨ For each given function, interval, and value of
, define evenly spaced nodes. Then use Function 5.3.2 to plot the cubic spline interpolant using those nodes, together with the original function over the given interval.(a)
on ,(b)
on ,(c)
on ,⌨ For each given function and interval, perform piecewise linear interpolation using Function 5.3.2 for
equispaced nodes with . For each , estimate the errorby evaluating the function and interpolant at 1600 points in the interval. Make a log-log plot of
as a function of and add the line for a constant of your choosing.(a)
on(b)
on(c)
on⌨ Although the cardinal cubic splines are intractable in closed form, they can be found numerically. Each cardinal spline interpolates the data from one column of an identity matrix. Define the nodes
. Plot over the five cardinal functions for this node set over the interval .✍ Suppose you were to define a piecewise quadratic spline that interpolates
given values and has a continuous first derivative. Follow the derivation of this section to express all of the interpolation and continuity conditions. How many additional conditions are required to make a square system for the coefficients?(a) ✍ If
, another possibility for cubic spline end conditions is to make a periodic function. This implies that and are also periodic. Write out the two new algebraic equations for these constraints in terms of the piecewise coefficients.(b) ⌨ Modify Function 5.3.2 to compute a periodic spline interpolant. Test by making a plot of the interpolant for
over the interval with equally spaced nodes and .
- 1
This explains the name of the not-a-knot spline—for splines, “knots” are the points at which different piecewise definitions meet.