我發現scipy.linalg.eig有時會給出不一致的結果。但不是每次。numpy/scipy eigendecompositions的不穩定結果
>>> import numpy as np
>>> import scipy.linalg as lin
>>> modmat=np.random.random((150,150))
>>> modmat=modmat+modmat.T # the data i am interested in is described by real symmetric matrices
>>> d,v=lin.eig(modmat)
>>> dx=d.copy()
>>> vx=v.copy()
>>> d,v=lin.eig(modmat)
>>> np.all(d==dx)
False
>>> np.all(v==vx)
False
>>> e,w=lin.eigh(modmat)
>>> ex=e.copy()
>>> wx=w.copy()
>>> e,w=lin.eigh(modmat)
>>> np.all(e==ex)
True
>>> e,w=lin.eigh(modmat)
>>> np.all(e==ex)
False
雖然我不是最偉大的線性代數嚮導,我不明白,是特徵分解本質上受到怪異的舍入誤差,但我不明白爲什麼重複計算會導致不同的值。但我的結果和可重複性是不同的。
問題的本質究竟是什麼 - 好的,有時結果是可以接受的不同,有時它們不是。以下是一些示例:
>>> d[1]
(9.8986888573772465+0j)
>>> dx[1]
(9.8986888573772092+0j)
〜3e-13的上述差異似乎並不是什麼大問題。相反,真正的問題(至少對於我現在的項目來說)是某些特徵值似乎無法在正確的符號上達成一致。
>>> np.all(np.sign(d)==np.sign(dx))
False
>>> np.nonzero(np.sign(d)!=np.sign(dx))
(array([ 38, 39, 40, 41, 42, 45, 46, 47, 79, 80, 81, 82, 83,
84, 109, 112]),)
>>> d[38]
(-6.4011617320002525+0j)
>>> dx[38]
(6.1888785138080209+0j)
在MATLAB中的類似的代碼似乎沒有這個問題。
(+1)有趣的... – NPE
我試圖重現此使用NumPy的1.6.1/SciPy的0.10.1,但不能。 – NPE
我使用numpy 1.6.1和scipy 0.10.0。另外,當我沒有使用copy()時,我無法產生這個錯誤(但它確實存在於我的大型應用程序中,其中類似於copy()的事情正在進行)。這並不意味着太多,因爲它的意思是不一致的。 – aestrivex