Files
CalWay_Python/注释完整版/68-1-zhushi.py
2025-04-16 21:40:31 +08:00

164 lines
5.3 KiB
Python
Raw 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
# 定义插值点
list_x = [10, 11, 12, 13] # 自变量列表
list_y = [2.3026, 2.3979, 2.4849, 2.5649] # 因变量列表
# 定义原函数和其导函数计算结果
def FxDiff_n(x, n):
"""
计算自然对数函数 ln(x) 的 n 阶导数值。
参数:
x (float): 自变量值,要求 x > 0。
n (int): 导数的阶数n >= 0。
返回:
float: ln(x) 的 n 阶导数值。
"""
result = 0
if n == 0:
result = math.log(x) # 原函数 ln(x)
else:
result = (-1)**(n+1) * math.factorial(n-1) / (x**n) # n 阶导数公式
return result
# 获取与待求 x 最接近的两个点
def GetClosestTwo(x, list_x):
"""
获取与待求点 x 最接近的两个插值点的索引。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
返回:
tuple of int: 最接近的两个点的索引 (i, j),满足 list_x[i] <= x < list_x[j]。
"""
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):
"""
获取与待求点 x 最接近的三个插值点的索引。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
返回:
tuple of int: 最接近的三个点的索引 (i, j, k),满足 list_x[i] <= x < list_x[k]。
"""
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):
"""
计算线性插值的余项估计值。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
返回:
float: 线性插值的余项估计值。
"""
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):
"""
计算抛物线插值的余项估计值。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
返回:
float: 抛物线插值的余项估计值。
"""
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):
"""
使用线性插值法计算插值结果及其余项估计值。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
list_y (list of float): 因变量列表,与 list_x 一一对应。
返回:
tuple: 插值结果和余项估计值 (result, r)。
"""
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) # 余项估计
return (result, r)
# 抛物线插值
def ParabolaInterpolation(x, list_x, list_y):
"""
使用抛物线插值法计算插值结果及其余项估计值。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
list_y (list of float): 因变量列表,与 list_x 一一对应。
返回:
tuple: 插值结果和余项估计值 (result, r)。
"""
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) # 余项估计
return (result, r)
# 拉格朗日插值
def LagrangeInterpolation(x, list_x, list_y):
"""
使用拉格朗日插值法计算插值结果。
参数:
x (float): 待插值的自变量值。
list_x (list of float): 自变量列表,要求已按升序排列。
list_y (list of float): 因变量列表,与 list_x 一一对应。
返回:
float: 插值结果。
"""
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
if __name__ == "__main__":
# 测试线性插值
print(LinearInterpolation(11.75, list_x, list_y))
# 测试抛物线插值
print(ParabolaInterpolation(11.75, list_x, list_y))
# 测试拉格朗日插值
print(LagrangeInterpolation(11.75, list_x, list_y))