稀疏对角块中的稀疏对角矩阵

时间:2019-05-25 16:51:10

标签: python scipy sparse-matrix

我想要一个稀疏A矩阵B,其中m x mn = m * m稀疏矩阵,B

我知道如何制作 data = np.vstack([-np.ones(n), 4 * np.ones(n), -np.ones(n)]) diag = np.array([-1, 0, 1]) B = scipy.sparse.spdiags(data, diag, m, m).tocsr()

I

,当然还有如何标识A。不知何故,我不能做同样的事情来制作B

我知道如何以一种愚蠢的方式进行操作:将A中的所有数字替换为A,并用与B相同的方式用5个对角线使scipy.sparse被制造。但是我确实相信matplotlib.widgets可以做到这一点。

我已经花了两个小时考虑它,也许找到一个更简单的方法是不值得的。

1 个答案:

答案 0 :(得分:1)

我发现了一个sparse.block_diag函数。

In [383]: n,m=3,3                                                                                        
In [385]: data = np.vstack([-np.ones(n), 4 * np.ones(n), -np.ones(n)]).astype(int) 
     ...: diag = np.array([-1, 0, 1]) 
     ...: B = sparse.spdiags(data, diag, m, m).tocsr()                                                   
In [386]: B                                                                                              
Out[386]: 
<3x3 sparse matrix of type '<class 'numpy.int64'>'
    with 7 stored elements in Compressed Sparse Row format>
In [387]: B.A                                                                                            
Out[387]: 
array([[ 4, -1,  0],
       [-1,  4, -1],
       [ 0, -1,  4]], dtype=int64)
In [388]: I = -sparse.eye(m).astype(int)   

block_diag没有偏移功能,因此我首先将BI组合成一个较大的块。

In [389]: M1 = sparse.bmat([[B,I],[I,B]])                                                                
In [390]: M1                                                                                             
Out[390]: 
<6x6 sparse matrix of type '<class 'numpy.int64'>'
    with 20 stored elements in COOrdinate format>
In [391]: M1.A                                                                                           
Out[391]: 
array([[ 4, -1,  0, -1,  0,  0],
       [-1,  4, -1,  0, -1,  0],
       [ 0, -1,  4,  0,  0, -1],
       [-1,  0,  0,  4, -1,  0],
       [ 0, -1,  0, -1,  4, -1],
       [ 0,  0, -1,  0, -1,  4]], dtype=int64)
In [392]: M2 =sparse.block_diag((M1,M1))                                                                 
In [393]: M2                                                                                             
Out[393]: 
<12x12 sparse matrix of type '<class 'numpy.int64'>'
    with 40 stored elements in COOrdinate format>
In [394]: M2.A                                                                                           
Out[394]: 
array([[ 4, -1,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0],
       [-1,  4, -1,  0, -1,  0,  0,  0,  0,  0,  0,  0],
       [ 0, -1,  4,  0,  0, -1,  0,  0,  0,  0,  0,  0],
       [-1,  0,  0,  4, -1,  0,  0,  0,  0,  0,  0,  0],
       [ 0, -1,  0, -1,  4, -1,  0,  0,  0,  0,  0,  0],
       [ 0,  0, -1,  0, -1,  4,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  4, -1,  0, -1,  0,  0],
       [ 0,  0,  0,  0,  0,  0, -1,  4, -1,  0, -1,  0],
       [ 0,  0,  0,  0,  0,  0,  0, -1,  4,  0,  0, -1],
       [ 0,  0,  0,  0,  0,  0, -1,  0,  0,  4, -1,  0],
       [ 0,  0,  0,  0,  0,  0,  0, -1,  0, -1,  4, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0, -1,  0, -1,  4]], dtype=int64)

查看block_mat代码;它构造了输入和None的嵌套列表,并将其传递给bmatbmat的代码将所有输入的coo属性与适当的偏移量结合在一起,从而为结果矩阵提供coo样式的输入。 sparse.hstacksparse.vstack是使用bmat的其他示例。

因此,遵循这些模型,您可以直接从BI来构建合成。

===

直接对角5条线:

In [405]: data = -np.ones((5,12),int)                                                                    
In [406]: data[0,:] *= -4                                                                                
In [407]: offsets=np.array([0,-1,-3,1,3])  # offsets dont have to be in order                                                         
In [408]: M4 = sparse.spdiags(data, offsets,12,12)                                                       
In [409]: M4                                                                                             
Out[409]: 
<12x12 sparse matrix of type '<class 'numpy.int64'>'
    with 52 stored elements (5 diagonals) in DIAgonal format>
In [410]: M4.A                                                                                           
Out[410]: 
array([[ 4, -1,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0],
       [-1,  4, -1,  0, -1,  0,  0,  0,  0,  0,  0,  0],
       [ 0, -1,  4, -1,  0, -1,  0,  0,  0,  0,  0,  0],
       [-1,  0, -1,  4, -1,  0, -1,  0,  0,  0,  0,  0],
       [ 0, -1,  0, -1,  4, -1,  0, -1,  0,  0,  0,  0],
       [ 0,  0, -1,  0, -1,  4, -1,  0, -1,  0,  0,  0],
       [ 0,  0,  0, -1,  0, -1,  4, -1,  0, -1,  0,  0],
       [ 0,  0,  0,  0, -1,  0, -1,  4, -1,  0, -1,  0],
       [ 0,  0,  0,  0,  0, -1,  0, -1,  4, -1,  0, -1],
       [ 0,  0,  0,  0,  0,  0, -1,  0, -1,  4, -1,  0],
       [ 0,  0,  0,  0,  0,  0,  0, -1,  0, -1,  4, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0, -1,  0, -1,  4]])

直接转到coo输入:

In [411]: data,rows,cols = [],[],[]  
In [413]: for v,z in zip([-1,-1,4,-1,-1],[-3,-1,0,1,3]): 
     ...:    len = 12-abs(z) 
     ...:    d = np.ones(len, int)*v 
     ...:    r = np.arange(len)+max(0,z) 
     ...:    c = np.arange(len)+max(0,-z) 
     ...:    data.append(d); rows.append(r); cols.append(c) 
     ...:                                                                                                
In [414]: data                                                                                           
Out[414]: 
[array([-1, -1, -1, -1, -1, -1, -1, -1, -1]),
 array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]),
 array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]),
 ...]
In [415]: rows                                                                                           
Out[415]: 
[array([0, 1, 2, 3, 4, 5, 6, 7, 8]),
 array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10]),
 ....]
In [416]: cols                                                                                           
Out[416]: 
[array([ 3,  4,  5,  6,  7,  8,  9, 10, 11]),
 array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]),
 ...]
In [417]: M5 = sparse.coo_matrix((np.hstack(data), (np.hstack(rows), np.hstack(cols))))                  
In [418]: M5                                                                                             
Out[418]: 
<12x12 sparse matrix of type '<class 'numpy.int64'>'
    with 52 stored elements in COOrdinate format>

或者仅使用data列表(和偏移量):

In [427]: M6=sparse.diags(data, [-3,-1,0,1,3],dtype=int,format='csr')                                 
In [428]: M6                                                                                          
Out[428]: 
<12x12 sparse matrix of type '<class 'numpy.int64'>'
    with 52 stored elements in Compressed Sparse Row format>