% Perform Hermite Interpolation on function func % evaluated at points x(1:n) % function [c,err,NewtonTable] = HermiteInterp(func,x,plt) % % Inputs: % func = name of function to be interpolated, returns f(x) and f'(x) % x = array of points at which to perform interpolation % plt = 1 to produce graphics, 0 not to % % Outputs: % c = coefficients of interpolation polynomial % err = maximum difference |p(x)-func(x)| at % 1000 equally spaced points in interpolation interval % NewtonTable = divided difference table (see page 367 of text) % if plot = 1, plot of func(x), p(x) at 1000 equally space points % plot of |func(x)-p(x)| at 1000 equally space points % function [c,err,NewtonTable] = HermiteInterp(func,x,plt) xmin = min(x); xmax = max(x); xx = xmin:(xmax-xmin)/999:xmax; n = 2*length(x); x = reshape(x,length(x),1); % % Compute Divided Difference Table NewtonTable = zeros(n,n+1); NewtonTableErr = zeros(n,n+1); NewtonTable(1:n,1) = kron(reshape(x,n/2,1),[1;1]); [fval,fpval] = eval([func,'(x)']); NewtonTable(1:n,2) = kron(fval,[1;1]); NewtonTableErr(1:n,2) = eps*abs(NewtonTable(1:n,2)); NewtonTable(1:2:n-1,3) = fpval; NewtonTable(2:2:n-2,3) = (fval(2:n/2)-fval(1:n/2-1)) ./ (x(2:n/2)-x(1:n/2-1)); NewtonTableErr(1:n,3) = eps*abs(NewtonTable(1:n,3)); for j=2:n-1, NewtonTable(1:n-j,j+2) = ... (NewtonTable(2:n-j+1,j+1) - NewtonTable(1:n-j,j+1)) ./ ... (NewtonTable(j+1:n,1) - NewtonTable(1:n-j,1)); NewtonTableErr(1:n-j,j+2) = ... ( eps*abs(NewtonTable(2:n-j+1,j+1) - NewtonTable(1:n-j,j+1)) + ... NewtonTableErr(2:n-j+1,j+1) + NewtonTableErr(1:n-j,j+1) ) ./ ... (NewtonTable(j+1:n,1) - NewtonTable(1:n-j,1)); end c = NewtonTable(1,2:n+1); cbnd = NewtonTableErr(1,2:n+1); % p = c(n)*ones(size(xx)); pbnd1 = eps*abs(p); pbnd2 = cbnd(n); for i = n/2:-1:2, p = (p.*(xx-x(i)) + c(2*i-1)).*(xx-x(i-1)) + c(2*i-2); pbnd1 = (pbnd1.*abs(xx-x(i)) + eps*abs(c(2*i-1))).*abs(xx-x(i-1)) + eps*abs(c(2*i-2)); pbnd2 = (pbnd2.*abs(xx-x(i)) + cbnd(2*i-1)).*abs(xx-x(i-1)) + cbnd(2*i-2); end p = p.*(xx-x(1)) + c(1); pbnd1 = pbnd1.*abs(xx-x(1)) + eps*abs(c(1)); pbnd2 = pbnd2.*abs(xx-x(1)) + cbnd(1); [fxx,fxxp] = eval([func,'(xx)']); [fx,fxp] = eval([func,'(x)']); err = max(abs(fxx-p)); % % Plot if (plt == 1) figure(1) hold off, clf plot(xx,fxx,'b.',xx,p,'r',x,fx,'bx') grid title('f(x) = blue, (xi,f(xi)) = blue x, p(x) = red') xlabel(['Maximum error = ',num2str(err)]) figure(2) hold off, clf % semilogy(xx,abs(fxx-p),'b',xx,pbnd1,'r.',xx,pbnd2,'g.'), grid semilogy(xx,abs(fxx-p),'b',xx,pbnd1,'r.'), grid title('|f(x) - p(x)| = blue, roundoff in p(x) = red') % figure(3) % semilogy((1:n),abs(c),'bx',(1:n),cbnd,'rx'), grid % title('coeff = blue, bound on coeff = red') end