Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在构造稀疏矩阵后,从稀疏到稠密再到稀疏的转换会降低密度_Python_Matrix_Scipy_Sparse Matrix - Fatal编程技术网

Python 在构造稀疏矩阵后,从稀疏到稠密再到稀疏的转换会降低密度

Python 在构造稀疏矩阵后,从稀疏到稠密再到稀疏的转换会降低密度,python,matrix,scipy,sparse-matrix,Python,Matrix,Scipy,Sparse Matrix,我正在使用scipy生成一个稀疏有限差分矩阵,首先从块矩阵构造它,然后编辑对角线以考虑边界条件。生成的稀疏矩阵为BSR类型。我发现,如果我使用scipy.sparse.BSR\u matrix函数将矩阵转换为稠密矩阵,然后再转换回稀疏矩阵,我将得到比以前更稀疏的矩阵。以下是我用来生成矩阵的代码: size = (4,4) xDiff = np.zeros((size[0]+1,size[0])) ix,jx = np.indices(xDiff.shape) xDiff[ix==jx] = 1

我正在使用scipy生成一个稀疏有限差分矩阵,首先从块矩阵构造它,然后编辑对角线以考虑边界条件。生成的稀疏矩阵为BSR类型。我发现,如果我使用
scipy.sparse.BSR\u matrix
函数将矩阵转换为稠密矩阵,然后再转换回稀疏矩阵,我将得到比以前更稀疏的矩阵。以下是我用来生成矩阵的代码:

size = (4,4)

xDiff = np.zeros((size[0]+1,size[0]))
ix,jx = np.indices(xDiff.shape)
xDiff[ix==jx] = 1
xDiff[ix==jx+1] = -1

yDiff = np.zeros((size[1]+1,size[1]))
iy,jy = np.indices(yDiff.shape)
yDiff[iy==jy] = 1
yDiff[iy==jy+1] = -1

Ax = sp.sparse.dia_matrix(-np.matmul(np.transpose(xDiff),xDiff))
Ay = sp.sparse.dia_matrix(-np.matmul(np.transpose(yDiff),yDiff))

lap = sp.sparse.kron(sp.sparse.eye(size[1]),Ax) + sp.sparse.kron(Ay,sp.sparse.eye(size[0]))

#set up boundary conditions
BC_diag = np.array([2]+[1]*(size[0]-2)+[2]+([1]+[0]*(size[0]-2)+[1])*(size[1]-2)+[2]+[1]*(size[0]-2)+[2])

lap += sp.sparse.diags(BC_diag)
如果我检查该矩阵的稀疏性,我会看到以下内容:

lap
<16x16 sparse matrix of type '<class 'numpy.float64'>'
with 160 stored elements (blocksize = 4x4) in Block Sparse Row format>
lap
但是,如果我将其转换为密集矩阵,然后返回到相同的稀疏格式,我会看到一个更稀疏的矩阵:

sp.sparse.bsr_matrix(lap.todense())
<16x16 sparse matrix of type '<class 'numpy.float64'>'
with 64 stored elements (blocksize = 1x1) in Block Sparse Row format>
sp.sparse.bsr\u矩阵(lap.todense())

我怀疑发生这种情况的原因是因为我使用sparse.kron函数构造了矩阵,但我的问题是,如果我最终想要模拟一个非常大的域,是否有办法在不首先转换为稠密的情况下得到较小的稀疏矩阵。

[我被告知我的答案不正确。如果我理解的话,原因是Scipy没有使用Lapack创建矩阵,而是使用自己的代码来创建矩阵。有趣的是,这些信息虽然出乎意料,但具有权威性。我将服从它

[我会将答案张贴以供参考,但不再断言答案是正确的。]

一般来说,当涉及到像稀疏矩阵这样的复杂数据结构时,有两种情况:

  • 建造商提前知道结构的全部内容;或
  • 结构设计为逐步建造,以便只有在结构完成后才能知道结构的全部内容
  • 复杂数据结构的典型例子是二叉树。在二叉树完成后,可以通过复制它来提高效率。否则,树的标准红黑实现会留下一些搜索路径,长度是其他路径的两倍,这通常是正常的,但不是最优的

    现在,您可能知道所有这些,但我提到它是有原因的。Scipy依赖于Lapack。Lapack带来了几种不同的存储方案。其中两种是

    • 一般稀疏和
    • 带状

    方案。Scipy似乎是从将矩阵存储为稀疏开始的,其中每个非零元素的索引都显式存储;但在复制时,Scipy注意到,带状表示更适合于矩阵,毕竟是带状的。

    BSR
    将数据存储在密集块中:

    In [167]: lap.data.shape                                                        
    Out[167]: (10, 4, 4)
    
    在这种情况下,这些块有相当多的零

    In [168]: lap1 = lap.tocsr() 
    In [170]: lap1                                                                  
    Out[170]: 
    <16x16 sparse matrix of type '<class 'numpy.float64'>'
        with 160 stored elements in Compressed Sparse Row format>
    In [171]: lap1.data                                                             
    Out[171]: 
    array([-2.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  1., -3.,  1.,  0.,  0.,
            1.,  0.,  0.,  0.,  1., -3.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,
            1., -2.,  0.,  0.,  0.,  1.,  1.,  0.,  0.,  0., -3.,  1.,  0.,
            0.,  1.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  1., -4.,  1.,  0., 
            ...
            0.,  0.,  1., -2.])
    

    注意blocksize的变化。在第二种情况下,大小是1x1。我想知道
    lap.tocsr()
    也会做同样的事情。我没有太多使用BSR,但我认为它将块存储为密集数组。啊哈,我有一个否决票。我的答案不正确吗?我想知道。如果答案是错误的,我很乐意删除,但据我所知答案是正确的。
    scipy.sparse
    没有使用Lapack创建矩阵。它它有自己的代码,是Python和cython的混合体。
    In [172]: lap1.eliminate_zeros()                                                
    In [173]: lap1                                                                  
    Out[173]: 
    <16x16 sparse matrix of type '<class 'numpy.float64'>'
        with 64 stored elements in Compressed Sparse Row format>
    
    In [181]: lap2 = sparse.kron(np.eye(size[1]),Ax,format='csr') + sparse.kron(Ay,n
         ...: p.eye(size[0]), format='csr')                                         
    In [182]: lap2                                                                  
    Out[182]: 
    <16x16 sparse matrix of type '<class 'numpy.float64'>'
        with 64 stored elements in Compressed Sparse Row format>