Под капотом scipy.integrate.odeint
a> использует решатель LSODA из библиотеки ODEPACK FORTRAN. Чтобы иметь дело с ситуациями, когда функция, которую вы пытаетесь интегрировать, является жесткой, LSODA адаптивно переключается между двумя разными методами вычисления интеграла — методом Адамса, который быстрее, но не подходит. для жестких систем и BDF, который медленнее, но устойчив к жесткости.
Конкретная функция, которую вы пытаетесь интегрировать, не является жесткой, поэтому LSODA будет использовать Адамса на каждой итерации. Вы можете проверить это, вернув infodict
(...,full_output=True
) и проверив infodict['mused']
.
Поскольку метод Адамса не использует якобиан, ваша функция градиента никогда не вызывается. Однако если вы зададите odeint
жесткую функцию для интегрирования, такую как уравнение Ван-дер-Поля:
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, и теперь вызывается функция Якоби.
Если вам нужен больший контроль над решателем, вам следует изучить scipy.integrate.ode
, который представляет собой гораздо более гибкий объектно-ориентированный интерфейс для нескольких различных интеграторов.
person
ali_m
schedule
09.07.2013