-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmodel_pystan3.stan
65 lines (64 loc) · 1.61 KB
/
model_pystan3.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
data {
// Dimensions of the data matrix, and matrix itself.
int<lower=1> n_p;
int<lower=1> n_a;
array[n_p, n_a] int<lower=0> M;
}
transformed data {
// Pre-compute the marginals of M to save computation in the model loop.
array[n_p] int M_rows = rep_array(0, n_p);
array[n_a] int M_cols = rep_array(0, n_a);
int M_tot = 0;
for (i in 1:n_p) {
for (j in 1:n_a) {
M_rows[i] += M[i, j];
M_cols[j] += M[i, j];
M_tot += M[i, j];
}
}
}
parameters {
real<lower=0> C;
real<lower=0> r;
simplex[n_p] sigma;
simplex[n_a] tau;
real<lower=0, upper=1> rho;
}
model {
// Prior
r ~ exponential(0.01);
// Global sums and parameters
target += M_tot * log(C) - C;
// Weighted marginals of the data matrix
for (i in 1:n_p) {
target += M_rows[i] * log(sigma[i]);
}
for (j in 1:n_a) {
target += M_cols[j] * log(tau[j]);
}
// Pairwise loop
for (i in 1:n_p) {
for (j in 1:n_a) {
real nu_ij_0 = log(1 - rho);
real nu_ij_1 = log(rho) + M[i,j] * log(1 + r) - C * r * sigma[i] * tau[j];
if (nu_ij_0 > nu_ij_1)
target += nu_ij_0 + log1p_exp(nu_ij_1 - nu_ij_0);
else
target += nu_ij_1 + log1p_exp(nu_ij_0 - nu_ij_1);
}
}
}
generated quantities {
// Posterior edge probability matrix
array[n_p, n_a] real<lower=0> Q;
for (i in 1:n_p) {
for (j in 1:n_a) {
real nu_ij_0 = log(1 - rho);
real nu_ij_1 = log(rho) + M[i,j] * log(1 + r) - C * r * sigma[i] * tau[j];
if (nu_ij_1 > 0)
Q[i, j] = 1 / (1+ exp(nu_ij_0 - nu_ij_1));
else
Q[i, j] = exp(nu_ij_1) / (exp(nu_ij_0) + exp(nu_ij_1));
}
}
}