在NetLogo中解决ODE,Eulers vs R-K vs R solver

在NetLogo中解决ODE,Eulers vs R-K vs R solver,netlogo,runge-kutta,Netlogo,Runge Kutta,在我的模型中,每个代理在每个滴答声中解决一个ODE系统。我使用了欧勒方法(类似于NetLogo中的系统动力学建模器)来解决这些一阶常微分方程。然而,对于一个稳定的解决方案,我不得不使用一个非常小的时间步长(dt),这意味着用这种方法进行模拟的速度非常慢。我很好奇,是否有人对更快解决ODE的方法有什么建议?我正在考虑实现Runge-Kutta(具有更大的时间步长?),正如在这里所做的()。我也会考虑在R.中使用R扩展和使用ODE求解器,但同样,每个代理都解决了ODE,所以我不知道这是否是一个有效的

在我的模型中,每个代理在每个滴答声中解决一个ODE系统。我使用了欧勒方法(类似于NetLogo中的系统动力学建模器)来解决这些一阶常微分方程。然而,对于一个稳定的解决方案,我不得不使用一个非常小的时间步长(dt),这意味着用这种方法进行模拟的速度非常慢。我很好奇,是否有人对更快解决ODE的方法有什么建议?我正在考虑实现Runge-Kutta(具有更大的时间步长?),正如在这里所做的()。我也会考虑在R.中使用R扩展和使用ODE求解器,但同样,每个代理都解决了ODE,所以我不知道这是否是一个有效的方法。
我希望有人能对这些方法的性能有所了解,并能提供一些建议。如果没有,我会尝试分享我的发现

总的来说,你的想法是正确的。对于顺序法
p
要在长度
T
的积分间隔内达到全局误差水平
tol
,需要在幅度范围内设置步长

h=pow(tol/T,1.0/p). 
然而,不仅离散化误差在
N=T/h
步骤上累积,而且浮点误差也累积。这给出了有用步长的下限,其大小为
h=pow(T*mu,1.0/(p+1))

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

  • 1阶欧拉方法需要大约
    h=1e-6
    的步长,因此
    N=1e+6
    步长和函数求值。可以预期得到合理结果的步长范围在
    h=3e-8
    的范围内

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

  • 经典的Runge-Kutta方法的阶数为4,给出了所需的步长约为
    h=3e-2
    ,步长约为
    N=30
    4N=120
    函数求值。下限为
    1e-3

因此,使用高阶方法可以获得显著的收益。同时,随着阶数的增加,步长减小导致全局误差降低的范围也明显缩小。但与此同时,可实现的精度也在提高。因此,当达到这一点时,人们必须有意识地去关心,让自己足够好


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


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


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


考虑到LOGO语言中没有函数调用的明确参数,
dotx=f(t,x)
的计算需要在调用
f
的函数计算之前,首先确定
t
x
的正确值

 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)

请您详细说明一下“稳定解决方案”的概念好吗?它是否达到了一个固定点,在步长减半的情况下收敛,由于ODE的僵硬区域或组件引起的问题。。。