我有一个不错的三次样条插值代码,但仅适用于插值。我需要稍微外推一下,预测未来。有人知道一个好的代码来源(非库),可以实现这个功能吗?
您不需要新的代码。
要推断样条曲线,您可以外推第一个和最后一个样条曲线的参数。
根据您现有的代码/库,如果不修改代码可能无法实现。在这种情况下,只需在点列表的开头/结尾添加两个其他点即可。您可以通过在线性插值第一个/最后两个点之间来获取这两个点。
请注意: 根据原始点的含义,该外推可能完全不适合,特别是涉及统计数据时。在这种情况下,您应考虑使用回归分析。
P0
F0 := average(P0, P1)
P1 S0 := average(F0, F1)
F1 := average(P1, P2) Midpoint := average(S0, S1)
P2 S1 := average(F1, F2)
F2 := average(P2, P3)
P3
S1 := M + (M - S0)
F1 := S0 + (S0 - F0)
P1 := F0 + (F0 - P0)
F2 := S1 + (S1 - F1)
P2 := F1 + (F1 - P1)
最后
P3 := F2 + (F2 - P2)
对于外推和恢复外推的Bazier曲线(P0,P1,P2,P3)。
细节
外推曲线(P0,P1,P2,P3) 通过原始曲线中的每个点 (P0,F0,S0,M)-- 特别是从P0开始,通过中点M -- 并一直保持到达P3。
我们总是可以从任何4个点(P0,F0,S0,M)进行外推, 无论这些4个点是否最初计算为某个更大的Bezier样条的左半部分(或右半部分)。
我确定您已经知道了,但只是为了清晰起见:
Midpoint = average(F0, F1)
意思是“在点F0和F1之间精确地找到正中间点”,换句话说,
Midpoint.x = (F0.x + F1.x)/2
Midpoint.y = (F0.y + F1.y)/2
Midpoint.z = (F0.z + F1.z)/2
表达式
S1 := M + (M - S0)
意思是“给定一条线段,其中一个端点为S0,中点为M,在S0处开始并沿着直线穿过M直到你到达另一个端点S1”,或者说(除非你有一个不错的向量库)需要3行代码。
S1.x := M.x + (M.x - S0.x)
S1.y := M.y + (M.y - S0.y)
S1.z := M.z + (M.z - S0.z)
您需要编写更好的代码需求。样条通常用于通过某些固定数据集对某些未知或复杂函数进行插值。如果您想要在此数据集范围之外估算函数值,那么就不应该使用样条。
如果您的样条是在您真正想要评估值的位置定义的函数(三次函数,但不是分段三次函数),那么您已经可以评估该值了。
如果您想要能够在插值范围之外评估您的样条,但仍将其保留为具有插值范围内相同值的分段三次函数,则应通过一些节点扩展样条范围,并添加一些逻辑以在新节点处评估值(例如,您希望您的样条不仅是连续函数,而且还具有一些连续函数的一阶导数)
实际上,我建议您使用更适合外推的算法,例如使用Lagrange polynomial,如果您真正需要的只是距离原始数据点不远的单个值。