epinowcast
discretised_logit_hazard.stan
Go to the documentation of this file.
1
16real loglogistic_lcdf (real y, real alpha, real beta) {
17 return -log1p((y / alpha) ^-beta);
18}
19
40vector lcdf_discretised(real mu, real sigma, int u, int dist) {
41 vector[u] integer_lcdf;
42 if (dist == 1) {
43 real emu = exp(-mu);
44 for (i in 1:u) {
45 integer_lcdf[i] = exponential_lcdf(i | emu);
46 }
47 } else if (dist == 2) {
48 for (i in 1:u) {
49 integer_lcdf[i] = lognormal_lcdf(i | mu, sigma);
50 }
51 } else if (dist == 3) {
52 real emu = exp(mu);
53 for (i in 1:u) {
54 integer_lcdf[i] = gamma_lcdf(i | emu, sigma);
55 }
56 } else if (dist == 4) {
57 real emu = exp(mu);
58 for (i in 1:u) {
59 integer_lcdf[i] = loglogistic_lcdf(i | emu, sigma);
60 }
61 } else {
62 reject("Unknown distribution function provided.");
63 }
64 return(integer_lcdf);
65}
66
85 int max_strat) {
86 vector[u] adjusted_lcdf;
87 if (max_strat == 0) {
88 // ignore (i.e. sum of probabilities does not add to 1)
89 // NOTE: This cannot be used when using lcdf_to_logit_hazard as
90 // it will return the same result as using strategy 2.
91 adjusted_lcdf = lcdf;
92 } else if (max_strat == 1) {
93 // add to upper bound: cdf_u = 1 (i.e. lcdf_u = 0)
94 adjusted_lcdf = lcdf;
95 adjusted_lcdf[u] = 0;
96 // normalise to account for double censoring
97 adjusted_lcdf = adjusted_lcdf - log(2);
98 } else if (max_strat == 2) {
99 // normalize: cdf = cdf / (cdf[u] + cdf[u-1])
100 // both u and u-1 are in the denominator to account for the 2 day width of
101 // the (overlapping) intervals from the uniform interval approximation:
102 // For a delay d, the interval is [d-1, d+1], e.g. the interval for delay 0
103 // goes from -1 to 1, and the interval for delay 1 goes from 0 to 2 in the
104 // LCDF, respectively. For a maximum delay of D days, we therefore evaluate
105 // the LCDF up to the integer u = D+1. The total mass of this LCDF is thus:
106 // sum_{d=0}^D (F_{d+1} - F_{d-1}) = sum_{i=1}^u (F_{i} - F_{i-2}) = F_{u} + F_{u-1}
107 // If u were infinite this would be equivalent to dividing by 2.
108 if (u == 1) {
109 adjusted_lcdf = lcdf - lcdf[1];
110 }
111 if (u > 1) {
112 adjusted_lcdf = lcdf - log_sum_exp(lcdf[u], lcdf[u-1]);
113 }
114 } else {
115 reject("Unknown strategy to handle probability mass beyond the maximum value.");
116 }
117 return(adjusted_lcdf);
118}
119
139 vector[u] lpmf;
140 // p_0 = cdf_1 - cdf_0
141 lpmf[1] = lcdf[1];
142 if (u > 1) {
143 // p_1 = cdf_2 - cdf_0
144 lpmf[2] = lcdf[2];
145 if (u > 2) {
146 // p_u = cdf_u+1 - cdf_u-1
147 lpmf[3:u] = log_diff_exp(lcdf[3:u], lcdf[1:(u-2)]);
148 }
149 }
150 return(lpmf);
151}
152
195vector lprob_to_uniform_double_censored_log_hazard(vector lprob, vector lcdf,
196 int u) {
197 vector[u] lhaz;
198 // h_0 = F_1
199 lhaz[1] = lcdf[1];
200 // h_d = p_d / (1 - sum^{d-1}_{i=0} p_i)
201 // h_d = (F_d+1 - F_d-1) / (1 - sum^{d-1}_{i=0} F_i+1 - F_i-1)
202 // h_d = (F_d+1 - F_d-1) / (1 - (F_d + F_d-1))
203 // h_d = (F_d+1 - F_d-1) / ((1 - F_d) - F_d-1)
204 // log(h_d) = log(F_d+1 - F_d-1) - log((1 - F_d) - F_d-1)
205 if (u > 1) {
206 vector[u-2] lccdf;
207 // ccdf_i = 1 - cdf_i
208 lccdf = log1m_exp(lcdf[1:(u-2)]);
209 lhaz[2] = lprob[2] - lccdf[1];
210 if (u > 2) {
211 // Note that lprob[1] = log(p_0), lcdf[1] = log(F_1), lccdf[1] = log(1 - F_1)
212 // e.g. lhaz[3] = lprob[3] - log_diff_exp(lccdf[2], lcdf[1])
213 // means log(h_2) = log(p_2) - log(1 - F_2, F_1)
214 lhaz[3:(u-1)] = lprob[3:(u-1)] - log_diff_exp(lccdf[2:(u-2)], lcdf[1:(u-3)]);
215 }
216 }
217 return(lhaz);
218}
219
233vector log_hazard_to_logit_hazard(vector lhaz) {
234 int n = num_elements(lhaz);
235 vector[n] logit_haz;
236 // Logit transformation
237 logit_haz[1:(n-1)] = lhaz[1:(n-1)] - log1m_exp(lhaz[1:(n-1)]);
238 // Set last logit transformed hazard to Inf (i.e h[n] = 1)
239 logit_haz[n] = positive_infinity();
240 return(logit_haz);
241}
242
286vector discretised_logit_hazard(real mu, real sigma, int dmax, int dist,
287 int max_strat, int ref_as_p) {
288 vector[dmax] lcdf;
289 vector[dmax] lprob;
290 vector[dmax] logit_haz;
291 lcdf = lcdf_discretised(mu, sigma, dmax, dist);
292 lcdf = normalise_lcdf_as_uniform_double_censored(lcdf, dmax, max_strat);
294 if (ref_as_p == 1) {
295 // In the mode where there are no hazard effects downstream functions
296 // make use of the log probability directly so we return it here without
297 // converting to the logit hazard.
298 logit_haz = lprob;
299 }else{
300 vector[dmax] lhaz;
301 lhaz = lprob_to_uniform_double_censored_log_hazard(lprob, lcdf, dmax);
302 logit_haz = log_hazard_to_logit_hazard(lhaz);
303 }
304 return(logit_haz);
305}
vector lcdf_to_uniform_double_censored_log_prob(vector lcdf, int u)
real loglogistic_lcdf(real y, real alpha, real beta)
vector normalise_lcdf_as_uniform_double_censored(vector lcdf, int u, int max_strat)
vector lprob_to_uniform_double_censored_log_hazard(vector lprob, vector lcdf, int u)
Compute discretised logit hazard.
vector discretised_logit_hazard(real mu, real sigma, int dmax, int dist, int max_strat, int ref_as_p)
vector log_hazard_to_logit_hazard(vector lhaz)
vector lcdf_discretised(real mu, real sigma, int u, int dist)