微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我正在尝试针对三对角矩阵的特征值/向量优化我的计算。我的代码目前大约需要30秒才能运行,而我需要更快地运行(大约1秒)。我目前正在使用scipy.sparse.linalg.eigsh方法来查找特征值/向量,但我认为应该有其他方法来加快速度。我将在下面发布我的代码,这样可以更轻松地了解我要执行的操作。任何建议都将受到欢迎,如果有任何不清楚的地方,请告诉我。

    H = (dx**-2)*diags([-1,2,-1],[-1,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倍的简单方法。从this post的时序中可以看到,即使Google出色地优化的jax库也仅比scipy中基本SVD实现的管理速度少了3倍。由于SVD对于对称矩阵等效于eigsh,因此我们可以期望eigsh的加速率最多大约相同。

因此,即使是Google,也至少以传统方式无法加快计算速度。

但是,对于非常大的稀疏矩阵,有专门的随机算法,可以在适当的情况下以更大的因数加快处理速度。其中之一具有sklearn实现:sklearn.utils.extmath.randomized_svd。 (我相信它是基于here描述的算法,并且在algorithm='randomized'时也可能与sklearn.decomposition.TruncatedSVD相同。)

这是您的示例的略微修改版本,显示了如何使用它:

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,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包含奇异值(此处等于特征值),UV包含奇异矢量(此处等同于特征矢量)。从理论上讲,如果H是对称矩阵,则U应该与V.T相同。我发现本例并非如此,这让我有些疑惑...但是我还是继续将其发布,因为实际上这大约需要一秒钟,因此可能是一个解决方案为你。

但是,还有另外一个警告。您正在将which="SM"传递给eigsh,据我了解,这意味着您要索取400个最小的特征值。那真的是你想要的吗?在我所知道的几乎所有应用程序中,您都需要400个最大特征值。如果实际上您确实确实想要400个最小的特征值,那么这将不起作用,因为它依赖于这样一个事实,即使用随机矩阵投影更容易哄骗最大的特征值。

结果是,您将需要对此进行测试,以查看它是否确实提供了可以使用的结果。鉴于您到目前为止对问题的评价,这是一个有趣的解决方案。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。