Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/scipy/sparse/_base.py: 1%

564 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-03 06:39 +0000

1"""Base class for sparse matrices""" 

2from warnings import warn 

3 

4import numpy as np 

5from scipy._lib._util import VisibleDeprecationWarning 

6 

7from ._sputils import (asmatrix, check_reshape_kwargs, check_shape, 

8 get_sum_dtype, isdense, isscalarlike, 

9 matrix, validateaxis,) 

10 

11from ._matrix import spmatrix 

12 

13__all__ = ['isspmatrix', 'issparse', 'sparray', 

14 'SparseWarning', 'SparseEfficiencyWarning'] 

15 

16 

17class SparseWarning(Warning): 

18 pass 

19 

20 

21class SparseFormatWarning(SparseWarning): 

22 pass 

23 

24 

25class SparseEfficiencyWarning(SparseWarning): 

26 pass 

27 

28 

29# The formats that we might potentially understand. 

30_formats = {'csc': [0, "Compressed Sparse Column"], 

31 'csr': [1, "Compressed Sparse Row"], 

32 'dok': [2, "Dictionary Of Keys"], 

33 'lil': [3, "List of Lists"], 

34 'dod': [4, "Dictionary of Dictionaries"], 

35 'sss': [5, "Symmetric Sparse Skyline"], 

36 'coo': [6, "COOrdinate"], 

37 'lba': [7, "Linpack BAnded"], 

38 'egd': [8, "Ellpack-itpack Generalized Diagonal"], 

39 'dia': [9, "DIAgonal"], 

40 'bsr': [10, "Block Sparse Row"], 

41 'msr': [11, "Modified compressed Sparse Row"], 

42 'bsc': [12, "Block Sparse Column"], 

43 'msc': [13, "Modified compressed Sparse Column"], 

44 'ssk': [14, "Symmetric SKyline"], 

45 'nsk': [15, "Nonsymmetric SKyline"], 

46 'jad': [16, "JAgged Diagonal"], 

47 'uss': [17, "Unsymmetric Sparse Skyline"], 

48 'vbr': [18, "Variable Block Row"], 

49 'und': [19, "Undefined"] 

50 } 

51 

52 

53# These univariate ufuncs preserve zeros. 

54_ufuncs_with_fixed_point_at_zero = frozenset([ 

55 np.sin, np.tan, np.arcsin, np.arctan, np.sinh, np.tanh, np.arcsinh, 

56 np.arctanh, np.rint, np.sign, np.expm1, np.log1p, np.deg2rad, 

57 np.rad2deg, np.floor, np.ceil, np.trunc, np.sqrt]) 

58 

59 

60MAXPRINT = 50 

61 

62 

63class _spbase: 

64 """ This class provides a base class for all sparse arrays. It 

65 cannot be instantiated. Most of the work is provided by subclasses. 

66 """ 

67 

68 __array_priority__ = 10.1 

69 _format = 'und' # undefined 

70 

71 @property 

72 def ndim(self) -> int: 

73 return len(self._shape) 

74 

75 @property 

76 def _shape_as_2d(self): 

77 s = self._shape 

78 return (1, s[-1]) if len(s) == 1 else s 

79 

80 @property 

81 def _bsr_container(self): 

82 from ._bsr import bsr_array 

83 return bsr_array 

84 

85 @property 

86 def _coo_container(self): 

87 from ._coo import coo_array 

88 return coo_array 

89 

90 @property 

91 def _csc_container(self): 

92 from ._csc import csc_array 

93 return csc_array 

94 

95 @property 

96 def _csr_container(self): 

97 from ._csr import csr_array 

98 return csr_array 

99 

100 @property 

101 def _dia_container(self): 

102 from ._dia import dia_array 

103 return dia_array 

104 

105 @property 

106 def _dok_container(self): 

107 from ._dok import dok_array 

108 return dok_array 

109 

110 @property 

111 def _lil_container(self): 

112 from ._lil import lil_array 

113 return lil_array 

114 

115 def __init__(self, maxprint=MAXPRINT): 

116 self._shape = None 

117 if self.__class__.__name__ == '_spbase': 

118 raise ValueError("This class is not intended" 

119 " to be instantiated directly.") 

120 self.maxprint = maxprint 

121 

122 # Use this in 1.14.0 and later: 

123 # 

124 # @property 

125 # def shape(self): 

126 # return self._shape 

127 

128 def reshape(self, *args, **kwargs): 

129 """reshape(self, shape, order='C', copy=False) 

130 

131 Gives a new shape to a sparse array/matrix without changing its data. 

132 

133 Parameters 

134 ---------- 

135 shape : length-2 tuple of ints 

136 The new shape should be compatible with the original shape. 

137 order : {'C', 'F'}, optional 

138 Read the elements using this index order. 'C' means to read and 

139 write the elements using C-like index order; e.g., read entire first 

140 row, then second row, etc. 'F' means to read and write the elements 

141 using Fortran-like index order; e.g., read entire first column, then 

142 second column, etc. 

143 copy : bool, optional 

144 Indicates whether or not attributes of self should be copied 

145 whenever possible. The degree to which attributes are copied varies 

146 depending on the type of sparse array being used. 

147 

148 Returns 

149 ------- 

150 reshaped : sparse array/matrix 

151 A sparse array/matrix with the given `shape`, not necessarily of the same 

152 format as the current object. 

153 

154 See Also 

155 -------- 

156 numpy.reshape : NumPy's implementation of 'reshape' for ndarrays 

157 """ 

158 # If the shape already matches, don't bother doing an actual reshape 

159 # Otherwise, the default is to convert to COO and use its reshape 

160 is_array = isinstance(self, sparray) 

161 shape = check_shape(args, self.shape, allow_1d=is_array) 

162 order, copy = check_reshape_kwargs(kwargs) 

163 if shape == self.shape: 

164 if copy: 

165 return self.copy() 

166 else: 

167 return self 

168 

169 return self.tocoo(copy=copy).reshape(shape, order=order, copy=False) 

170 

171 def resize(self, shape): 

172 """Resize the array/matrix in-place to dimensions given by ``shape`` 

173 

174 Any elements that lie within the new shape will remain at the same 

175 indices, while non-zero elements lying outside the new shape are 

176 removed. 

177 

178 Parameters 

179 ---------- 

180 shape : (int, int) 

181 number of rows and columns in the new array/matrix 

182 

183 Notes 

184 ----- 

185 The semantics are not identical to `numpy.ndarray.resize` or 

186 `numpy.resize`. Here, the same data will be maintained at each index 

187 before and after reshape, if that index is within the new bounds. In 

188 numpy, resizing maintains contiguity of the array, moving elements 

189 around in the logical array but not within a flattened representation. 

190 

191 We give no guarantees about whether the underlying data attributes 

192 (arrays, etc.) will be modified in place or replaced with new objects. 

193 """ 

194 # As an inplace operation, this requires implementation in each format. 

