EpiNow2 Stan Functions
delays.stan
Go to the documentation of this file.
1/**
2 * Delay Distribution Functions
3 *
4 * This group of functions handles the creation, manipulation, and application
5 * of delay distributions in the model. Delay distributions represent the time
6 * between events (e.g., infection to symptom onset, symptom onset to reporting).
7 *
8 * Per-delay values (PMFs, parameters) are packed into ragged vectors: one
9 * vector holds the concatenated values for every delay, and a companion
10 * `*_groups` array of lookup indices marks where each delay's segment
11 * starts and ends within that vector. See the Stan User's Guide section on
12 * ragged data structures:
13 * https://mc-stan.org/docs/stan-users-guide/sparse-ragged.html#ragged-data-structs.section
14 *
15 */
16
17/**
18 * Get the maximum delay for each delay type
19 *
20 * @param delay_types Number of delay types
21 * @param delay_types_p Array indicating whether each delay is parametric (1) or non-parametric (0)
22 * @param delay_types_id Array mapping delay types to their respective IDs
23 * @param delay_types_groups Array of lookup indices for the ragged groups
24 * of delay types
25 * @param delay_max Array of maximum delays for parametric distributions
26 * @param delay_np_pmf_groups Array of lookup indices for the ragged
27 * non-parametric PMF vector
28 * @return An array of maximum delays for each delay type
29 *
30 * @ingroup delay_handlers
31 */
33 int delay_types, array[] int delay_types_p, array[] int delay_types_id,
34 array[] int delay_types_groups, array[] int delay_max,
35 array[] int delay_np_pmf_groups
36) {
37 array[delay_types] int ret;
38 for (i in 1:delay_types) {
39 ret[i] = 0;
40 for (j in delay_types_groups[i]:(delay_types_groups[i + 1] - 1)) {
41 if (delay_types_p[j]) { // parametric
42 ret[i] += delay_max[delay_types_id[j]];
43 } else { // nonparametric
44 ret[i] += delay_np_pmf_groups[delay_types_id[j] + 1] -
45 delay_np_pmf_groups[delay_types_id[j]] - 1;
46 }
47 }
48 }
49 return ret;
50}
51
52/**
53 * Get the reversed probability mass function for a delay
54 *
55 * @param delay_id Identifier for the specific delay distribution
56 * @param len Length of the output PMF
57 * @param delay_types_p Array indicating whether each delay is parametric (1) or non-parametric (0)
58 * @param delay_types_id Array mapping delay types to their respective IDs
59 * @param delay_types_groups Array of lookup indices for the ragged groups
60 * of delay types
61 * @param delay_max Array of maximum delays for parametric distributions
62 * @param delay_np_pmf Ragged vector of probability mass functions for
63 * non-parametric delays
64 * @param delay_np_pmf_groups Array of lookup indices for the ragged
65 * non-parametric PMF vector
66 * @param delay_params Ragged vector of parameters for parametric delay
67 * distributions
68 * @param delay_params_groups Array of lookup indices for the ragged
69 * parameter vector
70 * @param delay_dist Array of distribution types using primarycensored
71 * convention (1: lognormal, 2: gamma, 3: weibull, 4: exponential)
72 * @param left_truncate Left truncation point (0 for no truncation)
73 * @param reverse_pmf Whether to reverse the PMF (1) or not (0)
74 * @param cumulative Whether to return cumulative (1) or daily (0) values
75 * @return A vector containing the (reversed) PMF of length len
76 *
77 * @ingroup delay_handlers
78 */
80 int delay_id, int len, array[] int delay_types_p, array[] int delay_types_id,
81 array[] int delay_types_groups, array[] int delay_max,
82 vector delay_np_pmf, array[] int delay_np_pmf_groups,
83 vector delay_params, array[] int delay_params_groups, array[] int delay_dist,
84 int left_truncate, int reverse_pmf, int cumulative
85) {
86 // loop over delays
87 vector[len] pmf = rep_vector(0, len);
88 int current_len = 1;
89 int new_len;
90 for (i in
91 delay_types_groups[delay_id]:(delay_types_groups[delay_id + 1] - 1)) {
92 if (delay_types_p[i]) { // parametric
93 int start = delay_params_groups[delay_types_id[i]];
94 int end = delay_params_groups[delay_types_id[i] + 1] - 1;
95 vector[delay_max[delay_types_id[i]] + 1] new_variable_pmf =
97 delay_params[start:end],
98 delay_max[delay_types_id[i]] + 1,
99 delay_dist[delay_types_id[i]],
100 0
101 );
102 new_len = current_len + delay_max[delay_types_id[i]];
103 if (current_len == 1) { // first delay
104 pmf[1:new_len] = new_variable_pmf;
105 } else { // subsequent delay to be convolved
106 pmf[1:new_len] = convolve_with_rev_pmf(
107 pmf[1:current_len], reverse(new_variable_pmf), new_len
108 );
109 }
110 } else { // nonparametric
111 int start = delay_np_pmf_groups[delay_types_id[i]];
112 int end = delay_np_pmf_groups[delay_types_id[i] + 1] - 1;
113 new_len = current_len + end - start;
114 if (current_len == 1) { // first delay
115 pmf[1:new_len] = delay_np_pmf[start:end];
116 } else { // subsequent delay to be convolved
117 pmf[1:new_len] = convolve_with_rev_pmf(
118 pmf[1:current_len], reverse(delay_np_pmf[start:end]), new_len
119 );
120 }
121 }
122 current_len = new_len;
123 }
124 if (left_truncate) {
125 pmf = append_row(
126 rep_vector(0, left_truncate),
127 pmf[(left_truncate + 1):len] / sum(pmf[(left_truncate + 1):len])
128 );
129 }
130 if (cumulative) {
131 pmf = cumulative_sum(pmf);
132 }
133 if (reverse_pmf) {
134 pmf = reverse(pmf);
135 }
136 return pmf;
137}
138
139/**
140 * Update log density for delay distribution priors
141 *
142 * @param delay_params Ragged vector of parameters for parametric delay
143 * distributions
144 * @param delay_params_mean Ragged vector of prior means for delay parameters
145 * @param delay_params_sd Ragged vector of prior standard deviations for
146 * delay parameters
147 * @param delay_params_groups Array of lookup indices for the ragged
148 * parameter vectors
149 * @param delay_dist Array of distribution types using primarycensored
150 * convention (1: lognormal, 2: gamma, 3: weibull, 4: exponential)
151 * @param weight Array of weights for each delay distribution in the log density
152 *
153 * @ingroup delay_handlers
154 */
155void delays_lp(vector delay_params,
156 vector delay_params_mean, vector delay_params_sd,
157 array[] int delay_params_groups,
158 array[] int delay_dist, array[] int weight) {
159 int n_delays = num_elements(delay_params_groups) - 1;
160 if (n_delays == 0) {
161 return;
162 }
163 for (d in 1:n_delays) {
164 int start = delay_params_groups[d];
165 int end = delay_params_groups[d + 1] - 1;
166 for (s in start:end) {
167 if (delay_params_sd[s] > 0) {
168 if (weight[d] > 1) {
169 target += weight[d] *
170 normal_lpdf(
171 delay_params[s] | delay_params_mean[s], delay_params_sd[s]
172 );
173 } else {
174 delay_params[s] ~ normal(delay_params_mean[s], delay_params_sd[s]);
175 }
176 }
177 }
178 }
179}
180
181/**
182 * Update log prior density for estimated nonparametric delays
183 *
184 * Applies Gamma(alpha, 1) priors to the raw vector that backs the
185 * estimated nonparametric PMFs. Once normalised within each ragged
186 * segment, this induces a Dirichlet(alpha) prior on the segment.
187 * See https://mc-stan.org/docs/stan-users-guide/simplexes.html for
188 * the gamma-normalisation construction.
189 *
190 * @param delay_np_est_raw Raw gamma-distributed values backing each
191 * estimated nonparametric PMF segment.
192 * @param delay_np_est_alpha Dirichlet concentration parameters,
193 * matched element-wise to delay_np_est_raw.
194 *
195 * @ingroup delay_handlers
196 */
198 vector delay_np_est_raw, vector delay_np_est_alpha
199) {
200 if (num_elements(delay_np_est_raw) == 0) return;
201 delay_np_est_raw ~ gamma(delay_np_est_alpha, 1);
202}
203
204/**
205 * Combine fixed and estimated nonparametric delay PMFs
206 *
207 * Returns a copy of the fixed PMF vector with the estimated entries
208 * overwritten by per-segment normalisation of the raw gamma values.
209 * Fixed entries and structural zeros are left unchanged.
210 *
211 * @param delay_np_pmf Fixed PMF vector (concatenated ragged array).
212 * @param delay_n_np_est Number of estimated nonparametric delays.
213 * @param delay_np_est_groups Ragged-array boundaries into
214 * delay_np_est_raw (length delay_n_np_est + 1).
215 * @param delay_np_est_pos For each estimated element, its position
216 * within delay_np_pmf.
217 * @param delay_np_est_raw Raw gamma values backing each segment.
218 * @return A vector of length num_elements(delay_np_pmf) containing
219 * the combined PMF.
220 *
221 * @ingroup delay_handlers
222 */
224 vector delay_np_pmf, int delay_n_np_est,
225 array[] int delay_np_est_groups, array[] int delay_np_est_pos,
226 vector delay_np_est_raw
227) {
228 vector[num_elements(delay_np_pmf)] ret = delay_np_pmf;
229 for (i in 1:delay_n_np_est) {
230 int es = delay_np_est_groups[i];
231 int ee = delay_np_est_groups[i + 1] - 1;
232 real seg_sum = sum(delay_np_est_raw[es:ee]);
233 for (j in es:ee) {
234 ret[delay_np_est_pos[j]] = delay_np_est_raw[j] / seg_sum;
235 }
236 }
237 return ret;
238}
239
240/**
241 * Generate random samples from a normal distribution with lower bounds
242 *
243 * @param mu Vector of means
244 * @param sigma Vector of standard deviations
245 * @param lb Vector of lower bounds
246 * @return A vector of random samples from the truncated normal distribution
247 *
248 * @ingroup delay_handlers
249 */
250vector normal_lb_rng(vector mu, vector sigma, vector lb) {
251 int len = num_elements(mu);
252 vector[len] ret;
253 for (i in 1:len) {
254 real p = normal_cdf(lb[i] | mu[i], sigma[i]); // cdf for bounds
255 real u = uniform_rng(p, 1);
256 ret[i] = (sigma[i] * inv_Phi(u)) + mu[i]; // inverse cdf for value
257 }
258 return ret;
259}
vector convolve_with_rev_pmf(vector x, vector y, int len)
Definition convolve.stan:62
array[] int get_delay_type_max(int delay_types, array[] int delay_types_p, array[] int delay_types_id, array[] int delay_types_groups, array[] int delay_max, array[] int delay_np_pmf_groups)
Definition delays.stan:32
void delays_np_lp(vector delay_np_est_raw, vector delay_np_est_alpha)
Definition delays.stan:197
void delays_lp(vector delay_params, vector delay_params_mean, vector delay_params_sd, array[] int delay_params_groups, array[] int delay_dist, array[] int weight)
Definition delays.stan:155
vector combine_np_pmf(vector delay_np_pmf, int delay_n_np_est, array[] int delay_np_est_groups, array[] int delay_np_est_pos, vector delay_np_est_raw)
Definition delays.stan:223
vector normal_lb_rng(vector mu, vector sigma, vector lb)
Definition delays.stan:250
vector get_delay_rev_pmf(int delay_id, int len, array[] int delay_types_p, array[] int delay_types_id, array[] int delay_types_groups, array[] int delay_max, vector delay_np_pmf, array[] int delay_np_pmf_groups, vector delay_params, array[] int delay_params_groups, array[] int delay_dist, int left_truncate, int reverse_pmf, int cumulative)
Definition delays.stan:79
vector discretised_pmf(vector params, data int n, int dist, data int L)
Definition pmfs.stan:27