Home > OS >  Error in Stan Code when variable is clearly defined
Error in Stan Code when variable is clearly defined

Time:02-15

I am getting the following error in my Stan code:

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
No matches for: 

  gpareto_lcdf(real, real, real)

Available argument signatures for gpareto_lcdf:

  gpareto_lcdf(vector, real, real)

 error in 'modelafda6ff99d79_gpd' at line 54, column 50
  -------------------------------------------------
    52:   for (i in 1:n) {
    53:     if (censored[i]) {
    54:       target  = gpareto_lcdf(value[i] | k, sigma);  
                                                         ^
    55:     } else {
  -------------------------------------------------

Error in stanc(file = file, model_code = model_code, model_name = model_name,  : 
  failed to parse Stan model 'gpd' due to the above error.

In my R studio version, it seems to be complaining about the sigma parameter and not being able to find a match for it. I don't understand why this is an issue given that sigma is defined in my gpareto_lcdf. Here is the code that I am using:

functions {
  real gpareto_lpdf(vector y, real k, real sigma) {
    // generalised Pareto log pdf 
    int N = rows(y);
    real inv_k = inv(k);
    if (k<0 && max(y)/sigma > -inv_k)
      reject("k<0 and max(y)/sigma > -1/k; found k, sigma =", k, sigma)
    if (sigma<=0)
      reject("sigma<=0; found sigma =", sigma)
    if (fabs(k) > 1e-15)
      return -(1 inv_k)*sum(log1p((y) * (k/sigma))) -N*log(sigma);
    else
      return -sum(y)/sigma -N*log(sigma); // limit k->0
  }

  real gpareto_lcdf(vector y, real k, real sigma) {
    // generalised Pareto log cdf
    real inv_k = inv(k);
    if (k<0 && max(y)/sigma > -inv_k)
      reject("k<0 and max(y)/sigma > -1/k; found k, sigma =", k, sigma)
    if (sigma<=0)
      reject("sigma<=0; found sigma =", sigma)
    if (fabs(k) > 1e-15)
      return sum(log1m_exp((-inv_k)*(log1p((y) * (k/sigma)))));
    else
      return sum(log1m_exp(-(y)/sigma)); // limit k->0
  }
}

data {
  // the input data
  int<lower = 1> n;                      
  real<lower = 0> value[n];              
  int<lower = 0, upper = 1> censored[n];  

  // parameters for the prior
  real<lower = 0> a;
  real<lower = 0> b;
}

parameters {
  real k;
  real sigma;
}

model {
 // prior
 k ~ gamma(a, b);
 sigma ~ gamma(a,b);

 // likelihood
  for (i in 1:n) {
    if (censored[i]) {
      target  = gpareto_lcdf(value[i] | k, sigma);  
    } else {
      target  = gpareto_lpdf(value[i] | k, sigma);
    }
  }
}

Clearly sigma is defined in the gpareto_lcdf and so I am unsure why Stan is complaining about this.

CodePudding user response:

Your code in the likelihood section of the model block doesn't match the way you have defined the gpareto...() functions in the functions block. The gpareto functions take a vector as the first argument but instead you are looping through and trying to pass a single element of value each time. That's why you get the error that the data types you are passing to gpareto_lcdf() do not match the "signature" of the function. The function expects the first argument to be a vector, the second to be a real, and the third to be a real. But you are passing three reals.

The error has nothing to do with sigma. The ^ symbol is pointing to the entire function call to gpareto_lcdf() and just happens to be pointing near where the word sigma is, but the error isn't related to sigma.

To fix this error, you would need to do one of the following:

  • Redefine the gpareto() functions to take three real arguments and keep your loop in the model block as is.
  • Rewrite your model block to not use a loop and instead be vectorized.

I'm not sure the vectorization will work with the condition you have in the model block so you may be forced to go with the first solution.

I would recommend posting this question on the Stan forum where you may get a better answer.

  • Related