I am trying to translate a MATLAB implementation into a Python 3 implementation. I've found a function, spdiags(), that I do not understand, and am also not sure how to translate it into Python 3.
What does the MATLAB function do, and is there a Python implementation of the same return available?
解决方案
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 ''
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.