primarycensored
Loading...
Searching...
No Matches
primarycensored_analytical_cdf.stan
Go to the documentation of this file.
1
15int check_for_uniform_terms(int dist_id, int primary_id) {
16 if (primary_id != 1) return 0;
17 return dist_id == 2 || dist_id == 1 || dist_id == 3 || dist_id == 5;
18}
19
37int check_for_analytical(int dist_id, int primary_id) {
38 // Gamma, Lognormal, Weibull and generalised gamma with a Uniform primary
39 if (check_for_uniform_terms(dist_id, primary_id)) return 1;
40 // Keep this primary list in sync with `primary_lcdf`; see the note above.
41 if (dist_id == 26 || dist_id == 27 || dist_id == 28) {
42 return primary_id == 1 || primary_id == 2;
43 }
44 return 0; // No analytical solution for other combinations
45}
46
68real primarycensored_uniform_lcdf_from_terms(vector terms_d, vector terms_q,
69 data real pwindow) {
70 real log_A = log_sum_exp(terms_d[1], terms_q[2]);
71 real log_B = log_sum_exp(terms_q[1], terms_d[2]);
72 // Deep enough into the lower tail every term underflows together. Both
73 // are then `-inf` and `log_diff_exp` would give NaN, so return the limit
74 // directly.
75 if (log_A == negative_infinity() && log_B == negative_infinity()) {
76 return negative_infinity();
77 }
78 return log_diff_exp(log_A, log_B) - log(pwindow);
79}
80
92 array[] real params) {
93 if (t <= 0) {
94 return rep_vector(negative_infinity(), 2);
95 }
96 real shape = params[1];
97 real rate = params[2];
98 // log E where E = k * theta = shape / rate is the mean of the delay
99 real log_E = log(shape) - log(rate);
100 // F_T(t; k) and the recursion to F_T(t; k+1):
101 // P(k+1, y) = P(k, y) - y^k e^{-y} / Gamma(k+1), with y = rate * t
102 real log_F_T_k = gamma_lcdf(t | shape, rate);
103 real gamma_kp1_pdf_log = shape * log(rate * t) - rate * t
104 - lgamma(shape + 1);
105 real log_F_T_kp1 = log_diff_exp(log_F_T_k, gamma_kp1_pdf_log);
106 return [log(t) + log_F_T_k, log_E + log_F_T_kp1]';
107}
108
123vector primarycensored_lognormal_uniform_terms(real t,
124 array[] real params) {
125 real mu = params[1];
126 real sigma = params[2];
127 real mu_sigma2 = mu + square(sigma);
128 // log E where E = exp(mu + sigma^2/2) is the mean of the delay
129 real log_E = mu + 0.5 * square(sigma);
130 real log_t_F_T = lognormal_lcdf_underflows(t, mu, sigma)
131 ? negative_infinity()
132 : log(t) + lognormal_lcdf(t | mu, sigma);
133 real log_E_tF_T = lognormal_lcdf_underflows(t, mu_sigma2, sigma)
134 ? negative_infinity()
135 : log_E + lognormal_lcdf(t | mu_sigma2, sigma);
136 return [log_t_F_T, log_E_tF_T]';
137}
138
153real log_weibull_g(real t, real shape, real scale) {
154 real x = pow(t * inv(scale), shape);
155 real a = 1 + inv(shape);
156 return log(gamma_p(a, x)) + lgamma(a);
157}
158
172 array[] real params) {
173 if (t <= 0) {
174 return rep_vector(negative_infinity(), 2);
175 }
176 real shape = params[1];
177 real scale = params[2];
178 return [
179 log(t) + weibull_lcdf(t | shape, scale),
180 log(scale) + log_weibull_g(t, shape, scale)
181 ]';
182}
183
201vector primarycensored_gengamma_uniform_terms(real t,
202 array[] real params) {
203 if (t <= 0) {
204 return rep_vector(negative_infinity(), 2);
205 }
206 real shape = params[1];
207 real scale = params[2];
208 real k = params[3];
209 real k_shift = k + inv(shape);
210 real log_E = log(scale) + lgamma(k_shift) - lgamma(k);
211 return [
212 log(t) + gengamma_lcdf(t | shape, scale, k),
213 log_E + gengamma_lcdf(t | shape, scale, k_shift)
214 ]';
215}
216
229vector primarycensored_uniform_terms(real t, data int dist_id,
230 array[] real params) {
231 if (dist_id == 2) {
232 return primarycensored_gamma_uniform_terms(t, params);
233 } else if (dist_id == 1) {
235 } else if (dist_id == 3) {
237 } else if (dist_id == 5) {
239 }
240 reject("Invalid distribution identifier: ", dist_id);
241}
242
255real primarycensored_gamma_uniform_lcdf(data real d, real q,
256 array[] real params,
257 data real pwindow) {
260 primarycensored_gamma_uniform_terms(q, params), pwindow
261 );
262}
263
277 array[] real params,
278 data real pwindow) {
282 );
283}
284
298 array[] real params,
299 data real pwindow) {
302 primarycensored_weibull_uniform_terms(q, params), pwindow
303 );
304}
305
320 array[] real params,
321 data real pwindow) {
325 );
326}
327
333real primarycensored_analytical_lcdf_raw(data real d, int dist_id,
334 array[] real params,
335 data real pwindow,
336 int primary_id,
337 array[] real primary_params) {
338 real q = max({d - pwindow, 0});
339
340 if (dist_id == 2 && primary_id == 1) {
341 return primarycensored_gamma_uniform_lcdf(d | q, params, pwindow);
342 } else if (dist_id == 1 && primary_id == 1) {
343 return primarycensored_lognormal_uniform_lcdf(d | q, params, pwindow);
344 } else if (dist_id == 3 && primary_id == 1) {
345 return primarycensored_weibull_uniform_lcdf(d | q, params, pwindow);
346 } else if (dist_id == 5 && primary_id == 1) {
347 return primarycensored_gengamma_uniform_lcdf(d | q, params, pwindow);
348 } else if (dist_id == 26) {
349 // params = [boundaries (K+1), pmf (K)]; length 2*K + 1.
350 int K = (size(params) - 1) %/% 2;
351 return discretestep_lcdf(
352 d | to_vector(segment(params, 1, K + 1)),
353 to_vector(segment(params, K + 2, K)),
354 primary_id, primary_params, pwindow
355 );
356 } else if (dist_id == 27 || dist_id == 28) {
357 // params = [boundaries (K+1), hazards (K)]; length 2*K + 1. The last
358 // hazard must equal 1. RW (27) and RE (28) only differ in their
359 // prior so they share this likelihood dispatch.
360 int K = (size(params) - 1) %/% 2;
361 return discretehazard_lcdf(
362 d | to_vector(segment(params, 1, K + 1)),
363 to_vector(segment(params, K + 2, K)),
364 primary_id, primary_params, pwindow
365 );
366 }
367 return negative_infinity();
368}
369
386real primarycensored_analytical_lcdf(data real d, int dist_id,
387 array[] real params,
388 data real pwindow, data real L,
389 data real D, int primary_id,
390 array[] real primary_params) {
391 if (d <= L) return negative_infinity();
392 if (d >= D) return 0;
393
395 d, dist_id, params, pwindow, primary_id, primary_params
396 );
397
398 // Apply truncation normalization
399 if (!is_inf(D) || L > 0) {
400 vector[2] bounds = primarycensored_truncation_bounds(
401 L, D, dist_id, params, pwindow, primary_id, primary_params
402 );
403 real log_cdf_L = bounds[1];
404 real log_cdf_D = bounds[2];
405
406 real log_normalizer = primarycensored_log_normalizer(log_cdf_D, log_cdf_L, L);
407 result = primarycensored_apply_truncation(result, log_cdf_L, log_normalizer, L);
408 }
409
410 return result;
411}
412
429real primarycensored_analytical_cdf(data real d, int dist_id,
430 array[] real params,
431 data real pwindow, data real L,
432 data real D, int primary_id,
433 array[] real primary_params) {
434 return exp(primarycensored_analytical_lcdf(d | dist_id, params, pwindow, L, D, primary_id, primary_params));
435}
436
455int check_for_analytical_vectorized(int dist_id, int primary_id,
456 data real pwindow) {
457 return check_for_uniform_terms(dist_id, primary_id) &&
458 pwindow >= 1 && floor(pwindow) == pwindow;
459}
460
482 data int n,
483 data int dist_id,
484 array[] real params,
485 data real pwindow) {
486 int pw = to_int(pwindow);
487 vector[n] log_cdfs;
488 // terms[t + 1] holds the terms at delay t
489 array[n + 1] vector[2] terms;
490 for (t in max(start - pw, 0):n) {
491 terms[t + 1] = primarycensored_uniform_terms(t, dist_id, params);
492 }
493 for (d in start:n) {
495 terms[d + 1], terms[max(d - pw, 0) + 1], pwindow
496 );
497 }
498 return log_cdfs;
499}
real log_weibull_g(real t, real shape, real scale)
vector primarycensored_weibull_uniform_terms(real t, array[] real params)
vector primarycensored_lognormal_uniform_terms(real t, array[] real params)
vector primarycensored_gengamma_uniform_terms(real t, array[] real params)
int check_for_uniform_terms(int dist_id, int primary_id)
vector primarycensored_gamma_uniform_terms(real t, array[] real params)
int check_for_analytical_vectorized(int dist_id, int primary_id, data real pwindow)
vector primarycensored_uniform_terms(real t, data int dist_id, array[] real params)
real primarycensored_uniform_lcdf_from_terms(vector terms_d, vector terms_q, data real pwindow)
int check_for_analytical(int dist_id, int primary_id)
real primarycensored_weibull_uniform_lcdf(data real d, real q, array[] real params, data real pwindow)
vector primarycensored_analytical_lcdf_vectorized(data int start, data int n, data int dist_id, array[] real params, data real pwindow)
real primarycensored_analytical_lcdf_raw(data real d, int dist_id, array[] real params, data real pwindow, int primary_id, array[] real primary_params)
real primarycensored_lognormal_uniform_lcdf(data real d, real q, array[] real params, data real pwindow)
real primarycensored_analytical_lcdf(data real d, int dist_id, array[] real params, data real pwindow, data real L, data real D, int primary_id, array[] real primary_params)
real primarycensored_gengamma_uniform_lcdf(data real d, real q, array[] real params, data real pwindow)
real primarycensored_gamma_uniform_lcdf(data real d, real q, array[] real params, data real pwindow)
real primarycensored_analytical_cdf(data real d, int dist_id, array[] real params, data real pwindow, data real L, data real D, int primary_id, array[] real primary_params)
real discretestep_lcdf(data real d, vector boundaries, vector pmf, int primary_id, array[] real primary_params, data real pwindow)
real discretehazard_lcdf(data real d, vector boundaries, vector hazards, int primary_id, array[] real primary_params, data real pwindow)
real primarycensored_apply_truncation(real log_cdf, real log_cdf_L, real log_normalizer, real L)
real primarycensored_log_normalizer(real log_cdf_D, real log_cdf_L, real L)
vector primarycensored_truncation_bounds(data real L, data real D, data int dist_id, array[] real params, data real pwindow, data int primary_id, array[] real primary_params)