CU Mechanical Engineering

Numerical Methods Matlab tutorials



Writing Matlab Functions: polynomial interpolation

In this example, we will write a function that will help us study the effect of the choice of polynomial interpolation points on a given interval.

To begin, all functions within matlab must begin by declaring that m-file is a function. This is accomplished by having the first line of the m-file having the word 'function' followed by the name of the variable that will be returned. This is consequently set equal to the name of the name of the file with the quantities that are passed to the function in parenthesis. For the purpose of this exercise, the name of the function will be 'cp3' and the first line of the function is as follows:

function cp3

This function utilzes nested functions to evaluate the algorithm for several differnt cases. The nested function used will be described momentarily. The rest of this function is as follows:

n=[1,5,10,15];
cp3_4figs('1/(1+x^2)',n,0)
cp3_4figs('abs(x-0.5)',n,1)
cp3_4figs('sqrt(1-x^2)',n,1)

By defining a separate function to interpolate an input function, multiple functions can easily be evaluated and compared.

The function 'cp3_4figs' takes. The first line of this function is as follows:

function cp3_4figs(f,n,xlog)

This function takes three arguments. The first is the function, the second is the number of points to use for the interpolation and the last is used to determine which kind of plot to use. This will come in to play shortly.

figure          
x=linspace(0,1,1001);                  
f_exact=subs(f,x);                      
linestyle=['k: ';'b: ';'g: ';'m: '];     
titles=['equally-spaced grid';...          
        'Chebyshev grid     ';...
        'Arc Sine Grid      '];

The above segment of code sets up the plot. The 'linestyles' command sets the colors for each of the different data sets being plotted. The first letter corresponds to the color and the colon indicates that the line is to be plotted as a dotted line. The 'titles' array identifies the kind of distributions used for the points. This information will be available in the legend.

for i=1:3 
    subplot(2,2,i);                        
    plot(x,f_exact,'y-','linewidth',3);
    xlabel('x');
    ylabel('f');
    title(titles(i,:));
    hold on
end

'subplot' divides the current figure into rectangular panes that are numbered rowwise. Each pane contains an axes object. Subsequent plots are output to the current pane. The 'subplot(2,2,i)' command sets up a 2x2 grid of plots and the 'for' loop goes through and plots in each quadrant.

for i=1:size(n,2)   
    i1=mod(i,3)+1;                 
    k      = linspace(0,n(i),n(i)+1);    
    x_eq   = k/n(i);                    
    x_ch   = (1-cos(pi*k/n(i)))/2;         
    x_asin = 0.5+asin(2.*k./n(i)-1)./pi;    
    f_eq   = interpolate_mine(x,x_eq  ,subs(f,x_eq  )); 
    f_ch   = interpolate_mine(x,x_ch  ,subs(f,x_ch  ));
    f_asin = interpolate_mine(x,x_asin,subs(f,x_asin));
    err(i,1)  = max(abs(f_exact-f_eq  ));         
    err(i,2)  = max(abs(f_exact-f_ch  ));
    err(i,3)  = max(abs(f_exact-f_asin));
    subplot(2,2,1);                                
    plot(x,f_eq,linestyle(i1,:),'linewidth',1);
    set(gca,'ylim',[min(f_exact),max(f_exact)])
    subplot(2,2,2);
    plot(x,f_ch,linestyle(i1,:),'linewidth',1);
    set(gca,'ylim',[min(f_exact),max(f_exact)])
    subplot(2,2,3);
    plot(x,f_asin,linestyle(i1,:),'linewidth',1);
    set(gca,'ylim',[min(f_exact),max(f_exact)])
end

The above segment of begins by calculating the diffent point distributions. The 'linspace' function generates linearly spaced vectors. It is similar to the colon operator ":", but gives direct control over the number of points. One the point distribution have been defined, the function 'interpolate_mine' is called for each of the three different cases. This function is explained in more detail below. The results of these interpolations are then ploted in the 2x2 array specified earlier.

In the fourth quadrant, the errors for the interpolation schemes are plotted.

subplot(2,2,4)
xlabel('N');
ylabel('error');
title('convergence');
if xlog == 1
    loglog(n,err(:,1),'k-')       
    xloc=1.25              
else
    semilogy(n,err(:,1),'k-')    
    xloc=2                          
end

The following portion adds the labels to the error plot. You can see how the position can be altered to make everything look nice.

hold on
plot(n,err(:,2),'r-')
plot(n,err(:,3),'b-')
axs=axis;
axs(1)=min(n);
axs(2)=max(n);
axis(axs);
if err(1,3) < err(end,3)     
    qshft=3
