我一直在使用不同的方法来计算矩阵的秩和矩阵方程组的解。我遇到了功能linalg.svd。与我自己用高斯消除法求解系统的努力相比,它看起来既更快又更精确。我试图了解这是怎么可能的。
据我所知,linalg.svd函数使用QR算法来计算矩阵的特征值。我知道这在数学上是如何工作的,但是我不知道Numpy如何如此迅速地做到这一点而又不会损失太多精度。
所以我的问题是:numpy.svd函数如何工作,更具体地说,如何快速,准确地实现它(与高斯消去相比)?
我一直在使用不同的方法来计算矩阵的秩和矩阵方程组的解。我遇到了功能linalg.svd。与我自己用高斯消除法求解系统的努力相比,它看起来既更快又更精确。我试图了解这是怎么可能的。
据我所知,linalg.svd函数使用QR算法来计算矩阵的特征值。我知道这在数学上是如何工作的,但是我不知道Numpy如何如此迅速地做到这一点而又不会损失太多精度。
所以我的问题是:numpy.svd函数如何工作,更具体地说,如何快速,准确地实现它(与高斯消去相比)?
Answers:
您的问题中有很多问题。
不要使用高斯消除(LU分解)来计算矩阵的数字等级。 为此,LU分解在浮点运算中是不可靠的。而是使用显示排名的QR分解(例如xGEQPX
或xGEPQY
在LAPACK中,其中x是C,D,S或Z,尽管这些例程很难追踪;请参阅JedBrown对相关问题的回答),或使用SVD (奇异值分解,例如xGESDD
或xGESVD
,其中x还是C,D,S或Z)。SVD是确定数字等级的更准确,可靠的算法,但它需要更多的浮点运算。
但是,对于求解线性系统,LU分解(具有部分枢转,这是LAPACK中的标准实现)在实践中非常可靠。在某些病理学情况下,带有部分枢轴的LU分解不稳定(请参阅数值线性代数中的第22讲)详见Trefethen和Bau)。QR分解是解决线性系统的更稳定的数值算法,这可能就是为什么它可以为您提供如此精确的结果。但是,对于平方矩阵,与LU因式分解相比,它需要更多的浮点运算2倍(我相信; JackPoulson可能会对此进行纠正)。对于矩形系统,QR分解是一个更好的选择,因为它将为超定线性系统提供最小二乘解。SVD也可以用于求解线性系统,但是它将比QR分解昂贵。
janneb是正确的,numpy.linalg.svd是xGESDD
LAPACK中的包装器。奇异值分解分为两个阶段。首先,将要分解的基质还原为对角线形式。在LAPACK中用于简化为对角线形式的算法可能是Lawson-Hanson-Chan算法,并且确实在一点上使用QR分解。Trefethen和Bau 在数值线性代数中的第31讲对此过程进行了概述。然后,xGESDD
使用分治法从双对角矩阵计算奇异值和左右奇异向量。要获得此步骤的背景知识,您需要查阅Golub和Van Loan撰写的Matrix Computations或Jim Demmel撰写的Applied Applied Linear Linear Algebra。
最后,您不应将奇异值与特征值混淆。这两组数量不相同。SVD计算矩阵的奇异值。克里夫·莫勒尔的数值计算与MATLAB给出了一个奇异值和特征值之间的差异很好的概述。通常,给定矩阵的奇异值与其特征值之间没有明显的关系,除非是正常矩阵,其中奇异值是特征值的绝对值。
rank
函数中使用SVD )。使用这两种方法时,都需要一点谨慎。在SVD方法中,数字等级是高于指定(通常很小)的临界值的奇异值的数量。(QR方法类似,但是用R矩阵的对角线条目替换奇异值。)
numpy.linalg.svd是来自LAPACK的{Z,D} GESDD的包装。反过来,LAPACK是由数字线性代数的世界上最杰出的专家精心编写的。确实,如果一个不熟悉该领域的人成功击败LAPACK(无论是速度还是准确性),这将是非常令人惊讶的。
至于为什么QR优于高斯消除,那可能更适合/scicomp//
dgesdd
用于实值SVD。因此,您真正的问题可能是“ Lapack dgesdd如何工作?”,这与stackoverflow无关。