python - 寻找大稀疏矩阵的最小特征向量,在 SciPy 中比在 Octave 中慢 100 倍以上

标签 python scipy octave sparse-matrix eigenvector

我正在尝试计算几个 (5-500) 特征向量,这些特征向量对应于大型对称方形稀疏矩阵(高达 30000x30000)的最小特征值,其中非零值小于 0.1%。

我目前在 shift-invert 模式 (sigma=0.0) 下使用 scipy.sparse.linalg.eigsh,我通过有关该主题的各种帖子发现这是首选解决方案。但是,在大多数情况下,解决问题最多需要 1 小时。另一方面,如果我要求最大的特征值(在我的系统上为亚秒),则该函数非常快,这是文档中预期的。

由于我在工作中更熟悉 Matlab,所以我尝试在 Octave 中解决这个问题,使用 eigs (sigma=0) 在短短几秒钟内(低于 10 秒)给了我相同的结果。由于我想对包括特征向量计算在内的算法进行参数扫描,因此在 python 中也能获得这种时间增益。

我首先更改了参数(尤其是容差),但在时间尺度上并没有太大变化。

我在 Windows 上使用 Anaconda,但试图将 scipy 使用的 LAPACK/BLAS(这是一个巨大的痛苦)从 mkl(默认 Anaconda)切换到 OpenBlas(根据文档由 Octave 使用),但看不到变化表现。

我无法弄清楚,使用的 ARPACK 是否有改变(以及如何改变)?

我将以下代码的测试用例上传到以下 dropbox 文件夹:
https://www.dropbox.com/sh/l6aa6izufzyzqr3/AABqij95hZOvRpnnjRaETQmka?dl=0

在 Python 中

import numpy as np
from scipy.sparse import csr_matrix, csc_matrix, linalg, load_npz   
M = load_npz('M.npz')
evals, evecs = linalg.eigsh(M,k=6,sigma=0.0)

在 Octave :
M=dlmread('M.txt');
M=spconvert(M);
[evecs,evals] = eigs(M,6,0);

任何帮助是appriciated !

我根据评论和建议尝试了一些其他选项:

Octave :eigs(M,6,0)eigs(M,6,'sm')给我同样的结果:
[1.8725e-05 1.0189e-05 7.5622e-06 7.5420e-07 -1.2239e-18 -2.5674e-16]

eigs(M,6,'sa',struct('tol',2))收敛到
[1.0423 2.7604 6.1548 11.1310 18.0207 25.3933] 

快得多,但前提是容差值大于 2,否则它根本不会收敛并且值相差很大。

Python:eigsh(M,k=6,which='SA')eigsh(M,k=6,which='SM')两者都不收敛(未达到收敛的 ARPACK 错误)。只有 eigsh(M,k=6,sigma=0.0)给出一些特征值(大约一个小时后),对于最小的特征值与 Octave 不同(甚至发现了 1 个额外的小值):
[3.82923317e-17 3.32269886e-16 2.78039665e-10 7.54202273e-07 7.56251500e-06 1.01893934e-05]

如果容差足够高,我也可以从 eigsh(M,k=6,which='SA',tol='1') 得到结果。 , 接近其他获得的值
[4.28732218e-14 7.54194948e-07 7.56220703e-06 1.01889544e-05, 1.87247350e-05 2.02652719e-05]

再次使用不同数量的小特征值。计算时间仍然接近30分钟。
虽然不同的非常小的值可能是可以理解的,因为它们可能代表 0 的倍数,不同的多重性让我感到困惑。

此外,SciPy 和 Octave 似乎存在一些根本差异,但我还无法弄清楚。

最佳答案

我知道这现在已经过时了,但我遇到了同样的问题。您是否在这里评论 ( https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html )?

似乎当您将 sigma 设置为低数 (0) 时,您应该设置 which='LM',即使您想要低值。这是因为设置 sigma 会将您想要的值(在这种情况下为低)转换为高,因此您仍然可以利用“LM”方法,这些方法可以更快地获得所需的值(低特征值) )。

关于python - 寻找大稀疏矩阵的最小特征向量,在 SciPy 中比在 Octave 中慢 100 倍以上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59416098/

相关文章:

c - 有没有一种方法可以将 graph500 生成的位图文件读取为图形文件?

python - 使用 pyinstaller 打包一个 twistd 插件

python - 无法弄清楚如何写入 csv

python - 使用 pyarrow 按大小重新分区 pyarrow 表并写入多个 Parquet 文件?

python - PYQT5 中的布局大小

python - 将默认值设置为稀疏 scipy 矩阵

python - 重新排列 linregress python 中的标题

python - 为 solve_ivp 传递参数(新的 SciPy ODE API)

octave - 如何在 GNU Octave 中查看函数体

algorithm - 遗传算法中的错误( Octave )