Introduction to Ecological Modelling 2003

advertisement
1
INTRODUCTION TO ECOLOGICAL MODELLING
3.11. – 12.12.2008
Teachers (e-mail: fistname.lastname@helsinki.fi)
Prof. Veijo Kaitala (course leader), Dr. Mike Fowler (coordinator), Doc. Jouni Laakso, M.Sc.
Andreas Lindén, M.Sc. Lasse Ruokolainen, M.Sc. Aleksi Lehikoinen, MSc. Minna Pekkonen
Schedule (always at 9.15–12 o’clock)
Day
Mon
Wed
Fri
Date
3.11.
5.11.
7.11.
Room
1402
1402
1402
Topic
Introduction to ecological modelling
Overview of Matlab; a simple population model
Population growth models
Mon
Wed
Fri
10.11.
12.11.
14.11.
4403
4403
4403
Tools for population dynamics analyses
Parameter space, bifurcation
Demographic and environmental stochasticity
Mon
Wed
Fri
17.11.
19.11.
21.11.
1402
4403
4403
Harvesting, maximum sustainable yield
Patch dynamics (Spatial models, with Report)
Patch dynamics
Mon
Wed
Fri
24.11.
26.11.
28.11.
4403
4403
1402
Predator and prey in continuous time
Matrix population models
Case studies from Integrative Ecology Unit members
Mon
Wed
Fri
1.12.
3.12.
5.12.
4403
4403
4403
Favourite population model (with Report)
Working on assignments
Working on assignments
Mon
Wed
Fri
8.12.
10.12.
12.12.
4403
4403
1402
Working on assignments
Working on assignments
Closing seminar
2
MATLAB – AN OVERVIEW
The first exercises are intended for you to get used to the Matlab environment, i.e., assigning
parameters with values, handling matrices and vectors.
Notation alert!
The Matlab code in this compendium is written in Courier font.
The symbol ">>" denotes something that can be written to the command line in Matlab.
Start
Be patient with these exercises, we are practicing things that you will be needed later in the
course. Start Matlab from the Start-menu. A command window will open when you start
Matlab. You can write commands and perform calculations directly on the command window, but most of the time you will be writing program code (called m-files by their suffix .m)
with Matlab editor (starts with the command edit).
Getting help
Matlab has some help facilities that you should know about and be able to use:
demo — demonstration and tutorials, well worth a look
helpdesk — opens a graphic help window
help command, —help on specified commands, e.g. help rand
lookfor topic —finds commands related to a specified topic
Useful information is also provided by the developers of Matlab, the Mathworks company
(www.mathworks.com). There is also an active newsgroup sci.software-sys.matlab where
everything concerning Matlab is discussed.
Scalars, vectors and matrices
From Matlab's point of view, all data are stored in matrices. Matrices are tables (arrays) of
different sizes:
Scalar is the most simple of matrices as it has only one row and one column, which makes it
a single cell (also called "an element"). Scalars are simple numbers, such as 15.2.
Vectors are like tables that have only one row or a column. A row vector has one row and
several columns (in Matlab: X(1,:)), while a column vector is a single column with several
rows (in Matlab: X(:,1)).
Matrix is a table with several rows and columns (in Matlab: Y(i,j), where i and j specify
the size of the matrix). It may also be multidimensional, e.g., a three-dimensional matrix can
be thought as a stack of several two-dimensional matrices (in Matlab: Y(i,j,k)).
There is an important difference between an array and a matrix, which affects how some
mathematical operations are performed. Array operations are done element wise, e.g., the array product of two vectors results in a vector where the elements are products of the corresponding elements of the two vectors multiplied with each other. The multiplication of a column vector and row vector results in a scalar and is thus called scalar product. The multiplication of a row vectors by column vector results in a matrix product, and is therefore called a
matrix product. Multiplication of a single row vector by column vector is called a dyadic (not
allowed in Matlab). This course will not go very deep in matrix algebra, but you should be
aware that some mathematical operations are different for arrays and matrices.
3
Practice with scalars, vectors and matrices
First create a scalar variable "a" and assign it value 5.2
>> a = 5.2
Variable names can be words and may contain (but not begin with) numbers, but spaces are
not allowed. Uppercase and lowercase characters are considered to be different. Matlab
commands have to be in lowercase. It is possible to give a variable a name that is also a
Matlab command, but should not do that because you will not be able to use that command
anymore.
Then create a 31 vector ("three-by-one vector", which means three rows and one column)
that contains elements 1.4, 3.1 and 4.
>> x = [1.4; 3.1; 4]
This is called a column vector. Notice that the rows are separated by semicolons (;) and that
the dot (.) is used as a decimal separator.
A row vector ("one-by-three vector, i.e., one row and three columns) is created by separating
columns by spaces (alternatively by commas).
>> x = [1.4 3.1 4]
Use the apostrophe (') for transposing a vector or a matrix (or function transpose), which
means changing rows to columns (or vice versa):
>> x = x’
Then create a 33 ("three-by-three", i.e., three rows and three columns) matrix A
>> A = [2.1 2.9 3; 4.6 5 6.2; 7.1 8.0 9.4]
Notice that the rows of a matrix are separated by semicolons, while the entries on a row are
separated by spaces.
It is crucial to understand the difference between the index of cell in matrix and the
value stored to that cell. The index to the cell (also called an element) is the address and
the value is what is stored in that address.
Pick the first element of A and call it a (yes, A and a mean different things for Matlab). You
do it by referring to the first row and first column of the matrix A as A(1,1) and assigning its
value 2.1 to parameter a:
>> a = A(1,1)
Then pick the last element of A and give its value to parameter b:
>> b = A(end,end)
You can view the value of a variable simply by writing its name on the command window.
Once you have assigned variables with some values you can use the variable names in the
calculations, e.g.:
>> a+b
Pick the first column of A and call it y. Here, you refer to all rows of the matrix A by the colon (:)
4
>> y = A(:,1)
Similarly pick the second row of A and call it z:
>> z = A(2,:)
A useful command is “whos”, which displays the names and types of all variables in the
memory space:
>> whos
If you want to remove variables from your workspace, type clear variable name. Typing
clear without variable names removes all variables from the memory.
Note that all variables we have are arrays; the “shape'' of the array determines its exact type.
The scalar a is a 11 array, the vector x is a 31 array, and A is a 33 array (try the size
command for each variable).
Standard operations with matrices
In addition to matrix operations, multiplications, divisions etc. can be done for each of the
elements in an array.
.*
./
.^
multiplication by elements
division by elements
power by elements
In Matlab-jargon these may be called "dot-operations" to separate them from matrix operations that do not have a dot. If A and B are arrays, then Matlab can compute A + B and A – B
when these operations are defined (i.e. when A and B are equal in size). For example, create
the following matrices:
>> A = [1 2 3; 4 5 6; 7 8 9];
>> B = [1 1 1; 2 2 2; 3 3 3];
>> C = [1 2; 3 4; 5 6];
Then try to make calculations, like: A+B, A+C, A*C, C*A, A.*C, C.*A, A-1, 3*B, A^B,
A.^B which ones worked? Make sure that you understand that there is a difference between
an element-wise product A*C and the matrix prouct A.*C. If you are not familiar with the
rules of matrix multiplication, don’t worry: you will learn that when we proceed to age and
stage structured models (i.e., matrix-models).
Matlab has many commands to create special matrices; the following command creates a row
vector whose components increase arithmetically:
>> t = 1:5
The components can also change by non-unit steps, try typing
>> x = 0:.1:1
A negative step is also allowed:
>> x = 1:-0.1:0
In Matlab there are several special matrices:
zeros(m,n) creates an m  n matrix of zeros;
ones(m,n) creates an m  n matrix of ones;
eye(n)
creates the n  n identity matrix;
5
rand(m,n) creates an m  n matrix with random entries
Here is a list of useful commands, try them with differently sized matrices and vectors. Create first a 5  1 vector (for example: a = rand(5,1)) and try the following commands.
Then create a 4  4 matrix (for example: B = rand(4,4)) and try the commands again.
Now the maximums and minimums are calculated separately for each column. If you want
the largest entry in the whole matrix, type: max(max(B)), similarly: min(min(B)) gives
the smallest element.
returns the largest entry of x, if x is a vector; see help max for the result when x is
a k-dimensional array;
min(x) analogous to max;
abs(x) returns an array of the same size as x whose entries are the magnitudes of the entries of x;
size(A) returns a vector with the number of rows, columns, etc. of the k-dimensional array A;
length(x) returns the ‘’length’’ of the array, i.e. max(size(A)).
max(x)
Simple calculations with Matlab
Matlab can be used as a calculator too. Common scientific functions, such as square root, sine, cosine, tangent, exponential, and logarithm are pre-defined. For example:
>>
>>
>>
>>
sqrt(11)
cos(.5)^2+sin(.5)^2
exp(1)
log(5)
The result of the last calculation not assigned to a variable is automatically assigned to the
variable ans, which can then be used as any other variable in subsequent computations. Here
is an example:
>> 100^2-4*2*3
ans =
9976
>> sqrt(ans)
ans =
99.8799
>> (-100+ans)/4
ans =
-0.0300
6
SIMPLE MODELS OF POPULATION DYNAMICS
Loops
Loops are among the most fundamental parts of all computer programs. Loops allow you to
perform calculations and other operations repeatedly. Most simulations build on iterations,
where the output from a calculation feeds back to the same calculation as an input. For example, a discrete time population model uses current years population density N(t) as an input
for calculating next years population density N(t+1), which is in used as the input for the calculation of population density two years forward, i.e., N(t+2). The population densities are
stored in subsequent elements of a vector, where they can be retrieved for plotting and other
analyses.
Exponential growth
The first growth model we will be looking at is exponential growth in discrete time (the same
thing as geometric growth). The idea is to calculate the population size at time steps 2, 3, 4,
… n when we know the population size at time t = 1.
The exponential growth follows the equation:
N(t+1) = BN(t) + (1-D) N(t) = RN(t) = N(0)Rt
First, open the Matlab editor and create an m-file where the program code will be written:
edit expon.m (edit is the command for opening the editor and expon.m is the file name).
The m-file is a normal text file that you should save at a known location at your hard disk.
Once the file is saved, it can be executed in Matlab by typing the file name without the .m
suffix at the command window. Depending on the system, there may also be an active function key (F5) to execute the m-file directly from the editor. In the latest version you can run a
code in the “cell-mode”, where you do not have to store any .m -files.
First we must decide the simulation time T. Here we can use for example T = 50.
Then create a vector N where you will then store the population size at every time step. This
can be done using the command N = zeros(T,1). This creates a vector containing zeros
and the length of the vector equals the simulation time. Next the initial population size must
be inserted to the first element of N, for example N(1) = 10. Then we need to define the
growth rate R, for example R = 2. These were the things that had to be defined before we
get to actual calculations, which are done in for-loop. In the for-loop Matlab calculates every
year the new population size based on the previous one. Each for-loop ends with an end
command. Your m-file should contain the rows:
% You can write comments on your code after a %-sign.
% The comments will not affect how the code functions,
% but will help you to remember what each line does.
clear
% clears all variables in the memory
T = 50;
% simulation time span
R = 2;
% population growth rate
N(1) = 10;
% initial population size
for t=1:T-1
% start of a for-loop for simulation time steps
N(t+1) = R*N(t); % model for population dynamics
end
% end of a for-loop
plot(1:T,N)
% plot population density against time
Notice that some of the lines end with a semicolon (;). The calculations at those lines are
performed normally, but the results are not shown in the command window. You should use
7
semicolons to limit the output only to those parts that you are interested in. This also speeds
up the execution of the code.
You have to save the code before you can execute it (not if you prefer using the cell-mode).
Do not give a name that is the same as some Matlab function that you are using. Save the file
as firstmodel.m and run it in the command window typing firstmodel. With exponential growth it is a good idea to plot the population size on a logarithmic scale (make sure
you understand why!). Try replacing the plot-command with semilogy. Run the simulation with different values of T, R and N(1) to see their effect on the results. Try also replasing
the growth function with N(1)*R^t (it will run faster, for comparison you can type tic in
the bigginning of your code and toc in the end in order to display the time taken to run the
code). Is the output the same or different? Why?
While-loop
The calculations inside a while-loop are repeated as long as the given expression is true.
Find out of the use of while loops (use help while) and change the exponential growth
model to run as long as population density is smaller than a specified maximum density, e.g.,
100 000. Use the "smaller than" (<) operator to compare current population density N(t) to
the maximum density. You will also need to add a counter of simulation years. Initiate the
counter before the beginning of the while loop as: t = 0; Inside the loop, increase the value of the counter by one at each run of the loop as: t = t+1; It is a good idea to save the
new version of the model with a new name.
Density dependent growth
Once you have a working simulation for the exponential growth you will find it easy to create
a similar .m-file which calculates the logistic growth of a population. Change back to a forloop if you have tried the while-loop. The logistic model has an additional parameter for the
carrying capacity (K), which you have to define by giving it a numerical value (e.g. K=100).
Then replace the growth equation of exponential growth in the firstmodel.m –file with that of
logistic and save this new file as logistic.m.
N(t+1) = N(t)*exp(R*(1-N(t)/K));
Run the model and see how the outcome differs from exponential growth. Compare the dynamics with different values of population growth rate parameter R and carrying capacity K.
What is their qualitative and quantitative effect on the population?
8
BIFURCATION GRAPHS
Bifurcation graphs show how the state variable (such as population density) responds to
changes in the value of some parameter of the model. Recall the Ricker model for population
growth. The following code shows how the dynamics of the system becomes increasingly
complicated when the value of population growth rate r is increased.
clear
tspan =
tplot =
K = 10;
R_min =
R_max =
R_steps
param_R
1000;
100;
1.5;
4;
= 201;
= linspace(R_min,R_max,R_steps);
%
%
%
%
%
%
%
%
clear memory
simulation time span
time steps to be plotted
carrying capacity
smallest value of R
largest value of R
number of R values
R values
for bif = 1:R_steps
% loop for R values
R = param_R(bif);
% current R value
N = zeros(tspan,1);
% initiate population density
vector
N(1) = rand;
% initial population density
for t = 1:tspan-1
% loop for simulation year
N(t+1) = N(t).*exp(R.*(1-N(t)./K)); % model
end
R_values(:,bif) = R*ones(tplot,1);
% store R values
N_values(:,bif) = N(tspan+1-tplot:end);
% store densities
end
figure(1), clf
bif = 15;
% R step to be plotted as time series
subplot(2,1,1)
plot(R_values(:), N_values(:),'k.', R_values(:,bif),N_values(:,bif),'r*')
xlabel('R (bifurcation parameter)', 'FontSize',16)
ylabel('Population density', 'FontSize',16)
subplot(2,1,2)
plot(1:tplot,N_values(:,bif),'r-')
xlabel('Time', 'FontSize',16)
ylabel('Population density', 'FontSize',16)
Change the population model from Ricker to Maynard Smith-Slatkin: N(t+1) =
R*N(t)/(1+(a*N(t))^b). Parameters a and b stand for the strength and type of density dependence, respectively. Draw the bifurcation graph with different values of R and b. What do
these parameters to population dynamics? How do they interact?
9
STOCHASTICITY
Conditionals
In addition to loops, conditionals are another fundamental part of programming languages.
Conditionals are used for deciding between different routes the program can proceed depending on the input data. Conditionals can thus be thought as crossroads in the program code.
The following examples show you the use of if-else structure. Notice that each if-command
has to be terminated by a corresponding end command.
Demographic stochasticity
Here we model birth and death processes in a population, assuming that both processes are
density dependent random events. Each individual has a probability of dying or giving birth
to one offspring. At every run of a while-loop, we draw from exponential distribution the indivudal specific times after which either birth or death will take place. The event that actually
takes place, is the one (birth or death) that the randomization gives the shortest waiting time.
The modelled time is increased by the shortest waiting time, the size of the population is updated with either birth or death of one individual, and the loop is repeated untill the simulation has taken the predefined time-span.
The methodological lesson is the use of while-loops and conditionals. The excercise also
serves as an example of individual based modelling, where a continuous-time process is
modelled as birth and death process taking places at random (but density dependent) time intervals.
Your task is to understand how the density independent and dependent parameters of waiting
time in birth and death affect (1) population size, (2) the variability of population size, and
(3) the difference between contiuous time dynamics and discrete-time dynamics (the Ricker
model with the same parameters as the event-based model).
clear
% give parameter values
B = 1;
% background time to birth (positive)
b = 0;
% birth density dependence (zero or negative)
D = 2;
% background time to death (positive)
d = 0.01;
% death density dependence (zero or positive)
tspan = 30;
% simulation time span
N(1) = 5;
% initial density
time = 0;
% initiate time between events
k = 1;
% initiate counter of time steps
while sum(time)<tspan
k = k+1;
% update counter of time steps
% draw event times from exponental distribution
lambda_birth = B*exp(-b*N(k-1))/N(k-1);
% birth rate
lambda_death = D*exp(-d*N(k-1))/N(k-1);
% death rate
bt = -lambda_birth*log(rand);
% time to next birth
dt = -lambda_death*log(rand);
% time to next death
% the first of the randomized
if bt < dt
N(k) = N(k-1)+1;
time(k) = bt;
else
N(k) = N(k-1)-1;
events is actualized
% if birth occurs before death
% add one individual
% update counter of time
% if death occurs before birth
% remove one individual
10
time(k) = dt;
% update counter of time
end
end
% simulate Ricker model for a comparison with the individual based model
X(1) = N(1);
% initial density
for t = 1:tspan-1
% loop for time
X(t+1) = X(t) * D/B * exp((b-d)*X(t));
% Ricker model
end
figure(1), clf
plot(cumsum(time(1:k)), N(1:k), 'k-', 1:tspan,X,'b-')
legend('Event based model', 'Ricker model')
ylabel('Population size')
xlabel('Time')
The take-home message here is that in a small population demographic stochasticity has an
important role. This is crucial for conservation of endangered species. Also estimating the
birth- and death-rates is very difficult in a small population as the stochasticity plays such an
important role. This makes the conservation even more difficult.
Another point to understand is that contiuous-time and discrete time dynamics can be qualitatively different, even if the population parameters were exactly same. Clearly, the accumulation of births and deaths and time it takes for the renewal process to respond to changes in
population density, is important for population dymamics.
Environmental stochasticity
Now let’s take a look at exponential growth with environmental stochasticity. We assume
that the environment can be either ’good’ or ’bad’, this quality of environment is modeled
altering the value of the growth rate, R. It can be either Rgood = 1.25 or Rbad = 0.8. We further assume that each value of R is equally probable (i.e. the probability is 0.5 for both values).
clear
tspan = 100;
% simulation length
Rgood = 1.25;
% growth rate at good year
Rbad = 0.8;
% growth rate at bad year
N(1) = 100;
% initial density
for t = 1:tspan-1
quality = rand;
% random environmental quality
if quality < 1/2
R = Rbad;
else
R = Rgood;
end
N(t+1) = R*N(t);
end
plot(1:tspan,N)
How does the environmental stochasticity change the population dynamics? What can you
say about the average growth rate? Try repeating the simulation many times to see the influence of stochasticity. Now the geometric average or R’s is 1, try situation in which the arithmetic average is 1 (for example Rgood = 1.2 and Rbad = 0.8). Arithmetic average of a and b
= sqrt(a*b).
11
If you have time you can also try a scenario in which there is a very bad year with a very
small probability. You can try for example Rgood = 1.05, Rbad = 0.5, P(Rgood) =
0.95, P(Rbad) = 0.05. Try different values or Rgood, Rbad, P(Rgood) and P(Rbad) to see
how large catastrophies and how often the population can tolerate. How is this tolerance related to growth rate?
If you still have time left, you can try how the environmental stochasticity works with density-dependent growth. Does it differ from what happens with density-independent growth?
12
HARVESTING, MAXIMUM SUSTAINABLE YIELD
Recall the model for logistic growth in discrete time and add a parameter H to stand for harvesting (or hunting)
N(t+1) = N(t) + R*N(t)*(1-N(t)/K) – H
Start the simulation with the initial population density equal to the carrying capacity K. Try
different values of H to see what gives the highest annual yield that the population can sustain without going extinct.
clear all
T = 100;
% simulation time span
R = 2;
% population growth rate
K = 100;
% carrying capacity
H = 10;
% harvest = number of killed individuals = Yield
N = zeros(T,1); % initiate population density vector
N(1) = 100; % initial population size
for t=1:T-1 % start of a for-loop for simulation time % steps
N(t+1) = N(t) + R*N(t)*(1-N(t)/K) - H;
% model
end
% end of a for-loop
MY = H;
% max annual Yield
clf
plot(1:T,N,'b')
% plot pop. size
axis([0 100 0 100]); xlabel('Time'); ylabel('N')
hold on
plot(1:T,H,'r')
% plot annual yield
Add some degree of stochasticity (randomness) in the growth rate or harvesting parameter.
How does this affect population persistence? What are the implications to recommended harvesting levels?
One way to add stochasticity e.g., in the growth rate (inside the for-loop):
Instead of R write: (R-randn*0.3)
How does the harvesting of a fixed proportion of the population differ from the harvesting of
a fixed quantity?
Harvest a proportion:
N(t+1) = N(t) + R*N(t)*(1-N(t)/K) – h*N(t);
Now you have to collect Yield separately and plot it instead of H.
13
SPATIAL POPULATION DYNAMICS: DISPERSAL AND MORAN-EFFECT
When a population is composed of subpopulations inhabiting different patches, each patch
needs to be treated as a distinct state variable. Patches may exchange individuals by dispersal,
which makes the dynamics in local patches connected to each other. However, patches that
are not connected by dispersal may exhibit similar, synchronized population dynamics if they
share the same environmental variation and have similar density dependent growth. This is
called the "Moran effect" after the famous Australian statistician P.A.P. Moran. Two populations can, e.g., be isolated but affected by same climatic conditions.
clear
tspan = 200;
r = 2.1;
% intrinsic growth rate
d1 = 0.1; % dispersal, patch 1
d2 = 0.1; % -“patch 2
extinction = 0.01; % extinction threshold
x1 = zeros(tspan,1); % memory preallocation
x2 = zeros(tspan,1); % memory preallocation
x1(1) = rand; % initial population size, patch 1
x2(1) = rand; % initial population size, patch 2
for t = 1:tspan-1
env1(t) = rand+0.5; % random environment for patch 1
env2(t) = rand+0.5; % random environment for patch 2
% density dependent growth
x1(t+1) = x1(t)*exp(r*(1-x1(t)))*env1(t);
x2(t+1) = x2(t)*exp(r*(1-x2(t)))*env2(t);
% dispersal
x1disp = d1*x1(t+1); %individuals leaving patch 1
x2disp = d2*x2(t+1); %inds. leaving patch 2
% new population size after growth and dispersal
x1(t+1) = x1(t+1) + x2disp - x1disp;
x2(t+1) = x2(t+1) + x1disp - x2disp;
x1(x1<extinction)=0; %check for extinction events
x2(x2<extinction)=0;
end
figure(1), clf
subplot(1,2,1)
plot(1:tspan,x1,'b-', 1:tspan,x2,'r-')
subplot(1,2,2)
plot(x1,x2,'*')
Experiment with a) the amount of correlation between environmental impacts, b) the magnitude of environmental stochasticity, and c) the
amount of dispersal between patches. You need to develop the code to
adjust the correlation between the two environments. To calculate correlation between the environments or the populations, you can use function corrcoef.
14
A CONTINUOUS TIME MODEL ON RESOURCE AND CONSUMER
DYNAMICS
The following exercise is a deviation from the otherwise discrete-time models used in this
course. The code given below simulates a Lotka-Volterra -type resource-consumer (e.g.,
predator-prey) system. The resource (R) population grows logistically towards a carrying capacity. Resource density is decreased by a consumer (C), which has the saturating Holling's
Type II functional response to resource density.
 R  aRC