195 raise NotImplementedError( 

196 f'{type(self).__name__}.resize is not implemented') 

197 

198 def astype(self, dtype, casting='unsafe', copy=True): 

199 """Cast the array/matrix elements to a specified type. 

200 

201 Parameters 

202 ---------- 

203 dtype : string or numpy dtype 

204 Typecode or data-type to which to cast the data. 

205 casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional 

206 Controls what kind of data casting may occur. 

207 Defaults to 'unsafe' for backwards compatibility. 

208 'no' means the data types should not be cast at all. 

209 'equiv' means only byte-order changes are allowed. 

210 'safe' means only casts which can preserve values are allowed. 

211 'same_kind' means only safe casts or casts within a kind, 

212 like float64 to float32, are allowed. 

213 'unsafe' means any data conversions may be done. 

214 copy : bool, optional 

215 If `copy` is `False`, the result might share some memory with this 

216 array/matrix. If `copy` is `True`, it is guaranteed that the result and 

217 this array/matrix do not share any memory. 

218 """ 

219 

220 dtype = np.dtype(dtype) 

221 if self.dtype != dtype: 

222 return self.tocsr().astype( 

223 dtype, casting=casting, copy=copy).asformat(self.format) 

224 elif copy: 

225 return self.copy() 

226 else: 

227 return self 

228 

229 @classmethod 

230 def _ascontainer(cls, X, **kwargs): 

231 if issubclass(cls, sparray): 

232 return np.asarray(X, **kwargs) 

233 else: 

234 return asmatrix(X, **kwargs) 

235 

236 @classmethod 

237 def _container(cls, X, **kwargs): 

238 if issubclass(cls, sparray): 

239 return np.array(X, **kwargs) 

240 else: 

241 return matrix(X, **kwargs) 

242 

243 def _asfptype(self): 

244 """Upcast array to a floating point format (if necessary)""" 

245 

246 fp_types = ['f', 'd', 'F', 'D'] 

247 

248 if self.dtype.char in fp_types: 

249 return self 

250 else: 

251 for fp_type in fp_types: 

252 if self.dtype <= np.dtype(fp_type): 

253 return self.astype(fp_type) 

254 

255 raise TypeError('cannot upcast [%s] to a floating ' 

256 'point format' % self.dtype.name) 

257 

258 def __iter__(self): 

259 for r in range(self.shape[0]): 

260 yield self[r] 

261 

262 def _getmaxprint(self): 

263 """Maximum number of elements to display when printed.""" 

264 return self.maxprint 

265 

266 def count_nonzero(self): 

267 """Number of non-zero entries, equivalent to 

268 

269 np.count_nonzero(a.toarray()) 

270 

271 Unlike the nnz property, which return the number of stored 

272 entries (the length of the data attribute), this method counts the 

273 actual number of non-zero entries in data. 

274 """ 

275 raise NotImplementedError("count_nonzero not implemented for %s." % 

276 self.__class__.__name__) 

277 

278 def _getnnz(self, axis=None): 

279 """Number of stored values, including explicit zeros. 

280 

281 Parameters 

282 ---------- 

283 axis : None, 0, or 1 

284 Select between the number of values across the whole array, in 

285 each column, or in each row. 

286 

287 See also 

288 -------- 

289 count_nonzero : Number of non-zero entries 

290 """ 

291 raise NotImplementedError("getnnz not implemented for %s." % 

292 self.__class__.__name__) 

293 

294 @property 

295 def nnz(self) -> int: 

296 """Number of stored values, including explicit zeros. 

297 

298 See also 

299 -------- 

300 count_nonzero : Number of non-zero entries 

301 """ 

302 return self._getnnz() 

303 

304 @property 

305 def size(self) -> int: 

306 """Number of stored values. 

307 

308 See also 

309 -------- 

310 count_nonzero : Number of non-zero values. 

311 """ 

312 return self._getnnz() 

313 

314 @property 

315 def format(self) -> str: 

316 """Format string for matrix.""" 

317 return self._format 

318 

319 @property 

320 def A(self) -> np.ndarray: 

321 """DEPRECATED: Return a dense array. 

322 

323 .. deprecated:: 1.11.0 

324 

325 `.A` is deprecated and will be removed in v1.14.0. 

326 Use `.toarray()` instead. 

327 """ 

328 if isinstance(self, sparray): 

329 message = ("`.A` is deprecated and will be removed in v1.14.0. " 

330 "Use `.toarray()` instead.") 

331 warn(VisibleDeprecationWarning(message), stacklevel=2) 

332 return self.toarray() 

333 

334 @property 

335 def T(self): 

336 """Transpose.""" 

337 return self.transpose() 

338 

339 @property 

340 def H(self): 

341 """DEPRECATED: Returns the (complex) conjugate transpose. 

342 

343 .. deprecated:: 1.11.0 

344 

345 `.H` is deprecated and will be removed in v1.14.0. 

346 Please use `.T.conjugate()` instead. 

347 """ 

348 if isinstance(self, sparray): 

349 message = ("`.H` is deprecated and will be removed in v1.14.0. " 

350 "Please use `.T.conjugate()` instead.") 

351 warn(VisibleDeprecationWarning(message), stacklevel=2) 

352 return self.T.conjugate() 

353 

354 @property 

355 def real(self): 

356 return self._real() 

357 

358 @property 

359 def imag(self): 

360 return self._imag() 

361 

362 def __repr__(self): 

363 _, format_name = _formats[self.format] 

364 sparse_cls = 'array' if isinstance(self, sparray) else 'matrix' 

365 shape_str = 'x'.join(str(x) for x in self.shape) 

366 return ( 

367 f"<{shape_str} sparse {sparse_cls} of type '{self.dtype.type}'\n" 

368 f"\twith {self.nnz} stored elements in {format_name} format>" 

369 ) 

370 

371 def __str__(self): 

372 maxprint = self._getmaxprint() 

373 

374 A = self.tocoo() 

375 

376 # helper function, outputs "(i,j) v" 

377 def tostr(row, col, data): 

378 triples = zip(list(zip(row, col)), data) 

379 return '\n'.join([(' {}\t{}'.format(*t)) for t in triples]) 

380 

381 if self.nnz > maxprint: 

382 half = maxprint // 2 

383 out = tostr(A.row[:half], A.col[:half], A.data[:half]) 

384 out += "\n :\t:\n" 

385 half = maxprint - maxprint//2 

386 out += tostr(A.row[-half:], A.col[-half:], A.data[-half:]) 

387 else: 

388 out = tostr(A.row, A.col, A.data) 

389 

390 return out 

391 

392 def __bool__(self): # Simple -- other ideas? 

393 if self.shape == (1, 1): 

394 return self.nnz != 0 

395 else: 

396 raise ValueError("The truth value of an array with more than one " 

397 "element is ambiguous. Use a.any() or a.all().") 

398 __nonzero__ = __bool__ 

399 

