I.2.6. The linear equations for cubic splines: version 2

advertisement
plot(XL,YL)
hold off
I.2.6. The linear equations for cubic splines: version 2
This version follows Numerical Recipes in C, by Press, et. al.
Given points (x1 , y1 ), . . . , (xn , yn ) with x1 < x2 < · · · < xn we wish to find a collection of cubic
polynomials p1 (x), p2 (x), . . . , pn−1 (x) such that
1. pi (xi ) = yi and pi (xi+1 ) = yi+1 for i = 1, . . . , n − 1 (Each pi has the correct values at the left
and right endpoints.)
2. p�i (xi+1 ) = p�i+1 (xi+1 ) for i = 1, . . . , n − 2 (First derivatives are continuous.)
3. p��i (xi+1 ) = p��i+1 (xi+1 ) for i = 1, . . . , n − 2 (Second derivatives are continuous.)
4. p��1 (x1 ) = p��n−1 (xn ) = 0 (Endpoint condition holds.)
There are a total of 2(n − 1) + 2(n − 2) + 2 = 4n − 4 equations. Each polynomial pi , being of the
form ai x3 + bi x2 + ci x + di , contains 4 unknown coefficients. Since there are n − 1 polynomials,
this gives a total of 4(n − 1) = 4n − 4 unknowns. The equations above form a system 4n − 4 linear
equations in 4n − 4 unknown coefficients. These have a unique solution which can be found and
plotted using MATLAB/Octave.
However, it turns out that we only need to solve a much smaller system of n equations in n
unknowns. Moreover, this system is tridiagonal (i.e., the coefficient matrix for the system only has
non-zero entries on the diagonal and the first sub- and superdiagonals.) Such systems can be solved
efficiently.
The key to reducing the size of the system is replacing the parameters ai , bi , ci , di with more
natural parameters. Instead of using these coefficients, we can specify a cubic polynomial on the
interval [xi , xi+1 ] by fixing its values and the values of its second derivatives at the endpoints.
Explicitly, let
A(x) =
xi+1 − x
xi+1 − xi
B(x) = 1 − A(x) =
x − xi
xi+1 − xi
1
C(x) = (A(x)3 − A(x))(xi+1 − xi )2
6
1
D(x) = (B(x)3 − B(x))(xi+1 − xi )2
6
41
and set
pi (x) = A(x)yi + B(x)yi+1 + C(x)zi + D(x)zi+1
for some unknown numbers z1 , . . . , zn . Notice that
[A(xi ), B(xi ), C(xi ), D(xi )] = [1, 0, 0, 0]
[A(xi+1 ), B(xi+1 ), C(xi+1 ), D(xi+1 )] = [0, 1, 0, 0]
[A�� (xi ), B �� (xi ), C �� (xi ), D�� (xi )] = [0, 0, 1, 0]
[A�� (xi+1 ), B �� (xi+1 ), C �� (xi+1 ), D�� (xi+1 )] = [0, 0, 0, 1].
It follows that
pi (xi ) = yi
pi (xi+1 ) = yi+1
p��i (xi ) = zi
p��i (xi+1 ) = zi+1
Thus we see that with this definition of pi , the equations 1. are automatically satisfied, and the
numbers zi are the second derivatives of the pi ’s at the endpoints. Although these are not yet
known, writing the pi ’s in the way we have done forces the continuity equations 3. to hold as well.
We are therefore left with the equations 2. and 4., a total of n equations in the n unknowns
z1 , . . . , zn . Equations 4. simply read z1 = zn = 0. When we substitute our expression for pi and
pi+1 into Equations 2., these take the form
�
�
�
�
�
�
xi+1 − xi
yi+2 − yi+1
yi+1 − yi
xi+2 − xi
xi+2 − xi+1
zi +
zi+1 +
zi+2 =
−
6
3
6
xi+2 − xi+1 xi+1 − xi
for i = 1, . . . , n − 2. So the remaining equations have the form
Sz = b
with z = [z1 , . . . , zn ]T ,

1
 x2 −x1
 6
 0

S =  ..
 .


42
0
0
x3 −x1
3
x3 −x1
6
x3 −x2
6
x4 −x2
3
..
.
..
.
0
0
x4 −x3
6
..
.

···
···
···
..
.
···
···
xn−1 −xn−2
6
0
xn −xn−2
3
0







xn −xn−1 
6
1
and

0
−
..
.
y3 −y2

