采取单个 ODE 步骤

Taking a single ODE step

是否可以使用 scipy ODE 积分器进行一步操作?我知道 scipy.integrate.ode.integratestep 参数,但我不知道如何设置 t 参数以保证它完全执行一个完整步骤。显而易见的选择是 t=inf,但这会导致 ODE 失败::

from scipy.integrate import ode
obj = ode(lambda t, y: -y)
obj.set_initial_value(1)
y_new = obj.integrate(inf, step=True)

-

 DVODE--  At T (=R1) and step size H (=R2), the    
       corrector convergence failed repeatedly     
       or with abs(H) = HMIN   
      In above,  R1 =  0.0000000000000D+00   R2 =             Infinity
C:\Anaconda3\lib\site-packages\scipy\integrate\_ode.py:869: UserWarning: 
vode: Repeated convergence failures. (Perhaps bad Jacobian supplied or 
wrong choice of MF or tolerances.)
  'Unexpected istate=%s' % istate))

如果我使用t=0,那么 ODE 根本不会前进。我可以选择一个有限的正数,但如果 t 小于整步,是否可以保证跨过 t 整步?我正在写一个通用库,不知道典型的步长是多少。

数值积分器并不是真正按照固定步骤设计的,因此即使有可能,也很难以这种方式实现您的目标。您可能会通过修改最大和最小步长参数找到一种方法。 但是,如果你想检查集成器在做什么,或者将一些日志功能附加到集成器进程,你可以这样做:使用 set_solout() method.

您作为参数传递给 set_solout() 的函数(callable 对象)将在每个集成步骤中被调用。

我做了一些测试并验证了设置 step=Truet 等于任何有限正数将恰好采取一步。如果 t 小于下一步,它将跳过 t

from scipy.integrate import ode
obj = ode(lambda t, y: -y)
obj.set_initial_value(1)
while obj.t < 1:
    y_new = obj.integrate(1, step=True)
print(obj.t) # prints 1.037070648009345

需要注意的一点是,自适应步长根据 t 的特定分数猜测初始步长。选择较小的 t 会导致它采取较小的第一步。这就是为什么 inf 失败以及为什么没有 t 的值会导致积分器在第一步中跨过 t 的原因。