Python 用numpy找出矩阵是否是正定的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16266720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:10:03  来源:igfitidea点击:

Find out if matrix is positive definite with numpy

pythonmatrixnumpyscipy

提问by Zygimantas Gatelis

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 help.

我需要找出矩阵是否为正定。我的矩阵是 numpy 矩阵。我期待在 numpy 库中找到任何相关的方法,但没有成功。我很感激任何帮助。

采纳答案by Akavall

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

您还可以检查矩阵的所有特征值是否为正,如果是,则矩阵是正定的:

import numpy as np

def is_pos_def(x):
    return np.all(np.linalg.eigvals(x) > 0)

回答by NPE

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

您可以尝试计算 Cholesky 分解 ( numpy.linalg.cholesky)。LinAlgError如果矩阵不是正定的,这将提高。

回答by InfiniteLooper

I don't know why the solution of NPE is so underrated. It's the best way to do this. I've found on Wkipediathat the complexity is cubic.

我不知道为什么 NPE 的解决方案被如此低估。这是最好的方法。我在维基百科上发现复杂度是三次的。

Furthermore, there it is said that it's more numerically stable than the Lu decomposition. And the Lu decomposition is more stable than the method of finding all the eigenvalues.

此外,据说它比 Lu 分解在数值上更稳定。并且Lu分解比求所有特征值的方法更稳定。

And, it is a very elegant solution, because it's a fact :

而且,这是一个非常优雅的解决方案,因为这是一个事实:

A matrix has a Cholesky decomposition if and only if it is symmetric positive.

矩阵具有 Cholesky 分解当且仅当它是对称正的。

So why not using maths ? Maybe some people are affraid of the raise of the exception, but it'a fact too, it's quite useful to program with exceptions.

那么为什么不使用数学呢?可能有些人害怕抛出异常,但事实也是如此,用异常编程是很有用的。

回答by Martin Wang

For a real matrix $A$, we have $x^TAx=\frac{1}{2}(x^T(A+A^T)x)$, and $A+A^T$ is symmetric real matrix. So $A$ is positive definite iff $A+A^T$ is positive definite, iff all the eigenvalues of $A+A^T$ are positive.

对于实矩阵 $A$,我们有 $x​​^TAx=\frac{1}{2}(x^T(A+A^T)x)$,而 $A+A^T$ 是对称实矩阵. 所以 $A$ 是正定的,当仅当 $A+A^T$ 是正定的,当所有的 $A+A^T$ 的特征值都是正的。

import numpy as np

def is_pos_def(A):
    M = np.matrix(A)
    return np.all(np.linalg.eigvals(M+M.transpose()) > 0)

回答by MarcoMag

To illustrate @NPE's answer with some ready-to-use code:

用一些现成的代码来说明@NPE 的答案:

import numpy as np

def is_pd(K):
    try:
        np.linalg.cholesky(K)
        return 1 
    except np.linalg.linalg.LinAlgError as err:
        if 'Matrix is not positive definite' in err.message:
            return 0
        else:
            raise 

回答by Daniel Garza

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).

对于实矩阵,np.linalg.cholesky 中正特征值和正前导项的检验仅适用于矩阵对称的情况。因此,首先需要测试矩阵是否对称,然后应用其中一种方法(正特征值或 Cholesky 分解)。

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:

矩阵 A 不是对称的,但特征值是正的,Numpy 返回一个错误的 Cholesky 分解。您可以检查:

chol_A.dot(chol_A.T)

is different than A.

与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:

您还可以检查上面的所有 python 函数是否对“正定性”测试为阳性。如果您尝试使用 Cholesky 分解来计算逆,这可能是一个严重的问题,因为:

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

您可能希望将上面函数中的 np.array_equal(A, AT) 替换为 np.allclose(A, AT) 以避免由于浮点错误引起的差异。