三次样条外推

发布于 2024-07-22 07:24:51 字数 268 浏览 8 评论 0原文

我有一个很好的三次样条代码,但它仅用于插值。 我需要外推一点到未来。 有谁知道执行此操作的良好代码源(而不是库)?

这是我在 basic(现在的 ASM)中编写的插值代码

I have a nice cubic spline code but it is for interpolation only. I need to extrapolate just a little into the future. Does anyone know of a good source of code, not a library, for doing this?

This is the code I wrote in basic (now ASM) for interpolation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

偏爱自由 2024-07-29 07:24:51

您不需要为此编写新代码。

要推断样条线,您可以推断第一个和最后一个样条线的参数

根据您现有的代码/库,如果不修改代码,这可能是不可能的。 在这种情况下,只需在点列表的开头/结尾添加另外两个点即可。 您可以通过在第一个/最后两个点之间进行线性插值来获得这两个点。

注意:根据要点的原始含义,推断可能完全不合适,尤其是在涉及统计数据时。 在这种情况下,您应该考虑使用回归分析

You don't need new code for that.

To extrapolate the spline you can extrapolate the parameters of the first and last spline.

Depending on your existing code/library that might not be possible without modifying the code. In that case just prepend/append two other points to the beginning/end of your list of points. You can get those two points by linearily interpolating between the first/last two points.

Be careful: Depending on the original meaning of the points that extrapolation might be completely inappropriate, especially when it comes to statistical data. In that case you should consider using regression analysis.

一紙繁鸢 2024-07-29 07:24:51

为简单起见,我将表示三次贝塞尔曲线
为 4 个点(A、B、C、D),
其中 A 和 D 是曲线的端点,
B和C是“控制手柄点”。
(实际曲线通常接触控制手柄点)。

请参阅“Don Lancaster 的 Guru 的巢穴三次样条库”
了解转换三次贝塞尔曲线表示的方法
进入其他流行的表现形式。

插值

给定一条三次贝塞尔曲线 (P0, P1, P2, P3),
我们使用De Casteljau算法
将贝塞尔曲线切割成
左半部和右半部。
即使在没有“乘法”指令的微控制器上,这也非常简单,
因为它只需要计算几个平均值,直到我们得到一个中点:

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

整个贝塞尔曲线是(P0,P1,P2,P3)。

整个贝塞尔曲线的左半部分是贝塞尔曲线(P0、F0、S0、M)。

整个贝塞尔曲线的右半部分是贝塞尔曲线(M、S1、F2、P3)。

许多微控制器继续将每条曲线分开
分成越来越小的曲线
直到每块小到足以近似
一条直线。

但我们想走另一条路——推断出更大的曲线。

外推

给定左半部分或右半部分,
我们可以反向运行它以恢复原始曲线。

假设我们忘记了原来的点 P1、P2、P3。

给定贝塞尔曲线的左半部分 (P0, F0, S0, M),
我们可以向右推断:

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点是否是最初计算的
作为一些较大的贝塞尔样条线的左半部分(或右半部分)。

我相信您已经知道这一点,但为了清楚起见:

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)


(如果您正在做 2D,请跳过所有“z”内容 - 它始终为零)。

For simplicity, I'm going to represent a cubic Bezier curve
as 4 points (A, B, C, D),
where A and D are the endpoints of the curve,
and B and C are the "control handle points".
(The actual curve usually does not touch the control handle points).

See "Don Lancaster's Guru's Lair Cubic Spline Library"
for ways to convert this representation of a cubic Bezier curve
into other popular representations.

interpolation

Given one cubic Bezier curve (P0, P1, P2, P3),
we use De Casteljau's algorithm
to chop a Bezier curve into
a left half and a right half.
This is super-easy even on a microcontroller that doesn't have a "multiply" instruction,
because it only requires calculating a few averages until we get a midpoint:

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

The entire Bezier curve is (P0, P1, P2, P3).

The left half of that entire Bezier curve is the Bezier curve (P0, F0, S0, M).

The right half of that entire Bezier curve is the Bezier curve (M, S1, F2, P3).

Many microcontrollers continue to divide each curve up
into smaller and smaller little curves
until each piece is small enough to approximate with
a straight line.

But we want to go the other way -- extrapolate out to a bigger curve.

extrapolation

Given either the left half or the right half,
we can run this in reverse to recover the original curve.

Let's imagine that we forgot the original points P1, P2, P3.

Given the left half of a Bezier curve (P0, F0, S0, M),
we can extrapolate to the right with:

S1 := M + (M - S0)
F1 := S0 + (S0 - F0)
P1 := F0 + (F0 - P0)

then use those values to calculate

F2 := S1 + (S1 - F1)
P2 := F1 + (F1 - P1)

and finally

P3 := F2 + (F2 - P2)

to extrapolate and recover the extrapolated Bazier curve (P0, P1, P2, P3).

details

