英文:
Iteration count in Scipy's Implicitly Restarted Arnoldi Method
问题
我试图获得在找到矩阵的`k`个最小特征值之前需要的迭代次数。尽管Scipy可以很容易地找到特征值,但我没有找到一种可以轻松获取所需迭代次数的方法。
在如下的代码块中,我认为将变量*i*中的计数器添加进去会解决我的问题,但这不可能是真的,因为*i*可能大于maxiter,这是一个明显的矛盾。
```python
import scipy.sparse.linalg._eigen.arpack as bark
#%%
def ct(v):
return np.conj(v.T)
def eigsb(A, k=6, M=None, sigma=None, which='LM', v0=None,
ncv=None, maxiter=None, tol=0, return_eigenvectors=True,
Minv=None, OPinv=None, OPpart=None):
n = A.shape[0]
mode = 1
M_matvec = None
Minv_matvec = None
matvec = bark._aslinearoperator_with_dtype(A).matvec
params = bark._UnsymmetricArpackParams(n, k, A.dtype.char, matvec, mode,
M_matvec, Minv_matvec, sigma,
ncv, v0, maxiter, which, tol)
i=0
while not params.converged:
params.iterate()
i=i+1
return i,params.extract(return_eigenvectors)
###制作Hermitian矩阵
d = 50
mat = np.random.rand(d,d)+ 1j * (np.random.rand(d,d))
mat = mat - (np.random.rand(d,d)+ 1j * (np.random.rand(d,d)))
mat = mat + ct(mat)
###
i,(vals, vecs) = eigsb(mat, k=1, which='SR', ncv=6, maxiter=50)
是否有其他方法我应该尝试?或者是否有关于计数i和我没有看到的真正迭代值之间的转换?
<details>
<summary>英文:</summary>
I'm trying to get a number of iterations needed until convergence for finding the `k` smallest eigenvalues of a matrix. While scipy can find the eigenvalues without much difficulty, there's no way that I see to easily get out the number of iterations needed.
In the code block as shown, my thought was that the addition of the counter in variable *i* would solve my problem, but this can't be the case as *i* can be greater than maxiter, a clear contradiction.
import scipy.sparse.linalg._eigen.arpack as bark
#%%
def ct(v):
return np.conj(v.T)
def eigsb(A, k=6, M=None, sigma=None, which='LM', v0=None,
ncv=None, maxiter=None, tol=0, return_eigenvectors=True,
Minv=None, OPinv=None, OPpart=None):
n = A.shape[0]
mode = 1
M_matvec = None
Minv_matvec = None
matvec = bark._aslinearoperator_with_dtype(A).matvec
params = bark._UnsymmetricArpackParams(n, k, A.dtype.char, matvec, mode,
M_matvec, Minv_matvec, sigma,
ncv, v0, maxiter, which, tol)
i=0
while not params.converged:
params.iterate()
i=i+1
return i,params.extract(return_eigenvectors)
###Make Herimtian Matrix
d = 50
mat = np.random.rand(d,d)+ 1j * (np.random.rand(d,d))
mat = mat - (np.random.rand(d,d)+ 1j * (np.random.rand(d,d)))
mat = mat + ct(mat)
i,(vals, vecs) = eigsb(mat, k=1, which='SR', ncv=6, maxiter=50)
Is there a different way I should be going about this? Or is there some conversion between the count *i* and the true iteration value I'm not seeing?
</details>
# 答案1
**得分**: 1
tol在这里起到了作用。我尝试将tol设置为非零正值,无论d或maxiter的值如何,它都会迭代相同的次数。尝试将tol设置为非零正值并检查。
参考链接:
https://sisl.readthedocs.io/en/v0.9.2/_modules/scipy/sparse/linalg/eigen/arpack/arpack.html
```python
class IterInv(LinearOperator):
"""
IterInv:
辅助类,使用迭代方法重复解决M*x=b。
"""
def __init__(self, M, ifunc=gmres, tol=0):
if tol <= 0:
# 当tol=0时,ARPACK使用由LAPACK的_LAMCH函数计算的机器精度。
# 我们应该匹配这个值。
tol = 2 * np.finfo(M.dtype).eps
tol: float,可选
特征值的相对精度(停止准则)
默认值0表示机器精度。
英文:
It appears to me that tol is playing a role here. I tried setting non-zero positive value for tol and it iterates exactly same number of times regardless of value of d or maxiter. Try setting tol as non-zero positive and check.
Reference :
https://sisl.readthedocs.io/en/v0.9.2/_modules/scipy/sparse/linalg/eigen/arpack/arpack.html
class IterInv(LinearOperator):
"""
IterInv:
helper class to repeatedly solve M*x=b
using an iterative method.
"""
def __init__(self, M, ifunc=gmres, tol=0):
if tol <= 0:
# when tol=0, ARPACK uses machine tolerance as calculated
# by LAPACK's _LAMCH function. We should match this
tol = 2 * np.finfo(M.dtype).eps
tol : float, optional
Relative accuracy for eigenvalues (stopping criterion)
The default value of 0 implies machine precision.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论