numpy:可以反转零行列式矩阵吗?

numpy: Possible for zero determinant matrix to be inverted?

根据定义,行列式为零的方阵不应是可逆的。但是,出于某种原因,在生成协方差矩阵后,我成功地对其进行了逆运算,但采用协方差矩阵的行列式最终得到了 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

求逆的 numerical inversion of matrices does not involve computing the determinant. (Cramer's formula 对于大型矩阵不实用。)因此,行列式的计算结果为 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) 太小而无法用双精度表示。

一种可能的解决方案是一种pre-conditioning(这里,只是重新缩放):在计算行列式之前,将矩阵乘以一个因子,使它的条目平均更接近 1。在我的示例中,np.linalg.det(5*A) returns 1.

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