DyThreshold

The DyThreshold (Dynamic Threshold) Model extends the classical Threshold 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 is in one of two states: inactive (not adopted) or active (adopted). A node becomes active once the influence aggregated from active neighbors in the current snapshot reaches its node threshold.

Compared with the static Threshold model on a single graph, DyThreshold captures adoption under evolving topology and optional time-varying edge weights. The number of simulation steps is bounded by the snapshot sequence length \(T\).

Implementation

Node transitions follow a single monotone rule:

1) if an inactive node receives enough influence from active neighbors in the current snapshot, i.e., aggregated influence is not smaller than its threshold, it becomes active; 2) once active, the node remains active.

Node states are represented by a Boolean indicator vector \(h \in \{0,1\}^N\), where \(h_i=1\) denotes active and \(h_i=0\) denotes inactive. Node thresholds are \(\theta_i \in [0,1]\).

  1. At step \(k\), neighbor \(j\) contributes:

\[m_{ji}^{(k)} = w_{ji}^{(k)} h_j^{(k-1)},\]

where \(w_{ji}^{(k)}=1\) when edge weights are not provided.

  1. Node \(i\) aggregates contributions from \(N^{(k)}(i)\):

\[m_i^{(k)} =\frac{1}{|N^{(k)}(i)|}\sum_{j\in N^{(k)}(i)} m_{ji}^{(k)}\]

The update rule is:

\[\begin{split}h_i^{(k)} = \begin{cases} 1, & \text{if } h_i^{(k-1)}=0 \land (\theta_i \le m_i^{(k)}), \\[4pt] h_i^{(k-1)}, & \text{otherwise}. \end{cases}\end{split}\]

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

Inactive

0

Active

1

DyThresholdModel

class fs_gplib.Dynamic.DyThresholdModel(x, edge_index_list, seeds, threshold: float, device='cpu', rand_seed=None, edge_attr_list=None)[source]

Bases: DiffusionModel

Dynamic Threshold (DyThreshold) diffusion model on time-varying networks.

This model extends the classical Threshold process to a sequence of graph snapshots \(\{G^{(k)}=(V,E^{(k)})\}_{k=1}^{T}\). Each node is either inactive or active. At snapshot \(k\), an inactive node becomes active once the influence aggregated from its active neighbors in the current snapshot reaches its node threshold; active nodes remain active thereafter.

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 active nodes: list of node IDs or a float in (0,1).

  • threshold (float) -- Node adoption threshold in [0,1]. If threshold > 0, every node uses that same threshold value; if threshold == 0, node thresholds are sampled uniformly in \([0,1)\); during batched multi-epoch execution, random thresholds are re-sampled independently for each epoch batch when threshold == 0.

  • 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 diffusion 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 0 or 1).

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 0 or 1).

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 0 or 1).

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 diffusion is evolved through all snapshots. Node states are re-initialised before the run.

When threshold == 0, random node thresholds are re-sampled independently for each epoch batch.

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 0 or 1).

Return type:

torch.Tensor

Note

Unlike the static Threshold model which accepts a single data object, the DyThreshold model requires an explicit node tensor x and a list of edge index tensors edge_index_list for dynamic snapshots. Optional edge weights are also provided as a list edge_attr_list.