400 # What should len(sparse) return? For consistency with dense matrices, 

401 # perhaps it should be the number of rows? But for some uses the number of 

402 # non-zeros is more important. For now, raise an exception! 

403 def __len__(self): 

404 raise TypeError("sparse array length is ambiguous; use getnnz()" 

405 " or shape[0]") 

406 

407 def asformat(self, format, copy=False): 

408 """Return this array/matrix in the passed format. 

409 

410 Parameters 

411 ---------- 

412 format : {str, None} 

413 The desired sparse format ("csr", "csc", "lil", "dok", "array", ...) 

414 or None for no conversion. 

415 copy : bool, optional 

416 If True, the result is guaranteed to not share data with self. 

417 

418 Returns 

419 ------- 

420 A : This array/matrix in the passed format. 

421 """ 

422 if format is None or format == self.format: 

423 if copy: 

424 return self.copy() 

425 else: 

426 return self 

427 else: 

428 try: 

429 convert_method = getattr(self, 'to' + format) 

430 except AttributeError as e: 

431 raise ValueError(f'Format {format} is unknown.') from e 

432 

433 # Forward the copy kwarg, if it's accepted. 

434 try: 

435 return convert_method(copy=copy) 

436 except TypeError: 

437 return convert_method() 

438 

439 ################################################################### 

440 # NOTE: All arithmetic operations use csr_matrix by default. 

441 # Therefore a new sparse array format just needs to define a 

442 # .tocsr() method to provide arithmetic support. Any of these 

443 # methods can be overridden for efficiency. 

444 #################################################################### 

445 

446 def multiply(self, other): 

447 """Point-wise multiplication by another array/matrix.""" 

448 return self.tocsr().multiply(other) 

449 

450 def maximum(self, other): 

451 """Element-wise maximum between this and another array/matrix.""" 

452 return self.tocsr().maximum(other) 

453 

454 def minimum(self, other): 

455 """Element-wise minimum between this and another array/matrix.""" 

456 return self.tocsr().minimum(other) 

457 

458 def dot(self, other): 

459 """Ordinary dot product 

460 

461 Examples 

462 -------- 

463 >>> import numpy as np 

464 >>> from scipy.sparse import csr_array 

465 >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]]) 

466 >>> v = np.array([1, 0, -1]) 

467 >>> A.dot(v) 

468 array([ 1, -3, -1], dtype=int64) 

469 

470 """ 

471 if np.isscalar(other): 

472 return self * other 

473 else: 

474 return self @ other 

475 

476 def power(self, n, dtype=None): 

477 """Element-wise power.""" 

478 return self.tocsr().power(n, dtype=dtype) 

479 

480 def __eq__(self, other): 

481 return self.tocsr().__eq__(other) 

482 

483 def __ne__(self, other): 

484 return self.tocsr().__ne__(other) 

485 

486 def __lt__(self, other): 

487 return self.tocsr().__lt__(other) 

488 

489 def __gt__(self, other): 

490 return self.tocsr().__gt__(other) 

491 

492 def __le__(self, other): 

493 return self.tocsr().__le__(other) 

494 

495 def __ge__(self, other): 

496 return self.tocsr().__ge__(other) 

497 

498 def __abs__(self): 

499 return abs(self.tocsr()) 

500 

501 def __round__(self, ndigits=0): 

502 return round(self.tocsr(), ndigits=ndigits) 

503 

504 def _add_sparse(self, other): 

505 return self.tocsr()._add_sparse(other) 

506 

507 def _add_dense(self, other): 

508 return self.tocoo()._add_dense(other) 

509 

510 def _sub_sparse(self, other): 

511 return self.tocsr()._sub_sparse(other) 

512 

513 def _sub_dense(self, other): 

514 return self.todense() - other 

515 

516 def _rsub_dense(self, other): 

517 # note: this can't be replaced by other + (-self) for unsigned types 

518 return other - self.todense() 

519 

520 def __add__(self, other): # self + other 

521 if isscalarlike(other): 

522 if other == 0: 

523 return self.copy() 

524 # Now we would add this scalar to every element. 

525 raise NotImplementedError('adding a nonzero scalar to a ' 

526 'sparse array is not supported') 

527 elif issparse(other): 

528 if other.shape != self.shape: 

529 raise ValueError("inconsistent shapes") 

530 return self._add_sparse(other) 

531 elif isdense(other): 

532 other = np.broadcast_to(other, self.shape) 

533 return self._add_dense(other) 

534 else: 

535 return NotImplemented 

536 

537 def __radd__(self,other): # other + self 

538 return self.__add__(other) 

539 

540 def __sub__(self, other): # self - other 

541 if isscalarlike(other): 

542 if other == 0: 

543 return self.copy() 

544 raise NotImplementedError('subtracting a nonzero scalar from a ' 

545 'sparse array is not supported') 

546 elif issparse(other): 

547 if other.shape != self.shape: 

548 raise ValueError("inconsistent shapes") 

549 return self._sub_sparse(other) 

550 elif isdense(other): 

551 other = np.broadcast_to(other, self.shape) 

552 return self._sub_dense(other) 

553 else: 

554 return NotImplemented 

555 

556 def __rsub__(self,other): # other - self 

557 if isscalarlike(other): 

558 if other == 0: 

559 return -self.copy() 

560 raise NotImplementedError('subtracting a sparse array from a ' 

561 'nonzero scalar is not supported') 

562 elif isdense(other): 

563 other = np.broadcast_to(other, self.shape) 

564 return self._rsub_dense(other) 

565 else: 

566 return NotImplemented 

567 

568 def _matmul_dispatch(self, other): 

569 """np.array-like matmul & `np.matrix`-like mul, i.e. `dot` or `NotImplemented` 

570 

571 interpret other and call one of the following 

572 self._mul_scalar() 

573 self._matmul_vector() 

574 self._matmul_multivector() 

575 self._matmul_sparse() 

576 """ 

577 # This method has to be different from `__matmul__` because it is also 

578 # called by sparse matrix classes. 

579 

580 # Currently matrix multiplication is only supported 

581 # for 2D arrays. Hence we unpacked and use only the 

582 # two last axes' lengths. 

583 M, N = self._shape_as_2d 

584 

585 if other.__class__ is np.ndarray: 

586 # Fast path for the most common case 

587 if other.shape == (N,): 

588 return self._matmul_vector(other) 

589 elif other.shape == (N, 1): 

590 result = self._matmul_vector(other.ravel()) 

591 if self.ndim == 1: 

592 return result 

593 return result.reshape(M, 1) 

594 elif other.ndim == 2 and other.shape[0] == N: 

595 return self._matmul_multivector(other) 

596 

597 if isscalarlike(other): 

598 # scalar value 

599 return self._mul_scalar(other) 

600 

601 if issparse(other): 

602 if self.shape[-1] != other.shape[0]: 

603 raise ValueError('dimension mismatch') 

604 if other.ndim == 1: 

