Python 如何优化三对角矩阵的特征值/向量计算

Python 如何优化三对角矩阵的特征值/向量计算,python,numpy,scipy,Python,Numpy,Scipy,我试图优化我对三对角矩阵的特征值/向量的计算。我的代码目前运行大约需要30秒,我需要它运行得更快,大约1秒。我目前正在使用这种方法来寻找特征值/向量,但我相信应该有其他更快的方法。我将在下面发布我的代码,以便更容易看到我正在尝试做什么。任何建议都是非常欢迎的,如果有任何不清楚的地方请告诉我 H = (dx**-2)*diags([-1, 2, -1], [-1, 0, 1], shape=(N, N)) H = sp.lil_matrix(H) H[0,0]=0.5*H[

我试图优化我对三对角矩阵的特征值/向量的计算。我的代码目前运行大约需要30秒,我需要它运行得更快,大约1秒。我目前正在使用这种方法来寻找特征值/向量,但我相信应该有其他更快的方法。我将在下面发布我的代码,以便更容易看到我正在尝试做什么。任何建议都是非常欢迎的,如果有任何不清楚的地方请告诉我

    H = (dx**-2)*diags([-1, 2, -1], [-1, 0, 1], shape=(N, N))
    H = sp.lil_matrix(H)
    H[0,0]=0.5*H[0,0]
    H[N-1,N-1]=0.5*H[N-1,N-1]
    lam, phi = eigsh(H, 400, which="SM")

你不太可能找到一个简单的方法来将计算速度提高30倍。从中的计时可以看出,即使是谷歌令人印象深刻的优化了的
jax
库,也只能比
scipy
中的基本SVD实现略低3倍的加速。由于对称矩阵的奇异值分解等价于
eigsh
,因此我们可以预期
eigsh
的加速比充其量也大致相同

因此,即使是谷歌也无法将计算速度提高那么多,至少在传统方式下是如此

然而,对于非常大的稀疏矩阵,有专门的随机算法,可以在适当的情况下以更大的因子加速。其中一个具有
sklearn
实现:。(我相信这是基于所描述的算法,也可能与
algorithm='randomized'
时相同)

下面是示例的一个稍加修改的版本,展示了如何使用它:

from scipy.sparse import diags, lil_matrix
from scipy.sparse.linalg import eigsh

from sklearn.utils.extmath import randomized_svd

N = 3200
k = 400
dx = 1.0

H = (dx**-2)*diags([-1, 2, -1], [-1, 0, 1], shape=(N, N))
H = lil_matrix(H)
H[0, 0] = 0.5*H[0, 0]
H[N-1, N-1] = 0.5*H[N-1, N-1]
# lam, phi = eigsh(H, k, which="SM")

U, s, V = randomized_svd(H, k)
此处,
s
包含奇异值(此处等效于特征值),
U
V
包含奇异向量(此处等效于特征向量)。理论上,如果
H
是对称矩阵,
U
应该与
V.T
相同。我没有发现这个例子是这样的,这让我有点困惑。。。但我还是要继续发布这篇文章,因为这实际上只需要大约一秒钟的时间,所以对你来说可能是一个解决方案

然而还有一个大警告。您正在将
which=“SM”
传递给
eigsh
,据我所知,这意味着您要求的是400个最小特征值。这真的是你想要的吗?在我所知道的几乎所有应用中,您都需要400个最大特征值。如果事实上你真的想要400个最小的特征值,那么这是行不通的,因为它依赖于这样一个事实,即最大的特征值更容易通过随机矩阵投影得到


结果是,您需要测试它,看看它是否真的给出了您可以使用的结果。但考虑到您目前为止对问题的看法,这是一个有趣的可能解决方案。

N的值是多少?@bnaecker这里N是3200