Logistic growth model - Overview
1 Introduction
We assume that we observe a population of organisms that grow according to the logistic growth model. We observe the population size at discrete time points.
This can be modelled with a state space model (synonyms are partially-observed Markov processes, hidden Markov model and nonlinear stochastic dynamical systems).
\(s(t)\): state that is modelled with a process-based model at time \(t\)
\(x(t)\): true hidden state at time \(t\)
\(y(t)\): observation at time \(t\)
\(p(x(t) | x(t-1))\): transition probability between the true states
\(p(y(t) | x(t))\): observation probability
\(p(x₀)\): prior for the initial state of the true states
\(εₜ₋₁\): process error
\(ηₜ₋₁\): observation error
2 Process model
\[ \begin{align} &x_{t} = \left(1 + r\left(1 - \frac{x_{t-1}}{K}\right) + \varepsilon_{t}\right) \cdot x_{t-1} \\ &\varepsilon_{t} \sim \mathcal{N}(0, \sigma_{p}^2) \end{align} \]
thereby we assume that the process error \(\varepsilon\) scales with the population size.
3 Observation model
We use a gamma distribution for the observation model: \[ \begin{align} &\alpha_t = \frac{x_{t}^2}{\sigma_o^2} \\ &\theta_t = \frac{\sigma_o^2}{x_{t}} \\ &y_t \sim \text{Gamma}(\alpha_t, \theta_t) \end{align} \]
similarly we could also use a normal distribution for the observation model: \[ y_t \sim \mathcal{N}(x_{t}, \sigma_o^2) \]
4 Parameters
We will use the folling parameters for the simulation experiment:
Parameter | Description | Value |
---|---|---|
\(\sigma_p\) | standard deviation of the process error | 0.05 |
\(\sigma_o\) | standard deviation of the observation error | 20.0 |
\(r\) | growth rate | 0.1 |
\(K\) | carrying capacity | 400 |
\(x_0\) | initial population size | 20 |
5 Generate data
Code
import Random
using CairoMakie
using Distributions
set_theme!(
= 18,
fontsize = (; xgridvisible = false, ygridvisible = false,
Axis = false, rightspinevisible = false),
topspinevisible = (; framevisible = false))
Legend
function generate_data(n_observations; σ_p, σ_o, r, K, x₀)
= 1:n_observations
ts = length(ts)
T
= Array{Float64}(undef, T)
s = Array{Float64}(undef, T)
x = Array{Float64}(undef, T)
y = rand(Normal(0, σ_p), T)
ε
for t in ts
= t == 1 ? x₀ : x[t-1]
x_lastt = t == 1 ? x₀ : s[t-1]
s_lastt
= (1 + r*(1 - s_lastt/K)) * s_lastt
s[t] = (1 + r*(1 - x_lastt/K) + ε[t]) * x_lastt
x[t] = rand(Gamma(x[t]^2 / σ_o^2, σ_o^2 / x[t]))
y[t] end
= (; σ_o, r, K, x₀))
(; ts, s, x, y, parameter end
Random.seed!(123)
= generate_data(100; σ_p = 0.05, σ_o = 20.0, r = 0.1, K = 400, x₀ = 20.0);
true_solution
let
= Figure(size = (900, 600))
fig
= Axis(fig[1, 1]; xlabel = "time", ylabel = "population size")
ax scatter!(true_solution.ts, true_solution.y, color = :steelblue4, label = "observations: y")
lines!(true_solution.ts, true_solution.x, color = :blue, label = "true hidden state: x")
lines!(true_solution.ts, true_solution.s, color = :red, label = "process-model state: s")
Legend(fig[1, 2], ax)
figend
6 Parameter inference
Experiment | Description |
---|---|
MCMC without states v1 | we will just ignore the process error |
MCMC without states v2 | we included the process error but we won’t model the hidden state |
MCMC without states v3 | we included the process error and use one step ahead prediction but we won’t model the hidden state |
state space - MCMC | we include the hidden state (the process error over time) as parameters in addition to the model parameters |
state space - pMCMC | we will infer the hidden state with a sequential monte carlo method (= particle filter) and use MCMC for the model parameters |
- An introduction to pMCMC: sbfnk.github.io/mfiidd/slides/smc.pdf
- Another intro to pMCMC: kingaa.github.io/sbied/pfilter/slides.pdf
for an introduction to state space models in ecology see Auger-Méthé et al. (2021)