Profile

The Profile model [1] describes a social contagion process in which each node possesses a personal profile value that governs its susceptibility to adoption. When an inactive node is exposed to at least one active neighbor, it adopts with a probability equal to its profile value; if it fails to adopt, the node may become blocked and permanently ineligible for future activation. Additionally, non-blocked inactive nodes can spontaneously adopt in each iteration with a fixed probability.

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. Profile-based adoption. If node \(i\) has at least one active neighbor and was not spontaneously adopted, it adopts with probability equal to its profile \(p_i\).

  3. Blocking. If node \(i\) was exposed to active neighbors but did not adopt via the profile mechanism, it becomes blocked with probability \(\beta\) (blocked_rate).

Profile model diagram

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:

  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 determine whether it is exposed:

\[m_i^{(k)} = \left(\bigvee_{j \in N(i)} m_{ji}^{(k)}\right) \land \lnot\, 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 } m_i^{(k)} \land (h_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)} \land (h_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

ProfileModel

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

Bases: DiffusionModel

Profile diffusion model on static graphs.

This model describes social contagion with node-specific susceptibility. Each node starts as inactive or active (seed). At every step a non-blocked inactive node may first become active spontaneously with probability \(\alpha\). If it is exposed to at least one active neighbor and does not adopt spontaneously, it adopts with probability equal to its profile value. If exposed but still not adopted, 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.

  • profile (float) -- Per-node adoption propensity after exposure. 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).

  • 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 an exposed node becomes blocked after failing to adopt via its profile.

  • 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