605 raise ValueError('Cannot yet multiply a 1d sparse array') 

606 return self._matmul_sparse(other) 

607 

608 # If it's a list or whatever, treat it like an array 

609 other_a = np.asanyarray(other) 

610 

611 if other_a.ndim == 0 and other_a.dtype == np.object_: 

612 # Not interpretable as an array; return NotImplemented so that 

613 # other's __rmatmul__ can kick in if that's implemented. 

614 return NotImplemented 

615 

616 try: 

617 other.shape 

618 except AttributeError: 

619 other = other_a 

620 

621 if other.ndim == 1 or other.ndim == 2 and other.shape[1] == 1: 

622 # dense row or column vector 

623 if other.shape != (N,) and other.shape != (N, 1): 

624 raise ValueError('dimension mismatch') 

625 

626 result = self._matmul_vector(np.ravel(other)) 

627 

628 if isinstance(other, np.matrix): 

629 result = self._ascontainer(result) 

630 

631 if other.ndim == 2 and other.shape[1] == 1: 

632 # If 'other' was an (nx1) column vector, reshape the result 

633 result = result.reshape(-1, 1) 

634 

635 return result 

636 

637 elif other.ndim == 2: 

638 ## 

639 # dense 2D array or matrix ("multivector") 

640 

641 if other.shape[0] != N: 

642 raise ValueError('dimension mismatch') 

643 

644 result = self._matmul_multivector(np.asarray(other)) 

645 

646 if isinstance(other, np.matrix): 

647 result = self._ascontainer(result) 

648 

649 return result 

650 

651 else: 

652 raise ValueError('could not interpret dimensions') 

653 

654 def __mul__(self, other): 

655 return self.multiply(other) 

656 

657 def __rmul__(self, other): # other * self 

658 return self.multiply(other) 

659 

660 # by default, use CSR for __mul__ handlers 

661 def _mul_scalar(self, other): 

662 return self.tocsr()._mul_scalar(other) 

663 

664 def _matmul_vector(self, other): 

665 return self.tocsr()._matmul_vector(other) 

666 

667 def _matmul_multivector(self, other): 

668 return self.tocsr()._matmul_multivector(other) 

669 

670 def _matmul_sparse(self, other): 

671 return self.tocsr()._matmul_sparse(other) 

672 

673 def _rmatmul_dispatch(self, other): 

674 if isscalarlike(other): 

675 return self._mul_scalar(other) 

676 else: 

677 # Don't use asarray unless we have to 

678 try: 

679 tr = other.transpose() 

680 except AttributeError: 

681 tr = np.asarray(other).transpose() 

682 ret = self.transpose()._matmul_dispatch(tr) 

683 if ret is NotImplemented: 

684 return NotImplemented 

685 return ret.transpose() 

686 

687 ####################### 

688 # matmul (@) operator # 

689 ####################### 

690 

691 def __matmul__(self, other): 

692 if isscalarlike(other): 

693 raise ValueError("Scalar operands are not allowed, " 

694 "use '*' instead") 

695 return self._matmul_dispatch(other) 

696 

697 def __rmatmul__(self, other): 

698 if isscalarlike(other): 

699 raise ValueError("Scalar operands are not allowed, " 

700 "use '*' instead") 

701 return self._rmatmul_dispatch(other) 

702 

703 #################### 

704 # Other Arithmetic # 

705 #################### 

706 

707 def _divide(self, other, true_divide=False, rdivide=False): 

708 if isscalarlike(other): 

709 if rdivide: 

710 if true_divide: 

711 return np.true_divide(other, self.todense()) 

712 else: 

713 return np.divide(other, self.todense()) 

714 

715 if true_divide and np.can_cast(self.dtype, np.float64): 

716 return self.astype(np.float64)._mul_scalar(1./other) 

717 else: 

718 r = self._mul_scalar(1./other) 

719 

720 scalar_dtype = np.asarray(other).dtype 

721 if (np.issubdtype(self.dtype, np.integer) and 

722 np.issubdtype(scalar_dtype, np.integer)): 

723 return r.astype(self.dtype) 

724 else: 

725 return r 

726 

727 elif isdense(other): 

728 if not rdivide: 

729 if true_divide: 

730 recip = np.true_divide(1., other) 

731 else: 

732 recip = np.divide(1., other) 

733 return self.multiply(recip) 

734 else: 

735 if true_divide: 

736 return np.true_divide(other, self.todense()) 

737 else: 

738 return np.divide(other, self.todense()) 

739 elif issparse(other): 

740 if rdivide: 

741 return other._divide(self, true_divide, rdivide=False) 

742 

743 self_csr = self.tocsr() 

744 if true_divide and np.can_cast(self.dtype, np.float64): 

745 return self_csr.astype(np.float64)._divide_sparse(other) 

746 else: 

747 return self_csr._divide_sparse(other) 

748 else: 

749 return NotImplemented 

750 

751 def __truediv__(self, other): 

752 return self._divide(other, true_divide=True) 

753 

754 def __div__(self, other): 

755 # Always do true division 

756 return self._divide(other, true_divide=True) 

757 

758 def __rtruediv__(self, other): 

759 # Implementing this as the inverse would be too magical -- bail out 

760 return NotImplemented 

761 

762 def __rdiv__(self, other): 

763 # Implementing this as the inverse would be too magical -- bail out 

764 return NotImplemented 

765 

766 def __neg__(self): 

767 return -self.tocsr() 

768 

769 def __iadd__(self, other): 

770 return NotImplemented 

771 

772 def __isub__(self, other): 

773 return NotImplemented 

774 

775 def __imul__(self, other): 

776 return NotImplemented 

777 

778 def __idiv__(self, other): 

779 return self.__itruediv__(other) 

780 

781 def __itruediv__(self, other): 

782 return NotImplemented 

783 

784 def __pow__(self, *args, **kwargs): 

785 return self.power(*args, **kwargs) 

786 

787 def transpose(self, axes=None, copy=False): 

788 """ 

789 Reverses the dimensions of the sparse array/matrix. 

790 

791 Parameters 

792 ---------- 

793 axes : None, optional 

794 This argument is in the signature *solely* for NumPy 

795 compatibility reasons. Do not pass in anything except 

796 for the default value. 

797 copy : bool, optional 

798 Indicates whether or not attributes of `self` should be 

799 copied whenever possible. The degree to which attributes 

800 are copied varies depending on the type of sparse array/matrix 

801 being used. 

802 

803 Returns 

804 ------- 

805 p : `self` with the dimensions reversed. 

806 

807 Notes 

808 ----- 

809 If `self` is a `csr_array` or a `csc_array`, then this will return a 

810 `csc_array` or a `csr_array`, respectively. 

811 

812 See Also 

813 -------- 

814 numpy.transpose : NumPy's implementation of 'transpose' for ndarrays 

815 """ 

816 return self.tocsr(copy=copy).transpose(axes=axes, copy=False) 

