% % Mfile name % mtl_inp_sim_ndd.m % Language: Matlab 7.4.0 (R2007a) % Revised: % July 7, 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 Newton Divided Difference method of interpolation % using Matlab. % Keywords % Interpolation % Newton Divided Difference % Clearing all data, variable names, and files from any other source and % clearing the command window after each succesive run of the program. clc clf clear all % Inputs: % This is the only place in the program where the user makes the changes % based on their wishes. % Enter arrays of x and y data and the value of x at which y is desired. % Array of x-data x=[10 0 20 15 30 22.5]; % Array of y-data y=[227.04 0 517.35 362.78 901.67 602.97]; % Value of x at which y is desired xdesired = 16; % ************************************************************************* disp(sprintf('\n\nNewton Divided Difference Method of Interpolation')) disp(sprintf('\nUniversity of South Florida')) disp(sprintf('United States of America')) disp(sprintf('kaw@eng.usf.edu')) disp(sprintf('\nNOTE: This worksheet illustrates the use of Matlab to illustrate')) disp(sprintf('the concepts of the Newton Divided Difference method of interpolation.')) disp(sprintf('\n**************************Introduction***************************')) disp(sprintf('\nThe following simulation uses Matlab to illustrate the Newton Divided')) disp(sprintf('Difference Method of interpolation. Given n data points of y vs x, it')) disp(sprintf('is required to find the value of y at a particular value of x using')) disp(sprintf('first, second, or third order interpolation. It is necessary to first')) disp(sprintf('pick the needed data points and use those specific points to interpolate')) disp(sprintf('the data. This method differs from the Direct Method of interpolation')) disp(sprintf('by first finding the value of the function at x0, and then solving for')) disp(sprintf('the slope by using the other known points that bracked the value of')) disp(sprintf('"xdesired". If higher order interpolations are required, the coefficients')) disp(sprintf('for the polynomial functions can be calculated recursively. Once the')) disp(sprintf('coefficients are found, the value of f(x) can be approximated at the')) disp(sprintf('value of "xdesired".')) disp(sprintf('\n\n***************************Input Data******************************')) fprintf('\n'); disp('x array of data:') x disp('y array of data:') y disp(sprintf('The value of x at which y is desired, xdesired = %g',xdesired)) disp(sprintf('\n***************************Simulation******************************')) % Determining whether or not "xdesired" is a valid point to ask for given % the range of the x data. high = max(x); low = min(x); if xdesired > high disp(sprintf('\nThe value entered for "xdesired" is too high. Please pick a smaller value')) disp(sprintf('that falls within the range of x data.')) break; elseif xdesired < low disp(sprintf('\nThe value entered for "xdesired" is too low. Please pick a larger value')) disp(sprintf('that falls within the range of x data.')) break; else disp(sprintf('\nThe value for "xdesired" falls within the given range of xdata. The')) disp(sprintf('simulation will now commence.')); % The following considers the x and y data and selects the two closest points to xdesired % that also bracket it. n = numel(x); comp = abs(x-xdesired); c=min(comp); for i=1:n if comp(i)==c; ci=i; end end if x(ci) < xdesired q=1; for i=1:n if x(i) > xdesired ne(q)=x(i); q=q+1; end end b=min(ne); for i=1:n if x(i)==b bi=i; end end end if x(ci) > xdesired q=1; for i=1:n if x(i) < xdesired ne(q)=x(i); q=q+1; end end b=max(ne); for i=1:n if x(i)==b bi=i; end end end % If more than two values are needed, the following selects the subsequent values and puts % them into a matrix, preserving the orginal data order. for i = 1:n A(i,2)=i; A(i,1)=comp(i); end A=sortrows(A,1); for i=1:n A(i,3)=i; end A=sortrows(A,2); d=A(1:n,3); if d(bi)~=2 temp=d(bi); d(bi)=1; for i=1:n if i ~= bi & i ~= ci & d(i) <= temp d(i)=d(i)+1; end d(ci)=1; end end %%%%%%%%% LINEAR INTERPOLATION %%%%%%%%% % Pick two data points datapoints=2; p=1; for i=1:n if d(i) <= datapoints xdata(p)=x(i); ydata(p)=y(i); p=p+1; end end % Calculating coefficients of Newton's Divided difference polynomial b0=sym('b0'); b1=sym('b1'); z=sym('z'); b0=ydata(1); b1=(ydata(2)-ydata(1))/(xdata(2)-xdata(1)); fl=b0 +b1*(z-xdata(1)); fxdesired=subs(fl,z,xdesired); fprev=fxdesired; % Displaying the outputs: disp(sprintf('\nLINEAR INTERPOLATION:')) disp(sprintf('\nx data chosen: x1 = %g, x2 = %g',xdata(1),xdata(2))) disp(sprintf('\ny data chosen: y1 = %g, y2 = %g',ydata(1),ydata(2))) % Displaying the determined coefficients b0,b1. disp(sprintf('\nCoefficients of the linear interpolation, b0 = %g, b1 = %g',b0,b1)) % Using concactenation to properly display the final function in the % command window. fprintf('\n'); str1 = ['Final Function: f1(x) = ',num2str(b0)]; if b1 > 0 str2 = [' + ',num2str(b1),'(x']; else str2 = [' ',num2str(b1),'(x']; end if xdata(1) > 0 str3 = [' - ',num2str(xdata(1)),')']; else str3 = [' + ',num2str(xdata(1)),')']; end % Putting all the strings together. finalstr = [str1,str2,str3]; disp(finalstr); % Displaying the final value of the function at xdesired. disp(sprintf('\nFinal value at xdesired = %g, f(%g) = %g',xdesired,xdesired,fxdesired)) % Creating inline function for plotting. func = inline([num2str(b0),'+',num2str(b1),'*(z-',num2str(xdata(1)),')']); % Figures displaying the interpolation and data points. axis on figure(1) subplot(2,1,1) fplot(func,[min(xdata),max(xdata)]) hold on title('Linear Interpolation (Data Points Used)','Fontweight','bold') xlabel('x data','Fontweight','bold'); ylabel('y data','Fontweight','bold'); plot(xdata,ydata,'ro','MarkerSize',8','MarkerFaceColor',[1,0,0]); plot(xdesired,fxdesired,'kx','Linewidth',2,'MarkerSize',12'); % Creating the second figure. axis on subplot(2,1,2) fplot(func,[min(xdata),max(xdata)]) hold on title('Linear Interpolation (Full Data Set)','Fontweight','bold') xlabel('x data','Fontweight','bold'); ylabel('y data','Fontweight','bold'); plot(x,y,'ro','MarkerSize',8','MarkerFaceColor',[1,0,0]) plot(xdesired,fxdesired,'kx','Linewidth',2,'MarkerSize',12') xlim([min(x) max(x)]) ylim([min(y) max(y)]) hold off %%%%%%%%% QUADRATIC INTERPOLATION %%%%%%%%% % Pick three data points datapoints=3; p=1; for i=1:n if d(i) <= datapoints xdata(p)=x(i); ydata(p)=y(i); p=p+1; end end % Calculating coefficients of Newton's Divided difference polynomial b0=sym('b0'); b1=sym('b1'); b2=sym('b2'); z=sym('z'); b0=ydata(1); b1=(ydata(2)-ydata(1))/(xdata(2)-xdata(1)); b2=((ydata(3)-ydata(2))/(xdata(3)-xdata(2))-(ydata(2)-ydata(1))/(xdata(2)-xdata(1)))/(xdata(3)-xdata(1)); fq=b0 +b1*(z-xdata(1)) + b2*(z-xdata(1))*(z-xdata(2)); fxdesired=subs(fq,z,xdesired); fnew=fxdesired; ea=abs((fnew-fprev)/fnew*100); if ea >= 5 sd=0; else sd=floor(2-log10(abs(ea)/0.5)); end % Displaying the outputs: disp('---------------------------------------------------------------------') disp(sprintf('\nQUADRATIC INTERPOLATION:')) disp(sprintf('\nx data chosen: x1 = %g, x2 = %g, x3 = %g',xdata(1),xdata(2),xdata(3))) disp(sprintf('\ny data chosen: y1 = %g, y2 = %g, y3 = %g',ydata(1),ydata(2),ydata(3))) % Displaying the determined coefficients b0, b1 and b2. disp(sprintf('\nCoefficients of the quadratic interpolation: b0 = %g, b1 = %g, b2 = %g',b0,b1,b2)) % Using concactenation to properly display the final function in the % command window. fprintf('\n') str1 = ['Final Function: f2(x) = ',num2str(b0)]; if b1 > 0 str2 = [' + ',num2str(b1),'(x']; else str2 = [' ',num2str(b1),'(x']; end if xdata(1) > 0 str3 = [' - ',num2str(xdata(1)),')']; str5 = [str3,'(x']; else str3 = [' + ',num2str(xdata(1)),')']; str5 = [str3,'(x']; end if b2 > 0 str4 = [' + ',num2str(b2),'(x']; else str4 = [' ',num2str(b2),'(x']; end if xdata(2) > 0 str6 = [' - ',num2str(xdata(2)),')']; else str6 = [' ',num2str(xdata(2)),')']; end % Putting all the strings together. finalstr = [str1,str2,str3,str4,str5,str6]; disp(finalstr); % Displaying the final value of the function at xdesired. disp(sprintf('\nFinal value at xdesired = %g, f(%g) = %g',xdesired,xdesired,fxdesired)) % Displaying the number of significant digits that can be taken and % absolute relative approximate error. disp(sprintf('\nAbsolute relative approximate error, abrae = %g%%',ea)) disp(sprintf('\nNumber of significant digits at least correct, sig_dig = %g',sd)) % Creating the inline function for plotting to take place. func1 = [num2str(b0),'+',num2str(b1),'*(z-',num2str(xdata(1)),')+',num2str(b2)]; func2 = ['*(z-',num2str(xdata(1)),')*(z-',num2str(xdata(2)),')']; func = inline([func1,func2]); % Creating the plots for quadratic interpolation. axis on figure(2) subplot(2,1,1) fplot(func,[min(xdata),max(xdata)]) title('Quadratic Interpolation (Data Points Used)','Fontweight','bold'); xlabel('x data','Fontweight','bold'); ylabel('y data','Fontweight','bold'); hold on plot(xdata,ydata,'ro','MarkerSize',8','MarkerFaceColor',[1,0,0]) plot(xdesired,fxdesired,'kx','Linewidth',2,'MarkerSize',12') % Creating the second figure for the Quadratic interpolation. axis on subplot(2,1,2) fplot(func,[min(xdata),max(xdata)]) title('Quadratic Interpolation (Full data set)','Fontweight','bold') xlabel('x data','Fontweight','bold'); ylabel('y data','Fontweight','bold'); hold on plot(x,y,'ro','MarkerSize',8','MarkerFaceColor',[1,0,0]) plot(xdesired,fxdesired,'kx','Linewidth',2,'MarkerSize',12') xlim([min(x) max(x)]) ylim([min(y) max(y)]) hold off fprev=fnew; %%%%%%%%% CUBIC INTERPOLATION %%%%%%%%% % Pick four data points datapoints=4; p=1; for i=1:n if d(i) <= datapoints xdata(p)=x(i); ydata(p)=y(i); p=p+1; end end % Calculating coefficients of Newton's Divided difference polynomial b0=sym('b0'); b1=sym('b1'); b2=sym('b2'); b3=sym('b3'); z=sym('z'); b0=ydata(1); b1=(ydata(2)-ydata(1))/(xdata(2)-xdata(1)); b2=((ydata(3)-ydata(2))/(xdata(3)-xdata(2))-(ydata(2)-ydata(1))/(xdata(2)-xdata(1)))/(xdata(3)-xdata(1)); b3=(((ydata(4)-ydata(3))/(xdata(4)-xdata(3))-(ydata(3)-ydata(2))/(xdata(3)-xdata(2)))/(xdata(4)-xdata(2))-b2)/(xdata(4)-xdata(1)); fc=b0 +b1*(z-xdata(1)) + b2*(z-xdata(1))*(z-xdata(2)) + b3*(z-xdata(1))*(z-xdata(2))*(z-xdata(3)); fxdesired=subs(fc,z,xdesired); fnew=fxdesired; ea=abs((fnew-fprev)/fnew*100); if ea >= 5 sd1=0; else sd1=floor(2-log10(abs(ea)/0.5)); end % Displaying the results for Cubic Interpolation. disp('---------------------------------------------------------------------') disp(sprintf('\nCUBIC INTERPOLATION:')) disp(sprintf('\nx data chosen: x1 = %g, x2 = %g, x3 = %g, x4 = %g',xdata(1),xdata(2),xdata(3),xdata(4))) disp(sprintf('\ny data chosen: y1 = %g, y2 = %g, y3 = %g, y4 = %g',ydata(1),ydata(2),ydata(3),ydata(4))) % Displaying the determined coefficients b0,b1,b2,b3. disp(sprintf('\nCoefficients of the cubic interpolation: b0 = %g, b1 = %g, b2 = %g, b3 = %g',b0,b1,b2,b3)) % Using concactenation to properly display the final function in the % command window. fprintf('\n') str1 = ['Final Function: f3(x) = ',num2str(b0)]; if b1 > 0 str2 = ['+',num2str(b1),'(x']; else str2 = [' ',num2str(b1),'(x']; end if xdata(1) > 0 str3 = ['-',num2str(xdata(1)),')']; str5 = [str3,'(x']; else str3 = ['+',num2str(xdata(1)),')']; str5 = [str3,'(x']; end if b2 > 0 str4 = ['+',num2str(b2),'(x']; else str4 = [' ',num2str(b2),'(x']; end if xdata(2) > 0 str6 = ['-',num2str(xdata(2)),')']; str8 = [str5,str6,'(x']; else str6 = [' ',num2str(xdata(2)),')']; str8 = [str5,str6,'(x']; end if b3 > 0 str7 = ['+',num2str(b3),'(x']; else str7 = [' ',num2str(b3),'(x']; end if xdata(3) > 0 str9 = ['-',num2str(xdata(3)),')']; else str9 = [' ',num2str(xdata(3)),')']; end % Putting it all together. finalstr = [str1,str2,str3,str4,str5,str6,str7,str8,str9]; disp(finalstr); % Displaying the value of the function at xdesired. disp(sprintf('\nFunction value at xdesired = %g, f(%g) = %g',xdesired,xdesired,fxdesired)) % Displaying the number of significant digits that can be taken and % absolute relative approximate error. disp(sprintf('\nAbsolute relative approximate error, abrae = %g%%',ea)) disp(sprintf('\nNumber of significant digits at least correct, sig_dig = %g',sd1)) % Creating the inline function func1 = [num2str(b0),'+',num2str(b1),'*(z-',num2str(xdata(1)),')+',num2str(b2),'*(z-',num2str(xdata(1)),')*(z-']; func2 = [num2str(xdata(2)),')+',num2str(b3),'*(z-',num2str(xdata(1)),')*(z-',num2str(xdata(2)),')*(z-',num2str(xdata(3)),')']; func = inline([func1,func2]); % Creating the plots for the Cubic Interpolation. axis on figure(3) subplot(2,1,1) fplot(func,[min(xdata),max(xdata)]) title('Cubic Interpolation (Data Points Used)','Fontweight','bold') xlabel('x data','Fontweight','bold'); ylabel('y data','Fontweight','bold'); hold on plot(xdata,ydata,'ro','MarkerSize',8','MarkerFaceColor',[1,0,0]) plot(xdesired,fxdesired,'kx','Linewidth',2,'MarkerSize',12') hold off % Creating the second plot for Cubic Interpolation axis on subplot(2,1,2) fplot(func,[min(xdata),max(xdata)]) title('Cubic Interpolation (Full Data Set)','Fontweight','bold') xlabel('x data','Fontweight','bold'); ylabel('y data','Fontweight','bold'); hold on plot(x,y,'ro','MarkerSize',8','MarkerFaceColor',[1,0,0]) plot(xdesired,fxdesired,'kx','Linewidth',2,'MarkerSize',12') xlim([min(x) max(x)]) ylim([min(y) max(y)]) hold off end