Dimension mismatch between a matrix and a vector

Hello,

I’m trying to fit a Stan model shown here:

data {
  int<lower=0> n_person;
  int<lower=0> n_item;
  int<lower = 1> D;
  int<lower=0, upper = 1> Y[n_person,n_item];
  real<lower=0> t[n_person,n_item];
  vector[D] Zero;
}

parameters {
  vector[n_person] theta;
  vector[n_person] tau;
  corr_matrix[2] correlP; 
  vector<lower=0>[D] sigmaP;
  vector[n_item] b;
  vector[n_item] beta;
  real mu_b;
  real mu_beta;
  real<lower=0> sigma_b;
  real<lower=0> sigma_beta;
}

transformed parameters{
  matrix[D, n_person] PersPar[n_person];
  cov_matrix[D] SigmaP;
  SigmaP=quad_form_diag(correlP, sigmaP);
  PersPar[1] = theta;
  PersPar[2] = tau;
}

model {
  PersPar~ multi_normal(Zero,SigmaP);
  sigmaP ~ cauchy(0,5);
  correlP ~ lkj_corr(1);
  b ~ normal(mu_b,sigma_b);
  beta ~ normal(mu_beta,sigma_beta);
  sigma_b ~ cauchy(0,5);
  sigma_beta ~ cauchy(0,5);
  for(i in 1:n_person){
    for (j in 1:n_item){
      Y[i,j] ~ bernoulli(inv_logit(theta[i] - b[j]));
      t[i,j] ~ lognormal(beta[j] - tau[i], sigma_beta);
    }}
}

However, I’m getting a mismatch between the matrix and the vector in rows 27 and 28. What is the proper way to write this code?

The data which is used here can be generated with the R code:

library(tidyverse)
library(magrittr)

Y <- list()
t <- list()

p <- rep(seq(.2, .8, .2),5)

for(i in 1:20){
  Y[[i]] <- rbinom(500, 1, p[i]) %>% as.numeric()
  t [[i]] <- rlnorm(n = 500, meanlog = log(4), sdlog = log(1.5)) %>% as.numeric()
}

Y %<>% transpose() %>% 
  map(unlist)

t %<>% transpose() %>% 
  map(unlist)

dfs <- list("Y" = Y,
            "t" = t)

data <- list("n_person" = length(Y),
             "n_item" = length(Y[[1]]),
             "D" = length(dfs),
             "Y" = dfs$Y,
             "t" = dfs$t,
             "Zero" = rep(0, length(dfs)))

Because you’re assigning to rows of PersPar, you need to declare theta and tau as being type row_vector

Scratch that, read your model too quickly.

You’ve declared PersPar as an array of matrices:

  matrix[D, n_person] PersPar[n_person];

So when you write PersPar[1] Stan is expecting a D x n_person matrix, but you’re assigning an n_person x 1 vector. Is that intended?

Thank you for your help! No, that was not intended. I was trying to make PersPar a matrix with D rows and n_person columns. Sorry, I’m new to Stan so I’m just figuring things out. In order to alleviate this error, I tried removing the [n_person] bit from the PersPar, so now it looks like this - is this correct?:

matrix[D, n_person] PersPar;

But now I am getting an error in line 32 of my code: No matches for: Available argument signatures for multi_normal: Real return type required for probability function. So I presume this is because PersPar is a matrix and the program expects a vector? But if so, how can I put theta and tau in the same object to be used in multi_normal, while still retaining their names so they can be used in the equations in lines 41 and 42?

Sorry if there’s too much questions, but like I said, I’m quite new to Stan.

Not a problem. In this situation you want an array of vectors, since each vector of observations is specified to follow a multivariate distribution. Try:

vector[D] PersPar[n_person];

for(i in 1:n_person) {
  PersPar[i] = [theta[i], tau[i]]';
}

The above code loops over n_person, packs the theta and tau values for that individual into a vector, and assigns it to PersPar

Thank you very much for your help! This works perfectly! The logic is also much clearer to me now!

1 Like