SEIR_ct

The SEIR_ct Model [1] assumes that infection spreads only through links between neighboring nodes in a graph \(G=(V,E)\). Each node is in one of four states: \(S\) (susceptible), \(E\) (exposed/incubating), \(I\) (infected), or \(R\) (recovered). Compared with the discrete-step SEIR, SEIR_ct uses elapsed-time–dependent transition probabilities for \(E\to I\) and \(I\to R\) based on the time since the last state entry.

Implementation

We use three Boolean indicator vectors \(h, e, r \in \{0,1\}^N\) and two integer tensors that store entry times:

  • \(h_i=1\) indicates node \(i\) is infected or exposed; \(h_i=0\) indicates susceptible or recovered.

  • \((h_i,e_i,r_i)=(1,0,0)\) denotes infected, \((h_i,e_i,r_i)=(1,1,0)\) denotes exposed.

  • \((h_i,e_i,r_i)=(0,0,1)\) denotes recovered, \((h_i,e_i,r_i)=(0,0,0)\) denotes susceptible.

  • \(t_i^{E}\) records the iteration \(k\) when node \(i\) entered E.

  • \(t_i^{I}\) records the iteration \(k\) when node \(i\) entered I.

With \(k\) denoting the current iteration, define duration variables \(\Delta t_i^{E} = k - t_i^{E}\) and \(\Delta t_i^{I} = k - t_i^{I}\). The update of the system at step \(k\) is decomposed into three stages:

SEIR_ct model diagram
  1. Each infected neighbor \(j\) of node \(i\) transmits a log-probability contribution for exposure

\[m_{ji}^{(k)} = \mathbf{1}\!\left(h_j^{(k-1)}=1 \land e_j^{(k-1)}=0\right)\,\log(1-\beta)\]
  1. Node \(i\) collects contributions from all neighbors \(N(i)\) to compute its exposure probability

\[m_i^{(k)} = 1 - \exp\!\left( \sum_{j \in N(i)} m_{ji}^{(k)} \right)\]
  1. The integer tensors and indicator variables are updated with independent uniform random variables \(U_i^{\mathrm{exp}}, U_i^{\mathrm{inf}}, U_i^{\mathrm{rec}} \sim \mathrm{Uniform}(0,1)\)

\[\begin{split}\begin{aligned} t_i^E &= k, \text{if } (U_i^{\mathrm{exp}}<m_i^{(k)}) \land (h_i^{(k-1)}=0 \land r_i^{(k-1)}=0) \\ t_i^I &= k, \text{if } (U_i^{\mathrm{inf}}<1-exp(-\alpha \cdot \Delta t_i^E)) \land e_i^{(k-1)}=1 \end{aligned}\end{split}\]
\[\begin{split}\begin{aligned} h_i^{(k)} &= \begin{cases} 1, & \text{if } (U_i^{\mathrm{exp}} < m_i^{(k)}) \land (h_i^{(k-1)}=0 \land r_i^{(k-1)}=0), \\[4pt] 0, & \text{if } (U_i^{\mathrm{rec}} < 1-exp(-\gamma\cdot \Delta t_i^I)) \land (h_i^{(k-1)}=1 \land e_i^{(k-1)}=0), \\[4pt] h_i^{(k-1)}, & \text{otherwise}, \end{cases} \\[6pt] e_i^{(k)} &= \begin{cases} 1, & \text{if } (U_i^{\mathrm{exp}} < m_i^{(k)}) \land (h_i^{(k-1)}=0 \land r_i^{(k-1)}=0), \\[4pt] 0, & \text{if } (U_i^{\mathrm{inf}} < 1-exp(-\alpha \cdot \Delta t_i^E)) \land e_i^{(k-1)}=1 , \\[4pt] e_i^{(k-1)}, & \text{otherwise}, \end{cases} \\[6pt] r_i^{(k)} &= \begin{cases} 1, & \text{if } (U_i^{\mathrm{rec}} < 1-exp(-\gamma\cdot \Delta t_i^I)) \land (h_i^{(k-1)}=1 \land e_i^{(k-1)}=0), \\[4pt] r_i^{(k-1)}, & \text{otherwise}. \end{cases} \end{aligned}\end{split}\]

