我正在使用 SciPy 的集成.odeint 函数集成一个僵硬的 ODE 系统。由于集成非常重要且耗时,我也在使用相应的 jacobian。通过重新排列方程,我可以将雅可比定义为带状矩阵。按照API 文档,我想用mu和ml参数定义形状。不幸的是,文档有点模棱两可,所以我无法弄清楚如何实现我的 jacobian 函数。
为了验证必须如何调用 odeint,我一直在使用以下(有点傻)代码:
from scipy.integrate import odeint
lmax = 5
def f1(y, t):
ydot = np.zeros(lmax)
for i in range(lmax):
ydot[i] = y[i]**2-y[i]**3
return ydot
def fulljac(y, t,):
J = np.zeros((lmax, lmax))
J[0,0]=-3*y[0]**2 + 2*y[0]
J[1,1]=-3*y[1]**2 + 2*y[1]
J[2,2]=-3*y[2]**2 + 2*y[2]
J[3,3]=-3*y[3]**2 + 2*y[3]
J[4,4]=-3*y[4]**2 + 2*y[4]
return J
## initial conditions and output times
delta = 0.0001;
yini = np.array([delta]*lmax)
times = np.linspace(0, 2/delta, 100)
y, infodict = odeint(f1, yini, times, Dfun=fulljac, full_output=1)
print("f1: nst: {0}, nfe: {1}, nje: {2}".format(infodict["nst"][-1],
infodict["nfe"][-1],
infodict["nje"][-1]))
使用完整的 NxN 雅可比矩阵,集成成功。仅使用对角线和mu=0和ml=0积分也成功。
为了测试带状矩阵用例,我正在使用mu=1和ml=1创建一个人工 3xN 带状雅可比矩阵,其中对角线之外的所有导数都为零。这会导致求解器出现奇怪的行为(类似于我在原始问题中看到的非对角线非零)。
def bandjac(y, t):
J = np.zeros((lmax, 3))
J[0,1]=-3*y[0]**2 + 2*y[0]
J[1,1]=-3*y[1]**2 + 2*y[1]
J[2,1]=-3*y[2]**2 + 2*y[2]
J[3,1]=-3*y[3]**2 + 2*y[3]
J[4,1]=-3*y[4]**2 + 2*y[4]
return J
y, infodict = odeint(f1, yini, times, Dfun=bandjac, full_output=1, mu=1, ml=1)
print("f1: nst: {0}, nfe: {1}, nje: {2}".format(infodict["nst"][-1],
infodict["nfe"][-1],
infodict["nje"][-1]))
将带状雅可比选项与 SciPy 的集成 odeint 一起使用的正确方法是什么?