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))