N = 50;
xN = linspace(-1,1,N+1);
% xN = cos(pi*(1+xN)/2);

x = linspace(-1,1,1000);

f = @(x) sin(x);  % good behavior
f = @(x) 1./(1+25*x.^2); % runge's phenomena
yj = f(xN);
p = 0;
for j = 0:N
    L = 1;
    for i = 0:N
        if (i~=j)
            L = L .* (x-xN(i+1))./(xN(j+1)-xN(i+1));
        end
    end    
    p = p + L*yj(j+1);
end

plot(x,f(x))
hold on
plot(x,p,'--')
plot(xN,f(xN),'o')

%% check convergence

% f = @(x) sin(x);  % good behavior
f = @(x) 1./(1+25*x.^2); % runge's phenomena

x = linspace(-1,1,10000); % for plotting
for N = 1:25
    xN = linspace(-1,1,N+1);
    xN = cos(pi*(1+xN)/2);
    yj = f(xN);
    p = 0;
    for j = 0:N
        L = 1;
        for i = 0:N
            if (i~=j)
                L = L .* (x-xN(i+1))./(xN(j+1)-xN(i+1));
            end
        end
        p = p + L*yj(j+1);
    end
    
    err(N) = max(abs(f(x)-p));
end
N = 1:N;
semilogy(N,err,'o--')
hold on
% semilogy(N,(max(x)-min(x)).^(N+1)./factorial(N+1),'--')

legend('Interpolation error','Error bound');

