@@ -80,21 +80,19 @@ def __init__(self, p: Parameters):
80
80
# Simplify equation to avoid division by zero:
81
81
# self.r_naught = r_t / (1.0 - relative_contact_rate)
82
82
r_naught = (intrinsic_growth_rate + gamma ) / gamma
83
- doubling_time_t = 1.0 / np .log2 (
84
- beta * susceptible - gamma + 1 )
83
+
85
84
86
85
self .susceptible = susceptible
87
86
self .infected = infected
88
87
self .recovered = p .recovered
89
88
90
89
self .detection_probability = detection_probability
91
- self . doubling_time_t = doubling_time_t
90
+
92
91
self .beta = beta
93
92
self .gamma = gamma
93
+ self .beta_t = get_beta (intrinsic_growth_rate , self .gamma , self .susceptible , p .relative_contact_rate )
94
94
self .intrinsic_growth_rate = intrinsic_growth_rate
95
- self .r_t = r_t
96
- self .r_naught = r_naught
97
- self .infected = 1.0 / p .hospitalized .rate / p .market_share
95
+ self .infected = infected
98
96
99
97
if p .date_first_hospitalized is None and p .doubling_time is not None :
100
98
logger .info ('Using doubling_time.' )
@@ -104,13 +102,19 @@ def __init__(self, p: Parameters):
104
102
/ susceptible
105
103
)
106
104
105
+ self .i_day = 0 # seed to the full length
106
+ self .beta_t = self .beta
107
107
self .run_projection (p )
108
108
self .i_day = i_day = int (get_argmin_ds (self .census_df , p .current_hospitalized ))
109
+
110
+ self .beta_t = get_beta (intrinsic_growth_rate , self .gamma , self .susceptible , p .relative_contact_rate )
109
111
self .run_projection (p )
110
112
self .infected = self .raw_df ['infected' ].values [i_day ]
111
113
self .susceptible = self .raw_df ['susceptible' ].values [i_day ]
112
114
self .recovered = self .raw_df ['recovered' ].values [i_day ]
113
115
self .n_days_since = i_day
116
+ self .r_t = self .beta_t / gamma * susceptible
117
+ self .r_naught = self .beta / gamma * susceptible
114
118
logger .info ('Set i_day = %s' , i_day )
115
119
116
120
elif p .date_first_hospitalized is not None and p .doubling_time is None :
@@ -123,6 +127,7 @@ def __init__(self, p: Parameters):
123
127
for i , i_dt in enumerate (dts ):
124
128
intrinsic_growth_rate = get_growth_rate (i_dt )
125
129
self .beta = get_beta (intrinsic_growth_rate , self .gamma , self .susceptible , 0.0 )
130
+ self .beta_t = get_beta (intrinsic_growth_rate , self .gamma , self .susceptible , p .relative_contact_rate )
126
131
127
132
self .run_projection (p )
128
133
loss = self .get_loss ()
@@ -132,17 +137,20 @@ def __init__(self, p: Parameters):
132
137
logger .info ('Set doubling_time = %s' , doubling_time )
133
138
intrinsic_growth_rate = get_growth_rate (p .doubling_time )
134
139
self .beta = get_beta (intrinsic_growth_rate , self .gamma , self .susceptible , 0.0 )
140
+ self .beta_t = get_beta (intrinsic_growth_rate , self .gamma , self .susceptible , p .relative_contact_rate )
135
141
self .run_projection (p )
136
142
137
143
self .intrinsic_growth_rate = intrinsic_growth_rate
138
- self .beta = beta
139
- self .doubling_time_t = doubling_time_t
140
144
self .population = p .population
141
- self .r_t = r_t
142
- self .r_naught = r_naught
143
145
else :
144
146
raise AssertionError ('doubling_time or date_first_hospitalized must be provided.' )
145
147
148
+ self .r_t = self .beta_t / gamma * susceptible
149
+ self .r_naught = self .beta / gamma * susceptible
150
+
151
+ doubling_time_t = 1.0 / np .log2 (
152
+ self .beta_t * susceptible - gamma + 1 )
153
+ self .doubling_time_t = doubling_time_t
146
154
147
155
self .sim_sir_w_date_df = build_sim_sir_w_date_df (self .raw_df , p .current_date )
148
156
@@ -154,10 +162,12 @@ def run_projection(self, p):
154
162
self .susceptible ,
155
163
self .infected ,
156
164
p .recovered ,
157
- self .beta ,
158
165
self .gamma ,
159
- p .n_days + self .i_day ,
160
- - self .i_day
166
+ - self .i_day ,
167
+ self .beta ,
168
+ self .i_day ,
169
+ self .beta_t ,
170
+ p .n_days
161
171
)
162
172
self .dispositions_df = build_dispositions_df (self .raw_df , self .rates , p .market_share , p .current_date )
163
173
self .admits_df = build_admits_df (self .dispositions_df )
@@ -225,28 +235,30 @@ def sir(
225
235
226
236
227
237
def gen_sir (
228
- s : float , i : float , r : float ,
229
- beta : float , gamma : float , n_days : int , i_day : int = 0
238
+ s : float , i : float , r : float , gamma : float , i_day : int = 0 , * args
230
239
) -> Generator [Tuple [int , float , float , float ], None , None ]:
231
- """Simulate SIR model forward in time yielding tuples."""
240
+ """Simulate SIR model forward in time yielding tuples.
241
+ Parameter order has changed to allow multiple (beta, n_days)
242
+ to reflect multiple changing social distancing policies.
243
+ """
232
244
s , i , r = (float (v ) for v in (s , i , r ))
233
245
n = s + i + r
234
246
d = i_day
235
- # TODO: Ask corey if n_days is really required for the sim
236
- # while i >= 0.5:
237
- for _ in range (n_days ):
238
- yield d , s , i , r
239
- s , i , r = sir (s , i , r , beta , gamma , n )
240
- d += 1
247
+ while args :
248
+ beta , n_days , * args = args
249
+ for _ in range (n_days ):
250
+ yield d , s , i , r
251
+ s , i , r = sir (s , i , r , beta , gamma , n )
252
+ d += 1
241
253
yield d , s , i , r
242
254
243
255
244
256
def sim_sir_df (
245
- s : float , i : float , r : float , beta : float , gamma : float , n_days : int , i_day : int = 0
257
+ s : float , i : float , r : float , gamma : float , i_day : int = 0 , * args
246
258
) -> pd .DataFrame :
247
259
"""Simulate the SIR model forward in time."""
248
260
return pd .DataFrame (
249
- data = gen_sir (s , i , r , beta , gamma , n_days , i_day ),
261
+ data = gen_sir (s , i , r , gamma , i_day , * args ),
250
262
columns = ("day" , "susceptible" , "infected" , "recovered" ),
251
263
)
252
264
0 commit comments