This package provides an efficient implementation of popular discrete-state spreading processes on networks of interacting agents.
They can be used to simulate how opinions about certain issues develop over time within a population, or how an infectious disease spreads.
The simulation loop is just-in-time compiled using numba
, which makes performance comparable with compiled languages like C++.
Available models:
- continuous-time noisy voter model (CNVM)
- continuous-time noisy threshold model (CNTM)
The package requires Python 3.9, 3.10, 3.11, or 3.12. Install from the PyPI repository:
pip install sponet
or get the latest version directly from GitHub:
pip install git+https://github.com/lueckem/SPoNet
Let a network (undirected simple graph) of
where
Thus, the transition rates
The parameter
The network itself is static, i.e., the nodes and edges do not change over time.
First define the model parameters:
from sponet import CNVMParameters
import numpy as np
import networkx as nx
num_nodes = 100
r = np.array([[0, .8], [.2, 0]])
r_tilde = np.array([[0, .1], [.2, 0]])
network = nx.erdos_renyi_graph(n=num_nodes, p=0.1)
params = CNVMParameters(
num_opinions=2,
network=network,
r=r,
r_tilde=r_tilde,
alpha=1,
)
Then simulate the model, starting in state x_init
:
from sponet import CNVM
x_init = np.random.randint(0, 2, num_nodes)
model = CNVM(params)
t, x = model.simulate(t_max=50, x_init=x_init)
The output t
contains the time points of state jumps and x
the system states after each jump.
A more detailed overview of the package can be found in the jupyter notebook examples/tutorial_cnvm.ipynb. Moreover, the behavior of the CNVM in the mean-field limit is discussed in examples/mean_field.ipynb. In the notebook examples/SIS-model.ipynb the existence of an epidemic threshold for the SIS model in epidemiology is demonstrated.
After a node switches its opinion, the system state
Furthermore, we define the cumulative rates
Then the simulation loop is given by
- Draw time of next jump event from exponential distribution
$\exp(\hat{\lambda})$ . Go to 2. - With probability
$\lambda / \hat{\lambda}$ the event is due to infection, in which case go to 3. Else it is due to noise, go to 4. - Draw agent
$i$ from${1,\dots,N}$ according to distribution$\mathbb{P}(i = j) = r_0 d_j^{(1-\alpha)} / \lambda$ . Let$m$ denote the state of agent$i$ . Draw$n$ from${1,\dots,M}$ according to$\mathbb{P}(n = k) = d_{i,k}(x) / d_i$ . With probability$p_{m,n}$ agent$i$ switches to state$n$ . Go back to 1. - Draw
$i$ from${1,\dots,N}$ and$n$ from${1,\dots,M}$ uniformly. Let$m$ denote the state of agent$i$ . With probability$\tilde{p}_{m,n}$ agent$i$ switches to state$n$ . Go back to 1.
On a network (undirected simple graph) of
where
First define the model parameters:
from sponet import CNTMParameters
import numpy as np
import networkx as nx
num_nodes = 100
r = 1
r_tilde = 0.1
threshold_01 = 0.5
threshold_10 = 0.3
network = nx.erdos_renyi_graph(n=num_nodes, p=0.1)
params = CNTMParameters(
network=network,
r=r,
r_tilde=r_tilde,
threshold_01=threshold_01,
threshold_10=threshold_10,
)
Then simulate the model, starting in state x_init
:
from sponet import CNTM
x_init = np.random.randint(0, 2, num_nodes)
model = CNTM(params)
t, x = model.simulate(t_max=50, x_init=x_init)
The output t
contains the time points of state jumps and x
the system states after each jump.