Search code examples
pythonodeodeint

How to shorten ODE equations using ancillary functions


I would like to shorten my ODE equations somehow, becuase the code will become messy otherwise. I have tried using ancillary functions, like fe() here, but this doesn't work. The code below is just an example Any advice is welcomed! Thanks!

# Import the required modules
import numpy as np
import matplotlib.pyplot as plt

from scipy.integrate import odeint

# Here the parameters
a,b,c,d = 1,1,1,1

def fe(P[0]):
    return d*P[0]

# Define a function which calculates the derivative
def dP_dl(P, l):
    return [P[0]*(a - b*P[1]),
            -P[1]*(c - fe(P[0]) )]


ts = np.linspace(0, 12, 100)
P0 = [1.5, 1.0]
Ps = odeint(dP_dl, P0, ts) 
prey = Ps[:,0]
predators = Ps[:,1]


plt.plot(ts, prey, "+", label="Rabbits")
plt.plot(ts, predators, "x", label="Foxes")
plt.xlabel("Time")
plt.ylabel("Population")
plt.legend();

This is what i got from the python console.

Python 3.6.3 |Anaconda, Inc.| (default, Oct 15 2017, 07:29:16) [MSC v.1900 32 bit (Intel)] Type "copyright", "credits" or "license" for more information.

IPython 6.1.0 -- An enhanced Interactive Python.

runfile('C:/Users/Matteo S/Desktop/vocaboli tedesco/untitled0.py', wdir='C:/Users/Matteo S/Desktop/vocaboli tedesco') Traceback (most recent call last):

File "C:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2862, in run_code exec(code_obj, self.user_global_ns, self.user_ns)

File "", line 1, in runfile('C:/Users/Matteo S/Desktop/vocaboli tedesco/untitled0.py', wdir='C:/Users/Matteo S/Desktop/vocaboli tedesco')

File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 710, in runfile execfile(filename, namespace)

File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 101, in execfile exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Matteo S/Desktop/vocaboli tedesco/untitled0.py", line 17 def fe(P[0]): ^ SyntaxError: invalid syntax


Solution

  • The functions should not know that you are passing the first element of an iterable, he should only know that you are passing a number. On the other hand in the case the function dP_dl is styled to separate the components to make it more readable.

    # Import the required modules
    import numpy as np
    import matplotlib.pyplot as plt
    
    from scipy.integrate import odeint
    
    # Here the parameters
    a,b,c,d = 1,1,1,1
    
    def fe(x): return d*x
    
    # Define a function which calculates the derivative
    def dP_dl(P, l):
        x1, x2 = P
        dx1dt = x1*(a-b*x2)
        dx2dt = -x2*(c-fe(x1)) 
        return dx1dt, dx2dt
    
    
    ts = np.linspace(0, 12, 100)
    P0 = [1.5, 1.0]
    Ps = odeint(dP_dl, P0, ts) 
    prey = Ps[:,0]
    predators = Ps[:,1]
    
    
    plt.plot(ts, prey, "+", label="Rabbits")
    plt.plot(ts, predators, "x", label="Foxes")
    plt.xlabel("Time")
    plt.ylabel("Population")
    plt.legend();
    plt.show()