我试图用python解决大对称稀疏矩阵的特征值问题。我的主要关注点是结构动力学,因此我处理质量和刚度矩阵,并且通常在计算第一个“K”特征值(> 0)时进行调整。目前我已经尝试过scipy.sparse.linalg函数eigsh和lobpcg。我做了以下测试:
from pyamg.gallery import poisson
N = 300
K = 9
A = poisson((N,N), format='csr') # <90000x90000 sparse matrix with 448800
# stored elements in CSR format>
首先我尝试了scipy.sparse.linalg.eigsh(我寻找0附近的特征值,因此:sigma = 0):
from scipy.sparse.linalg import eigsh
W, V = eigsh(A=A, k=K, sigma=0, tol=1e-8)
%timeit -n10 eigsh(A=A, k=K, sigma=0, tol=1e-8
# Result: 10 loops, best of 3: 2.42 s per loop
结果:
W =数组([0.00021787,0.00054466,0.00054466,0.00087145, 0.00108927, 0.00108927,0.00141606,0.00141606,0.00185164])
接下来,我尝试了scipy.sparse.linalg.lobpcg
from scipy.sparse.linalg import lobpcg
W2, V2 = lobpcg(A, X, tol=1e-8, largest=False, maxiter=1000)
然而,整个1000次迭代(时间= 171.66秒)得到:
W2 =数组([0.00021787,0.00054466,0.00054466,0.00087145, 0.00108927, 0.00108927,0.00141606,0.00141606,0.00185166])
Afterwars我尝试使用预处理器来更快地解决逆迭代。我使用了pyamg.smoothed_aggregation_solver
# create the AMG hierarchy
ml = smoothed_aggregation_solver(A)
# initial approximation to the K eigenvectors
X = scipy.rand(A.shape[0], K)
# preconditioner based on ml
M = ml.aspreconditioner()
并且在这种情况下,lobpcg收敛得更快(31次迭代):
W3 ,V3 = lobpcg(A, X, M=M, tol=1e-8, largest=False, maxiter=1000)
%timeit -n10 eigsh(A=A, k=K, sigma=0, tol=1e-8, maxiter=1000)
# Result: 10 loops, best of 3: 4.45 s per loop
结果与eigsh相同:
W3 =数组([0.00021787,0.00054466,0.00054466,0.00087145, 0.00108927,0.00108927,0.00141606,0.00141606,0.00185164])
Afterwars,我也试过了一个预处理的eigsh,必须计算OPinv。然而,计算矩阵的逆矩阵会耗费大量时间并且效率低下。
所以我的问题是,如果有更快/更有效的方法来计算python中的特征问题(对于大型稀疏矩阵)?我已经阅读了一些有关petsc(petsc4py)和pysparse的内容,但尚未尝试过。