3

根据定义,具有零行列式的方阵不应该是可逆的。但是,由于某种原因,在生成协方差矩阵之后,我成功地取了它的逆矩阵,但是取协方差矩阵的行列式最终得到了 0.0 的输出。

可能会出现什么问题?我应该不相信行列式输出,还是不应该相信逆协方差矩阵?或两者?

我的代码片段:

cov_matrix = np.cov(data)
adjusted_cov = cov_matrix + weight*np.identity(cov_matrix.shape[0]) # add small weight to ensure cov_matrix is non-singular
inv_cov = np.linalg.inv(adjusted_cov) # runs with no error, outputs a matrix
det = np.linalg.det(adjusted_cov) # ends up being 0.0
4

1 回答 1

3

矩阵的数值求逆不涉及计算行列式。(Cramer 的逆公式不适用于大型矩阵。)因此,行列式计算结果为 0(由于浮点数精度不足)这一事实对于矩阵求逆例程来说不是障碍。

跟进 BobChao87 的评论,这里是一个简化的测试用例(Python 3.4 控制台,numpy 导入为 np)

A = 0.2*np.identity(500)
np.linalg.inv(A)

输出:一个主对角线上为 5 的矩阵,它是 A 的正确逆矩阵。

np.linalg.det(A)

输出:0.0,因为行列式 (0.2^500) 太小而无法以双精度表示。

一种可能的解决方案是一种预处理(这里只是重新调整):在计算行列式之前,将矩阵乘以一个因子,使其条目平均接近 1。在我的示例中,np.linalg.det(5*A)返回 1。

当然,这里使用因子 5 是作弊,但np.linalg.det(3*A)也会返回一个非零值(约 1.19e-111)。如果您尝试np.linalg.det(2**k*A)让 k 穿过适度的正整数,您可能会遇到一个返回非零的值。然后你就会知道原始矩阵的行列式大约是输出的 2**(-k*n) 倍,其中 n 是矩阵大小。

于 2015-02-25T18:58:29.590 回答