% % Mfile name
%   mtl_inp_sim_speneedspline.m

% Language: Matlab 7.4.0 (R2007a)
% Revised: 
%   August 8, 2008

% Authors:
%   Nathan Collier, Luke Snyder, Autar Kaw
%   University of South Florida
%   kaw@eng.usf.edu
%   Website: http://numericalmethods.eng.usf.edu
       
% Purpose
%   To illustrate the need for spline interpolation as opposed to higher
%   order polynomial interpolation.

% Keywords
%   Higher order Interpolation
%   Spline Interplolation
%   Carl Runge

% Clearing all data, variable names, and files from any other source and
% clearing the command window after each sucessive run of the program.
clc
clf
clear all

% INPUTS: This is the only section in the program where the user can make
% changes to the program.

% Enter the number of points chosen for interpolation in [-1,1]
n=9;
% NOTE: For the number scheme to work properly n needs to be an odd number

% *************************************************************************

disp(sprintf('\n\nAdditional Interpolation Topics: Need for Spline Interpolation'))
disp(sprintf('\nUniversity of South Florida'))
disp(sprintf('United States of America'))
disp(sprintf('kaw@eng.usf.edu'))
disp(sprintf('\nNOTE: This worksheet utilizes Matlab to illustrate the concept'))
disp(sprintf('that spline interpolation is often preferred over polynomial ')) 
disp(sprintf('interpolation.'))

disp(sprintf('\n*****************************Introduction******************************'))

disp(sprintf('\nThis simulation shows the need for spline interpolation as opposed'))
disp(sprintf('to using polynomial interpolation.  The function chosen for demonstration'))
disp(sprintf('was first used by Carl Runge in 1901.  He wanted to show that higher'))
disp(sprintf('order interpolation was often a bad idea due to large percent relative'))
disp(sprintf('true errors that could be observed as the function moved towards the'))
disp(sprintf('endpoints of the chosen interval.  He took a simple looking function'))
disp(sprintf('f(x)=1/(1+25x^2) and chose equidistantly spaced points to interpolate'))
disp(sprintf('the function.  He then used spline interpolation to demonstrate the'))
disp(sprintf('increases in accuracy versus the traditional polynomial interpolation.'))

disp(sprintf('\n******************************Simulation*********************************'))    

% SOLUTION:

% Creating the first figure for the data.
figure(1)
frunge=inline('1/(1+25*x^2)');

% Using a loop to create a new x array of data "xf" on the interval [-1,1]
% and plugging these values into the inline function "frunge".  Note that
% the same operation could be done using vectorization but the
% multiplication, division and root operators inside the inline function
% would have to be changed to array operators.
nn=1;
for i =-1:0.01:1
    xf(nn)=i;
    yf(nn)=frunge(xf(nn));
    nn=nn+1;
end

plot(xf,yf,'k','LineWidth',2)
str1 = 'Runge^,s function interpolated using polynomial interpolation';
str2 = 'and cubic spline interpolation';
title({str1;str2},'Fontweight','bold','FontSize',10)
xlabel('\bfx from -1 to 1');
ylabel('\bff(x)');
hold on
xlim([-1,1])
ylim([-1.1,1.1])

% Using a loop to create the equidistant point array "X" and then plugging
% these values into inline function "frunge" to create the "Y" array for
% interpolation.
for i=1:n
    X(i)=2/(n-1)*(i-1)-1;
    Y(i)=frunge(X(i));
end

% Interpolating the values across the specified [-1,1] interval using
% polynomial interpolation.
p=polyfit(X,Y,numel(X)-1);
x1=-1:0.01:1;
y1=polyval(p,x1);
plot(x1,y1,'b')

% Interpolating the values across the specified [-1,1] interval using
% spline interpolation.
xx=-1:0.01:1;
yy=spline(X,Y,xx);
plot(xx,yy,'g')

plot(X,Y,'ro','MarkerSize',6,'MarkerFaceColor',[1,0,0])

% Creating a legend for the figure.
legend('= Runge^,s function','= Polynomial fit','= Spline fit','= Data points',4)

% Comments:
disp(sprintf('\nIt can be seen from the figure that the spline interpolation'))
disp(sprintf('is a much better approximation to the actual function.  The '))
disp(sprintf('polynomial interpolant would yeild much higher percent relative'))
disp(sprintf('true error values near the ends of the interval.  The curve produced'))
disp(sprintf('via spline interpolation would obviously produce much lower percent'))
disp(sprintf('relative true error values and thus it is a better overall'))
disp(sprintf('approximation of the function.'))






