base Module#
Abstract base class for all compartmental epidemic models.
This module defines the CompartmentalModel abstract base class,
which provides a unified interface for all epidemic models in Episia.
Class#
- class episia.models.base.CompartmentalModel(parameters)[source]#
Bases:
ABCAbstract base class for compartmental epidemic models.
- Subclasses must implement:
compartment_names property listing compartment names (e.g. [‘S’,’I’,’R’]) _derivatives() ODE right-hand side _initial_state() initial conditions vector from parameters _compute_metrics() derive R0, peak, final_size from solution
The run() method is fully implemented here via _derivatives() and the shared solver in models.solver.
- Parameters:
parameters (ModelParameters)
- __init__(parameters)[source]#
- Parameters:
parameters (ModelParameters)
- abstract property compartment_names: List[str]#
Ordered list of compartment names, e.g. [‘S’, ‘I’, ‘R’].
- plot(backend='plotly', **kwargs)[source]#
Plot model trajectories.
Runs the model first if not already run.
- run(t_span=None, t_eval=None, method='RK45', rtol=1e-06, atol=1e-08)[source]#
Solve the ODE system and return a ModelResult.
- Parameters:
t_span (Tuple[float, float] | None) – (t_start, t_end). Defaults to parameters.t_span.
t_eval (ndarray | None) – Time points at which to store solution. Defaults to np.linspace(t_start, t_end, 1000).
method (str) – scipy solve_ivp integration method (default RK45).
rtol (float) – Relative tolerance.
atol (float) – Absolute tolerance.
- Returns:
ModelResult (also cached as self._result).
- Raises:
RuntimeError – If the solver fails to integrate.
- Return type:
Abstract Methods#
Subclasses must implement:
_derivatives()_initial_state()_compute_metrics()
Examples#
Creating a custom model:
from episia.models.base import CompartmentalModel
from episia.models.parameters import ModelParameters
import numpy as np
class SISModel(CompartmentalModel):
@property
def compartment_names(self):
return ["S", "I"]
def _initial_state(self):
p = self.parameters
return np.array([p.S0, p.I0])
def _derivatives(self, t, y):
S, I = y
N = self.parameters.N
beta = self.parameters.beta
gamma = self.parameters.gamma
dS = -beta * S * I / N + gamma * I
dI = beta * S * I / N - gamma * I
return np.array([dS, dI])
def _compute_metrics(self, t, solution):
S, I = solution
return {
"peak_infected": float(np.max(I)),
"peak_time": float(t[np.argmax(I)]),
"steady_state": float(I[-1])
}
params = ModelParameters(N=1000, I0=10, t_span=(0, 100))
model = SISModel(params)
result = model.run()