dR
 rR1  
dt
 K  1 hR
dC caRC

 mC
dt 1 hR
The parameters are explained in the Matlab-code below. Matlab needs two files to run this
simulation. The first file, which should be saved with the name "LVPredPreySys.m", is a user-defined function of the differential equations for predator and prey populations.
% -------------------------------------------------------function dy = LVPredPreySys(t,y)
global r K h a c m % define global variables
% Differential equations
dy = zeros(2,1);
% initialize a system vector
dy(1) = r*y(1)*(1-y(1)/K) - a*y(1)*y(2)/(1+h*y(1));% Prey
dy(2) = c*a*y(1)*y(2)/(1+h*y(1)) - m*y(2);
% Predator
% --------------------------------------------------------
The second file, which should be saved as "LVPredPrey.m", defines values for the parameters of the model and uses 4th and 5th order Runga-Kutta method for the numerical solution
(integration) of the predator and prey equations. This file also has the graphing commands for
time-series and phase-plane plots. Running this file executes the simulation.
% -------------------------------------------------------clear
% Parameters for this file and the LVPredPreySys function
global r K h a c m % define global variables
r = 0.1;
% prey intrinsic growth rate
K = 1;
% prey carrying capacity
h = 0.5;
% handling time
a = 1;
% attack rate
c = 0.1;
% conversion efficiency
m = 0.01;
% predator mortality rate
initstate = [0.1 0.01]; % initial population densities
tspan = [0 1000];
% time span of the simulation
% Numerial solution of the equations
[T,Y] = ode45('LVPredPreySys',tspan,initstate);
% Zero growth isoclines
x = linspace(0,K,30);
prey_zero = r.*(K-x).*(1+h.*x)./(K.*a);
pred_zero = m/(c*a-m*h);
figure(1), clf
15
fsize = 14; % font size
subplot(1,2,1)
% Time series
plot(T,Y(:,1),'b-', T,Y(:,2),'r-')
xlabel('Time', 'FontSize',fsize)
ylabel('Population density', 'FontSize',fsize)
legend('Prey', 'Predator')
subplot(1,2,2)
% Phase plane
plot(Y(:,1),Y(:,2),'k-', x,prey_zero,'b-', ...
[pred_zero pred_zero],[0,1.1*max(Y(:,2))],'r-')
axis tight
xlabel('Prey density', 'FontSize',fsize)
ylabel('Predator density', 'FontSize',fsize)
% --------------------------------------------------------
Using this system you may, e.g., study how population sizes and system stability change
when:
1.
2.
3.
4.
prey growth rate changes,
prey carrying capacity changes,
predator mortality changes,
there is interference competition within the predator population. (Hint: add densitydependence in predator mortality).
Notice, that in (4) you should also derive new equations for the zero-growth
rate isoclines. You can do this by setting the population equations equal to zero and solving the resource equation for consumer density and consumer
equation for resource density. After all the simulations you have done by now,
you have ended up using pen and paper (or symbolic mathematics software,
but that's another story).
16
MATRIX MODELS
Age is a continuous variable, but discrete time models make the census to the modelled population (usually) once a year, and individuals will therefore always be of an age that can be
expressed as integer numbers. When individuals are classified in age groups, the age-specific
probabilities for individuals to survive to the next age class (survive to next year) and then
per capita number of offspring produced can be expressed in a Leslie matrix.
When individuals are classified according to their life history stage, such as newborn, juvenile, adult, or seed, vegetative plant, flowering plant, they may spend several years in the
same stage. The matrices formed according to the classification to life history stages are
called Lefkovitch matrices.
The choice between age and stage structured population models should be done according to
their relation to the vital rates, such as survival and fecundity. Birds, fish and mammals are
usually modelled with age structure, while classification according to life-history stage may
be more relevant for plants and invertebrates.
The methodological lesson here is that population state can be a vector instead of a scalar. It
would be possible to model each state variable (such as age or stage class, species, or ecosystem compartment in element cycling) of the system as a separate equation, but this becomes
highly unpractical when the number of state variables is large and impossible when the number of state variables changes during the simulation. The ability to perceive system state as a
vector enables you to write compact and easy-to-read code, which helps to keep it free from
bugs. The ability to separate system matrix that determines the dynamics, from the system
vector enables you to utilize very efficient methods for analysing system dynamics. Becoming accustomed to matrix-vector presentation may feel like major rewiring in your cerebral
network, but it is well worth the effort!
Age structure population
Now we have a population with different age classes. Here we start with 3 classes, but it is
easy to add more. Let Px denote the probability that an individual starting in age class x survives through the entire time step (here x = 1, 2 or 3). Similarly let Fx be the fertility of an
individual in age group x. Also let nx(t) be the number of individuals in age group x at time t.
Now we can calculate the number of new offspring using the sizes of different age classes
and fecundities in the age classes:
n1t  1 F1n1t  F2n1t  F3n1t 
The number of individuals in age class 2 at the next time step is the proportion of individuals
that survive the previous time step in age class 1:
n2t  1 P1n1t 
Similarly the age class 3 at next time step is the proportion of individuals in age class 2 that
survive:
n3t  1 P2n2t 
Now these three equations can be represented in matrix form. The survival probabilities and
fecundities are collected in matrix A, while age-class specific population densities are placed
in vector n(t):
17
 F1
A   P1

0
F2
0
P2
F3 
0

0
n1 
nt   
n2
t 

 

n3
Using this notation we can write the model as the sum of transition matrix A and system state
vector n(t):
nt  1  Ant 
Notice that the product of A and n(t) is a matrix-product, which is different from a product by
elements. Let’s try a numerical example. Open the editor and write:
clear
tspan = 20;
% a matrix can be written on several rows
A = [0.5
1
0.75
0.666 0
0
0
0.3333 0];
n = zeros(3,tspan);
s = zeros(1,tspan);
n(:,1) = [2;0;0]; % initial population densities
for t = 1:tspan-1
n(:,t+1) = A*n(:,t);
% a matrix-vector product!
end
% If a command does not fit on a single line,
% three dots (...) are used for break it:
figure(1), clf
plot(1:tspan, n(1,:),'b-',1:tspan,n(2,:),'r-', ...
1:tspan,n(3,:),'g-')
Save the file as leslie1.m and try running it.
The matrix n consists of column vectors containing the sizes of 3 age groups. n(:,1) is the initial distribution of animals belonging to age groups 1, 2 and 3 (first column in the matrix). In
the for-loop the program calculates first n(:,2), then n(:,3) etc.
Use semilogy for plotting the population size in a logarithmic scale at the y-axis. You
should see that after a couple of time steps the population growth becomes exponential.
Eigenvalue analysis: sensitivity and elasticity in a plant population
The transition matrix of a age or stage structured population model contains all factors intrinsic to the population itself that affect its dynamics. Certain characteristics of the transition
matrix can therefore be used in the analysis of population dynamics without simulations. We
will concentrate on the measures that indicate the asymptotic dynamics of the population, i.e.,
the dynamics that the population approaches over time, but other measures are able to provide insight of the transient behaviour of the system as well.
The growth rate can be calculated from the time-series, but it is also equals to the dominant
eigenvalue of the transition matrix A. The scalar (i.e. number)  is an eigenvalue and w is the
corresponding eigenvector if Aw = w. Eigenvalue-problems could be devoted a course of
their own, but now it is sufficient to understand that a matrix can be replaced by an eigenvalue (i.e., growth rate) when the state of the population n(t) corresponds to the stable state of
the system (w). Try:
L = eig(A)
18
R = max(L)
Try then altering the values of fecundities and survival rates and observe how the population
behaves.
The following Leslie-matrix describes the red deer population in isle of Rhum, Scotland. The
population is being hunted and these fecundities and survivorships are estimated with hunting
in presence. The question here is whether the hunting keeps the population in check, i.e. its
geometric growth factor R near one.
0 0 .26 .26 .26 .26 .35 .26 .31


0
0
0
0
0
0
0 
1 0


0
0
0
0
0
0 
0 .94 0
0 0 .80 0
0
0
0
0
0 




0
0
0
.67
0
0
0
0
0
red 


0 0
0
0 .61 0
0
0
0 


0
0
0 .63 0
0
0 
0 0


0
0
0
0 .72 0
0 
0 0
0 0
0
0
0
0
0 .22 0 


Enter the matrix into Matlab. The geometric growth factor is equal to the dominant (i.e. largest real) eigenvalue. Try typing
>> [w,L] = eig(red)
>> R = max(diag(L))
>> r = log(R)
[w,L] = eig(red) calculates the eigenvalues (L) and eigenvectors (w) of matrix red. R
is the dominant eigenvalue. What can you conclude about the hunting, is it keeping the population in check? The stable age distribution can be also calculated from the Leslie-matrix. It
equals the eigenvector corresponding to the dominant eigenvalue. In this example we have
already calculated the eigenvectors (w), so we only have to pick the first one (w(:,1),
which corresponds to the dominant eigenvalue) and divide it by its sum to get an age distribution which sums up to one.
>> c = w(:,1)/sum(w(:,1))
>> figure
>> bar(c)
Below is a transition matrix for an imagined plant species. The population is divided into
three life-stages: seeds, vegetative individuals and fertile individuals. The transitions between
the stages form the matrix A.
clear
A =
[
0.1
0
10
0.05 0.2
.6
0
0.3
.2]
[L,ind] = max(real(eig(A)));
lambda = L
[W,L] = eig(A);
w = W(:,ind);
[L,ind] = max(real(eig(A')));
lambda = L;
%
%
%
%
%
%
dominant eigenvalue...
...is population growth rate
right eigenvectors
stable distribution
dominant eigenvalue...
...is population growth rate
19
[V,L] = eig(A');
v = V(:,ind);
w = w./sum(w)
v = v./v(1)
sens = v*w'./(v'*w)
elast = A./lambda.*sens
%
%
%
%
%
%
left eigenvectors
reproductive values
scaling to sum to unity
scaling to first stage
sensitivities
elasticities
The Matlab code below that performs the sensitivity and elasticity analyses for the dominant
eigenvalue of matrix A. What can you say about the ecology of the plant in the light of this
analysis? What do sensitivity and elasticity analyses tell about the Red deer, when you place
matrix red in place of the plant matrix?
20
MY FAVORITE POPULATION MODEL
Deadline 18:00, 10.12.2008
Choose an ecological problem or question, formulate the problem as a mathematical model or
take a model from literature. Analyse the model using Matlab. Report your work in written
form, with the following components
Name, student number and course are all vital, then:
1. Introduction – should give some background to your study (including important literature) and state your aim clearly
2. Model and analysis – clearly describe the system you are studying, including any
equations that feature in your model. The information here must allow someone reading the report to replicate what you did exactly!
3. Results – Present your model outcomes and results here, using graphs, tables, statistics, equations, whatever communicates your results most clearly to an uninformed
reader.
4. Discussion – Relate your results to other work and important concepts. You can be
speculative here, but not ridiculous.
5. References – List all literature you have cited in your report, including books, journal
articles and web-sites. Beware of websites, though – they are not peer-reviewed and
may not all be suitable to back up any arguments you make.
6. Appendix: the Matlab-code to generate any results shown in the report.
We are all subjective readers. The way you report your work will be part of our judgment
about its quality, so — make it look good!
Download