检验存储在scipy稀疏矩阵中的对称矩阵的一种更好的方法是什么?

时间:2014-11-30 12:47:55

标签: python numpy scipy linear-algebra sparse-matrix

我有一个非常大的对称矩阵来存储和操作RAM(大约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)

1 个答案:

答案 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函数可以提供帮助 - 而无需深入研究文档。