primarycensored
Loading...
Searching...
No Matches
primarycensored_ode.stan
Go to the documentation of this file.
1
17real gengamma_lcdf(real y, real shape, real scale, real k) {
18 return gamma_lcdf(pow(y / scale, shape) | k, 1);
19}
20
33int dist_has_positive_support(data int dist_id) {
34 if (dist_id == 1) return 1; // Lognormal
35 if (dist_id == 2) return 1; // Gamma
36 if (dist_id == 3) return 1; // Weibull
37 if (dist_id == 4) return 1; // Exponential
38 if (dist_id == 5) return 1; // Generalised gamma
39 if (dist_id == 9) return 1; // Beta (support on [0, 1])
40 if (dist_id == 13) return 1; // Chi-square
41 if (dist_id == 16) return 1; // Inverse Gamma
42 if (dist_id == 19) return 1; // Inverse Chi-square
43 if (dist_id == 21) return 1; // Pareto
44 if (dist_id == 22) return 1; // Scaled inverse Chi-square
45 return 0;
46}
47
69int lognormal_lcdf_underflows(real y, real mu, real sigma) {
70 if (y <= 0) {
71 return 1;
72 }
73 return (log(y) - mu) / sigma < -38 ? 1 : 0;
74}
75
107real dist_lcdf(real delay, array[] real params, int dist_id) {
108 if (dist_has_positive_support(dist_id) && delay <= 0) {
109 return negative_infinity();
110 }
111
112 // IDs match pcd_distributions$stan_id in R
113 // Guarded so a lower-tail underflow cannot put a NaN partial on the tape.
114 // The downstream `exp(-inf)` differentiates to 0.
115 if (dist_id == 1) {
116 return lognormal_lcdf_underflows(delay, params[1], params[2])
117 ? negative_infinity()
118 : lognormal_lcdf(delay | params[1], params[2]);
119 }
120 else if (dist_id == 2) return gamma_lcdf(delay | params[1], params[2]);
121 else if (dist_id == 3) return weibull_lcdf(delay | params[1], params[2]);
122 else if (dist_id == 4) return exponential_lcdf(delay | params[1]);
123 else if (dist_id == 5) return gengamma_lcdf(delay | params[1], params[2], params[3]);
124 else if (dist_id == 9) return beta_lcdf(delay | params[1], params[2]);
125 else if (dist_id == 12) return cauchy_lcdf(delay | params[1], params[2]);
126 else if (dist_id == 13) return chi_square_lcdf(delay | params[1]);
127 else if (dist_id == 15) return gumbel_lcdf(delay | params[1], params[2]);
128 else if (dist_id == 16) return inv_gamma_lcdf(delay | params[1], params[2]);
129 else if (dist_id == 17) return logistic_lcdf(delay | params[1], params[2]);
130 else if (dist_id == 18) return normal_lcdf(delay | params[1], params[2]);
131 else if (dist_id == 19) return inv_chi_square_lcdf(delay | params[1]);
132 else if (dist_id == 20) return double_exponential_lcdf(delay | params[1], params[2]);
133 else if (dist_id == 21) return pareto_lcdf(delay | params[1], params[2]);
134 else if (dist_id == 22) return scaled_inv_chi_square_lcdf(delay | params[1], params[2]);
135 else if (dist_id == 23) return student_t_lcdf(delay | params[1], params[2], params[3]);
136 else if (dist_id == 24) return uniform_lcdf(delay | params[1], params[2]);
137 else if (dist_id == 25) return von_mises_lcdf(delay | params[1], params[2]);
138 else if (dist_id == 26) {
139 // Non-parametric step: params = [boundaries (K+1), pmf (K)].
140 int K = (size(params) - 1) %/% 2;
141 return pstep_lcdf(
142 delay | to_vector(segment(params, 1, K + 1)),
143 to_vector(segment(params, K + 2, K))
144 );
145 }
146 else if (dist_id == 27 || dist_id == 28) {
147 // Non-parametric discrete hazard: params = [boundaries (K+1),
148 // hazards (K)] with hazards[K] = 1. RW (27) and RE (28) share the
149 // same likelihood; they only differ in the prior.
150 int K = (size(params) - 1) %/% 2;
151 return phazard_lcdf(
152 delay | to_vector(segment(params, 1, K + 1)),
153 to_vector(segment(params, K + 2, K))
154 );
155 }
156 else reject("Invalid distribution identifier: ", dist_id);
157}
158
176real primary_lcdf(real p, int primary_id, array[] real primary_params,
177 data real pwindow) {
178 if (primary_id == 1) {
179 // Uniform on [0, pwindow]: built-in uniform_lcdf matches the package
180 // primary semantics over [0, pwindow].
181 if (p <= 0) return negative_infinity();
182 if (p >= pwindow) return 0;
183 return uniform_lcdf(p | 0, pwindow);
184 } else if (primary_id == 2) {
185 return expgrowth_lcdf(p | 0, pwindow, primary_params[1]);
186 }
187 reject("primary_lcdf: unsupported primary_id ", primary_id);
188}
189
212real primary_lpdf(real x, int primary_id, array[] real params, real xmin, real xmax) {
213 // Implement switch for different primary distributions
214 if (primary_id == 1) return uniform_lpdf(x | xmin, xmax);
215 if (primary_id == 2) return expgrowth_lpdf(x | xmin, xmax, params[1]);
216 // Add more primary distributions as needed
217 reject("Invalid primary distribution identifier");
218}
219
232vector primarycensored_ode(real t, vector y, array[] real theta,
233 array[] real x_r, array[] int x_i) {
234 real d = x_r[1];
235 int dist_id = x_i[1];
236 int primary_id = x_i[2];
237 real pwindow = x_r[2];
238 int dist_params_len = x_i[3];
239 int primary_params_len = x_i[4];
240
241 // Extract distribution parameters
242 array[dist_params_len] real params;
243 if (dist_params_len) {
244 params = theta[1:dist_params_len];
245 }
246 array[primary_params_len] real primary_params;
247 if (primary_params_len) {
248 int primary_loc = num_elements(theta);
249 primary_params = theta[primary_loc - primary_params_len + 1:primary_loc];
250 }
251
252 real log_cdf = dist_lcdf(t | params, dist_id);
253 real log_primary_pdf = primary_lpdf(d - t | primary_id, primary_params, 0, pwindow);
254
255 return rep_vector(exp(log_cdf + log_primary_pdf), 1);
256}
real dist_lcdf(real delay, array[] real params, int dist_id)
int lognormal_lcdf_underflows(real y, real mu, real sigma)
int dist_has_positive_support(data int dist_id)
real gengamma_lcdf(real y, real shape, real scale, real k)
real expgrowth_lcdf(real x, real xmin, real xmax, real r)
real expgrowth_lpdf(real x, real xmin, real xmax, real r)
vector primarycensored_ode(real t, vector y, array[] real theta, array[] real x_r, array[] int x_i)
real primary_lpdf(real x, int primary_id, array[] real params, real xmin, real xmax)
real phazard_lcdf(real t, vector boundaries, vector hazards)
real pstep_lcdf(real t, vector boundaries, vector pmf)
real primary_lcdf(real p, int primary_id, array[] real primary_params, data real pwindow)