在numpy中計算矩陣求逆(求解線性系統)時,我得到了看似不可接受的高誤差。Numpy不準確的矩陣求逆
- 這是不正常的正常水平?
- 如何提高此計算的準確性?
- 此外,有沒有辦法更有效地解決這個系統在numpy或scipy(
scipy.linalg.cho_solve
似乎很有前途,但沒有做我想要的)?
在下面的代碼中,cholM
是一個128 x 128矩陣。矩陣數據太大而不能包含在這裏,但位於pastebin:cholM.txt。
此外,原始矢量ovec
是隨機選擇的,因此對於不同的ovec
的準確度會有所不同,但是對於大多數情況下,錯誤仍然看起來高得令人無法接受。
編輯使用奇異值分解求解系統產生的誤差明顯低於其他方法。
import numpy.random as rnd
import numpy.linalg as lin
import numpy as np
cholM=np.loadtxt('cholM.txt')
dims=len(cholM)
print 'Dimensions',dims
ovec=rnd.normal(size=dims)
rvec=np.dot(cholM.T,ovec)
invCholM=lin.inv(cholM.T)
svec=np.dot(invCholM,rvec)
svec1=lin.solve(cholM.T,rvec)
def back_substitute(M,v):
r=np.zeros(len(v))
k=len(v)-1
r[k]=v[k]/M[k,k]
for k in xrange(len(v)-2,-1,-1):
r[k]=(v[k]-np.dot(M[k,k+1:],r[k+1:]))/M[k,k]
return r
svec2=back_substitute(cholM.T,rvec)
u,s,v=lin.svd(cholM)
svec3=np.dot(u,np.dot(np.diag(1./s),np.dot(v,rvec)))
for k in xrange(dims):
print '%20.3f%20.3f%20.3f%20.3f'%(ovec[k]-svec[k],ovec[k]-svec1[k],ovec[k]-svec2[k],ovec[k]-svec3[k])
assert np.all(np.abs(ovec-svec)<1e-5)
assert np.all(np.abs(ovec-svec1)<1e-5)
通常情況下,這是一個跡象,表明您的矩陣病態。對於您提供的下三角矩陣,似乎最大奇異值與最小奇異值的比值(條件號)大約爲10^16。這絕對是一個問題。 –
爲什麼條件號碼在這裏?我正在採取逆向行動,所以通常情況下,如果矩陣接近單數,我會擔心。 'cholM'矩陣是三角形的,所以對角線上的非常小的值肯定會影響解,但這不會發生。 – user1149913
您可以嘗試乘以cholM和invCholM,然後減去單位矩陣以說服您自己條件數是否重要 –