#!/usr/bin/env python
# coding: utf-8
# # Epidemics on networks
# On this lab we will consider an implementation of disease spreading over a network. We will start from SIS model and slightly modify it to SIR model.
# ## SIS model
# Just to recall from the lecture how it looks like:
# \begin{equation}
# \begin{cases}
# \cfrac{ds_i(t)}{dt} = -\beta s_i(t)\sum\limits_j A_{ij}x_j(t) + \gamma x_i(t)\\
# \cfrac{dx_i(t)}{dt} = \beta s_i(t)\sum\limits_j A_{ij}x_j(t) - \gamma x_i(t)
# \end{cases}
# \\
# x_i(t) + s_i(t) = 1
# \end{equation}
# where $x_i(t)$ and $s_i(t)$ are probabilities for a node $v_i$ to be infected or susceptable.
# In[1]:
import numpy as np
import scipy as sp
import networkx as nx
import matplotlib.pyplot as plt
from numpy.linalg import eig
from scipy.integrate import odeint
get_ipython().run_line_magic('matplotlib', 'inline')
# In[24]:
# Let's start from a complete graph
n = 50
G = nx.watts_strogatz_graph(n, 5, 0.4)
# Get adj. matrix
A = np.array(nx.adjacency_matrix(G).todense())
# Spreading\restoring coefficient
beta, gamma = 0.03, 0.2
# Time domain
t = np.arange(0,5,0.05)
# Initial state
idx = np.random.choice(range(n), 5)
i0 = np.zeros((n,))
i0[idx] = 1
# i0 = np.random.random_integers(0,1,[n,])
z0 = np.concatenate((1-i0,i0))
# System of differential equations..
def sis(z, t, A, n, beta, gamma):
return np.concatenate((
-beta * z[0:n] * A.dot(z[n:2*n]) + gamma * z[n:2*n],
beta * z[0:n] * A.dot(z[n:2*n]) - gamma * z[n:2*n]))
# ..Solved
z = odeint(sis, z0, t, (A, n, beta, gamma))
# In[3]:
# It's a bit messy, so let's see what we have got here
z.shape
# In[25]:
# Plot probs for some node
nId = 6
s = z[:,0:n]
x = z[:,n:2*n]
fig, ax = plt.subplots(1,1,figsize=(10,6))
ax.plot(s,color = 'blue')
ax.plot(x,color = 'red')
ax.set_xlabel('$t$')
ax.set_ylabel('prob')
ax.set_title('Probability for all nodes', fontsize = 15)
# Hope that you remember that stuff about the correspondence between largest eigenvalue and $\frac{\gamma}{\beta}$ ratio:
# * if $\lambda_1 > \frac{\gamma}{\beta}$ - GROWTH
# * if $\lambda_1 < \frac{\gamma}{\beta}$ - NOPE
# Check it
# In[23]:
w,v = eig(A)
print max(w), gamma/beta
# ### Task
# 1. Play with $\gamma$, $\beta$ parameters and try out SIS model for other graphs
# 2. Does it matter how many nodes are initially infected?
# ## SIR model
# In SIR model healed population gain immunity to the infection
# \begin{equation}
# \begin{cases}
# \cfrac{ds_i(t)}{dt} = -\beta s_i(t)\sum\limits_j A_{ij} x_j(t)\\
# \cfrac{dx_i(t)}{dt} = \beta s_i(t)\sum\limits_j A_{ij} x_j(t) - \gamma x_i(t)\\
# \cfrac{dr_i(t)}{dt} = \gamma x_i(t)
# \end{cases}
# \\
# x_i(t) + s_i(t) + r_i(t) = 1
# \end{equation}
# Adapt the code above to produce SIR model
# In[36]:
# Let's start from a complete graph
n = 50
G = nx.barabasi_albert_graph(n, 5)
# Get adj. matrix
A = np.array(nx.adj_matrix(G))
# Spreading\restoring coefficient
beta, gamma = 0.3, 0.2
# Time domain
t = np.arange(0,5,0.05)
# Initial state
idx = np.random.choice(range(n), 30)
i0 = np.zeros((n,))
i0[idx] = 1
# i0 = np.random.random_integers(0,1,[n,])
z0 = np.concatenate((1-i0,i0,np.zeros((n,))))
# System of differential equations..
def sir(z, t, A, n, beta, gamma):
return np.concatenate((
-beta * z[0:n] * A.dot(z[n:2*n]),
beta * z[0:n] * A.dot(z[n:2*n]) - gamma * z[n:2*n],
gamma * z[n:2*n]
))
# ..Solved
z = odeint(sir, z0, t, (A, n, beta, gamma))
# In[29]:
z.shape
# In[37]:
# Plot probs for some node
nId = 6
s = z[:,0:n]
x = z[:,n:2*n]
r = z[:,2*n:3*n]
fig, ax = plt.subplots(1,1,figsize=(10,6))
ax.plot(s,color = 'blue')
ax.plot(x,color = 'red')
ax.plot(r,color = 'green')
ax.set_xlabel('$t$')
ax.set_ylabel('prob')
ax.set_title('Probability for all nodes', fontsize = 15)
# ## Stochastic Modelling
# The stuff that you will see below is kind of simulation model of infection spreading on graph. The description of the model is the following:
#
# * The infection has some vital period, the node is diseased for that period
# * At the end of this period node become susceptible without immunity system's reinforcement
# * Each infected node can spread disease within its neigbours with a sertain probability
# In[38]:
size = 4
# Create Grid Graph
G = nx.grid_2d_graph(size,size)
# Make node relabelling
f = {}
for v in G.nodes_iter():
f[v] = v[0]*size+v[1]
G = nx.relabel_nodes(G, f)
nx.draw_spectral(G)
# In[39]:
def simulSIS(A, timePeriod, modelParams):
# init params
initInfected = modelParams.get('initInfected', None)
p = modelParams.get('probInfect', 0.5)
upd = modelParams.get('updateInfection', True)
maxRecTime = modelParams.get('t2Recover', 2)
# init output
n = A.shape[0]
states = np.zeros([n, timePeriod+1]) # 1 = infected, 0 = susceptable
recTime = np.zeros(n,)
# set initially infected nodes
if initInfected is None:
initInfected = np.random.choice(range(n), n/2)
states[initInfected,0] = 1
else:
states[initInfected,0] = 1
recTime[initInfected] = maxRecTime + 1
# Start simulation
for t in xrange(1, timePeriod+1):
recTime = np.maximum(recTime-1,0)
states[recTime>0, t] = 1
states[recTime==0, t] = 0
curInf = np.nonzero(states[:,t])[0]
states[curInf, t] = 1
for i in curInf:
#NN = np.setdiff1d(np.nonzero(A[i,])[0], curInf)
NN = np.nonzero(A[i,])[0]
infNN = NN[np.random.rand(len(NN))