Status

During the simulation, a node can be in one of the following states:

Status

Code

Susceptible

0

Infected

1

Exposed

2

Recovered

3

SEIRctModel

class fs_gplib.Epidemics.SEIRctModel(data, seeds, infection_beta: float, removal_gamma: float, latent_alpha: float, device='cpu', use_weight: bool = False, rand_seed=None)[source]

Bases: DiffusionModel

SEIR_ct (continuous-time SEIR) diffusion model on static graphs.

Variant of SEIR where the E→I and I→R transition probabilities depend on the elapsed time since entering that state. Specifically, \(P(E \to I) = 1 - e^{-\Delta t^E \,\alpha}\) and \(P(I \to R) = 1 - e^{-\Delta t^I \,\gamma}\). Recovered nodes are permanently immune.

Returned node states are encoded as: 0 = susceptible, 1 = infected, 2 = exposed, 3 = recovered.

Parameters:
  • data (torch_geometric.data.Data) -- PyTorch Geometric Data object representing graph \(G=(V,E)\). Must contain edge_index (the edge set \(E\)) and num_nodes (\(|V|\)). When use_weight is True, edge_attr supplies per-edge weights \(w_{ji}\).

  • seeds (list[int] | float) -- Nodes whose initial state is Infected. Pass a list of node IDs, or a float in (0, 1) to infect that fraction of nodes chosen uniformly at random.

  • infection_beta (float) -- Per-contact exposure probability \(\beta \in [0,1]\) (S→E).

  • removal_gamma (float) -- Recovery rate \(\gamma > 0\) (I→R). Used in \(1 - e^{-\Delta t^I \,\gamma}\).

  • latent_alpha (float) -- Incubation rate \(\alpha > 0\) (E→I). Used in \(1 - e^{-\Delta t^E \,\alpha}\).

  • device (str | int) -- (optional) 'cpu' or a CUDA device index. Defaults to 'cpu'.

  • use_weight (bool) -- (optional) If True, each edge \((j,i)\) carries a weight \(w_{ji}\) from data.edge_attr and the exposure probability becomes \(\beta w_{ji}\). If False all weights default to 1 (i.e. \(w_{ji}=1\)). Defaults to False.

  • rand_seed (int | None) -- (optional) Random seed used when seeds is a float. Defaults to None.

run_iteration()[source]

Execute a single simulation step.

The internal node_status is updated so that subsequent calls continue from the latest state.

Returns:

Node states after one step, shape (1, N).

Return type:

torch.Tensor

run_iterations(times)[source]

Execute times simulation steps sequentially.

The internal node_status is updated in-place so that subsequent calls continue from the latest state.

Parameters:

times (int) -- Number of steps to run.

Returns:

Node states at final step, shape (1, N).

Return type:

torch.Tensor

run_epoch(iterations_times)[source]

Run a single Monte-Carlo epoch (one independent realisation).

Node states are re-initialised before the epoch starts.

Parameters:

iterations_times (int) -- Number of simulation steps per epoch.

Returns:

Node states at final step of the epoch, shape (1, N).

Return type:

torch.Tensor

run_epochs(epochs, iterations_times, batch_size=200)[source]

Run multiple independent Monte-Carlo epochs in batches.

Node states are re-initialised before the run.

Parameters:
  • epochs (int) -- Total number of independent realisations.

  • iterations_times (int) -- Number of simulation steps per epoch.

  • batch_size (int) -- (optional) Number of epochs processed in parallel per batch. Defaults to 200.

Returns:

Node states at final step of all epochs, shape (epochs, N).

Return type:

torch.Tensor

References