def tocoo(self): """ Return a copy of this matrix in COOrdinate format""" from coo import coo_matrix if self.nnz == 0: return coo_matrix(self.shape, dtype=self.dtype) else: data = np.asarray(self.values(), dtype=self.dtype) indices = np.asarray(self.keys(), dtype=np.intc).T return coo_matrix((data,indices), shape=self.shape, dtype=self.dtype)
def __init__(self, arg1, shape=None, dtype=None, copy=False): dict.__init__(self) spmatrix.__init__(self) self.dtype = getdtype(dtype, default=float) if isinstance(arg1, tuple) and isshape(arg1): # (M,N) M, N = arg1 self.shape = (M, N) elif isspmatrix(arg1): # Sparse ctor if isspmatrix_dok(arg1) and copy: arg1 = arg1.copy() else: arg1 = arg1.todok() if dtype is not None: arg1 = arg1.astype(dtype) self.update(arg1) self.shape = arg1.shape self.dtype = arg1.dtype else: # Dense ctor try: arg1 = np.asarray(arg1) except: raise TypeError('invalid input format') if len(arg1.shape) != 2: raise TypeError('expected rank <=2 dense array or matrix') from coo import coo_matrix self.update(coo_matrix(arg1, dtype=dtype).todok()) self.shape = arg1.shape self.dtype = arg1.dtype
def find(A): """Return the indices and values of the nonzero elements of a matrix Parameters ---------- A : dense or sparse matrix Matrix whose nonzero elements are desired. Returns ------- (I,J,V) : tuple of arrays I,J, and V contain the row indices, column indices, and values of the nonzero matrix entries. Examples -------- >>> from scipy.sparse import csr_matrix >>> A = csr_matrix([[7.0, 8.0, 0],[0, 0, 9.0]]) >>> find(A) (array([0, 0, 1], dtype=int32), array([0, 1, 2], dtype=int32), array([ 7., 8., 9.])) """ A = coo_matrix(A).tocsr() #sums duplicates A.eliminate_zeros() #removes explicit zeros A = A.tocoo(copy=False) #(cheaply) convert to COO return A.row, A.col, A.data
def __init__(self, arg1, shape=None, dtype=None, copy=False): dict.__init__(self) spmatrix.__init__(self) self.dtype = getdtype(dtype, default=float) if isinstance(arg1, tuple) and isshape(arg1): # (M,N) M, N = arg1 self.shape = (M, N) elif isspmatrix(arg1): # Sparse ctor if isspmatrix_dok(arg1) and copy: arg1 = arg1.copy() else: arg1 = arg1.todok() if dtype is not None: arg1 = arg1.astype(dtype) self.update(arg1) self.shape = arg1.shape self.dtype = arg1.dtype else: # Dense ctor try: arg1 = np.asarray(arg1) except: raise TypeError('invalid input format') if len(arg1.shape)!=2: raise TypeError('expected rank <=2 dense array or matrix') from coo import coo_matrix self.update( coo_matrix(arg1, dtype=dtype).todok() ) self.shape = arg1.shape self.dtype = arg1.dtype
def find(A): """Return the indices and values of the nonzero elements of a matrix Parameters ---------- A : dense or sparse matrix Matrix whose nonzero elements are desired. Returns ------- (I,J,V) : tuple of arrays I,J, and V contain the row indices, column indices, and values of the nonzero matrix entries. Example ------- >>> from scipy.sparse import csr_matrix >>> A = csr_matrix([[7.0, 8.0, 0],[0, 0, 9.0]]) >>> find(A) (array([0, 0, 1], dtype=int32), array([0, 1, 2], dtype=int32), array([ 7., 8., 9.])) """ A = coo_matrix(A).tocsr() #sums duplicates A.eliminate_zeros() #removes explicit zeros A = A.tocoo(copy=False) #(cheaply) convert to COO return A.row,A.col,A.data
def tocoo(self, copy=True): """Convert this matrix to COOrdinate format. When copy=False the data array will be shared between this matrix and the resultant coo_matrix. """ M, N = self.shape R, C = self.blocksize row = (R * np.arange(M / R)).repeat(np.diff(self.indptr)) row = row.repeat(R * C).reshape(-1, R, C) row += np.tile(np.arange(R).reshape(-1, 1), (1, C)) row = row.reshape(-1) col = (C * self.indices).repeat(R * C).reshape(-1, R, C) col += np.tile(np.arange(C), (R, 1)) col = col.reshape(-1) data = self.data.reshape(-1) if copy: data = data.copy() from coo import coo_matrix return coo_matrix((data, (row, col)), shape=self.shape)
def tocoo(self,copy=True): """Convert this matrix to COOrdinate format. When copy=False the data array will be shared between this matrix and the resultant coo_matrix. """ M,N = self.shape R,C = self.blocksize row = (R * np.arange(M//R)).repeat(np.diff(self.indptr)) row = row.repeat(R*C).reshape(-1,R,C) row += np.tile(np.arange(R).reshape(-1,1), (1,C)) row = row.reshape(-1) col = (C * self.indices).repeat(R*C).reshape(-1,R,C) col += np.tile(np.arange(C), (R,1)) col = col.reshape(-1) data = self.data.reshape(-1) if copy: data = data.copy() from coo import coo_matrix return coo_matrix((data,(row,col)), shape=self.shape)
def rand(m, n, density=0.01, format="coo", dtype=None): """Generate a sparse matrix of the given shape and density with uniformely distributed values. Parameters ---------- m, n: int shape of the matrix density: real density of the generated matrix: density equal to one means a full matrix, density of 0 means a matrix with no non-zero items. format: str sparse matrix format. dtype: dtype type of the returned matrix values. Notes ----- Only float types are supported for now. """ if density < 0 or density > 1: raise ValueError("density expected to be 0 <= density <= 1") if dtype and not dtype in [np.float32, np.float64, np.longdouble]: raise NotImplementedError("type %s not supported" % dtype) mn = m * n # XXX: sparse uses intc instead of intp... tp = np.intp if mn > np.iinfo(tp).max: msg = """\ Trying to generate a random sparse matrix such as the product of dimensions is greater than %d - this is not supported on this machine """ raise ValueError(msg % np.iinfo(tp).max) # Number of non zero values k = long(density * m * n) # Generate a few more values than k so that we can get unique values # afterwards. # XXX: one could be smarter here mlow = 5 fac = 1.02 gk = min(k + mlow, fac * k) def _gen_unique_rand(_gk): id = np.random.rand(_gk) return np.unique(np.floor(id * mn))[:k] id = _gen_unique_rand(gk) while id.size < k: gk *= 1.05 id = _gen_unique_rand(gk) j = np.floor(id * 1. / m).astype(tp) i = (id - j * m).astype(tp) vals = np.random.rand(k).astype(dtype) return coo_matrix((vals, (i, j)), shape=(m, n)).asformat(format)
def kronsum(A, B, format=None): """kronecker sum of sparse matrices A and B Kronecker sum of two sparse matrices is a sum of two Kronecker products kron(I_n,A) + kron(B,I_m) where A has shape (m,m) and B has shape (n,n) and I_m and I_n are identity matrices of shape (m,m) and (n,n) respectively. Parameters ---------- A square matrix B square matrix format : string format of the result (e.g. "csr") Returns ------- kronecker sum in a sparse matrix format Examples -------- """ A = coo_matrix(A) B = coo_matrix(B) if A.shape[0] != A.shape[1]: raise ValueError('A is not square') if B.shape[0] != B.shape[1]: raise ValueError('B is not square') dtype = upcast(A.dtype, B.dtype) L = kron(identity(B.shape[0],dtype=dtype), A, format=format) R = kron(B, identity(A.shape[0],dtype=dtype), format=format) return (L+R).asformat(format) #since L + R is not always same format
def kronsum(A, B, format=None): """kronecker sum of sparse matrices A and B Kronecker sum of two sparse matrices is a sum of two Kronecker products kron(I_n,A) + kron(B,I_m) where A has shape (m,m) and B has shape (n,n) and I_m and I_n are identity matrices of shape (m,m) and (n,n) respectively. Parameters ---------- A square matrix B square matrix format : string format of the result (e.g. "csr") Returns ------- kronecker sum in a sparse matrix format Examples -------- """ A = coo_matrix(A) B = coo_matrix(B) if A.shape[0] != A.shape[1]: raise ValueError('A is not square') if B.shape[0] != B.shape[1]: raise ValueError('B is not square') dtype = upcast(A.dtype, B.dtype) L = kron(identity(B.shape[0], dtype=dtype), A, format=format) R = kron(B, identity(A.shape[0], dtype=dtype), format=format) return (L + R).asformat(format) #since L + R is not always same format
def eye(m, n=None, k=0, dtype=float, format=None): """Sparse matrix with ones on diagonal Returns a sparse (m x n) matrix where the k-th diagonal is all ones and everything else is zeros. Parameters ---------- n : integer Number of rows in the matrix. m : integer, optional Number of columns. Default: n k : integer, optional Diagonal to place ones on. Default: 0 (main diagonal) dtype : Data type of the matrix format : string Sparse format of the result, e.g. format="csr", etc. Examples -------- >>> from scipy import sparse >>> sparse.eye(3).todense() matrix([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> sparse.eye(3, dtype=np.int8) <3x3 sparse matrix of type '<type 'numpy.int8'>' with 3 stored elements (1 diagonals) in DIAgonal format> """ if n is None: n = m m, n = int(m), int(n) if m == n and k == 0: # fast branch for special formats if format in ['csr', 'csc']: indptr = np.arange(n + 1, dtype=np.intc) indices = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) cls = {'csr': csr_matrix, 'csc': csc_matrix}[format] return cls((data, indices, indptr), (n, n)) elif format == 'coo': row = np.arange(n, dtype=np.intc) col = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) return coo_matrix((data, (row, col)), (n, n)) diags = np.ones((1, max(0, min(m + k, n))), dtype=dtype) return spdiags(diags, k, m, n).asformat(format)
def eye(m, n=None, k=0, dtype=float, format=None): """Sparse matrix with ones on diagonal Returns a sparse (m x n) matrix where the k-th diagonal is all ones and everything else is zeros. Parameters ---------- n : integer Number of rows in the matrix. m : integer, optional Number of columns. Default: n k : integer, optional Diagonal to place ones on. Default: 0 (main diagonal) dtype : Data type of the matrix format : string Sparse format of the result, e.g. format="csr", etc. Examples -------- >>> from scipy import sparse >>> sparse.eye(3).todense() matrix([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> sparse.eye(3, dtype=np.int8) <3x3 sparse matrix of type '<type 'numpy.int8'>' with 3 stored elements (1 diagonals) in DIAgonal format> """ if n is None: n = m m,n = int(m),int(n) if m == n and k == 0: # fast branch for special formats if format in ['csr', 'csc']: indptr = np.arange(n+1, dtype=np.intc) indices = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) cls = {'csr': csr_matrix, 'csc': csc_matrix}[format] return cls((data,indices,indptr),(n,n)) elif format == 'coo': row = np.arange(n, dtype=np.intc) col = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) return coo_matrix((data,(row,col)),(n,n)) diags = np.ones((1, max(0, min(m + k, n))), dtype=dtype) return spdiags(diags, k, m, n).asformat(format)
def block_diag(mats, format=None, dtype=None): """ Build a block diagonal sparse matrix from provided matrices. .. versionadded:: 0.11.0 Parameters ---------- A, B, ... : sequence of matrices Input matrices. format : str, optional The sparse format of the result (e.g. "csr"). If not given, the matrix is returned in "coo" format. dtype : dtype specifier, optional The data-type of the output matrix. If not given, the dtype is determined from that of `blocks`. Returns ------- res : sparse matrix See Also -------- bmat, diags Examples -------- >>> A = coo_matrix([[1, 2], [3, 4]]) >>> B = coo_matrix([[5], [6]]) >>> C = coo_matrix([[7]]) >>> block_diag((A, B, C)).todense() matrix([[1, 2, 0, 0], [3, 4, 0, 0], [0, 0, 5, 0], [0, 0, 6, 0], [0, 0, 0, 7]]) """ nmat = len(mats) rows = [] for ia, a in enumerate(mats): row = [None] * nmat if issparse(a): row[ia] = a else: row[ia] = coo_matrix(a) rows.append(row) return bmat(rows, format=format, dtype=dtype)
def block_diag(mats, format=None, dtype=None): """ Build a block diagonal sparse matrix from provided matrices. .. versionadded:: 0.11.0 Parameters ---------- A, B, ... : sequence of matrices Input matrices. format : str, optional The sparse format of the result (e.g. "csr"). If not given, the matrix is returned in "coo" format. dtype : dtype specifier, optional The data-type of the output matrix. If not given, the dtype is determined from that of `blocks`. Returns ------- res : sparse matrix See Also -------- bmat, diags Examples -------- >>> A = coo_matrix([[1, 2], [3, 4]]) >>> B = coo_matrix([[5], [6]]) >>> C = coo_matrix([[7]]) >>> block_diag((A, B, C)).todense() matrix([[1, 2, 0, 0], [3, 4, 0, 0], [0, 0, 5, 0], [0, 0, 6, 0], [0, 0, 0, 7]]) """ nmat = len(mats) rows = [] for ia, a in enumerate(mats): row = [None]*nmat if issparse(a): row[ia] = a else: row[ia] = coo_matrix(a) rows.append(row) return bmat(rows, format=format, dtype=dtype)
def identity(n, dtype='d', format=None): """Identity matrix in sparse format Returns an identity matrix with shape (n,n) using a given sparse format and dtype. Parameters ---------- n : integer Shape of the identity matrix. dtype : Data type of the matrix format : string Sparse format of the result, e.g. format="csr", etc. Examples -------- >>> identity(3).todense() matrix([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> identity(3, dtype='int8', format='dia') <3x3 sparse matrix of type '<type 'numpy.int8'>' with 3 stored elements (1 diagonals) in DIAgonal format> """ if format in ['csr', 'csc']: indptr = np.arange(n + 1, dtype=np.intc) indices = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) cls = eval('%s_matrix' % format) return cls((data, indices, indptr), (n, n)) elif format == 'coo': row = np.arange(n, dtype=np.intc) col = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) return coo_matrix((data, (row, col)), (n, n)) elif format == 'dia': data = np.ones(n, dtype=dtype) diags = [0] return dia_matrix((data, diags), shape=(n, n)) else: return identity(n, dtype=dtype, format='csr').asformat(format)
def identity(n, dtype='d', format=None): """Identity matrix in sparse format Returns an identity matrix with shape (n,n) using a given sparse format and dtype. Parameters ---------- n : integer Shape of the identity matrix. dtype : Data type of the matrix format : string Sparse format of the result, e.g. format="csr", etc. Examples -------- >>> identity(3).todense() matrix([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> identity(3, dtype='int8', format='dia') <3x3 sparse matrix of type '<type 'numpy.int8'>' with 3 stored elements (1 diagonals) in DIAgonal format> """ if format in ['csr','csc']: indptr = np.arange(n+1, dtype=np.intc) indices = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) cls = eval('%s_matrix' % format) return cls((data,indices,indptr),(n,n)) elif format == 'coo': row = np.arange(n, dtype=np.intc) col = np.arange(n, dtype=np.intc) data = np.ones(n, dtype=dtype) return coo_matrix((data,(row,col)),(n,n)) elif format == 'dia': data = np.ones(n, dtype=dtype) diags = [0] return dia_matrix((data,diags), shape=(n,n)) else: return identity(n, dtype=dtype, format='csr').asformat(format)
def tocoo(self): num_data = len(self.data) len_data = self.data.shape[1] row = np.arange(len_data).reshape(1,-1).repeat(num_data,axis=0) col = row.copy() for i,k in enumerate(self.offsets): row[i,:] -= k row,col,data = row.ravel(),col.ravel(),self.data.ravel() mask = (row >= 0) mask &= (row < self.shape[0]) mask &= (col < self.shape[1]) mask &= data != 0 row,col,data = row[mask],col[mask],data[mask] from coo import coo_matrix return coo_matrix((data,(row,col)), shape=self.shape)
def tocoo(self): num_data = len(self.data) len_data = self.data.shape[1] row = np.arange(len_data).reshape(1, -1).repeat(num_data, axis=0) col = row.copy() for i, k in enumerate(self.offsets): row[i, :] -= k row, col, data = row.ravel(), col.ravel(), self.data.ravel() mask = (row >= 0) mask &= (row < self.shape[0]) mask &= (col < self.shape[1]) mask &= data != 0 row, col, data = row[mask], col[mask], data[mask] from coo import coo_matrix return coo_matrix((data, (row, col)), shape=self.shape)
def tocoo(self, copy=True): """Return a COOrdinate representation of this matrix When copy=False the index and data arrays are not copied. """ major_dim, minor_dim = self._swap(self.shape) data = self.data minor_indices = self.indices if copy: data = data.copy() minor_indices = minor_indices.copy() major_indices = np.empty(len(minor_indices), dtype=np.intc) sparsetools.expandptr(major_dim, self.indptr, major_indices) row, col = self._swap((major_indices, minor_indices)) from coo import coo_matrix return coo_matrix((data, (row, col)), self.shape)
def tocoo(self,copy=True): """Return a COOrdinate representation of this matrix When copy=False the index and data arrays are not copied. """ major_dim,minor_dim = self._swap(self.shape) data = self.data minor_indices = self.indices if copy: data = data.copy() minor_indices = minor_indices.copy() major_indices = np.empty(len(minor_indices), dtype=np.intc) sparsetools.expandptr(major_dim,self.indptr,major_indices) row,col = self._swap((major_indices,minor_indices)) from coo import coo_matrix return coo_matrix((data,(row,col)), self.shape)
def __init__(self, arg1, shape=None, dtype=None, copy=False): _data_matrix.__init__(self) if isspmatrix(arg1): if arg1.format == self.format and copy: arg1 = arg1.copy() else: arg1 = arg1.asformat(self.format) self._set_self( arg1 ) elif isinstance(arg1, tuple): if isshape(arg1): # It's a tuple of matrix dimensions (M, N) # create empty matrix self.shape = arg1 #spmatrix checks for errors here M, N = self.shape self.data = np.zeros(0, getdtype(dtype, default=float)) self.indices = np.zeros(0, np.intc) self.indptr = np.zeros(self._swap((M,N))[0] + 1, dtype=np.intc) else: if len(arg1) == 2: # (data, ij) format from coo import coo_matrix other = self.__class__( coo_matrix(arg1, shape=shape) ) self._set_self( other ) elif len(arg1) == 3: # (data, indices, indptr) format (data, indices, indptr) = arg1 self.indices = np.array(indices, copy=copy) self.indptr = np.array(indptr, copy=copy) self.data = np.array(data, copy=copy, dtype=getdtype(dtype, data)) else: raise ValueError("unrecognized %s_matrix constructor usage" % self.format) else: #must be dense try: arg1 = np.asarray(arg1) except: raise ValueError("unrecognized %s_matrix constructor usage" % self.format) from coo import coo_matrix self._set_self( self.__class__(coo_matrix(arg1, dtype=dtype)) ) # Read matrix dimensions given, if any if shape is not None: self.shape = shape # spmatrix will check for errors else: if self.shape is None: # shape not already set, try to infer dimensions try: major_dim = len(self.indptr) - 1 minor_dim = self.indices.max() + 1 except: raise ValueError('unable to infer matrix dimensions') else: self.shape = self._swap((major_dim,minor_dim)) if dtype is not None: self.data = self.data.astype(dtype) self.check_format(full_check=False)
def __init__(self, arg1, shape=None, dtype=None, copy=False): _data_matrix.__init__(self) if isspmatrix(arg1): if arg1.format == self.format and copy: arg1 = arg1.copy() else: arg1 = arg1.asformat(self.format) self._set_self(arg1) elif isinstance(arg1, tuple): if isshape(arg1): # It's a tuple of matrix dimensions (M, N) # create empty matrix self.shape = arg1 #spmatrix checks for errors here M, N = self.shape self.data = np.zeros(0, getdtype(dtype, default=float)) self.indices = np.zeros(0, np.intc) self.indptr = np.zeros(self._swap((M, N))[0] + 1, dtype=np.intc) else: if len(arg1) == 2: # (data, ij) format from coo import coo_matrix other = self.__class__(coo_matrix(arg1, shape=shape)) self._set_self(other) elif len(arg1) == 3: # (data, indices, indptr) format (data, indices, indptr) = arg1 self.indices = np.array(indices, copy=copy) self.indptr = np.array(indptr, copy=copy) self.data = np.array(data, copy=copy, dtype=getdtype(dtype, data)) else: raise ValueError( "unrecognized %s_matrix constructor usage" % self.format) else: #must be dense try: arg1 = np.asarray(arg1) except: raise ValueError("unrecognized %s_matrix constructor usage" % self.format) from coo import coo_matrix self._set_self(self.__class__(coo_matrix(arg1, dtype=dtype))) # Read matrix dimensions given, if any if shape is not None: self.shape = shape # spmatrix will check for errors else: if self.shape is None: # shape not already set, try to infer dimensions try: major_dim = len(self.indptr) - 1 minor_dim = self.indices.max() + 1 except: raise ValueError('unable to infer matrix dimensions') else: self.shape = self._swap((major_dim, minor_dim)) if dtype is not None: self.data = self.data.astype(dtype) self.check_format(full_check=False)
def __init__(self, arg1, shape=None, dtype=None, copy=False): _data_matrix.__init__(self) if isspmatrix_dia(arg1): if copy: arg1 = arg1.copy() self.data = arg1.data self.offsets = arg1.offsets self.shape = arg1.shape elif isspmatrix(arg1): if isspmatrix_dia(arg1) and copy: A = arg1.copy() else: A = arg1.todia() self.data = A.data self.offsets = A.offsets self.shape = A.shape elif isinstance(arg1, tuple): if isshape(arg1): # It's a tuple of matrix dimensions (M, N) # create empty matrix self.shape = arg1 #spmatrix checks for errors here self.data = np.zeros((0, 0), getdtype(dtype, default=float)) self.offsets = np.zeros((0), dtype=np.intc) else: try: # Try interpreting it as (data, offsets) data, offsets = arg1 except: raise ValueError( 'unrecognized form for dia_matrix constructor') else: if shape is None: raise ValueError('expected a shape argument') self.data = np.atleast_2d( np.array(arg1[0], dtype=dtype, copy=copy)) self.offsets = np.atleast_1d( np.array(arg1[1], dtype=np.intc, copy=copy)) self.shape = shape else: #must be dense, convert to COO first, then to DIA try: arg1 = np.asarray(arg1) except: raise ValueError("unrecognized form for" \ " %s_matrix constructor" % self.format) from coo import coo_matrix A = coo_matrix(arg1, dtype=dtype).todia() self.data = A.data self.offsets = A.offsets self.shape = A.shape if dtype is not None: self.data = self.data.astype(dtype) #check format if self.offsets.ndim != 1: raise ValueError('offsets array must have rank 1') if self.data.ndim != 2: raise ValueError('data array must have rank 2') if self.data.shape[0] != len(self.offsets): raise ValueError('number of diagonals (%d) ' \ 'does not match the number of offsets (%d)' \ % (self.data.shape[0], len(self.offsets))) if len(np.unique(self.offsets)) != len(self.offsets): raise ValueError('offset array contains duplicate values')
def __init__(self, arg1, shape=None, dtype=None, copy=False, blocksize=None): _data_matrix.__init__(self) if isspmatrix(arg1): if isspmatrix_bsr(arg1) and copy: arg1 = arg1.copy() else: arg1 = arg1.tobsr(blocksize=blocksize) self._set_self( arg1 ) elif isinstance(arg1,tuple): if isshape(arg1): #it's a tuple of matrix dimensions (M,N) self.shape = arg1 M,N = self.shape #process blocksize if blocksize is None: blocksize = (1,1) else: if not isshape(blocksize): raise ValueError('invalid blocksize=%s' % blocksize) blocksize = tuple(blocksize) self.data = np.zeros( (0,) + blocksize, getdtype(dtype, default=float) ) self.indices = np.zeros( 0, dtype=np.intc ) R,C = blocksize if (M % R) != 0 or (N % C) != 0: raise ValueError('shape must be multiple of blocksize') self.indptr = np.zeros(M//R + 1, dtype=np.intc ) elif len(arg1) == 2: # (data,(row,col)) format from coo import coo_matrix self._set_self( coo_matrix(arg1, dtype=dtype).tobsr(blocksize=blocksize) ) elif len(arg1) == 3: # (data,indices,indptr) format (data, indices, indptr) = arg1 self.indices = np.array(indices, copy=copy) self.indptr = np.array(indptr, copy=copy) self.data = np.array(data, copy=copy, dtype=getdtype(dtype, data)) else: raise ValueError('unrecognized bsr_matrix constructor usage') else: #must be dense try: arg1 = np.asarray(arg1) except: raise ValueError("unrecognized form for" \ " %s_matrix constructor" % self.format) from coo import coo_matrix arg1 = coo_matrix(arg1, dtype=dtype).tobsr(blocksize=blocksize) self._set_self( arg1 ) if shape is not None: self.shape = shape # spmatrix will check for errors else: if self.shape is None: # shape not already set, try to infer dimensions try: M = len(self.indptr) - 1 N = self.indices.max() + 1 except: raise ValueError('unable to infer matrix dimensions') else: R,C = self.blocksize self.shape = (M*R,N*C) if self.shape is None: if shape is None: #TODO infer shape here raise ValueError('need to infer shape') else: self.shape = shape if dtype is not None: self.data = self.data.astype(dtype) self.check_format(full_check=False)
def __init__(self, arg1, shape=None, dtype=None, copy=False, blocksize=None): _data_matrix.__init__(self) if isspmatrix(arg1): if isspmatrix_bsr(arg1) and copy: arg1 = arg1.copy() else: arg1 = arg1.tobsr(blocksize=blocksize) self._set_self(arg1) elif isinstance(arg1, tuple): if isshape(arg1): #it's a tuple of matrix dimensions (M,N) self.shape = arg1 M, N = self.shape #process blocksize if blocksize is None: blocksize = (1, 1) else: if not isshape(blocksize): raise ValueError('invalid blocksize=%s' % blocksize) blocksize = tuple(blocksize) self.data = np.zeros((0, ) + blocksize, getdtype(dtype, default=float)) self.indices = np.zeros(0, dtype=np.intc) R, C = blocksize if (M % R) != 0 or (N % C) != 0: raise ValueError, 'shape must be multiple of blocksize' self.indptr = np.zeros(M / R + 1, dtype=np.intc) elif len(arg1) == 2: # (data,(row,col)) format from coo import coo_matrix self._set_self( coo_matrix(arg1, dtype=dtype).tobsr(blocksize=blocksize)) elif len(arg1) == 3: # (data,indices,indptr) format (data, indices, indptr) = arg1 self.indices = np.array(indices, copy=copy) self.indptr = np.array(indptr, copy=copy) self.data = np.array(data, copy=copy, dtype=getdtype(dtype, data)) else: raise ValueError('unrecognized bsr_matrix constructor usage') else: #must be dense try: arg1 = np.asarray(arg1) except: raise ValueError("unrecognized form for" \ " %s_matrix constructor" % self.format) from coo import coo_matrix arg1 = coo_matrix(arg1, dtype=dtype).tobsr(blocksize=blocksize) self._set_self(arg1) if shape is not None: self.shape = shape # spmatrix will check for errors else: if self.shape is None: # shape not already set, try to infer dimensions try: M = len(self.indptr) - 1 N = self.indices.max() + 1 except: raise ValueError('unable to infer matrix dimensions') else: R, C = self.blocksize self.shape = (M * R, N * C) if self.shape is None: if shape is None: #TODO infer shape here raise ValueError('need to infer shape') else: self.shape = shape if dtype is not None: self.data = self.data.astype(dtype) self.check_format(full_check=False)
def kron(A, B, format=None): """kronecker product of sparse matrices A and B Parameters ---------- A : sparse or dense matrix first matrix of the product B : sparse or dense matrix second matrix of the product format : string format of the result (e.g. "csr") Returns ------- kronecker product in a sparse matrix format Examples -------- >>> A = csr_matrix(array([[0,2],[5,0]])) >>> B = csr_matrix(array([[1,2],[3,4]])) >>> kron(A,B).todense() matrix([[ 0, 0, 2, 4], [ 0, 0, 6, 8], [ 5, 10, 0, 0], [15, 20, 0, 0]]) >>> kron(A,[[1,2],[3,4]]).todense() matrix([[ 0, 0, 2, 4], [ 0, 0, 6, 8], [ 5, 10, 0, 0], [15, 20, 0, 0]]) """ B = coo_matrix(B) if (format is None or format == "bsr") and 2*B.nnz >= B.shape[0] * B.shape[1]: #B is fairly dense, use BSR A = csr_matrix(A,copy=True) output_shape = (A.shape[0]*B.shape[0], A.shape[1]*B.shape[1]) if A.nnz == 0 or B.nnz == 0: # kronecker product is the zero matrix return coo_matrix( output_shape ) B = B.toarray() data = A.data.repeat(B.size).reshape(-1,B.shape[0],B.shape[1]) data = data * B return bsr_matrix((data,A.indices,A.indptr), shape=output_shape) else: #use COO A = coo_matrix(A) output_shape = (A.shape[0]*B.shape[0], A.shape[1]*B.shape[1]) if A.nnz == 0 or B.nnz == 0: # kronecker product is the zero matrix return coo_matrix( output_shape ) # expand entries of a into blocks row = A.row.repeat(B.nnz) col = A.col.repeat(B.nnz) data = A.data.repeat(B.nnz) row *= B.shape[0] col *= B.shape[1] # increment block indices row,col = row.reshape(-1,B.nnz),col.reshape(-1,B.nnz) row += B.row col += B.col row,col = row.reshape(-1),col.reshape(-1) # compute block entries data = data.reshape(-1,B.nnz) * B.data data = data.reshape(-1) return coo_matrix((data,(row,col)), shape=output_shape).asformat(format)
def tril(A, k=0, format=None): """Return the lower triangular portion of a matrix in sparse format Returns the elements on or below the k-th diagonal of the matrix A. - k = 0 corresponds to the main diagonal - k > 0 is above the main diagonal - k < 0 is below the main diagonal Parameters ---------- A : dense or sparse matrix Matrix whose lower trianglar portion is desired. k : integer : optional The top-most diagonal of the lower triangle. format : string Sparse format of the result, e.g. format="csr", etc. Returns ------- L : sparse matrix Lower triangular portion of A in sparse format. See Also -------- triu : upper triangle in sparse format Examples -------- >>> from scipy.sparse import csr_matrix >>> A = csr_matrix( [[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]], dtype='int32' ) >>> A.todense() matrix([[1, 2, 0, 0, 3], [4, 5, 0, 6, 7], [0, 0, 8, 9, 0]]) >>> tril(A).todense() matrix([[1, 0, 0, 0, 0], [4, 5, 0, 0, 0], [0, 0, 8, 0, 0]]) >>> tril(A).nnz 4 >>> tril(A, k=1).todense() matrix([[1, 2, 0, 0, 0], [4, 5, 0, 0, 0], [0, 0, 8, 9, 0]]) >>> tril(A, k=-1).todense() matrix([[0, 0, 0, 0, 0], [4, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) >>> tril(A, format='csc') <3x5 sparse matrix of type '<type 'numpy.int32'>' with 4 stored elements in Compressed Sparse Column format> """ # convert to COOrdinate format where things are easy A = coo_matrix(A, copy=False) mask = A.row + k >= A.col row = A.row[mask] col = A.col[mask] data = A.data[mask] return coo_matrix( (data,(row,col)), shape=A.shape ).asformat(format)
def bmat(blocks, format=None, dtype=None): """ Build a sparse matrix from sparse sub-blocks Parameters ---------- blocks grid of sparse matrices with compatible shapes an entry of None implies an all-zero matrix format : sparse format of the result (e.g. "csr") by default an appropriate sparse matrix format is returned. This choice is subject to change. Examples -------- >>> from scipy.sparse import coo_matrix, bmat >>> A = coo_matrix([[1,2],[3,4]]) >>> B = coo_matrix([[5],[6]]) >>> C = coo_matrix([[7]]) >>> bmat( [[A,B],[None,C]] ).todense() matrix([[1, 2, 5], [3, 4, 6], [0, 0, 7]]) >>> bmat( [[A,None],[None,C]] ).todense() matrix([[1, 2, 0], [3, 4, 0], [0, 0, 7]]) """ blocks = np.asarray(blocks, dtype='object') if np.rank(blocks) != 2: raise ValueError('blocks must have rank 2') M,N = blocks.shape block_mask = np.zeros(blocks.shape, dtype=np.bool) brow_lengths = np.zeros(blocks.shape[0], dtype=np.intc) bcol_lengths = np.zeros(blocks.shape[1], dtype=np.intc) # convert everything to COO format for i in range(M): for j in range(N): if blocks[i,j] is not None: A = coo_matrix(blocks[i,j]) blocks[i,j] = A block_mask[i,j] = True if brow_lengths[i] == 0: brow_lengths[i] = A.shape[0] else: if brow_lengths[i] != A.shape[0]: raise ValueError('blocks[%d,:] has incompatible row dimensions' % i) if bcol_lengths[j] == 0: bcol_lengths[j] = A.shape[1] else: if bcol_lengths[j] != A.shape[1]: raise ValueError('blocks[:,%d] has incompatible column dimensions' % j) # ensure that at least one value in each row and col is not None if brow_lengths.min() == 0: raise ValueError('blocks[%d,:] is all None' % brow_lengths.argmin() ) if bcol_lengths.min() == 0: raise ValueError('blocks[:,%d] is all None' % bcol_lengths.argmin() ) nnz = sum([ A.nnz for A in blocks[block_mask] ]) if dtype is None: dtype = upcast( *tuple([A.dtype for A in blocks[block_mask]]) ) row_offsets = np.concatenate(([0], np.cumsum(brow_lengths))) col_offsets = np.concatenate(([0], np.cumsum(bcol_lengths))) data = np.empty(nnz, dtype=dtype) row = np.empty(nnz, dtype=np.intc) col = np.empty(nnz, dtype=np.intc) nnz = 0 for i in range(M): for j in range(N): if blocks[i,j] is not None: A = blocks[i,j] data[nnz:nnz + A.nnz] = A.data row[nnz:nnz + A.nnz] = A.row col[nnz:nnz + A.nnz] = A.col row[nnz:nnz + A.nnz] += row_offsets[i] col[nnz:nnz + A.nnz] += col_offsets[j] nnz += A.nnz shape = (np.sum(brow_lengths), np.sum(bcol_lengths)) return coo_matrix((data, (row, col)), shape=shape).asformat(format)
def tril(A, k=0, format=None): """Return the lower triangular portion of a matrix in sparse format Returns the elements on or below the k-th diagonal of the matrix A. - k = 0 corresponds to the main diagonal - k > 0 is above the main diagonal - k < 0 is below the main diagonal Parameters ---------- A : dense or sparse matrix Matrix whose lower trianglar portion is desired. k : integer : optional The top-most diagonal of the lower triangle. format : string Sparse format of the result, e.g. format="csr", etc. Returns ------- L : sparse matrix Lower triangular portion of A in sparse format. See Also -------- triu : upper triangle in sparse format Examples -------- >>> from scipy.sparse import csr_matrix >>> A = csr_matrix( [[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]], dtype='int32' ) >>> A.todense() matrix([[1, 2, 0, 0, 3], [4, 5, 0, 6, 7], [0, 0, 8, 9, 0]]) >>> tril(A).todense() matrix([[1, 0, 0, 0, 0], [4, 5, 0, 0, 0], [0, 0, 8, 0, 0]]) >>> tril(A).nnz 4 >>> tril(A, k=1).todense() matrix([[1, 2, 0, 0, 0], [4, 5, 0, 0, 0], [0, 0, 8, 9, 0]]) >>> tril(A, k=-1).todense() matrix([[0, 0, 0, 0, 0], [4, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) >>> tril(A, format='csc') <3x5 sparse matrix of type '<type 'numpy.int32'>' with 4 stored elements in Compressed Sparse Column format> """ # convert to COOrdinate format where things are easy A = coo_matrix(A, copy=False) mask = A.row + k >= A.col row = A.row[mask] col = A.col[mask] data = A.data[mask] return coo_matrix((data, (row, col)), shape=A.shape).asformat(format)
def __init__(self, arg1, shape=None, dtype=None, copy=False): _data_matrix.__init__(self) if isspmatrix_dia(arg1): if copy: arg1 = arg1.copy() self.data = arg1.data self.offsets = arg1.offsets self.shape = arg1.shape elif isspmatrix(arg1): if isspmatrix_dia(arg1) and copy: A = arg1.copy() else: A = arg1.todia() self.data = A.data self.offsets = A.offsets self.shape = A.shape elif isinstance(arg1, tuple): if isshape(arg1): # It's a tuple of matrix dimensions (M, N) # create empty matrix self.shape = arg1 #spmatrix checks for errors here self.data = np.zeros( (0,0), getdtype(dtype, default=float)) self.offsets = np.zeros( (0), dtype=np.intc) else: try: # Try interpreting it as (data, offsets) data, offsets = arg1 except: raise ValueError('unrecognized form for dia_matrix constructor') else: if shape is None: raise ValueError('expected a shape argument') self.data = np.atleast_2d(np.array(arg1[0], dtype=dtype, copy=copy)) self.offsets = np.atleast_1d(np.array(arg1[1], dtype=np.intc, copy=copy)) self.shape = shape else: #must be dense, convert to COO first, then to DIA try: arg1 = np.asarray(arg1) except: raise ValueError("unrecognized form for" \ " %s_matrix constructor" % self.format) from coo import coo_matrix A = coo_matrix(arg1, dtype=dtype).todia() self.data = A.data self.offsets = A.offsets self.shape = A.shape if dtype is not None: self.data = self.data.astype(dtype) #check format if self.offsets.ndim != 1: raise ValueError('offsets array must have rank 1') if self.data.ndim != 2: raise ValueError('data array must have rank 2') if self.data.shape[0] != len(self.offsets): raise ValueError('number of diagonals (%d) ' \ 'does not match the number of offsets (%d)' \ % (self.data.shape[0], len(self.offsets))) if len(np.unique(self.offsets)) != len(self.offsets): raise ValueError('offset array contains duplicate values')
def bmat(blocks, format=None, dtype=None): """ Build a sparse matrix from sparse sub-blocks Parameters ---------- blocks grid of sparse matrices with compatible shapes an entry of None implies an all-zero matrix format : sparse format of the result (e.g. "csr") by default an appropriate sparse matrix format is returned. This choice is subject to change. Examples -------- >>> from scipy.sparse import coo_matrix, bmat >>> A = coo_matrix([[1,2],[3,4]]) >>> B = coo_matrix([[5],[6]]) >>> C = coo_matrix([[7]]) >>> bmat( [[A,B],[None,C]] ).todense() matrix([[1, 2, 5], [3, 4, 6], [0, 0, 7]]) >>> bmat( [[A,None],[None,C]] ).todense() matrix([[1, 2, 0], [3, 4, 0], [0, 0, 7]]) """ blocks = np.asarray(blocks, dtype='object') if np.rank(blocks) != 2: raise ValueError('blocks must have rank 2') M, N = blocks.shape block_mask = np.zeros(blocks.shape, dtype=np.bool) brow_lengths = np.zeros(blocks.shape[0], dtype=np.intc) bcol_lengths = np.zeros(blocks.shape[1], dtype=np.intc) # convert everything to COO format for i in range(M): for j in range(N): if blocks[i, j] is not None: A = coo_matrix(blocks[i, j]) blocks[i, j] = A block_mask[i, j] = True if brow_lengths[i] == 0: brow_lengths[i] = A.shape[0] else: if brow_lengths[i] != A.shape[0]: raise ValueError( 'blocks[%d,:] has incompatible row dimensions' % i) if bcol_lengths[j] == 0: bcol_lengths[j] = A.shape[1] else: if bcol_lengths[j] != A.shape[1]: raise ValueError( 'blocks[:,%d] has incompatible column dimensions' % j) # ensure that at least one value in each row and col is not None if brow_lengths.min() == 0: raise ValueError('blocks[%d,:] is all None' % brow_lengths.argmin()) if bcol_lengths.min() == 0: raise ValueError('blocks[:,%d] is all None' % bcol_lengths.argmin()) nnz = sum([A.nnz for A in blocks[block_mask]]) if dtype is None: dtype = upcast(*tuple([A.dtype for A in blocks[block_mask]])) row_offsets = np.concatenate(([0], np.cumsum(brow_lengths))) col_offsets = np.concatenate(([0], np.cumsum(bcol_lengths))) data = np.empty(nnz, dtype=dtype) row = np.empty(nnz, dtype=np.intc) col = np.empty(nnz, dtype=np.intc) nnz = 0 for i in range(M): for j in range(N): if blocks[i, j] is not None: A = blocks[i, j] data[nnz:nnz + A.nnz] = A.data row[nnz:nnz + A.nnz] = A.row col[nnz:nnz + A.nnz] = A.col row[nnz:nnz + A.nnz] += row_offsets[i] col[nnz:nnz + A.nnz] += col_offsets[j] nnz += A.nnz shape = (np.sum(brow_lengths), np.sum(bcol_lengths)) return coo_matrix((data, (row, col)), shape=shape).asformat(format)
def kron(A, B, format=None): """kronecker product of sparse matrices A and B Parameters ---------- A : sparse or dense matrix first matrix of the product B : sparse or dense matrix second matrix of the product format : string format of the result (e.g. "csr") Returns ------- kronecker product in a sparse matrix format Examples -------- >>> A = csr_matrix(array([[0,2],[5,0]])) >>> B = csr_matrix(array([[1,2],[3,4]])) >>> kron(A,B).todense() matrix([[ 0, 0, 2, 4], [ 0, 0, 6, 8], [ 5, 10, 0, 0], [15, 20, 0, 0]]) >>> kron(A,[[1,2],[3,4]]).todense() matrix([[ 0, 0, 2, 4], [ 0, 0, 6, 8], [ 5, 10, 0, 0], [15, 20, 0, 0]]) """ B = coo_matrix(B) if (format is None or format == "bsr") and 2 * B.nnz >= B.shape[0] * B.shape[1]: #B is fairly dense, use BSR A = csr_matrix(A, copy=True) output_shape = (A.shape[0] * B.shape[0], A.shape[1] * B.shape[1]) if A.nnz == 0 or B.nnz == 0: # kronecker product is the zero matrix return coo_matrix(output_shape) B = B.toarray() data = A.data.repeat(B.size).reshape(-1, B.shape[0], B.shape[1]) data = data * B return bsr_matrix((data, A.indices, A.indptr), shape=output_shape) else: #use COO A = coo_matrix(A) output_shape = (A.shape[0] * B.shape[0], A.shape[1] * B.shape[1]) if A.nnz == 0 or B.nnz == 0: # kronecker product is the zero matrix return coo_matrix(output_shape) # expand entries of a into blocks row = A.row.repeat(B.nnz) col = A.col.repeat(B.nnz) data = A.data.repeat(B.nnz) row *= B.shape[0] col *= B.shape[1] # increment block indices row, col = row.reshape(-1, B.nnz), col.reshape(-1, B.nnz) row += B.row col += B.col row, col = row.reshape(-1), col.reshape(-1) # compute block entries data = data.reshape(-1, B.nnz) * B.data data = data.reshape(-1) return coo_matrix((data, (row, col)), shape=output_shape).asformat(format)