由于数值精度,未能重现基本的Stan示例

时间:2016-09-16 20:27:24

标签: floating-point simulation stan

我正在尝试重现Stan手册2.11节中第15.2-15.3节中的示例:

gpdemo.stan
/*
 * Stan manual, ch. 15
 */

data {
  int<lower=1> N;
  real x[N];
}


transformed data {
  vector[N] mu;
  cov_matrix[N] Sigma;
  matrix[N, N] L;

  for (i in 1:N)
    mu[i] = 0;

  for (i in 1:N)
    for (j in 1:N)
      Sigma[i, j] = exp(-square(x[i] - x[j])) + i == j ? 0.1 : 0.0;
  L = cholesky_decompose(Sigma);
}


parameters {
  vector[N] z;
}


model {
  z ~ normal(0, 1);
}


generated quantities {
  vector[N] y;
  y = mu + L * z;
}
gpdemo.R
library('rstan')

x <- -50:50 / 10

data <- list(
  N = length(x),
  x = x
)

sim <- stan("gp-demo.stan", "gp_demo", data = data, iter = 200, chains = 3)

但斯坦抱怨Sigma不是肯定的:

Error : Exception thrown at line 23: cholesky_decompose: Matrix m is not positive definite
failed to create the sampler; sampling not done

事实上并非如此:

x_dist <- as.matrix(dist(x))
x_kernel <- exp(-x_dist^2)
eigen(x_kernel)$values
# [1] FALSE

但问题似乎是数字精度而不是其他任何问题:

summary(eigen(x_kernel)$values)
#      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
#  0.000000  0.000000  0.000000  1.000000  0.000049 17.360000 
min(eigen(x_kernel)$values)
# [1] -1.125251e-15

显然,这个例子在某人的机器上运行没有数字问题(否则它不会出现在手册中,更不用说在互联网上的博客上复制了)。这是一个非常简单的例子,所以我想知道我是否只是在某个地方犯了错误。

为了它的价值,我能够通过更明智地循环来构建Sigma来实现这一点:

for (i in 1:N) Sigma[i, i] = 1.1;
for (i in 1:(N-1))
  for (j in (i+1):N) {
    Sigma[i, j] = exp(-square(x[i] - x[j]));
    Sigma[j, i] = Sigma[i, j];
}

0 个答案:

没有答案