7

Can anybody give me some advice how to solve an ODE in Python that has a time-delay implemented in it? I can't seem to figure out how to do it using scipy.integrate.odeint. What I am looking for should look like:

# 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 = ...

Where the N(t), N(t - tau) etc. indicate the time arguments of the functions. Does a good library exist to solve these types of equations? Many thanks in advance!

ThePiIsALie
  • 71
  • 1
  • 4

1 Answers1

5

I am the author of JiTCDDE, which can solve delay differential equations and is mostly analogous to scipy.ode. You can install it, e.g., with pip3 install jitcdde. As far as I know, the other existing DDE libraries for Python are either broken or based on deprecated dependencies.

The following code would integrate your problem:

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) )
Wrzlprmft
  • 4,234
  • 1
  • 28
  • 54
  • Thank you, your library looks promising, I will definitely give it a shot! – ThePiIsALie Mar 06 '17 at 21:26
  • In my code this library creates all sorts of problems, since it uses SymPy which I didn't use before (I only wanted to integrate numerically). Is there a way around this? – ThePiIsALie Mar 07 '17 at 10:22
  • No, SymPy is an unavoidable requirement, as it is used for the interface. But since this is a pretty popular module, it should be easy to install (I do not see how it would cause other problems). — The most likely portability issue is the just-in-time compilation which needs an environment that can build a Python C module, but you can bypass this by using the Python kernel, which is however much slower. – Wrzlprmft Mar 07 '17 at 10:27
  • I have SymPy installed, but it gives me the error "TypeError: cannot determine truth value of Relational" for many thing I was previously doing in the code. However, I will try and see if I can work these out. Thanks! – ThePiIsALie Mar 07 '17 at 12:32
  • @ThePiIsALie: Just so I get this right: Just by installing SymPy, some existing code of yours began to throw errors? That would be very weird. – Wrzlprmft Mar 07 '17 at 12:39
  • No, I already had SymPy. The example I gave in my question was only a minimal working example. My actual code contains a few functions that come together in the integration, and SymPy doesn't accept the way they were defined, since they aren't SymPy functions. – ThePiIsALie Mar 07 '17 at 13:44
  • @ThePiIsALie: I see. In that case, you have to indeed adapt your code. But I presume that my version of your minimal example works? – Wrzlprmft Mar 07 '17 at 13:48
  • Indeed, and I like the user-friendlines of your library also. – ThePiIsALie Mar 07 '17 at 13:49
  • Can it solve problems like [this](https://math.stackexchange.com/questions/2272848/how-to-solve-delayed-partial-differential-equations) – user6043040 Oct 08 '17 at 12:42
  • 1
    @user6043040: Not directly. You would have to discretise the spacial aspect of your problem first (which any solver would have to do). Also note that for partial differential equations, you can usually speed things up by using parallelisation techniques due to their regular structure, which JiTCDDE doesn’t support (as it is not aimed at this case). – Wrzlprmft Oct 08 '17 at 12:48
  • @Wrzlprmft does provide_basic_symbols still exist? I get the error `ImportError: cannot import name 'provide_basic_symbols' from 'jitcdde' (/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/jitcdde/__init__.py)` – jjrr Oct 24 '19 at 16:53
  • 1
    @jjrr: No, I got rid of this due to being unnecessarily complicated and unpythonic. You can now import those symbols directly. See my edit. – Wrzlprmft Oct 24 '19 at 22:36