Python scipy eigh(Arpack)为广义特征值问题给出错误的特征值

计算科学 Python 特征值 scipy 拉帕克
2021-12-02 16:33:19

我正在尝试使用 Arpack 解决广义特征值问题,现在代码正在使用 LAPACK,但这太慢了,我们只需要几个特征值并且矩阵是稀疏的,所以使用 Arpack 应该是要走的路。

在开始使用原始代码之前,我决定使用 Arpack (eigs) 的 scipy 包装器来测试一个简单的案例,但我得到的结果是错误的,并且每次代码运行时都会发生变化。

最小工作示例:

    import numpy as np
    from scipy.linalg import eig
    from scipy.sparse.linalg import eigs
    n = 8
    A = np.diag(np.arange(1,n+1,1.0))
    B = np.eye(n) # We want symmetric but a non-diagonal B. eigs gives correct answer for B=np.eye(n)
    B[0][n-1] = 2
    B[n-1][0] = 2


    evals,_ = eigs(A,k=3,M=B,which='LM') 
    print("The eigenvalues obtained by eigs (uses Arpack)")
    print(evals)

    print("Correct eigenvalues using eig (uses Lapack):")
    evals_l,_ = eig(A,b=B)
    print(evals_l)
```
2个回答

矩阵 B(文档中的 M)需要根据文档进行正定:“如果 sigma 为无,M 为正定”,这是对第一个要求“M 必须表示一个实数对称矩阵,如果 A 是真实的”,你的 B 遵循。当前矩阵 B 的特征值为 -1、1 和 6。因此矩阵 B 不是正定矩阵,因此 eigs 不起作用是有道理的。

相比之下,eig 的文档没有对矩阵 B 施加任何此类限制。

不是你的问题的真正答案,但已知 QZ 的 LAPACK 实现(它解决了 GEP)非常慢。我的 PR(https://github.com/Reference-LAPACK/lapack/pull/421)解决了这个问题。你可以从源代码构建我的 fork 并使用它。

在使用 MKL 时也要注意,他们出于某种原因使用阻塞因子 1 来降低 HT,这确实会影响性能。根据条目的不同,我的 PR 实现了高达 250 的加速,因此可能值得一试。