How to constraint multilevel parameters when using a non-centered parametrisation?

I have a multilevel model for which the “parent” and “children” parameters are known to be strictly positive (excuse my lack of statistics vocabulary). Using a centred parameterization is sampling a bit too slow for my needs, so I want to test a non-centred model and see if that improves things.

For sake of argument, say I’m fitting something like the 8-schools example but I know that the effect in each school is strictly positive. How can I write such constraint while using a non-centred parameterization?

data {
    int<lower=0> J; 
    real y[J];                                 
    real<lower=0> sigma[J];                    
}
parameters {
    real<lower=0> mu;             // Lower bound on mean effect                   
    real<lower=0> tau;                        
    real<offset=mu, multiplier=tau> theta[J]; // How to constraint theta[J] ???
}
model {
    theta ~ normal(mu, tau);
    y ~ normal(theta, sigma);
}

Thank you! :)

1 Like

Hi Omar,

Have a look at Bob’s answer in this thread: Non-centered parameterisation with boundaries

It should cover what you’re after

2 Likes

That actually helped me. Thank you!! Although, I was thinking there would be some syntax of the form:
real<offset=mu, multiplier=tau><lower=...> theta[J];, that’d allow me to specify bounds, offsets and multipliers in the declaration.

But given the link you sent me, I assume the answer to that is no?

No, you’re not (yet) able to mix offset/multiplier with upper and lower bounds. For now you’ll have to use the ‘old’ non-centered construction with a separate ‘raw’ variable:

data {
    int<lower=0> J; 
    real y[J];                                 
    real<lower=0> sigma[J];                    
}
parameters {
    real<lower=0> mu;             // Lower bound on mean effect                   
    real<lower=0> tau;                        
    real<lower=-mu/tau> theta_raw[J]; // How to constraint theta[J] ???
}
transformed parameters {
  theta[J] = mu + theta_raw * tau;
}
model {
    theta_raw ~ std_normal();
    y ~ normal(theta, sigma);
}
2 Likes

Got it. Thanks a lot!

1 Like