3 if (x < xmin || x > xmax) {
4 return negative_infinity();
7 return -log(xmax - xmin);
9 return log(abs(r)) + r * x -
10 log(abs(exp(r * xmax) - exp(r * xmin)));
13 if (dist_id == 2 && primary_id == 1)
return 1;
14 if (dist_id == 1 && primary_id == 1)
return 1;
15 if (dist_id == 3 && primary_id == 1)
return 1;
19 real shape = params[1];
20 real rate = params[2];
21 real log_window = log(pwindow);
23 real log_E = log(shape) - log(rate);
27 real log_F_T_d_k = gamma_lcdf(d | shape, rate);
28 real gamma_kp1_pdf_log_d
29 = shape * log(rate * d) - rate * d - lgamma(shape + 1);
30 real log_F_T_d_kp1 = log_diff_exp(log_F_T_d_k, gamma_kp1_pdf_log_d);
38 real log_F_T_q_k = gamma_lcdf(q | shape, rate);
39 real gamma_kp1_pdf_log_q
40 = shape * log(rate * q) - rate * q - lgamma(shape + 1);
41 real log_F_T_q_kp1 = log_diff_exp(log_F_T_q_k, gamma_kp1_pdf_log_q);
42 log_q_F_T_q = log(q) + log_F_T_q_k;
43 log_E_tF_T_q = log_E + log_F_T_q_kp1;
45 log_q_F_T_q = negative_infinity();
46 log_E_tF_T_q = negative_infinity();
53 real log_A = log_sum_exp(log(d) + log_F_T_d_k, log_E_tF_T_q);
54 real log_B = log_sum_exp(log_q_F_T_q, log_E + log_F_T_d_kp1);
56 return log_diff_exp(log_A, log_B) - log_window;
60 real sigma = params[2];
61 real mu_sigma2 = mu + square(sigma);
62 real log_window = log(pwindow);
64 real log_E = mu + 0.5 * square(sigma);
66 real log_F_T_d = lognormal_lcdf(d | mu, sigma);
67 real log_tF_T_d = lognormal_lcdf(d | mu_sigma2, sigma);
73 real log_F_T_q = lognormal_lcdf(q | mu, sigma);
74 real log_tF_T_q = lognormal_lcdf(q | mu_sigma2, sigma);
75 log_q_F_T_q = log(q) + log_F_T_q;
76 log_E_tF_T_q = log_E + log_tF_T_q;
78 log_q_F_T_q = negative_infinity();
79 log_E_tF_T_q = negative_infinity();
86 real log_A = log_sum_exp(log(d) + log_F_T_d, log_E_tF_T_q);
87 real log_B = log_sum_exp(log_q_F_T_q, log_E + log_tF_T_d);
89 return log_diff_exp(log_A, log_B) - log_window;
92 real x = pow(t * inv(scale), shape);
93 real a = 1 + inv(shape);
94 return log(gamma_p(a, x)) + lgamma(a);
97 real shape = params[1];
98 real scale = params[2];
99 real log_window = log(pwindow);
100 real log_scale = log(scale);
104 real log_F_T_d = weibull_lcdf(d | shape, scale);
105 real log_E_tF_T_d = log_scale +
log_weibull_g(d, shape, scale);
111 log_q_F_T_q = log(q) + weibull_lcdf(q | shape, scale);
114 log_q_F_T_q = negative_infinity();
115 log_E_tF_T_q = negative_infinity();
122 real log_A = log_sum_exp(log(d) + log_F_T_d, log_E_tF_T_q);
123 real log_B = log_sum_exp(log_q_F_T_q, log_E_tF_T_d);
125 return log_diff_exp(log_A, log_B) - log_window;
131 real q = max({d - pwindow, 0});
133 if (dist_id == 2 && primary_id == 1) {
135 }
else if (dist_id == 1 && primary_id == 1) {
137 }
else if (dist_id == 3 && primary_id == 1) {
140 return negative_infinity();
144 data real pwindow, data real L,
145 data real D,
int primary_id,
146 array[] real primary_params) {
147 if (d <= L)
return negative_infinity();
148 if (d >= D)
return 0;
151 d, dist_id, params, pwindow, primary_id
155 if (!is_inf(D) || L > 0) {
157 L, D, dist_id, params, pwindow, primary_id, primary_params
159 real log_cdf_L = bounds[1];
160 real log_cdf_D = bounds[2];
170 data real pwindow, data real L,
171 data real D,
int primary_id,
172 array[] real primary_params) {
176 if (dist_id == 1)
return 1;
177 if (dist_id == 2)
return 1;
178 if (dist_id == 3)
return 1;
179 if (dist_id == 4)
return 1;
180 if (dist_id == 9)
return 1;
181 if (dist_id == 13)
return 1;
182 if (dist_id == 16)
return 1;
183 if (dist_id == 19)
return 1;
184 if (dist_id == 21)
return 1;
185 if (dist_id == 22)
return 1;
188real
dist_lcdf(real delay, array[] real params,
int dist_id) {
190 return negative_infinity();
194 if (dist_id == 1)
return lognormal_lcdf(delay | params[1], params[2]);
195 else if (dist_id == 2)
return gamma_lcdf(delay | params[1], params[2]);
196 else if (dist_id == 3)
return weibull_lcdf(delay | params[1], params[2]);
197 else if (dist_id == 4)
return exponential_lcdf(delay | params[1]);
198 else if (dist_id == 9)
return beta_lcdf(delay | params[1], params[2]);
199 else if (dist_id == 12)
return cauchy_lcdf(delay | params[1], params[2]);
200 else if (dist_id == 13)
return chi_square_lcdf(delay | params[1]);
201 else if (dist_id == 15)
return gumbel_lcdf(delay | params[1], params[2]);
202 else if (dist_id == 16)
return inv_gamma_lcdf(delay | params[1], params[2]);
203 else if (dist_id == 17)
return logistic_lcdf(delay | params[1], params[2]);
204 else if (dist_id == 18)
return normal_lcdf(delay | params[1], params[2]);
205 else if (dist_id == 19)
return inv_chi_square_lcdf(delay | params[1]);
206 else if (dist_id == 20)
return double_exponential_lcdf(delay | params[1], params[2]);
207 else if (dist_id == 21)
return pareto_lcdf(delay | params[1], params[2]);
208 else if (dist_id == 22)
return scaled_inv_chi_square_lcdf(delay | params[1], params[2]);
209 else if (dist_id == 23)
return student_t_lcdf(delay | params[1], params[2], params[3]);
210 else if (dist_id == 24)
return uniform_lcdf(delay | params[1], params[2]);
211 else if (dist_id == 25)
return von_mises_lcdf(delay | params[1], params[2]);
212 else reject(
"Invalid distribution identifier: ", dist_id);
214real
primary_lpdf(real x,
int primary_id, array[] real params, real xmin, real xmax) {
216 if (primary_id == 1)
return uniform_lpdf(x | xmin, xmax);
217 if (primary_id == 2)
return expgrowth_lpdf(x | xmin, xmax, params[1]);
219 reject(
"Invalid primary distribution identifier");
222 array[] real x_r, array[]
int x_i) {
224 int dist_id = x_i[1];
225 int primary_id = x_i[2];
226 real pwindow = x_r[2];
227 int dist_params_len = x_i[3];
228 int primary_params_len = x_i[4];
231 array[dist_params_len] real params;
232 if (dist_params_len) {
233 params = theta[1:dist_params_len];
235 array[primary_params_len] real primary_params;
236 if (primary_params_len) {
237 int primary_loc = num_elements(theta);
238 primary_params = theta[primary_loc - primary_params_len + 1:primary_loc];
241 real log_cdf =
dist_lcdf(t | params, dist_id);
242 real log_primary_pdf =
primary_lpdf(d - t | primary_id, primary_params, 0, pwindow);
244 return rep_vector(exp(log_cdf + log_primary_pdf), 1);
248 return log_diff_exp(log_cdf_D, log_cdf_L);
254 real log_normalizer, real L) {
256 return log_diff_exp(log_cdf, log_cdf_L) - log_normalizer;
258 return log_cdf - log_normalizer;
262 data real L, data real D,
263 data
int dist_id, array[] real params, data real pwindow,
264 data
int primary_id, array[] real primary_params
276 result[1] = negative_infinity();
279 L | dist_id, params, pwindow,
281 positive_infinity(), primary_id, primary_params
290 D | dist_id, params, pwindow,
292 positive_infinity(), primary_id, primary_params
299 data real pwindow, data real L, data real D,
301 array[] real primary_params) {
315 d | dist_id, params, pwindow, L, D, primary_id, primary_params
324 real lower_bound = d - pwindow;
325 int n_params = num_elements(params);
326 int n_primary_params = num_elements(primary_params);
327 array[n_params + n_primary_params] real theta = append_array(params, primary_params);
328 array[4]
int ids = {dist_id, primary_id, n_params, n_primary_params};
330 vector[1] y0 = rep_vector(0.0, 1);
331 result = ode_rk45(
primarycensored_ode, y0, lower_bound, {d}, theta, {d, pwindow}, ids)[1, 1];
335 if (!is_inf(D) || L > 0 ||
337 real log_result = log(result);
339 L, D, dist_id, params, pwindow, primary_id, primary_params
341 real log_cdf_L = bounds[1];
342 real log_cdf_D = bounds[2];
346 log_result, log_cdf_L, log_normalizer, L
348 result = exp(log_result);
355 data real pwindow, data real L, data real D,
357 array[] real primary_params) {
361 return negative_infinity();
373 d | dist_id, params, pwindow,
375 positive_infinity(), primary_id, primary_params
380 d | dist_id, params, pwindow,
382 positive_infinity(), primary_id, primary_params
388 if (!is_inf(D) || L > 0 ||
391 L, D, dist_id, params, pwindow, primary_id, primary_params
393 real log_cdf_L = bounds[1];
394 real log_cdf_D = bounds[2];
403 data real pwindow, data real d_upper,
404 data real L, data real D, data
int primary_id,
405 array[] real primary_params) {
407 reject(
"Upper truncation point is greater than D. It is ", d_upper,
408 " and D is ", D,
". Resolve this by increasing D to be greater or equal to d + swindow or decreasing swindow.");
411 reject(
"Upper truncation point is less than or equal to d. It is ", d_upper,
412 " and d is ", d,
". Resolve this by increasing d to be less than d_upper.");
415 return negative_infinity();
418 d_upper | dist_id, params, pwindow,
420 positive_infinity(), primary_id, primary_params
423 d | dist_id, params, pwindow,
425 positive_infinity(), primary_id, primary_params
430 if (!is_inf(D) || L > 0 ||
438 log_cdf_L = negative_infinity();
441 log_cdf_L = log_cdf_lower;
445 L | dist_id, params, pwindow,
447 positive_infinity(), primary_id, primary_params
453 log_cdf_D = log_cdf_upper;
454 }
else if (is_inf(D)) {
458 D | dist_id, params, pwindow,
460 positive_infinity(), primary_id, primary_params
465 return log_diff_exp(log_cdf_upper, log_cdf_lower) - log_normalizer;
467 return log_diff_exp(log_cdf_upper, log_cdf_lower);
471 data
int max_delay, data real L, data real D, data
int dist_id,
472 array[] real params, data real pwindow,
473 data
int primary_id, array[] real primary_params
476 int upper_interval = max_delay + 1;
477 vector[upper_interval] log_pmfs;
478 vector[upper_interval] log_cdfs;
482 if (D < upper_interval) {
483 reject(
"D must be at least max_delay + 1");
492 int start_idx = (!is_inf(L) && L > 0) ? max(1, to_int(floor(L))) : 1;
493 for (d in start_idx:upper_interval) {
495 d | dist_id, params, pwindow,
497 positive_infinity(), primary_id, primary_params
505 log_cdf_L = negative_infinity();
506 }
else if (L >= 1 && L <= upper_interval && floor(L) == L) {
508 log_cdf_L = log_cdfs[to_int(L)];
512 L | dist_id, params, pwindow,
514 positive_infinity(), primary_id, primary_params
520 if (D > upper_interval) {
525 D | dist_id, params, pwindow,
527 positive_infinity(), primary_id, primary_params
531 log_cdf_D = log_cdfs[upper_interval];
537 for (d in 1:upper_interval) {
540 log_pmfs[d] = negative_infinity();
541 }
else if (d - 1 < L) {
543 log_pmfs[d] = log_diff_exp(log_cdfs[d], log_cdf_L) - log_normalizer;
547 log_pmfs[d] = log_cdfs[d] - log_normalizer;
552 0.0 | dist_id, params, pwindow,
553 negative_infinity(), positive_infinity(),
554 primary_id, primary_params
556 log_pmfs[d] = log_diff_exp(log_cdfs[d], log_cdf_0) - log_normalizer;
559 log_pmfs[d] = log_diff_exp(log_cdfs[d], log_cdfs[d-1]) - log_normalizer;
566 data
int max_delay, data real L, data real D, data
int dist_id,
567 array[] real params, data real pwindow,
569 array[] real primary_params
573 max_delay, L, D, dist_id, params, pwindow, primary_id, primary_params
real dist_lcdf(real delay, array[] real params, int dist_id)
vector primarycensored_sone_lpmf_vectorized(data int max_delay, data real L, data real D, data int dist_id, array[] real params, data real pwindow, data int primary_id, array[] real primary_params)
real primarycensored_apply_truncation(real log_cdf, real log_cdf_L, real log_normalizer, real L)
real primarycensored_cdf(data real d, data int dist_id, array[] real params, data real pwindow, data real L, data real D, data int primary_id, array[] real primary_params)
real primarycensored_log_normalizer(real log_cdf_D, real log_cdf_L, real L)
real log_weibull_g(real t, real shape, real scale)
vector primarycensored_ode(real t, vector y, array[] real theta, array[] real x_r, array[] int x_i)
real primarycensored_analytical_lcdf_raw(data real d, int dist_id, array[] real params, data real pwindow, int primary_id)
real primarycensored_weibull_uniform_lcdf(data real d, real q, array[] real params, data real pwindow)
real expgrowth_lpdf(real x, real xmin, real xmax, real r)
vector primarycensored_sone_pmf_vectorized(data int max_delay, data real L, data real D, data int dist_id, array[] real params, data real pwindow, data int primary_id, array[] real primary_params)
real primarycensored_lpmf(data int d, data int dist_id, array[] real params, data real pwindow, data real d_upper, data real L, data real D, data int primary_id, array[] real primary_params)
real primarycensored_lcdf(data real d, data int dist_id, array[] real params, data real pwindow, data real L, data real D, data 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)
int dist_has_positive_support(data int dist_id)
real primarycensored_gamma_uniform_lcdf(data real d, real q, array[] real params, data real pwindow)
real primary_lpdf(real x, int primary_id, array[] real params, real xmin, real xmax)
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)
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)
int check_for_analytical(int dist_id, int primary_id)