问题
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.
The MATLAB documentation on the function is here: http://www.mathworks.com/help/matlab/ref/spdiags.html
The Scipy documentation on an identically named function is here: http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.spdiags.html
What does the MATLAB function do, and is there a Python implementation of the same return available?
回答1:
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.
回答2:
Well, this answer can only scratch the surface, but:
For matrices, there's different storage formats. Of course, there's the most intuitive "row after row" and "column after column" formats, but there's also formats for matrices with only a few non-zero entries, which of course save a lot of memory (and might save a lot of CPU) if used correctly.
So, these diagonal sparse matrices are such a case of a specially stored matrix in matlab; If you don't care about the computational advantages, just use diag
, which is functionally 100% equivalent (but doesn't generate sparse matrices).
The existence of sparse matrix storage is a Matlab feature, and scipy does in fact (I'm actually surprised by that) have that feature, too. So use the scipy method if it fits your needs!
来源:https://stackoverflow.com/questions/31900043/spdiags-in-matlab-into-python