Profile Threshold

The Profile Threshold model [1] combines the Threshold model with the Profile model to describe a social contagion process governed by two node-level attributes: a threshold \(\theta_i\) and a profile \(p_i\). An inactive node can become active through two pathways: (1) spontaneous adoption with a fixed probability, or (2) threshold-gated profile adoption — the node first checks whether the fraction of its active neighbors exceeds its threshold, and if so, adopts with a probability equal to its profile value. If a node passes the threshold gate but fails the profile check, it may become blocked and permanently ineligible for future activation.

Model Description

Node transitions follow three mechanisms at each iteration \(k\):

  1. Spontaneous adoption. Each non-blocked inactive node \(i\) independently adopts with probability \(\alpha\) (adopter_rate).

  2. Threshold-gated profile adoption. If node \(i\) was not spontaneously adopted, the model first checks whether the mean activation of its neighbors exceeds its threshold \(\theta_i\). If so, the node adopts with probability equal to its profile value \(p_i\).

  3. Blocking. If node \(i\) passes the threshold gate but fails the profile check, it becomes blocked with probability \(\beta\) (blocked_rate).

We use two Boolean indicator vectors \(h, b \in \{0,1\}^N\) to represent node states:

  • \(h_i=1\) and \(b_i=0\) denotes Active,

  • \(h_i=0\) and \(b_i=0\) denotes Inactive,

  • \(h_i=0\) and \(b_i=1\) denotes Blocked.

ProfileThreshold model diagram

The update of the system at step \(k\) is decomposed into three stages:

  1. Each active neighbor \(j\) of node \(i\) transmits a contribution

\[m_{ji}^{(k)} = h_j^{(k-1)}\]
  1. Node \(i\) collects contributions from all neighbors \(N(i)\) to compute its mean neighbor activation:

\[m_i^{(k)} = \frac{1}{|N(i)|}\sum_{j \in N(i)} m_{ji}^{(k)} \cdot (1 - b_i^{(k-1)})\]
  1. The indicator variables are updated with independent uniform random variables \(U_i^{\mathrm{a}}, U_i^{\mathrm{p}}, U_i^{\mathrm{b}} \sim \mathrm{Uniform}(0,1)\):

\[\begin{split} h_i^{(k)} = \begin{cases} 1, & \text{if } (h_i^{(k-1)}=0 \land b_i^{(k-1)}=0) \land (U_i^{\mathrm{a}} < \alpha), \\[4pt] 1, & \text{if } (\theta_i \leq m_i^{(k)}) \land (h_i^{(k-1)}=0 \land b_i^{(k-1)}=0) \\ &\land (U_i^{\mathrm{a}} \geq \alpha) \land (p_i > U_i^{\mathrm{p}}), \\[4pt] h_i^{(k-1)}, & \text{otherwise}, \end{cases} \\[6pt] b_i^{(k)} = \begin{cases} 1, & \text{if } (m_i^{(k)}>0) \land (\theta_i \leq m_i^{(k)}) \land (h_i^{(k-1)}=0 \land b_i^{(k-1)}=0)\\ & \land (U_i^{\mathrm{a}} \geq \alpha) \land (p_i \leq U_i^{\mathrm{p}}) \land (\beta > U_i^{\mathrm{b}}), \\[4pt] b_i^{(k-1)}, & \text{otherwise}, \end{cases}\end{split}\]

Status

During the simulation, each node can be in one of three states:

Status

Code

Inactive

0

Active

1

Blocked

-1

ProfileThresholdModel

class fs_gplib.Epidemics.ProfileThresholdModel(data, seeds, threshold, profile: float, adopter_rate, blocked_rate, device='cpu', rand_seed=None)[source]

Bases: DiffusionModel

Profile Threshold diffusion model on static graphs.

This model combines threshold-based exposure with profile-based adoption. Each node starts as inactive or active (seed). At every step a non-blocked inactive node may first become active spontaneously with probability \(\alpha\). Otherwise, the node checks whether the mean activation level of its neighbors reaches its threshold. If the threshold gate is passed, the node adopts with probability equal to its profile value. If it passes the threshold gate but fails the profile check, it may become blocked with probability \(\beta\) and then remain permanently ineligible for activation. Once activated, a node stays active.

Returned node states are encoded as: -1 = blocked, 0 = inactive, 1 = active.

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|\)).

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

  • threshold (float) -- Per-node threshold value for the activation-ratio gate. When threshold \in (0,1), all nodes share the same threshold. When threshold == 0, a threshold is sampled independently for each node from Uniform(0,1) during initialisation.

  • profile (float) -- Per-node adoption propensity after passing the threshold gate. When profile \in (0,1], all nodes share the same profile value. When profile == 0, a profile is sampled independently for each node from Uniform(0,1) during initialisation.

  • adopter_rate (float) -- Per-step spontaneous adoption probability \(\alpha \in [0,1]\) for each non-blocked inactive node.

  • blocked_rate (float) -- Probability \(\beta \in [0,1]\) that a node becomes blocked after passing the threshold gate but failing the profile-based adoption check.

  • 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.

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=1)[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 1.

Returns:

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

Return type:

torch.Tensor

References