[英]Complex eigenvalues computation using scipy.sparse.linalg.eigs
Given the following input numpy 2d-array A
that may be retrieved with the following link through the file hill_mat.npy
, it would be great if I can compute only a subset of its eigenvalues using an iterative solver like scipy.sparse.linalg.eigs .鉴于以下输入 numpy 二维数组
A
可以通过文件hill_mat.npy
使用以下链接检索,如果我可以使用像scipy.sparse.linalg这样的迭代求解器仅计算其特征值的子集,那就太好了。 .
First of all, a little bit of context.首先,一点上下文。 This matrix
A
results from a quadratic eigenvalue problem of size N
which has been linearized in an equivalent eigenvalue problem of double size 2*N
.该矩阵
A
来自大小为N
的二次特征值问题,该问题已在双大小2*N
的等效特征值问题中线性化。 A
has the following structure (blue color being zeroes): A
具有以下结构(蓝色为零):
plt.imshow(np.where(A > 1e-15,1.,0), interpolation='None')
and the following features:以及以下特点:
A shape = (748, 748)
A dtype = float64
A sparsity ratio = 77.64841716949297 %
The true dimensions of A
are much bigger than this small reproducible example. A
的真实尺寸比这个可重复的小例子大得多。 I expect the real sparsity ratio and shape to be close to 95%
and (5508, 5508)
for this case.在这种情况下,我预计实际稀疏率和形状接近
95%
和(5508, 5508)
。
The resulting eigenvalues of A
are complex (which come in complex conjugate pairs) and I am more interested in the ones with the smallest imaginary part in modulus. A
的结果特征值是复数(以复共轭对的形式出现),我对模数虚部最小的那些更感兴趣。
Problem : when using direct solver:问题:使用直接求解器时:
w_dense = np.linalg.eigvals(A)
idx = np.argsort(abs(w_dense.imag))
w_dense = w_dense[idx]
calculation times become rapidly prohibitive.计算时间迅速变得令人望而却步。 I am thus looking to use a sparse algorithm:
因此,我希望使用稀疏算法:
from scipy.sparse import csc_matrix, linalg as sla
w_sparse = sla.eigs(A, k=100, sigma=0+0j, which='SI', return_eigenvectors=False)
but it seems that ARPACK doesn't find any eigenvalues this way.但似乎 ARPACK 没有以这种方式找到任何特征值。 From thescipy/arpack tutorial , when looking for small eigenvalues like
which = 'SI'
, one should use the so-called shift-invert mode by specifying sigma
kwarg, ie in order for the algorithm to know where it could expect to find these eigenvalues.从scipy/arpack 教程中,当寻找像
which = 'SI'
这样的小特征值时,应该通过指定sigma
kwarg 来使用所谓的移位反转模式,即为了让算法知道它可以在哪里找到这些特征值。 Nonetheless, all of my attempts did not yield any results...尽管如此,我所有的尝试都没有产生任何结果......
Could someone more experienced with this function give me a hand in order to make this work?有没有对这个 function 更有经验的人帮我完成这项工作?
Here follows a whole code snippet:下面是一个完整的代码片段:
import numpy as np
from matplotlib import pyplot as plt
from scipy.sparse import csc_matrix, linalg as sla
A = np.load('hill_mat.npy')
print('A shape =', A.shape)
print('A dtype =', A.dtype)
print('A sparsity ratio =',(np.product(A.shape) - np.count_nonzero(A)) / np.product(A.shape) *100, '%')
# quick look at the structure of A
plt.imshow(np.where(A > 1e-15,1.,0), interpolation='None')
# direct
w_dense = np.linalg.eigvals(A)
idx = np.argsort(abs(w_dense.imag))
w_dense = w_dense[idx]
# sparse
w_sparse = sla.eigs(csc_matrix(A), k=100, sigma=0+0j, which='SI', return_eigenvectors=False)
Problem finally solved, I guess I should have read the documentation more carefully, but yet, the following is quite counter-intuitive and could be better emphasized in my opinion:问题终于解决了,我想我应该更仔细地阅读文档,但是,以下内容非常违反直觉,我认为可以更好地强调:
... ARPACK contains a mode that allows a quick determination of non-external eigenvalues: shift-invert mode .
... ARPACK 包含一种允许快速确定非外部特征值的模式:移位反转模式。 As mentioned above, this mode involves transforming the eigenvalue problem to an equivalent problem with different eigenvalues.
如上所述,这种模式涉及将特征值问题转换为具有不同特征值的等价问题。 In this case, we hope to find eigenvalues near zero, so we'll choose
sigma = 0
.在这种情况下,我们希望找到接近零的特征值,因此我们将选择
sigma = 0
。 The transformed eigenvalues will then satisfy转换后的特征值将满足
, so our small eigenvalues
,所以我们的小特征值
become large
变大
eigenvalues.
特征值。
This way, when looking for small eigenvalues, in order to help LAPACK do the work, one should activate shift-invert mode by specifying an appropriate sigma
value while also reversing the desired specified subset specified in the which
keyword argument.这样,当寻找小的特征值时,为了帮助 LAPACK 完成工作,应该通过指定适当的
sigma
值来激活移位反转模式,同时反转在which
关键字参数中指定的所需指定子集。
Thus, it is simply a matter of executing:因此,只需执行以下操作:
w_sparse = sla.eigs(csc_matrix(A), k=100, sigma=0+0j, which='LM', return_eigenvectors=False, maxiter=2000)
idx = np.argsort(abs(w_sparse.imag))
w_sparse = w_sparse[idx]
Therefore, I can only hope this mistake help someone else:)因此,我只能希望这个错误对其他人有所帮助:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.