817 

818 def conjugate(self, copy=True): 

819 """Element-wise complex conjugation. 

820 

821 If the array/matrix is of non-complex data type and `copy` is False, 

822 this method does nothing and the data is not copied. 

823 

824 Parameters 

825 ---------- 

826 copy : bool, optional 

827 If True, the result is guaranteed to not share data with self. 

828 

829 Returns 

830 ------- 

831 A : The element-wise complex conjugate. 

832 

833 """ 

834 if np.issubdtype(self.dtype, np.complexfloating): 

835 return self.tocsr(copy=copy).conjugate(copy=False) 

836 elif copy: 

837 return self.copy() 

838 else: 

839 return self 

840 

841 def conj(self, copy=True): 

842 return self.conjugate(copy=copy) 

843 

844 conj.__doc__ = conjugate.__doc__ 

845 

846 def _real(self): 

847 return self.tocsr()._real() 

848 

849 def _imag(self): 

850 return self.tocsr()._imag() 

851 

852 def nonzero(self): 

853 """Nonzero indices of the array/matrix. 

854 

855 Returns a tuple of arrays (row,col) containing the indices 

856 of the non-zero elements of the array. 

857 

858 Examples 

859 -------- 

860 >>> from scipy.sparse import csr_array 

861 >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]]) 

862 >>> A.nonzero() 

863 (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2])) 

864 

865 """ 

866 

867 # convert to COOrdinate format 

868 A = self.tocoo() 

869 nz_mask = A.data != 0 

870 return (A.row[nz_mask], A.col[nz_mask]) 

871 

872 def _getcol(self, j): 

873 """Returns a copy of column j of the array, as an (m x 1) sparse 

874 array (column vector). 

875 """ 

876 if self.ndim == 1: 

877 raise ValueError("getcol not provided for 1d arrays. Use indexing A[j]") 

878 # Subclasses should override this method for efficiency. 

879 # Post-multiply by a (n x 1) column vector 'a' containing all zeros 

880 # except for a_j = 1 

881 N = self.shape[-1] 

882 if j < 0: 

883 j += N 

884 if j < 0 or j >= N: 

885 raise IndexError("index out of bounds") 

886 col_selector = self._csc_container(([1], [[j], [0]]), 

887 shape=(N, 1), dtype=self.dtype) 

888 result = self @ col_selector 

889 return result 

890 

891 def _getrow(self, i): 

892 """Returns a copy of row i of the array, as a (1 x n) sparse 

893 array (row vector). 

894 """ 

895 if self.ndim == 1: 

896 raise ValueError("getrow not meaningful for a 1d array") 

897 # Subclasses should override this method for efficiency. 

898 # Pre-multiply by a (1 x m) row vector 'a' containing all zeros 

899 # except for a_i = 1 

900 M = self.shape[0] 

901 if i < 0: 

902 i += M 

903 if i < 0 or i >= M: 

904 raise IndexError("index out of bounds") 

905 row_selector = self._csr_container(([1], [[0], [i]]), 

906 shape=(1, M), dtype=self.dtype) 

907 return row_selector @ self 

908 

909 # The following dunder methods cannot be implemented. 

910 # 

911 # def __array__(self): 

912 # # Sparse matrices rely on NumPy wrapping them in object arrays under 

913 # # the hood to make unary ufuncs work on them. So we cannot raise 

914 # # TypeError here - which would be handy to not give users object 

915 # # arrays they probably don't want (they're looking for `.toarray()`). 

916 # # 

917 # # Conversion with `toarray()` would also break things because of the 

918 # # behavior discussed above, plus we want to avoid densification by 

919 # # accident because that can too easily blow up memory. 

920 # 

921 # def __array_ufunc__(self): 

922 # # We cannot implement __array_ufunc__ due to mismatching semantics. 

923 # # See gh-7707 and gh-7349 for details. 

924 # 

925 # def __array_function__(self): 

926 # # We cannot implement __array_function__ due to mismatching semantics. 

927 # # See gh-10362 for details. 

928 

929 def todense(self, order=None, out=None): 

930 """ 

931 Return a dense representation of this sparse array/matrix. 

932 

933 Parameters 

934 ---------- 

935 order : {'C', 'F'}, optional 

936 Whether to store multi-dimensional data in C (row-major) 

937 or Fortran (column-major) order in memory. The default 

938 is 'None', which provides no ordering guarantees. 

939 Cannot be specified in conjunction with the `out` 

940 argument. 

941 

942 out : ndarray, 2-D, optional 

943 If specified, uses this array (or `numpy.matrix`) as the 

944 output buffer instead of allocating a new array to 

945 return. The provided array must have the same shape and 

946 dtype as the sparse array/matrix on which you are calling the 

947 method. 

948 

949 Returns 

950 ------- 

951 arr : numpy.matrix, 2-D 

952 A NumPy matrix object with the same shape and containing 

953 the same data represented by the sparse array/matrix, with the 

954 requested memory order. If `out` was passed and was an 

955 array (rather than a `numpy.matrix`), it will be filled 

956 with the appropriate values and returned wrapped in a 

957 `numpy.matrix` object that shares the same memory. 

958 """ 

959 return self._ascontainer(self.toarray(order=order, out=out)) 

960 

961 def toarray(self, order=None, out=None): 

962 """ 

963 Return a dense ndarray representation of this sparse array/matrix. 

964 

965 Parameters 

966 ---------- 

967 order : {'C', 'F'}, optional 

968 Whether to store multidimensional data in C (row-major) 

969 or Fortran (column-major) order in memory. The default 

970 is 'None', which provides no ordering guarantees. 

971 Cannot be specified in conjunction with the `out` 

972 argument. 

973 

974 out : ndarray, 2-D, optional 

975 If specified, uses this array as the output buffer 

976 instead of allocating a new array to return. The provided 

977 array must have the same shape and dtype as the sparse 

978 array/matrix on which you are calling the method. For most 

979 sparse types, `out` is required to be memory contiguous 

980 (either C or Fortran ordered). 

981 

982 Returns 

983 ------- 

984 arr : ndarray, 2-D 

985 An array with the same shape and containing the same 

986 data represented by the sparse array/matrix, with the requested 

987 memory order. If `out` was passed, the same object is 

988 returned after being modified in-place to contain the 

989 appropriate values. 

990 """ 

991 return self.tocoo(copy=False).toarray(order=order, out=out) 

992 

993 # Any sparse array format deriving from _spbase must define one of 

994 # tocsr or tocoo. The other conversion methods may be implemented for 

995 # efficiency, but are not required. 

996 def tocsr(self, copy=False): 

997 """Convert this array/matrix to Compressed Sparse Row format. 

998 

999 With copy=False, the data/indices may be shared between this array/matrix and 

1000 the resultant csr_array/matrix. 

1001 """ 

1002 return self.tocoo(copy=copy).tocsr(copy=False) 

1003 

1004 def todok(self, copy=False): 

