sra*_*mij 10 python math matrix linear-algebra scipy
我想用Python检查矩阵是正定的还是正半定的.
我怎样才能做到这一点?SciPy中是否有针对该模块或其他模块的专用功能?
Ale*_* C. 16
我假设你已经知道你的矩阵是对称的.
对正定性的一个很好的测试(实际上是标准的!)是试图计算其Cholesky分解.如果你的矩阵是正定的,它就会成功.
这是最直接的方式,因为它需要O(n ^ 3)运算(具有小常数),并且您需要至少n个矩阵向量乘法来"直接"测试.
Tom*_*oim 10
如果您使用正定(PD)矩阵,Cholesky分解是一个不错的选择.
但是,它会在正半无限(PSD)矩阵上抛出以下错误,比方说,
A = np.zeros((3,3)) // the all-zero matrix is a PSD matrix
np.linalg.cholesky(A)
LinAlgError: Matrix is not positive definite -
Cholesky decomposition cannot be computed
Run Code Online (Sandbox Code Playgroud)
对于PSD矩阵,您可以使用scipy/numpy的eigh()来检查所有特征值是否为非负的.
>> E,V = scipy.linalg.eigh(np.zeros((3,3)))
>> E
array([ 0., 0., 0.])
Run Code Online (Sandbox Code Playgroud)
但是,您很可能会遇到数值稳定性问题.要克服这些,您可以使用以下功能.
def isPSD(A, tol=1e-8):
E = np.linalg.eigvalsh(A)
return np.all(E > -tol)
Run Code Online (Sandbox Code Playgroud)
在大约PSD到达给定容差的矩阵上返回True.
A如果A非常大,检查对称矩阵的整个特征值是否为非负很耗时,而该模块scipy.sparse.linalg.arpack提供了一个很好的解决方案,因为可以通过指定参数来自定义返回的特征值。(Scipy.sparse.linalg.arpack更多信息请参阅)
我们知道,如果 的谱的两端A都是非负的,那么其余的特征值也一定是非负的。所以我们可以这样做:
from scipy.sparse.linalg import arpack
def isPSD(A, tol = 1e-8):
vals, vecs = arpack.eigsh(A, k = 2, which = 'BE') # return the ends of spectrum of A
return np.all(vals > -tol)
Run Code Online (Sandbox Code Playgroud)
通过这个我们只需要计算两个特征值来检查PSD,我认为这对于大 A