maxdegree = 40;
xp = linspace(-5,5,1000); % fine grid
f = @(x)(x+sin(3*x)).*exp(-(x.^2)/6); % true function value on a fine grid
err_poly = zeros(maxdegree+1,1); 
err_pwpoly = zeros(maxdegree,1);

% continuous polynomial approximation
for n=0:maxdegree
    x = linspace(-5,5,n+1);
    
%     % Chebyshev points on [-5,5]
%     x = linspace(-1,1,n+1);
%     x = cos(pi*(1+x)/2)*5; 
        
    p = polyfit(x,f(x),n); % MATLAB's polynomial interpolation routine
    err_poly(n+1) = max(abs(polyval(p,xp)-f(xp)));
    figure(1), clf
    plot(xp,f(xp), 'b-','linewidth',2), hold on
    plot(xp,polyval(p,xp), 'r--','linewidth',2)
    plot(x,f(x), 'r.','markersize',30)
    axis equal, axis([-5 5 -3 3])
    title(sprintf('Continuous Polynomial Interpolant of Degree %d',n))%,'fontsize',20)
    pause(.5)
% drawnow
end

pause

% piecewise linear interpolation
for n=1:maxdegree
    x = linspace(-5,5,n+1)';    
    pxx = interp1(x,f(x),xp,'linear'); % MATLAB's piecewise linear interpolation routine
    err_pwpoly(n) = max(abs(pxx-f(xp)));
    figure(2), clf
    plot(xp,f(xp), 'b-','linewidth',2), hold on
    plot(xp,pxx, 'r--','linewidth',2)
    plot(x,f(x), 'r.','markersize',30)
    axis equal, axis([-5 5 -3 3])
    title(sprintf('Piecewise Polynomial Interpolant with %d Intervals',n))%,'fontsize',20)
    pause(.5)
%     drawnow
end

% compare errors
figure(3), clf
semilogy([0:maxdegree], err_poly, 'b-','linewidth', 2), hold on
semilogy([1:maxdegree], err_pwpoly, 'r--','linewidth', 2)
legend('Continuous Polynomial', 'Piecewise Linear Polynomials')
title('Maximum Error in Interpolants')%, 'fontsize', 20)
xlabel('Number of Data Points, n')%, 'fontsize', 18)
ylabel('Maximum Error on [-5, 5]')%, 'fontsize', 18)