1005 """Convert this array/matrix to Dictionary Of Keys format. 

1006 

1007 With copy=False, the data/indices may be shared between this array/matrix and 

1008 the resultant dok_array/matrix. 

1009 """ 

1010 return self.tocoo(copy=copy).todok(copy=False) 

1011 

1012 def tocoo(self, copy=False): 

1013 """Convert this array/matrix to COOrdinate format. 

1014 

1015 With copy=False, the data/indices may be shared between this array/matrix and 

1016 the resultant coo_array/matrix. 

1017 """ 

1018 return self.tocsr(copy=False).tocoo(copy=copy) 

1019 

1020 def tolil(self, copy=False): 

1021 """Convert this array/matrix to List of Lists format. 

1022 

1023 With copy=False, the data/indices may be shared between this array/matrix and 

1024 the resultant lil_array/matrix. 

1025 """ 

1026 return self.tocsr(copy=False).tolil(copy=copy) 

1027 

1028 def todia(self, copy=False): 

1029 """Convert this array/matrix to sparse DIAgonal format. 

1030 

1031 With copy=False, the data/indices may be shared between this array/matrix and 

1032 the resultant dia_array/matrix. 

1033 """ 

1034 return self.tocoo(copy=copy).todia(copy=False) 

1035 

1036 def tobsr(self, blocksize=None, copy=False): 

1037 """Convert this array/matrix to Block Sparse Row format. 

1038 

1039 With copy=False, the data/indices may be shared between this array/matrix and 

1040 the resultant bsr_array/matrix. 

1041 

1042 When blocksize=(R, C) is provided, it will be used for construction of 

1043 the bsr_array/matrix. 

1044 """ 

1045 return self.tocsr(copy=False).tobsr(blocksize=blocksize, copy=copy) 

1046 

1047 def tocsc(self, copy=False): 

1048 """Convert this array/matrix to Compressed Sparse Column format. 

1049 

1050 With copy=False, the data/indices may be shared between this array/matrix and 

1051 the resultant csc_array/matrix. 

1052 """ 

1053 return self.tocsr(copy=copy).tocsc(copy=False) 

1054 

1055 def copy(self): 

1056 """Returns a copy of this array/matrix. 

1057 

1058 No data/indices will be shared between the returned value and current 

1059 array/matrix. 

1060 """ 

1061 return self.__class__(self, copy=True) 

1062 

1063 def sum(self, axis=None, dtype=None, out=None): 

1064 """ 

1065 Sum the array/matrix elements over a given axis. 

1066 

1067 Parameters 

1068 ---------- 

1069 axis : {-2, -1, 0, 1, None} optional 

1070 Axis along which the sum is computed. The default is to 

1071 compute the sum of all the array/matrix elements, returning a scalar 

1072 (i.e., `axis` = `None`). 

1073 dtype : dtype, optional 

1074 The type of the returned array/matrix and of the accumulator in which 

1075 the elements are summed. The dtype of `a` is used by default 

1076 unless `a` has an integer dtype of less precision than the default 

1077 platform integer. In that case, if `a` is signed then the platform 

1078 integer is used while if `a` is unsigned then an unsigned integer 

1079 of the same precision as the platform integer is used. 

1080 

1081 .. versionadded:: 0.18.0 

1082 

1083 out : np.matrix, optional 

1084 Alternative output matrix in which to place the result. It must 

1085 have the same shape as the expected output, but the type of the 

1086 output values will be cast if necessary. 

1087 

1088 .. versionadded:: 0.18.0 

1089 

1090 Returns 

1091 ------- 

1092 sum_along_axis : np.matrix 

1093 A matrix with the same shape as `self`, with the specified 

1094 axis removed. 

1095 

1096 See Also 

1097 -------- 

1098 numpy.matrix.sum : NumPy's implementation of 'sum' for matrices 

1099 

1100 """ 

1101 validateaxis(axis) 

1102 

1103 # Mimic numpy's casting. 

1104 res_dtype = get_sum_dtype(self.dtype) 

1105 

1106 if self.ndim == 1: 

1107 if axis not in (None, -1, 0): 

1108 raise ValueError("axis must be None, -1 or 0") 

1109 ret = (self @ np.ones(self.shape, dtype=res_dtype)).astype(dtype) 

1110 

1111 if out is not None: 

1112 if any(dim != 1 for dim in out.shape): 

1113 raise ValueError("dimensions do not match") 

1114 out[...] = ret 

1115 return ret 

1116 

1117 # We use multiplication by a matrix of ones to achieve this. 

1118 # For some sparse array formats more efficient methods are 

1119 # possible -- these should override this function. 

1120 M, N = self.shape 

1121 

1122 if axis is None: 

1123 # sum over rows and columns 

1124 return ( 

1125 self @ self._ascontainer(np.ones((N, 1), dtype=res_dtype)) 

1126 ).sum(dtype=dtype, out=out) 

1127 

1128 if axis < 0: 

1129 axis += 2 

1130 

1131 # axis = 0 or 1 now 

1132 if axis == 0: 

1133 # sum over columns 

1134 ret = self._ascontainer( 

1135 np.ones((1, M), dtype=res_dtype) 

1136 ) @ self 

1137 else: 

1138 # sum over rows 

1139 ret = self @ self._ascontainer( 

1140 np.ones((N, 1), dtype=res_dtype) 

1141 ) 

1142 

1143 if out is not None and out.shape != ret.shape: 

1144 raise ValueError("dimensions do not match") 

1145 

1146 return ret.sum(axis=axis, dtype=dtype, out=out) 

1147 

1148 def mean(self, axis=None, dtype=None, out=None): 

1149 """ 

1150 Compute the arithmetic mean along the specified axis. 

1151 

1152 Returns the average of the array/matrix elements. The average is taken 

1153 over all elements in the array/matrix by default, otherwise over the 

1154 specified axis. `float64` intermediate and return values are used 

1155 for integer inputs. 

1156 

1157 Parameters 

1158 ---------- 

1159 axis : {-2, -1, 0, 1, None} optional 

1160 Axis along which the mean is computed. The default is to compute 

1161 the mean of all elements in the array/matrix (i.e., `axis` = `None`). 

1162 dtype : data-type, optional 

1163 Type to use in computing the mean. For integer inputs, the default 

1164 is `float64`; for floating point inputs, it is the same as the 

1165 input dtype. 

1166 

1167 .. versionadded:: 0.18.0 

1168 

1169 out : np.matrix, optional 

1170 Alternative output matrix in which to place the result. It must 

1171 have the same shape as the expected output, but the type of the 

1172 output values will be cast if necessary. 

1173 

1174 .. versionadded:: 0.18.0 

1175 

1176 Returns 

1177 ------- 

1178 m : np.matrix 

1179 

1180 See Also 

1181 -------- 

1182 numpy.matrix.mean : NumPy's implementation of 'mean' for matrices 

1183 

1184 """ 

