Skip to content

Commit c0827ba

Browse files
committed
Stan code for multi-level sma model
1 parent b382243 commit c0827ba

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

inst/stan/bmsma.stan

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// A multi-level sma model fit
2+
data {
3+
int<lower=1> n_obs;
4+
int<lower=1> n_groups;
5+
int<lower=1> group[n_obs];
6+
vector[2] x[n_obs];
7+
}
8+
9+
parameters {
10+
// hyper parameters
11+
real mu_mu_x;
12+
real<lower=0> sigma_mu_x;
13+
real mu_b_0;
14+
real<lower=0> sigma_b_0;
15+
real mu_log_b_1;
16+
real<lower=0> sigma_log_b_1;
17+
real<lower=0> a_sigma_u1;
18+
real<lower=0> b_sigma_u1;
19+
real<lower=0> a_sigma_u2;
20+
real<lower=0> b_sigma_u2;
21+
22+
// group-level effects
23+
real mu_x1[n_groups];
24+
real b_0[n_groups];
25+
real<lower=0> b_1[n_groups];
26+
real<lower=0> sigma_u1[n_groups];
27+
real<lower=0> sigma_u2[n_groups];
28+
}
29+
30+
model {
31+
// Define variables used
32+
real u_c; // constant
33+
vector[2] uv[n_obs]; // (u1,u2) data in vector form
34+
35+
matrix[2,2] U[n_groups]; // Rotation matrices
36+
vector[2] mu_x[n_groups]; // vector means for x
37+
vector[2] sigma_u[n_groups]; // covariance matrices for u
38+
39+
// Sample group parameters from distributions
40+
mu_x1 ~ normal(mu_mu_x, sigma_mu_x);
41+
b_0 ~ normal(mu_b_0, sigma_b_0);
42+
b_1 ~ lognormal(mu_log_b_1, sigma_log_b_1);
43+
sigma_u1 ~ normal(a_sigma_u1, b_sigma_u1);
44+
sigma_u2 ~ normal(a_sigma_u2, b_sigma_u2);
45+
// NB: sigmas should be sampled from gamma (or inverse gamma),
46+
// but that doesn't converge. Gelman says gamma performs badly
47+
// when variance is close to zero
48+
49+
// Now calculate vectors and matrices from proposed parameters, indexed by group
50+
for (i in 1:n_groups) {
51+
mu_x[i, 1] = mu_x1[i];
52+
mu_x[i, 2] = b_0[i] + b_1[i] * mu_x1[i];
53+
54+
// Rotation matrix, U
55+
u_c = 1 / sqrt(2) / b_1[i];
56+
U[i,1,1] = b_1[i]^2 * u_c;
57+
U[i,1,2] = b_1[i] * u_c;
58+
U[i,2,1] = -b_1[i] * u_c;
59+
U[i,2,2] = 1 * u_c;
60+
61+
// Covariance matrix of U
62+
sigma_u[i,1] = sigma_u1[i];
63+
sigma_u[i,2] = sigma_u2[i];
64+
}
65+
66+
for (j in 1:n_obs) {
67+
// Calculate u by centering then rotating x
68+
uv[j] = U[group[j]] * (log(x[j]) - mu_x[group[j]]);
69+
70+
// Likelihood of data
71+
// consider re-parameterising as described on pg 218
72+
uv[j] ~ multi_normal(rep_vector(0,2), diag_matrix(sigma_u[group[j]]));
73+
}
74+
}

0 commit comments

Comments
 (0)