使用Python求牛顿插值多项式及其差商表(附加一个拉格朗日插值多项式)
闲话不多说,直接上代码。
import numpy as np from sympy import * # 定义一个求差商表的函数,使用递归求解差商表,返回值是差商的值 # x是数组,表示样本点的x # f是数组,表示样本点的函数值f(x) # start是int类型,表示x数组的起始下标, # end是int类型,表示x数组的结束下标, # res是数组类型,表示差商表,对角线以下为各阶差商表 def cs(x,f,start,end,res): # 当x中只有两个元素的时候,结束递归 if((end-start)==1): # 将一阶差商填入差商表 res[end-1][end-start-1]=(f[end]-f[start])/(x[end]-x[start]) # 返回差商 return res[end-1][end-start-1] # 当x中元素个数大于2时,根据公式递归调用此函数求差商,并将差商填入差商表 res[end-1][end-start-1]=(cs(x,f,start+1,end,res)-cs(x,f,start,end-1,res))/(x[end]-x[start]) # 返回差商 return res[end-1][end-start-1] # 定义一个求牛顿插值多项式的函数 # x是数组,表示样本点的x # f是数组,表示样本点的函数值f(x) def Newton(x,f): res = np.ones([x.size - 1, x.size - 1])*np.inf # 初始化差商表骨架结构 cs(x, f, 0, x.size - 1, res) #调用差商表函数给差商表填值,对角线及以下才是差商表的值 X=symbols("x") #定义x变量 y=f[0] #初始化牛顿插值多项式,它的第一项是常数项,正好是f[0] for i in range(x.size-1): temp=1 #临时变量,保存 f[x0,x1,...,xn]*(x-x1)(x-x2)...(x-xn-1) for j in range(i+1): temp=temp*(X-x[j]) #(x-x1)(x-x2)...(x-xn-1) temp=res[i,i]*temp #将差商表对角线元素作为系数 y=y+temp #将temp添加到多项式中 # 返回牛顿插值多项式 return y if __name__=="__main__": # 样本点 x=np.array([2.0,2.1,2.2,2.3,2.4]) f=np.array([1.414214,1.449138,1.483240,1.516575,1.549193]) ##### 可以直接得到差商表 res = np.ones([x.size - 1, x.size - 1]) * np.inf # 初始化差商表骨架结构 # 调用差商表函数 cs(x,f,0,x.size-1,res) print(res) #### 也可以直接得到牛顿插值多项式 X=symbols("x") #定义自变量x y=Newton(x,f) #调用函数得到牛顿插值多项式,类型是print("N(x)=",y) # 给自变量x赋值,求出函数近似值 print(y.evalf(subs={X:2.15})) #求给定自变量x值时函数f(x)的值 | 将表达式转化为函数
得到的差商表:
牛顿插值多项式(比较长,就截取了部分):
拉格朗日插值多项式代码(使用方法很简单,和牛顿插值多项式一样):
#拉格朗日插值法 def L(x,f): X=symbols("x") m=x.size #x个数 L=0 for i in range(m): temp=1 for j in range(m): if(i!=j): temp=temp*((X-x[j])/(x[i]-x[j])) L=L+temp*f[i] return L
各位大哥点个赞呐(卑微)