Numpy 计算scipy线性拟合器的特征值时出错:“;gmres没有收敛”;
我试图用Scipy解决一个大的特征值问题,其中矩阵Numpy 计算scipy线性拟合器的特征值时出错:“;gmres没有收敛”;,numpy,scipy,linear-algebra,eigenvalue,Numpy,Scipy,Linear Algebra,Eigenvalue,我试图用Scipy解决一个大的特征值问题,其中矩阵a是稠密的,但我可以计算它对向量的作用,而不必显式地组合a。因此,为了避免矩阵A变大时出现内存问题,我希望使用稀疏解算器scipy.sparse.linalg.eigs和执行此操作的LinearOperator 将eigs应用于显式numpy数组A效果良好。但是,如果我将eigs应用于LinearOperator,则迭代解算器无法收敛。即使LinearOperator的matvec方法只是将矩阵向量与给定矩阵A相乘,这也是正确的 下面附有一个说明
a
是稠密的,但我可以计算它对向量的作用,而不必显式地组合a
。因此,为了避免矩阵A变大时出现内存问题,我希望使用稀疏解算器scipy.sparse.linalg.eigs
和执行此操作的LinearOperator
将eigs
应用于显式numpy数组A
效果良好。但是,如果我将eigs
应用于LinearOperator
,则迭代解算器无法收敛。即使LinearOperator
的matvec
方法只是将矩阵向量与给定矩阵A
相乘,这也是正确的
下面附有一个说明故障的最小示例(我使用移位反转模式,因为我对最小的几个特征值感兴趣)。这可以计算随机矩阵a
的特征值,但在应用于直接从a
转换而来的LinearOperator
时失败。我试图摆弄迭代解算器的参数(v0
,ncv
,maxiter
),但没有效果
我错过了什么明显的东西吗?有没有办法让这一切顺利进行?如有任何建议,将不胜感激。非常感谢
编辑:我应该澄清我所说的“使这项工作成功”是什么意思(谢谢,迪特里希)。下面的示例使用随机矩阵进行说明。然而,在我的应用程序中,我知道特征值几乎是纯虚值(或者,如果我将矩阵乘以1j
,则几乎是纯实值)。我对10-20个最小幅值的特征值感兴趣,但如果我指定which='SM'
,则该算法的性能不好(即,即使对于较小的ish矩阵大小也不会停止)。因此,我通过传递参数sigma=0.0来使用移位反转模式,该参数为
。我很乐意尝试一种不同的方法,只要它允许我计算一组最小的幅值特征值
from scipy.sparse.linalg import eigs, LinearOperator, aslinearoperator
import numpy as np
# Set a seed for reproducibility
np.random.seed(0)
# Size of the matrix
N = 100
# Generate a random matrix of size N x N
# and compute its eigenvalues
A = np.random.random_sample((N, N))
eigvals = eigs(A, sigma=0.0, which='LM', return_eigenvectors=False)
print eigvals
# Convert the matrix to a LinearOperator
A_op = aslinearoperator(A)
# Try to solve the same eigenproblem again.
# This time it produces an error:
#
# ValueError: Error in inverting M: function gmres did not converge (info = 1000).
eigvals2 = eigs(A_op, sigma=0.0, which='LM', return_eigenvectors=False)
我尝试运行您的代码,但没有将
sigma
参数传递给eigs()
,因此运行时没有出现问题(请阅读其含义)。我在你的例子中没有看到它的好处 EIG已经可以首先找到最小的特征值。设置which='SM'Dietrich,非常感谢您的回复!我同意,从我的问题的措辞来看,“西格玛”参数的必要性并不明确。本质上,我需要它来计算使用移位反转模式的前几个最小幅值特征值。不幸的是,这意味着我不能忽略“sigma”参数,因为它会计算最大的幅值特征值。此外,简单地传递“which='SM'”是不起作用的,因为算法永远不会完成。我对问题进行了编辑以包含此信息。我不是特征值方面的专家,但我不确定你的方法是否可行:我知道的所有算法都不会以特定的顺序返回特征值,所以当你有一个特征值时,你不知道它是否是较小的一个。此外,我对gmres的了解是,它不能保证收敛,小的特征值,特别是在大矩阵中,很容易受到数值误差的影响。也许你的矩阵中有一些其他的结构(比如把它排列成带状矩阵),这可以帮助你。谢谢你的建议。我确实尝试了which='SM'(请参见对我的问题的编辑),但不幸的是,对于我的应用程序来说,它表现不好,并且计算从未完成。