gpt4 book ai didi

python - 为什么在 SciPy 中使用 integrate.odeint 时不调用 Dfun(gradient)?

转载 作者:太空狗 更新时间:2023-10-29 20:14:28 25 4
gpt4 key购买 nike

谁能提供一个向 SciPy 中的 integrate.odeint 函数提供 Jacobian 行列式的示例?我尝试从 SciPy 教程 odeint example 运行这段代码但似乎从未调用过 Dfun()(雅可比函数)。

from numpy import * # added
from scipy.integrate import odeint
from scipy.special import gamma, airy
y1_0 = 1.0/3**(2.0/3.0)/gamma(2.0/3.0)
y0_0 = -1.0/3**(1.0/3.0)/gamma(1.0/3.0)
y0 = [y0_0, y1_0]


def func(y, t):
return [t*y[1],y[0]]


def gradient(y,t):
print 'jacobian' # added
return [[0,t],[1,0]]


x = arange(0,4.0, 0.01)
t = x
ychk = airy(x)[0]
y = odeint(func, y0, t)
y2 = odeint(func, y0, t, Dfun=gradient)
print y2 # added

最佳答案

在幕后,scipy.integrate.odeint使用 ODEPACK FORTRAN library 中的 LSODA 求解器.为了处理您尝试集成的功能是 stiff 的情况, LSODA 在两种不同的积分计算方法之间自适应切换 - Adams' method ,速度更快但不适合刚性系统,并且 BDF ,它速度较慢但对刚度很稳健。

您尝试集成的特定函数是非刚性函数,因此 LSODA 将在每次迭代中使用 Adams。您可以通过返回 infodict (...,full_output=True) 并检查 infodict['mused'] 来检查这一点。

由于 Adams 的方法不使用 Jacobian,因此永远不会调用您的梯度函数。然而,如果你给 odeint 一个刚性函数来集成,比如 Van der Pol equation :

def vanderpol(y, t, mu=1000.):
return [y[1], mu*(1. - y[0]**2)*y[1] - y[0]]

def vanderpol_jac(y, t, mu=1000.):
return [[0, 1], [-2*y[0]*y[1]*mu - 1, mu*(1 - y[0]**2)]]

y0 = [2, 0]
t = arange(0, 5000, 1)
y,info = odeint(vanderpol, y0, t, Dfun=vanderpol_jac, full_output=True)

print info['mused'] # method used (1=adams, 2=bdf)
print info['nje'] # cumulative number of jacobian evaluations
plot(t, y[:,0])

您应该看到 odeint 切换到使用 BDF,现在调用了 Jacobian 函数。

如果你想更好地控制求解器,你应该查看 scipy.integrate.ode ,这是面向多个不同集成商的更加灵活的面向对象的接口(interface)。

关于python - 为什么在 SciPy 中使用 integrate.odeint 时不调用 Dfun(gradient)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17533751/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com