明确定义变量时 Stan Code 出错

Error in Stan Code when variable is clearly defined

我的 Stan 代码出现以下错误:

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.

在我的 R studio 版本中,它似乎在抱怨 sigma 参数并且无法找到匹配项。我不明白为什么这是一个问题,因为我的 gpareto_lcdf 中定义了 sigma。这是我正在使用的代码:

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);
    }
  }
}

很明显 sigma 是在 gpareto_lcdf 中定义的,所以我不确定为什么 Stan 会抱怨这个。

您在 model 块的 likelihood 部分中的代码与您在 functions 块中定义 gpareto...() 函数的方式不匹配。 gpareto 函数将向量作为第一个参数,但您每次都在循环并尝试传递 value 的单个元素。这就是为什么您会收到错误消息,即您传递给 gpareto_lcdf() 的数据类型与函数的“签名”不匹配。该函数期望第一个参数为 vector,第二个参数为 real,第三个参数为 real。但是你传递了三个 reals.

该错误与 sigma 无关。 ^ 符号指向对 gpareto_lcdf() 的整个函数调用,恰好指向单词 sigma 所在的位置附近,但错误与 sigma 无关.

要修复此错误,您需要执行以下操作之一:

  • 重新定义 gpareto() 函数以接受三个 real 参数并保持循环在 model 块中。
  • 重写您的 model 块以不使用循环而是进行矢量化。

我不确定矢量化是否适用于 model 块中的条件,因此您可能被迫使用第一个解决方案。

我建议将此问题发布到 Stan forum 上,您可能会得到更好的答案。