else
    qshft=0
end
q=(axs(4)/axs(3))^(1/8)           
text(xloc,q^(qshft+2)*axs(3),'equally-spaced','Color','k')
text(xloc,q^(qshft+1)*axs(3),'Chebyshev','Color','r')
text(xloc,q^(qshft+3)*axs(3),'arc sine','Color','b')

The folowing is the interpolation step which calls on the 'lagrange_mine' function.

function f=interpolate_mine(x,xvec,fvec)

n1=size(xvec,2);
n2=size(fvec,2);
if n1 ~= n2
    disp('error');
    f=zeros(size(xvec));
    return;
end
n=n1;
f=zeros(size(x));
for i = 1:n
    f=f+fvec(i).*lagrange_mine(x,xvec,i);
end
function f=interpolate_mine(x,xvec,fvec)

n1=size(xvec,2);
n2=size(fvec,2);
if n1 ~= n2
    disp('error');
    f=zeros(size(xvec));
    return;
end
n=n1;
f=zeros(size(x));
for i = 1:n
    f=f+fvec(i).*lagrange_mine(x,xvec,i);
end

The m-file can now be saved as 'cp3.m' The following are several sample outputs from the code illustrating the ways to call the function with different types of return arguments.

>> cp3

xloc =

     2


qshft =

     0


q =

   74.9894


xloc =

    1.2500


qshft =

     3


q =

    5.6234


xloc =

    1.2500


qshft =

     0


q =

    1.7783



The entire matlab script can be seen below or downloaded here (right-click to save):

function cp3
n=[1,5,10,15];                
cp3_4figs('1/(1+x^2)',n,0)
cp3_4figs('abs(x-0.5)',n,1)
cp3_4figs('sqrt(1-x^2)',n,1)


%------------------------------------------------------------

%cp3_4figs

function cp3_4figs(f,n,xlog)
figure                                 
x=linspace(0,1,1001);                
f_exact=subs(f,x);                       
linestyle=['k: ';'b: ';'g: ';'m: '];    
titles=['equally-spaced grid';...       
        'Chebyshev grid     ';...
        'Arc Sine Grid      '];
for i=1:3                             
    subplot(2,2,i);                    
    plot(x,f_exact,'y-','linewidth',3);
    xlabel('x');
    ylabel('f');
    title(titles(i,:));
    hold on
end
for i=1:size(n,2)                       
    i1=mod(i,3)+1;                       
    k      = linspace(0,n(i),n(i)+1);       
    x_eq   = k/n(i);                        
    x_ch   = (1-cos(pi*k/n(i)))/2;        
    x_asin = 0.5+asin(2.*k./n(i)-1)./pi;  
    f_eq   = interpolate_mine(x,x_eq  ,subs(f,x_eq  )); 
    f_ch   = interpolate_mine(x,x_ch  ,subs(f,x_ch  ));
    f_asin = interpolate_mine(x,x_asin,subs(f,x_asin));
    err(i,1)  = max(abs(f_exact-f_eq  ));       
    err(i,2)  = max(abs(f_exact-f_ch  ));
    err(i,3)  = max(abs(f_exact-f_asin));
    subplot(2,2,1);                                  
    plot(x,f_eq,linestyle(i1,:),'linewidth',1);
    set(gca,'ylim',[min(f_exact),max(f_exact)])
    subplot(2,2,2);
    plot(x,f_ch,linestyle(i1,:),'linewidth',1);
    set(gca,'ylim',[min(f_exact),max(f_exact)])
    subplot(2,2,3);
    plot(x,f_asin,linestyle(i1,:),'linewidth',1);
    set(gca,'ylim',[min(f_exact),max(f_exact)])
end
subplot(2,2,4)
xlabel('N');
ylabel('error');
title('convergence');
if xlog == 1
    loglog(n,err(:,1),'k-')    
    xloc=1.25                   
else
    semilogy(n,err(:,1),'k-')      
    xloc=2                       
end
hold on
plot(n,err(:,2),'r-')
plot(n,err(:,3),'b-')
axs=axis;
axs(1)=min(n);
axs(2)=max(n);
axis(axs);
if err(1,3) < err(end,3)         
    qshft=3
else
    qshft=0
end
q=(axs(4)/axs(3))^(1/8)           
text(xloc,q^(qshft+2)*axs(3),'equally-spaced','Color','k')
text(xloc,q^(qshft+1)*axs(3),'Chebyshev','Color','r')
text(xloc,q^(qshft+3)*axs(3),'arc sine','Color','b')