Skip to main content
 首页 » 编程设计

python之使用 Python/Scipy 对角化大型稀疏矩阵

2025年05月04日7lyj

我正在处理一个大型(复杂的)Hermitian 矩阵,我正在尝试使用 Python/Scipy 有效地对角化它。

使用 scipy.linalg 中的 eigh 函数,大约需要 3 秒的时间来生成大约 800x800 的矩阵并对其进行对角化,并计算所有特征值和特征向量。

我的问题中的特征值围绕 0 对称分布,范围大致从 -4 到 4。不过,我只需要与负特征值对应的特征向量,这会将我要计算的范围变成 [-4,0 ).

我的矩阵是稀疏的,所以很自然地使用 scipy.sparse 包及其函数通过 eigsh 计算特征向量,因为它使用更少的内存来存储矩阵。

我还可以通过 which='SA' 告诉程序只计算负特征值。这种方法的问题是,现在大约需要 40 秒来计算一半的特征值/特征向量。我知道,ARPACK 算法在计算小特征值时效率非常低,但我想不出任何其他方法来计算我需要的所有特征向量。

有什么办法可以加快计算速度吗?也许使用 shift-invert 模式?我将不得不做很多很多对角化并最终增加矩阵的大小,所以我现在有点迷茫。

如果有任何帮助,我将不胜感激!

请您参考如下方法:

这个问题最好在 http://scicomp.stackexchange.com 上提问因为它更像是一个一般的数学问题,而不是特定于 Scipy 或与编程相关的问题。

如果您需要所有特征向量,那么使用 ARPACK 就没有多大意义。由于您需要 N/2 个特征向量,因此您的内存要求至少是 N*N/2 float ;并且可能在实践中更多。使用 eigh 需要 N*N+3*N float 。 eigh 与最低要求相差 2 倍以内,因此最简单的解决方案是坚持使用它。

如果您可以“在线”处理特征向量,以便在处理下一个之前丢弃前一个,则还有其他方法;查看 scicomp 上类似问题的答案。