Ill-typed arguments to '~' statement. No distribution 'categorical' was found with the correct signature

Hello!
It’s my first time doing inference in Stan and after solving many bugs, this is where I am stuck at. I am trying to simulate a 3-state Markov chain and the transition probabilities come from a Gaussian process with spatio-temporal covariance matrix and some other variables. The error refers to the part that I want to simulate y (the states), which comes from a categorical distribution.

functions {

    array[] matrix cor_sep(real nu, real c, real a, real alpha, 
    data array[] matrix u_ar, data array[] matrix h_ar, data int n_var, data int n_block_row) {
    
        array[n_block_row] matrix[n_var, n_var] corr;
        
        for (n in 1:n_block_row) {

            corr[n] = (a * u_ar[n] ^ (2 * alpha) + 1) ^ (-1) .* ((1 - nu) * exp(-c * h_ar[n]));
            
            for (j in 1:n_var) {
                for (i in 1:n_var) {
                    if (i == j)
                        corr[n][i, j] = (a * (u_ar[n][i, j]) ^ (2 * alpha) + 1) ^ (-1);
                }
            }
        }
        return corr;
    }
    
    matrix cor_joint(real nu, real c, real a, real alpha, array[] matrix corr_ar, 
    data int n_var, data int n_block_row) {
    
        int ind_i_start;
        int ind_i_end;
        int ind_j_start;
        int ind_j_end; 
        matrix[n_var * n_block_row, n_var * n_block_row] corr;
        
        for (i in 1:n_block_row) {
        
            ind_i_start = ((i - 1) * n_var + 1);
            ind_i_end = (n_var * i);
        
            for (j in 1:n_block_row) {
    
                ind_j_start = ((j - 1) * n_var + 1);
                ind_j_end = (n_var * j);
        
                if (j >= i) 
                    corr[ind_i_start:ind_i_end, ind_j_start:ind_j_end] = corr_ar[j - i + 1];
                else 
                    corr[ind_i_start:ind_i_end, ind_j_start:ind_j_end] = corr_ar[i - j + 1];
            }
        }
        return corr;
    }
}

data {
    int<lower=1> N;
    int<lower=1> N_mu;
    int<lower=1> lag_u;
    int<lower=1> n_ahead;
    
    //number of wind farms
    int<lower=1> n_var;
    
    int<lower=1> lag_max;
    int<lower=1> n_block_row;
    
    
    matrix[n_var, n_var] dist;
    vector[N_mu] X[N];
    
    array[n_block_row] matrix[n_var, n_var] h_ar;
    array[n_block_row] matrix[n_var, n_var] u_ar;
    
    //the final y
    int<lower = -1, upper = 1> y[N,n_var];
    
}

parameters {
    // model parameters
    real<lower=0, upper=1> nu;
    real<lower=0> c;
    real<lower=0> a;
    real<lower=0, upper=1> alpha;
    
    //new_parameters
    //array[N] matrix[3,3] beta;
    //array[n_var] matrix[3,3] b;
    //array[N,n_var] simplex[3] theta[3];
    vector[N]beta[3,3];
    matrix[N,n_var]b[3,3];
    
    

    // mean
    vector[N_mu] mu;
}

transformed parameters {

    array[n_block_row] matrix[n_var, n_var] c_sep;
    matrix[n_var * n_block_row, n_var * n_block_row] c_joint;
    array[N, n_var, 3, 3] simplex[3] theta;

    c_sep = cor_sep(nu, c, a, alpha, u_ar, h_ar, n_var, n_block_row);
    c_joint = cor_joint(nu, c, a, alpha, c_sep, n_var, n_block_row);
    
        for(i in 2:N){
          for(j in 1:n_var){
            for(t in 1:3){
              for(k in 1:3){
                    theta[i,j,t,k] = softmax(beta[i,t,k]*X[i] + b[i,j,t,k]);
                 }
               }
            }
        }
}
model {
    // flat priors
    nu ~ uniform(0, 1);
    c ~ uniform(0.0001, 5);
    a ~ uniform(0.0001, 5);
    alpha ~ uniform(0, 1);
    mu ~ uniform(-10,10);
    for(i in 2:N){
      X[i]~ multi_normal(mu, c_joint);
      for(j in 1:n_var){

        y[i,j] ~ categorical(theta[y[i-1,j]]);
      }
    }
}
"

