Find out if matrix is positive definite with numpy Find out if matrix is positive definite with numpy numpy numpy

Find out if matrix is positive definite with numpy


You can also check if all the eigenvalues of matrix are positive, if so the matrix is positive definite:

import numpy as npdef is_pos_def(x):    return np.all(np.linalg.eigvals(x) > 0)


You could try computing Cholesky decomposition (numpy.linalg.cholesky). This will raise LinAlgError if the matrix is not positive definite.


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 matrixA = 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.