python 中的矩阵求逆问题:( A⁻ⁱA ≠ I )

Problem with matrix inversion in python: ( A⁻ⁱA ≠ I )

我一直面临一个有趣的 python 问题。我试过求逆 3x3 矩阵 A

[[1 2 3]
[4 5 6]
[7 8 9]]

然后乘以第一个:A⁻ⁱA。而不是单位矩阵(所有对角线元素都等于一个)我有这个:

[[ 12.   8.   8.]
 [-16.  -8.   0.]
 [  4.   0.   0.]]

只有在这种特定情况下才会出现此问题。具有其他值的矩阵给出正确的结果。这是代码:

import numpy as np
np.set_printoptions(precision=2,suppress=True)

A = np.array([1,2,3,4,5,6,7,8,9])
A = A.reshape(3,3)

print(A)
print(np.linalg.det(A))
print(np.matmul(np.linalg.inv(A),A))

输出:

[[1 2 3]
 [4 5 6]
 [7 8 9]]

6.66133814775094e-16

[[ 12.   8.   8.]
 [-16.  -8.   0.]
 [  4.   0.   0.]] 

您的矩阵不可逆,例如参见wolfram alpha,表示矩阵是奇异的。

您可能会误以为 Python 打印了一个非零的行列式值 (6.66133814775094e-16),但是,这个值非常接近 0,您应该这样对待它。计算机对浮点数所做的操作通常并不完全准确(参见例如这个问题Why are floating point numbers inaccurate?),这可能是行列式的值接近于零但又不完全如此的原因。

这个矩阵的行列式是0。因为

import numpy as np
np.set_printoptions(precision=2,suppress=True)

A = np.array([1,2,3,4,5,6,7,8,9])
A = A.reshape(3,3)
# print determinant
print(np.linalg.det(A))

returns

[[1 2 3]
 [4 5 6]
 [7 8 9]]
0.0

你有一个没有可计算逆矩阵的矩阵。

正如其他人所指出的,奇异矩阵是 non-invertible,所以你从 A^-1 A.

得到了一个无意义的答案

Numpy 包含一个方便的函数来检查 condition number

np.linalg.cond(A)
# 5.0522794445385096e+16

如维基百科所述,这是 Ax = b 中输出值 bA 中矩阵值微小变化的敏感度的度量(有点像广义的衍生物)。较大的值表示 A 是“il-conditioned”,并且可能导致值不稳定。这是 real-valued 矩阵固有的,但浮点运算会使情况恶化。

cond 比查看 np.linalg.det(A) 更有用,可以了解您的矩阵是否为 well-behaved,因为它对 A 中值的比例不敏感(而范数和决定因素是)。例如,这是一个具有小值的矩阵,但确实没有可逆性问题:

A = 1e-10*np.random.random(size=(3,3))

np.linalg.det(A)
# 2.128774239739163e-31
# ^^ this looks really bad...

np.linalg.cond(A)
# 8.798791503909136
# nevermind, it's probably ok

A_ident = np.matmul(np.linalg.inv(A), A)
np.linalg.norm(A_ident - np.identity(3))
# 5.392490230798587e-16
# A^(-1)*A is very close to the identity matrix, not il-conditioned.