DySIR
The DySIR (Dynamic SIR) Model extends the classical SIR model 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 time step \(k\). Each node can be in one of three states: \(S\) (susceptible), \(I\) (infected), or \(R\) (removed/recovered).
A susceptible node \(i\) can be infected by infected neighbors \(j \in N^{(k)}(i)\) with infection rate \(\beta\); meanwhile an infected node recovers independently with rate \(\lambda\):
Compared with the static SIR model on a single graph, the DySIR model captures the impact of evolving topology on transmission and recovery dynamics. The number of simulation steps is bounded by the length of the snapshot sequence \(T\).
Implementation
Node transitions follow three rules:
if a \(S\) state node has \(I\) state neighbors, each \(I\) state neighbor transmits the infection to the \(S\) state node with probability \(\beta\);
the \(I\) state node is recovered to the \(R\) state with probability \(\lambda\);
once recovered, a node remains in \(R\).
Node states are represented by two Boolean indicator vectors \(h, r \in \{0,1\}^N\),
where \(h_i=1\) denotes infected, \(r_i=1\) denotes removed/recovered, and
\((h_i,r_i)=(0,0)\) denotes susceptible.
The update of the system at step \(k\) is decomposed into three stages:
1) Each infected neighbor \(j\) of node \(i\) in the current snapshot \(G^{(k)}\) transmits a log-probability contribution
where \(w_{ji}^{(k)}=1\) if edge weights are not provided.
Node \(i\) collects contributions from neighbors \(N^{(k)}(i)\) to compute its infection probability
3) The indicator variables are updated with independent uniform random variables \(U_i^{\mathrm{inf}}, U_i^{\mathrm{rec}} \sim \mathrm{Uniform}(0,1)\)
As in other dynamic models, \(N^{(k)}(i)\) and optional edge weights
\(w_{ji}^{(k)}\) are time-dependent and taken 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 |
Removed |
2 |
DySIRModel
- class fs_gplib.Dynamic.DySIRModel(x, edge_index_list, seeds, infection_beta: float, recovery_lambda: float, device='cpu', rand_seed=None, edge_attr_list=None)[source]
Bases:
DiffusionModelDynamic SIR (DySIR) epidemic model on time-varying networks (dynamic network models).
This model extends the classical static SIR dynamics (see the epidemic
SIRModel) to a sequence of graph snapshots \(\{G^{(k)}=(V,E^{(k)})\}_{k=1}^{T}\). Nodes are susceptible \(S\), infected \(I\), or removed/recovered \(R\). Infections spread along edges of the current snapshot with probability \(\beta\) per contact (optionally weighted by edge_attr_list); infected nodes recover to \(R\) with probability \(\lambda\) and never leave \(R\).Returned tensors encode states as float values: susceptible
0, infected1, removed2.The number of simulation steps cannot exceed
len(edge_index_list). Pass an explicit node tensor x (shape(N, 1)) and edge_index_list (and optional edge_attr_list) instead of a single PyGDataobject.- Parameters:
x (torch.Tensor) -- Node feature tensor of shape
(N, 1)(node count \(N\) from the leading dimension).edge_index_list (list[torch.Tensor]) -- One
edge_indextensor per snapshot, length \(T\), defining \(E^{(k)}\) at each step.seeds (list[int] | float) -- Initially infected nodes: a list of integer node IDs, or a float in
(0, 1)to infect that fraction of nodes uniformly at random.infection_beta (float) -- Per-contact infection probability \(\beta \in [0, 1]\).
recovery_lambda (float) -- Per-step recovery probability \(\lambda \in [0, 1]\) for infected nodes.
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) One edge-weight tensor per snapshot, aligned with edge_index_list. If
None, weights are1.
- run_iteration()[source]
Advance the epidemic by one snapshot step.
The internal
node_statusis updated so that subsequent calls continue from the latest state. Requires at least one remaining snapshot.- Returns:
State codes after that step, shape
(1, 1, N)(values0/1/2).- Return type:
torch.Tensor
- run_iterations(times)[source]
Run times consecutive snapshot steps on the evolving graph sequence.
The internal
node_statusis updated to the state after the last step. Requireslen(edge_index_list) - t >= timeswhere \(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:
State codes after each step, stacked with shape
(times, 1, N)(values0/1/2).- 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:
State-code trajectory over all snapshots, shape
(T, 1, N)with \(T =\)len(edge_index_list)(values0/1/2).- 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:
State-code trajectories for all realisations, shape
(T, E, N)where \(T =\)len(edge_index_list)and \(E\) is epochs (values0/1/2).- Return type:
torch.Tensor
Note
Unlike the static SIR model which accepts a single data object containing
edge_index and edge_attr, the DySIR model requires an explicit node
tensor x and a list of edge index tensors edge_index_list representing the
dynamic network snapshots. Edge weights are similarly provided as a list
edge_attr_list.