Gaffer on Games有great article关于使用RK4 integration更好的游戏物理。实现很简单,但背后的数学让我感到困惑。我从概念层面理解衍生物和积分,但很长一段时间没有操纵方程式。
这是Gaffer实施的主要内容:
void integrate(State &state, float t, float dt)
{
Derivative a = evaluate(state, t, 0.0f, Derivative());
Derivative b = evaluate(state, t+dt*0.5f, dt*0.5f, a);
Derivative c = evaluate(state, t+dt*0.5f, dt*0.5f, b);
Derivative d = evaluate(state, t+dt, dt, c);
const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv)
state.x = state.x + dxdt * dt;
state.v = state.v + dvdt * dt;
}
任何人都能用简单的语言解释RK4的工作原理吗?具体来说,为什么我们在0.0f
,0.5f
,0.5f
和1.0f?
对衍生工具求平均值。如何将平均导数推广到第4阶不同于进行简单的euler积分一个较小的时间步长?
在阅读下面接受的答案和其他几篇文章后,我掌握了RK4的工作原理。回答我自己的问题:
任何人都可以用简单的语言解释RK4的工作原理吗?
RK4充分利用了这一事实 我们可以得到更好的近似值 如果我们使用它的功能 高阶导数而不是 只是一阶或二阶导数。 这就是Taylor series的原因 收敛比欧拉快得多 近似。 (看看 动画在右侧 页)
具体来说,为什么我们在0.0f
,0.5f
,0.5f
和1.0f
平均衍生品?
Runge-Kutta方法是一个 近似函数 样品衍生物有几点 在一个时间步之内,不像泰勒 系列只采样衍生物 单点。取样后 这些衍生品我们需要知道如何 称重每个样品得到 最接近的可能。一个 这样做的简单方法就是选择 与...重合的常数 泰勒系列,这是怎么回事 Runge-Kutta方程的常数 确定了。
This article让它更加清晰 我。请注意
(15)
是怎样的泰勒 系列扩展而(17)
是 Runge-Kutta推导。
如果将衍生物平均到4阶不同于如何使用较小的时间步长进行简单的euler积分?
数学上,它收敛很多 比做许多欧拉更快 近似。当然,够了 欧拉近似我们可以获得平等 精度为RK4,但计算结果 所需的电力并不合理 欧拉。
答案 0 :(得分:33)
就实际数学而言,这可能有点过于简单,但它是Runge Kutta
整合的直观指南。
在某个时间t1
给出一些数量,我们想知道另一个时间t2
的数量。使用一阶微分方程,我们可以知道t1
处该数量的变化率。我们无从谈及其他任何事情;剩下的就是猜测。
Euler积分是最简单的猜测方法:使用t1
处精确已知的变化率,从t1
线性推断到t2。这通常会给出错误的答案。如果t2远离t1,则此线性外推将无法匹配理想答案中的任何曲率。如果我们从t1到t2
采取许多小步骤,我们就会遇到减去相似值的问题。舍入错误将破坏结果。
所以我们改进了猜测。一种方法是继续进行线性外推,然后希望它与真理不太相似,使用微分方程计算t2
处的变化率估计值。这与t1
处的(准确)变化率平均,更好地表示t1
和t2
之间的真实答案的典型斜率。我们使用它来进行从t1
到t2
的新线性外推。我们不应该采用简单的平均值,或者在t1
给予更多权重,而不用数学来估计误差,但这里有一个选择。无论如何,这是比欧拉给出的更好的答案。
或许更好,将我们的初始线性外推到t1
和t2
之间的某个时间点,并使用微分方程计算那里的变化率。这给出了与刚才描述的平均值大致相同的答案。然后使用它进行从t1
到t2
的线性推断,因为我们的目的是在t2
找到数量。这是中点算法。
您可以想象使用变化率的中点估计来对t1
到中点的数量进行另一次线性推断。通过微分方程,我们可以更好地估计那里的斜率。使用此功能,我们将从t1
一直推断到我们想要答案的t2
。这是Runge Kutta
算法。
我们可以对中点进行第三次推断吗?当然,这不是非法的,但详细的分析表明改进正在减少,因此其他错误来源主导了最终结果。
Runge Kutta将微分方程应用于初始点t1,两次应用于中点,一次应用于最终点t2。中间点是一个选择问题。可以使用t1
和t2
之间的其他点来进行斜率的改进估计。例如,我们可以使用t1
,这是指向t2的三分之一,另一个是t2
的两分之二,以及t2
。四种衍生物的平均权重将不同。在实践中,这并没有真正的帮助,但可能在测试中占有一席之地,因为它应该给出相同的答案,但会提供一组不同的舍入错误。
答案 1 :(得分:2)
关于你的问题为什么:我记得曾经写过一个布料模拟器,其中布是一系列在节点处相互连接的弹簧。在模拟器中,弹簧施加的力与弹簧拉伸的距离成比例。该力导致节点处的加速度,这导致移动节点的速度,该节点拉伸弹簧。有两个积分(积分加速度来获得速度,积分速度来获得位置)如果它们不准确,则错误滚雪球:太多的加速度会导致太大的速度导致过多的拉伸,从而导致更多的加速度,使得整个系统不稳定。
没有图形很难解释,但我会尝试:假设你有f(t),其中f(0)= 10,f(1)= 20,f(2)= 30。
f(t)在0 <0的区间内的适当积分。 t&lt; 1会在这段时间内给出f(t)图下的曲面。
矩形规则积分近似于具有矩形的表面,其中宽度是时间上的Δ,并且长度是f(t)的新值,因此在区间0&lt; t&lt; 1,它将产生20 * 1 = 20,并在下一个间隔1
现在,如果您要绘制这些点并在其中绘制一条线,您将看到它实际上是三角形,表面为30(单位),因此Euler积分不足。
为了更准确地估计表面(积分),可以采用较小的t间隔,例如在f(0),f(0.5),f(1),f(1.5)和f(2)处进行评估)。
如果您仍然关注我,那么RK4方法就是估算t0 (但正如其他人所说,请阅读维基百科文章以获得更详细的解释.RK4属于numerical integration)
答案 2 :(得分:2)
RK4在最简单的意义上是制作一个近似函数,它基于4个导数并指向每个时间步长:您在起始点A的初始条件,基于您时间步骤的数据点A的第一个近似斜率B / 2和A的斜率,第三个近似值C,它具有B处斜率的校正值,以反映函数的形状变化,最后是基于C点校正斜率的最终斜率。
因此,基本上这种方法可以让你使用一个起点,一个平均中点进行计算,该中点在两个部分内置校正以调整形状,以及一个双重校正的终点。这使得每个数据点的有效贡献为1/6 1/3 1/3和1/6,因此大部分答案都是基于对函数形状的校正。
事实证明,RK近似的顺序(Euler被认为是RK1)对应于其精度如何随着较小的时间步长而缩放。
RK1近似值之间的关系是线性的,因此精度的10倍可以获得大约10倍的收敛效果。
对于RK4,精度的10倍可以使收敛效率提高10 ^ 4倍。因此,当您的计算时间在RK4中线性增加时,它会以多项式增加您的精度。