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
对于PSD矩阵,可以使用scipy/numpy的eigh()检查所有特征值是否为非负。
>> E,V = scipy.linalg.eigh(np.zeros((3,3)))
>> E
array([ 0., 0., 0.])
但是,您很可能会遇到数值稳定性问题。
要克服这些问题,可以使用以下函数。
def isPSD(A, tol=1e-8):
E = np.linalg.eigvalsh(A)
return np.all(E > -tol)
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)
如果使用正定(PD)矩阵,Cholesky分解是一个很好的选择。
但是,它在正半定(PSD)矩阵上抛出以下错误, 说
对于PSD矩阵,可以使用scipy/numpy的eigh()检查所有特征值是否为非负。
但是,您很可能会遇到数值稳定性问题。 要克服这些问题,可以使用以下函数。
它在矩阵上返回
True
,该矩阵在给定公差范围内近似为PSD。我假设你已经知道你的矩阵是对称的。
一个很好的确定性测试(实际上是标准测试!)试图计算它的Cholesky因子分解。如果你的矩阵是正定的,它就成功了。
这是最直接的方法,因为它需要O(n^3)运算(用一个小常数),而且您至少需要n个矩阵向量乘法来“直接”测试。
A
非常大,检查对称矩阵A
的整个特征值是否为非负是很耗时的,而模块scipy.sparse.linalg.arpack
提供了一个很好的解决方案,因为可以通过指定参数自定义返回的特征值。(有关详细信息,请参见^{我们知道如果
A
谱的两端都是非负的,那么剩余的特征值也必须是非负的。所以我们可以这样做:因此,我们只需要计算两个特征值来检查PSD,我认为这对于大型
A
非常有用相关问题 更多 >
编程相关推荐