The extrapolated curve (P0, P1, P2, P3)
passes through every point in the original curve
(P0, F0, S0, M) --
in particular, starting at P0 and passing through the midpoint M --
and keeps on going until it reaches P3.

We can always extrapolate from any 4 points (P0, F0, S0, M),
whether or not those 4 points were originally calculated
as the left half (or right half) of some larger Bezier spline.

I'm sure you already know this, but just for clarity:

Midpoint = average(F0, F1)

means "find the Midpoint exactly halfway between points F0 and F1",
or in other words,

Midpoint.x = (F0.x + F1.x)/2
Midpoint.y = (F0.y + F1.y)/2
Midpoint.z = (F0.z + F1.z)/2

The expression

S1 := M + (M - S0)

means "Given a line segment, with one end at S0, and the midpoint at M,
start at S0 and run in a straight line past M until you reach the other end at S1",
or in other words
(unless you have a decent vector library) 3 lines of code

S1.x := M.x + (M.x - S0.x)
S1.y := M.y + (M.y - S0.y)
S1.z := M.z + (M.z - S0.z)

.
(If you're doing 2D, skip all the "z" stuff -- it's always zero).

江挽川 2024-07-29 07:24:51

您需要为所请求的代码编写更好的要求。 样条曲线通常用于利用某些固定数据集对某些未知或复杂函数进行插值。 如果您想估计该数据集边界之外的函数值,则不应使用样条曲线。

如果您的样条函数是在您真正想要评估您的值的地方定义的函数(三次,但不是分段三次),那么您已经可以评估该值。

如果您希望能够评估插值范围之外的样条线,但将其保留为分段三次函数,在插值范围内具有相同的值,那么您应该通过一些节点扩展样条线范围,并在新节点(例如,您希望样条线不仅是连续函数,而且还希望有一些一阶导数也是连续函数)

真的,我建议您使用一些更适合外推的算法,例如使用 拉格朗日多项式 如果您真正需要的一切都是距原始数据集点不远的单个值。

You need to write better requirements for requested code. Splines are usually used for interpolation of some unknown or complex function by using of some fixed data set. If you want to have an estimate of function's value outside of boundaries of this data set then you shouldn't use splines.

If your spline is function defined in the place where you really want to evaluate your value (cubic, but not piecewise-cubic) then you already can evaluate that value.

If you want to have ability to evaluate your spline outside of interpolation range, but leave it as piecewise-cubic function with the same values inside of interpolation range then you should extend spline range by some nodes, and add some logic of evaluation values at the new nodes (for example you want to have your spline be not only a continuous function, but also have some number of first derivatives be also continuous functions)

Really I suggest you to use some algorithm more suitable for extrapolation, like usage of Lagrange polynomial if everything you really need is single value not very far from points of original data set.

断舍离 2024-07-29 07:24:51

你真的必须稍微扩展一下这个问题。 此外,“三次样条”是一个非常广泛的术语。

如果您对样条线感兴趣,我衷心推荐 Carl de Boors 的《样条线实用指南》。 然而,它有点数学导向,但它包含代码示例(可以从作者的主页下载)。 谷歌搜索和维基百科上的“三次样条”可以找到一些例子,甚至可能是特定语言的例子——这是另一个要添加到问题中的东西(如果你正在寻找代码)。

如果您对外推法和曲线拟合感兴趣,谷歌搜索这些可能会有所帮助。 Matlab 软件包有一个非常好的曲线拟合工具箱。 维基百科有一些有用参考的链接

确实,这是一个太宽泛的问题,甚至无法开始猜测答案。

另外,您能解释一下您到底想做什么吗? 什么样的数据? 任何事物 ?


Edit1:在这里,试试这个:你可能会在这里找到一些有用的东西 - 链接

You'll really have to expand that question a little. Also, "cubic spline" is a very wide term.

If you're interested in splines, I can heartly reccomend Carl de Boors "A Practical Guide to Splines". It is however a little mathematically oriented, but it has code examples included (they can be downloaded from the author's home page). Googling and wikiing for "cubic spline" can bring up some examples, maybe even in particular languages - another thing to add to the question (if you're looking for code).

If you're interested in extrapolation and curve fitting, googling those could help. Matlab package has a very nice curve fitting toolbox. Wikipedia has some links to useful references

Really, it is too wide a question, to even start guessing an answer.

Also, could you explain what exactly are you trying to do ? What kind of data ? Anything ?


Edit1: Here, try this: you may find something useful in here - link

兔姬 2024-07-29 07:24:51

通常,对于样条插值,您使用变量 t 在线上进行插值。 只要 0 <= t <= 1 就可以进行插值。 然而,当t<1时, 0或t> 1 你只是简单地推断样条线。

Generally for spline interpolation you use a variable t to interpolate over the line. As long as 0 <= t <= 1 you're interpolating. However, when t < 0 or t > 1 you're simply extrapolating the spline.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文