我想要一个稀疏A
矩阵B
,其中m x m
是n = 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
可以做到这一点。
我已经花了两个小时考虑它,也许找到一个更简单的方法是不值得的。
答案 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
没有偏移功能,因此我首先将B
和I
组合成一个较大的块。
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
的嵌套列表,并将其传递给bmat
。 bmat
的代码将所有输入的coo
属性与适当的偏移量结合在一起,从而为结果矩阵提供coo
样式的输入。 sparse.hstack
和sparse.vstack
是使用bmat
的其他示例。
因此,遵循这些模型,您可以直接从B
和I
来构建合成。
===
直接对角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>