【发布时间】:2020-10-02 05:58:48
【问题描述】:
我想了解scipy.integrate 在内部做什么。也就是说,似乎正在发生一些奇怪和不一致的事情。
如何让它正常工作?我需要它一次执行一个集成步骤,因为我在 ODE 中使用 t 做了一些事情,并且需要它保持一致
所以,这是我的 MWE
import numpy as np
from scipy.integrate import ode
t0 = 0
t1 = 1
def myODE(t, x):
print('INTERNAL t = {time:2.3f}'.format(time=t))
Dx = np.zeros([2, 1])
Dx[0] = -x[0]**2
Dx[1] = -x[1]**2
return Dx
simulator = ode(myODE).set_integrator('dopri5')
simulator.set_initial_value(np.ones([2,1]), t0)
t = simulator.t
while t < t1:
t = simulator.t
print('Outside integrate t = {time:2.3f}'.format(time=t))
x = simulator.integrate(2, step=True)
print('x1 = {x1:2.3f}'.format(x1=x[0,0]))
我试图一次执行一个集成步骤。相反,integrate 做了其他事情。从下面的输出可以看出,它一次执行多个步骤,并且这些步骤不一致:有时,t 增加然后又减少。
Outside integrate t = 0.000
INTERNAL t = 0.000
INTERNAL t = 0.010
INTERNAL t = 0.004
INTERNAL t = 0.006
INTERNAL t = 0.016
...
INTERNAL t = 1.969
INTERNAL t = 1.983
INTERNAL t = 2.000
INTERNAL t = 2.000
x1 = 0.333
Outside integrate t = 2.000
INTERNAL t = 2.000
...
INTERNAL t = 2.000
x1 = 0.333
【问题讨论】:
-
ode求解器使用可变时间步长是正常的。根据特定的求解器,它可能会计算多次接近以获得数字jacobian(导数)。当函数变化快时,它也可以使用精细的步骤,而当它变化较慢时,它可能会使用更长的步骤。目标是在保持准确性的同时最小化评估的总数。文档提供了期刊参考。 -
看
odeint。它允许您将数组指定为t点。 -
您可以为
dopri5求解器提供nsteps=1参数。然而,这仍然导致采取 2 个步骤。请注意,dopri5 每一步有 6+1 次 ODE 函数评估,可以重用一步的最后一次评估,因为它与下一步的第一步相同。 -
无论你想用 ODE 做什么,它几乎肯定不应该依赖于所用方法的内部及其步长控制器。使用事件和密集输出选项,如果可能的话,积极开发的接口
solve_ivp。 -
@LutzLehmann 1solve_ivp` 不允许您一次执行一个步骤并存储中间数据。说,
RK45是一个在我看来要优越得多的类。问题是events不适用于我的情况:我需要在 RHS 中缓冲t变量
标签: scipy integration ode integrate