将稀疏矩阵转换为密集并获得完整的特征值

时间:2017-10-16 12:05:38

标签: python c++ matrix

最近我正在处理一个需要的问题 对角化巨大的厄米特矩阵以获得所有特征值。 目前我正在使用Mathematica来完成这项工作。

但由于内存的限制,它不适用 当矩阵大小接近(2 ^ 15,2 ^ 15)时,对角化成本约为32 GB内存。

我尝试通过从mathematica导入矩阵来尝试使用python,

import numpy as np
from scipy.io import mmread
from scipy.sparse import csc_matrix

#importing sparse matrix to save space
h = mmread("h.mtx")
h = csc_matrix(h)
#diagonlizing the dense one
ev = np.linalg.eigvalsh(h.todense())

它可以工作但不幸的是比Mathematica慢一个数量级。

那么,有没有其他可能的解决方案,比如C ++?

我对C ++一无所知,所以我想最简单的方法就是导入 矩阵到C ++和对角化。

谢谢!

2 个答案:

答案 0 :(得分:1)

使用此矩阵运行一些初步测试:

http://math.nist.gov/MatrixMarket/data/NEP/h2plus/qc2534.html

我确定转换为密集不会占用大部分时间。特征值计算确实如此。

Numpy使用高度优化的Lapack例程进行计算。这些与您在C ++中使用的相同。因此C ++不会给你太多的加速。如果你想加速使用稀疏性作为属性,可以转到更好的计算机或切换到分布式矩阵存储(这里很多人工)。

P.S:如果你为大学项目这样做,你可能想看看你的大学是否有某种类型的集群。群集节点通常具有大量内存。如果没有,请检查amazon的AWS EC2或googles计算引擎以获取具有批量ram的实例。

编辑:

Wolfram表示Mathematica在幕后所做的事情:http://reference.wolfram.com/language/tutorial/LinearAlgebraAppendix.html#83486633

Arpack是一个(arnoldi)子空间求解器,只给出最高或最低的k-特征值,ATLAS只是一个Lapack实现,其余的似乎是用于求解线性系统。

所有给出完全特征谱的方法都需要NxN矩阵的矩阵分解。如果你只想要k个向量,有一些方法可以将它简化为k x k矩阵的分解。

Arpack(http://slepc.upv.es/或MKL附带的现代替代品)有现代替代品,但它们都为您提供子空间。

答案 1 :(得分:0)

c ++无济于事。 在python中,您可以轻松地委托给C ++,并且很多scipy例程都可以做到这一点(性能)。我还期望,如果你只对特征值线进行计时,你将获得与Matematica类似的性能,并且性能的差异来自于读取数据。

最好的解决方案是寻找更合适的算法,可能是直接对稀疏矩阵进行操作,或者将原始分解为较小的矩阵并将它们组合起来。

为了使原始解决方案更容易处理,您可以尝试增加交换空间量。在linux中它是一个专用分区,在windows中它是一个设置。这应该允许Matematica / python使用更多的内存,但由于内存垃圾,它会慢得多。获得一个SSD来加速这种设置,但请注意,由于经常写入,它会被更快地销毁。或者甚至更好地购买更多内存。