EpiNow2 Stan Functions
params.stan
Go to the documentation of this file.
1/**
2 * Parameter Handlers
3 *
4 * This group of functions handles parameter access, retrieval, and prior
5 * specification in the model. Parameters can be either fixed (specified in advance)
6 * or variable (estimated during inference).
7 */
8
9/**
10 * Get a parameter value from either fixed or variable parameters
11 *
12 * This function retrieves a parameter value based on its ID, checking first if it's
13 * a fixed parameter and then if it's a variable parameter.
14 *
15 * @param id Parameter ID
16 * @param params_fixed_lookup Array of fixed parameter lookup indices
17 * @param params_variable_lookup Array of variable parameter lookup indices
18 * @param params_value Vector of fixed parameter values
19 * @param params Vector of variable parameter values
20 * @return The parameter value (scalar)
21 *
22 * @ingroup parameter_handlers
23 */
24real get_param(int id,
25 array[] int params_fixed_lookup,
26 array[] int params_variable_lookup,
27 vector params_value, vector params) {
28 if (id == 0) {
29 return 0; // parameter not used
30 } else if (params_fixed_lookup[id]) {
31 return params_value[params_fixed_lookup[id]];
32 } else {
33 return params[params_variable_lookup[id]];
34 }
35}
36
37/**
38 * Get a parameter value from either fixed or variable parameters (matrix version)
39 *
40 * This function is an overloaded version of get_param that works with a matrix of
41 * parameter values, returning a vector of parameter values for multiple samples.
42 *
43 * @param id Parameter ID
44 * @param params_fixed_lookup Array of fixed parameter lookup indices
45 * @param params_variable_lookup Array of variable parameter lookup indices
46 * @param params_value Vector of fixed parameter values
47 * @param params Matrix of variable parameter values (rows are samples)
48 * @return A vector of parameter values across samples
49 *
50 * @ingroup parameter_handlers
51 */
52vector get_param(int id,
53 array[] int params_fixed_lookup,
54 array[] int params_variable_lookup,
55 vector params_value, matrix params) {
56 int n_samples = rows(params);
57 if (id == 0) {
58 return rep_vector(0, n_samples) ; // parameter not used
59 } else if (params_fixed_lookup[id]) {
60 return rep_vector(params_value[params_fixed_lookup[id]], n_samples);
61 } else {
62 return params[, params_variable_lookup[id]];
63 }
64}
65
66/**
67 * Apply a truncated prior to a value
68 *
69 * Adds the log density of the chosen distribution, truncated to `[lb, ub]`,
70 * to the target.
71 *
72 * @param value Value to apply the prior to (sampled parameter or derived
73 * quantity).
74 * @param dist Prior distribution type (0: lognormal, 1: gamma, 2: normal).
75 * @param p1 First distribution parameter.
76 * @param p2 Second distribution parameter.
77 * @param lb Lower bound of the parameter's support.
78 * @param ub Upper bound of the parameter's support.
79 *
80 * @ingroup parameter_handlers
81 */
82void apply_prior_lp(real value, int dist,
83 real p1, real p2,
84 real lb, real ub) {
85 if (dist == 0) {
86 value ~ lognormal(p1, p2) T[lb, ub];
87 } else if (dist == 1) {
88 value ~ gamma(p1, p2) T[lb, ub];
89 } else if (dist == 2) {
90 value ~ normal(p1, p2) T[lb, ub];
91 } else {
92 reject("dist must be <= 2");
93 }
94}
95
96/**
97 * Update log density for parameter priors
98 *
99 * Adds the log density contributions from parameter priors to the target.
100 *
101 * @param params Vector of parameter values
102 * @param prior_dist Array of prior distribution types (0: lognormal, 1: gamma, 2: normal)
103 * @param prior_dist_params Vector of prior distribution parameters
104 * @param params_lower Vector of lower bounds for parameters
105 * @param params_upper Vector of upper bounds for parameters
106 *
107 * @ingroup parameter_handlers
108 */
109void params_lp(vector params, array[] int prior_dist,
110 vector prior_dist_params, vector params_lower,
111 vector params_upper) {
112 int params_id = 1;
113 int num_params = num_elements(params);
114 for (id in 1:num_params) {
116 params[id], prior_dist[id],
117 prior_dist_params[params_id], prior_dist_params[params_id + 1],
118 params_lower[id], params_upper[id]
119 );
120 params_id += 2;
121 }
122}
123
124/**
125 * Apply user priors on the initial values of centred-GP-wrapped trajectories
126 *
127 * For each registered init prior, dispatches on the parameter id to the
128 * corresponding derived initial value and to the parameter actually sampled,
129 * then applies the user's truncated prior via `apply_prior_lp`.
130 *
131 * The prior is declared on a derived value (e.g. `R[1]`) while the sampler
132 * moves on a different parameter (e.g. `R_mean`), whose `<lower = 0>`
133 * transform already contributes `log(sampled_value)` to the target. The
134 * Jacobian of the sampled-to-derived map is therefore taken relative to the
135 * sampled value, `log(init_value) - log(sampled_value)`.
136 *
137 * @param init_param_ids Per-prior id of the parameter the prior applies to.
138 * @param init_dists Per-prior distribution code (0: lognormal, 1: gamma,
139 * 2: normal).
140 * @param init_dist_params Flat ragged vector of distribution parameters,
141 * two per prior.
142 * @param init_lower Per-prior lower bound on the parameter's support.
143 * @param init_upper Per-prior upper bound on the parameter's support.
144 * @param param_id_R0 Registered id of R0.
145 * @param R Reproduction-number trajectory.
146 * @param R_mean Sampled mean reproduction number over the centring window.
147 *
148 * @ingroup parameter_handlers
149 */
150void init_priors_lp(array[] int init_param_ids, array[] int init_dists,
151 vector init_dist_params,
152 vector init_lower, vector init_upper,
153 int param_id_R0, vector R, array[] real R_mean) {
154 int params_id = 1;
155 for (i in 1:num_elements(init_param_ids)) {
156 real init_value;
157 real sampled_value;
158 if (init_param_ids[i] == param_id_R0) {
159 init_value = R[1];
160 sampled_value = R_mean[1];
161 } else {
162 reject("no init param registered for id ", init_param_ids[i]);
163 }
165 init_value, init_dists[i],
166 init_dist_params[params_id], init_dist_params[params_id + 1],
167 init_lower[i], init_upper[i]
168 );
169 target += log(init_value) - log(sampled_value);
170 params_id += 2;
171 }
172}
173
174
void params_lp(vector params, array[] int prior_dist, vector prior_dist_params, vector params_lower, vector params_upper)
Definition params.stan:109
void init_priors_lp(array[] int init_param_ids, array[] int init_dists, vector init_dist_params, vector init_lower, vector init_upper, int param_id_R0, vector R, array[] real R_mean)
Definition params.stan:150
real get_param(int id, array[] int params_fixed_lookup, array[] int params_variable_lookup, vector params_value, vector params)
Definition params.stan:24
void apply_prior_lp(real value, int dist, real p1, real p2, real lb, real ub)
Definition params.stan:82