我在scipy.integrate.ode遇到了一个奇怪的问题。这是一个最小的工作示例:
import sys
import time
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from scipy.integrate import ode, complex_ode
def fun(t):
return np.exp( -t**2 / 2. )
def ode_fun(t, y):
a, b = y
f = fun(t)
c = np.conjugate(b)
dt_a = -2j*f*c + 2j*f*b
dt_b = 1j*f*a
return [dt_a, dt_b]
t_range = np.linspace(-10., 10., 10000)
init_cond = [-1, 0]
trajectory = np.empty((len(t_range), len(init_cond)), dtype=np.complex128)
### setup ###
r = ode(ode_fun).set_integrator('zvode', method='adams', with_jacobian=False)
r.set_initial_value(init_cond, t_range[0])
dt = t_range[1] - t_range[0]
### integration ###
for i, t_i in enumerate(t_range):
trajectory[i,:] = r.integrate(r.t+dt)
a_traj = trajectory[:,0]
b_traj = trajectory[:,1]
fun_traj = fun(t_range)
### plot ###
plt.figure(figsize=(10,5))
plt.subplot(121, title='ODE solution')
plt.plot(t_range, np.real(a_traj))
plt.subplot(122, title='Input')
plt.plot(t_range, fun_traj)
plt.show()
此代码工作正常,输出图为(ODE 显式依赖于输入变量,右侧面板显示输入,左侧面板显示第一个变量的 ode 解决方案)。
所以原则上我的代码是有效的。奇怪的是,如果我只是简单地替换积分范围
t_range = np.linspace(-10., 10., 10000)
经过
t_range = np.linspace(-20., 20., 10000)
我得到输出
所以不知何故,集成商只是放弃了集成,并将我的解决方案保持不变。为什么会这样?我该如何解决?
我测试过的一些东西:这显然不是分辨率问题,集成步骤已经很小了。相反,似乎集成商在几步之后甚至不再费心调用 ode 函数了。我已经通过在 ode_fun() 中包含一个打印语句来测试它。
我目前的怀疑是,在最初的几个集成步骤中,我的函数没有发生显着变化后,集成商决定我的函数是恒定的。我可能需要在某处设置一些容忍度吗?
任何帮助表示赞赏!