Hi all,
I’m trying to reimplement Lopes and Carvalho 2007. I’ve cross-referenced Rick Farouni’s very helpful post and ldeschamps’s thread on the forum, and have arrived at a simplified working implementation. However, I am getting various Stan warnings about divergent transitions, maximum treedepth, largest R-hat is NA etc. Could someone enlighten me about what I’m doing wrong in terms of code/efficiency/priors as it’s the first time I’m using Stan?
data {
int <lower=1> P; // number of dimensions
int <lower=1> TS; // number of time steps
int <lower=1> D; // number of latent factors
vector[P] y[TS];
}
transformed data {
int<lower=1> beta_l; // number of lower-triangular, non-zero loadings
beta_l = P * (P - D) + D * (D - 1) / 2;
}
parameters {
// Parameters
vector<lower=0>[D] f_sd[TS]; // latent factor standard deviations
vector[beta_l] L_lower[TS]; // lower diagonal loadings
vector<lower=0>[beta_l] L_lower_sd; // lower diagonal standard deviations
vector<lower=0>[D] L_diag[TS]; // positive diagonal loadings
vector[P] y_mu; // y means
vector<lower=0>[P] y_sd; // y standard deviations
// Hyperparameters
vector<lower=0>[D] tau; // scale
cholesky_factor_corr[D] sigma_f_sd; //prior correlation
}
transformed parameters {
cholesky_factor_cov[P, D] beta [TS];
cov_matrix[P] Q[TS];
// beta[T] and Q[T]
for (t in 1:TS){
int idx;
idx = 1;
for (j in 1:D) {
beta[t][j, j] = L_diag[t][j]; // set positive diagonal loadings
for (k in (j+1):D){
beta[t][j, k] = 0; // set upper triangle values to 0
}
for (i in (j+1):P){
beta[t][i, j] = L_lower[t][idx]; // set lower diagonal loadings
idx = idx + 1;
}
}
Q[t] = beta[t] * diag_matrix(f_sd[t]) * beta[t]' + diag_matrix(y_sd); // specify covariance of y
}
}
model {
// priors
f_sd[1] ~ gamma(2, 0.1);
L_lower[1] ~ normal(0, 1);
L_diag[1] ~ gamma(1, 1);
tau ~ cauchy(0, 2.5);
sigma_f_sd ~ lkj_corr_cholesky(2);
L_lower_sd ~ gamma(2, 0.1);
for (t in 2:TS){
f_sd[t] ~ multi_normal_cholesky(f_sd[t-1], quad_form_diag(sigma_f_sd, tau));
L_lower[t] ~ normal(L_lower[t-1], L_lower_sd);
y[t] ~ multi_normal(y_mu, Q[t]);
}
}
Cheers