Adding normal_rng and normal_lpdf to matrix specification

Greetings all,

I’m trying to get information to calculate PPCs and LOO from a horseshoe regression using matrix notation for the model. Here is the code

modelString = "
data {
  int<lower=1> n; // Number of data
  int<lower=1> p; // Number of covariates
  matrix[n,p] X;
  real readscore[n];
}

parameters {
  vector[p] beta;
  vector<lower=0>[p] lambda;
  real<lower=0> tau;
  real alpha;
  real<lower=0> sigma;
}

model {
  beta ~ normal(0, tau * lambda);
  tau ~ cauchy(0, 1);
  lambda ~ cauchy(0, 1);
  alpha ~ normal(0, 1);
  sigma ~ cauchy(0, 1);
  
  readscore ~ normal(alpha + X * beta, sigma);
}

// For posterior predictive checking and loo cross-validation
generated quantities {
  vector[n] readscore_rep;
  vector[n] log_lik;
  for (i in 1:n) {
    readscore_rep[i] = normal_rng(alpha + X * beta, sigma);
    log_lik[i] = normal_lpdf(readscore[i] | alpha + X * beta, sigma);
  }
}

"

I’m getting this error message which I presume is a conflict in the assignment, but I am not sure what is needed to get this to run.

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Dimension mismatch in assignment; variable name = readscore_rep, type = real; right-hand side type = real[ ].
Illegal statement beginning with non-void expression parsed as
  readscore_rep[i]
Not a legal assignment, sampling, or function statement.  Note that
  * Assignment statements only allow variables (with optional indexes) on the left;
  * Sampling statements allow arbitrary value-denoting expressions on the left.
  * Functions used as statements must be declared to have void returns

 error in 'model10676ac612dc_50bc7d8a3e141c2f4fdff6b380d8232a' at line 32, column 4
  -------------------------------------------------
    30:   vector[n] log_lik;
    31:   for (i in 1:n) {
    32:     readscore_rep[i] = normal_rng(alpha + X * beta, sigma);
           ^
    33: 
  -------------------------------------------------

PARSER EXPECTED: "}"
Error in stanc(file = file, model_code = model_code, model_name = model_name,  : 
  failed to parse Stan model '50bc7d8a3e141c2f4fdff6b380d8232a' due to the above error.

As always, thank you for your time an patience.

The error says

Dimension mismatch in assignment; variable name = readscore_rep, type = real; right-hand side type = real[ ].

The normal_rng() expression is vectorized and generates an array of values but this is inside a loop so you’re trying to assign that array into a single element of readscore_rep. You can move it out of the loop and have

readscore_rep = normal_rng(alpha + X * beta, sigma);

or select a single row of X so that the normal_rng generates single value

for (i in 1:n) {
  readscore_rep[i] = normal_rng(alpha + X[i,:] * beta, sigma);
  log_lik[i] = normal_lpdf(readscore[i] | alpha + X[i,:] * beta, sigma);
}

Niko,

Thanks. The second approach works. The first approach is giving me the following

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Dimension mismatch in assignment; variable name = readscore_rep, type = vector; right-hand side type = real[ ].
Illegal statement beginning with non-void expression parsed as
  readscore_rep
Not a legal assignment, sampling, or function statement.  Note that
  * Assignment statements only allow variables (with optional indexes) on the left;
  * Sampling statements allow arbitrary value-denoting expressions on the left.
  * Functions used as statements must be declared to have void returns

 error in 'model2108373c6251_86e53254a4d33155e368c3d5d9fb9f68' at line 31, column 2
  -------------------------------------------------
    29:   vector[n] readscore_rep;
    30:   vector[n] log_lik;
    31:   readscore_rep = normal_rng(alpha + X * beta, sigma);
         ^
    32:   log_lik = normal_lpdf(readscore| alpha + X * beta, sigma);
  -------------------------------------------------

PARSER EXPECTED: <one of the following:
  a variable declaration, beginning with type
      (int, real, vector, row_vector, matrix, unit_vector,
       simplex, ordered, positive_ordered,
       corr_matrix, cov_matrix,
       cholesky_corr, cholesky_cov
  or a <statement>
  or '}' to close variable declarations and definitions>
Error in stanc(file = file, model_code = model_code, model_name = model_name,  : 
  failed to parse Stan model '86e53254a4d33155e368c3d5d9fb9f68' due to the above error.
> 

Still, things seem to be working. Thanks again.

Ooh, I forgot the “vectorized” normal_rng outputs an array and not a vector. You could convert that with to_vector() but the second approach is probably better anyway.