-
Notifications
You must be signed in to change notification settings - Fork 3
/
mvpmm.stan
executable file
·67 lines (57 loc) · 1.67 KB
/
mvpmm.stan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Manuel A. Rivas, 6.6.2017
// Stanford University
// Rivas Lab
// Model to estimate covariance parameters
data {
int<lower=0> N; // number of loci
int<lower=1> M; // number of phenotypes
matrix[N, M] B; // observed effect sizes
matrix[N, M] SE; // standard errors
int<lower=1> K; // number of mixture components
}
transformed data{
vector[M] zeros;
vector[K] ones; // mass for dirichlet
vector[M] SE_vec[N];
zeros = rep_vector(0, M);
ones = rep_vector(1, K);
ones[1] = 1;
// fill in the matrix of standard errors
for (n in 1:N) {
SE_vec[n] = to_vector(SE[n]);
}
}
parameters {
simplex[K] pi; // mixing proportions
cholesky_factor_corr[M] L_Omega;
cholesky_factor_corr[M] L_Theta;
vector<lower=0>[M] tau;
}
transformed parameters{
matrix[M, M] Sigma;
matrix[M, M] Sigmas[K];
Sigma = diag_pre_multiply(tau, L_Omega);
Sigmas[1] = diag_matrix(rep_vector(0,M));
Sigmas[2] = Sigma;
}
model {
vector[K] ps; // contributions of each
tau ~ cauchy(0, 2.5);
L_Omega ~ lkj_corr_cholesky(2.0);
L_Theta ~ lkj_corr_cholesky(2.0);
pi ~ dirichlet(ones);
for (n in 1:N){
// two components
for (k in 1:K){
ps[k] = log(pi[k]) + multi_normal_cholesky_lpdf(B[n] | zeros, Sigmas[k] + diag_pre_multiply(SE_vec[n], L_Theta));
}
target += log_sum_exp(ps);
}
}
generated quantities {
matrix[M,M] Omegacor;
matrix[M,M] Thetacor;
// matrix[N,K] p;
Omegacor = multiply_lower_tri_self_transpose(L_Omega);
Thetacor = multiply_lower_tri_self_transpose(L_Theta);
}