Hierarchical Non-centred Parameterisation

Hi,
I am working on a 3 level hierarchical model but I am struggling with the computation time.

I know that going from a centred to a non-centred approach is the way forward to solve this and I have attempted to implement it, however I have come into problems when assigning bounds of the raw parameters for standard deviation (where the parameter has a lower=0).

I saw a very helpful post and solution by @Bob_Carpenter about assigning the raw parameter bounds based on rearranging the non-centred equation and I implemented this. However, I came across a few problems when applying this to the lower level standard deviations.

The code below is a snippet of the hierarchy for parameter ‘a’.

  1. The raw parameter’s bounds are specified in the parameter section of the code but relate to transformed parameters that are not yet defined. Do you have any suggestions on how to get around this?

In the code below on line [ real<lower=-a_sd_mu[X]/a_sd_sd[X]>[X,Y] a_sd_raw;] a_sd_sd and a_sd_mu are not yet defined.

  1. In attempt to avoid this issue, I centred the top and middle level and non-centred the lowest level (where the most of the parameters are and therefore I assume the most computationally expensive level). A new problem arose involving standard deviation bounds - I am assigning the raw parameter bounds to a matrix but each element in the matrix has a different bound which is the result of elementwise vector division. I’m not sure how to index which vector division values applied to each element of the matrix.

In the code below on line [ real<lower=-a_sd_mu[X]/a_sd_sd[X]>[X,Y] a_sd_raw;] … I am struggling to assign a_sd_mu[X] to the appropriate index in a_sd_raw [X,Y]

  1. The final solution has been to centre all standard deviation parameters in order to be able to set bounds but keep the non-centred approach for the mean throughout all of the levels. This has sped up the model considerably. The issue now is … it doesn’t converge and n_eff is ~ 9/5000. Am I doing something wrong?

parameters{
  ...
  real a_sd_sd_mu; //global
  real<lower=0> a_sd_sd_sd; //global

  real<lower=-a_sd_sd_mu/a_sd_sd_sd>[X] a_sd_sd_raw; //middle level, x groups within this level

  real<lower=-a_sd_mu[X]/a_sd_sd[X]>[X,Y] a_sd_raw; //bottom level, X*Y groups within this level
  ...
}
transformed parameters{
  real<lower=0> a_sd_mu[X]; // middle level
  real<lower=0> a_sd_sd[X]; // middle level

  real<lower=0> a_sd[X,Y]; //bottom level
  ...
  //non-centred
  for (x in 1:X){

    for (y in 1:Y){
      a_sd[x,y] = a_sd_mu[x] + a_sd_sd[x]*a_sd_raw[x,y];
    }
  }
  ...
}

I am not sure if it is faux pas to shout out to individual members on questions, so please excuse my ignorance as a newbie around here!

I saw that @jonah and @Bob_Carpenter have done similar type work, itwould be much appreciated if you could take a look and give some pointers if possible.

Thanks!