<s> """<STR_LIT>""" <EOL> from __future__ import division , print_function , absolute_import <EOL> __docformat__ = "<STR_LIT>" <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> from warnings import warn <EOL> import numpy as np <EOL> from scipy . _lib . six import zip as izip <EOL> from . _sparsetools import coo_tocsr , coo_todense , coo_matvec <EOL> from . base import isspmatrix , SparseEfficiencyWarning , spmatrix <EOL> from . data import _data_matrix , _minmax_mixin <EOL> from . sputils import ( upcast , upcast_char , to_native , isshape , getdtype , <EOL> get_index_dtype , downcast_intp_index ) <EOL> class coo_matrix ( _data_matrix , _minmax_mixin ) : <EOL> """<STR_LIT>""" <EOL> format = '<STR_LIT>' <EOL> def __init__ ( self , arg1 , shape = None , dtype = None , copy = False ) : <EOL> _data_matrix . __init__ ( self ) <EOL> if isinstance ( arg1 , tuple ) : <EOL> if isshape ( arg1 ) : <EOL> M , N = arg1 <EOL> self . shape = ( M , N ) <EOL> idx_dtype = get_index_dtype ( maxval = max ( M , N ) ) <EOL> self . row = np . array ( [ ] , dtype = idx_dtype ) <EOL> self . col = np . array ( [ ] , dtype = idx_dtype ) <EOL> self . data = np . array ( [ ] , getdtype ( dtype , default = float ) ) <EOL> self . has_canonical_format = True <EOL> else : <EOL> try : <EOL> obj , ( row , col ) = arg1 <EOL> except ( TypeError , ValueError ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if shape is None : <EOL> if len ( row ) == <NUM_LIT:0> or len ( col ) == <NUM_LIT:0> : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> M = np . max ( row ) + <NUM_LIT:1> <EOL> N = np . max ( col ) + <NUM_LIT:1> <EOL> self . shape = ( M , N ) <EOL> else : <EOL> M , N = shape <EOL> self . shape = ( M , N ) <EOL> idx_dtype = get_index_dtype ( maxval = max ( self . shape ) ) <EOL> self . row = np . array ( row , copy = copy , dtype = idx_dtype ) <EOL> self . col = np . array ( col , copy = copy , dtype = idx_dtype ) <EOL> self . data = np . array ( obj , copy = copy ) <EOL> self . has_canonical_format = False <EOL> else : <EOL> if isspmatrix ( arg1 ) : <EOL> if isspmatrix_coo ( arg1 ) and copy : <EOL> self . row = arg1 . row . copy ( ) <EOL> self . col = arg1 . col . copy ( ) <EOL> self . data = arg1 . data . copy ( ) <EOL> self . shape = arg1 . shape <EOL> else : <EOL> coo = arg1 . tocoo ( ) <EOL> self . row = coo . row <EOL> self . col = coo . col <EOL> self . data = coo . data <EOL> self . shape = coo . shape <EOL> self . has_canonical_format = False <EOL> else : <EOL> M = np . atleast_2d ( np . asarray ( arg1 ) ) <EOL> if M . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> else : <EOL> self . shape = M . shape <EOL> self . row , self . col = M . nonzero ( ) <EOL> self . data = M [ self . row , self . col ] <EOL> self . has_canonical_format = True <EOL> if dtype is not None : <EOL> self . data = self . data . astype ( dtype , copy = False ) <EOL> self . _check ( ) <EOL> def getnnz ( self , axis = None ) : <EOL> if axis is None : <EOL> nnz = len ( self . data ) <EOL> if nnz != len ( self . row ) or nnz != len ( self . col ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if self . data . ndim != <NUM_LIT:1> or self . row . ndim != <NUM_LIT:1> or self . col . ndim != <NUM_LIT:1> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return int ( nnz ) <EOL> if axis < <NUM_LIT:0> : <EOL> axis += <NUM_LIT:2> <EOL> if axis == <NUM_LIT:0> : <EOL> return np . bincount ( downcast_intp_index ( self . col ) , <EOL> minlength = self . shape [ <NUM_LIT:1> ] ) <EOL> elif axis == <NUM_LIT:1> : <EOL> return np . bincount ( downcast_intp_index ( self . row ) , <EOL> minlength = self . shape [ <NUM_LIT:0> ] ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> getnnz . __doc__ = spmatrix . getnnz . __doc__ <EOL> def _check ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . row . dtype . kind != '<STR_LIT:i>' : <EOL> warn ( "<STR_LIT>" <EOL> % self . row . dtype . name ) <EOL> if self . col . dtype . kind != '<STR_LIT:i>' : <EOL> warn ( "<STR_LIT>" <EOL> % self . col . dtype . name ) <EOL> idx_dtype = get_index_dtype ( maxval = max ( self . shape ) ) <EOL> self . row = np . asarray ( self . row , dtype = idx_dtype ) <EOL> self . col = np . asarray ( self . col , dtype = idx_dtype ) <EOL> self . data = to_native ( self . data ) <EOL> if self . nnz > <NUM_LIT:0> : <EOL> if self . row . max ( ) >= self . shape [ <NUM_LIT:0> ] : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if self . col . max ( ) >= self . shape [ <NUM_LIT:1> ] : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if self . row . min ( ) < <NUM_LIT:0> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if self . col . min ( ) < <NUM_LIT:0> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> def transpose ( self , copy = False ) : <EOL> M , N = self . shape <EOL> return coo_matrix ( ( self . data , ( self . col , self . row ) ) , shape = ( N , M ) , copy = copy ) <EOL> def toarray ( self , order = None , out = None ) : <EOL> """<STR_LIT>""" <EOL> B = self . _process_toarray_args ( order , out ) <EOL> fortran = int ( B . flags . f_contiguous ) <EOL> if not fortran and not B . flags . c_contiguous : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> M , N = self . shape <EOL> coo_todense ( M , N , self . nnz , self . row , self . col , self . data , <EOL> B . ravel ( '<STR_LIT:A>' ) , fortran ) <EOL> return B <EOL> def tocsc ( self , copy = False ) : <EOL> """<STR_LIT>""" <EOL> from . csc import csc_matrix <EOL> if self . nnz == <NUM_LIT:0> : <EOL> return csc_matrix ( self . shape , dtype = self . dtype ) <EOL> else : <EOL> M , N = self . shape <EOL> self . sum_duplicates ( ) <EOL> idx_dtype = get_index_dtype ( ( self . col , self . row ) , <EOL> maxval = max ( self . nnz , M ) ) <EOL> row = self . row . astype ( idx_dtype , copy = False ) <EOL> col = self . col . astype ( idx_dtype , copy = False ) <EOL> indptr = np . empty ( N + <NUM_LIT:1> , dtype = idx_dtype ) <EOL> indices = np . empty_like ( row , dtype = idx_dtype ) <EOL> data = np . empty_like ( self . data , dtype = upcast ( self . dtype ) ) <EOL> coo_tocsr ( N , M , self . nnz , col , row , self . data , <EOL> indptr , indices , data ) <EOL> return csc_matrix ( ( data , indices , indptr ) , shape = self . shape ) <EOL> def tocsr ( self , copy = False ) : <EOL> """<STR_LIT>""" <EOL> from . csr import csr_matrix <EOL> if self . nnz == <NUM_LIT:0> : <EOL> return csr_matrix ( self . shape , dtype = self . dtype ) <EOL> else : <EOL> M , N = self . shape <EOL> self . sum_duplicates ( ) <EOL> idx_dtype = get_index_dtype ( ( self . row , self . col ) , <EOL> maxval = max ( self . nnz , N ) ) <EOL> row = self . row . astype ( idx_dtype , copy = False ) <EOL> col = self . col . astype ( idx_dtype , copy = False ) <EOL> indptr = np . empty ( M + <NUM_LIT:1> , dtype = idx_dtype ) <EOL> indices = np . empty_like ( col , dtype = idx_dtype ) <EOL> data = np . empty_like ( self . data , dtype = upcast ( self . dtype ) ) <EOL> coo_tocsr ( M , N , self . nnz , row , col , self . data , <EOL> indptr , indices , data ) <EOL> return csr_matrix ( ( data , indices , indptr ) , shape = self . shape ) <EOL> def tocoo ( self , copy = False ) : <EOL> if copy : <EOL> return self . copy ( ) <EOL> else : <EOL> return self <EOL> tocoo . __doc__ = spmatrix . tocoo . __doc__ <EOL> def todia ( self , copy = False ) : <EOL> from . dia import dia_matrix <EOL> self . sum_duplicates ( ) <EOL> ks = self . col - self . row <EOL> diags , diag_idx = np . unique ( ks , return_inverse = True ) <EOL> if len ( diags ) > <NUM_LIT:100> : <EOL> warn ( "<STR_LIT>" <EOL> "<STR_LIT>" % len ( diags ) , SparseEfficiencyWarning ) <EOL> if self . data . size == <NUM_LIT:0> : <EOL> data = np . zeros ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , dtype = self . dtype ) <EOL> else : <EOL> data = np . zeros ( ( len ( diags ) , self . col . max ( ) + <NUM_LIT:1> ) , dtype = self . dtype ) <EOL> data [ diag_idx , self . col ] = self . data <EOL> return dia_matrix ( ( data , diags ) , shape = self . shape ) <EOL> todia . __doc__ = spmatrix . todia . __doc__ <EOL> def todok ( self , copy = False ) : <EOL> from . dok import dok_matrix <EOL> self . sum_duplicates ( ) <EOL> dok = dok_matrix ( ( self . shape ) , dtype = self . dtype ) <EOL> dok . update ( izip ( izip ( self . row , self . col ) , self . data ) ) <EOL> return dok <EOL> todok . __doc__ = spmatrix . todok . __doc__ <EOL> def diagonal ( self ) : <EOL> diag = np . zeros ( min ( self . shape ) , dtype = self . dtype ) <EOL> diag_mask = self . row == self . col <EOL> if self . has_canonical_format : <EOL> row = self . row [ diag_mask ] <EOL> data = self . data [ diag_mask ] <EOL> else : <EOL> row , _ , data = self . _sum_duplicates ( self . row [ diag_mask ] , <EOL> self . col [ diag_mask ] , <EOL> self . data [ diag_mask ] ) <EOL> diag [ row ] = data <EOL> return diag <EOL> diagonal . __doc__ = _data_matrix . diagonal . __doc__ <EOL> def _setdiag ( self , values , k ) : <EOL> M , N = self . shape <EOL> if values . ndim and not len ( values ) : <EOL> return <EOL> idx_dtype = self . row . dtype <EOL> full_keep = self . col - self . row != k <EOL> if k < <NUM_LIT:0> : <EOL> max_index = min ( M + k , N ) <EOL> if values . ndim : <EOL> max_index = min ( max_index , len ( values ) ) <EOL> keep = np . logical_or ( full_keep , self . col >= max_index ) <EOL> new_row = np . arange ( - k , - k + max_index , dtype = idx_dtype ) <EOL> new_col = np . arange ( max_index , dtype = idx_dtype ) <EOL> else : <EOL> max_index = min ( M , N - k ) <EOL> if values . ndim : <EOL> max_index = min ( max_index , len ( values ) ) <EOL> keep = np . logical_or ( full_keep , self . row >= max_index ) <EOL> new_row = np . arange ( max_index , dtype = idx_dtype ) <EOL> new_col = np . arange ( k , k + max_index , dtype = idx_dtype ) <EOL> if values . ndim : <EOL> new_data = values [ : max_index ] <EOL> else : <EOL> new_data = np . empty ( max_index , dtype = self . dtype ) <EOL> new_data [ : ] = values <EOL> self . row = np . concatenate ( ( self . row [ keep ] , new_row ) ) <EOL> self . col = np . concatenate ( ( self . col [ keep ] , new_col ) ) <EOL> self . data = np . concatenate ( ( self . data [ keep ] , new_data ) ) <EOL> self . has_canonical_format = False <EOL> def _with_data ( self , data , copy = True ) : <EOL> """<STR_LIT>""" <EOL> if copy : <EOL> return coo_matrix ( ( data , ( self . row . copy ( ) , self . col . copy ( ) ) ) , <EOL> shape = self . shape , dtype = data . dtype ) <EOL> else : <EOL> return coo_matrix ( ( data , ( self . row , self . col ) ) , <EOL> shape = self . shape , dtype = data . dtype ) <EOL> def sum_duplicates ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . has_canonical_format : <EOL> return <EOL> summed = self . _sum_duplicates ( self . row , self . col , self . data ) <EOL> self . row , self . col , self . data = summed <EOL> self . has_canonical_format = True <EOL> def _sum_duplicates ( self , row , col , data ) : <EOL> if len ( data ) == <NUM_LIT:0> : <EOL> return row , col , data <EOL> order = np . lexsort ( ( row , col ) ) <EOL> row = row [ order ] <EOL> col = col [ order ] <EOL> data = data [ order ] <EOL> unique_mask = ( ( row [ <NUM_LIT:1> : ] != row [ : - <NUM_LIT:1> ] ) | <EOL> ( col [ <NUM_LIT:1> : ] != col [ : - <NUM_LIT:1> ] ) ) <EOL> unique_mask = np . append ( True , unique_mask ) <EOL> row = row [ unique_mask ] <EOL> col = col [ unique_mask ] <EOL> unique_inds , = np . nonzero ( unique_mask ) <EOL> data = np . add . reduceat ( data , unique_inds , dtype = self . dtype ) <EOL> return row , col , data <EOL> def eliminate_zeros ( self ) : <EOL> """<STR_LIT>""" <EOL> mask = self . data != <NUM_LIT:0> <EOL> self . data = self . data [ mask ] <EOL> self . row = self . row [ mask ] <EOL> self . col = self . col [ mask ] <EOL> def _mul_vector ( self , other ) : <EOL> result = np . zeros ( self . shape [ <NUM_LIT:0> ] , dtype = upcast_char ( self . dtype . char , <EOL> other . dtype . char ) ) <EOL> coo_matvec ( self . nnz , self . row , self . col , self . data , other , result ) <EOL> return result <EOL> def _mul_multivector ( self , other ) : <EOL> return np . hstack ( [ self . _mul_vector ( col ) . reshape ( - <NUM_LIT:1> , <NUM_LIT:1> ) for col in other . T ] ) <EOL> def isspmatrix_coo ( x ) : <EOL> return isinstance ( x , coo_matrix ) </s>