1185 validateaxis(axis) 

1186 

1187 res_dtype = self.dtype.type 

1188 integral = (np.issubdtype(self.dtype, np.integer) or 

1189 np.issubdtype(self.dtype, np.bool_)) 

1190 

1191 # output dtype 

1192 if dtype is None: 

1193 if integral: 

1194 res_dtype = np.float64 

1195 else: 

1196 res_dtype = np.dtype(dtype).type 

1197 

1198 # intermediate dtype for summation 

1199 inter_dtype = np.float64 if integral else res_dtype 

1200 inter_self = self.astype(inter_dtype) 

1201 

1202 if self.ndim == 1: 

1203 if axis not in (None, -1, 0): 

1204 raise ValueError("axis must be None, -1 or 0") 

1205 res = inter_self / self.shape[-1] 

1206 return res.sum(dtype=res_dtype, out=out) 

1207 

1208 if axis is None: 

1209 return (inter_self / (self.shape[0] * self.shape[1]))\ 

1210 .sum(dtype=res_dtype, out=out) 

1211 

1212 if axis < 0: 

1213 axis += 2 

1214 

1215 # axis = 0 or 1 now 

1216 if axis == 0: 

1217 return (inter_self * (1.0 / self.shape[0])).sum( 

1218 axis=0, dtype=res_dtype, out=out) 

1219 else: 

1220 return (inter_self * (1.0 / self.shape[1])).sum( 

1221 axis=1, dtype=res_dtype, out=out) 

1222 

1223 def diagonal(self, k=0): 

1224 """Returns the kth diagonal of the array/matrix. 

1225 

1226 Parameters 

1227 ---------- 

1228 k : int, optional 

1229 Which diagonal to get, corresponding to elements a[i, i+k]. 

1230 Default: 0 (the main diagonal). 

1231 

1232 .. versionadded:: 1.0 

1233 

1234 See also 

1235 -------- 

1236 numpy.diagonal : Equivalent numpy function. 

1237 

1238 Examples 

1239 -------- 

1240 >>> from scipy.sparse import csr_array 

1241 >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]]) 

1242 >>> A.diagonal() 

1243 array([1, 0, 5]) 

1244 >>> A.diagonal(k=1) 

1245 array([2, 3]) 

1246 """ 

1247 return self.tocsr().diagonal(k=k) 

1248 

1249 def trace(self, offset=0): 

1250 """Returns the sum along diagonals of the sparse array/matrix. 

1251 

1252 Parameters 

1253 ---------- 

1254 offset : int, optional 

1255 Which diagonal to get, corresponding to elements a[i, i+offset]. 

1256 Default: 0 (the main diagonal). 

1257 

1258 """ 

1259 return self.diagonal(k=offset).sum() 

1260 

1261 def setdiag(self, values, k=0): 

1262 """ 

1263 Set diagonal or off-diagonal elements of the array/matrix. 

1264 

1265 Parameters 

1266 ---------- 

1267 values : array_like 

1268 New values of the diagonal elements. 

1269 

1270 Values may have any length. If the diagonal is longer than values, 

1271 then the remaining diagonal entries will not be set. If values are 

1272 longer than the diagonal, then the remaining values are ignored. 

1273 

1274 If a scalar value is given, all of the diagonal is set to it. 

1275 

1276 k : int, optional 

1277 Which off-diagonal to set, corresponding to elements a[i,i+k]. 

1278 Default: 0 (the main diagonal). 

1279 

1280 """ 

1281 M, N = self.shape 

1282 if (k > 0 and k >= N) or (k < 0 and -k >= M): 

1283 raise ValueError("k exceeds array dimensions") 

1284 self._setdiag(np.asarray(values), k) 

1285 

1286 def _setdiag(self, values, k): 

1287 """This part of the implementation gets overridden by the 

1288 different formats. 

1289 """ 

1290 M, N = self.shape 

1291 if k < 0: 

1292 if values.ndim == 0: 

1293 # broadcast 

1294 max_index = min(M+k, N) 

1295 for i in range(max_index): 

1296 self[i - k, i] = values 

1297 else: 

1298 max_index = min(M+k, N, len(values)) 

1299 if max_index <= 0: 

1300 return 

1301 for i, v in enumerate(values[:max_index]): 

1302 self[i - k, i] = v 

1303 else: 

1304 if values.ndim == 0: 

1305 # broadcast 

1306 max_index = min(M, N-k) 

1307 for i in range(max_index): 

1308 self[i, i + k] = values 

1309 else: 

1310 max_index = min(M, N-k, len(values)) 

1311 if max_index <= 0: 

1312 return 

1313 for i, v in enumerate(values[:max_index]): 

1314 self[i, i + k] = v 

1315 

1316 def _process_toarray_args(self, order, out): 

1317 if out is not None: 

1318 if order is not None: 

1319 raise ValueError('order cannot be specified if out ' 

1320 'is not None') 

1321 if out.shape != self.shape or out.dtype != self.dtype: 

1322 raise ValueError('out array must be same dtype and shape as ' 

1323 'sparse array') 

1324 out[...] = 0. 

1325 return out 

1326 else: 

1327 return np.zeros(self.shape, dtype=self.dtype, order=order) 

1328 

1329 def _get_index_dtype(self, arrays=(), maxval=None, check_contents=False): 

1330 """ 

1331 Determine index dtype for array. 

1332 

1333 This wraps _sputils.get_index_dtype, providing compatibility for both 

1334 array and matrix API sparse matrices. Matrix API sparse matrices would 

1335 attempt to downcast the indices - which can be computationally 

1336 expensive and undesirable for users. The array API changes this 

1337 behaviour. 

1338 

1339 See discussion: https://github.com/scipy/scipy/issues/16774 

1340 

1341 The get_index_dtype import is due to implementation details of the test 

1342 suite. It allows the decorator ``with_64bit_maxval_limit`` to mock a 

1343 lower int32 max value for checks on the matrix API's downcasting 

1344 behaviour. 

1345 """ 

1346 from ._sputils import get_index_dtype 

1347 

1348 # Don't check contents for array API 

1349 return get_index_dtype(arrays, 

1350 maxval, 

1351 (check_contents and not isinstance(self, sparray))) 

1352 

1353 

1354 ## All methods below are deprecated and should be removed in 

1355 ## scipy 1.14.0 

1356 ## 

1357 ## Also uncomment the definition of shape above. 

1358 

1359 def get_shape(self): 

1360 """Get shape of a sparse array/matrix. 

1361 

1362 .. deprecated:: 1.11.0 

1363 This method will be removed in SciPy 1.14.0. 

1364 Use `X.shape` instead. 

1365 """ 

1366 msg = ( 

1367 "`get_shape` is deprecated and will be removed in v1.14.0; " 

1368 "use `X.shape` instead." 

1369 ) 

1370 warn(msg, DeprecationWarning, stacklevel=2) 

1371 

1372 return self._shape 

1373 

