在NetLogo,Eulers vs R-K vs R求解器中求解ODE

时间:2015-04-10 14:28:04

标签: netlogo runge-kutta

在我的模型中,每个代理在每个滴答处解决了一个ODE系统。我使用Euler方法(类似于NetLogo中的系统动力学建模器)来解决这些一阶ODE。然而,对于稳定的解决方案,我被迫使用非常小的时间步长(dt),这意味着使用该方法模拟进行得非常缓慢。我很好奇是否有人对如何更快地解决ODE的方法提出建议?我正在考虑实施Runge-Kutta(有更大的时间步长?),就像在这里所做的那样(http://academic.evergreen.edu/m/mcavityd/netlogo/Bouncing_Ball.html)。我还会考虑使用R扩展并在R中使用ODE求解器。但同样,每个代理都会解决ODE,因此我不知道这是否是一种有效的方法。

我希望有人对这些方法的表现有所了解,并可以提供一些建议。如果没有,我会尝试分享我发现的东西。

1 个答案:

答案 0 :(得分:1)

一般来说,你的想法是正确的。对于订单p在长度为tol的积分间隔内达到全局错误级别T的方法,您需要一个幅度范围内的步长

h=pow(tol/T,1.0/p). 

但是,不仅离散误差会累积在N=T/h步骤上,还会累积浮点误差。这为有用的步长h=pow(T*mu,1.0/(p+1))提供了下限。

示例:适用于T=1mu=1e-15tol=1e-6

  • 订单1的Euler方法需要大约h=1e-6的步长,因此需要N=1e+6步骤和函数评估。可以预期合理结果的步长范围受h=3e-8的限制。

  • 改进的Euler或Heun方法具有阶数2,这意味着步长1e-3N=1000步和2N=2000函数评估,有用步长的下限是1e-3

  • 经典的Runge-Kutta方法具有阶数4,其给出了大约h=3e-2的所需步长,具有大约N=30步和4N=120函数评估。下限为1e-3

因此,使用更高阶的方法可以获得显着的收益。同时,步长减小导致较低的全局误差的范围对于增加的顺序也变得明显更窄。但与此同时,可实现的准确度也会提高。因此,当达到这一点时,必须明知谨慎,单独留下足够好的东西。


球示例中的RK4 的实现,一般用于ODE的数值积分,适用于ODE系统x'=f(t,x),其中x是可能的非常大的状态向量


通过使状态向量的速度成为二阶ODE(系统),将其转换为一阶系统。 x''=a(x,x')转化为[x',v']=[v, a(x,v)]。然后,代理系统的大向量由对[x,v]的集合组成,或者,如果需要,作为所有x组件的集合和所有v的集合的串联组成。组件。


在基于代理的系统中,将属于代理的状态向量的组件存储为代理的内部变量是合理的。然后通过迭代代理集合并计算为内部变量定制的操作来执行向量操作。


考虑到在LOGO语言中没有明确的函数调用参数,dotx = f(t,x)的评估需要先调整tx的正确值才能调用f

的功能评估
 save t0=t, x0=x
 evaluate k1 = f_of_t_x

 set t=t0+h/2, x=x0+h/2*k1
 evaluate k2=f_of_t_x

 set x=x0+h/2*k2
 evaluate k3=f_of_t_x

 set t=t+h, x=x0+h*k3
 evaluate k4=f_of_t_x

 set x=x0+h/6*(k1+2*(k2+k3)+k4)