Vectorising random slopes model equation

Hi stan community,

I’m trying to optimise the stan code for some models, and want to vectorise the following random intercept and slope model equation to speed up the computation process:

model {
 for (o in 1:No)
    z_exp[o] = mu + i[ID[o],1] + (psi + i[ID[o],2])*x[o] + i[partnerID[o],3];
} 

where

real psi; // slope for response to x
matrix[Nid,3] i; // individual effects
 i = iz * diag_pre_multiply(sd_I, LI)';
vector<lower=0>[3] sd_I; //  individual standard deviations
matrix[Na,3] iz; // standardised  individual effects
cholesky_factor_corr[3] LI;

to

    z_exp = mu + i[ID,1] + (psi + i[ID,2])*x + i[partnerID,3];

However, I get the following error concerning the random slopes part:

Error in stanc(file = file, model_code = model_code, model_name = model_name,  : 
  0
Semantic error in 'string', line 38, column 31 to column 55:
   -------------------------------------------------

    38:     z_exp = mu + i[ID,1] + (psi + i[ID,2])*x + i[partnerID,3];
                                   ^
   -------------------------------------------------

Ill-typed arguments supplied to infix operator .*. Available signatures: 
(int, int) => int
(real, real) => real
(real, vector) => vector
(vector, real) => vector
(vector, vector) => vector
(complex, complex) => complex
(real, row_vector) => row_vector
(row_vector, real) => row_vector
(row_vector, row_vector) => row_vector
(real, matrix) => matrix
(matrix, real) => matrix
(matrix, matrix) => ma

I think this because the real element for the slope psi and the matrix i provide an ill-typed argument? I would like to maintain the matrix element because it is used to estimate the correlation between the random intercept and slope. What would be the solution to vectorise this equation whilst maintaining the matrix format?

Are you trying to do element-wise multiplication rather than vector multiplication? Because in that case you need .* not *

I have tried fitting it with .* instead, but I still get the same error as I pasted in the previous post with the Ill-typed arguments supplied to infix operator

If you’re doing an element-wise matrix operation, they need to be the same dimensions. If you are doing matrix multiplication, the number of columns of the first must be equal to the number of rows of the second. What are the sizes of these objects you’re attempting to multiply together? Also, you can transform a matrix into its vectors or row vectors using to_vector() or to_row_vector() commands, if that’s what you’re asking about in “what would be the solution to vectorise this equation whilst maintaining the matrix format?”

The total number of observations No is 5991, the matrix i is Nid by npar which is 245 by 3 in this case. ID and partnerID both have a length of No.

I tried

vector[Nid] i_slope = col(i,2); // Individual slopes

which did not work out and returned the same error as before.

What is the correct syntax for transforming the matrix into a vector? I tried to following code from this page Mixed Operations

to_vector(i); 

But get the following error:
Ill-formed statement or expression. A statement or expression could be expected here.

Are you doing anything with to_vector(i); here? That statement doesn’t actually do anything but vectorize the matrix, so on its own it’s not a complete expression. It would be like writing i; — it lacks any operation within the machinery of the sampler.

Seems I made a typo in the last post. I tried to use to following line:

i to_vector(i);

Because I assume the vectorised version needs to be assigned to itself again, similar to Mixed Operations.

I also tried:

  vector[Na] i_mu = col(i,1); //intercept
  vector[Na] i_slopes = col(i,2); //slopes
  vector[Na] i_eps = col(i,3); //partner effects

Which should do the same as using the to_vector command, but similar like before it goes wrong with the random slopes part, similar to in the first post.