Barycentric Lagrange interpolation¶

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)}$$

In [13]:
import numpy as np
from matplotlib import pyplot as plt

In [14]:
def fun(x):
f = 1.0/(1.0+16.0*x**2)
return f

In [15]:
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

In [16]:
xmin, xmax = -1.0, +1.0
N = 20


We first interpolate on uniformly spaced points.

In [27]:
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')

Out[27]:
<matplotlib.legend.Legend at 0x10f92e350>

Next, we interpolate on Chebyshev points.

In [26]:
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')

Out[26]:
<matplotlib.legend.Legend at 0x10ecf3a10>