Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# coding: utf-8
2"""
3Implementation of a model for epidemics propagation.
4"""
5import numpy.random
6from ._base_sir import BaseSIR
7from .covid_sird import CovidSIRD
10class CovidSIRDMixture(BaseSIR):
11 """
12 The model extends model @see cl CovidSIRD and assumes
13 there are two variants of the same virus.
14 The term `beta1 * beta2 * S * I1 / N * I2 / N` means
15 that for all people being in contact with both
16 virus, the second one wins as it is more contagious.
18 .. runpython::
19 :showcode:
20 :rst:
22 from aftercovid.models import CovidSIRDMixture
24 model = CovidSIRDMixture()
25 print(model.to_rst())
27 .. exref::
28 :title: Mixture of SIRD simulation and plotting
30 .. plot::
32 from pandas import DataFrame
33 import matplotlib.pyplot as plt
34 from aftercovid.models import CovidSIRDMixture
36 model = CovidSIRDMixture()
37 sims = list(model.iterate(60))
38 df = DataFrame(sims)
39 print(df.head())
40 ax = df.plot(y=['S', 'I1', 'I2', 'R', 'D'], kind='line')
41 ax.set_xlabel("jours")
42 ax.set_ylabel("population")
43 r0 = model.R0()
44 ax.set_title("Simulation SIRD\\nR0=%f" % r0)
46 plt.show()
48 Visual representation:
50 .. gdot::
51 :script:
53 from aftercovid.models import CovidSIRDMixture
54 model = CovidSIRDMixture()
55 print(model.to_dot())
57 See :ref:`l-base-model-sir` to get the methods
58 common to SIRx models.
59 """
61 P0 = [
62 ('beta1', 0.5, 'taux de transmission dans la population'),
63 ('beta2', 0.7, 'second taux de transmission dans la population'),
64 ('mu', 1 / 14., '1/. : durée moyenne jusque la guérison'),
65 ('nu', 1 / 21., '1/. : durée moyenne jusqu\'au décès'),
66 ]
68 Q0 = [
69 ('S', 9990., 'personnes non contaminées'),
70 ('I1', 8., 'nombre de personnes malades ou contaminantes '
71 'pour le premier variant'),
72 ('I2', 2., 'nombre de personnes malades ou contaminantes '
73 'pour le second variant'),
74 ('R', 0., 'personnes guéries (recovered)'),
75 ('D', 0., 'personnes décédées'),
76 ]
78 C0 = [
79 ('N', 10000., 'population'),
80 ]
82 eq = {
83 'S': ('- beta1 * S / N * I1 - beta2 * S / N * I2 '
84 '+ beta1 * beta2 * S * I1 / N * I2 / N'),
85 'I1': ('beta1 * S / N * I1 - mu * I1 - nu * I1 '
86 '- beta1 * beta2 * S * I1 / N * I2 / N'),
87 'I2': 'beta2 * S / N * I2 - mu * I2 - nu * I2',
88 'R': 'mu * (I1 + I2)',
89 'D': 'nu * (I1 + I2)'
90 }
92 def __init__(self):
93 BaseSIR.__init__(
94 self,
95 p=CovidSIRDMixture.P0.copy(),
96 q=CovidSIRDMixture.Q0.copy(),
97 c=CovidSIRDMixture.C0.copy(),
98 eq=CovidSIRDMixture.eq.copy())
100 def R0(self, t=0):
101 '''
102 Returns R0 coefficient.
104 :param t: unused
105 '''
106 return (self['beta1'] + self['beta2']) / (self['nu'] + self['mu'])
108 def correctness(self, X=None):
109 """
110 Unused.
111 """
112 if X is None:
113 X = self.vect().reshape((1, -1))
114 return numpy.zeros(X.shape)
116 def rnd(self):
117 '''
118 Draws random parameters.
119 Not perfect.
120 '''
121 self['beta1'] = numpy.random.randn(1) * 0.1 + 0.5
122 self['beta2'] = numpy.random.randn(1) * 0.1 + 0.7
123 self['mu'] = numpy.random.randn(1) * 0.1 + 1. / 14
124 self['nu'] = numpy.random.randn(1) * 0.1 + 1. / 21
126 @staticmethod
127 def add_noise(X, epsilon=1.):
128 """
129 Tries to add reasonable noise to the quantities stored in *X*.
131 :param epsilon: amplitude
132 :return: new X
133 """
134 return CovidSIRD.add_noise(X, epsilon=epsilon)