In Octave (MATLAB alternative), the example in its documentation:
octave:7> x = spdiags (reshape (1:12, 4, 3), [-1 0 1], 5, 4);
octave:8> full(x) # display as a full or dense matrix
ans =
5 10 0 0
1 6 11 0
0 2 7 12
0 0 3 8
0 0 0 4
The actual values that are stored in x
are:
x =
Compressed Column Sparse (rows = 5, cols = 4, nnz = 11 [55%])
(1, 1) -> 5
(2, 1) -> 1
(1, 2) -> 10
(2, 2) -> 6
(3, 2) -> 2
(2, 3) -> 11
(3, 3) -> 7
(4, 3) -> 3
(3, 4) -> 12
(4, 4) -> 8
(5, 4) -> 4
The equivalent scipy.sparse
expression:
In [294]: x = sparse.spdiags(np.arange(1,13).reshape(3,4), [-1, 0, 1], 5, 4)
In [295]: x.A # display as normal numpy array
Out[295]:
array([[ 5, 10, 0, 0],
[ 1, 6, 11, 0],
[ 0, 2, 7, 12],
[ 0, 0, 3, 8],
[ 0, 0, 0, 4]])
In [296]: x
Out[296]:
<5x4 sparse matrix of type '<class 'numpy.int32'>'
with 11 stored elements (3 diagonals) in DIAgonal format>
This use the dia
format, but it easy to transfrom to csc
(equivalent to the Octave format) with x.tocsc()
.
To see the same coordinates and values, we can use the dok
format (a dictionary subclass):
In [299]: dict(x.todok())
Out[299]:
{(0, 1): 10,
(1, 2): 11,
(3, 2): 3,
(0, 0): 5,
(3, 3): 8,
(2, 1): 2,
(2, 3): 12,
(4, 3): 4,
(2, 2): 7,
(1, 0): 1,
(1, 1): 6}
Same values, adjusting for the 0 based indexing.
In both cases, the diagonal values come from a matrix:
octave:10> reshape(1:12, 4, 3)
ans =
1 5 9
2 6 10
3 7 11
4 8 12
In [302]: np.arange(1,13).reshape(3,4)
Out[302]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
Octave/MATLAB arrange values by column, numpy
by row, hence the different reshape
. The numpy
matrix is the transpose of the MATLAB equivalent.
Note that 9
has been omitted from both (4 items mapped on to a 3 element diagonal).
The other argument is a list of diagonals to set, [-1,0,1]
, and final shape (5,4)
.
Most of the differences in arguments have to do the basic differences between MATLAB and numpy. The other difference is that MATLAB has only one sparse matrix representation, scipy has a half dozen.