From e79abfbbe64398744a311bb9ff2a6dc1bebdde98 Mon Sep 17 00:00:00 2001 From: Nick Papior Date: Wed, 1 Oct 2025 15:23:21 +0200 Subject: [PATCH] Changed to scipy.sparse.*_array This will be the preferred way of interacting with scipy sparse matrices. However, they have the down-side of not allowing 1D slicing (in older versions). Only in scipy commit: 66ec33370c889e9c9acba320354b624ee258ee22 did this enter (in June 2024). So for now, it has to be limited only, but with the latest scipy, it shouldn't be a problem. --- changes/902.change.rst | 8 + src/sisl/_core/geometry.py | 4 +- src/sisl/_core/grid.py | 8 +- src/sisl/_core/sparse.py | 144 +++++++++--------- src/sisl/_core/sparse_geometry.py | 6 +- src/sisl/_core/tests/test_grid.py | 6 +- src/sisl/_core/tests/test_sparse.py | 24 +-- src/sisl/_core/tests/test_sparse_geometry.py | 14 +- src/sisl/io/dftb/realdat.py | 4 +- src/sisl/io/gulp/fc.py | 6 +- src/sisl/io/gulp/got.py | 6 +- src/sisl/io/ham.py | 6 +- src/sisl/io/scaleup/rham.py | 4 +- src/sisl/io/siesta/fdf.py | 6 +- src/sisl/io/tbtrans/tbt.py | 62 ++++---- src/sisl/io/tbtrans/tbtproj.py | 4 +- src/sisl/io/wannier90/seedname.py | 6 +- src/sisl/physics/_ufuncs_matrix.py | 6 +- src/sisl/physics/densitymatrix.py | 12 +- src/sisl/physics/dynamicalmatrix.py | 7 +- src/sisl/physics/electron.py | 4 +- src/sisl/physics/energydensitymatrix.py | 8 +- src/sisl/physics/hamiltonian.py | 6 +- src/sisl/physics/sparse.py | 70 ++++----- src/sisl/physics/tests/test_hamiltonian.py | 6 +- src/sisl/physics/tests/test_physics_sparse.py | 8 +- src/sisl/tests/test_sparse_grid.py | 4 +- src/sisl_toolbox/btd/_green.py | 2 +- 28 files changed, 231 insertions(+), 220 deletions(-) create mode 100644 changes/902.change.rst diff --git a/changes/902.change.rst b/changes/902.change.rst new file mode 100644 index 0000000000..f2a4a20007 --- /dev/null +++ b/changes/902.change.rst @@ -0,0 +1,8 @@ +Changed internal ``scipy.sparse.*_matrix`` to ``*_array`` + +This is necessary to further the usage of scipy which +now encourages the use of ``*_array``. + +There are some missing features using the array-like +interface, but they should be easy to circumvent +until full compatibility is shipped in scipy. diff --git a/src/sisl/_core/geometry.py b/src/sisl/_core/geometry.py index d2f29e58ab..833e995801 100644 --- a/src/sisl/_core/geometry.py +++ b/src/sisl/_core/geometry.py @@ -31,7 +31,7 @@ tile, unique, ) -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array import sisl._array as _a from sisl._category import Category, GenericCategory @@ -4078,7 +4078,7 @@ def sphere_grid_index(grid, center, R): grid_indices = grid_indices[:i_value] orbital_indices = orbital_indices[:i_value] - psi_values = csr_matrix( + psi_values = csr_array( (grid_values, (grid_indices, orbital_indices)), shape=(np.prod(grid.shape), sp_grid_geom.no_s), ) diff --git a/src/sisl/_core/grid.py b/src/sisl/_core/grid.py index 5c50e51cf8..05162b982b 100644 --- a/src/sisl/_core/grid.py +++ b/src/sisl/_core/grid.py @@ -12,6 +12,8 @@ import numpy as np from numpy import add, asarray, cos, dot, floor, int32, ogrid, sin, take from scipy.ndimage import zoom as ndimage_zoom + +# TODO: scipy >= 1.11 use diags_array from scipy.sparse import SparseEfficiencyWarning from scipy.sparse import diags as sp_diags @@ -1067,7 +1069,7 @@ def pyamg_fix(self, A, b, pyamg_indices, value): Parameters ---------- - A : `~scipy.sparse.csr_matrix`/`~scipy.sparse.csc_matrix` + A : `~scipy.sparse.csr_array`/`~scipy.sparse.csc_matrix` sparse matrix describing the LHS for the linear system of equations b : numpy.ndarray a vector containing RHS of :math:`\mathbf A \mathbf x = \mathbf b` for the solution of the grid stencil @@ -1111,7 +1113,7 @@ def pyamg_boundary_condition(self, A, b): Parameters ---------- - A : scipy.sparse.csr_matrix + A : scipy.sparse.csr_array sparse matrix describing the grid b : numpy.ndarray a vector containing RHS of :math:`\mathbf A \mathbf x = \mathbf b` for the solution of the grid stencil @@ -1203,7 +1205,7 @@ def topyamg(self, dtype=None): Returns ------- - scipy.sparse.csr_matrix + scipy.sparse.csr_array the stencil for the `pyamg` solver numpy.ndarray RHS of the linear system of equations diff --git a/src/sisl/_core/sparse.py b/src/sisl/_core/sparse.py index b2d5eab36c..6fa8121eae 100644 --- a/src/sisl/_core/sparse.py +++ b/src/sisl/_core/sparse.py @@ -44,7 +44,7 @@ zeros, ) from numpy.lib.mixins import NDArrayOperatorsMixin -from scipy.sparse import csr_matrix, issparse +from scipy.sparse import csr_array, issparse from sisl import _array as _a from sisl._array import array_arange @@ -57,7 +57,7 @@ from ._sparse import sparse_dense -# Although this re-implements the CSR in scipy.sparse.csr_matrix +# Although this re-implements the CSR in scipy.sparse.csr_array # we use it slightly differently and thus require this new sparse pattern. __all__ = ["SparseCSR", "ispmatrix", "ispmatrixd"] @@ -175,20 +175,20 @@ def invalid_index(idx, shape: int): @set_module("sisl") class SparseCSR(NDArrayOperatorsMixin): """ - A compressed sparse row matrix, slightly different than :class:`~scipy.sparse.csr_matrix`. + A compressed sparse row matrix, slightly different than :class:`~scipy.sparse.csr_array`. This class holds all required information regarding the CSR matrix format. - Note that this sparse matrix of data does not retain the number of columns + Note that this sparse array of data does not retain the number of columns in the matrix, i.e. it has no way of determining whether the input is correct. - This sparse matrix class tries to resemble the - :class:`~scipy.sparse.csr_matrix` as much as possible with + This sparse array class tries to resemble the + :class:`~scipy.sparse.csr_array` as much as possible with the difference of this class being multi-dimensional. - Creating a new sparse matrix is much similar to the + Creating a new sparse array is much similar to the `scipy` equivalent. `nnz` is only used if ``nnz > nr * nnzpr``. @@ -198,20 +198,20 @@ class SparseCSR(NDArrayOperatorsMixin): - ``SparseCSR(S)`` where ``S`` is a `scipy.sparse` matrix - ``SparseCSR((M,N)[, dtype])`` - the shape of the sparse matrix (equivalent + the shape of the sparse array (equivalent to ``SparseCSR((M,N,1)[, dtype])``. - ``SparseCSR((M,N), dim=K, [, dtype])`` - the shape of the sparse matrix (equivalent + the shape of the sparse array (equivalent to ``SparseCSR((M,N,K)[, dtype])``. - ``SparseCSR((M,N,K)[, dtype])`` - creating a sparse matrix with ``M`` rows, ``N`` columns + creating a sparse array with ``M`` rows, ``N`` columns and ``K`` elements per sparse element. - ``SparseCSR((data, ptr, indices), [shape, dtype])`` - creating a sparse matrix with specific data as would - be used when creating `scipy.sparse.csr_matrix`. + creating a sparse array with specific data as would + be used when creating `scipy.sparse.csr_array`. Additionally these parameters control the - creation of the sparse matrix. + creation of the sparse array. Parameters ---------- @@ -244,9 +244,9 @@ def __init__(self, arg1, dim=1, dtype=None, nnzpr: int = 20, nnz=None, **kwargs) self._finalized = False if issparse(arg1): - # This is a sparse matrix + # This is a sparse array # The data-type is infered from the - # input sparse matrix. + # input sparse array. arg1 = arg1.tocsr() # Default shape to the CSR matrix kwargs["shape"] = kwargs.get("shape", arg1.shape) @@ -327,13 +327,13 @@ def __init_shape(self, arg1, dim=1, dtype=None, nnzpr=20, nnz=None, **kwargs): if M <= 0 or N <= 0 or K <= 0: raise ValueError( self.__class__.__name__ - + f" invalid size of sparse matrix, one of the dimensions is zero: M={M}, N={N}, K={K}" + + f" invalid size of sparse array, one of the dimensions is zero: M={M}, N={N}, K={K}" ) # Store shape self._shape = (M, N, K) - # Check default construction of sparse matrix + # Check default construction of sparse array nnzpr = max(nnzpr, 1) # Re-create options @@ -385,7 +385,7 @@ def sparsity_union( Output dtype. If not given, use the result dtype of the spmats. dim : If given, the returned SparseCSR will have this as dim. - By default the first sparse matrix in `sparse_matrices` determines + By default the first sparse array in `sparse_matrices` determines the resulting 3rd dimension. value : The used fill value. @@ -399,7 +399,7 @@ def sparsity_union( shape2 = spmats[0].shape[:2] if not all(shape2 == m.shape[:2] for m in spmats): raise ValueError( - f"Cannot find sparsity union of differently shaped sparse matrices: " + f"Cannot find sparsity union of differently shaped sparse arrays: " " & ".join(str(m.shape) for m in spmats) ) @@ -407,7 +407,7 @@ def sparsity_union( shape = shape2 + (dim,) elif len(spmats[0].shape) == 3: shape = shape2 + (spmats[0].shape[2],) - else: # csr_matrix + else: # csr_array shape = shape2 + (1,) if dtype is None: @@ -476,7 +476,7 @@ def diags(self, diagonals, offsets=0, dim: Optional[int] = None, dtype=None): if dtype is None: dtype = np.result_type(self.dtype, diagonals.dtype) - # Now create the sparse matrix + # Now create the sparse array shape = list(self.shape) shape[2] = dim shape = tuple(shape) @@ -512,8 +512,8 @@ def empty(self, keep_nnz: bool = False) -> None: keep_nnz : if ``True`` keeps the sparse elements *as is*. I.e. it will merely set the stored sparse elements to zero. - This may be advantagegous when re-constructing a new sparse - matrix from an old sparse matrix + This may be advantageous when re-constructing a new sparse + matrix from an old sparse array """ self._D[:, :] = 0.0 @@ -528,36 +528,36 @@ def empty(self, keep_nnz: bool = False) -> None: @property def shape(self) -> tuple[int, int, int]: - """The shape of the sparse matrix""" + """The shape of the sparse array""" return self._shape @property def dim(self) -> int: - """The extra dimensionality of the sparse matrix (elements per matrix element)""" + """The extra dimensionality of the sparse array (elements per matrix element)""" return self.shape[2] @property def data(self) -> np.ndarray: - """Data contained in the sparse matrix (numpy array of elements)""" + """Data contained in the sparse array (numpy array of elements)""" return self._D @property def dtype(self): - """The data-type in the sparse matrix""" + """The data-type in the sparse array""" return self._D.dtype @property def dkind(self): - """The data-type in the sparse matrix (in str)""" + """The data-type in the sparse array (in str)""" return np.dtype(self._D.dtype).kind @property def nnz(self) -> int: - """Number of non-zero elements in the sparse matrix""" + """Number of non-zero elements in the sparse array""" return self._nnz def __len__(self) -> int: - """Number of rows in the sparse matrix""" + """Number of rows in the sparse array""" return self.shape[0] @property @@ -566,12 +566,12 @@ def finalized(self) -> bool: return self._finalized def finalize(self, sort: bool = True) -> None: - """Finalizes the sparse matrix by removing all non-set elements + """Finalizes the sparse array by removing all non-set elements - One may still interact with the sparse matrix as one would previously. + One may still interact with the sparse array as one would previously. NOTE: This is mainly an internal used routine to ensure data structure - when converting to :class:`~scipy.sparse.csr_matrix` + when converting to :class:`~scipy.sparse.csr_array` Parameters ---------- @@ -617,13 +617,13 @@ def finalize(self, sort: bool = True) -> None: if len(col) != self.nnz: raise SislError( - "Final size in the sparse matrix finalization went wrong." + "Final size in the sparse array finalization went wrong." ) # pragma: no cover # Check that all column indices are within the expected shape if invalid_index(self.col, self.shape[1]).any(): warn( - "Sparse matrix contains column indices outside the shape " + "sparse array contains column indices outside the shape " "of the matrix. Data may not represent what is expected!" ) @@ -769,7 +769,7 @@ def delete_columns(self, cols: SeqOrScalarInt, keep_shape: bool = False): self._shape = tuple(shape) def _clean_columns(self): - """Remove all intrinsic columns that are not defined in the sparse matrix + """Remove all intrinsic columns that are not defined in the sparse array (below 0 or above nc)""" # Grab pointers ptr = self.ptr @@ -946,7 +946,7 @@ def spsame(self, other) -> bool: return True def align(self, other): - """Aligns this sparse matrix with the sparse elements of the other sparse matrix + """Aligns this sparse array with the sparse elements of the other sparse array Routine for ensuring that all non-zero elements in `other` are also in this object. @@ -958,7 +958,7 @@ def align(self, other): Parameters ---------- other : SparseCSR - the other sparse matrix to align. + the other sparse array to align. """ if self.shape[:2] != other.shape[:2]: @@ -997,7 +997,7 @@ def iter_nnz(self, rows: Optional[SeqOrScalarInt] = None): >>> self[r, c] - returns the non-zero element of the sparse matrix. + returns the non-zero element of the sparse array. Parameters ---------- @@ -1048,7 +1048,7 @@ def _extend(self, i, j, ret_indices=True): return _a.arrayi([]) if i.size > 1: raise ValueError( - "extending the sparse matrix is only allowed for single rows at a time" + "extending the sparse array is only allowed for single rows at a time" ) if invalid_index(i, self.shape[0]): raise IndexError(f"row index is out-of-bounds {i} : {self.shape[0]}") @@ -1056,7 +1056,7 @@ def _extend(self, i, j, ret_indices=True): # We skip this check and let sisl die if wrong input is given... # if not isinstance(i, Integral): - # raise ValueError("Retrieving/Setting elements in a sparse matrix" + # raise ValueError("Retrieving/Setting elements in a sparse array" # " must only be performed at one row-element at a time.\n" # "However, multiple columns at a time are allowed.") # Ensure flattened array... @@ -1095,7 +1095,7 @@ def _extend(self, i, j, ret_indices=True): ncol_ptr_i = ptr_i + ncol_i # Check how many elements cannot fit in the currently - # allocated sparse matrix... + # allocated sparse array... new_nnz = new_n - int(ptr[i1]) + ncol_ptr_i if new_nnz > 0: @@ -1106,7 +1106,7 @@ def _extend(self, i, j, ret_indices=True): # on first expansion calls this part. self._finalized = False - # Get how much larger we wish to create the sparse matrix... + # Get how much larger we wish to create the sparse array... ns = max(self._ns, new_nnz) # ...expand size of the sparsity pattern... @@ -1145,7 +1145,7 @@ def _extend(self, i, j, ret_indices=True): # Step the number of non-zero elements self._nnz += new_n - # Now we have extended the sparse matrix to hold all + # Now we have extended the sparse array to hold all # information that is required... # ... retrieve the indices and return @@ -1297,7 +1297,7 @@ def __delitem__(self, key): self._nnz -= n_index def __getitem__(self, key): - """Intrinsic sparse matrix retrieval of a non-zero element""" + """Intrinsic sparse array retrieval of a non-zero element""" # Get indices of sparse data (-1 if non-existing) get_idx = self._get(key[0], key[1]) @@ -1337,7 +1337,7 @@ def __getitem__(self, key): return r def __setitem__(self, key, data): - """Intrinsic sparse matrix assignment of the item. + """Intrinsic sparse array assignment of the item. It will only allow to set the data in the sparse matrix if the dimensions match. @@ -1480,7 +1480,7 @@ def nonzero(self, rows: Optional[SeqOrScalarInt] = None, only_cols: bool = False return _to_coo(self, data=False, rows=rows) def eliminate_zeros(self, atol: float = 0.0) -> None: - """Remove all zero elememts from the sparse matrix + """Remove all zero elememts from the sparse array This is an *in-place* operation @@ -1519,7 +1519,7 @@ def eliminate_zeros(self, atol: float = 0.0) -> None: del self[r, col[idx[C0]]] def copy(self, dims: Optional[SeqOrScalarInt] = None, dtype=None): - """A deepcopy of the sparse matrix + """A deepcopy of the sparse array Parameters ---------- @@ -1529,7 +1529,7 @@ def copy(self, dims: Optional[SeqOrScalarInt] = None, dtype=None): this defaults to the dtype of the object, but one may change it if supplied. """ - # Create sparse matrix (with only one entry per + # Create sparse array (with only one entry per # row, we overwrite it immediately afterward) if dims is None: dims = range(self.dim) @@ -1562,20 +1562,20 @@ def copy(self, dims: Optional[SeqOrScalarInt] = None, dtype=None): return new - def tocsr(self, dim: int = 0, **kwargs) -> csr_matrix: - """Convert dimension `dim` into a :class:`~scipy.sparse.csr_matrix` format + def tocsr(self, dim: int = 0, **kwargs) -> csr_array: + """Convert dimension `dim` into a :class:`~scipy.sparse.csr_array` format Parameters ---------- dim : - dimension of the data returned in a scipy sparse matrix format + dimension of the data returned in a scipy sparse array format **kwargs: - arguments passed to the :class:`~scipy.sparse.csr_matrix` routine + arguments passed to the :class:`~scipy.sparse.csr_array` routine """ shape = self.shape[:2] if self.finalized: # Easy case... - return csr_matrix( + return csr_array( ( self._D[:, dim].copy(), self.col.astype(int32, copy=True), @@ -1590,14 +1590,14 @@ def tocsr(self, dim: int = 0, **kwargs) -> csr_matrix: # create new pointer ptr = _ncol_to_indptr(self.ncol) - return csr_matrix( + return csr_array( (self._D[idx, dim].copy(), self.col[idx], ptr.astype(int32, copy=False)), shape=shape, **kwargs, ) def transform(self, matrix, dtype=None): - r"""Apply a linear transformation :math:`R^n \rightarrow R^m` to the :math:`n`-dimensional elements of the sparse matrix + r"""Apply a linear transformation :math:`R^n \rightarrow R^m` to the :math:`n`-dimensional elements of the sparse array Notes ----- @@ -1627,7 +1627,7 @@ def transform(self, matrix, dtype=None): f"matrix.shape={matrix.shape} and self.spin={self.shape[2]} ; out.spin={matrix.shape[0]}" ) - # set dimension of new sparse matrix + # set dimension of new sparse array new_dim = matrix.shape[0] shape = list(self.shape[:]) shape[2] = new_dim @@ -1651,7 +1651,7 @@ def astype(self, dtype, copy: bool = True) -> Self: Parameters ---------- dtype : - the new dtype for the sparse matrix + the new dtype for the sparse array copy : copy when needed, or do not copy when not needed. """ @@ -1676,7 +1676,7 @@ def fromsp(cls, sparse_matrices: OrSequence[SparseMatrix], dtype=None): Parameters ---------- sparse_matrices : - any sparse matrix which can convert to a `scipy.sparse.csr_matrix` matrix + any sparse array which can convert to a `scipy.sparse.csr_array` matrix dtype : numpy.dtype, optional data-type to store in the matrix, default to largest ``dtype`` for the passed sparse matrices @@ -1704,7 +1704,7 @@ def get_3rddim(spmat): return spmat.copy(dtype=dtype) # We are dealing with something different from a SparseCSR - # Likely some scipy.sparse matrix. + # Likely some scipy.sparse array. # Use that one. m = spmat.tocsr() out = cls(m.shape + (1,), nnzpr=1, nnz=1, dtype=dtype) @@ -1732,7 +1732,7 @@ def finalize(spmat): # Now transfer the data for r in range(out.shape[0]): - # loop across all rows of the sparse matrix + # loop across all rows of the sparse array osl = slice(out.ptr[r], out.ptr[r] + out.ncol[r]) ocol = out.col[osl] if len(ocol) == 0: @@ -1871,7 +1871,7 @@ def sub(self, indices: SeqOrScalarInt) -> Self: return csr def transpose(self, sort: bool = True): - """Create the transposed sparse matrix + """Create the transposed sparse array Parameters ---------- @@ -1886,7 +1886,7 @@ def transpose(self, sort: bool = True): Returns ------- object - an equivalent sparse matrix with transposed matrix elements + an equivalent sparse array with transposed matrix elements """ # Create a temporary copy to put data into T = self.copy() @@ -1902,7 +1902,7 @@ def transpose(self, sort: bool = True): # First extract the actual data in COO format row, col, D = _to_coo(self) - # Now we can re-create the sparse matrix + # Now we can re-create the sparse array # All we need is to count the number of non-zeros per column. rows, nrow = unique(col, return_counts=True) T.ncol = _a.zerosi(T.shape[0]) @@ -1931,7 +1931,7 @@ def transpose(self, sort: bool = True): return T def __str__(self) -> str: - """Representation of the sparse matrix model""" + """Representation of the sparse array model""" ints = self.shape[:] + (self.nnz,) return ( self.__class__.__name__ @@ -2123,7 +2123,7 @@ def rowslice(r): issorted = False else: # makes this work for all matrices - # and csr_matrix.tocsr is a no-op + # and csr_array.tocsr is a no-op mat = mat.tocsr() mat.sort_indices() @@ -2297,7 +2297,7 @@ def ispmatrix(matrix, map_row=None, map_col=None): Parameters ---------- matrix : scipy.sparse.sp_matrix - the sparse matrix to iterate non-zero elements + the sparse array to iterate non-zero elements map_row : func, optional map each row entry through the function `map_row`, defaults to ``None`` which is equivalent to no mapping. @@ -2393,7 +2393,7 @@ def ispmatrix(matrix, map_row=None, map_col=None): else: raise NotImplementedError( - "The iterator for this sparse matrix has not been implemented" + "The iterator for this sparse array has not been implemented" ) @@ -2403,7 +2403,7 @@ def _ispmatrix_all(matrix): Parameters ---------- matrix : ``scipy.sparse.*_matrix`` - the sparse matrix to iterate non-zero elements + the sparse array to iterate non-zero elements Yields ------ @@ -2437,7 +2437,7 @@ def _ispmatrix_all(matrix): else: raise NotImplementedError( - "The iterator for this sparse matrix has not been implemented" + "The iterator for this sparse array has not been implemented" ) @@ -2448,7 +2448,7 @@ def ispmatrixd(matrix, map_row=None, map_col=None): Parameters ---------- matrix : scipy.sparse.sp_matrix - the sparse matrix to iterate non-zero elements + the sparse array to iterate non-zero elements map_row : func, optional map each row entry through the function `map_row`, defaults to ``None`` which is equivalent to no mapping. @@ -2504,5 +2504,5 @@ def ispmatrixd(matrix, map_row=None, map_col=None): else: raise NotImplementedError( - "The iterator for this sparse matrix has not been implemented" + "The iterator for this sparse array has not been implemented" ) diff --git a/src/sisl/_core/sparse_geometry.py b/src/sisl/_core/sparse_geometry.py index e3f714a0b7..f355407e84 100644 --- a/src/sisl/_core/sparse_geometry.py +++ b/src/sisl/_core/sparse_geometry.py @@ -26,7 +26,7 @@ unique, ) from numpy.lib.mixins import NDArrayOperatorsMixin -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array from sisl import _array as _a from sisl._array import array_arange @@ -984,7 +984,7 @@ def conv(dim): cols = cols % geom_no + geom.sc_index(cols_lsc) * geom_no - return csr_matrix( + return csr_array( (csr.data, cols, csr.indptr), shape=(geom_no, geom_no * geom.n_s), dtype=self.dtype, @@ -1023,7 +1023,7 @@ def finalize(self, *args, **kwargs) -> None: self._csr.finalize(*args, **kwargs) def tocsr(self, dim: int = 0, isc=None, **kwargs): - """Return a :class:`~scipy.sparse.csr_matrix` for the specified dimension + """Return a :class:`~scipy.sparse.csr_array` for the specified dimension Parameters ---------- diff --git a/src/sisl/_core/tests/test_grid.py b/src/sisl/_core/tests/test_grid.py index 5d080e83b1..aa1637c3b3 100644 --- a/src/sisl/_core/tests/test_grid.py +++ b/src/sisl/_core/tests/test_grid.py @@ -5,7 +5,7 @@ import numpy as np import pytest -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array from sisl import ( Atom, @@ -398,7 +398,7 @@ def test_pyamg1(self, setup): g = setup.g.copy() g.lattice.set_boundary_condition(g.PERIODIC) # periodic boundary conditions n = np.prod(g.shape) - A = csr_matrix((n, n)) + A = csr_array((n, n)) b = np.zeros(A.shape[0]) lb = g.mgrid(slice(0, 1), slice(0, g.shape[1]), slice(0, g.shape[2])) @@ -425,7 +425,7 @@ def test_pyamg2(self, setup): with pytest.warns(SislWarning, match=r"is having image connections"): g.lattice.set_boundary_condition(bc) n = np.prod(g.shape) - A = csr_matrix((n, n)) + A = csr_array((n, n)) b = np.zeros(A.shape[0]) g.pyamg_boundary_condition(A, b) diff --git a/src/sisl/_core/tests/test_sparse.py b/src/sisl/_core/tests/test_sparse.py index 11d0489ef8..2a030b6125 100644 --- a/src/sisl/_core/tests/test_sparse.py +++ b/src/sisl/_core/tests/test_sparse.py @@ -75,9 +75,9 @@ def test_init_csr_inputs(): SparseCSR((data, indices, indptr)) -def test_csr_matrix_int64_fail(): +def test_csr_array_int64_fail(): # fixes #901 - s = sc.sparse.csr_matrix((2, 2)) + s = sc.sparse.csr_array((2, 2)) s[0, 0] = 1 s[1, 1] = 1 # this will also break scipy, but here for testing purposes: @@ -134,7 +134,7 @@ def test_init2(): def test_init3(): - lil = sc.sparse.lil_matrix((10, 10), dtype=np.int32) + lil = sc.sparse.lil_array((10, 10), dtype=np.int32) lil[0, 1] = 1 lil[0, 2] = 2 sp = SparseCSR(lil) @@ -152,7 +152,7 @@ def test_init3(): def test_init4(): - lil = sc.sparse.lil_matrix((10, 10), dtype=np.int32) + lil = sc.sparse.lil_array((10, 10), dtype=np.int32) lil[0, 1] = 1 lil[0, 2] = 2 csr = lil.tocsr() @@ -985,7 +985,7 @@ def test_op2(s1): def test_op_csr(s1): - csr = sc.sparse.csr_matrix((10, 100), dtype=np.int32) + csr = sc.sparse.csr_array((10, 100), dtype=np.int32) for i in range(10): j = range(i + 2) s1[0, j] = i @@ -1198,10 +1198,10 @@ def add3(m): @pytest.fixture(scope="module") -def matrix_csr_matrix(): +def matrix_csr_array(): matrix = [] - csr_matrix = sc.sparse.csr_matrix + csr_array = sc.sparse.csr_array def add3(m): matrix.append(m) @@ -1210,14 +1210,14 @@ def add3(m): matrix.append(m) # diagonal - m = csr_matrix((10, 80), dtype=np.int32) + m = csr_array((10, 80), dtype=np.int32) for i in range(10): m[i, i] = 1 add3(m) # not completely full (some empty ncol) - m = csr_matrix((10, 80), dtype=np.int32) + m = csr_array((10, 80), dtype=np.int32) m[0, [1, 0]] = [11, 3] m[2, 2] = 10 m[4, [4, 0]] = [22, 40] @@ -1225,7 +1225,7 @@ def add3(m): add3(m) # all more than 1 coupling, and not sorted - m = csr_matrix((10, 80), dtype=np.int32) + m = csr_array((10, 80), dtype=np.int32) m[0, [1, 0]] = [12, 4] m[1, [10, 50, 20]] = [11, 20, 401] m[2, [4, 7, 3, 1]] = [2, 5, 4, 10] @@ -1241,7 +1241,7 @@ def add3(m): @pytest.mark.parametrize("op", binary()) -def test_op_binary(matrix_sisl_csr, matrix_csr_matrix, op): +def test_op_binary(matrix_sisl_csr, matrix_csr_array, op): for m in matrix_sisl_csr: mD = m.toarray()[..., 0] if op not in (operator.add, operator.sub): @@ -1254,7 +1254,7 @@ def test_op_binary(matrix_sisl_csr, matrix_csr_matrix, op): v = op(m, m2) assert np.allclose(op(mD, m2D), v.toarray()[..., 0]) - for m2 in matrix_csr_matrix: + for m2 in matrix_csr_array: m2D = m2.toarray() v = op(m, m2) assert np.allclose(op(mD, m2D), v.toarray()[..., 0]) diff --git a/src/sisl/_core/tests/test_sparse_geometry.py b/src/sisl/_core/tests/test_sparse_geometry.py index 71e609bf6d..d13e792200 100644 --- a/src/sisl/_core/tests/test_sparse_geometry.py +++ b/src/sisl/_core/tests/test_sparse_geometry.py @@ -520,7 +520,7 @@ def test_sanitize_atoms_assign(self, setup): def test_fromsp1(self, setup): g = setup.g.repeat(2, 0).tile(2, 1) - lil = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) + lil = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) lil[0, [1, 2, 3]] = 1 lil[1, [2, 4, 1]] = 2 s1 = SparseAtom.fromsp(g, [lil], unknown_key="hello") @@ -536,8 +536,8 @@ def test_fromsp1(self, setup): def test_fromsp2(self, setup): g = setup.g.repeat(2, 0).tile(2, 1) - lil1 = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) - lil2 = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) + lil1 = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) + lil2 = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) lil1[0, [1, 2, 3]] = 1 lil2[1, [2, 4, 1]] = 2 s1 = SparseAtom.fromsp(g, [lil1, lil2]) @@ -551,8 +551,8 @@ def test_fromsp2(self, setup): def test_fromsp4(self, setup): g = setup.g.repeat(2, 0).tile(2, 1) - lil1 = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) - lil2 = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) + lil1 = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) + lil2 = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) lil1[0, [1, 2, 3]] = 1 lil2[1, [2, 4, 1]] = 2 @@ -564,8 +564,8 @@ def test_pickle(self, setup): import pickle as p g = setup.g.repeat(2, 0).tile(2, 1) - lil1 = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) - lil2 = sc.sparse.lil_matrix((g.na, g.na_s), dtype=np.int32) + lil1 = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) + lil2 = sc.sparse.lil_array((g.na, g.na_s), dtype=np.int32) lil1[0, [1, 2, 3]] = 1 lil2[1, [2, 4, 1]] = 2 S = SparseAtom.fromsp(g, [lil1, lil2]) diff --git a/src/sisl/io/dftb/realdat.py b/src/sisl/io/dftb/realdat.py index 1600b31e66..052f6031ac 100644 --- a/src/sisl/io/dftb/realdat.py +++ b/src/sisl/io/dftb/realdat.py @@ -9,7 +9,7 @@ import numpy as np import scipy.sparse as sps -from scipy.sparse import lil_matrix +from scipy.sparse import lil_array import sisl._array as _a from sisl._core import Atom, AtomicOrbital, Atoms, Geometry, Lattice @@ -71,7 +71,7 @@ def _r_matrix(self, na, nos, nneighs): # different resulting supercells. # The final construction happens in the end. # Remember that DFTB+ only returns the lower triangle of the matrix. - Hsc = defaultdict(lambda: lil_matrix((no, no), dtype=np.float64)) + Hsc = defaultdict(lambda: lil_array((no, no), dtype=np.float64)) isc = [0, 0, 0] for ia in range(na): diff --git a/src/sisl/io/gulp/fc.py b/src/sisl/io/gulp/fc.py index 7f70d7ef08..f474929667 100644 --- a/src/sisl/io/gulp/fc.py +++ b/src/sisl/io/gulp/fc.py @@ -8,7 +8,7 @@ """ import numpy as np -from scipy.sparse import lil_matrix +from scipy.sparse import lil_array from sisl._internal import set_module from sisl.messages import deprecation @@ -38,7 +38,7 @@ def read_hessian(self, **kwargs): Returns ------- - M : Hessian/force constant in `scipy.sparse.coo_matrix` format + M : Hessian/force constant in `scipy.sparse.coo_array` format """ # Default cutoff cutoff = kwargs.get("cutoff", 0.0) @@ -48,7 +48,7 @@ def read_hessian(self, **kwargs): na = int(self.readline()) no = na * 3 - fc = lil_matrix((no, no), dtype=dtype) + fc = lil_array((no, no), dtype=dtype) tmp = np.empty([3, na, 3], dtype=dtype) # Reduce overhead... diff --git a/src/sisl/io/gulp/got.py b/src/sisl/io/gulp/got.py index a5d80ad7f6..2cc40d720c 100644 --- a/src/sisl/io/gulp/got.py +++ b/src/sisl/io/gulp/got.py @@ -225,14 +225,14 @@ def read_dynamical_matrix(self, **kwargs) -> DynamicalMatrix: def _r_dynamical_matrix_got(self, geometry, **kwargs): """In case the dynamical matrix is read from the file""" # Easier for creation of the sparsity pattern - from scipy.sparse import lil_matrix + from scipy.sparse import lil_array # Default cutoff eV / Ang ** 2 cutoff = kwargs.get("cutoff", 0.0) dtype = kwargs.get("dtype", np.float64) nxyz = geometry.no - dyn = lil_matrix((nxyz, nxyz), dtype=dtype) + dyn = lil_array((nxyz, nxyz), dtype=dtype) f, _ = self.step_to(self._keys["dyn"]) if not f: @@ -277,7 +277,7 @@ def _r_dynamical_matrix_got(self, geometry, **kwargs): # clean-up for memory del dat - # Convert to COO matrix format + # Convert to COO array format dyn = dyn.tocoo() # Construct mass ** (-.5), so we can check cutoff correctly (in unit eV/Ang**2) diff --git a/src/sisl/io/ham.py b/src/sisl/io/ham.py index b010864aac..26e9a4336b 100644 --- a/src/sisl/io/ham.py +++ b/src/sisl/io/ham.py @@ -4,7 +4,7 @@ from __future__ import annotations import numpy as np -from scipy.sparse import SparseEfficiencyWarning, lil_matrix, triu +from scipy.sparse import SparseEfficiencyWarning, lil_array, triu from sisl import Atom, Geometry, Lattice from sisl import _array as _a @@ -110,8 +110,8 @@ def read_hamiltonian( # With the geometry in place we can read in the entire matrix # Create a new sparse matrix - H = lil_matrix((geom.no, geom.no_s), dtype=dtype) - S = lil_matrix((geom.no, geom.no_s), dtype=dtype) + H = lil_array((geom.no, geom.no_s), dtype=dtype) + S = lil_array((geom.no, geom.no_s), dtype=dtype) def i2o(geom, i): try: diff --git a/src/sisl/io/scaleup/rham.py b/src/sisl/io/scaleup/rham.py index 46dbfa8e27..b347da941b 100644 --- a/src/sisl/io/scaleup/rham.py +++ b/src/sisl/io/scaleup/rham.py @@ -4,7 +4,7 @@ from __future__ import annotations import numpy as np -from scipy.sparse import lil_matrix +from scipy.sparse import lil_array from sisl import Geometry from sisl.physics import Hamiltonian @@ -94,7 +94,7 @@ def pl(line): for s, isc, o1, o2, rH, iH in lines: if s != old_s: # We need to create a new Hamiltonian - H = lil_matrix((no, no_s), dtype=np.float64) + H = lil_array((no, no_s), dtype=np.float64) old_s = s Hs[s - 1] = H diff --git a/src/sisl/io/siesta/fdf.py b/src/sisl/io/siesta/fdf.py index 234b2a2474..be600f7620 100644 --- a/src/sisl/io/siesta/fdf.py +++ b/src/sisl/io/siesta/fdf.py @@ -1315,7 +1315,7 @@ def _dynamical_matrix_from_fc(self, geom, FC, FC_atoms, *args, **kwargs): if np.all(supercell <= 1): # also catches supercell == 0 - D = sp.sparse.lil_matrix((geom.no, geom.no), dtype=np.float64) + D = sp.sparse.lil_array((geom.no, geom.no), dtype=np.float64) FC = np.squeeze(FC, axis=(2, 3, 4)) # Instead of doing the sqrt in all D = FC (below) we do it here @@ -1384,8 +1384,8 @@ def _dynamical_matrix_from_fc(self, geom, FC, FC_atoms, *args, **kwargs): FC[:, :, :, :, halve_idx, :, :] *= 0.5 # Now create the dynamical matrix - # Currently this will be in lil_matrix (changed in the end) - D = sp.sparse.lil_matrix((geom.no, geom.no_s), dtype=np.float64) + # Currently this will be in lil_array (changed in the end) + D = sp.sparse.lil_array((geom.no, geom.no_s), dtype=np.float64) # When x, y, z are negative we simply look-up from the back of the array # which is exactly what is required diff --git a/src/sisl/io/tbtrans/tbt.py b/src/sisl/io/tbtrans/tbt.py index bcf881983e..20c97022ba 100644 --- a/src/sisl/io/tbtrans/tbt.py +++ b/src/sisl/io/tbtrans/tbt.py @@ -19,7 +19,7 @@ ndarray = np.ndarray # The sparse matrix for the orbital/bond currents -from scipy.sparse import SparseEfficiencyWarning, csr_matrix, issparse +from scipy.sparse import SparseEfficiencyWarning, csr_array, issparse import sisl._array as _a from sisl import Atoms, Geometry, constant @@ -1162,7 +1162,7 @@ def _sparse_data( # retrieve and return data return self._value_E(name, elec, kavg, E) - def _sparse_data_to_matrix(self, data, isc=None, orbitals=None) -> csr_matrix: + def _sparse_data_to_matrix(self, data, isc=None, orbitals=None) -> csr_array: """Internal routine for retrieving sparse data (orbital current, COOP)""" # Get the geometry for obtaining the sparsity pattern. geom = self.geometry @@ -1267,7 +1267,7 @@ def ret_range(val, req): data = data[..., all_col] - return csr_matrix((data, col, rptr), shape=mat_size) + return csr_array((data, col, rptr), shape=mat_size) def _sparse_matrix( self, @@ -1277,18 +1277,18 @@ def _sparse_matrix( kavg: Union[int, bool] = True, isc=None, orbitals=None, - ) -> csr_matrix: + ) -> csr_array: """Internal routine for retrieving sparse matrices (orbital current, COOP)""" data = self._sparse_data(name, elec, E, kavg) return self._sparse_data_to_matrix(data, isc, orbitals) def sparse_orbital_to_atom( self, Dij, uc: bool = False, sum_dup: bool = True - ) -> csr_matrix: + ) -> csr_array: """Reduce a sparse matrix in orbital sparse to a sparse matrix in atomic indices This algorithm *may* keep the same non-zero entries, but will return - a new csr_matrix with duplicate indices. + a new csr_array with duplicate indices. Notes ----- @@ -1297,7 +1297,7 @@ def sparse_orbital_to_atom( Parameters ---------- - Dij : scipy.sparse.csr_matrix + Dij : scipy.sparse.csr_array the input sparse matrix in orbital format uc : whether the returned data are only in the unit-cell. @@ -1318,13 +1318,13 @@ def sparse_orbital_to_atom( # We convert to atomic bond-currents if uc: - Dab = csr_matrix((na, na), dtype=Dij.dtype) + Dab = csr_array((na, na), dtype=Dij.dtype) def map_col(c): return o2a(c) % na else: - Dab = csr_matrix((na, na * geom.n_s), dtype=Dij.dtype) + Dab = csr_array((na, na * geom.n_s), dtype=Dij.dtype) map_col = o2a @@ -1382,7 +1382,7 @@ def sparse_atom_to_vector(self, Dab) -> ndarray: Parameters ---------- - Dab : scipy.sparse.csr_matrix + Dab : scipy.sparse.csr_array the input sparse matrix in atomic indices """ geom = self.geometry @@ -1429,7 +1429,7 @@ def sparse_orbital_to_vector( Parameters ---------- - Dij : scipy.sparse.csr_matrix + Dij : scipy.sparse.csr_array the input sparse matrix uc : whether the returned data are only in the unit-cell. @@ -1468,7 +1468,7 @@ def sparse_orbital_to_scalar(self, Dij, activity: bool = True) -> ndarray: Parameters ---------- - Dij: scipy.sparse.csr_matrix + Dij: scipy.sparse.csr_array the orbital sparse matrix. activity: ``True`` to return the atomic activity, see explanation above @@ -1514,7 +1514,7 @@ def orbital_transmission( isc=None, what: str = "all", orbitals=None, - ) -> csr_matrix: + ) -> csr_array: r"""Transmission at energy `E` between orbitals originating from `elec` Each matrix element of the sparse matrix corresponds to the orbital indices of the @@ -1566,7 +1566,7 @@ def orbital_transmission( Returns ------- - A `scipy.sparse.csr_matrix` containing the supercell transmission pathways, or + A `scipy.sparse.csr_array` containing the supercell transmission pathways, or orbital transmissions. Examples @@ -1617,7 +1617,7 @@ def orbital_current( isc=None, what: str = "all", orbitals=None, - ) -> csr_matrix: + ) -> csr_array: r"""Orbital current originating from `elec` as a sparse matrix This is the bias window integrated quantity of `orbital_transmission`. As such it @@ -1725,7 +1725,7 @@ def bond_transmission( what: str = "all", orbitals=None, uc: bool = False, - ) -> csr_matrix: + ) -> csr_array: r"""Bond transmission between atoms at a specific energy Short hand function for calling `orbital_transmission` and `sparse_orbital_to_atom`. @@ -1793,7 +1793,7 @@ def bond_current( what: str = "all", orbitals=None, uc: bool = False, - ) -> csr_matrix: + ) -> csr_array: r"""Bond current between atoms (sum of orbital currents) Short hand function for calling `orbital_current` and `sparse_orbital_to_atom`. @@ -2182,7 +2182,7 @@ def density_matrix( isc=None, orbitals=None, geometry: Optional[Geometry] = None, - ) -> csr_matrix: + ) -> csr_array: r"""Density matrix from the Green function at energy `E` (1/eV) The density matrix can be used to calculate the LDOS in real-space. @@ -2240,7 +2240,7 @@ def Adensity_matrix( isc=None, orbitals=None, geometry: Optional[Geometry] = None, - ) -> csr_matrix: + ) -> csr_array: r"""Spectral function density matrix at energy `E` (1/eV) The density matrix can be used to calculate the LDOS in real-space. @@ -2303,10 +2303,10 @@ def Adensity_matrix( @missing_input_fdf([("TBT.COOP.Gf", "True")]) def orbital_COOP( self, E: EType, kavg: Union[int, bool] = True, isc=None, orbitals=None - ) -> csr_matrix: + ) -> csr_array: r""" Orbital COOP analysis of the Green function - This will return a sparse matrix, see `scipy.sparse.csr_matrix` for details. + This will return a sparse matrix, see `scipy.sparse.csr_array` for details. Each matrix element of the sparse matrix corresponds to the COOP of the underlying geometry. @@ -2374,10 +2374,10 @@ def orbital_ACOOP( kavg: Union[int, bool] = True, isc=None, orbitals=None, - ) -> csr_matrix: + ) -> csr_array: r""" Orbital COOP analysis of the spectral function - This will return a sparse matrix, see `~scipy.sparse.csr_matrix` for details. + This will return a sparse matrix, see `~scipy.sparse.csr_array` for details. Each matrix element of the sparse matrix corresponds to the COOP of the underlying geometry. @@ -2445,7 +2445,7 @@ def atom_COOP( isc=None, orbitals=None, uc: bool = False, - ) -> csr_matrix: + ) -> csr_array: r"""Atomic COOP curve of the Green function The atomic COOP are a sum over all orbital COOP: @@ -2493,7 +2493,7 @@ def atom_ACOOP( isc=None, orbitals=None, uc: bool = False, - ) -> csr_matrix: + ) -> csr_array: r"""Atomic COOP curve of the spectral function The atomic COOP are a sum over all orbital COOP: @@ -2541,10 +2541,10 @@ def atom_ACOOP( @missing_input_fdf([("TBT.COHP.Gf", "True")]) def orbital_COHP( self, E: EType, kavg: Union[int, bool] = True, isc=None, orbitals=None - ) -> csr_matrix: + ) -> csr_array: r"""Orbital resolved COHP analysis of the Green function - This will return a sparse matrix, see `scipy.sparse.csr_matrix` for details. + This will return a sparse matrix, see `scipy.sparse.csr_array` for details. Each matrix element of the sparse matrix corresponds to the COHP of the underlying geometry. @@ -2594,10 +2594,10 @@ def orbital_ACOHP( kavg: Union[int, bool] = True, isc=None, orbitals=None, - ) -> csr_matrix: + ) -> csr_array: r"""Orbital resolved COHP analysis of the spectral function - This will return a sparse matrix, see `scipy.sparse.csr_matrix` for details. + This will return a sparse matrix, see `scipy.sparse.csr_array` for details. Each matrix element of the sparse matrix corresponds to the COHP of the underlying geometry. @@ -2643,7 +2643,7 @@ def atom_COHP( isc=None, orbitals=None, uc: bool = False, - ) -> csr_matrix: + ) -> csr_array: r"""Atomic COHP curve of the Green function The atomic COHP are a sum over all orbital COHP: @@ -2691,7 +2691,7 @@ def atom_ACOHP( isc=None, orbitals=None, uc: bool = False, - ) -> csr_matrix: + ) -> csr_array: r"""Atomic COHP curve of the spectral function Parameters diff --git a/src/sisl/io/tbtrans/tbtproj.py b/src/sisl/io/tbtrans/tbtproj.py index fc3f5b2629..777944dd4c 100644 --- a/src/sisl/io/tbtrans/tbtproj.py +++ b/src/sisl/io/tbtrans/tbtproj.py @@ -269,7 +269,7 @@ def orbital_ACOOP( ): r""" Orbital COOP analysis of the projected spectral function - This will return a sparse matrix, see `scipy.sparse.csr_matrix` for details. + This will return a sparse matrix, see `scipy.sparse.csr_array` for details. Each matrix element of the sparse matrix corresponds to the COOP of the underlying geometry. @@ -338,7 +338,7 @@ def orbital_ACOHP( ): r"""Orbital COHP analysis of the projected spectral function - This will return a sparse matrix, see `scipy.sparse.csr_matrix` for details. + This will return a sparse matrix, see `scipy.sparse.csr_array` for details. Each matrix element of the sparse matrix corresponds to the COHP of the underlying geometry. diff --git a/src/sisl/io/wannier90/seedname.py b/src/sisl/io/wannier90/seedname.py index be7a6cea0c..e683d674ff 100644 --- a/src/sisl/io/wannier90/seedname.py +++ b/src/sisl/io/wannier90/seedname.py @@ -10,7 +10,7 @@ import numpy as np import scipy.sparse as sps -from scipy.sparse import lil_matrix +from scipy.sparse import lil_array import sisl._array as _a from sisl import Geometry, Lattice @@ -502,7 +502,7 @@ def read_hamiltonian( ws = self._r_wigner_seitz_weights() # List for holding the Hamiltonian - Hsc = defaultdict(lambda: lil_matrix((geometry.no, geometry.no), dtype=dtype)) + Hsc = defaultdict(lambda: lil_array((geometry.no, geometry.no), dtype=dtype)) is_complex = np.iscomplexobj(dtype(1)) # Parse hamiltonian matrix elements @@ -590,7 +590,7 @@ def read_hamiltonian( ws = self._r_wigner_seitz_weights() # List for holding the Hamiltonian - Hsc = defaultdict(lambda: lil_matrix((geometry.no, geometry.no), dtype=dtype)) + Hsc = defaultdict(lambda: lil_array((geometry.no, geometry.no), dtype=dtype)) is_complex = np.iscomplexobj(dtype(1)) iws = -1 diff --git a/src/sisl/physics/_ufuncs_matrix.py b/src/sisl/physics/_ufuncs_matrix.py index e568d65e48..8679115e15 100644 --- a/src/sisl/physics/_ufuncs_matrix.py +++ b/src/sisl/physics/_ufuncs_matrix.py @@ -51,7 +51,7 @@ def matrix_at_k( chosen gauge, either the lattice gauge (``lattice``), or the interatomic distance gauge (``atomic``). format : {"csr", "array", "coo", ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`"array"`). Prefixing with "sc:", or simply "sc" returns the matrix in supercell format @@ -99,7 +99,7 @@ def overlap_at_k( chosen gauge, either the lattice gauge (``lattice``), or the interatomic distance gauge (``atomic``). format : {"csr", "array", "coo", ...} - the returned format of the overlap matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the overlap matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`"array"`). Prefixing with "sc:", or simply "sc" returns the overlap matrix in supercell format @@ -121,7 +121,7 @@ def overlap_at_k( S = np.zeros([nr, nc], dtype=dtype) np.fill_diagonal(S, 1.0) else: - S = sps.csr_matrix((nr, nc), dtype=dtype) + S = sps.csr_array((nr, nc), dtype=dtype) S.setdiag(1.0) S = S.asformat(format) return S diff --git a/src/sisl/physics/densitymatrix.py b/src/sisl/physics/densitymatrix.py index f41f9c708c..050bd76791 100644 --- a/src/sisl/physics/densitymatrix.py +++ b/src/sisl/physics/densitymatrix.py @@ -8,7 +8,7 @@ import numpy as np from numpy import add, dot, logical_and, repeat, subtract, unique -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array from scipy.sparse import hstack as ss_hstack from scipy.sparse import tril, triu @@ -237,8 +237,8 @@ def density( # Perform dot-product with spinor, and take out the diagonal real part DM = dot(DM, spinor.T)[:, [0, 1], [0, 1]].sum(1).real - # Create the DM csr matrix. - csrDM = csr_matrix( + # Create the DM csr array. + csrDM = csr_array( (DM, csr.col[idx], _ncol_to_indptr(csr.ncol)), shape=(uc_dm.shape[:2]), dtype=DM.dtype, @@ -974,7 +974,7 @@ def Dk( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). Prefixing with 'sc:', or simply 'sc' returns the matrix in supercell format @@ -1039,7 +1039,7 @@ def dDk( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). spin : int, optional @@ -1102,7 +1102,7 @@ def ddDk( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). spin : int, optional diff --git a/src/sisl/physics/dynamicalmatrix.py b/src/sisl/physics/dynamicalmatrix.py index 33f2891308..458663207e 100644 --- a/src/sisl/physics/dynamicalmatrix.py +++ b/src/sisl/physics/dynamicalmatrix.py @@ -97,7 +97,7 @@ def Dk( the chosen gauge, `lattice` for lattice vector gauge, and `atomic` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). Prefixing with 'sc:', or simply 'sc' returns the matrix in supercell format @@ -158,7 +158,7 @@ def dDk( the chosen gauge, `lattice` for lattice vector gauge, and `atomic` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). @@ -217,7 +217,7 @@ def ddDk( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). @@ -247,6 +247,7 @@ def apply_newton(self) -> None: # Create UC dynamical matrix dyn_sc = self.tocsr(0) no = self.no + # TODO scipy < ... 1D slicing does not work d_uc = lil_matrix((no, no), dtype=dyn_sc.dtype) for i, _ in self.lattice: diff --git a/src/sisl/physics/electron.py b/src/sisl/physics/electron.py index d46a2a018f..6d2ced57fa 100644 --- a/src/sisl/physics/electron.py +++ b/src/sisl/physics/electron.py @@ -68,7 +68,7 @@ sort, zeros, ) -from scipy.sparse import csr_matrix, hstack, issparse +from scipy.sparse import csr_array, hstack, issparse import sisl._array as _a from sisl import BoundaryCondition as BC @@ -460,7 +460,7 @@ def new_list(bools, tmp, we): idx = np.arange(no) def tosize(diag, idx): - return csr_matrix((diag, (idx, idx)), shape=M.shape) + return csr_array((diag, (idx, idx)), shape=M.shape) cop = oplist(tosize(d, idx) for d in cop) diff --git a/src/sisl/physics/energydensitymatrix.py b/src/sisl/physics/energydensitymatrix.py index 8b2edbea91..6c4f335f3d 100644 --- a/src/sisl/physics/energydensitymatrix.py +++ b/src/sisl/physics/energydensitymatrix.py @@ -143,7 +143,7 @@ def Ek( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). Prefixing with 'sc:', or simply 'sc' returns the matrix in supercell format @@ -160,7 +160,7 @@ def Ek( Returns ------- - matrix : numpy.ndarray or scipy.sparse.*_matrix + matrix : numpy.ndarray or scipy.sparse.*_array the energy density matrix at :math:`\mathbf k`. The returned object depends on `format`. """ pass @@ -208,7 +208,7 @@ def dEk( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). spin : int, optional @@ -271,7 +271,7 @@ def ddEk( the chosen gauge, ``lattice`` for cell vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). spin : int, optional diff --git a/src/sisl/physics/hamiltonian.py b/src/sisl/physics/hamiltonian.py index e55502312f..3a7a2e7465 100644 --- a/src/sisl/physics/hamiltonian.py +++ b/src/sisl/physics/hamiltonian.py @@ -146,7 +146,7 @@ def Hk( the chosen gauge, ``lattice`` for lattice vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). Prefixing with 'sc:', or simply 'sc' returns the matrix in supercell format @@ -212,7 +212,7 @@ def dHk( the chosen gauge, ``lattice`` for lattice vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). spin : int, optional @@ -275,7 +275,7 @@ def ddHk( the chosen gauge, ``lattice`` for lattice vector gauge, and ``atomic`` for atomic distance gauge. format : {'csr', 'array', 'dense', 'coo', ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`'array'`/`'dense'`/`'matrix'`). spin : int, optional diff --git a/src/sisl/physics/sparse.py b/src/sisl/physics/sparse.py index 070ea6e709..3527461613 100644 --- a/src/sisl/physics/sparse.py +++ b/src/sisl/physics/sparse.py @@ -7,7 +7,7 @@ from typing import Literal, Optional, Tuple, Union import numpy as np -from scipy.sparse import SparseEfficiencyWarning, coo_matrix, csr_matrix +from scipy.sparse import SparseEfficiencyWarning, coo_matrix, csr_array from scipy.sparse import hstack as ss_hstack import sisl._array as _a @@ -432,7 +432,7 @@ def fromsp( except AttributeError: orthogonal.append(True) - # Extract all SparseCSR matrices (or csr_matrix) + # Extract all SparseCSR matrices (or csr_array) def extract_csr(P, orthogonal: bool = True): try: P = P._csr @@ -525,7 +525,7 @@ def _Pk( format: str = "csr", _dim=0, ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a polarized system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` for a polarized system Parameters ---------- @@ -547,7 +547,7 @@ def _dPk( format: str = "csr", _dim=0, ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` differentiated with respect to `k` for a polarized system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` differentiated with respect to `k` for a polarized system Parameters ---------- @@ -569,7 +569,7 @@ def _ddPk( format: str = "csr", _dim=0, ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` double differentiated with respect to `k` for a polarized system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` double differentiated with respect to `k` for a polarized system Parameters ---------- @@ -624,7 +624,7 @@ def Sk( gauge : the chosen gauge format : {"csr", "array", "matrix", "coo", ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`"array"`/`"dense"`/`"matrix"`). Prefixing with "sc:", or simply "sc" returns the matrix in supercell format @@ -671,7 +671,7 @@ def _Sk_diagonal( S = np.zeros([nr, nc], dtype=dtype) np.fill_diagonal(S, 1.0) return S - S = csr_matrix((nr, nc), dtype=dtype) + S = csr_array((nr, nc), dtype=dtype) S.setdiag(1.0) return S.asformat(format) @@ -682,7 +682,7 @@ def _Sk( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k`. + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k`. Parameters ---------- @@ -737,7 +737,7 @@ def dSk( gauge : the chosen gauge. format : {"csr", "array", "matrix", "coo", ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`"array"`/`"dense"`/`"matrix"`). @@ -760,7 +760,7 @@ def _dSk( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k` differentiated with respect to `k` + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k` differentiated with respect to `k` Parameters ---------- @@ -780,7 +780,7 @@ def _dSk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k` for non-collinear spin, differentiated with respect to `k` + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k` for non-collinear spin, differentiated with respect to `k` Parameters ---------- @@ -839,7 +839,7 @@ def ddSk( the chosen gauge, ``cell`` for cell vector gauge, and ``atom`` for atomic distance gauge. format : {"csr", "array", "matrix", "coo", ...} - the returned format of the matrix, defaulting to the `scipy.sparse.csr_matrix`, + the returned format of the matrix, defaulting to the `scipy.sparse.csr_array`, however if one always requires operations on dense matrices, one can always return in `numpy.ndarray` (`"array"`/`"dense"`/`"matrix"`). @@ -862,7 +862,7 @@ def _ddSk( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k` double differentiated with respect to `k` + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k` double differentiated with respect to `k` Parameters ---------- @@ -882,7 +882,7 @@ def _ddSk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k` for non-collinear spin, differentiated with respect to `k` + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k` for non-collinear spin, differentiated with respect to `k` Parameters ---------- @@ -905,7 +905,7 @@ def _ddSk_nambu( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k` for Nambu spin, differentiated with respect to `k` + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k` for Nambu spin, differentiated with respect to `k` Parameters ---------- @@ -1512,7 +1512,7 @@ def _Pk_unpolarized( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` Parameters ---------- @@ -1533,7 +1533,7 @@ def _Pk_polarized( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a polarized system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` for a polarized system Parameters ---------- @@ -1555,7 +1555,7 @@ def _Pk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a non-collinear system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` for a non-collinear system Parameters ---------- @@ -1576,7 +1576,7 @@ def _Pk_spin_orbit( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a spin-orbit system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` for a spin-orbit system Parameters ---------- @@ -1597,7 +1597,7 @@ def _Pk_nambu( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a Nambu system + r"""Sparse matrix (`scipy.sparse.csr_array`) at `k` for a Nambu system Parameters ---------- @@ -1618,7 +1618,7 @@ def _dPk_unpolarized( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k`, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k`, differentiated with respect to `k` Parameters ---------- @@ -1639,7 +1639,7 @@ def _dPk_polarized( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k`, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k`, differentiated with respect to `k` Parameters ---------- @@ -1661,7 +1661,7 @@ def _dPk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a non-collinear system, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k` for a non-collinear system, differentiated with respect to `k` Parameters ---------- @@ -1682,7 +1682,7 @@ def _dPk_spin_orbit( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a spin-orbit system, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k` for a spin-orbit system, differentiated with respect to `k` Parameters ---------- @@ -1703,7 +1703,7 @@ def _dPk_nambu( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a Nambu spin system, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k` for a Nambu spin system, differentiated with respect to `k` Parameters ---------- @@ -1724,7 +1724,7 @@ def _ddPk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a non-collinear system, differentiated with respect to `k` twice + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k` for a non-collinear system, differentiated with respect to `k` twice Parameters ---------- @@ -1745,7 +1745,7 @@ def _ddPk_spin_orbit( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a spin-orbit system, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k` for a spin-orbit system, differentiated with respect to `k` Parameters ---------- @@ -1766,7 +1766,7 @@ def _ddPk_nambu( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Tuple of sparse matrix (`scipy.sparse.csr_matrix`) at `k` for a Nambu system, differentiated with respect to `k` + r"""Tuple of sparse matrix (`scipy.sparse.csr_array`) at `k` for a Nambu system, differentiated with respect to `k` Parameters ---------- @@ -1787,7 +1787,7 @@ def _Sk( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix in a `scipy.sparse.csr_matrix` at `k`. + r"""Overlap matrix in a `scipy.sparse.csr_array` at `k`. Parameters ---------- @@ -1807,7 +1807,7 @@ def _Sk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix (`scipy.sparse.csr_matrix`) at `k` for a non-collinear system + r"""Overlap matrix (`scipy.sparse.csr_array`) at `k` for a non-collinear system Parameters ---------- @@ -1828,7 +1828,7 @@ def _Sk_nambu( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix (`scipy.sparse.csr_matrix`) at `k` for a Nambu system + r"""Overlap matrix (`scipy.sparse.csr_array`) at `k` for a Nambu system Parameters ---------- @@ -1849,7 +1849,7 @@ def _dSk_non_colinear( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix (`scipy.sparse.csr_matrix`) at `k` for a non-collinear system + r"""Overlap matrix (`scipy.sparse.csr_array`) at `k` for a non-collinear system Parameters ---------- @@ -1872,7 +1872,7 @@ def _dSk_nambu( gauge: GaugeType = "lattice", format: str = "csr", ): - r"""Overlap matrix (`scipy.sparse.csr_matrix`) at `k` for a Nambu system + r"""Overlap matrix (`scipy.sparse.csr_array`) at `k` for a Nambu system Parameters ---------- @@ -2783,8 +2783,8 @@ def mm(A, B): # initialize the result array # Not strictly needed, but enforces that the - # data always contains a csr_matrix - r = csr_matrix((n, n), dtype=A.dtype) + # data always contains a csr_array + r = csr_array((n, n), dtype=A.dtype) # get current supercell information for i, sc in enumerate(sc_offj): diff --git a/src/sisl/physics/tests/test_hamiltonian.py b/src/sisl/physics/tests/test_hamiltonian.py index d0b558ad13..f42efce8a5 100644 --- a/src/sisl/physics/tests/test_hamiltonian.py +++ b/src/sisl/physics/tests/test_hamiltonian.py @@ -1334,8 +1334,8 @@ def test_coop_against_pdos_nonortho(self, setup): # This one returns sparse matrices, so we have to # deal with that. DOS = es.PDOS(E, "lorentzian")[0] - COOP2DOS = np.array([C.sum(1).A1 for C in COOP]).T - assert DOS.shape == COOP2DOS.shape + COOP2DOS = np.array([C.sum(1) for C in COOP]).T + assert DOS.shape == COOP2DOS.shape[1:] assert np.allclose(DOS, COOP2DOS) def test_coop_against_pdos_ortho(self, setup): @@ -1352,7 +1352,7 @@ def test_coop_against_pdos_ortho(self, setup): assert np.allclose(DOS, COOP2DOS) DOS = es.PDOS(E, "lorentzian") - COOP2DOS = np.array([C.sum(1).A1 for C in COOP]).T + COOP2DOS = np.array([C.sum(1) for C in COOP]).T assert DOS.shape[1:] == COOP2DOS.shape assert np.allclose(DOS, COOP2DOS) diff --git a/src/sisl/physics/tests/test_physics_sparse.py b/src/sisl/physics/tests/test_physics_sparse.py index 6cf9d57ebc..01d2155476 100644 --- a/src/sisl/physics/tests/test_physics_sparse.py +++ b/src/sisl/physics/tests/test_physics_sparse.py @@ -793,10 +793,10 @@ def test_sparseorbital_spin_dtypes(dtype, spin): assert M.dtype == dtype -def test_sparseorbital_fromsp_csr_matrix(): +def test_sparseorbital_fromsp_csr_array(): gr = geom.graphene() no, no_s = gr.no, gr.no_s - s1 = sps.csr_matrix((no, no_s)) + s1 = sps.csr_array((no, no_s)) M = SparseOrbitalBZ.fromsp(gr, s1) assert M.shape == (no, no_s, 1) @@ -837,7 +837,7 @@ def test_sparseorbital_fromsp_combined(): gr = geom.graphene() no, no_s = gr.no, gr.no_s s1 = SparseCSR((no, no_s, 2)) - s2 = sps.csr_matrix((no, no_s)) + s2 = sps.csr_array((no, no_s)) M = SparseOrbitalBZ.fromsp(gr, [s1, s2]) assert M.shape == (no, no_s, 3) @@ -854,7 +854,7 @@ def test_sparseorbital_fromsp_orthogonal(): gr = geom.graphene() no, no_s = gr.no, gr.no_s s1 = SparseCSR((no, no_s, 2)) - s2 = sps.csr_matrix((no, no_s)) + s2 = sps.csr_array((no, no_s)) M = SparseOrbitalBZ.fromsp(gr, [s1, s2], orthogonal=False) assert M.shape == (no, no_s, 3) diff --git a/src/sisl/tests/test_sparse_grid.py b/src/sisl/tests/test_sparse_grid.py index c78774b7c4..3603cb5084 100644 --- a/src/sisl/tests/test_sparse_grid.py +++ b/src/sisl/tests/test_sparse_grid.py @@ -160,8 +160,8 @@ def test_orbital_products(geometry): psi_values = geometry._orbital_values((10, 10, 10)) orb_csr = psi_values._csr.tocsr() - orb_0 = orb_csr[:, 0].toarray().ravel() - orb_1 = orb_csr[:, 1].toarray().ravel() + orb_0 = orb_csr[:, [0]].toarray().ravel() + orb_1 = orb_csr[:, [1]].toarray().ravel() # Compute the orbital products with one coefficient DM = sisl.DensityMatrix(geometry, dim=1, dtype=np.float64) diff --git a/src/sisl_toolbox/btd/_green.py b/src/sisl_toolbox/btd/_green.py index ca58f5f273..e47d61a517 100644 --- a/src/sisl_toolbox/btd/_green.py +++ b/src/sisl_toolbox/btd/_green.py @@ -1037,7 +1037,7 @@ def _green_bd(self) -> BlockMatrix: def _green_sparse(self): """Calculate the Green function only where the sparse H and S are non-zero. - Stored in a `scipy.sparse.csr_matrix` class.""" + Stored in a `scipy.sparse.csr_array` class.""" # create a sparse matrix G = self.H.Sk(format="csr", dtype=self._data.A[0].dtype) # pivot the matrix