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
中输出值 b
对 A
中矩阵值微小变化的敏感度的度量(有点像广义的衍生物)。较大的值表示 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.
我一直面临一个有趣的 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
中输出值 b
对 A
中矩阵值微小变化的敏感度的度量(有点像广义的衍生物)。较大的值表示 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.