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