// generated with brms 2.17.4 functions { /* Efficient computation of the horseshoe prior * see Appendix C.1 in https://projecteuclid.org/euclid.ejs/1513306866 * Args: * z: standardized population-level coefficients * lambda: local shrinkage parameters * tau: global shrinkage parameter * c2: slap regularization parameter * Returns: * population-level coefficients following the horseshoe prior */ vector horseshoe(vector z, vector lambda, real tau, real c2) { int K = rows(z); vector[K] lambda2 = square(lambda); vector[K] lambda_tilde = sqrt(c2 * lambda2 ./ (c2 + tau^2 * lambda2)); return z .* lambda_tilde * tau; } /* integer sequence of values * Args: * start: starting integer * end: ending integer * Returns: * an integer sequence from start to end */ int[] sequence(int start, int end) { int seq[end - start + 1]; for (n in 1:num_elements(seq)) { seq[n] = n + start - 1; } return seq; } // compute partial sums of the log-likelihood real partial_log_lik_lpmf(int[] seq, int start, int end, data vector Y, data matrix Xc, vector b, real Intercept, real sigma, data int[] J_1, data vector Z_1_1, vector r_1_1) { real ptarget = 0; int N = end - start + 1; // initialize linear predictor term //vector[N] mu; = Intercept; // + rep_vector(0.0, N); vector[N] mu = rep_vector(Intercept, N); /* for (n in 1:N) { // add more terms to the linear predictor int nn = n + start - 1; mu[n] += r_1_1[J_1[nn]] * Z_1_1[nn]; } */ mu += r_1_1[J_1[start:end]] .* Z_1_1[start:end]; ptarget += normal_id_glm_lpdf(Y[start:end] | Xc[start:end], mu, b, sigma); return ptarget; } } data { int N; // total number of observations vector[N] Y; // response variable int K; // number of population-level effects matrix[N, K] X; // population-level design matrix // data for the horseshoe prior real hs_df; // local degrees of freedom real hs_df_global; // global degrees of freedom real hs_df_slab; // slab degrees of freedom real hs_scale_global; // global prior scale real hs_scale_slab; // slab prior scale int grainsize; // grainsize for threading // data for group-level effects of ID 1 int N_1; // number of grouping levels int M_1; // number of coefficients per level int J_1[N]; // grouping indicator per observation // group-level predictor values vector[N] Z_1_1; int prior_only; // should the likelihood be ignored? } transformed data { int Kc = K - 1; matrix[N, Kc] Xc; // centered version of X without an intercept vector[Kc] means_X; // column means of X before centering int seq[N] = sequence(1, N); for (i in 2:K) { means_X[i - 1] = mean(X[, i]); Xc[, i - 1] = X[, i] - means_X[i - 1]; } } parameters { // local parameters for the horseshoe prior vector[Kc] zb; vector[Kc] hs_local; real Intercept; // temporary intercept for centered predictors // horseshoe shrinkage parameters real hs_global; // global shrinkage parameter real hs_slab; // slab regularization parameter real sigma; // dispersion parameter vector[N_1] z_1[M_1]; // standardized group-level effects } transformed parameters { vector[Kc] b; // population-level effects vector[M_1] sd_1; // group-level standard deviations vector[N_1] r_1_1; // actual group-level effects real lprior = 0; // prior contributions to the log posterior sd_1 = rep_vector(1, rows(sd_1)); // compute the actual regression coefficients b = horseshoe(zb, hs_local, hs_global, hs_scale_slab^2 * hs_slab); r_1_1 = (sd_1[1] * (z_1[1])); lprior += normal_lpdf(Intercept | 0, 1); lprior += student_t_lpdf(hs_global | hs_df_global, 0, hs_scale_global) - 1 * log(0.5); lprior += inv_gamma_lpdf(hs_slab | 0.5 * hs_df_slab, 0.5 * hs_df_slab); lprior += student_t_lpdf(sigma | 3, 0, 3.6) - 1 * student_t_lccdf(0 | 3, 0, 3.6); } model { // likelihood including constants if (!prior_only) { // reduce_sum is blocking SoA, but it should not since the slice // argument is data in this case //target += reduce_sum(partial_log_lik_lpmf, seq, grainsize, Y, Xc, b, Intercept, sigma, J_1, Z_1_1, r_1_1); // this call instead gives me a full SoA program target += partial_log_lik_lpmf(seq| 1, N, Y, Xc, b, Intercept, sigma, J_1, Z_1_1, r_1_1); } // priors including constants target += lprior; target += std_normal_lpdf(zb); target += student_t_lpdf(hs_local | hs_df, 0, 1) - rows(hs_local) * log(0.5); target += std_normal_lpdf(z_1[1]); } generated quantities { // actual population-level intercept real b_Intercept = Intercept - dot_product(means_X, b); }