Source code for seirmo._stoch_model

#
# This file is part of seirmo (https://github.com/SABS-R3-Epidemiology/seirmo/)
# which is released under the BSD 3-clause license. See accompanying LICENSE.md
# for copyright notice and full license details.
#

import numpy as np
import seirmo as se
from ._gillespie import solve_gillespie


[docs] class StochasticSEIRModel(se.SEIRForwardModel): r""" ODE model: Stochastic SEIR The SEIR Model has four compartments: susceptible individuals (:math:`S`), exposed but not yet infectious (:math:`E`), infectious (:math:`I`) and recovered (:math:`R`): Possible processes between compartments: Exposure: S -> E, at rate :math:\beta S(t)I(t)`` Infection: E -> I, at rate :math:\kappa E(t)`` Recovery: I -> R, at rate :math:\gamma I(t)`` Can be used in conjunction with solve_gillespie(), a stochastic ODE solver implemented in this package. Extends :class:`SEIRForwardModel`. """ def __init__(self, params_names: list): super(StochasticSEIRModel, self).__init__() self._parameters = se.SEIRParameters(params_names) # sets up n compartments, returns names of output variables # Define the names of the compartments to record - default all self._output_collector = se.StochasticOutputCollector( ['S', 'E', 'I', 'R'])
[docs] def update_propensity(self, current_states: np.ndarray) -> np.ndarray: ''' This function takes the current populations in each of the N compartments and returns a NxN array where the entry (i,j) gives the rate of transfer of the population of compartment i to compartment j. Each non-zero element here corresponds to one equation in the SEIR model. Non-zero diagonal elements would correspond to no change in the overall population. Warning - negative elements should be avoided - a negative value at (i,j) corresponds to a positive element at (j,i) and should be implemented as such if required. ''' params_names = self._parameters.parameter_names() beta = self._parameters[params_names.index('beta')] kappa = self._parameters[params_names.index('kappa')] gamma = self._parameters[params_names.index('gamma')] [t, S, E, I, R] = current_states N = len(current_states) - 1 propens_matrix = np.zeros((N, N)) propens_matrix[0, 1] = beta * S * I propens_matrix[1, 2] = kappa * E propens_matrix[2, 3] = gamma * I return propens_matrix
[docs] def simulate(self, parameters: np.ndarray, times: list, max_t_step: float = 0.01): self._parameters.configure_parameters(parameters) # array of length 7 # with values of beta # gamma kappa and initial self._output_collector.begin(times) initial_states = self._parameters[:4] # input initial values for point in solve_gillespie( lambda states: self.update_propensity(states), # states # includes t as first argument initial_states, [times[0], times[-1]], max_t_step): self._output_collector.report(point) self._output_collector.retrieve() return self._output_collector.retrieve()