Incompatible type with reduce_sum

This is related to my post here, but I changed the model and data structure enough to warrant a new post.

The model is as follows:

//This stan code fits a model with lags done ahead of time, rather than in the 
// Stan code
//lags should be calculated manually, and the first observation in each time 
//series should be removed before data is given to stan

functions{
  
  real partial_sum(matrix[] y_slice,
                   int start, int end,
                   matrix lagvars,
                   vector alpha, matrix beta,
                   matrix Omega, vector[] tau,
                   int[] country)
  {
    for(i in start:end){
      return multi_normal_lpdf(to_vector(y_slice[i]) | alpha[country[i]] + to_matrix(beta[country[i]])*lagvars[i]',
      quad_form_diag(to_matrix(Omega[country[i]]), tau[country[i]]));
    }                 
  }
                   
  
  
}


data{
  
  int N; //# observations
  int K; //# dimensions of Y
  int C; //# of countries
  int R; //# of regions
  
  int<lower = 1, upper=C> country[N]; //country id for each obs
  int<lower = 1, upper=N> n[N]; //observation id for each obs

  matrix[N,K] Y; //the outcome array - each variable's time series stacked by region
  matrix[N,K] L; //the lagged variables
  
}

parameters{
  
  
  //individual level
  vector<lower = 0>[K] tau[C]; //scale for residuals
  matrix[K, K] z_beta[C]; //untransformed betas 
  vector[K] z_alpha[C]; //untransformed intercepts
  
  //hierarchical parameters
  corr_matrix[K] Omega[C]; //country level correlation matrix
  vector[K] tau_loc; //mean for variance scaling factor
  vector<lower=0>[K] tau_scale; //scale for tau
  matrix[K, K] bhat_location; //mean for prior on beta
  matrix<lower = 0>[K, K] bhat_scale; //scale for prior on beta
  vector[K] ahat_location; //means for prior on intercepts
  vector<lower = 0>[K] ahat_scale; //variance for intercept prior
  
  
}

transformed parameters{
  
  matrix[K, K] beta[C]; //VAR(1) coefficients, country specific
  vector[K] alpha[C]; //country specific intercepts

  
  for(c in 1:C){
    //recentering random effects
    alpha[c] = ahat_location + ahat_scale .*z_alpha[c];
    beta[c] = bhat_location + bhat_scale*z_beta[c];
  }
 
}

model{
  
  int grainsize = 1;
  
  //hyperpriors
  tau_loc ~ cauchy(0,1);The pa
  tau_scale ~ cauchy(0,1);
  ahat_location ~ normal(0,1);
  ahat_scale ~ cauchy(0, 1); 
  to_vector(bhat_location) ~ normal(0, 0.5);
  to_vector(bhat_scale) ~ cauchy(0, 0.5);

  
  //hierarchical priors
  for(c in 1:C){
    //non-centered paramaterization to avoid convergence issues
    z_alpha[c] ~ normal(0, 1);
    to_vector(z_beta[c]) ~ normal(0, 1);
    tau[c] ~ normal(tau_loc, tau_scale);
    Omega[c] ~ lkj_corr(5);
  }
  
  target+= reduce_sum(partial_sum, Y, grainsize, L,
                      alpha, beta, Omega, tau, 
                      country);
  
  
}

This fails to compile with the following error:

Ill-typed arguments supplied to function 'reduce_sum'. Available arguments:
(T[], int, int, ...) => real, T[], int, ...
(T[,], int, int, ...) => real, T[,], int, ...
(T[,,], int, int, ...) => real, T[,,], int, ...
(T[,,,], int, int, ...) => real, T[,,,], int, ...
(T[,,,,], int, int, ...) => real, T[,,,,], int, ...
(T[,,,,,], int, int, ...) => real, T[,,,,,], int, ...
(T[,,,,,,], int, int, ...) => real, T[,,,,,,], int, ...
Where T is any one of int, real, vector, row_vector or matrix.
Instead supplied arguments of incompatible type: (matrix, int, int, matrix, vector[], matrix[], matrix[], vector[], int[]) => real, matrix, int, matrix, vector[], matrix[], matrix[], vector[], int[]

Error: An error occured during compilation! See the message above for more information.

I don’t know exactly what this error is trying to tell me, specifically which term is incompatible. This code compiles and runs using only partial_sum in the model block, so I’m guessing it’s some issue with how I’m passing or defining the arguments and reduce_sum, but I’m in the dark as to what the issue is.

Y that you supply to reduce_sum is a matrix, not a vector of matrices ( matrix[ ] ).

There may be something else but that is the first thing you need to fix.

Thank you, but I’m not quite sure what it means to declare Y as a vector of matrices for this purpose. I’ve tried declaring Y as vector[N] Y[K] but this produces the same error.

If you do that then real partial_sum(matrix[] y_slice, ... must also be real partial_sum(vector[] y_slice, ....

Ah, of course. That makes sense. Is it not possible to slice over rows of a matrix with reduce_sum? The function documentation (which I may be misreading) seems to say that T[] can be an array of any type, which I assumed included a matrix.

And y slice is indexed not from start to end, but from 1 to end-start+1.

1 Like

A matrix is as an array vector or row_vectors and you have to specify it as either one of them.

Thanks for the clarification. I need to select the appropriate country for each observation in order to index the correct coefficients. Should I instead slice on an index variable, i.e. something like?:

  real partial_sum(int[] n_slice,
                   int start, int end,
                   matrix Y,
                   matrix lagvars,
                   vector[] alpha, matrix[] beta,
                   matrix[] Omega, vector[] tau,
                   int[] country)
  {
    for(i in n_slice){
      return multi_normal_lpdf(Y[i]| alpha[country[i]] + to_matrix(beta[country[i]])*lagvars[i]',
      quad_form_diag(to_matrix(Omega[country[i]]), tau[country[i]]));
    }                 
  }