游戏中的Gaffer有一个关于使用伟大的文章来改善游戏物理的RK4集成。实现是简单的,但其背后的数学让我感到困惑。我从概念上理解导数和积分,但很长一段时间没有操纵方程了。
以下是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阶的导数与用较小的时间步长进行简单的欧拉积分不同?
在阅读了下面被接受的答案和其他几篇文章之后,我掌握了RK4的工作原理。回答我自己的问题:
可以用简单的术语解释RK4是如何工作的吗?
RK4利用了这样一个事实,如果我们使用函数的高阶导数,而不仅仅是一阶或二阶导数,我们就可以得到更好的函数逼近。这就是为什么泰勒级数比欧拉近似更快收敛的原因。(看一看页面右侧的动画)
具体来说,为什么我们在0.0f**,** 0.5f**,** 0.5f**,和** 1.0f**?**上对衍生品进行平均化?
Runge方法是一个函数的近似,它在一个时间步长内对几个点的导数进行采样,而泰勒级数只对一个点的导数进行采样。在对这些导数进行采样后,我们需要知道如何对每个样本进行加权,才能得到最接近的近似。一个简单的方法是选择与Taylor级数一致的常数,这就是Runge方程常数的确定方法。 这篇文章为我说得更清楚了。注意
(15)是泰勒级数展开,而(17)是Runge推导。
将导数平均到4阶与用较小的时间步长进行简单的欧拉积分有何不同?
在数学上,它比许多欧拉近似收敛得快得多。当然,只要有足够的欧拉近似,我们可以获得与RK4相同的精度,但是所需的计算能力并不能证明使用欧拉是正确的。
发布于 2009-11-06 19:08:26
就实际数学而言,这可能有点过于简化,但作为Runge Kutta集成的直观指南。
给定某个时间的数量,t1,我们想知道另一个时间的数量,t2。用一个一阶微分方程,我们可以知道在t1上这个量的变化率。没有什么是我们能确定的,其余的都是猜测。
欧拉积分是最简单的猜测方式:从t1线性外推到t2,使用t1的精确变化率。这通常会给出一个糟糕的答案。如果t2离t1很远,这种线性外推将不能与理想答案中的任何曲率相匹配。如果我们采取从t1到t2的许多小步骤,就会遇到类似值的减法问题。舍入错误会破坏结果。
所以我们改进了我们的猜测。一种方法是继续进行线性外推,然后希望它离事实不远,用微分方程来计算t2的变化率。这与t1的(精确)变化率相比较,更好地代表了t1和t2之间真实答案的典型斜率。我们利用它来进行从t1到t2的新的线性外推。如果我们应该取简单的平均值,或者在t1给出更多的权重,而不做数学来估计错误,那就不太明显了,但是这里有一个选择。无论如何,这是一个比欧拉更好的答案。
也许更好的方法是,将我们的初始线性外推到t1和t2之间的某个时间点,并使用微分方程来计算那里的变化率。这给出的答案大致和刚才描述的平均水平一样好。然后将它用于从t1到t2的线性外推,因为我们的目的是在t2找到数量。这是中点算法。
您可以想象使用变化率的中点估计来对从t1到中点的数量进行另一个线性外推。利用微分方程,我们得到了一个更好的斜坡估计。使用这个方法,我们最终从t1推断到t2,在那里我们需要一个答案。这是Runge Kutta算法。
我们能不能对中点进行第三次外推?当然,这不是非法的,但是详细的分析显示,改进越来越少,因此其他错误的来源主宰了最终的结果。
Runge将微分方程应用于初始点t1,两次应用于中点,一次应用于最终点t2。中间点是一个选择问题。可以使用t1和t2之间的其他点对斜率进行这些改进估计。例如,我们可以使用t1,距离t2三分之一的路,向t2和t2的2/3的路。四种衍生品的平均权重将有所不同。在实践中,这并没有真正的帮助,但在测试中可能有一席之地,因为它应该给出相同的答案,但会提供一组不同的舍入错误。
发布于 2009-11-03 16:11:31
至于你的问题,为什么:我记得曾经写过一个布料模拟器,其中的布是一系列连接在节点上的弹簧。在模拟器中,弹簧所施加的力与弹簧拉伸的距离成正比。力在节点处产生加速度,从而导致速度,使伸展弹簧的节点移动。有两个积分(积分加速度得到速度,积分速度得到位置),如果它们不准确,误差雪球:过大的加速度导致过大的速度,导致过大的拉伸,导致更多的加速度,使整个系统不稳定。
如果没有图形很难解释,但我将尝试:假设有f(t),其中f(0) = 10,f(1) = 20,f(2) = 30。
在区间0
矩形规则积分用矩形逼近曲面,其中宽度是时间上的三角形,长度是f(t)的新值,所以在区间0
现在,如果你画出这些点并画一条线穿过它们,你会发现它实际上是三角形的,它的曲面是30 (单位),因此欧拉积分是不够的。
为了得到更精确的曲面(积分)估计,可以采取较小的t区间,例如f(0)、f(0.5)、f(1)、f(1.5)和f(2)。
如果您还在跟踪我,那么RK4方法只是估算t0
(但正如其他人所说,请阅读维基百科的文章,以获得更详细的解释。RK4属于数值积分范畴)
发布于 2013-09-27 18:35:33
从最简单的意义上说,RK4是一个基于4个导数和每个时间步长点的逼近函数:起始点A的初始条件,时间步长/2的数据点A为基础的第一个近似斜率B,以及A的斜率,第三个近似C,它对B处的斜率有一个修正值,以反映函数的形状变化,最后是一个基于修正点C的最终斜率。
因此,基本上这个方法允许你使用一个起点,一个平均中点,在两个部分中都有校正来调整形状,以及一个双重修正的端点。这是每个数据点1/6、1/3、1/3和1/6的有效贡献,所以你的大部分答案都是基于你对函数形状的修正。
结果表明,RK近似的阶数(欧拉被认为是RK1)对应于它的精度尺度和较小的时间步长。
RK1近似之间的关系是线性的,所以对于10倍的精度,你得到了大约10倍的收敛性。
对于RK4,10倍的精度使收敛性提高了10^4倍。所以,当你的计算时间在RK4中线性增加时,它会多项式地提高你的精度。
https://stackoverflow.com/questions/1668098
复制相似问题