拉格朗日插值法¶

一种多项式插值,多项式插值的多项式是唯一的

使用$n+1$个点构建最高项次数为$n$的多项式

拉格朗日插值基函数

$$ l_k(x)=\frac{(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_j(x_k) = \begin{cases} 1 & k = j \\ 0 & k \neq j \end{cases} \qquad j = 0,1,...n $$

拉格朗日插值多项式$L_n(x)$为

$$ L_n(x)=\sum_{k=0}^{n} y_kl_k(x) $$

令函数$w_{n+1}(x)$可以求出导数$w_{n+1}^{'}(x)$

$$ \begin{array}{c} w_{n+1}(x)=(x-x_0)(x-x_1)...(x-x_n)\\ w_{n+1}^{'}(x_k)=(x_k-x_0)...(x_k-x_{k-1})(x_k-x_{k+1})...(x_k-x_n) \end{array} $$

拉格朗日插值多项式可以写成

$$ L_n(x)=\sum_{k=0}^{n} y_k \frac{w_{n+1}(x)}{(x-x_k)w_{n+1}^{'}(x_k)} $$

In [2]:
def lagrange_interpolation(points: list[list[float]]):
    
    def p(x: float):

        res = 0

        for k, _ in enumerate(points):
            
            z1 = 1      # 分子
            z2 = 1      # 分母

            for j, _ in enumerate(points):
                if j != k:
                    z1 = z1 * (x - points[j][0])
                    z2 = z2 * (points[k][0] - points[j][0])

            res += ((z1 / z2) * points[k][1])

        return res

    return p
In [4]:
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 4, 20)[1:]
y = np.log(x)

points = [[float(xi), float(yi)] for xi, yi in zip(x, y)]

p = lagrange_interpolation(points)
p_f = np.vectorize(p)

y_1 = p_f(x)

plt.plot(x, y_1, 'o', label='lagrange p')

plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.grid()
plt.show()
No description has been provided for this image