x3 −x2


b=
 yn −yn−1

−
xn −xn−1
0
y2 −y1
x2 −x1





yn−1 −yn−2 

xn−1 −xn−2
Solving these equation for z and using the resulting values in the expressions for pi (x), i = 1, . . . , n−
1 completes the computation of the splines.
We now examine how we could implement this in MATLAB/Octave. We begin by computing
the matrix S. To do this we can use the diag command. If a is a vector, then diag(a) defines a
diagonal matrix with a on the diagonal. For example
> a=[1,2,3]
a =
1
2
3
> diag(a)
ans =
Diagonal Matrix
1
0
0
0
2
0
0
0
3
Similarly, diag(a,1) (resp. diag(a,-1)) puts a on the superdiagonal (resp. subdiagonal). Thus
> diag(a,1)
ans =
0
0
0
0
1
0
0
0
0
2
0
0
0
0
3
0
To define S, we start with the vector X = [x1 , . . . , xn ] and assemble the diagonal and sub- and
superdiagonals by taking suitable subvectors and concatenating them. The diagonal of S is given
by
[1, (x3 − x1 )/3, (x4 − x2 )/3, . . . , (xn − xn−2 )/3, 1].
43
In MATLAB/Octave we can define this vector as [1,(X(3:n)-X(1:n-2))/3,1]. Similarly the superdiagonal is given by [0,(X(3:n)-X(2:n-1))/6] and the subdiagonal by [(X(2:n-1)-X(1:n-2))/6,0].
Here are the commands, which should be stored in a file called splinemat2.m. The first and last
lines make splinemat2 a function. If the file splinemat2.m is stored in the working directory for
MATLAB/Octave and the vector X has been defined, then typing S=splinemat2(X) will define S
using the values in X.
function S=splinemat2(X)
n=length(X);
SD = [1,(X(3:n)-X(1:n-2))/3,1];
SU = [0,(X(3:n)-X(2:n-1))/6];
SL = [(X(2:n-1)-X(1:n-2))/6,0];
S=diag(SD)+diag(SU,1)+diag(SL,-1);
end
The following function takes as input the lower and upper endpoints of the interval (xl and
xu), the values of the cubic polynomial at the endpoints (yl and yu) and the values of the second
derivative at the endpoints (zl and zu) and plots the corresponding cubic polynomial. The code
contains expressions that appear to add a number to a vector, which is an undefined operation. In
this situation MATLAB/Octave replaces the number by a vector where every component is equal
to the number. So, for example 1+[1,2,3] is evaluated as [1,1,1]+[1,2,3].
function plotcubic2(xl,xu,yl,yu,zl,zu)
%
% plots the cubic polynomial in the interval [xl,xu]
% whose values (resp. 2nd derivatives) at the endpoints
% are yl,yu (resp. zl,zu)
%
n=100;
X=linspace(xl,xu,100);
A=(xu-X)/(xu-xl);
B=1-A;
C=A.*(A.^2-1)*(xu-xl)^2/6;
D=B.*(B.^2-1)*(xu-xl)^2/6;
P=A*yl + B*yu + C*zl + D*zu;
44
plot(X,P)
end;
Finally, the following function takes as input the values X = [x1 , . . . , xn ] and Y = [y1 , . . . , yn ]
to be interpolated, solves the equation Sz = b to find the values Z = [z1 , . . . , zn ] of the second
derivatives at the endpoints, and then uses plotcubic2 to plot the resulting polynomials in each
interval.
function plotspline2(X,Y)
%
% For inputs X=[x1, ... ,xn] and Y=[y1, ... ,yn] this plots the cubic
% spline through the points (x1,y1) ... (xn,yn)
%
S=splinemat2(X);
n=length(X)
b=[0,(Y(3:n)-Y(2:n-1))./(X(3:n)-X(2:n-1)) - (Y(2:n-1)-Y(1:n-2))./(X(2:n-1)-X(1:n-2)),0];
Z=S\b’;
for k=[1:n-1]
plotcubic2(X(k),X(k+1),Y(k),Y(k+1),Z(k),Z(k+1));
hold on
end
hold off
end
I.2.7. Summary of MATLAB/Octave commands used in this section
How to access elements of a vector
a(i) returns the i-th element of the vector a
How to create a vector with linearly spaced elements
linspace(x1,x2,n) generates n points between the values x1 and x2.
45
Related documents
Download