1374 def set_shape(self, shape): 

1375 """See `reshape`. 

1376 

1377 .. deprecated:: 1.11.0 

1378 This method will be removed in SciPy 1.14.0. 

1379 Use `X.reshape` instead. 

1380 """ 

1381 msg = ( 

1382 "Shape assignment is deprecated and will be removed in v1.14.0; " 

1383 "use `reshape` instead." 

1384 ) 

1385 warn(msg, DeprecationWarning, stacklevel=2) 

1386 

1387 # Make sure copy is False since this is in place 

1388 # Make sure format is unchanged because we are doing a __dict__ swap 

1389 new_self = self.reshape(shape, copy=False).asformat(self.format) 

1390 self.__dict__ = new_self.__dict__ 

1391 

1392 shape = property( 

1393 fget=lambda self: self._shape, 

1394 fset=set_shape, 

1395 doc="""The shape of the array. 

1396 

1397Note that, starting in SciPy 1.14.0, this property will no longer be 

1398settable. To change the array shape, use `X.reshape` instead. 

1399""" 

1400 ) 

1401 

1402 def asfptype(self): 

1403 """Upcast array/matrix to a floating point format (if necessary) 

1404 

1405 .. deprecated:: 1.11.0 

1406 This method is for internal use only, and will be removed from the 

1407 public API in SciPy 1.14.0. 

1408 """ 

1409 msg = ( 

1410 "`asfptype` is an internal function, and is deprecated " 

1411 "as part of the public API. It will be removed in v1.14.0." 

1412 ) 

1413 warn(msg, DeprecationWarning, stacklevel=2) 

1414 return self._asfptype() 

1415 

1416 def getmaxprint(self): 

1417 """Maximum number of elements to display when printed. 

1418 

1419 .. deprecated:: 1.11.0 

1420 This method is for internal use only, and will be removed from the 

1421 public API in SciPy 1.14.0. 

1422 """ 

1423 msg = ( 

1424 "`getmaxprint` is an internal function, and is deprecated " 

1425 "as part of the public API. It will be removed in v1.14.0." 

1426 ) 

1427 warn(msg, DeprecationWarning, stacklevel=2) 

1428 return self._getmaxprint() 

1429 

1430 def getformat(self): 

1431 """Sparse array/matrix storage format. 

1432 

1433 .. deprecated:: 1.11.0 

1434 This method will be removed in SciPy 1.14.0. 

1435 Use `X.format` instead. 

1436 """ 

1437 msg = ( 

1438 "`getformat` is deprecated and will be removed in v1.14.0; " 

1439 "use `X.format` instead." 

1440 ) 

1441 warn(msg, DeprecationWarning, stacklevel=2) 

1442 return self.format 

1443 

1444 def getnnz(self, axis=None): 

1445 """Number of stored values, including explicit zeros. 

1446 

1447 Parameters 

1448 ---------- 

1449 axis : None, 0, or 1 

1450 Select between the number of values across the whole array/matrix, in 

1451 each column, or in each row. 

1452 

1453 See also 

1454 -------- 

1455 count_nonzero : Number of non-zero entries 

1456 """ 

1457 return self._getnnz(axis=axis) 

1458 

1459 def getH(self): 

1460 """Return the Hermitian transpose of this array/matrix. 

1461 

1462 .. deprecated:: 1.11.0 

1463 This method will be removed in SciPy 1.14.0. 

1464 Use `X.conj().T` instead. 

1465 """ 

1466 msg = ( 

1467 "`getH` is deprecated and will be removed in v1.14.0; " 

1468 "use `X.conj().T` instead." 

1469 ) 

1470 warn(msg, DeprecationWarning, stacklevel=2) 

1471 return self.conjugate().transpose() 

1472 

1473 def getcol(self, j): 

1474 """Returns a copy of column j of the array/matrix, as an (m x 1) sparse 

1475 array/matrix (column vector). 

1476 

1477 .. deprecated:: 1.11.0 

1478 This method will be removed in SciPy 1.14.0. 

1479 Use array/matrix indexing instead. 

1480 """ 

1481 msg = ( 

1482 "`getcol` is deprecated and will be removed in v1.14.0; " 

1483 f"use `X[:, [{j}]]` instead." 

1484 ) 

1485 warn(msg, DeprecationWarning, stacklevel=2) 

1486 return self._getcol(j) 

1487 

1488 def getrow(self, i): 

1489 """Returns a copy of row i of the array/matrix, as a (1 x n) sparse 

1490 array/matrix (row vector). 

1491 

1492 .. deprecated:: 1.11.0 

1493 This method will be removed in SciPy 1.14.0. 

1494 Use array/matrix indexing instead. 

1495 """ 

1496 msg = ( 

1497 "`getrow` is deprecated and will be removed in v1.14.0; " 

1498 f"use `X[[{i}]]` instead." 

1499 ) 

1500 warn(msg, DeprecationWarning, stacklevel=2) 

1501 return self._getrow(i) 

1502 

1503 ## End 1.14.0 deprecated methods 

1504 

1505 

1506class sparray: 

1507 """A namespace class to separate sparray from spmatrix""" 

1508 pass 

1509 

1510sparray.__doc__ = _spbase.__doc__ 

1511 

1512 

1513def issparse(x): 

1514 """Is `x` of a sparse array or sparse matrix type? 

1515 

1516 Parameters 

1517 ---------- 

1518 x 

1519 object to check for being a sparse array or sparse matrix 

1520 

1521 Returns 

1522 ------- 

1523 bool 

1524 True if `x` is a sparse array or a sparse matrix, False otherwise 

1525 

1526 Examples 

1527 -------- 

1528 >>> import numpy as np 

1529 >>> from scipy.sparse import csr_array, csr_matrix, issparse 

1530 >>> issparse(csr_matrix([[5]])) 

1531 True 

1532 >>> issparse(csr_array([[5]])) 

1533 True 

1534 >>> issparse(np.array([[5]])) 

1535 False 

1536 >>> issparse(5) 

1537 False 

1538 """ 

1539 return isinstance(x, _spbase) 

1540 

1541 

1542def isspmatrix(x): 

1543 """Is `x` of a sparse matrix type? 

1544 

1545 Parameters 

1546 ---------- 

1547 x 

1548 object to check for being a sparse matrix 

1549 

1550 Returns 

1551 ------- 

1552 bool 

1553 True if `x` is a sparse matrix, False otherwise 

1554 

1555 Examples 

1556 -------- 

1557 >>> import numpy as np 

1558 >>> from scipy.sparse import csr_array, csr_matrix, isspmatrix 

1559 >>> isspmatrix(csr_matrix([[5]])) 

1560 True 

1561 >>> isspmatrix(csr_array([[5]])) 

1562 False 

1563 >>> isspmatrix(np.array([[5]])) 

1564 False 

1565 >>> isspmatrix(5) 

1566 False 

1567 """ 

1568 return isinstance(x, spmatrix)