A primer on predator-prey population dynamics via the Lotka–Volterra ODEs
Today, we are once again dealing with the math of differential equations.
I’ve mentioned them so many times in my previous posts that they are almost getting old at this point. And it’s really interesting for me at least, to see how the tools of Physics find themselves into so many, hitherto unrelated fields of study.
But let’s get into it, and just have a brief discussion on the origins.
It started out from the American scientist, Alfred J. Lotka, who chanced upon the works of the renowned Soviet Mathematician Andrey Kolmogrov.
Drawing inspiration from Kolmogrov, Lotka had an epiphany and decided to extend his work in the study of statistical thermodynamics of chemical reaction, to the study of bioinformatics.
Interestingly enough, the same conclusions were also derived in parallel, around the same time by Italian Physicist, Vito Volterra. In recognition of the contributions of both individuals, the equations is hence named after both of them.
The Lotka-Volterra Equations
And this is our start point.
In order to estimate the number of predator and prey at various times.
We do need to integrate these 2 coupled nonlinear ordinary differential equations.
Again, credit must be given where it is due.
The following code samples are referenced from this book, with minor edits for clarity.
Numerical Integration
In the subsequent section, We utilise the Integrate function from Scipy. However, it may be of note that there are 2 different packages for numerical integration under the scipy.integrate function.
- integrate.odeint
- integrate.ode
These two functions connect to two different underlying Fortran libraries, optimized and written by the consummate scientific computing professionals over at the Lawrence Livemore National Laboratory.
The documentation may be found here: https://computing.llnl.gov/casc/odepack/
Perhaps for the truly complex calculations such as those pertaining to nuclear research, one would have to be mindful of the differences in how each library is written and optimized.
Thankfully for most use cases, we need not bother.
Here are the code samples used in calculating the Lotka-Volterra equations.
##Importing dependenciesimport numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
First, we set values of the parameters between species. Values are arbitrarily chosen, as given in the book. They can be tweaked to fit any ecosystem.
Next we define the function required. They are as per the differential defined.
a, b, c, d = 0.4, 0.002, 0.001, 0.7 def f(xy, t):
x, y = xy
return[a * x - b * x * y, c * x * y - d* y]
Setting the initial conditions, or in other cases, they are called the boundary value conditions. Here, we have chosen to define the populations at t=0, as 600 (prey), and 400(predators).
I am not 100% certain how Fortan calculates the integral, but it appears to be using a variant of the Finite Difference Method (FDM), given the format of the input, which is the np.linspace() function.
It works, through np.linspace(‘Start’, ‘Stop’, ‘Interval’).
Whereby the time boundary is from zero to fifty, interspaced by 250 discrete intervals.
Finally, we feed the 3 inputs into the ODE solver.
- The function (f)
- The initial conditions (xy0)
- The time scales we wish to iterate over (t)
Predictably, we obtain the form of the solution,
A 2-D array of the values of predator and prey over 250 intervals of time.
xy0 = [600, 400]
t = np.linspace(0, 50, 250)
xy_t = odeint(f, xy0, t)
xy_t.shape
< (250, 2) >
Finally, a visualisation of the population dynamics via two different plots.
fig, axes = plt.subplots(1, 2, figsize=(10,4))
axes[0].plot(t, xy_t[:,0], 'r', label='Prey')
axes[0].plot(t, xy_t[:,1], 'b', label='Predator')
axes[0].set_xlabel('Time')
axes[0].set_ylabel("Number of animals")
axes[0].legend()axes[1].plot(xy_t[:,0], xy_t[:,1], 'k')
axes[1].set_xlabel('Number of prey')
axes[1].set_ylabel('Number of predators')plt.tight_layout(pad=3.0)
Closing remarks
Naturally, the prey and predator exist in some sort of dynamic equilibrium. With the numbers of each species balancing each other.
Intuitively, it makes sense.
- If the predators hunt the prey too much, there is too few prey left. Some predators starve to death.
- With the numbers of predators resume, the prey gets the breathing space to multiply and rise in number.
However, this is reflective of an extremely simple ecosystem, with 2 species.
In reality, there are multiple predator species which feed on a certain prey, and each predator can feed on multiple species of prey.
We also need to account for the variations in the lifespans of each species, whether diseases are circulating among them, the climate of the time of the year and many others.
And that will be venturing into the realm of Complex Dynamical Systems.
That will be a post for another time.
Thank you and check back again soon!