python scipy.sparse.linalg.eigs 连续调用给出不同的结果

python scipy.sparse.linalg.eigs giving different results for consecutive calls

我正在尝试计算 python 中稀疏矩阵的 spectral radius。这是我的:

from scipy.sparse.linalg import eigs
from scipy import sparse

w = sparse.rand(10, 10, 0.1)
spec_radius = max(abs(eigs(w)[0]))

其中 w 的值被缩放到 [-1,1] 的范围内。但是,运行 该命令每次都会给出不同的结果:

>>> print max(abs(eigs(w)[0]))
4.51859016293e-05

>>> print max(abs(eigs(w)[0]))
4.02309443625e-06

>>> print max(abs(eigs(w)[0]))
3.7611221426e-05

什么给了?我本以为每次都会一样。我是否误解了这些命令的工作原理?

你正确地应用了这些方法,如果最大特征值的绝对值明显大于 0,它们会给出相同的结果。你观察到的结果的原因是基于算法的迭代性质,即用于确定特征值。来自 documentation:

"This function is a wrapper to the ARPACK [R209] SNEUPD, DNEUPD, CNEUPD, ZNEUPD, functions which use the Implicitly Restarted Arnoldi Method to find the eigenvalues and eigenvectors [R210]." 如果您对该算法的细节感兴趣,您可以找到解释,例如here.

与所有数值方法一样,您只能以一定的精度确定所需的值。对于显着不等于 0 的特征值,您将始终获得相同的输出;对于接近 0 的值,您可能会获得与上例中观察到的不同的值。

您可以尝试改变可以传递给 "eigs" 的参数 "maxiter" 和 "tol"(查看上面引用的文档了解详细信息)。 Maxiter 是允许的最大 Arnoldi 更新迭代次数 - 通过增加次数,您应该会获得更准确的结果。 "Tol" 是算法的特征值和停止标准的相对精度。

很抱歉在这里回答一个老问题,但另一个答案不太令人满意。

随机性不是与ARPACK捆绑在一起的算法的一部分,而是算法的初始化。从 scipy documentation 开始,初始化 v0 是随机的,除非用户指定。果然,我们看到了这一点(注意设置略有不同——w 的条目被缩放到 [0,1] 中):

import numpy
from scipy.sparse.linalg import eigs
from scipy import sparse
w = sparse.rand(10, 10, 0.1)
w = w/w.max()

如果我们不指定 v0,我们会得到一些(轻微的)随机性:

>>> print max(abs(eigs(w)[0]))
0.00024188777676476916
>>> print max(abs(eigs(w)[0]))
0.00028073646868200566
>>> print max(abs(eigs(w)[0]))
0.00025250058038424729
>>> print max(abs(eigs(w)[0]))
0.00018183677959035711

但是,如果我们指定初始化,我们总是得到相同的答案:

>>> print numpy.all([max(abs(eigs(w, v0 = numpy.ones(10))[0])) == 0.00026363015600771211 for k in range(1000)])
True