In-Class#

Coding Practice#

Code 13.1: Predator-Prey Update#

We will write a Python module to simulate and visualize population dynamics of a predator-prey system

\[\begin{split} \begin{align*} \Delta N &= r N \left(1 - \frac{N}{K}\right) - a P \frac{N}{N + D}\\ \Delta P &= s P \left(1 - \frac{mP}{N}\right) \end{align*} \end{split}\]

with the parameters \(r\), \(K\), \(a\), \(D\), \(s\), and \(m\). Here, \(N\) and \(P\) are the population sizes of the prey and predator, respectively, and \(\Delta N\) and \(\Delta P\) are the changes in the population sizes per unit time.

We will test the code using the parameters \(r=0.16\), \(K=2400\), \(a=5\), \(D=1000\), \(s=0.01\), and \(m=2\), with the initial population sizes \(N_0=120\) and \(P_0=40\). You can assume that the population sizes are in thousands, and that the time unit is one week.

Our goal is to define a class PredatorPrey, where object of this class store the parameters of the model. The class should have a method which updates the population sizes according to the models equations.

Start by defining the class PredatorPrey and the __init__ method which initializes the six attributes of the class. Make also a __str__ method which returns a string with the parameters of the model.

Now we want to write the method update which given the population sizes of the prey and predator returns the updated population sizes. The method should, apart from self, take two arguments N and P which are the population sizes. Inside the method calculate the values of \(\Delta N\) and \(\Delta P\) and return the tuple with \(N + \Delta N\) and \(P + \Delta P\).

Now we can use the class for the first attempt to simulate the population dynamics. Starting with the parameters as in the check above, write a for-loop which updates the population sizes for 1000 iterations. In the loop. plot the population sizes of the prey and predator as a point in the predator-pray plane using the Matplotlib library. Your plot should look similar to the one below.

../_images/47334c0492e3f359da6e9d81006dd33cad2a5b7bc39059ce902a2e291930a45e.png

Try also plotting the time evolution of the population sizes of the prey and predator. Your plot should look similar to the one below.

../_images/e395506e7f2962fc5af3a6172c6f259cc11fee81655ec753f0e35124ea1da54d.png

Code 13.2: Predator-Prey Evolution#

We would like to plot the evolution as a curve, and not as points. To do this, we need to store the population sizes in a list.

Modify your code such that you before the loop define two lists N_values and P_values, which initially only contain the initial population sizes. In the loop, append the updated population sizes to the lists. After the loop, plot the lists using the Matplotlib library. Your plot should look similar to the one below.

../_images/f8c622c509337d6ef3dff2a1c3844c79e5475a28b273f4804a30f37225303d5d.png

Instead of looping in the main code, write a method evolve in the class PredatorPrey. The method should take the initial population sizes and the number of iterations as arguments. The method should return the lists N_values and P_values.

Instead of plotting in the main code, define a method plot_evolution in the class PredatorPrey. The method should take the initial population sizes and the number of iterations as arguments. The method should produce two plots. The firs is a phase plot where prey and predator populations are plotted against each other. The second is a time plot where prey and predator populations are plotted against the iteration number. Add as many information to the plots as you find useful: labels, titles, legends, etc. The code below shows how the method should be used, and you can look at the produced plots for inspiration.

model = PredatorPrey(0.16, 2400, 5, 1000, 0.01, 2)
model.plot_evolution(120, 40, 1000)
../_images/63f382a424f1222b64078399a992a8d44701d504c6bd7cf78c6268dfd80e3eec.png ../_images/984cc29186327bf89a4497a2ae4f9000b9774f4cdcc50e4a78f8576a37b44606.png

Code 13.3: Predator-Prey Module#

Once you have a well-working class, divide your code in two python files. Name one file predator_prey.py and keep only class definition in it. This is the module we produced. You need to import Matplotlib in the module, since you use it in the method which plots the evolution. Name the other file predator_prey_simulation.py. This is the main script. In the main script, import the class from the module. Use the class to produce the plots as in the previous exercise.

If you have done everything correctly, your main script need only to contain three lines of code.

By separating your code in the module and the script, you can reuse the module in the other scripts, and your script is simpler and easier to read.

Problem Solving#

Problem 13.4: Allee Effect Analysis#

You should write a Python module which can be used to analyze the Allee effect in a population. The Alle effect is modeled using the differential equation

\[ \frac{\mathrm{d}N}{\mathrm{d}t} = r N \left(1 - \frac{N}{K}\right) \left(\frac{N}{A} - 1\right) \]

where \(N\) is the population size, \(r\) is the growth rate, \(K\) is the carrying capacity, and \(A<K\) is the Allee threshold.

You should make a class AlleeEffect which has the following methods:

  • __init__ which initializes the attributes of the class, which are the growth rate \(r\), the carrying capacity \(K\), and the Allee threshold \(A\).

  • __str__ which returns a string with the parameters of the model. You can choose the format of the string.

  • update which given the population size \(N\) and the time step \(\Delta t\) returns the updated population size \(N + \frac{\mathrm{d}N}{\mathrm{d}t}\Delta t\).

  • evolve which given the initial population size, the length of the time interval, and the time step \(\Delta t\) returns the list of time steps and the list of population sizes. The list of time steps should start with 0, increase by \(\Delta t\), and end with the length of the time interval. The list of population sizes should start with the initial population size and be updated using the update method.

  • plot_evolutions which given the list of initial population sizes, the length of the time interval, and the time step \(\Delta t\), produces a plot of the population sizes as a function of time. The plot should contain as many curves as there are initial population sizes.

Place the class in the module allee_effect.py and write a script allee_effect_simulation.py which imports the class and uses it to produce a plot of the population size as a function of time. Use the parameters \(r=0.03\), \(K=9000\), and \(A=1000\), a number of initial population size in a interval between 0 and 10000, the time step \(\Delta t=0.1\) and the length of the time interval \(T=100\).

Look at the code below and the plot for the desired behavior of the script.

from alle_effect import AlleeEffect as AE
model = AE(0.03, 9000, 1000)
model.plot_evolutions(list(range(0, 10000, 100)), 100, 0.1)
../_images/d36e6927a4daa6ef65eae1c1aeee144643d8054f32c45489d1925e1173f3d3c0.png