Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 573 lines (499 sloc) 21.299 kb
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
1 """Dictionary Of Keys based matrix"""
2
5f4c579 @pv MAINT: add relevant from __future__ import to all files
pv authored
3 from __future__ import division, print_function, absolute_import
4
4e0da1a updated sparse docstrings
wnbell authored
5 __docformat__ = "restructuredtext en"
6
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
7 __all__ = ['dok_matrix', 'isspmatrix_dok']
8
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
9
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
10
da9cb74 cleaned up dok_matrix imports
wnbell authored
11 import numpy as np
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
12
3b9859f @pv PY23: restore xrange()
pv authored
13 from scipy.lib.six.moves import zip as izip, xrange
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
14 from scipy.lib.six import iteritems
15
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
16 from .base import spmatrix, isspmatrix
17 from .sputils import isdense, getdtype, isshape, isintlike, isscalarlike, upcast
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
18
feccc93 @pv 3K: sparse: operator module no longer contains isSequenceType
pv authored
19 try:
20 from operator import isSequenceType as _is_sequence
21 except ImportError:
22 def _is_sequence(x):
23 return (hasattr(x, '__len__') or hasattr(x, '__next__')
24 or hasattr(x, 'next'))
25
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
26 class dok_matrix(spmatrix, dict):
9350fab @rgommers DOC: merge wiki edits - linalg, maxentropy and sparse.
rgommers authored
27 """
28 Dictionary Of Keys based sparse matrix.
d7afea6 @jarrodmillman ran reindent
jarrodmillman authored
29
30 This is an efficient structure for constructing sparse
dc0c2ab sparse matrices now conform to spmatrix( (M,N) ) -> empty M-by-N matrix
wnbell authored
31 matrices incrementally.
20c536f added DOK matrix patch by James Philbin
wnbell authored
32
9350fab @rgommers DOC: merge wiki edits - linalg, maxentropy and sparse.
rgommers authored
33 This can be instantiated in several ways:
20c536f added DOK matrix patch by James Philbin
wnbell authored
34 dok_matrix(D)
35 with a dense matrix, D
36
37 dok_matrix(S)
38 with a sparse matrix, S
39
40 dok_matrix((M,N), [dtype])
41 create the matrix with initial shape (M,N)
42 dtype is optional, defaulting to dtype='d'
43
d19c963 @pv DOC: sparse: document attributes of the sparse matrices, and mention tha...
pv authored
44 Attributes
45 ----------
46 dtype : dtype
47 Data type of the matrix
48 shape : 2-tuple
49 Shape of the matrix
50 ndim : int
51 Number of dimensions (this is always 2)
52 nnz
53 Number of nonzero elements
54
20c536f added DOK matrix patch by James Philbin
wnbell authored
55 Notes
56 -----
d19c963 @pv DOC: sparse: document attributes of the sparse matrices, and mention tha...
pv authored
57
58 Sparse matrices can be used in arithmetic operations: they support
59 addition, subtraction, multiplication, division, and matrix power.
60
20c536f added DOK matrix patch by James Philbin
wnbell authored
61 Allows for efficient O(1) access of individual elements.
62 Duplicates are not allowed.
63 Can be efficiently converted to a coo_matrix once constructed.
64
65 Examples
66 --------
67 >>> from scipy.sparse import *
68 >>> from scipy import *
69 >>> S = dok_matrix((5,5), dtype=float32)
70 >>> for i in range(5):
71 >>> for j in range(5):
72 >>> S[i,j] = i+j # Update element
73
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
74 """
c004831 deprecated dims argument in CSR/CSC/COO constructors
wnbell authored
75
20c536f added DOK matrix patch by James Philbin
wnbell authored
76 def __init__(self, arg1, shape=None, dtype=None, copy=False):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
77 dict.__init__(self)
4b4bc38 made str() work for all sparse mats
wnbell authored
78 spmatrix.__init__(self)
20c536f added DOK matrix patch by James Philbin
wnbell authored
79
80 self.dtype = getdtype(dtype, default=float)
81 if isinstance(arg1, tuple) and isshape(arg1): # (M,N)
82 M, N = arg1
83 self.shape = (M, N)
84 elif isspmatrix(arg1): # Sparse ctor
85 if isspmatrix_dok(arg1) and copy:
86 arg1 = arg1.copy()
de19ca5 allow all sparse matrices to be initialized with dense matrices and anyt...
wnbell authored
87 else:
20c536f added DOK matrix patch by James Philbin
wnbell authored
88 arg1 = arg1.todok()
a01c277 @jarrodmillman ran reindent
jarrodmillman authored
89
f4146a7 fixed handling of dtype= constructor argument in sparse case
wnbell authored
90 if dtype is not None:
91 arg1 = arg1.astype(dtype)
92
20c536f added DOK matrix patch by James Philbin
wnbell authored
93 self.update(arg1)
94 self.shape = arg1.shape
95 self.dtype = arg1.dtype
96 else: # Dense ctor
97 try:
da9cb74 cleaned up dok_matrix imports
wnbell authored
98 arg1 = np.asarray(arg1)
20c536f added DOK matrix patch by James Philbin
wnbell authored
99 except:
100 raise TypeError('invalid input format')
101
102 if len(arg1.shape)!=2:
103 raise TypeError('expected rank <=2 dense array or matrix')
104
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
105 from .coo import coo_matrix
40e1c9a added scipy.sparse.find()
wnbell authored
106 self.update( coo_matrix(arg1, dtype=dtype).todok() )
20c536f added DOK matrix patch by James Philbin
wnbell authored
107 self.shape = arg1.shape
108 self.dtype = arg1.dtype
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
109
110 def getnnz(self):
111 return dict.__len__(self)
199b69f add nnz properties to all sparse matrices
wnbell authored
112 nnz = property(fget=getnnz)
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
113
114 def __len__(self):
115 return dict.__len__(self)
116
117 def get(self, key, default=0.):
118 """This overrides the dict.get method, providing type checking
119 but otherwise equivalent functionality.
120 """
121 try:
122 i, j = key
123 assert isintlike(i) and isintlike(j)
124 except (AssertionError, TypeError, ValueError):
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
125 raise IndexError('index must be a pair of integers')
7ac2646 @rgommers STY: remove plain asserts from sparse, lib/lapack, linalg and stats modu...
rgommers authored
126 if (i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]):
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
127 raise IndexError('index out of bounds')
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
128 return dict.get(self, key, default)
129
130 def __getitem__(self, key):
131 """If key=(i,j) is a pair of integers, return the corresponding
132 element. If either i or j is a slice or sequence, return a new sparse
133 matrix with just these elements.
134 """
135 try:
136 i, j = key
137 except (ValueError, TypeError):
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
138 raise TypeError('index must be a pair of integers or slices')
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
139
140
141 # Bounds checking
142 if isintlike(i):
143 if i < 0:
144 i += self.shape[0]
145 if i < 0 or i >= self.shape[0]:
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
146 raise IndexError('index out of bounds')
147
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
148 if isintlike(j):
149 if j < 0:
150 j += self.shape[1]
151 if j < 0 or j >= self.shape[1]:
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
152 raise IndexError('index out of bounds')
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
153
154 # First deal with the case where both i and j are integers
155 if isintlike(i) and isintlike(j):
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
156 return dict.get(self, (i,j), 0.)
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
157 else:
158 # Either i or j is a slice, sequence, or invalid. If i is a slice
159 # or sequence, unfold it first and call __getitem__ recursively.
160
161 if isinstance(i, slice):
162 # Is there an easier way to do this?
3b9859f @pv PY23: restore xrange()
pv authored
163 seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1)
feccc93 @pv 3K: sparse: operator module no longer contains isSequenceType
pv authored
164 elif _is_sequence(i):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
165 seq = i
166 else:
167 # Make sure i is an integer. (But allow it to be a subclass of int).
168 if not isintlike(i):
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
169 raise TypeError('index must be a pair of integers or slices')
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
170 seq = None
171 if seq is not None:
172 # i is a seq
173 if isintlike(j):
174 # Create a new matrix of the correct dimensions
175 first = seq[0]
176 last = seq[-1]
177 if first < 0 or first >= self.shape[0] or last < 0 \
178 or last >= self.shape[0]:
baa9e6a added more rigorous checking of __getitem__ and __setitem__
wnbell authored
179 raise IndexError('index out of bounds')
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
180 newshape = (last-first+1, 1)
181 new = dok_matrix(newshape)
182 # ** This uses linear time in the size m of dimension 0:
183 # new[0:seq[-1]-seq[0]+1, 0] = \
184 # [self.get((element, j), 0) for element in seq]
185 # ** Instead just add the non-zero elements. This uses
186 # ** linear time in the number of non-zeros:
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
187 for (ii, jj) in self.keys():
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
188 if jj == j and ii >= first and ii <= last:
189 dict.__setitem__(new, (ii-first, 0), \
190 dict.__getitem__(self, (ii,jj)))
191 else:
192 ###################################
193 # We should reshape the new matrix here!
194 ###################################
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
195 raise NotImplementedError("fancy indexing supported over"
196 " one axis only")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
197 return new
198
199 # Below here, j is a sequence, but i is an integer
200 if isinstance(j, slice):
201 # Is there an easier way to do this?
3b9859f @pv PY23: restore xrange()
pv authored
202 seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1)
feccc93 @pv 3K: sparse: operator module no longer contains isSequenceType
pv authored
203 elif _is_sequence(j):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
204 seq = j
205 else:
206 # j is not an integer
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
207 raise TypeError("index must be a pair of integers or slices")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
208
209 # Create a new matrix of the correct dimensions
210 first = seq[0]
211 last = seq[-1]
212 if first < 0 or first >= self.shape[1] or last < 0 \
213 or last >= self.shape[1]:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
214 raise IndexError("index out of bounds")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
215 newshape = (1, last-first+1)
216 new = dok_matrix(newshape)
217 # ** This uses linear time in the size n of dimension 1:
218 # new[0, 0:seq[-1]-seq[0]+1] = \
219 # [self.get((i, element), 0) for element in seq]
220 # ** Instead loop over the non-zero elements. This is slower
221 # ** if there are many non-zeros
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
222 for (ii, jj) in self.keys():
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
223 if ii == i and jj >= first and jj <= last:
224 dict.__setitem__(new, (0, jj-first), \
225 dict.__getitem__(self, (ii,jj)))
226 return new
227
228
229 def __setitem__(self, key, value):
230 try:
20c536f added DOK matrix patch by James Philbin
wnbell authored
231 i, j = key
232 except (ValueError, TypeError):
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
233 raise TypeError("index must be a pair of integers or slices")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
234
235 # First deal with the case where both i and j are integers
236 if isintlike(i) and isintlike(j):
237 if i < 0:
238 i += self.shape[0]
239 if j < 0:
240 j += self.shape[1]
241
242 if i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
243 raise IndexError("index out of bounds")
20c536f added DOK matrix patch by James Philbin
wnbell authored
244
da9cb74 cleaned up dok_matrix imports
wnbell authored
245 if np.isscalar(value):
fbedf49 BUG: Fix for ticket 1160 (thanks to derPhil and JustinPeel)
warren.weckesser authored
246 if value == 0:
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
247 if (i,j) in self:
fbedf49 BUG: Fix for ticket 1160 (thanks to derPhil and JustinPeel)
warren.weckesser authored
248 del self[(i,j)]
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
249 else:
20c536f added DOK matrix patch by James Philbin
wnbell authored
250 dict.__setitem__(self, (i,j), self.dtype.type(value))
251 else:
121d953 lil_matrix now rejects sequences where scalars are expected
wnbell authored
252 raise ValueError('setting an array element with a sequence')
253
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
254 else:
255 # Either i or j is a slice, sequence, or invalid. If i is a slice
256 # or sequence, unfold it first and call __setitem__ recursively.
257 if isinstance(i, slice):
258 # Is there an easier way to do this?
3b9859f @pv PY23: restore xrange()
pv authored
259 seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1)
feccc93 @pv 3K: sparse: operator module no longer contains isSequenceType
pv authored
260 elif _is_sequence(i):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
261 seq = i
262 else:
263 # Make sure i is an integer. (But allow it to be a subclass of int).
264 if not isintlike(i):
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
265 raise TypeError("index must be a pair of integers or slices")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
266 seq = None
267 if seq is not None:
268 # First see if 'value' is another dok_matrix of the appropriate
269 # dimensions
270 if isinstance(value, dok_matrix):
271 if value.shape[1] == 1:
272 for element in seq:
273 self[element, j] = value[element, 0]
274 else:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
275 raise NotImplementedError("setting a 2-d slice of"
276 " a dok_matrix is not yet supported")
da9cb74 cleaned up dok_matrix imports
wnbell authored
277 elif np.isscalar(value):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
278 for element in seq:
279 self[element, j] = value
280 else:
281 # See if value is a sequence
282 try:
283 if len(seq) != len(value):
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
284 raise ValueError("index and value ranges must"
285 " have the same length")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
286 except TypeError:
287 # Not a sequence
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
288 raise TypeError("unsupported type for"
289 " dok_matrix.__setitem__")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
290
291 # Value is a sequence
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
292 for element, val in izip(seq, value):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
293 self[element, j] = val # don't use dict.__setitem__
294 # here, since we still want to be able to delete
295 # 0-valued keys, do type checking on 'val' (e.g. if
296 # it's a rank-1 dense array), etc.
297 else:
298 # Process j
299 if isinstance(j, slice):
3b9859f @pv PY23: restore xrange()
pv authored
300 seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1)
feccc93 @pv 3K: sparse: operator module no longer contains isSequenceType
pv authored
301 elif _is_sequence(j):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
302 seq = j
303 else:
304 # j is not an integer
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
305 raise TypeError("index must be a pair of integers or slices")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
306
307 # First see if 'value' is another dok_matrix of the appropriate
308 # dimensions
309 if isinstance(value, dok_matrix):
310 if value.shape[0] == 1:
311 for element in seq:
312 self[i, element] = value[0, element]
313 else:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
314 raise NotImplementedError("setting a 2-d slice of"
315 " a dok_matrix is not yet supported")
da9cb74 cleaned up dok_matrix imports
wnbell authored
316 elif np.isscalar(value):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
317 for element in seq:
318 self[i, element] = value
319 else:
320 # See if value is a sequence
321 try:
322 if len(seq) != len(value):
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
323 raise ValueError("index and value ranges must have"
324 " the same length")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
325 except TypeError:
326 # Not a sequence
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
327 raise TypeError("unsupported type for dok_matrix.__setitem__")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
328 else:
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
329 for element, val in izip(seq, value):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
330 self[i, element] = val
331
332
333 def __add__(self, other):
334 # First check if argument is a scalar
335 if isscalarlike(other):
336 new = dok_matrix(self.shape, dtype=self.dtype)
337 # Add this scalar to every element.
338 M, N = self.shape
3b9859f @pv PY23: restore xrange()
pv authored
339 for i in xrange(M):
340 for j in xrange(N):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
341 aij = self.get((i, j), 0) + other
342 if aij != 0:
343 new[i, j] = aij
344 #new.dtype.char = self.dtype.char
345 elif isinstance(other, dok_matrix):
346 if other.shape != self.shape:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
347 raise ValueError("matrix dimensions are not equal")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
348 # We could alternatively set the dimensions to the the largest of
349 # the two matrices to be summed. Would this be a good idea?
350 new = dok_matrix(self.shape, dtype=self.dtype)
351 new.update(self)
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
352 for key in other.keys():
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
353 new[key] += other[key]
354 elif isspmatrix(other):
355 csc = self.tocsc()
356 new = csc + other
357 elif isdense(other):
358 new = self.todense() + other
359 else:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
360 raise TypeError("data type not understood")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
361 return new
362
363 def __radd__(self, other):
364 # First check if argument is a scalar
365 if isscalarlike(other):
366 new = dok_matrix(self.shape, dtype=self.dtype)
367 # Add this scalar to every element.
368 M, N = self.shape
3b9859f @pv PY23: restore xrange()
pv authored
369 for i in xrange(M):
370 for j in xrange(N):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
371 aij = self.get((i, j), 0) + other
372 if aij != 0:
373 new[i, j] = aij
374 elif isinstance(other, dok_matrix):
375 if other.shape != self.shape:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
376 raise ValueError("matrix dimensions are not equal")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
377 new = dok_matrix(self.shape, dtype=self.dtype)
378 new.update(self)
379 for key in other:
380 new[key] += other[key]
381 elif isspmatrix(other):
382 csc = self.tocsc()
383 new = csc + other
384 elif isdense(other):
385 new = other + self.todense()
386 else:
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
387 raise TypeError("data type not understood")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
388 return new
389
390 def __neg__(self):
391 new = dok_matrix(self.shape, dtype=self.dtype)
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
392 for key in self.keys():
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
393 new[key] = -self[key]
394 return new
395
d2a18de refactored sparse matrix multiplication handlers
wnbell authored
396 def _mul_scalar(self, other):
397 # Multiply this scalar by every element.
da9cb74 cleaned up dok_matrix imports
wnbell authored
398 new = dok_matrix(self.shape, dtype=self.dtype)
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
399 for (key, val) in iteritems(self):
d2a18de refactored sparse matrix multiplication handlers
wnbell authored
400 new[key] = val * other
401 return new
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
402
da9cb74 cleaned up dok_matrix imports
wnbell authored
403 def _mul_vector(self, other):
404 #matrix * vector
405 result = np.zeros( self.shape[0], dtype=upcast(self.dtype,other.dtype) )
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
406 for (i,j),v in iteritems(self):
da9cb74 cleaned up dok_matrix imports
wnbell authored
407 result[i] += v * other[j]
408 return result
a01c277 @jarrodmillman ran reindent
jarrodmillman authored
409
da9cb74 cleaned up dok_matrix imports
wnbell authored
410 def _mul_multivector(self, other):
411 #matrix * multivector
412 M,N = self.shape
413 n_vecs = other.shape[1] #number of column vectors
414 result = np.zeros( (M,n_vecs), dtype=upcast(self.dtype,other.dtype) )
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
415 for (i,j),v in iteritems(self):
da9cb74 cleaned up dok_matrix imports
wnbell authored
416 result[i,:] += v * other[j,:]
417 return result
418
d2a18de refactored sparse matrix multiplication handlers
wnbell authored
419 def __imul__(self, other):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
420 if isscalarlike(other):
421 # Multiply this scalar by every element.
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
422 for (key, val) in iteritems(self):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
423 self[key] = val * other
424 #new.dtype.char = self.dtype.char
425 return self
426 else:
427 return NotImplementedError
428
d2a18de refactored sparse matrix multiplication handlers
wnbell authored
429
430 def __truediv__(self, other):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
431 if isscalarlike(other):
432 new = dok_matrix(self.shape, dtype=self.dtype)
433 # Multiply this scalar by every element.
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
434 for (key, val) in iteritems(self):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
435 new[key] = val / other
436 #new.dtype.char = self.dtype.char
437 return new
438 else:
439 return self.tocsr() / other
440
441
d2a18de refactored sparse matrix multiplication handlers
wnbell authored
442 def __itruediv__(self, other):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
443 if isscalarlike(other):
444 # Multiply this scalar by every element.
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
445 for (key, val) in iteritems(self):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
446 self[key] = val / other
447 return self
448 else:
449 return NotImplementedError
450
451 # What should len(sparse) return? For consistency with dense matrices,
452 # perhaps it should be the number of rows? For now it returns the number
453 # of non-zeros.
454
455 def transpose(self):
456 """ Return the transpose
457 """
458 M, N = self.shape
459 new = dok_matrix((N, M), dtype=self.dtype)
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
460 for key, value in iteritems(self):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
461 new[key[1], key[0]] = value
462 return new
463
464 def conjtransp(self):
465 """ Return the conjugate transpose
466 """
467 M, N = self.shape
468 new = dok_matrix((N, M), dtype=self.dtype)
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
469 for key, value in iteritems(self):
720e000 BUG: sparse: fix a few undefined names found by pyflakes (but there are ...
warren.weckesser authored
470 new[key[1], key[0]] = np.conj(value)
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
471 return new
472
473 def copy(self):
474 new = dok_matrix(self.shape, dtype=self.dtype)
475 new.update(self)
476 return new
477
478 def take(self, cols_or_rows, columns=1):
479 # Extract columns or rows as indictated from matrix
480 # assume cols_or_rows is sorted
481 new = dok_matrix(dtype=self.dtype) # what should the dimensions be ?!
482 indx = int((columns == 1))
483 N = len(cols_or_rows)
484 if indx: # columns
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
485 for key in self.keys():
720e000 BUG: sparse: fix a few undefined names found by pyflakes (but there are ...
warren.weckesser authored
486 num = np.searchsorted(cols_or_rows, key[1])
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
487 if num < N:
488 newkey = (key[0], num)
489 new[newkey] = self[key]
490 else:
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
491 for key in self.keys():
720e000 BUG: sparse: fix a few undefined names found by pyflakes (but there are ...
warren.weckesser authored
492 num = np.searchsorted(cols_or_rows, key[0])
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
493 if num < N:
494 newkey = (num, key[1])
495 new[newkey] = self[key]
496 return new
497
498 def split(self, cols_or_rows, columns=1):
499 # Similar to take but returns two arrays, the extracted columns plus
500 # the resulting array. Assumes cols_or_rows is sorted
501 base = dok_matrix()
502 ext = dok_matrix()
503 indx = int((columns == 1))
504 if indx:
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
505 for key in self.keys():
720e000 BUG: sparse: fix a few undefined names found by pyflakes (but there are ...
warren.weckesser authored
506 num = np.searchsorted(cols_or_rows, key[1])
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
507 if cols_or_rows[num] == key[1]:
508 newkey = (key[0], num)
509 ext[newkey] = self[key]
510 else:
511 newkey = (key[0], key[1]-num)
512 base[newkey] = self[key]
513 else:
dbe3310 @pv PY23: sparse: __bool__/__nonzero__ + remove unnecessary list()'s + iteri...
pv authored
514 for key in self.keys():
720e000 BUG: sparse: fix a few undefined names found by pyflakes (but there are ...
warren.weckesser authored
515 num = np.searchsorted(cols_or_rows, key[0])
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
516 if cols_or_rows[num] == key[0]:
517 newkey = (num, key[1])
518 ext[newkey] = self[key]
519 else:
520 newkey = (key[0]-num, key[1])
521 base[newkey] = self[key]
522 return base, ext
a01c277 @jarrodmillman ran reindent
jarrodmillman authored
523
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
524 def tocoo(self):
525 """ Return a copy of this matrix in COOrdinate format"""
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
526 from .coo import coo_matrix
199b69f add nnz properties to all sparse matrices
wnbell authored
527 if self.nnz == 0:
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
528 return coo_matrix(self.shape, dtype=self.dtype)
529 else:
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
530 data = np.asarray(list(self.values()), dtype=self.dtype)
531 indices = np.asarray(list(self.keys()), dtype=np.intc).T
da9cb74 cleaned up dok_matrix imports
wnbell authored
532 return coo_matrix((data,indices), shape=self.shape, dtype=self.dtype)
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
533
534 def todok(self,copy=False):
535 if copy:
536 return self.copy()
537 else:
538 return self
539
540 def tocsr(self):
541 """ Return a copy of this matrix in Compressed Sparse Row format"""
542 return self.tocoo().tocsr()
543
544 def tocsc(self):
545 """ Return a copy of this matrix in Compressed Sparse Column format"""
546 return self.tocoo().tocsc()
547
5378661 @dwf ENH: Added an out= argument to sparse toarray().
dwf authored
548 def toarray(self, order=None, out=None):
0ceeefa @dwf DOC: added pointers to superclass docstring.
dwf authored
549 """See the docstring for `spmatrix.toarray`."""
5378661 @dwf ENH: Added an out= argument to sparse toarray().
dwf authored
550 return self.tocoo().toarray(order=order, out=out)
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
551
552 def resize(self, shape):
0dd55fa BUG: sparse: fixed the resize() method of dok_matrix (ticket #997); than...
warren.weckesser authored
553 """ Resize the matrix in-place to dimensions given by 'shape'.
7ac2646 @rgommers STY: remove plain asserts from sparse, lib/lapack, linalg and stats modu...
rgommers authored
554
0dd55fa BUG: sparse: fixed the resize() method of dok_matrix (ticket #997); than...
warren.weckesser authored
555 Any non-zero elements that lie outside the new shape are removed.
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
556 """
557 if not isshape(shape):
1559800 ENH: sparse: update 'raise' statements
warren.weckesser authored
558 raise TypeError("dimensions must be a 2-tuple of positive"
559 " integers")
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
560 newM, newN = shape
561 M, N = self.shape
562 if newM < M or newN < N:
563 # Remove all elements outside new dimensions
3add620 @pv MAINT: Automated 2to3 conversion of the code base
pv authored
564 for (i, j) in list(self.keys()):
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
565 if i >= newM or j >= newN:
566 del self[i, j]
0dd55fa BUG: sparse: fixed the resize() method of dok_matrix (ticket #997); than...
warren.weckesser authored
567 self._shape = shape
33e29d7 split sparse matrix classes and functions into separate files
wnbell authored
568
569
570
571 def isspmatrix_dok(x):
06cd6e5 @pv ENH: sparse: reduce overheads in sparse matrix multiplication
pv authored
572 return isinstance(x, dok_matrix)
Something went wrong with that request. Please try again.