拉格朗日插值
拉格朗日插值基函数
拉格朗日插值基函数 l i ( x ) l_i(x) li(x),要求满足 l i ( x j ) = δ i j l_i(x_j)=\delta_{ij} li(xj)=δij。
那么插值多项式就为 p ( x ) = ∑ i = 0 n y i l i ( x ) p(x)=\sum_{i=0}^ny_il_i(x) p(x)=i=0∑nyili(x)
基函数具体形式可以是:
l k ( x ) = ( x − x 0 ) ( x − x 1 ) . . . ( x − x k − 1 ) ( x − x k + 1 ) . . . ( x − x n ) ( x k − x 0 ) ( x k − x 1 ) . . . ( x k − x k − 1 ) ( x k − x k + 1 ) . . . ( x k − x n ) l_k(x)=\dfrac{(x-x_0)(x-x_1)...(x-x_{k-1})(x-x_{k+1})...(x-x_n)}{(x_k-x_0)(x_k-x_1)...(x_k-x_{k-1})(x_k-x_{k+1})...(x_k-x_n)} lk(x)=(xk−x0)(xk−x1)...(xk−xk−1)(xk−xk+1)...(xk−xn)(x−x0)(x−x1)...(x−xk−1)(x−xk+1)...(x−xn)
当 n = 1 n=1 n=1时,就变成了上一篇里推出的线性插值的表达式。
代码示例
对函数 f ( x ) = 1 1 + x 2 f(x)=\dfrac{1}{1+x^2} f(x)=1+x21,在区间 [ − 5 , 5 ] [-5,5] [−5,5]上等距取点,进行拉格朗日插值。
import numpy as np
import matplotlib.pyplot as plt
# 取数据点
n = 5 # 点数 x0 x1 x2 x3 x4
xdata = np.linspace(-5, 5, n).reshape((-1,1))
ydata = 1 / (1 + xdata ** 2)
# 计算基函数
def l(k, x, xdata, n):
below = 1
up = 1
for i in range(n):
if i != k:
below = below * (xdata[k] - xdata[i])
up = up * (x - xdata[i])
return up / below
x_plot = np.linspace(-5, 5, 500)
l_matrix = np.zeros((len(x_plot), n))
for i in range(n):
l_matrix[:,i] = l(i, x_plot, xdata, n)
p1, = plt.plot(x_plot, l_matrix@ydata)
p2, = plt.plot(x_plot, 1/(1 + x_plot**2))
p3 = plt.scatter(xdata, ydata)
plt.legend([p1, p2], ["p(x)", "f(x)"])
plt.show()
当
n
=
5
n=5
n=5时,得到图像为:
当
n
=
10
n=10
n=10时,图像变为:
当
n
=
15
n=15
n=15时,图像为:
可以看到,n很大时,插值函数反而可能波动极大,类似于机器学习的过拟合。