稀疏特征值:scipy.sparse.linalg.eigs比scipy.linalg.eigvals慢

Ohm*_*Ohm 5 python numpy scipy eigenvalue sparse-matrix

我有一个特殊的现象,虽然scipy.sparse.linalg.eigs对于稀疏矩阵应该更快,我得到它比正常eigvals方法运行得慢scipy:

In [4]: %timeit m.calc_pde_numerical_jacobian(m.initial_state)
10 loops, best of 3: 41.2 ms per loop

In [5]: %timeit m.calc_pde_analytic_jacobian(m.initial_state)
1000 loops, best of 3: 1.42 ms per loop

In [6]: %timeit m.calc_analytic_pde_eigs(m.initial_state)
1 loop, best of 3: 374 ms per loop

In [7]: %timeit m.calc_numeric_pde_eigs(m.initial_state)
1 loop, best of 3: 256 ms per loop 
Run Code Online (Sandbox Code Playgroud)

因此,该方法calc_pde_numerical_jacobian构造了我的方程组的雅可比行列式的密集矩阵,并且calc_pde_analytic_jacobian正在构造雅可比分析(csc格式)的稀疏矩阵.虽然分析方法在构造雅可比矩阵的稀疏矩阵方面工作得更快,但当使用scipy的特征值求解方法时,稀疏矩阵特征值方法较慢.我用来计算特征值的函数是这样的:

def calc_numeric_pde_eigs(self,state):
    return linalg.eigvals(self.calc_pde_numerical_jacobian(state))
def calc_analytic_pde_eigs(self,state):
    return sparse.linalg.eigs(self.calc_pde_analytic_jacobian(state),k=6,which='LR',return_eigenvectors=False)
Run Code Online (Sandbox Code Playgroud)

谁知道这会怎么样?

War*_*ser 2

对于足够大且稀疏的矩阵,稀疏求解器应该更快。我对范围 (150, 550, 50) 和 N = 1000 的 N 运行了以下代码片段:

In [150]: from scipy import sparse

In [151]: from scipy import linalg

[...]

In [186]: N = 150

In [187]: m = sparse.random(N, N, density=0.05).tocsc()

In [188]: a = m.A

In [189]: %timeit sparse.linalg.eigs(m, k=6, which='LR', return_eigenvectors=False)
10 loops, best of 3: 20.2 ms per loop

In [190]: %timeit linalg.eigvals(a)
100 loops, best of 3: 9.66 ms per loop
Run Code Online (Sandbox Code Playgroud)

并得到以下时间(以毫秒为单位):

N                    150   200   250   300   350   400   450   500   1000
sparse.linalg.eig   20.2  22.2  28.9  29.4  48.5  38.6  75.2   57.9   152
linalg.eigvals       9.7  17.0  24.5  37.0  52.7  63.3  82.5  105     482
Run Code Online (Sandbox Code Playgroud)

在这种情况下,稀疏求解器具有竞争力的大小是 250-300。

时间可能取决于稀疏性(即矩阵非零的百分比)以及非零元素的结构或模式。对于您的问题,稀疏求解器可能不会更好,直到矩阵大于 512x512。