Stan中cov_exp_quad函数返回非对称协方差矩阵问题咨询
问题原因分析
你遇到的非对称问题并不是cov_exp_quad函数的bug,而是你对该函数的功能和参数定义存在误解:
- Stan中
cov_exp_quad是针对一维输入设计的协方差计算函数,标准调用逻辑有两种:- 仅传入一组一维点
x:cov_exp_quad(x, sigma, l),返回x的自协方差矩阵,该矩阵是对称正定的 - 传入两组一维点
x和y:cov_exp_quad(x, y, sigma, l),返回两组点的交叉协方差矩阵,其中K[i,j] = sigma^2 * exp(-(x[i] - y[j])^2/(2l^2)),仅当x和y完全相同时返回结果才对称
- 仅传入一组一维点
- 你当前的需求是计算二维输入点的指数平方核协方差矩阵,但错误地把二维点的两个维度分别作为两组一维输入传给了
cov_exp_quad,传入的x是二维点的第一维坐标序列,y是二维点的第二维坐标序列,两者本身并不相同,因此返回的交叉协方差矩阵自然是非对称的,完全符合函数的预期行为。
验证说明
你传入的输入数据实际为:x序列:[0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1]y序列:[0, 0.5, 1, 0, 0.5, 1, 0, 0.5, 1]
按cov_exp_quad的计算逻辑,K[1,2] = exp(-(0 - 0.5)^2/2) = 0.8824969,而K[2,1] = exp(-(0 - 0)^2/2) = 1,和你输出的结果完全一致,不存在函数异常。
正确实现方案
如果要计算二维输入点的指数平方核自协方差矩阵,需要手动遍历计算两个点的二维距离,示例Stan脚本修改如下:
data { int<lower=1> N; real x[N]; // 二维点的第一维 real y[N]; // 二维点的第二维 real<lower=0> sigma; real<lower=0> l; } transformed data { matrix[N,N] K; // 手动计算二维指数平方核 for (i in 1:N) { K[i,i] = square(sigma); for (j in 1:(i-1)) { real sq_dist = square(x[i] - x[j]) + square(y[i] - y[j]); K[i,j] = square(sigma) * exp(-sq_dist / (2 * square(l))); K[j,i] = K[i,j]; // 保证对称性 } } } generated quantities { matrix[N, N] Cov = K; }
调用时传入sigma=1, l=1即可得到对称的二维输入协方差矩阵。
内容的提问来源于stack exchange,提问作者Marco De Virgilis
相关产品推荐
相关产品推荐

