![](/img/trans.png)
[英]Sparse eigenvalues : scipy.sparse.linalg.eigs is slower than scipy.linalg.eigvals
[英]Complex eigenvalues computation using scipy.sparse.linalg.eigs
鑒於以下輸入 numpy 二維數組A
可以通過文件hill_mat.npy
使用以下鏈接檢索,如果我可以使用像scipy.sparse.linalg這樣的迭代求解器僅計算其特征值的子集,那就太好了。 .
首先,一點上下文。 該矩陣A
來自大小為N
的二次特征值問題,該問題已在雙大小2*N
的等效特征值問題中線性化。 A
具有以下結構(藍色為零):
plt.imshow(np.where(A > 1e-15,1.,0), interpolation='None')
以及以下特點:
A shape = (748, 748)
A dtype = float64
A sparsity ratio = 77.64841716949297 %
A
的真實尺寸比這個可重復的小例子大得多。 在這種情況下,我預計實際稀疏率和形狀接近95%
和(5508, 5508)
。
A
的結果特征值是復數(以復共軛對的形式出現),我對模數虛部最小的那些更感興趣。
問題:使用直接求解器時:
w_dense = np.linalg.eigvals(A)
idx = np.argsort(abs(w_dense.imag))
w_dense = w_dense[idx]
計算時間迅速變得令人望而卻步。 因此,我希望使用稀疏算法:
from scipy.sparse import csc_matrix, linalg as sla
w_sparse = sla.eigs(A, k=100, sigma=0+0j, which='SI', return_eigenvectors=False)
但似乎 ARPACK 沒有以這種方式找到任何特征值。 從scipy/arpack 教程中,當尋找像which = 'SI'
這樣的小特征值時,應該通過指定sigma
kwarg 來使用所謂的移位反轉模式,即為了讓算法知道它可以在哪里找到這些特征值。 盡管如此,我所有的嘗試都沒有產生任何結果......
有沒有對這個 function 更有經驗的人幫我完成這項工作?
下面是一個完整的代碼片段:
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)
問題終於解決了,我想我應該更仔細地閱讀文檔,但是,以下內容非常違反直覺,我認為可以更好地強調:
... ARPACK 包含一種允許快速確定非外部特征值的模式:移位反轉模式。 如上所述,這種模式涉及將特征值問題轉換為具有不同特征值的等價問題。 在這種情況下,我們希望找到接近零的特征值,因此我們將選擇
sigma = 0
。 轉換后的特征值將滿足,所以我們的小特征值
變大
特征值。
這樣,當尋找小的特征值時,為了幫助 LAPACK 完成工作,應該通過指定適當的sigma
值來激活移位反轉模式,同時反轉在which
關鍵字參數中指定的所需指定子集。
因此,只需執行以下操作:
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]
因此,我只能希望這個錯誤對其他人有所幫助:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.