Source code for dynamicalab.dynamics.sis

import numpy as np
from numpy.random import random
from .base import BaseDynamics

[docs]class SISDynamics(BaseDynamics): """Markovian discrete time Suceptible-infected-suceptible process on networks. """
[docs] def __init__(self, p, q, self_activation=0): """ **Parameters** p : Float Probability of infection q : Float Probability of recovery self_activation : Float : (default=0) Probability of spontaneous activation Note that the `__call__(G, T)` method is independent of ``T[i]-T[i+1]``. Only ``len(T)`` is taken into account for the number of steps. """ super(SISDynamics, self).__init__() self.p = p self.q = q self.self_activation = self_activation self.infected_node_set = set()
def __call__(self, G, T, x0=None): if x0 is None: x0 = self.best_x0(G) #initialize for node in range(len(x0)): if x0[node] == 1: self.infected_node_set.add(node) X = [] for t in T: self.__step(G) X.append(self.__get_state(G)) self.infected_node_set = set() return np.array(X) def best_x0(self, G): """Convenient method to get a good initial state given as a random infection. **Params** G : nx.Graph Network structure **Returns** np.array(N): Binary state of each node. """ N = G.number_of_nodes() return np.random.randint(0,2, size=(N,)) def __step(self, G): """Realize a time step of the process """ new_infected_node_set = self.infected_node_set.copy() #look for new infections for node in self.infected_node_set: #try to infect neighbors for neighbor in G.neighbors(node): if random() < self.p: new_infected_node_set.add(neighbor) #look for recuperations for node in self.infected_node_set: #try to recuperate if random() < self.q: new_infected_node_set.remove(node) #set new infected nodes self.infected_node_set = new_infected_node_set def __get_state(self, G): """Returns the current state""" x = np.zeros(len(G)) for node in self.infected_node_set: x[node] = 1 # Random activation if self.self_activation>0: rdm_act = np.random.choice([0,1], size=len(x), p=[1-self.self_activation, self.self_activation]) x = np.minimum(x+rdm_act, 1) return x