Skip to main content
 首页 » 编程设计

python之矩阵乘以逆不产生身份

2025年05月04日13powertoolsteam

我正在尝试使用 np.linalg.inv() 函数查找给定矩阵的逆矩阵。 inv 生成一个看起来不错的矩阵,但是当尝试将原始矩阵乘以逆矩阵时,输出不是逆矩阵定义所假设的恒等式。

from numpy.linalg import inv 
 
M = np.random.random((4, 4)) 
Mi = inv(M) 
I = M @ Mi # using matrix multiplication operator 
I.astype(int) #as the output looks like 2.77555756e-17 
 
>>> array([[0, 0, 0, 0], 
           [0, 0, 0, 0], 
           [0, 0, 0, 0], 
           [0, 0, 0, 1]]) 

这显然不是身份(多次运行时给出的答案略有不同)

请您参考如下方法:

先尝试四舍五入,然后再转换为 int。

np.around(I).astype(int) 

创建一个随机矩阵:

>>> M = np.random.random((4,4)) 
>>> M 
array([[0.51351957, 0.57864882, 0.0489495 , 0.85066216], 
       [0.60052988, 0.93844708, 0.74651889, 0.17237584], 
       [0.26191596, 0.46451226, 0.46514401, 0.81917544], 
       [0.19247662, 0.82801899, 0.83839146, 0.08531949]]) 

取反:

>>> from numpy.linalg import inv 
>>> Mi = inv(M) 
>>> Mi 
array([[-1.3515514 ,  3.53647196,  1.0391335 , -3.64654487], 
       [ 2.76188122, -2.23981308, -2.74634579,  3.35680468], 
       [-2.44320291,  1.47102487,  2.36135635, -1.28451339], 
       [ 0.2533113 , -0.69591469,  1.10498293, -0.00818495]]) 

现在,M 和 Mi 的乘积应该是恒等式。

>>> M @ Mi 
array([[ 1.00000000e+00, -4.44089210e-16, -1.11022302e-16, -6.93889390e-18], 
       [-4.16333634e-17,  1.00000000e+00, -8.32667268e-17, -8.60856525e-17], 
       [ 5.55111512e-17, -2.22044605e-16,  1.00000000e+00, -1.57859836e-16], 
       [ 6.24500451e-17, -8.32667268e-17, -2.35922393e-16, 1.00000000e+00]]) 

但这显然不是身份。但如果仔细观察,对角线值非常接近 1,而所有其他值都是非常小的数字(几乎为零),例如 -16 或 -17指数。

这个错误是因为浮点值从来都不是精确值,它们总是有一些错误。看看文章15. Floating Point Arithmetic: Issues and Limitations和 Is floating point math broken? .

现在,如果我们只是将它转换为 int,它很可能仍然不是一个恒等式。因为一个真正接近 1 的值,它实际上可能比 1 小一点,导致在转换为 int 时为 0。

>>> (M @ Mi).astype(int) 
array([[1, 0, 0, 0], 
       [0, 0, 0, 0], 
       [0, 0, 1, 0], 
       [0, 0, 0, 0]]) 

但如果在转换为 int 之前先对其进行舍入,您将获得一个恒等式。

>>> np.around(M @ Mi).astype(int) 
array([[1, 0, 0, 0], 
       [0, 1, 0, 0], 
       [0, 0, 1, 0], 
       [0, 0, 0, 1]])