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