[英]scipy eigh gives negative eigenvalues for positive semidefinite matrix
我有一些问题scipy的eigh
函数返回正半定矩阵的负特征值。 以下是MWE。
hess_R
函数返回正半定矩阵(它是秩1矩阵和对角矩阵的总和,两者都具有非负条目)。
import numpy as np
from scipy import linalg as LA
def hess_R(x):
d = len(x)
H = np.ones(d*d).reshape(d,d) / (1 - np.sum(x))**2
H = H + np.diag(1 / (x**2))
return H.astype(np.float64)
x = np.array([ 9.98510710e-02 , 9.00148922e-01 , 4.41547488e-10])
H = hess_R(x)
w,v = LA.eigh(H)
print w
印刷的特征值是
[ -6.74055241e-271 4.62855397e+016 5.15260753e+018]
如果我更换np.float64
与np.float32
在return语句hess_R
我得到
[ -5.42905303e+10 4.62854925e+16 5.15260506e+18]
相反,所以我猜这是一种精确的问题。
有没有办法来解决这个问题? 从技术上讲,我不需要使用eigh,但我认为这是我的其他错误的根本问题(取这些矩阵的平方根,得到NaN等)
我认为问题在于你已经达到了浮点精度的极限。 对于线性代数结果来说,一个很好的经验法则是它们对于float32来说大约是10 ^ 8中的一个部分,对于浮动64来说它们在10 ^ 16中大约是一个部分。看起来你的最小到最大的比例这里的特征值小于10 ^ -16。 因此,返回的值实际上不可信,并且取决于您使用的特征值实现的详细信息。
例如,这里有四种不同的求解器; 看看他们的结果:
# using the 64-bit version
for impl in [np.linalg.eig, np.linalg.eigh, LA.eig, LA.eigh]:
w, v = impl(H)
print(np.sort(w))
reconstructed = np.dot(v * w, v.conj().T)
print("Allclose:", np.allclose(reconstructed, H), '\n')
输出:
[ -3.01441754e+02 4.62855397e+16 5.15260753e+18]
Allclose: True
[ 3.66099625e+02 4.62855397e+16 5.15260753e+18]
Allclose: True
[ -3.01441754e+02+0.j 4.62855397e+16+0.j 5.15260753e+18+0.j]
Allclose: True
[ 3.83999999e+02 4.62855397e+16 5.15260753e+18]
Allclose: True
请注意,他们都同意较大的两个特征值,但最小特征值的值从实现变为实现。 尽管如此,在所有四种情况下,输入矩阵可以重建为64位精度:这意味着算法按预期运行,直到达到它们可用的精度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.