numpy中矩阵求逆的复杂性


11

我正在解决需要对稠密平方矩阵求逆的微分方程。这种矩阵求反消耗了我的大部分计算时间,所以我想知道我是否正在使用最快的算法。

我当前的选择是numpy.linalg.inv。从我的数字中,我看到它的缩放比例为,其中n是行数,因此该方法似乎是高斯消除法。Øñ3

根据维基百科,有更快的算法可用。有谁知道是否有一个实现这些的库?

我想知道,为什么不用numpy使用这些更快的算法?


您需要先执行矩阵。看Scipy。稀疏为您提供帮助。它包含您需要的许多工具。
Tobal

@Tobal不确定我会遵循...您将如何“执行”矩阵?究竟有什么scipy.sparse帮助?
GoHokies,2016年

@GoHokies scipy是numpy的补充。在进行一些计算之前,必须很好地实现密集/稀疏矩阵,它可以改善您的计算。请阅读此docs.scipy.org/doc/scipy/reference/sparse.html,它的英语不好,比我解释得更好。
Tobal

@Tobal这个问题专门针对稠密矩阵,所以我看不出scipy.sparse这有什么关系?
克里斯蒂安·克拉森

2
@Tobal-我想我还是不明白。您“对矩阵进行预设置”到底是什么意思,并且“在进行一些计算之前必须很好地实现矩阵”?关于您的最后评论,您肯定会同意可用于稀疏和密集矩阵的技术有很大不同。
Wolfgang Bangerth '02

Answers:


21

(评论时间太长了...)

我假设您实际上需要在算法中计算逆。1首先,重要的是要注意,这些替代算法实际上并没有声称具有更快的速度,只是它们具有更好的渐近复杂度(这意味着所需的基本运算数量增长得较慢)。实际上,实际上,由于以下原因,这些方法实际上比标准方法(对于给定的)要得多。ñ

  1. 所述 -notation兽皮中的功率的前面的恒定,其可以是大天文数字-如此之大,可以比小得多任何该在可预见的将来可以由任何计算机处理。(例如,Coppersmith–Winograd算法就是这种情况。)ØñC1个ñ3C2ñ2。Xñ

  2. 复杂性假定每个(算术)运算都花费相同的时间-但这在实际实践中远非如此:将一堆数字与相同的数字相乘比将相同数量的不同数字相乘要快得多。这是由于以下事实:当前计算的主要瓶颈是将数据放入缓存,而不是对该数据进行实际的算术运算。因此,可以重新安排为具有第一种情况的算法(称为“ 缓存感知”)将比不可能的算法快得多。(例如,Strassen算法就是这种情况。)

同样,数值稳定性至少与性能同样重要。在这里,通常,标准方法通常会胜出。

因此,标准的高性能库(BLAS / LAPACK,当您要求Numpy计算逆时会调用Numpy)通常仅实现此方法。当然,那里有Numpy的实现,例如Strassen算法,但是在汇编级别手动调整的算法将大大击败写在任何合理的矩阵大小的高级语言算法。Øñ3Øñ2。X


1但如果我没有指出这真的很少需要的话,我会感到不对:每当您需要计算乘积,您都应该求解线性系统(例如,使用),并使用代替-这是更稳定的,并且可以做(取决于基质的结构)快。如果需要多次使用,则可以预先计算的因式分解(通常是求解中最昂贵的部分),并在以后重用。一种-1个b一种X=bnumpy.linalg.solveX一种一种-1个一种


很好,谢谢您,先生,特别是您指出了细节上的魔鬼(以O表示的常量),这在理论速度和实用速度之间产生了很大的差异。
华丽的

我认为应该更多地强调“很少需要逆”部分。如果目的是解决微分方程组,则似乎不需要完全逆。
Jared Goguen '16

@o_o好吧,这是我的第一个原始评论(在将它们全部合并为一个答案后将其删除)。但是我认为,为了站点(和以后的读者)的利益,即使答案背后存在XY问题,答案也应回答该问题中的实际问题(既合理又在主题上)。另外,我也不想听起来太劝诫...
Christian Clason

1
如我所写,几乎在所有情况下,您都可以重写算法,以通过求解相应的线性系统(或在这种情况下,线性系统的序列)来代替涉及逆运算的运算-如果您有兴趣,可以询问一个有关(“可以避免在此算法中求矩阵求逆吗?”)。是的,因为矩阵的数量不取决于,所以复杂度仍然是相同的(您只是获得了一个更大的常数-在您的情况下为四分之一)。ñ
克里斯蒂安·克拉森

1
@Heisenberg:取决于的结构-LU ,Cholesky甚至QR分解作品。要点(在任何数字线性代数中都是如此)是,与计算分解相比,应用分解便宜,因此您只需进行一次分解,然后进行多次分解。一种
克里斯蒂安·克拉森

4

您可能应该注意到,埋入numpy源代码的深处(请参阅https://github.com/numpy/numpy/blob/master/numpy/linalg/umath_linalg.c.src),inv例程会尝试调用dgetrf函数从系统LAPACK程序包中执行,然后对原始矩阵执行LU分解。从道德上讲,这等效于高斯消除,但是可以通过在高性能BLAS中使用更快的矩阵乘法算法将其调整为稍微降低的复杂度。

如果您遵循这种方法,则应警告您,强迫整个库链使用新库,而不是与发行版一起提供的系统库相当复杂。现代计算机系统上的一种替代方法是使用scaLAPACK或(在python世界中)petsc4py之类的程序包研究并行化方法。但是,与应用于直接方法相比,这些方法通常更适合用作线性代数系统的迭代求解器,而在特定目标稀疏系统中,PETSc比适用于直接方法更有效。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.