拉格朗日插值数学原理
- 线性插值
对于一个函数f(x)f(x)f(x)在区间[a,b][a,b][a,b]上有定义,且已知在点a<=x0<x1<⋅⋅⋅<xn<=ba<=x_0<x_1<···<x_n<=ba<=x0<x1<⋅⋅⋅<xn<=b上的值y0,y1,⋅⋅⋅,yny_0,y_1,···,y_ny0,y1,⋅⋅⋅,yn. 若存在一个函数P(x)=a0+a1x+⋅⋅⋅+anxP(x)=a_0+a_1x+···+a_nxP(x)=a0+a1x+⋅⋅⋅+anx.使得:
P(xi)=yi
P(x_i) = y_i
P(xi)=yi
我们就说P(x)为f(x)P(x)为f(x)P(x)为f(x)的插值函数。对于如何求出这个插值函数,我们有多种方法,我们先设n=1n=1n=1时的简单情况,假定给定区间[xk,xk+1][x_k,x_{k+1}][xk,xk+1],及插值端点值yk=f(xk),yk+1=f(xk+1)y_k=f(x_k),y_{k+1}=f(x_{k+1})yk=f(xk),yk+1=f(xk+1),要求线性多项式L1(x)L_1(x)L1(x)满足:
L1(xk)=yk,L1(xk+1)=yk+1
L_1(x_k)=y_k,L_1(x_{k+1})=y_{k+1}
L1(xk)=yk,L1(xk+1)=yk+1
上式的几何意义是通过两点(xk,yk),(xk+1,yk+1)(x_k,y_k),(x_{k+1},y_{k+1})(xk,yk),(xk+1,yk+1)的直线,用公式表达它们的几何意义:
L1(x)=yk+yk+1−ykxk+1−xk(x−xk)(点斜式)L1(x)=ykxk+1−xxk1−xk+yk+1x−xkxk+1−xk(两点式)
L_1(x) = y_k+\frac{y_{k+1}-y_k}{x_{k+1}-x_k}(x-x_k) (点斜式) \\
L_1(x) = y_k\frac{x_{k+1}-x}{x_{k_1}-x_k}+y_{k+1}\frac{x-x_k}{x_{k+1}-x_k} (两点式)
L1(x)=yk+xk+1−xkyk+1−yk(x−xk)(点斜式)L1(x)=ykxk1−xkxk+1−x+yk+1xk+1−xkx−xk(两点式)
由以上两式可以看出L1(1x)L_1(1x)L1(1x)是由两个线性函数:
lk(x)=yk+1−ykxk+1−xk,lk+1=x−xkxk+1−xk
l_k(x)=\frac{y_{k+1}-y_k}{x_{k+1}-x_k},l_{k+1}=\frac{x-x_k}{x_{k+1}-x_k}
lk(x)=xk+1−xkyk+1−yk,lk+1=xk+1−xkx−xk
线性组合得到的,其系数分别为yky_kyk及yk+1y_{k+1}yk+1,即:
L1(x)=y1lk(x)+yk+1lk+1(x).
L_1(x)=y_1l_k(x)+y_{k+1}l_{k+1}(x).
L1(x)=y1lk(x)+yk+1lk+1(x).
我们称lk(x)l_k(x)lk(x)及kk+1k_{k+1}kk+1为线性插值基函数,L(x)L(x)L(x)为一次插值多项式,同理当n=2n=2n=2时我们也可以构造出二次插值多项式,此外我们可以把它推广到nnn,所以就得到了nnn次插值多项式,如下公式;
lk(x)=(x−x0)⋅⋅⋅(x−xk−1)(x−xk+1)⋅⋅⋅(x−xn)(xk−x0)⋅⋅⋅(xk−xk−1)(xk−xk+1)⋅⋅⋅(xk−xn)Ln(x)=∑k=1nyklk(x)Ln(xj)∑k=1nyklk(xj)yj,j=0,1,⋅⋅⋅,n.(1)
l_k(x) = \frac{(x-x_0)···(x-x_{k-1})(x-x_{k+1})···(x-x_{n})}{(x_k-x_0)···(x_k-x_{k-1})(x_k-x_{k+1})···(x_k-x_{n})} \\
L_n(x)=\sum_{k=1}^ny_kl_k(x)\\
L_n(x_j)\sum_{k=1}^ny_kl_k(x_j) y_j , j= 0,1,···,n. (1)
lk(x)=(xk−x0)⋅⋅⋅(xk−xk−1)(xk−xk+1)⋅⋅⋅(xk−xn)(x−x0)⋅⋅⋅(x−xk−1)(x−xk+1)⋅⋅⋅(x−xn)Ln(x)=k=1∑nyklk(x)Ln(xj)k=1∑nyklk(xj)yj,j=0,1,⋅⋅⋅,n.(1)
我们得到的(1)式被称为拉格朗日插值多项式。
算法实现
import matplotlib.pyplot as plt
import numpy as np
from numpy import poly1d
from scipy._lib.six import xrange
# 自己实现的拉格朗日插值
def h(x,y,a):
if len(x)!= len(y):
print('向量长度必须相等!')
exit(-1)
ans=0.0
for i in range(len(y)):
temp = 1.0
t = y[i]
#这个循环算出一个插值基函数值
for j in range(len(y)):
if i !=j:
temp *= (a-x[j])/(x[i]-x[j])
t *= temp #得出一个插值多项式
ans +=t
return ans
def lagrange(x,w):
M = len(x)
p = poly1d(0.0)
for j in xrange(M):
pt = poly1d(w[j])
print(pt)
for k in xrange(M):
if k == j:
continue
fac = x[j] - x[k]
pt *= poly1d([1.0, -x[k]]) / fac
p += pt
return p
origin_x = np.linspace(-4, 4, 50)
origin_y = fun(origin_x)
x = np.linspace(-4, 4, 9)
y = fun(x)
f = lagrange(x,y)
Inter_x = np.linspace(-4, 4, 50)
NormlagInter_y = [ f(a) for a in Inter_x ]
mylagInter_y = [neton_inter(x, y, a) for a in Inter_x]
plt.figure(figsize=[15, 10])
ax = plt.subplot(1, 3, 1)
ax.set_title("orgin")
plt.plot(origin_x, origin_y, c='red')
ax = plt.subplot(1,3,2)
ax.set_title("NormlagInter")
plt.plot(Inter_x,NormlagInter_y)
ax = plt.subplot(1,3,3)
ax.set_title('mylagInter')
plt.plot(Inter_x,mylagInter_y,c='blue')
plt.show()
本文深入探讨了拉格朗日插值法的基本原理,包括线性插值和高次插值的数学推导过程,展示了如何利用Python实现拉格朗日插值,并通过实例比较了不同插值方法的效果。
447

被折叠的 条评论
为什么被折叠?



