import matplotlib
if not hasattr(matplotlib.RcParams, "_get"):
matplotlib.RcParams._get = dict.get
Theory#
This project studies age-structured population models using linear algebra. The main idea is to describe a population at time \(k\) by a vector
where each entry represents the number of individuals in a specific age class (or stage class). The population evolves in discrete time steps (months/years) through a transition matrix \(A\):
The long-run behavior is governed by eigenvalues and eigenvectors of \(A\).
Setup#
import numpy as np
import matplotlib.pyplot as plt
1. Discrete dynamical systems#
A discrete dynamical system is a rule that updates the state in steps:
In this project, \(F\) is (mostly) linear:
Iterating gives
This viewpoint is useful because:
it separates model assumptions (encoded in \(A\)) from computation,
it connects simulation to theoretical tools (spectral theory).
2. Warm-up idea: Fibonacci as a matrix model#
Fibonacci-type growth can be written as a 2-class age model (young/adult). In that case, the update is linear and can be encoded in a \(2\times 2\) matrix. The key takeaway is not the specific rabbit story, but the modeling principle:
Rows in \(A\) describe how each next-step class is formed from current classes.
Columns in \(A\) describe how each current class contributes to future classes.
3. Eigenvalues, eigenvectors, and growth rates#
An eigenvalue \(\lambda\) and eigenvector \(\boldsymbol{v}\neq 0\) satisfy
Interpretation in population models:
If the population is exactly proportional to \(\boldsymbol{v}\) at some time, then it stays proportional forever.
The total size scales by the factor \(\lambda\) each time step.
If \(A\) is diagonalizable with eigenpairs \((\lambda_i,\boldsymbol{v}_i)\), we can expand
If one eigenvalue dominates in magnitude, it controls the long-run behavior.
4. Dominant eigenvalue and demographic profile#
In many population matrices, entries are nonnegative. Then a variant of the Perron–Frobenius theorem implies:
There is a dominant eigenvalue \(\lambda_{\max} > 0\).
There is an associated eigenvector with nonnegative entries.
For many initial states \(\boldsymbol{x}_0\), the direction of \(\boldsymbol{x}_k\) approaches the dominant eigenvector.
A common normalization is the demographic profile
If \(\lambda_{\max}\) is strictly dominant, then typically
where \(\widehat{\boldsymbol{v}}_{\max}\) is the dominant eigenvector scaled to norm 1 (or scaled so entries sum to 1).
Practical meaning:
Even if the initial age distribution is unusual, the population tends to approach a stable age distribution (up to scaling).
5. Birth and survival rates in small age models#
A 2-class model (young/adult) often has the form
where
\(f_2\) is a fertility rate (newborns per adult per time step),
\(s_1\) is survival from young to adult,
\(s_2\) is survival of adults (staying adult).
Here:
\(\lambda_{\max} > 1\) usually means growth,
\(\lambda_{\max} < 1\) means decline,
\(\lambda_{\max} = 1\) suggests a stable total population (in the linear model).
A key modeling lesson is that changing a single parameter (like \(f_2\)) shifts \(\lambda_{\max}\) and therefore changes the long-run trend.
6. More age classes and Leslie matrices#
A standard age-structured model uses a Leslie matrix. For \(n\) age classes:
The first row contains fertility rates \(f_i\) (birth contributions).
The subdiagonal contains survival rates \(s_i\).
One common template is
Interpretation:
Survival pushes individuals one class forward each step.
Fertility injects newborns into class 1 (or class 0, depending on indexing convention).
With many age classes (e.g. Denmark modeled with \(n=100\)), \(A\) becomes large but still structured and sparse.
7. Net reproduction rate#
The net reproduction rate \(R_0\) is the expected number of offspring a newborn individual produces over its lifetime (often modeling females only). In a Leslie-type model:
Let \(f_i\) be fertility in class \(i\).
Let \(s_i\) be survival from class \(i\) to \(i+1\).
Define survival-to-class probabilities
Then
Interpretation (in simplified settings):
\(R_0>1\): each generation replaces itself with more than one new individual → growth.
\(R_0=1\): replacement → stability.
\(R_0<1\): decline.
Important: \(R_0\) and \(\lambda_{\max}\) are related but not generally equal. \(\lambda_{\max}\) is the per-step growth factor in the linear system, while \(R_0\) is a lifetime reproduction measure.
8. Migration and affine dynamics#
If migration or other external inflow/outflow is included, the model becomes affine:
If an equilibrium exists (a fixed point), it satisfies
When \((I-A)\) is invertible, this gives
Conceptually:
\(A\) describes the internal demographic mechanism.
\(\boldsymbol{b}\) can shift the long-run level and shape.
9. Competing species and block matrices#
When modeling two interacting populations, you can stack the state vectors:
If the interaction is linear (e.g. cross-birth contributions), then
where \(A\) becomes a block matrix. The same spectral ideas apply:
the dominant eigenvalue predicts growth/decline of the combined system,
the dominant eigenvector predicts the long-run composition across both species and age classes (in the linear approximation).
In real ecology, interactions are often nonlinear (density dependence, resource limits). The linear block model is still useful as a first approximation, especially when analyzing short-term dynamics or local behavior around an equilibrium.