首页 > 解决方案 > np.linalg.det() 结果与我的计算不同

问题描述

我试图了解计算行列式的工作原理。我有:

b = np.array([ [1,2,3], [2,3,4], [5 6,7] ])
np.linalg.det(b)
>>> 1.7763568394002396e-15

现在,这就是我的理解:

>>>>>>> array([[1, 2, 3],
               [2, 3, 4],
               [5, 6, 7]])
>>>>>>> |b| = |1  2  3|   = 1|3  4| - 2|2  4| + 3|2  3|
              |2  3  4|      |6  7|    |5  7|    |5  6|
              |5  6  7|
        |b|               = 1*(3*7 - 4*6) - 2*(2*7 - 4*5) + 3*(2*6 - 3*5)
        |b|               = 1*(   - 3   ) - 2*(    - 6  ) + 3*(    - 3  )    
        |b|               =   (   - 3   ) -   (    - 12 )   + (    - 9  )
        |b|               =       -3               +12             - 9     = 0      

我没有正确理解吗?

为什么在我结束时det()返回?1.770

它应该是以下内容吗?

>>>>>>> |b| = |1  2  5|   = 1|3  6| - 2|2  6| + 5|2  3|
              |2  3  6|      |4  7|    |3  7|    |3  4|
              |3  4  7|

标签: numpy

解决方案


以上评论的意思是numpy输出:

b = np.array([ [1,2,3], [2,3,4], [5,6,7] ], dtype=np.float64)
np.linalg.det(b)
>>> 1.7763568394002396e-15

可以粗略地视为与数据类型的机器精度相对应的0. +/- roundoff_errors位置roundoff_errors非常接近。实际上,它不会解析地计算行列式,而是依赖于使用 LU 分解的数值近似(如文档中所述)。我没有查看源文件来查看究竟做了什么,但它肯定可以归结为:np.finfo(np.float64).eps = 2.22e-16float64np.linalg.detbnumpy

from scipy.linalg import lu_factor
b_LU = lu_factor(b)

def lu_det(A_LU):

    # The determinant of a permutation matrix is (-1)**n where n is the number of permutations.
    # Recall a permutation matrix is a matrix with a one in each row, and column, and zeros everywhere else.
    # => if the elements of the diagonal are not 1, they will be zero, and then there has been a swap
    nswaps = len(A_LU[1]) - sum(A_LU[1]==np.arange(len(A_LU[1])))
    detP = (-1)**nswaps

    # The determinant of a triangular matrix is the product of the elements on the diagonal.
    detL = 1 # The unit diagonal elements of L are not stored.
    detU = np.prod(np.diag(A_LU[0]))
    # Matrix containing U in its upper triangle, and L in its lower triangle.

    # The determinant of a product of matrices is equal to the product of the determinant of the matrices.
    return detP * detL * detU

lu_det(b_LU)
>>> 4.4408920985006196e-17

这又是非零但确实非常接近!如果你想要一个真正的零,你可能想看看sympy符号计算,它给出了简单的:

import sympy as sp

sp.Matrix(b).det()
>>> 0

希望你现在更清楚了。


推荐阅读