Skip to main content

Section 23.3 Using cubic splines

We do not go into the process of finding the coefficients of a cubic spline: it involves solving a linear system with only a few nonzero diagonals. In Matlab, the command spline computes a not-a-knot spline from given data, for example

x = 1:7;
y = [1 3 2 4 4 1 5];
s = spline(x, y);
disp(s.coefs)

Each row of the output contains the coefficients A, B, C, D of cubic polynomial (23.2.1) which is used on the interval \([x_{k}, x_{k+1}]\text{.}\) We could use these coefficients to evaluate the spline, but Matlab can do this automatically with ppval (meaning “Piecewise Polynomial VALues”). Specifically, ppval(s, t) evaluates the spline at a value (or vector of values) t. Thus,

t = linspace(min(x), max(x), 1000);
plot(t, ppval(s, t))

plots the spline computed above.

There is also an option to combine construction and evaluation of a spline into the same command spline, by feeding t as a third argument. That is, spline(x, y, t) constructs a spline from x, y and immediately evaluates it at t. For example:

t = linspace(min(x), max(x), 1000);
plot(t, spline(x, y, t))

We can also plot it with the original data points marked:

plot(t, spline(x, y, t), x, y, 'r*')

How else could we use the spline data? The formula (23.2.1) shows that \(S'(x_k) = C_k\text{,}\) which is the entry of the 3rd column of matrix s.coefs. Try s.coefs(:, 3)' and compare the values with the slope of the spline at the data points. This is another approach to numerical differentiation, different from what we did in Chapter 12: given discrete data, fit a spline to it and differentiate the spline.

Looking at the coefficients, we can also find the critical points of a spline, answering the question raised at the end of Section 23.1. Indeed, we have \(A, B, C, D\) coefficients of a cubic polynomial, so its derivative is a quadratic polynomial with coefficients \(3A, 2B, C\text{.}\) We can find its roots with roots but one must be careful to check if a root indeed falls into the subinterval on which this polynomial is used.

Find and plot the critical points of the spline constructed from the data

x = 1:7;
y = [1 3 2 4 4 1 5];
Answer

Since the number of critical points is not known in advance, we can gather them by appending each new critical point to the vector critpts. To qualify for inclusion, a root of derivative of the cubic polynomial used on \([x_k, x_{k+1}]\) must be real and must lie within this interval.

s = spline(x, y);
critpts = [];
for k=1:numel(x)-1
    r = roots([3 2 1].*s.coefs(k, 1:3));
    for j = 1:numel(r)
        if isreal(r(j)) && r(j) >= 0 && r(j) <= x(k+1)-x(k)
            critpts = [critpts, x(k)+r(j)];
        end
    end
end
t = linspace(min(x), max(x), 1000);
plot(t, ppval(s, t), x, y, 'r+', critpts, ppval(s, critpts), 'k*')

The script uses ppval since the spline s is already constructed; calling spline(x, y, ...) repeatedly with the same x, y seems wasteful.