matpopmod.examples¶
This module provides ready-made models that can be used to get familiar with the library or for pedagogical purposes.
>>> from matpopmod.examples import orcinus_orca
>>> orcinus_orca
MPM(
S = [[0. , 0. , 0. , 0. ],
[0.9775, 0.9111, 0. , 0. ],
[0. , 0.0736, 0.9534, 0. ],
[0. , 0. , 0.0452, 0.9804]],
F = [[0. , 0.0043, 0.1132, 0. ],
[0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. ]],
metadata = {
'ModelName': 'orcinus_orca',
'Species': 'Orcinus orca',
'CommonName': 'Killer whale',
'Classes': ['Newborns', 'Juveniles', 'Reproductive adults',
'Post-reproductive adults'],
'Source': 'Example 5.1 from Caswell H. (2000). Matrix
Population Models: Construction, Analysis, and Interpretation.',
'Comments': 'The projection matrix is not irreducible due
to the presence of a post-reproductive class.\n\nExample of a
K-strategy, with high survival and low fertility.'
}
)
Only a handful of models of specific interest are given.
For a much larger collection of models, see the module
compadre
, which provides an interface to the
COMPADRE and COMADRE databases.
Complete list of models
- matpopmod.examples.orcinus_orca¶
Stage-based model for the killer whale Orcinus orca (Example 5.1 in [Casw00], based on data from [BrCa93]). The projection matrix is
and the classes correspond to newborns, juveniles, reproductive adults and post-reproductive adults. This is an example of what refer to as an Usher model, that is, the survival probabilities are on the diagonal and subdiagonal entries of the projection matrix, and the fertilities on its first row.
>>> orcinus_orca.usher True
An interesting feature of the model is that it is reducible due to the presence of a post-reproductive class:
>>> orcinus_orca.irreducible False >>> orcinus_orca.postreproductive_classes array([0., 0., 0., 1.]) >>> orcinus_orca.v # reproductive values array([ 1.14163164, 1.19762278, 1.79386902, -0. ])
It also is an example of a K-strategy, i.e. of a life-cycle with a very high survival and a low fertility. This results in long lifespans, but because individuals do not reproduce during their whole life the generation time remains comparatively short.
>>> orcinus_orca.life_expectancy 69.41056244644568 >>> orcinus_orca.T_a # generation time (mean age of mothers) 23.69204811243964 >>> orcinus_orca.T_R0 # R0 generation time 27.850790932634087
- matpopmod.examples.bernardelli_beetle¶
The famous model for Bernardelli’s fictitious beetle, from [Bern41] (partially reprinted in [SmKe77]). In this influential paper, Bernardelli imagined a population of beetles whose dynamics are governed by the projection matrix
(although he does point out that the numerical values are irrelevant), and showed that the population would be subject to sustained oscillations, which he termed “population waves”. And, indeed:
traj = bernardelli_beetle.trajectory([100, 0, 0], 40) matpopmod.plot.trajectory(traj)
This is because the projection matrix is periodic, with index of imprimitivity 3:
>>> bernardelli_beetle.aperiodic False >>> bernardelli_beetle.index_of_imprimitivity 3
As a result, there is no stable distribution in the usual sense. However, since the projection matrix is irreducible, it has a well-defined Perron vector (that is, a unique non-negative eigenvector associated to λ) and it remains possible to compute quantities such as the elasticities.
>>> bernardelli_beetle.w UserWarning: A is not quasi-primitive. Most descriptors are ill-defined. They will be set to NaN. array([nan, nan, nan]) >>> bernardelli_beetle.right_eigenvectors[0] array([0.6, 0.3, 0.1]) >>> bernardelli_beetle.elasticities array([[0. , 0. , 0.33333333], [0.33333333, 0. , 0. ], [0. , 0.33333333, 0. ]])
- matpopmod.examples.passerine_postbreeding¶
A generic model for passerine birds, using a post-breeding census. The projection matrix is
where
(resp. , ) is the survival probability of newborns (resp. yearlings, adults); (resp. ) is the fecundity of female yearlings (resp. adults), i.e. the expected number of chicks they produce; and is the primary sex ratio, i.e. the proportion of females at birth. The numerical values used here are from the model passa_0 shipped with the ULM software.The output of this model can be compared with that of the corresponding pre-breeding model,
passerine_prebreeding
.>>> passerine_postbreeding.w # stable distribution array([0.77777778, 0.14077741, 0.08144481]) >>> passerine_prebreeding.w array([0.63349835, 0.36650165]) >>> passerine_postbreeding.elasticities array([[0.37947486, 0.12019835, 0.09934154], [0.21953989, 0. , 0. ], [0. , 0.09934154, 0.08210381]]) >>> passerine_prebreeding.elasticities array([[0.37947486, 0.21953989], [0.21953989, 0.18144535]])
- matpopmod.examples.passerine_prebreeding¶
A generic model for passerine birds, using a pre-breeding census. The projection matrix is
See
passerine_postbreeding
for more information.
- matpopmod.examples.dipsacus_sylvestris¶
Complex life-cycle for the common teasel Dipsacus fullonum (also referred to as Dispacus sylvestris by most publications citing this model) from [Casw00], Example 5.2. Based on the original publication [CaWe78].
matpopmod.plot.life_cycle(dipsacus_sylvestris)
The classes are, from 0 to 5: first-year dormant seeds, second-year dormant seeds, small rosettes, medium rosettes, rosettes and flowering plants.
This is an example of a model with ill-defined newborn classes: classes 3, 4 and 5 can be reached either by following a reproductive transition or by following a survival one. As a result, it is not possible to know if individuals in those classes are newborns or not.
>>> dipsacus_sylvestris.newborn_classes array([ 1., 0., nan, nan, nan, 0.])
However, this does not affect the calculation of the descriptors implemented in this library. It is also possible to compute the fraction of individuals that are newborns in each class in the stable class structure population:
>>> dipsacus_sylvestris.proportion_newborns array([1. , 0. , 0.5611508 , 0.86103652, 0.139299 , 0. ])
- matpopmod.examples.homo_sapiens_USA¶
Leslie model with a 5-year projection interval for the population of the United States in 1966, from [KeCa05], Example 7.2. (also in [Casw00] and based on [KeFl71]). The life-table is:
Age class
Survival probability
Fertility
0–4
0.99670
0
5–9
0.99837
0.00102
10–14
0.99780
0.08515
15–19
0.99672
0.30574
20–24
0.99607
0.40002
25–29
0.99472
0.28061
30–34
0.99240
0.15260
35–39
0.98867
0.06420
40–44
0.98274
0.01483
45–49
–
0.00089
Because the projection interval is 5 years, one must be careful when interpreting the descriptors. For instance, the yearly growth rate is
, and not :>>> PI = homo_sapiens_USA.metadata["ProjectionInterval"] >>> PI 5.0 >>> homo_sapiens_USA.lmbd 1.0497530435202165 >>> homo_sapiens_USA.lmbd ** (1 / PI) 1.0097582926164328
Similarly, quantities such as the generation time should be multiplied by the length of the projection interval.
>>> homo_sapiens_USA.T_a * PI 25.935182726205607 >>> homo_sapiens_USA.T_R0 * PI 26.14245390652162
- matpopmod.examples.thalia_democratica¶
Two-sex model for the small salp Thalia democratica, from [HSES15].
The classes are, from 1 to 4: females (>1 mm), males (>4 mm), juvenile oozoids (3-10 mm) and post-release oozoids (>10 mm).
Despite the name “two-sex model”, males have no impact on the dynamics of the population. Mathematically, they correspond to a post-reproductive class. It is never possible to have a two-sex matrix population model where the frequency of males and females influences the dynamics of the population. This is because this would require introducing non-linearities, whereas matrix population models are by definition linear.
This is an example of a model where the classic measure of
– namely, the dominant eigenvalue of the next generation matrix – and its usual interpretation (the expected per-capita reproductive output of a cohort of newborns at the stable class distribution) differ markedly:>>> thalia_democratica.R0 4.001730883164397 >>> thalia_democratica.cohort_R0 5.222416673531084
The reason for this discrepancy is that at the stable stage distribution, 28% of the new individuals produced in a year are juvenile oozoids and 72% are females. By contrast, if we sample a newborn according to the dominant eigenvector of next generation matrix, it only has a 20% chance of being a juvenile oozoid. Since juvenile oozoids have a higher reproductive value than females, this explains that a stable cohort of newborns will have a higher expected reproductive output.
- matpopmod.examples.astrocaryum_mexicanum¶
Usher model for the palm tree Astrocaryum mexicanum (Table A2 in [CoEl92], based on data from [PiMS84]).
The stages are, from 1 to 10: fruits, infants, juveniles, immature adults, mature adults 1–6.
This is an example of a model where the three classic measures of generation time
, the mean age of parents of offspring produced by a cohort, also frequently referred to as the cohort generation time; , the mean age of mothers in the stable population; and , the generation time) differs greatly.>>> astrocaryum_mexicanum.mu1 275.1594139265308 >>> astrocaryum_mexicanum.T_a 152.5908805755843 >>> astrocaryum_mexicanum.T_R0 197.61963152089652
This models highlights problems with the interpretation of
(and of the related measure introduced by [StTC14]). Indeed, is often claimed to be a measure of the mean age at reproduction for a typical individual, but in reality it systematically overestimates it, as explained in [Bien19]. In fact, differs can even exceed the life expectancy conditional on reproduction, as is the case here:>>> astrocaryum_mexicanum.mu1 275.1594139265308 >>> mpm.set_rng_seed(0) # for reproducibility >>> astrocaryum_mexicanum.mean_age_repro() # ~20 mins 152.61792711532627 >>> astrocaryum_mexicanum.life_expectancy_repro 232.18934046629712
- matpopmod.examples.second_order_oscillations¶
An example of a projection matrix with non-trivial second order oscillations:
The eigenvalues of A are
. Thus, there are three eigenvalues on the second spectral circle: generates oscillations with period 2 and the pair generates oscillations with period 3. Since there exist positive integers such that , the second-order dynamic of this model is periodic, with period .>>> second_order_oscillations.transient_period 5.999999999999999
The periodic component of the second-order dynamics can be illustrated by plotting it. Note that here we rescale the second order term by
to compensate the damping of the oscillations and make the periodicity more apparent.traj = second_order_oscillations.trajectory( n0 = [1, 1, 1, 1], t_max = 30 ) matpopmod.plot.trajectory( traj, second_order = True, rescale = True, show_period = True )