function [X,Y] = not_a_knot_spline(x,y,z,yz,N) % We're given data in the vectors x and y. The output will be a % fitting where there are N-1 new points introduced between each % x(j) and x(j+1). To close the problem, we provide an additional % pair of points: z(1) and z(2) where x(1) < z(1) < x(2) and % x(n-1) < z(2) < x(n). yz(1) is the value at z(1) and yz(2) is % the value at z(2). % if we have meshpoints x_1...x_n and assume a cubic function on % each subinterval [x_j,x_{j+1}] where s''(x_j) =: M_j and s(x_j) = y_j % then % s(x) = ((x(j+1)-x)^3*M(j) + (x-x(j))^3*M(j+1))/(6*(x(j+1)-x(j))) % + ((x(j+1)-x)*y(j) + (x-x(j))*y(j+1))/(x(j+1)-x(j)) % -1/6 (x(j+1) - x(j))*((x(j+1) - x)*M(j) + (x-x(j))*M(j+1)) % % the requirement that s' be continuous on [x_1,x_n] leads to n-2 % equations for j=2..n-1: % % (x_j - x_(j-1))/6 M_{j-1} + (x_{j+1}-x_{j-1})/3 M_j + (x_{j+1}-x_j)/6 M_{j+1} % = (y_{j+1}-y_j)/(x_{j+1}-x_j) - (y_j-y_{j-1})/(x_j - x_{j-1}) % % for a not-a-knot spline, we close the system with two more constraints, % specified at two points, z_1 in [x_1,x_2] and z_2 in [x_{n-1},x_n] % test case: % x = [0 1 2 2.5 3 3.5 4]; % y = x.^3 + 2*x.^2 - x; % z = [.5 3.75]; % yz = z.^3 + 2*z.^2 - z; n = length(x); for j=2:n-1 A(j,j-1) = (x(j)-x(j-1))/6; A(j,j) = (x(j+1)-x(j-1))/3; A(j,j+1) = (x(j+1)-x(j))/6; b(j) = (y(j+1)-y(j))/(x(j+1)-x(j)) - (y(j)-y(j-1))/(x(j)-x(j-1)); end % the following will create a not-a-knot spline by requiring correct % interpolation xx = z(1); yy = yz(1); j = 1; A(j,j) = (x(j+1)-xx)^3/(6*(x(j+1)-x(j))) - (1/6)*(x(j+1) - x(j))*((x(j+1) - xx)); A(j,j+1) = (xx-x(j))^3/(6*(x(j+1)-x(j))) - (1/6)*(x(j+1)-x(j))*(xx-x(j)); b(1) = yy - ((x(j+1)-xx)*y(j) + (xx-x(j))*y(j+1))/(x(j+1)-x(j)); xx = z(2); yy = yz(2); j = n-1; A(j+1,j) = (x(j+1)-xx)^3/(6*(x(j+1)-x(j))) - (1/6)*(x(j+1) - x(j))*((x(j+1) - xx)); A(j+1,j+1) = (xx-x(j))^3/(6*(x(j+1)-x(j))) - (1/6)*(x(j+1)-x(j))*(xx-x(j)); b(j+1) = yy - ((x(j+1)-xx)*y(j) + (xx-x(j))*y(j+1))/(x(j+1)-x(j)); b = b'; M = A\b; % now that I have the coefficients M, I can construct the not-a-knot % spline. Recall that N is the number of subintervals that will be % introduced between x(j) and x(j+1). (There will be N-1 new points.) j=1; dx = (x(j+1)-x(j))/N; xx = x(j):dx:x(j+1)-dx; X(1:N) = xx; Y(1:N) = ((x(j+1)-xx).^3*M(j) + (xx-x(j)).^3*M(j+1))/(6*(x(j+1)-x(j))) ... + ((x(j+1)-xx)*y(j) + (xx-x(j))*y(j+1))/(x(j+1)-x(j)) ... -(1/6)*(x(j+1) - x(j))*((x(j+1) - xx)*M(j) + (xx-x(j))*M(j+1)); for j=2:n-1 dx = (x(j+1)-x(j))/N; xx = x(j):dx:x(j+1)-dx; X((j-1)*N+1:j*N) = xx; Y((j-1)*N+1:j*N) = ((x(j+1)-xx).^3*M(j) + (xx-x(j)).^3*M(j+1))/(6*(x(j+1)-x(j))) ... + ((x(j+1)-xx)*y(j) + (xx-x(j))*y(j+1))/(x(j+1)-x(j)) ... -(1/6)*(x(j+1) - x(j))*((x(j+1) - xx)*M(j) + (xx-x(j))*M(j+1)); end X(N*(n-1)+1) = x(n); Y(N*(n-1)+1) = y(n);