DySEIS_ct

The DySEIS_ct (Dynamic SEIS with continuous-time transition hazards) model extends the classical SEIS process to time-varying networks. Instead of a fixed graph \(G=(V,E)\), diffusion evolves on a sequence of graph snapshots \(\{G^{(k)}=(V,E^{(k)})\}_{k=1}^{T}\), where the edge set \(E^{(k)}\) may change at each discrete step \(k\). Each node can be in one of three states: \(S\) (susceptible), \(E\) (exposed), or \(I\) (infected).

Compared with the discrete DySEIS model, DySEIS_ct keeps the same \(S\to E\) infection mechanism but uses elapsed-time dependent transition probabilities for \(E\to I\) and \(I\to S\). For node \(i\), if \(\Delta t_i^E\) is time since entering \(E\), and \(\Delta t_i^I\) is time since entering \(I\), then

\[P(E\to I) = 1-\exp(-\alpha\Delta t_i^E), \qquad P(I\to S) = 1-\exp(-\gamma\Delta t_i^I).\]

This design models non-memoryless incubation and recovery while preserving snapshot-based interaction dynamics.

Implementation

Node states are represented by two Boolean vectors \(h,e \in \{0,1\}^N\) plus two integer entry-time tensors \(t^E,t^I\):

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

  • \((h_i,e_i)=(1,1)\) denotes exposed; \((h_i,e_i)=(1,0)\) denotes infected; \((h_i,e_i)=(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.

At step \(k\), define \(\Delta t_i^E = k - t_i^E\) and \(\Delta t_i^I = k - t_i^I\). The update has three stages:

1. Each infected (non-exposed) neighbor \(j\) of node \(i\) in snapshot \(G^{(k)}\) 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\!\bigl(1-\beta\,w_{ji}^{(k)}\bigr)\]

2. Node \(i\) aggregates contributions from neighbors \(N^{(k)}(i)\) to obtain its exposure probability:

\[m_i^{(k)} = 1-\exp\!\left(\sum_{j\in N^{(k)}(i)}m_{ji}^{(k)}\right)\]

3. The entry-time 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 \\ 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, \\[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, \\[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} \end{aligned}\end{split}\]

As in other dynamic models, neighbors \(N^{(k)}(i)\) and optional edge weights \(w_{ji}^{(k)}\) are read from the \(k\)-th snapshot. The total number of iterations is bounded by \(T =\) len(edge_index_list).

Status

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

Status

Code

Susceptible

0

Infected

1

Exposed

2

DySEISctModel

class fs_gplib.Dynamic.DySEISctModel(x, edge_index_list, seeds, infection_beta: float, removal_gamma: float, latent_alpha: float, device='cpu', rand_seed=None, edge_attr_list=None)[source]

Bases: DiffusionModel

Dynamic SEIS with continuous-time hazards (DySEIS_ct) on time-varying networks.

This model runs SEIS diffusion on a snapshot sequence \(\{G^{(k)}=(V,E^{(k)})\}_{k=1}^{T}\). The exposure mechanism for \(S\to E\) follows the discrete DySEIS model: infectious neighbors in the current snapshot expose a susceptible node with probability \(\beta\) per contact (optionally scaled by snapshot edge weights).

Unlike DySEIS, transitions \(E\to I\) and \(I\to S\) are governed by elapsed-time dependent probabilities. If a node entered state \(E\) at iteration \(t_i^E\) and state \(I\) at iteration \(t_i^I\), then at snapshot index \(k\):

  • \(P(E\to I)=1-\exp(-\alpha\,(k-t_i^E))\)

  • \(P(I\to S)=1-\exp(-\gamma\,(k-t_i^I))\)

Returned tensors encode states as float values: susceptible 0, infected 1, exposed 2.

The number of simulation steps cannot exceed len(edge_index_list).

Parameters:
  • x (torch.Tensor) -- Node tensor of shape (N, 1).

  • edge_index_list (list[torch.Tensor]) -- List of snapshot edge_index tensors, length \(T\).

  • seeds (list[int] | float) -- Initially infectious nodes: list of node IDs or a float in (0,1).

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

  • latent_alpha (float) -- Latent parameter \(\alpha > 0\) for E→I.

  • removal_gamma (float) -- Removal parameter \(\gamma > 0\) for I→S.

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

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

  • edge_attr_list (list[torch.Tensor] | None) -- (optional) Snapshot edge weights aligned with edge_index_list.

run_iteration()[source]

Advance the epidemic by one snapshot step.

The internal node_status is updated so that subsequent calls continue from the latest state. Requires at least one remaining snapshot.

Returns:

Node states after that step, shape (1, 1, N) (values 02).

Return type:

torch.Tensor

run_iterations(times)[source]

Run times consecutive snapshot steps on the evolving graph sequence.

The internal node_status is updated to the state after the last step. Requires len(edge_index_list) - t >= times where \(t\) is the number of steps already consumed on this process.

Parameters:

times (int) -- Number of snapshots to advance (must not exceed remaining snapshots).

Returns:

Node states after each step, stacked with shape (times, 1, N) (values 02).

Return type:

torch.Tensor

run_epoch()[source]

Run one Monte-Carlo realisation over the full snapshot sequence.

The process internal step counter is reset; node states are re-initialised before the epoch starts.

Returns:

Node states trajectory over all snapshots, shape (T, 1, N) with \(T =\) len(edge_index_list) (values 02).

Return type:

torch.Tensor

run_epochs(epochs, batch_size=200)[source]

Run multiple independent Monte-Carlo realisations in batches.

For each realisation the snapshot index is reset to the beginning and the epidemic is evolved through all snapshots. Node states are re-initialised before the run.

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

  • batch_size (int) -- (optional) Parallel epochs per batch. Defaults to 200.

Returns:

Node states trajectories for all realisations, shape (T, E, N) where \(T =\) len(edge_index_list) and \(E\) is epochs (values 02).

Return type:

torch.Tensor

Note

Unlike the static SEIS_ct model which accepts a single graph object, DySEIS_ct requires a node tensor x and a snapshot list edge_index_list. Optional edge weights are provided by edge_attr_list with one tensor per snapshot.