我正在处理一个大的(复杂的)Hermitian矩阵,我正在尝试使用Python / Scipy有效地对它进行对角化。
使用eigh
中的scipy.linalg
函数生成大约800x800矩阵并对角化大约需要3秒,并计算所有特征值和特征向量。
我的问题中的特征值对称分布在0左右,范围从大约-4到4.我只需要对应于负特征值的特征向量,这会将我想要计算的范围变为[-4,0] )。
我的矩阵是稀疏的,所以使用scipy.sparse
包及其函数通过eigsh
来计算特征向量是很自然的,因为它使用更少的内存来存储矩阵。
此外,我可以告诉程序只通过which='SA'
计算负特征值。这种方法的问题是,现在需要大约40秒来计算特征值/特征向量的一半。我知道,ARPACK算法在计算小特征值时非常低效,但我想不出任何其他方法来计算我需要的所有特征向量。
有什么方法可以加快计算速度吗?也许使用shift-invert模式?我将不得不做很多很多对角化,并最终增加矩阵的大小,所以我现在有点迷失。
我真的很感激任何帮助!
答案 0 :(得分:1)
这个问题可能更好地问http://scicomp.stackexchange.com,因为它更像是一般的数学问题,而不是特定于Scipy或与编程有关。
如果您需要所有特征向量,使用ARPACK没有多大意义。由于您需要N / 2个特征向量,因此您的内存要求至少为N*N/2
个浮点数;并且可能在实践中更多。使用eigh
需要N*N+3*N
个浮点数。 eigh
因此与最低要求相差2倍,因此最简单的解决方案就是坚持下去。
如果你可以处理特征向量"在线"这样你就可以在处理下一个之前扔掉前一个,还有其他方法;看看关于scicomp的类似问题的答案。