Restricting parameters based on data

Hi!

In my Stan programme’s data block, I have a matrix of parameters:

// the coefficients for control variables
row_vector[10] gamma[2];

I want each of these 20 parameters to be restricted in a different way (positive, negative, or unrestricted). In the data block, I have a matrix that describes these restrictions:

// the matrix of parameter restrictions
row_vector[10] params_restr[2];

It has 1s, -1s and 0s, standing for the restrictions mentioned above.

If gamma was just a single number, I would do something like:

real<lower = params_restr > 0 ? 0 : negative_infinity(),
        upper = params_restr < 0 ? 0 : positive_infinity()>;

How to define corresponding restrictions for a matrix? Thanks in advance!

Update: a solution I have found to work: just truncate the priors. However, I am not sure how generic this solution is. Also, it seems to be quite slow, so I’d still welcome better ideas.

for (k in 1:2) {
  for (ctrl in 1:10) {
    gamma[k, ctrl] ~ normal(0, 1) T[params_restr[k, ctrl] > 0 ? 0 : negative_infinity(),
                                                      params_restr[k, ctrl] < 0 ? 0 : positive_infinity()];
 }

}

EDIT: Is it possible to vectorize it, to avoid the double loop? I tried, but with no success.

If you truncate your priors you’ll also want to constrain your variables (to prevent the sampler from going outside of the support of the truncated distribution – this’ll give HMC trouble), so that doesn’t get around the problem.

Vectorized constraints aren’t here yet, but for what you’re describing you might be better off just rolling your own: How to specify variable parameter constraints based on other model parameters . Check out the constraints part of the manual: https://mc-stan.org/docs/2_18/reference-manual/variable-transforms-chapter.html for how this is done.

Also, since your priors aren’t a function of other parameters, you really don’t need that truncation either. The normalization for the truncation is constant so you can leave it out.

Hope that helps!