Let us interpolate the Runge function on $[-1,+1]$ $$ f(x) = \frac{1}{1 + 16 x^2} $$ using the Barycentric formula $$ p(x) = \frac{ \sum_{i=0}^N \frac{w_i}{x - x_i} f_i }{ \sum_{i=0}^N \frac{w_i}{x - x_i} } $$ where the weight $w_i$ is given by $$ w_i = \frac{1}{\prod_{j=0,j\ne i}^N (x_i - x_j)} $$
import numpy as np
from matplotlib import pyplot as plt
def fun(x):
f = 1.0/(1.0+16.0*x**2)
return f
def LagrangeInterpolation(X,Y,x):
nx = np.size(x)
nX = np.size(X)
w = np.ones(nX)
for i in range(nX):
for j in range(nX):
if i != j:
w[i] = w[i]/(X[i]-X[j])
num= np.zeros(nx)
den= np.zeros(nx)
eps=1.0e-14
for i in range(nX):
num = num + Y[i]*w[i]/((x-X[i])+eps)
den = den + w[i]/((x-X[i])+eps)
f = num/den
return f
xmin, xmax = -1.0, +1.0
N = 20
We first interpolate on uniformly spaced points.
X = np.linspace(xmin,xmax,20)
Y = fun(X)
x = np.linspace(xmin,xmax,100)
fi = LagrangeInterpolation(X,Y,x)
fe = fun(x)
plt.plot(x,fe,'b--',x,fi,'r-',X,Y,'o')
plt.legend(("True function","Interpolation","Data"),'upper center')
<matplotlib.legend.Legend at 0x10f92e350>
Next, we interpolate on Chebyshev points.
X = cos(np.linspace(0.0,pi,N))
Y = fun(X)
x = np.linspace(xmin,xmax,100)
fi = LagrangeInterpolation(X,Y,x)
fe = fun(x)
plt.plot(x,fe,'b--',x,fi,'r-',X,Y,'o')
plt.legend(("True function","Interpolation","Data"),'upper right')
<matplotlib.legend.Legend at 0x10ecf3a10>