Numpy 不精确矩阵逆

Numpy 不精确矩阵逆,numpy,scipy,linear-algebra,Numpy,Scipy,Linear Algebra,在numpy中计算矩阵逆(解线性系统)时,我的精确度似乎高得令人无法接受 这是正常的不准确程度吗 如何提高此计算的准确性 另外,是否有一种方法可以在numpy或scipy中更有效地解决此系统(scipy.linalg.cho_solve似乎很有希望,但并没有达到我的目的) 在下面的代码中,cholM是一个128 x 128的矩阵。矩阵数据太大,无法包含在此处,但位于pastebin: 此外,原始向量是随机选择的,ovec,因此对于不同的ovec,精度各不相同,但在大多数情况下,误差仍然高得令

在numpy中计算矩阵逆(解线性系统)时,我的精确度似乎高得令人无法接受

  • 这是正常的不准确程度吗
  • 如何提高此计算的准确性
  • 另外,是否有一种方法可以在numpy或scipy中更有效地解决此系统(
    scipy.linalg.cho_solve
    似乎很有希望,但并没有达到我的目的)
在下面的代码中,
cholM
是一个128 x 128的矩阵。矩阵数据太大,无法包含在此处,但位于pastebin:

此外,原始向量是随机选择的,
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 )
导入numpy.random作为rnd
将numpy.linalg作为lin导入
将numpy作为np导入
cholM=np.loadtxt('cholM.txt')
dims=len(千分之一)
打印“尺寸”,变暗
ovec=rnd.normal(尺寸=dims)
rvec=np.dot(cholM.T,ovec)
invCholM=lin.inv(cholM.T)
svec=np.dot(invCholM,rvec)
svec1=lin.solve(cholM.T,rvec)
def背面_替代品(M,v):
r=np.零(len(v))
k=len(v)-1
r[k]=v[k]/M[k,k]
对于x范围内的k(len(v)-2,-1,-1):
r[k]=(v[k]-np.dot(M[k,k+1:],r[k+1:])/M[k,k]
返回r
svec2=背面替代物(cholM.T,rvec)
u、 s,v=lin.svd(cholM)
svec3=np.dot(u,np.dot(np.diag(1./s),np.dot(v,rvec)))
对于X范围内的k(dims):
打印“%20.3f%20.3f%20.3f%20.3f%”(ovec[k]-svec[k]、ovec[k]-svec1[k]、ovec[k]-svec2[k]、ovec[k]-svec3[k])
断言np.all(np.abs(ovec svec)

我们可以使用矩阵求逆来找到解向量: ... 但是,最好使用linalg.solve命令,该命令速度更快,数值更稳定

编辑-来自MATLAB的Steve Lord

为什么要反转?如果你是为了解一个系统而反转,不要-- 通常,您会希望使用反斜杠

但是,对于条件编号在1e17左右的系统(条件编号 必须大于或等于1,因此我假设中的1e-17图 你的帖子是来自RCOND的互惠条件编号)你不会 在任何情况下都能得到非常准确的结果


正如@Craig J Copi和@pv所指出的,
cholM
矩阵的精度很高,约为10^16,这表明要获得更高的反演精度,可能需要更高的数值精度


条件数可由最大奇异值与最小奇异值之比确定。在本例中,该比与特征值之比不同。

通常这是矩阵病态的标志。对于您提供的下三角矩阵,最大与最小单值之比似乎是r值(条件编号)大约是10^16。这肯定是个问题。为什么条件数在这里很重要?我在取一个逆矩阵,所以通常情况下,我会担心矩阵是否接近奇异值。
cholM
矩阵是三角形的,所以对角线上非常小的值肯定会影响解,但这不会发生。你可以尝试乘以cholM和invCholM,然后减去恒等矩阵,以确定条件数是否重要。条件数衡量的是你能得到的最大误差。因此,它无疑会对原始回代的准确性给出可靠的估计。你提供的矩阵的条件数是~1e16,而不是44.6。特征值没有t通常给出条件数,正常矩阵除外(cholM显然不是)。这里似乎有一个误解。条件数不会影响数学世界中的解;它们确实会影响计算机科学世界中的解。条件数1e16绝对是个坏消息。请确保您首先使用双精度。如果没有帮助,请使用解决同一系统的不同方法em对数值误差的敏感度可能大不相同。我所看到的反替代现象也正好出现在“不要在条件不良的情况下尝试这个”阵营中。