40,000 * 40,000
),所以我使用 scispy.sparse 格式来存储它的一半,下面是我的代码
import numpy as np
from scipy.sparse import coo_matrix
def to_sparse(W):
tmp = np.tril(W)
del W
return coo_matrix(tmp)
然后我想根据公式W
计算L = D - W
(对称的)的拉普拉斯矩阵(其中D
是对角线矩阵,其对角线是W
的cols或行的总和,根据L
的定义,我需要检查它是否为正半定(PSD)或不。
但似乎计算以稀疏格式存储的'L'
的特征值不等于原始问题,所以我必须将L
转换为密集格式,然后检查? 我的问题:如果不将L
转换回密集矩阵,有没有更好的方法来实现这一目标?
以下是生成L
并检查PSD的代码:
from scipy.sparse import diags
from numpy import linalg
def gen_D(W):
# W is sparse matrix
tmp = W.sum(axis = 0)
tmp2 = W.sum(axis = 1).T - W.diagonal()
return np.squeeze(np.asarray(tmp + tmp2))
def gen_laplacian(W):
D = gen_D(W)
return diags(D, 0).tocoo() - W
def check_PSD(L):
origin_L = L.todense() + L.T.todense() - np.diag(L.diagonal())
E, V = linalg.eigh(origin_L)
return np.all(E > -1e-10)
我很抱歉在上传之前我没有检查代码示例,现在我已经修复了错误,下面就是一个例子:
W = np.random.random_integers(1, 100, size = (100, 100))
W = .5 * (W + W.T)
W = to_sparse(W)
L = gen_laplacian(W)
答案 0 :(得分:0)
原始数组是否已经稀疏(大量零),或者只是tril
的产品?如果是后者,则可能无法通过使用稀疏代码来节省空间或时间。例如
def gen1(W):
tmp = np.tril(W)
d = tmp.sum(0)+tmp.sum(1)-tmp.diagonal()
return np.diag(d) - tmp
对于此100x100测试,比gen_laplacian(to_sparse(W))
快8倍。
def check(L):
oL = L+L.T-np.diag(L.diagonal())
E, V = linalg.eigh(oL)
return np.all(E > -1e-10)
即使check(L.A)
也快2倍。
但是你需要构建orginal_L
吗?看起来linalg.eigh(L.A)
生成相同的东西,因为the calculation is done with the lower triangular part
。并非构建orginal_L
需要花费很多时间。
但测试问题的症结在于sparse.linalg
函数如eigsh
是否会产生与eigh
等价的东西。
我不太了解那些eigh
函数可以提供帮助 - 而无需深入研究文档。