Advice on optimizing transformed parameters definition


I would like to get some advice on how to optimize a transformed parameters’ block.

I have a P by Q matrix M, that I need to fill with some transformation of my parameters as follows. param_1 is a vector of length P and param_2 is a P by Q matrix.

For all p, the pth diagonal element of M is 1 / (1 + exp(-param_1[p])).
For all p and q such that p != q, I have M[p, q] = -2*M[p, p] * (exp(param_2[p,q])/(1+sum(exp(param_2[p,])) - exp(param_2[p,q])).

Would anyone have an idea of how to code this efficiently in rstan? I am doing the following but this doesn’t seem to be optimal. M_intermediate is a P by Q matrix, and M_pp is a vector of length P.

  for (p in 1:P){
      M_intermediate[p,] = to_row_vector(exp(param_2[p,]));
      M_pp[p] = 1 / (1 + exp(-param_1[p]));
      for (q in 1:Q){
        M[p,q] = - 2 * M_pp[p] * M_intermediate[p,q] / (1 + sum(M_intermediate[p,q]) - M_intermediate[p,q]);
    M[p,p] = M_pp[p];

Thank you very much!

[edit: escaped code]

1 / (1 + exp(-x)) is just inv_logit(x) and our built-in will be more efficient. And it can be vectorized. So that’s just

M_pp = inv_logit(param_1);

But usually you don’t want to do that, but rather pass the actual log odds into one of our log-odds parameterized bernoulli or binomials.

If that’s symmetric, then you only want to compute once, but it doesn’t look like it is. You want to avoid things like to_row_vector and just declare param_2 as a matrix so that param_2[p] is a row vector.