Files
CalWay_Python/按方法整理/插值-线性-抛物线-拉格朗日多项式.py
2025-06-16 20:44:29 +08:00

80 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import math
# 获取与待求x最接近的两个点
def GetClosestTwo(x,list_x):
for i in range(0, len(list_x)):
if x < list_x[i]:
return i-1, i
return len(list_x)-2, len(list_x)-1
# 获取与待求x最接近的三个点
def GetClosestThree(x,list_x):
if x < list_x[1]:
return 0, 1, 2
for i in range(3, len(list_x)):
if x < list_x[i]:
return i-2, i-1, i
return len(list_x)-3, len(list_x)-2, len(list_x)-1
# 线性插值余项计算
def LinearRegression(x,list_x,FxDiff_n):
i, j = GetClosestTwo(x,list_x)
ks = max([abs(FxDiff_n(list_x[i],2)), abs(FxDiff_n(list_x[j],2))])
omg = (x-list_x[i])*(x-list_x[j])
return abs(ks*omg/2)
# 抛物线插值余项计算
def ParabolaRegression(x,list_x,FxDiff_n):
i, j, k = GetClosestThree(x,list_x)
ks = max([abs(FxDiff_n(list_x[i],3)), abs(FxDiff_n(list_x[j],3)), abs(FxDiff_n(list_x[k],3))])
omg = (x-list_x[i])*(x-list_x[j])*(x-list_x[k])
return abs(ks*omg/6)
# 线性插值
def LinearInterpolation(x,list_x,list_y,FxDiff_n):
i, j = GetClosestTwo(x,list_x)
result = list_y[i] + (x - list_x[i]) * (list_y[j] - list_y[i]) / (list_x[j] - list_x[i])
r = LinearRegression(x,list_x,FxDiff_n)
return (result,r)
# 抛物线插值
def ParabolaInterpolation(x,list_x,list_y,FxDiff_n):
i, j, k = GetClosestThree(x,list_x)
result = list_y[i] * (x - list_x[j]) * (x - list_x[k]) / (list_x[i] - list_x[j]) / (list_x[i] - list_x[k])
result += list_y[j] * (x - list_x[i]) * (x - list_x[k]) / (list_x[j] - list_x[i]) / (list_x[j] - list_x[k])
result += list_y[k] * (x - list_x[i]) * (x - list_x[j]) / (list_x[k] - list_x[i]) / (list_x[k] - list_x[j])
r = ParabolaRegression(x,list_x,FxDiff_n)
return (result,r)
# 拉格朗日插值
def LagrangeInterpolation(x,list_x,list_y):
result = 0
for i in range(0, len(list_x)):
temp = 1
for j in range(0, len(list_x)):
if i != j:
temp *= (x - list_x[j]) / (list_x[i] - list_x[j])
result += temp * list_y[i]
return result
# 定义原函数和其导函数计算结果,用于计算插值的截断误差,如果不需要则不用管
def FxDiff_n1(x,n):
result = 0
if n == 0:
# 下面改成原函数 ############################################################
result = math.log(x)
else:
# 下面改成n阶导数 ##############################################################################
result = (-1)**(n+1) * math.factorial(n-1) / (x**n)
return result
if __name__ == "__main__":
##############################################################################
list_x = [10,11,12,13] # 已给出的x数值与y数值对应
list_y = [2.3026,2.3979,2.4849,2.5649] # 已给出的y数值与x数值对应
x_to_predict = 11.75 # 要预测的x值
print("线性插值结果为%f, 截断误差%f" % LinearInterpolation(x_to_predict,list_x,list_y,FxDiff_n1))
print("抛物线插值结果为%f, 截断误差%f" % ParabolaInterpolation(x_to_predict,list_x,list_y,FxDiff_n1))
# print(LagrangeInterpolation(x_to_predict,list_x,list_y))