我需要一个ODE求解器来解决类似于MATLAB ode15s的僵硬问题。
对于我的问题,我需要检查不同初始值需要多少步(计算),并将其与我自己的ODE求解器进行比较。
我尝试使用
solver = scipy.integrate.ode(f)
solver.set_integrator('vode', method='bdf', order=15, nsteps=3000)
solver.set_initial_value(u0, t0)
然后整合:
i = 0
while solver.successful() and solver.t<tf:
solver.integrate(tf, step=True)
i += 1
print(i)
tf
是我的时间间隔的结束。
使用的函数定义为:
def func(self, t, u):
u1 = u[1]
u2 = mu * (1-numpy.dot(u[0], u[0]))*u[1] - u[0]
return numpy.array([u1, u2])
初始值为u0 = [ 2, 0]
的问题很严重。
这意味着步数不应取决于我的常量mu
。
但确实如此。
我认为odeint
- 方法可以解决这个问题 - 但是我必须发送整个t
- 向量,因此需要设置完成的步骤数量和这破坏了我的任务。
是否有使用odeint
在两个t0
和tf
之间使用自适应步长?
或者您可以在使用vode
- 积分器时看到我想念的任何内容吗?
答案 0 :(得分:6)
我看到了类似的东西;使用'vode'
解算器,更改'adams'
和'bdf'
之间的方法不会更改步数。 (顺便说一下,使用order=15
没有意义; 'bdf'
解算器的'vode'
方法的最大顺序是5('adams'解算器的最大顺序是12)。如果你退出论证,它应该默认使用最大值。)
odeint
是LSODA的包装器。 ode
还提供了LSODA的包装:
将'vode'
更改为'lsoda'
。不幸的是'lsoda'
求解器忽略了
step=True
方法的integrate
参数。
'lsoda'
解算器<{1>} <{1}} 'vode'
。
你可以得到一个上限
初始化method='bdf'
时使用的步骤数,
在tvals = []
中,执行func
。解算器完成后,设置
tvals.append(t)
。 tvals = np.unique(tvals)
的长度告诉你
评估函数的时间值。
这不是你想要的,但确实显示了巨大的差异
使用tvals
解算器和'lsoda'
求解器之间的关系
方法'vode'
。 'bdf'
解算器使用的步数是
与您在评论中为matlab引用的订单相同。 (我使用'lsoda'
,mu=10000
。)
更新:事实证明,至少对于一个僵硬的问题,如果你提供一个计算雅可比矩阵的函数,它会对tf = 10
求解器产生巨大的影响。
下面的脚本使用这两种方法运行'vode'
解算器
运行'vode'
求解器。在每种情况下,它都会运行带有和不带雅可比函数的求解器。这是它生成的输出:
'lsoda'
剧本:
vode adams jac=None len(tvals) = 517992
vode adams jac=jac len(tvals) = 195
vode bdf jac=None len(tvals) = 516284
vode bdf jac=jac len(tvals) = 55
lsoda jac=None len(tvals) = 49
lsoda jac=jac len(tvals) = 49