在python中计算非常大且稀疏的邻接矩阵的所有特征值的最快方法是什么?


12

我试图找出一种比使用scipy.sparse.linalg.eigsh更快的方法来计算非常大且稀疏的邻接矩阵的所有特征值和特征向量,据我所知,此方法仅使用稀疏性和矩阵的对称属性。邻接矩阵也是二进制的,这使我认为有一种更快的方法可以实现。

我创建了一个随机的1000x1000稀疏邻接矩阵,并在x230 ubuntu 13.04笔记本电脑上比较了几种方法:

  • scipy.sparse.linalg.eigs:0.65秒
  • scipy.sparse.linalg.eigsh:0.44秒
  • scipy.linalg.eig:6.09秒
  • scipy.linalg.eigh:1.60秒

对于稀疏的eigs和eigsh,我将所需特征值和特征向量的数量k设置为矩阵的秩。

问题始于更大的矩阵-在9000x9000矩阵上,scipy.sparse.linalg.eigsh花了45分钟!


1
注意 scipy.sparse.linalg.eigsh是ARPACK
pv。

4
要进行跟进,矩阵越大,则准确计算内部特征值(即最大特征值或最小特征值)的可能性就越小。您需要从分解的矩阵中获取哪些信息?
Geoff Oxberry

1
这个问题已经在这里交叉发布。我建议关闭交叉发布的版本。
阿隆·艾玛迪亚

2
我想计算A ^ k。反思之后,我觉得这样的矩阵是更快,计算直接乘法(A 一个 A ...)Rathen市的比使用特征分解。当然,它取决于k。
Noam Peled

2
是的,直接做。本征分解的结果并不稀疏,因此您将遇到存储问题(然后,如果k足够大,则A ^ k也不是)。相关stackoverflow.com/a/9495457/424631
dranxo 2013年

Answers:


6

FILTLAN是一个C ++库,用于计算稀疏对称矩阵的内部特征值。事实上,有一个完整的软件包专用于此,这应该告诉您这是一个非常困难的问题。可以通过移位/求逆并使用Lanczos算法来找到对称矩阵的最大或最小特征值,但是频谱的中间是另一回事。如果确实要使用它,则可以使用SWIG从python调用C ++程序。

如果您的最终目标是计算矩阵的大幂,则只需计算与最大特征值相对应的特征向量即可,因为小模在获得大幂时将不再那么重要。

也就是说,直接计算能力可能确实更好。随着您计算出更高的功率,它们将越来越稀疏,这意味着要占用更多的内存。取决于有多高,您最终可能希望切换到密集矩阵。k

如果这些对您来说已经很明显了,请原谅:您可以通过告诉numpy它是由整数而不是浮点数组成的,从而利用矩阵的二进制性质,例如使用

a = np.zeros(100,dtype=np.uint)

(希望)可以节省一些空间。通过阻止矩阵乘法,可以节省时间(但不能节省内存)。假设您要计算;您计算,然后求平方得到,再求平方得到,依此类推。这样,您可以执行矩阵乘法,而不是乘法。A16A2A4A8log2kk

如果您担心速度并且拥有NVIDIA GPU,也可以探索从Python调用并行稀疏线性代数库,例如CUSP或cuSPARSE。


1

我想评论Daniel Shapero的回答,但我没有足够的SE名声。

公认的答案使我很困惑。我认为平移反转模式可以很容易地用于计算内部特征值。请参阅:https//docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

要回答最初的问题:很少需要大型稀疏矩阵的所有特征值。通常,您需要极值或一些内部值簇。在那种情况下,对于埃尔米特矩阵eigsh更快。对于非埃尔米特语的人,您将不得不与eigs。而且它们比numpy eigeigh

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.