Find out if matrix is positive definite with numpy

后端 未结 8 2171
慢半拍i
慢半拍i 2020-12-23 13:40

I need to find out if matrix is positive definite. My matrix is numpy matrix. I was expecting to find any related method in numpy library, but no success. I appreciate any

8条回答
  •  眼角桃花
    2020-12-23 13:44

    There seems to be a small confusion in all of the answers above (at least concerning the question).

    For real matrices, the tests for positive eigenvalues and positive-leading terms in np.linalg.cholesky only applies if the matrix is symmetric. So first one needs to test if the matrix is symmetric and then apply one of those methods (positive eigenvalues or Cholesky decomposition).

    For example:

    import numpy as np
    
    #A nonsymmetric matrix
    A = np.array([[9,7],[6,14]])
    
    #check that all eigenvalues are positive:
    np.all(np.linalg.eigvals(A) > 0)
    
    #take a 'Cholesky' decomposition:
    chol_A = np.linalg.cholesky(A)
    

    The matrix A is not symmetric, but the eigenvalues are positive and Numpy returns a Cholesky decomposition that is wrong. You can check that:

    chol_A.dot(chol_A.T)
    

    is different than A.

    You can also check that all the python functions above would test positive for 'positive-definiteness'. This could potentially be a serious problem if you were trying to use the Cholesky decomposition to compute the inverse, since:

    >np.linalg.inv(A)
    array([[ 0.16666667, -0.08333333],
       [-0.07142857,  0.10714286]])
    
    >np.linalg.inv(chol_A.T).dot(np.linalg.inv(chol_A))
    array([[ 0.15555556, -0.06666667],
       [-0.06666667,  0.1       ]])
    

    are different.

    In summary, I would suggest adding a line to any of the functions above to check if the matrix is symmetric, for example:

    def is_pos_def(A):
        if np.array_equal(A, A.T):
            try:
                np.linalg.cholesky(A)
                return True
            except np.linalg.LinAlgError:
                return False
        else:
            return False
    

    You may want to replace np.array_equal(A, A.T) in the function above for np.allclose(A, A.T) to avoid differences that are due to floating point errors.

提交回复
热议问题