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\):
Spontaneous adoption. Each non-blocked inactive node \(i\) independently adopts with probability \(\alpha\) (
adopter_rate).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\).
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.
The update of the system at step \(k\) is decomposed into three stages:
Each active neighbor \(j\) of node \(i\) transmits a contribution
Node \(i\) collects contributions from all neighbors \(N(i)\) to compute its mean neighbor activation:
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)\):
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:
DiffusionModelProfile 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
Dataobject representing graph \(G=(V,E)\). Must containedge_index(the edge set \(E\)) andnum_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. Whenthreshold == 0, a threshold is sampled independently for each node fromUniform(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. Whenprofile == 0, a profile is sampled independently for each node fromUniform(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_statusis 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_statusis 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