Skip to content

Commit 1f9e74c

Browse files
Merge pull request #174 from stan-dev/case-study/liza-sir-model
corrections
2 parents f0341fe + 6b9449e commit 1f9e74c

File tree

5 files changed

+308
-111
lines changed

5 files changed

+308
-111
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
@misc{chatzilena2019contemporary,
2+
title={Contemporary statistical inference for infectious disease models using Stan},
3+
author={Anastasia Chatzilena and Edwin van Leeuwen and Oliver Ratmann and Marc Baguelin and Nikolaos Demiris},
4+
year={2019},
5+
eprint={1903.00423},
6+
archivePrefix={arXiv},
7+
primaryClass={stat.AP}
8+
}
9+
10+
@article{kermack_contributions_1991,
11+
title = {Contributions to the mathematical theory of epidemics{I}},
12+
volume = {53},
13+
issn = {1522-9602},
14+
url = {https://doi.org/10.1007/BF02464423},
15+
doi = {10.1007/BF02464423},
16+
number = {1},
17+
journal = {Bulletin of Mathematical Biology},
18+
author = {Kermack, W. O. and McKendrick, A. G.},
19+
month = mar,
20+
year = {1991},
21+
pages = {33--55}
22+
}
23+
24+
@misc{carpenter2015stan,
25+
title={The Stan Math Library: Reverse-Mode Automatic Differentiation in C++},
26+
author={Bob Carpenter and Matthew D. Hoffman and Marcus Brubaker and Daniel Lee and Peter Li and Michael Betancourt},
27+
year={2015},
28+
eprint={1509.07164},
29+
archivePrefix={arXiv},
30+
primaryClass={cs.MS}
31+
}
32+
33+
@article {PMID:12995455,
34+
Title = {The analysis of equilibrium in malaria},
35+
Author = {MACDONALD, G},
36+
Number = {9},
37+
Volume = {49},
38+
Month = {September},
39+
Year = {1952},
40+
Journal = {Tropical diseases bulletin},
41+
ISSN = {0041-3240},
42+
Pages = {813—829},
43+
URL = {http://europepmc.org/abstract/MED/12995455}
44+
}
45+
46+
@conference{margossian_differential_2017,
47+
Author = {Margossian, Charles C and Gillespie, William R},
48+
Booktitle = {StanCon 2017},
49+
Journal = {Journal of Pharmacokinetics and Pharmacodynamics},
50+
Month = {January},
51+
Title = {Differential Equation Based Models in Stan},
52+
Year = {2017},
53+
doi = {10.5281/zenodo.1284264}}
54+
55+
@misc{carpenter_predator-prey_2018,
56+
title = {Predator-{Prey} {Population} {Dynamics}: the {Lotka}-{Volterra} model in {Stan}},
57+
url = {https://mc-stan.org/users/documentation/case-studies/lotka-volterra-predator-prey.html},
58+
author = {Carpenter, Bob},
59+
year = {2018}
60+
}
61+
@misc{prior_choice,
62+
title = {Prior Choice Recommendations},
63+
url = {https://github.com/stan-dev/stan/wiki/Prior-Choice-Recommendations},
64+
author = {Stan Team},
65+
year = {2020}
66+
}
67+
68+
@article{hall_infectious_1992,
69+
title = {Infectious {Diseases} of {Humans}. {R}. {M}. {Anderson} \& {R}. {M}. {May}. {Oxford} etc.: {Oxford} {University} {Press}, 1991. viii+757 pp. {Price} £50. {ISBN} 0-19-854599-1},
70+
volume = {86},
71+
issn = {0035-9203},
72+
url = {https://doi.org/10.1016/0035-9203(92)90276-I},
73+
doi = {10.1016/0035-9203(92)90276-I},
74+
number = {4},
75+
journal = {Transactions of The Royal Society of Tropical Medicine and Hygiene},
76+
author = {Hall, A.J.},
77+
year = {1992},
78+
pages = {461--461}
79+
}
80+
81+
@article{Riou_covid_2020,
82+
Author = {Riou, Julien and Hauser, Anthony and Counotte, Michel J and Margossian, Charles C
83+
and Konstantinoudis, Garyfallos and Low, Nicola and Althaus, Christian L},
84+
Title = {Estimation of SARS-CoV-2 mortality during the early stages of an epidemic:
85+
a modeling study in Hubei, China and northern Italy},
86+
journal = {medRxiv:2020.03.04.20031104},
87+
year = {2020}}
88+
89+
@article{Betancourt_hmc_2018,
90+
Author = {Betancourt, Michael},
91+
Journal = {arXiv:1701.02434v1},
92+
Month = {January},
93+
Title = {A Conceptual Introduction to Hamiltonian Monte Carlo},
94+
Year = {2018}}
95+
96+
@article{Hoffman_nuts_2014,
97+
Author = {Hoffman, Matthew D. and Gelman, Andrew},
98+
Date-Added = {2016-10-07 17:06:45 +0000},
99+
Date-Modified = {2017-08-17 09:27:44 +0000},
100+
Journal = {Journal of Machine Learning Research},
101+
Month = {April},
102+
Pages = {1593-1623},
103+
Title = {The No-U-Turn Sampler: Adaptively Setting Path Lengths in Hamiltonian Monte Carlo},
104+
Year = {2014}}
105+
106+
@techreport{Hindmarsh_ode_2020,
107+
Author = {Hindmarsh, Alan and Serban, Radu},
108+
Date-Modified = {2020-01-16 22:47:24 -0500},
109+
Institution = {Lawrence Livermore National Laboratory},
110+
Month = {January},
111+
Title = {User Documentation for CVODES v5.1.0},
112+
Year = {2020}}
113+
114+
@book{Griewank_ad_2008,
115+
Author = {Griewank, Andreas and Walther, Andrea},
116+
Edition = {Second},
117+
Publisher = {Society for Industrial and Applied Mathematics (SIAM), Philadelphia, PA},
118+
Title = {Evaluating derivatives},
119+
Year = {2008}}
120+
121+
@article{Margossian_ad_2019,
122+
Author = {Charles C. Margossian},
123+
Month = {3},
124+
Title = {A Review of automatic differentiation and its efficient implementation},
125+
journal = {Wiley interdisciplinary reviews: data mining and knowledge discovery},
126+
volume = {9},
127+
issue = {4},
128+
doi = {10.1002/WIDM.1305},
129+
Year = {2019}}
130+
131+
@article{margossian_mixed_solver_2017,
132+
Author = {Margossian, Charles C and Gillespie, William R},
133+
Booktitle = {American },
134+
Journal = {Journal of Pharmacokinetics and Pharmacodynamics},
135+
Month = {October},
136+
Title = {Gaining Efficiency by Combining Analytical and Numerical Methods to Solve ODEs: Implementation in Stan and Application to Bayesian PK/PD },
137+
Volume = {44},
138+
Year = {2017}}
139+
140+
@article{Flaxman_covid_2020,
141+
Author = {Seth Flaxman and Swapnil Mishra and Axel Gandy and H Juliette T Unwin and Helen Coupland and ... and Samir Bhatt},
142+
title = {Report 13 - Estimating the number of infections and the impact of non-pharmaceutical interventions on COVID-19 in 11 European countries},
143+
journal = {arXiv:2004.11342},
144+
year = {2020},
145+
month = {April}}
146+
147+
@article{Carpenter_stan_2017,
148+
Title = {Stan: A Probabilistic Programming Language},
149+
Author = {Carpenter, Bob and Gelman, Andrew and Hoffman, Matt and Lee, Daniel and Goodrich, Ben and Betancourt, Michael and Brubaker, Marcus A. and Guo, Jiqiang and Li, Peter and Riddel, Allen},
150+
Journal = {Journal of Statistical Software},
151+
volume = {76},
152+
issue = {1},
153+
pages = {1 --32},
154+
Year = {2017},
155+
doi = {10.18637/jss.v076.i01}}
156+
157+
@article{Chatzilena_tutorial_2019,
158+
author = {Chatzilena, Anastasia and van Leeuwen, Edwin and Ratmann, Olivier
159+
and Baguelin, Olivier and Demiris, Nikolaos},
160+
title = {Contemporary statistical inference for infectious disease models using Stan},
161+
journal = {Epidemics},
162+
volume = {29},
163+
year = {2019},
164+
doi = {https://doi.org/10.1016/j.epidem.2019.100367}}
165+
166+
@article{Mihaljevic_tutorial_2016,
167+
title = {Estimating transmission by fitting mechanistic models in Stan},
168+
author = {Mihaljevic, Joseph},
169+
year = {2016},
170+
url = {https://jrmihalj.github.io/estimating-transmission-by-fitting-mechanistic-models-in-Stan/}
171+
}
172+
173+
@article{Weber_ode_2018,
174+
title = {Solving ODEs in the wild: Scalable pharmacometrics with Stan},
175+
author = {Weber, Sebastian},
176+
journal = {StanCon Helsinki 2018},
177+
year = {2018}}
178+
179+
@article{Carpenter_predatory-prey_2018,
180+
title = {Predator-Prey Population Dynamics: the Lotka-Volterra model in Stan},
181+
author = {Carpenter, Bob},
182+
url = {https://mc-stan.org/users/documentation/case-studies/lotka-volterra-predator-prey.html},
183+
year = {2018}}
184+
185+
@article{Talts_sbc_2018,
186+
author = {Talts, Sean and Betancourt, Michael and Simpson, Daniel and Vehtari, Aki and Gelman, Andrew},
187+
title = {Validating Bayesian inference algorithms with simulation-based calibration},
188+
journal = {arXiv:1804.06788v1},
189+
year = {2018}}
190+
191+
@article{Roberts_mcmc_2004,
192+
author = {Roberts, Gareth O and Rosenthal, Jeffrey S},
193+
title = {General state space Markov chains and MCMC algorithms},
194+
journal = {Probability survey},
195+
volume = {1},
196+
pages = {20 - 71},
197+
doi = {10.1214/154957804100000024},
198+
year = {2004}}
199+

knitr/disease_transmission/boarding_school_case_study.Rmd

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -305,21 +305,25 @@ We motivate this signature in our discussion on scaling ODEs (section 3).
305305

306306
In our example, the ODEs for the SIR model is defined as follows:
307307
```{stan, eval=F, output.var="md"}
308-
//theta[1] = beta
309-
//theta[2] = gamma
310-
//x_i[1] = N, total population
311-
// y = S, I, R
312-
real[] sir(real t,
313-
real[] y,
314-
real[] theta,
315-
real[] x_r,
316-
int[] x_i) {
317-
real dydt[3];
318-
dydt[1] = - theta[1] * y[1] * y[2] / x_i[1];
319-
dydt[2] = theta[1] * y[1] * y[2] / x_i[1] - theta[2] * y[2];
320-
dydt[3] = theta[2] * y[2];
321-
return dydt;
308+
functions {
309+
real[] sir(real t, real[] y, real[] theta,
310+
real[] x_r, int[] x_i) {
311+
312+
real S = y[1];
313+
real I = y[2];
314+
real R = y[3];
315+
real N = x_i[1];
316+
317+
real beta = theta[1];
318+
real gamma = theta[2];
319+
320+
real dS_dt = -beta * I * S / N;
321+
real dI_dt = beta * I * S / N - gamma * I;
322+
real dR_dt = gamma * I;
323+
324+
return {dS_dt, dI_dt, dR_dt};
322325
}
326+
}
323327
```
324328

325329
We evaluate the solution numerically by using one of Stan's numerical integrators.
@@ -343,6 +347,13 @@ with
343347

344348
We now have all the ingredients to solve our ODE.
345349

350+
Note that in the given example, when we assume that the total population remains constant, the three derivatives $\frac{dS}{dt}$, $\frac{dI}{dt}$, $\frac{dR}{dt}$ sum up to $0$: We can use this fact to improve computational efficiency of the `sir` function by deriving the value of $\frac{dI}{dt}$ from $\frac{dS}{dt}$ and $\frac{dR}{dt}$:
351+
```{stan, eval=F, output.var="md"}
352+
real dS_dt = -beta * I * S / N;
353+
real dR_dt = gamma * I;
354+
real dI_dt = -(dS_dt + dR_dt);
355+
```
356+
346357
### Building the model in Stan
347358

348359
We next code the model in Stan, working through the various coding blocks.
@@ -553,24 +564,24 @@ ggplot(smr_y, mapping = aes(x = t)) +
553564
## Complete Stan program
554565
```{stan, eval=F, output.var="md"}
555566
functions {
556-
//theta[1] = beta
557-
//theta[2] = gamma
558-
//x_i[1] = N, total population
559-
// y = S, I, R
560-
real[] sir(real t,
561-
real[] y,
562-
real[] theta,
563-
real[] x_r,
564-
int[] x_i) {
565-
real dydt[3];
566-
dydt[1] = - theta[1] * y[1] * y[2] / x_i[1];
567-
dydt[2] = theta[1] * y[1] * y[2] / x_i[1] - theta[2] * y[2];
568-
dydt[3] = theta[2] * y[2];
569-
return dydt;
570-
567+
real[] sir(real t, real[] y, real[] theta,
568+
real[] x_r, int[] x_i) {
569+
570+
real S = y[1];
571+
real I = y[2];
572+
real R = y[3];
573+
real N = x_i[1];
574+
575+
real beta = theta[1];
576+
real gamma = theta[2];
577+
578+
real dS_dt = -beta * I * S / N;
579+
real dI_dt = beta * I * S / N - gamma * I;
580+
real dR_dt = gamma * I;
581+
582+
return {dS_dt, dI_dt, dR_dt};
571583
}
572584
}
573-
574585
data {
575586
int<lower=1> n_days;
576587
real y0[3];
@@ -579,18 +590,15 @@ data {
579590
int N;
580591
int cases[n_days];
581592
}
582-
583593
transformed data {
584594
real x_r[0];
585595
int x_i[1] = { N };
586596
}
587-
588597
parameters {
589598
real<lower=0> gamma;
590599
real<lower=0> beta;
591600
real<lower=0> phi_inv;
592601
}
593-
594602
transformed parameters{
595603
real y[n_days, 3];
596604
real phi = 1. / phi_inv;
@@ -602,8 +610,6 @@ transformed parameters{
602610
y = integrate_ode_rk45(sir, y0, t0, ts, theta, x_r, x_i);
603611
}
604612
}
605-
606-
607613
model {
608614
//priors
609615
beta ~ normal(2, 1);
@@ -614,14 +620,12 @@ model {
614620
//col(matrix x, int n) - The n-th column of matrix x. Here the number of infected people
615621
cases ~ neg_binomial_2(col(to_matrix(y), 2), phi);
616622
}
617-
618623
generated quantities {
619624
real R0 = beta / gamma;
620625
real recovery_time = 1 / gamma;
621626
real pred_cases[n_days];
622627
pred_cases = neg_binomial_2_rng(col(to_matrix(y), 2), phi);
623628
}
624-
625629
```
626630

627631
# 2 Using simulated data to understand our model
@@ -716,7 +720,7 @@ colnames(smr_pred) <- make.names(colnames(smr_pred)) # to remove % in the col na
716720
ggplot(smr_pred, mapping=aes(x=t)) +
717721
geom_ribbon(aes(ymin = X5., ymax = X95.), fill = "orange", alpha = 0.6) +
718722
geom_line(mapping=aes(x=t, y=X50.)) +
719-
geom_abline(intercept=577, color="red", ) +
723+
geom_abline(intercept=577, color="red" ) +
720724
geom_text(x=1.8, y=560, label="Population size", color="red") +
721725
labs(x = "Day", y="Number of students in bed")
722726
```

0 commit comments

Comments
 (0)