Решите ODE в Python с временной задержкой

Может ли кто-нибудь дать мне совет, как решить ODE в Python, в котором реализована временная задержка? Я не могу понять, как это сделать, используя scipy.integrate.odeint. То, что я ищу, должно выглядеть так:

# the constants in the equation
b = 1/50
d = 1/75
a = 0.8
G = 10 ** (-2)
tau = 0.5
u = [b, d, tau, a, G]

# enter initial conditions
N0 = 0.1
No0 = 10
w = [N0, No0]

def logistic(w, t, u):
    N, No = w
    b, d, tau, a, G = u
    dNdt = b * (No(t) - N(t) ) * (N(t) / No(t) ) - d * N(t - tau)
    dNodt = G * (a * No(t) - N(t) ) * (N(t) / No(t) )
    return [dNdt, dNodt]

# create timescale
# create timescale
stoptime = 1000.0
numpoints = 10000
t = np.linspace(0, stoptime, numpoints)

# in my previous code I would use scipy.integrate.odeint here to integrate my 
# equations, but with a time-delay that doesn't work (I think)
soln = ...

Где N(t), N(t - тау) и т.д. указывают временные аргументы функций. Существует ли хорошая библиотека для решения этих типов уравнений? Спасибо заранее!


person ThePiIsALie    schedule 06.03.2017    source источник


Ответы (1)


Я являюсь автором JiTCDDE, который может решать дифференциальные уравнения с запаздыванием и в основном аналогичен scipy.ode. Вы можете установить его, например, с помощью pip3 install jitcdde. Насколько я знаю, другие существующие библиотеки DDE для Python либо сломаны, либо основаны на устаревших зависимостях.

Следующий код интегрирует вашу проблему:

from jitcdde import t, y, jitcdde
import numpy as np

# the constants in the equation
b = 1/50
d = 1/75
a = 0.8
G = 10**(-2)
tau = 0.5

# the equation
f = [    
    b * (y(1) - y(0)) * y(0) / y(1) - d * y(0, t-tau),
    G * (a*y(1) - y(0)) * y(0) / y(1)
    ]

# initialising the integrator
DDE = jitcdde(f)

# enter initial conditions
N0 = 0.1
No0 = 10
DDE.add_past_point(-1.0, [N0,No0], [0.0, 0.0])
DDE.add_past_point( 0.0, [N0,No0], [0.0, 0.0])

# short pre-integration to take care of discontinuities
DDE.step_on_discontinuities()

# create timescale
stoptime = 1000.0
numpoints = 100
times = DDE.t + np.linspace(1, stoptime, numpoints)

# integrating
data = []
for time in times:
    data.append( DDE.integrate(time) )
person Wrzlprmft    schedule 06.03.2017
comment
Спасибо, ваша библиотека выглядит многообещающе, обязательно попробую! - person ThePiIsALie; 07.03.2017
comment
В моем коде эта библиотека создает всевозможные проблемы, поскольку использует SymPy, который я раньше не использовал (я хотел только численно интегрировать). Есть ли способ обойти это? - person ThePiIsALie; 07.03.2017
comment
Нет, SymPy является неизбежным требованием, так как он используется для интерфейса. Но поскольку это довольно популярный модуль, его должно быть легко установить (я не вижу, как это вызовет другие проблемы). — Наиболее вероятная проблема с переносимостью — это своевременная компиляция, для которой требуется среда, которая может построить модуль Python C, но вы можете обойти это, используя ядро ​​​​Python, которое, однако, намного медленнее. - person Wrzlprmft; 07.03.2017
comment
У меня установлен SymPy, но он выдает ошибку TypeError: невозможно определить истинное значение Relational для многих вещей, которые я ранее делал в коде. Тем не менее, я постараюсь и посмотреть, если я могу решить эти. Спасибо! - person ThePiIsALie; 07.03.2017
comment
@ThePiIsALie: Я правильно понял: просто после установки SymPy какой-то ваш существующий код начал выдавать ошибки? Это было бы очень странно. - person Wrzlprmft; 07.03.2017
comment
Нет, у меня уже был SymPy. Пример, который я привел в своем вопросе, был лишь минимальным рабочим примером. Мой фактический код содержит несколько функций, которые объединяются при интеграции, и SymPy не принимает то, как они были определены, поскольку они не являются функциями SymPy. - person ThePiIsALie; 07.03.2017
comment
@ThePiIsALie: Понятно. В этом случае вам действительно нужно адаптировать свой код. Но я предполагаю, что моя версия вашего минимального примера работает? - person Wrzlprmft; 07.03.2017
comment
Действительно, и мне также нравится удобство вашей библиотеки. - person ThePiIsALie; 07.03.2017
comment
Может ли он решать такие задачи, как эта - person user6043040; 08.10.2017
comment
@ user6043040: Не напрямую. Сначала вам нужно будет дискретизировать пространственный аспект вашей проблемы (что должен сделать любой решатель). Также обратите внимание, что для уравнений в частных производных вы обычно можете ускорить работу, используя методы распараллеливания из-за их регулярной структуры, которую JiTCDDE не поддерживает (поскольку она не предназначена для этого случая). - person Wrzlprmft; 08.10.2017
comment
@Wrzlprmft Provide_basic_symbols все еще существует? Я получаю сообщение об ошибке ImportError: cannot import name 'provide_basic_symbols' from 'jitcdde' (/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/jitcdde/__init__.py) - person jjrr; 24.10.2019
comment
@jjrr: Нет, я избавился от этого из-за излишней сложности и отсутствия питона. Теперь вы можете импортировать эти символы напрямую. Смотрите мою правку. - person Wrzlprmft; 25.10.2019