And this is the error:


> fit_sep <- stan(model_code = fit_sep_stan_code, iter = 10000, verbose = FALSE, 
+                 chain = 4, data = stan_data, init = stan_init, seed = 123)
Error in stanc(file = file, model_code = model_code, model_name = model_name,  : 
  0

Semantic error in 'string', line 116, column 8 to column 46:

Ill-typed arguments to '~' statement. No distribution 'categorical' was found with the correct signature.

Any help is appreciated!

One issue data y is declared with a range -1 to 1 and then used to index theta:

I see thanks. Can you be more clear how should I change this? I thought that’s the way to define a categorical distribution based on the manual.

Indexing in Stan starts at one, and the categorical distribution expects the lower bound of your y value to be one.

oh got you! I did the changes and the error is now this:

`Syntax error in ‘string’, line 90, column 26 to column 31, parsing error:

Ill-formed phrase. Found L-value. This can be completed in many ways.`

I believe it is because of this part and the way I defined these variables:

  for(i in 2:N){
      for(j in 1:n_var){
        for(t in 1:3){
          for(k in 1:3){
                theta[i,j,t,k] = beta[t,k,i]*X[i,j] + b[t,k,i,j];
             }
           }
        }
    }`
 vector[N]beta[3,3];
 matrix[N,n_var]b[3,3];

 array[N, n_var, 3, 3] theta;
 vector[N_mu] X[N];

Do you know how should I change this?

Assuming your theta is still a parameter, you cannot assign it a value.

I put it in the transformed parameters block. Is that a problem? I thought the problem was caused because of the way I defined beta and b.

Theta is defined in parameters block? I think you need to define it in transformed block.

Have you tried commenting out a line of code or a portion, saving and checking the syntax? Systematically doing that will save you a lot of time narrowing down the issue.

Comparing,

y[i,j] ~ categorical( theta[ y[i-1,j] ] );

with your declaration for theta shows that you are only indexing one of the 5 dimensions of that transformed parameter.

Also, once you get past the syntax issues, you’ll have runtime issues because the loops are not indexing the right array dimensions. In the old syntax,

matrix[N,n_var] b[3,3];

you are indexing it in the loops starting with N, … but this declaration is a two-dimensional array, each element containing a two-dimensional matrix. The new, equivalent syntax makes it easier to follow,

array[3,3] matrix[N,n_var] b;

And comparing that syntax to your loops, you’ll see where to make changes.

1 Like

Thanks for your time.
I applied the changes and I’m still getting the error. I don’t know how else I can define the parameters for it to work.


functions {

    array[] matrix cor_sep(real nu, real c, real a, real alpha, 
    data array[] matrix u_ar, data array[] matrix h_ar, data int n_var, data int n_block_row) {
    
        array[n_block_row] matrix[n_var, n_var] corr;
        
        for (n in 1:n_block_row) {

            corr[n] = (a * u_ar[n] ^ (2 * alpha) + 1) ^ (-1) .* ((1 - nu) * exp(-c * h_ar[n]));
            
            for (j in 1:n_var) {
                for (i in 1:n_var) {
                    if (i == j)
                        corr[n][i, j] = (a * (u_ar[n][i, j]) ^ (2 * alpha) + 1) ^ (-1);
                }
            }
        }
        return corr;
    }
    
    matrix cor_joint(real nu, real c, real a, real alpha, array[] matrix corr_ar, 
    data int n_var, data int n_block_row) {
    
        int ind_i_start;
        int ind_i_end;
        int ind_j_start;
        int ind_j_end; 
        matrix[n_var * n_block_row, n_var * n_block_row] corr;
        
        for (i in 1:n_block_row) {
        
            ind_i_start = ((i - 1) * n_var + 1);
            ind_i_end = (n_var * i);
        
            for (j in 1:n_block_row) {
    
                ind_j_start = ((j - 1) * n_var + 1);
                ind_j_end = (n_var * j);
        
                if (j >= i) 
                    corr[ind_i_start:ind_i_end, ind_j_start:ind_j_end] = corr_ar[j - i + 1];
                else 
                    corr[ind_i_start:ind_i_end, ind_j_start:ind_j_end] = corr_ar[i - j + 1];
            }
        }
        return corr;
    }
}

data {
    int<lower=1> N;
    int<lower=1> N_mu;
    int<lower=1> lag_u;
    int<lower=1> n_ahead;
    
    //number of wind farms
    int<lower=1> n_var;
    
    int<lower=1> lag_max;
    int<lower=1> n_block_row;
    
    
    matrix[n_var, n_var] dist;
    vector[N_mu] X[N];
    
    array[n_block_row] matrix[n_var, n_var] h_ar;
    array[n_block_row] matrix[n_var, n_var] u_ar;
    
    //the final y
    int<lower = 1, upper = 3> y[N,n_var];
    
}

parameters {
    // model parameters
    real<lower=0, upper=1> nu;
    real<lower=0> c;
    real<lower=0> a;
    real<lower=0, upper=1> alpha;
    
    //new_parameters

    vector[N]beta[3,3];
    array[3,3] matrix[N,n_var] b;
    
    // mean
    vector[N_mu] mu;
    }

transformed parameters {

    array[n_block_row] matrix[n_var, n_var] c_sep;
    matrix[n_var * n_block_row, n_var * n_block_row] c_joint;
    array[3,3] matrix[N,n_var] theta;

    c_sep = cor_sep(nu, c, a, alpha, u_ar, h_ar, n_var, n_block_row);
    c_joint = cor_joint(nu, c, a, alpha, c_sep, n_var, n_block_row);
    
    
    for(t in 1:3){
      for(k in 1:3){
        for(i in 2:N){
          for(j in 1:n_var){

                  theta[t,k,i,j] = beta[t,k,i]*X[i,j] + b[t,k,i,j];
                 }
               }
            }
        }
}

model {
    // flat priors
    nu ~ uniform(0, 1);
    c ~ uniform(0.0001, 5);
    a ~ uniform(0.0001, 5);
    alpha ~ uniform(0, 1);
    mu ~ uniform(-10,10);
    
      for(t in 1:3){
        for(k in 1:3){
        for(i in 2:N){
          for(j in 1:n_var){
                b[t,k,i,j]~ uniform(0.001, 1);
                beta[t,k,i] ~ uniform(0.001, 1);
              }
            }
          }
        }

    for(i in 2:N){
      X[i]~ multi_normal(mu, c_joint);
      for(j in 1:n_var){
        y[i,j] ~ categoricalLogit(theta[y[i-1,j],,i,j]);
    }
   }
}

The error I am getting is because of this line:

 y[i,j] ~ categoricalLogit(theta[y[i-1,j],,i,j]);

and the error itself is:

Ill-typed arguments to '~' statement. No distribution 'categoricalLogit' was found with the correct signature.

Thanks again!

It looks function call changed from categorical to categoricalLogit, which doesn’t exist as a function name in Stan. For that, you would use categorical_logit, but the two expect different args.

oh yes I figured that later, dumb mistake!
Still getting the same error. and yes the parameter theta stays the same since I omitted the SoftMax function I had before.

Thanks Scott, I was able to figure out the problem and get the chain running! I will open an another topic if I face any issues - which most probably I will!

2 Likes