function [X,Y] = natural_cubic_spline(x,y,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). % 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 the n unknowns M. We close the system with two more constraints: % M(1) = 0 and M(n) = 0; 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 force M(1) = 0 and M(n) = 0 which % will create the "natural spline function" A(1,1) = 1; b(1) = 0; A(n,n) = 1; b(n) = 0; 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);