Coverage for aftercovid/models/covid_sird_mixture.py: 100%

25 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2024-03-28 03:09 +0100

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 

8 

9 

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. 

17 

18 .. runpython:: 

19 :showcode: 

20 :rst: 

21 

22 from aftercovid.models import CovidSIRDMixture 

23 

24 model = CovidSIRDMixture() 

25 print(model.to_rst()) 

26 

27 .. exref:: 

28 :title: Mixture of SIRD simulation and plotting 

29 

30 .. plot:: 

31 

32 from pandas import DataFrame 

33 import matplotlib.pyplot as plt 

34 from aftercovid.models import CovidSIRDMixture 

35 

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) 

45 

46 plt.show() 

47 

48 Visual representation: 

49 

50 .. gdot:: 

51 :script: 

52 

53 from aftercovid.models import CovidSIRDMixture 

54 model = CovidSIRDMixture() 

55 print(model.to_dot()) 

56 

57 See :ref:`l-base-model-sir` to get the methods 

58 common to SIRx models. 

59 """ 

60 

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 ] 

67 

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 ] 

77 

78 C0 = [ 

79 ('N', 10000., 'population'), 

80 ] 

81 

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 } 

91 

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()) 

99 

100 def R0(self, t=0): 

101 ''' 

102 Returns R0 coefficient. 

103 

104 :param t: unused 

105 ''' 

106 return (self['beta1'] + self['beta2']) / (self['nu'] + self['mu']) 

107 

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) 

115 

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 

125 

126 @staticmethod 

127 def add_noise(X, epsilon=1.): 

128 """ 

129 Tries to add reasonable noise to the quantities stored in *X*. 

130 

131 :param epsilon: amplitude 

132 :return: new X 

133 """ 

134 return CovidSIRD.add_noise(X, epsilon=epsilon)