Centered vs NCP Question -> Mixed parameterisation & Correlations

Background: I’m trying to figure out how to do a mixed parameterisation (as per @betanalpha 's excellent course & case studies) but where effects are correlated across responses.

Simpler problem: I’m wondering what actually defines the centered vs non-centered parameterisations - is it the existence of the parameter, or the positioning of the prior?

e.g.

theta = mu + tau * theta_tilde;
mu ~ normal(0, 5);   
tau ~ normal(0, 5); 
theta_tilde ~ normal(0, 1); 

vs

theta = mu + tau * theta_tilde;
mu ~ normal(0, 5);
tau ~ normal(0, 5); 
theta ~ normal(mu, tau); 

Is #2 enough to define it as centered, or is the existence of an unconstrained theta_tilde enough to define it as non-centered?

If #2 is centered, I could correlate levels across responses with a mixed parameterisation, something like this (not tested, so please excuse what may amount to a whole lot of rubbish)!

data {
   ...
   int<lower=1> M; // Number of responses;
   int<lower=1> K; // Number of levels
   int<lower=0, upper=K> K_cp; // Number of levels for centered parameterisation
   int<lower=1, upper=K> cp_idx[K_cp];  Index for cp levels
   int<lower=0, upper=K> K_ncp;  // Number of levels for non-centered parameterisation
   int<lower=1, upper=K> ncp_idx[K_ncp]; // Index for ncp levels
}
parameters {
   ...
   cholesky_factor_corr[M] L_u; // Correlation matrix amongst responses
   matrix[M, K] z_u; // Matrix of levels, standardised for the ncp & non-standardised for the cp levels.
   vector<lower=0>[M] tau;
}
transformed parameters {
  ...
  matrix[M, K] theta; 
  theta[1:M, ncp_idx] = diag_pre_multiply(tau, L_u) * z_u[1:M, ncp_idx];
  theta[1:M, cp_idx] = L_u * z_u[1:M, cp_idx];
}

model {
   // Let's assume mu = 0;
   tau ~ normal(0, 5);
   L_u ~ lkj_corr_cholesky(1.0);
   to_vector(z_u[1:M, ncp_idx]) ~ std_normal();
   to_vector(theta[1:M, cp_idx]) ~ normal(0, tau);
   ...
}

Thoughts/comments welcome, but please be gentle!

1 Like

OK, so in some tests on non-correlated heirarchies, this performs like a true mixed parameterisation, so I think I have my answer - it’s the location of the prior, not the existence of the intermediate variable, & I should be able to implement this in a correlated context. Fingers crossed!

data {
   int<lower=1> N; // Number of observations
   vector[N] y; // Observations
   int<lower=1> K; // Number of levels
   int<lower=0, upper=K> indiv_idx[N]; // Context
   int<lower=0, upper=K> K_cp; // Number of levels for centered parameterisation
   int<lower=1, upper=K> cp_idx[K_cp];  Index for cp levels
   int<lower=0, upper=K> K_ncp;  // Number of levels for non-centered parameterisation
   int<lower=1, upper=K> ncp_idx[K_ncp]; // Index for ncp levels
}

parameters {
  real mu;
  real<lower=0> tau;
  real<lower=0> sigma;
  vector[K] theta_tilde;
}
transformed parameters {
  vector[K] theta;
  theta[ncp_idx] = mu + tau * theta_tilde[ncp_idx];
  theta[cp_idx] = theta_tilde[cp_idx];
}

model {
  mu ~ normal(0, 5);
  tau ~ normal(0, 5);
  sigma ~ normal(0, 1);
  target += normal_lpdf(theta_tilde[ncp_idx] | 0, 1);
  target += normal_lpdf(theta_tilde[cp_idx] | mu, tau);
  y ~ normal(theta[indiv_idx], sigma);
}