<s> from __future__ import print_function , division <EOL> import copy <EOL> from collections import defaultdict <EOL> from sympy . core . containers import Dict <EOL> from sympy . core . compatibility import is_sequence , as_int , range <EOL> from sympy . core . logic import fuzzy_and <EOL> from sympy . core . singleton import S <EOL> from sympy . functions . elementary . miscellaneous import sqrt <EOL> from sympy . utilities . iterables import uniq <EOL> from . matrices import MatrixBase , ShapeError , a2idx <EOL> from . dense import Matrix <EOL> import collections <EOL> class SparseMatrix ( MatrixBase ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args ) : <EOL> if len ( args ) == <NUM_LIT:1> and isinstance ( args [ <NUM_LIT:0> ] , SparseMatrix ) : <EOL> self . rows = args [ <NUM_LIT:0> ] . rows <EOL> self . cols = args [ <NUM_LIT:0> ] . cols <EOL> self . _smat = dict ( args [ <NUM_LIT:0> ] . _smat ) <EOL> return <EOL> self . _smat = { } <EOL> if len ( args ) == <NUM_LIT:3> : <EOL> self . rows = as_int ( args [ <NUM_LIT:0> ] ) <EOL> self . cols = as_int ( args [ <NUM_LIT:1> ] ) <EOL> if isinstance ( args [ <NUM_LIT:2> ] , collections . Callable ) : <EOL> op = args [ <NUM_LIT:2> ] <EOL> for i in range ( self . rows ) : <EOL> for j in range ( self . cols ) : <EOL> value = self . _sympify ( <EOL> op ( self . _sympify ( i ) , self . _sympify ( j ) ) ) <EOL> if value : <EOL> self . _smat [ ( i , j ) ] = value <EOL> elif isinstance ( args [ <NUM_LIT:2> ] , ( dict , Dict ) ) : <EOL> for key in args [ <NUM_LIT:2> ] . keys ( ) : <EOL> v = args [ <NUM_LIT:2> ] [ key ] <EOL> if v : <EOL> self . _smat [ key ] = self . _sympify ( v ) <EOL> elif is_sequence ( args [ <NUM_LIT:2> ] ) : <EOL> if len ( args [ <NUM_LIT:2> ] ) != self . rows * self . cols : <EOL> raise ValueError ( <EOL> '<STR_LIT>' % <EOL> ( len ( args [ <NUM_LIT:2> ] ) , self . rows * self . cols ) ) <EOL> flat_list = args [ <NUM_LIT:2> ] <EOL> for i in range ( self . rows ) : <EOL> for j in range ( self . cols ) : <EOL> value = self . _sympify ( flat_list [ i * self . cols + j ] ) <EOL> if value : <EOL> self . _smat [ ( i , j ) ] = value <EOL> else : <EOL> r , c , _list = Matrix . _handle_creation_inputs ( * args ) <EOL> self . rows = r <EOL> self . cols = c <EOL> for i in range ( self . rows ) : <EOL> for j in range ( self . cols ) : <EOL> value = _list [ self . cols * i + j ] <EOL> if value : <EOL> self . _smat [ ( i , j ) ] = value <EOL> def __getitem__ ( self , key ) : <EOL> if isinstance ( key , tuple ) : <EOL> i , j = key <EOL> try : <EOL> i , j = self . key2ij ( key ) <EOL> return self . _smat . get ( ( i , j ) , S . Zero ) <EOL> except ( TypeError , IndexError ) : <EOL> if isinstance ( i , slice ) : <EOL> i = list ( range ( self . rows ) ) [ i ] <EOL> elif is_sequence ( i ) : <EOL> pass <EOL> else : <EOL> if i >= self . rows : <EOL> raise IndexError ( '<STR_LIT>' ) <EOL> i = [ i ] <EOL> if isinstance ( j , slice ) : <EOL> j = list ( range ( self . cols ) ) [ j ] <EOL> elif is_sequence ( j ) : <EOL> pass <EOL> else : <EOL> if j >= self . cols : <EOL> raise IndexError ( '<STR_LIT>' ) <EOL> j = [ j ] <EOL> return self . extract ( i , j ) <EOL> if isinstance ( key , slice ) : <EOL> lo , hi = key . indices ( len ( self ) ) [ : <NUM_LIT:2> ] <EOL> L = [ ] <EOL> for i in range ( lo , hi ) : <EOL> m , n = divmod ( i , self . cols ) <EOL> L . append ( self . _smat . get ( ( m , n ) , S . Zero ) ) <EOL> return L <EOL> i , j = divmod ( a2idx ( key , len ( self ) ) , self . cols ) <EOL> return self . _smat . get ( ( i , j ) , S . Zero ) <EOL> def __setitem__ ( self , key , value ) : <EOL> raise NotImplementedError ( ) <EOL> def copy ( self ) : <EOL> return self . _new ( self . rows , self . cols , self . _smat ) <EOL> @ property <EOL> def is_Identity ( self ) : <EOL> if not self . is_square : <EOL> return False <EOL> if not all ( self [ i , i ] == <NUM_LIT:1> for i in range ( self . rows ) ) : <EOL> return False <EOL> return len ( self . _smat ) == self . rows <EOL> def tolist ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . rows : <EOL> return [ ] <EOL> if not self . cols : <EOL> return [ [ ] for i in range ( self . rows ) ] <EOL> I , J = self . shape <EOL> return [ [ self [ i , j ] for j in range ( J ) ] for i in range ( I ) ] <EOL> def row ( self , i ) : <EOL> """<STR_LIT>""" <EOL> return self [ i , : ] <EOL> def col ( self , j ) : <EOL> """<STR_LIT>""" <EOL> return self [ : , j ] <EOL> def row_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ tuple ( k + ( self [ k ] , ) ) for k in <EOL> sorted ( list ( self . _smat . keys ( ) ) , key = lambda k : list ( k ) ) ] <EOL> RL = property ( row_list , None , None , "<STR_LIT>" ) <EOL> def col_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ tuple ( k + ( self [ k ] , ) ) for k in sorted ( list ( self . _smat . keys ( ) ) , key = lambda k : list ( reversed ( k ) ) ) ] <EOL> CL = property ( col_list , None , None , "<STR_LIT>" ) <EOL> def _eval_trace ( self ) : <EOL> """<STR_LIT>""" <EOL> trace = S . Zero <EOL> for i in range ( self . cols ) : <EOL> trace += self . _smat . get ( ( i , i ) , <NUM_LIT:0> ) <EOL> return trace <EOL> def _eval_transpose ( self ) : <EOL> """<STR_LIT>""" <EOL> tran = self . zeros ( self . cols , self . rows ) <EOL> for key , value in self . _smat . items ( ) : <EOL> key = key [ <NUM_LIT:1> ] , key [ <NUM_LIT:0> ] <EOL> tran . _smat [ key ] = value <EOL> return tran <EOL> def _eval_conjugate ( self ) : <EOL> """<STR_LIT>""" <EOL> conj = self . copy ( ) <EOL> for key , value in self . _smat . items ( ) : <EOL> conj . _smat [ key ] = value . conjugate ( ) <EOL> return conj <EOL> def multiply ( self , other ) : <EOL> """<STR_LIT>""" <EOL> A = self <EOL> B = other <EOL> Blist = [ [ ] for i in range ( B . rows ) ] <EOL> for i , j , v in B . row_list ( ) : <EOL> Blist [ i ] . append ( ( j , v ) ) <EOL> Cdict = defaultdict ( int ) <EOL> for k , j , Akj in A . row_list ( ) : <EOL> for n , Bjn in Blist [ j ] : <EOL> temp = Akj * Bjn <EOL> Cdict [ k , n ] += temp <EOL> rv = self . zeros ( A . rows , B . cols ) <EOL> rv . _smat = { k : v for k , v in Cdict . items ( ) if v } <EOL> return rv <EOL> def scalar_multiply ( self , scalar ) : <EOL> "<STR_LIT>" <EOL> M = self . zeros ( * self . shape ) <EOL> if scalar : <EOL> for i in self . _smat : <EOL> v = scalar * self . _smat [ i ] <EOL> if v : <EOL> M . _smat [ i ] = v <EOL> else : <EOL> M . _smat . pop ( i , None ) <EOL> return M <EOL> def __mul__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( other , SparseMatrix ) : <EOL> return self . multiply ( other ) <EOL> if isinstance ( other , MatrixBase ) : <EOL> return other . _new ( self * self . _new ( other ) ) <EOL> return self . scalar_multiply ( other ) <EOL> __matmul__ = __mul__ <EOL> def __rmul__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( other , MatrixBase ) : <EOL> return other * other . _new ( self ) <EOL> return self . scalar_multiply ( other ) <EOL> __rmatmul__ = __rmul__ <EOL> def __add__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( other , SparseMatrix ) : <EOL> return self . add ( other ) <EOL> elif isinstance ( other , MatrixBase ) : <EOL> return other . _new ( other + self ) <EOL> else : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" % <EOL> tuple ( [ c . __class__ . __name__ for c in ( other , self ) ] ) ) <EOL> def __neg__ ( self ) : <EOL> """<STR_LIT>""" <EOL> rv = self . copy ( ) <EOL> for k , v in rv . _smat . items ( ) : <EOL> rv . _smat [ k ] = - v <EOL> return rv <EOL> def add ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( other , SparseMatrix ) : <EOL> raise ValueError ( '<STR_LIT>' % <EOL> tuple ( [ c . __class__ . __name__ for c in ( self , other ) ] ) ) <EOL> if self . shape != other . shape : <EOL> raise ShapeError ( ) <EOL> M = self . copy ( ) <EOL> for i , v in other . _smat . items ( ) : <EOL> v = M [ i ] + v <EOL> if v : <EOL> M . _smat [ i ] = v <EOL> else : <EOL> M . _smat . pop ( i , None ) <EOL> return M <EOL> def extract ( self , rowsList , colsList ) : <EOL> urow = list ( uniq ( rowsList ) ) <EOL> ucol = list ( uniq ( colsList ) ) <EOL> smat = { } <EOL> if len ( urow ) * len ( ucol ) < len ( self . _smat ) : <EOL> for i , r in enumerate ( urow ) : <EOL> for j , c in enumerate ( ucol ) : <EOL> smat [ i , j ] = self . _smat . get ( ( r , c ) , <NUM_LIT:0> ) <EOL> else : <EOL> for rk , ck in self . _smat : <EOL> if rk in urow and ck in ucol : <EOL> smat [ ( urow . index ( rk ) , ucol . index ( ck ) ) ] = self . _smat [ ( rk , ck ) ] <EOL> rv = self . _new ( len ( urow ) , len ( ucol ) , smat ) <EOL> if len ( rowsList ) != len ( urow ) : <EOL> for i , r in enumerate ( rowsList ) : <EOL> i_previous = rowsList . index ( r ) <EOL> if i_previous != i : <EOL> rv = rv . row_insert ( i , rv . row ( i_previous ) ) <EOL> if len ( colsList ) != len ( ucol ) : <EOL> for i , c in enumerate ( colsList ) : <EOL> i_previous = colsList . index ( c ) <EOL> if i_previous != i : <EOL> rv = rv . col_insert ( i , rv . col ( i_previous ) ) <EOL> return rv <EOL> extract . __doc__ = MatrixBase . extract . __doc__ <EOL> @ property <EOL> def is_hermitian ( self ) : <EOL> """<STR_LIT>""" <EOL> def cond ( ) : <EOL> d = self . _smat <EOL> yield self . is_square <EOL> if len ( d ) <= self . rows : <EOL> yield fuzzy_and ( <EOL> d [ i , i ] . is_real for i , j in d if i == j ) <EOL> else : <EOL> yield fuzzy_and ( <EOL> d [ i , i ] . is_real for i in range ( self . rows ) if ( i , i ) in d ) <EOL> yield fuzzy_and ( <EOL> ( ( self [ i , j ] - self [ j , i ] . conjugate ( ) ) . is_zero <EOL> if ( j , i ) in d else False ) for ( i , j ) in d ) <EOL> return fuzzy_and ( i for i in cond ( ) ) <EOL> def is_symmetric ( self , simplify = True ) : <EOL> """<STR_LIT>""" <EOL> if simplify : <EOL> return all ( ( k [ <NUM_LIT:1> ] , k [ <NUM_LIT:0> ] ) in self . _smat and <EOL> not ( self [ k ] - self [ ( k [ <NUM_LIT:1> ] , k [ <NUM_LIT:0> ] ) ] ) . simplify ( ) <EOL> for k in self . _smat ) <EOL> else : <EOL> return all ( ( k [ <NUM_LIT:1> ] , k [ <NUM_LIT:0> ] ) in self . _smat and <EOL> self [ k ] == self [ ( k [ <NUM_LIT:1> ] , k [ <NUM_LIT:0> ] ) ] for k in self . _smat ) <EOL> def has ( self , * patterns ) : <EOL> """<STR_LIT>""" <EOL> return any ( self [ key ] . has ( * patterns ) for key in self . _smat ) <EOL> def applyfunc ( self , f ) : <EOL> """<STR_LIT>""" <EOL> if not callable ( f ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> out = self . copy ( ) <EOL> for k , v in self . _smat . items ( ) : <EOL> fv = f ( v ) <EOL> if fv : <EOL> out . _smat [ k ] = fv <EOL> else : <EOL> out . _smat . pop ( k , None ) <EOL> return out <EOL> def reshape ( self , rows , cols ) : <EOL> """<STR_LIT>""" <EOL> if len ( self ) != rows * cols : <EOL> raise ValueError ( "<STR_LIT>" % ( rows , cols ) ) <EOL> smat = { } <EOL> for k , v in self . _smat . items ( ) : <EOL> i , j = k <EOL> n = i * self . cols + j <EOL> ii , jj = divmod ( n , cols ) <EOL> smat [ ( ii , jj ) ] = self . _smat [ ( i , j ) ] <EOL> return self . _new ( rows , cols , smat ) <EOL> def liupc ( self ) : <EOL> """<STR_LIT>""" <EOL> R = [ [ ] for r in range ( self . rows ) ] <EOL> for r , c , _ in self . row_list ( ) : <EOL> if c <= r : <EOL> R [ r ] . append ( c ) <EOL> inf = len ( R ) <EOL> parent = [ inf ] * self . rows <EOL> virtual = [ inf ] * self . rows <EOL> for r in range ( self . rows ) : <EOL> for c in R [ r ] [ : - <NUM_LIT:1> ] : <EOL> while virtual [ c ] < r : <EOL> t = virtual [ c ] <EOL> virtual [ c ] = r <EOL> c = t <EOL> if virtual [ c ] == inf : <EOL> parent [ c ] = virtual [ c ] = r <EOL> return R , parent <EOL> def row_structure_symbolic_cholesky ( self ) : <EOL> """<STR_LIT>""" <EOL> R , parent = self . liupc ( ) <EOL> inf = len ( R ) <EOL> Lrow = copy . deepcopy ( R ) <EOL> for k in range ( self . rows ) : <EOL> for j in R [ k ] : <EOL> while j != inf and j != k : <EOL> Lrow [ k ] . append ( j ) <EOL> j = parent [ j ] <EOL> Lrow [ k ] = list ( sorted ( set ( Lrow [ k ] ) ) ) <EOL> return Lrow <EOL> def _cholesky_sparse ( self ) : <EOL> """<STR_LIT>""" <EOL> Crowstruc = self . row_structure_symbolic_cholesky ( ) <EOL> C = self . zeros ( self . rows ) <EOL> for i in range ( len ( Crowstruc ) ) : <EOL> for j in Crowstruc [ i ] : <EOL> if i != j : <EOL> C [ i , j ] = self [ i , j ] <EOL> summ = <NUM_LIT:0> <EOL> for p1 in Crowstruc [ i ] : <EOL> if p1 < j : <EOL> for p2 in Crowstruc [ j ] : <EOL> if p2 < j : <EOL> if p1 == p2 : <EOL> summ += C [ i , p1 ] * C [ j , p1 ] <EOL> else : <EOL> break <EOL> else : <EOL> break <EOL> C [ i , j ] -= summ <EOL> C [ i , j ] /= C [ j , j ] <EOL> else : <EOL> C [ j , j ] = self [ j , j ] <EOL> summ = <NUM_LIT:0> <EOL> for k in Crowstruc [ j ] : <EOL> if k < j : <EOL> summ += C [ j , k ] ** <NUM_LIT:2> <EOL> else : <EOL> break <EOL> C [ j , j ] -= summ <EOL> C [ j , j ] = sqrt ( C [ j , j ] ) <EOL> return C <EOL> def _LDL_sparse ( self ) : <EOL> """<STR_LIT>""" <EOL> Lrowstruc = self . row_structure_symbolic_cholesky ( ) <EOL> L = self . eye ( self . rows ) <EOL> D = self . zeros ( self . rows , self . cols ) <EOL> for i in range ( len ( Lrowstruc ) ) : <EOL> for j in Lrowstruc [ i ] : <EOL> if i != j : <EOL> L [ i , j ] = self [ i , j ] <EOL> summ = <NUM_LIT:0> <EOL> for p1 in Lrowstruc [ i ] : <EOL> if p1 < j : <EOL> for p2 in Lrowstruc [ j ] : <EOL> if p2 < j : <EOL> if p1 == p2 : <EOL> summ += L [ i , p1 ] * L [ j , p1 ] * D [ p1 , p1 ] <EOL> else : <EOL> break <EOL> else : <EOL> break <EOL> L [ i , j ] -= summ <EOL> L [ i , j ] /= D [ j , j ] <EOL> elif i == j : <EOL> D [ i , i ] = self [ i , i ] <EOL> summ = <NUM_LIT:0> <EOL> for k in Lrowstruc [ i ] : <EOL> if k < i : <EOL> summ += L [ i , k ] ** <NUM_LIT:2> * D [ k , k ] <EOL> else : <EOL> break <EOL> D [ i , i ] -= summ <EOL> return L , D <EOL> def _lower_triangular_solve ( self , rhs ) : <EOL> """<STR_LIT>""" <EOL> rows = [ [ ] for i in range ( self . rows ) ] <EOL> for i , j , v in self . row_list ( ) : <EOL> if i > j : <EOL> rows [ i ] . append ( ( j , v ) ) <EOL> X = rhs . copy ( ) <EOL> for i in range ( self . rows ) : <EOL> for j , v in rows [ i ] : <EOL> X [ i , <NUM_LIT:0> ] -= v * X [ j , <NUM_LIT:0> ] <EOL> X [ i , <NUM_LIT:0> ] /= self [ i , i ] <EOL> return self . _new ( X ) <EOL> def _upper_triangular_solve ( self , rhs ) : <EOL> """<STR_LIT>""" <EOL> rows = [ [ ] for i in range ( self . rows ) ] <EOL> for i , j , v in self . row_list ( ) : <EOL> if i < j : <EOL> rows [ i ] . append ( ( j , v ) ) <EOL> X = rhs . copy ( ) <EOL> for i in range ( self . rows - <NUM_LIT:1> , - <NUM_LIT:1> , - <NUM_LIT:1> ) : <EOL> rows [ i ] . reverse ( ) <EOL> for j , v in rows [ i ] : <EOL> X [ i , <NUM_LIT:0> ] -= v * X [ j , <NUM_LIT:0> ] <EOL> X [ i , <NUM_LIT:0> ] /= self [ i , i ] <EOL> return self . _new ( X ) <EOL> def _diagonal_solve ( self , rhs ) : <EOL> "<STR_LIT>" <EOL> return self . _new ( self . rows , <NUM_LIT:1> , lambda i , j : rhs [ i , <NUM_LIT:0> ] / self [ i , i ] ) <EOL> def _cholesky_solve ( self , rhs ) : <EOL> L = self . _cholesky_sparse ( ) <EOL> Y = L . _lower_triangular_solve ( rhs ) <EOL> rv = L . T . _upper_triangular_solve ( Y ) <EOL> return rv <EOL> def _LDL_solve ( self , rhs ) : <EOL> L , D = self . _LDL_sparse ( ) <EOL> Z = L . _lower_triangular_solve ( rhs ) <EOL> Y = D . _diagonal_solve ( Z ) <EOL> return L . T . _upper_triangular_solve ( Y ) <EOL> def cholesky ( self ) : <EOL> """<STR_LIT>""" <EOL> from sympy . core . numbers import nan , oo <EOL> if not self . is_symmetric ( ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> M = self . as_mutable ( ) . _cholesky_sparse ( ) <EOL> if M . has ( nan ) or M . has ( oo ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> return self . _new ( M ) <EOL> def LDLdecomposition ( self ) : <EOL> """<STR_LIT>""" <EOL> from sympy . core . numbers import nan , oo <EOL> if not self . is_symmetric ( ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> L , D = self . as_mutable ( ) . _LDL_sparse ( ) <EOL> if L . has ( nan ) or L . has ( oo ) or D . has ( nan ) or D . has ( oo ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> return self . _new ( L ) , self . _new ( D ) <EOL> def solve_least_squares ( self , rhs , method = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> t = self . T <EOL> return ( t * self ) . inv ( method = method ) * t * rhs <EOL> def solve ( self , rhs , method = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if not self . is_square : <EOL> if self . rows < self . cols : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> elif self . rows > self . cols : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> else : <EOL> return self . inv ( method = method ) * rhs <EOL> def _eval_inverse ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> sym = self . is_symmetric ( ) <EOL> M = self . as_mutable ( ) <EOL> I = M . eye ( M . rows ) <EOL> if not sym : <EOL> t = M . T <EOL> r1 = M [ <NUM_LIT:0> , : ] <EOL> M = t * M <EOL> I = t * I <EOL> method = kwargs . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if method in "<STR_LIT>" : <EOL> solve = M . _LDL_solve <EOL> elif method == "<STR_LIT>" : <EOL> solve = M . _cholesky_solve <EOL> else : <EOL> raise NotImplementedError ( <EOL> '<STR_LIT>' % method ) <EOL> rv = M . hstack ( * [ solve ( I [ : , i ] ) for i in range ( I . cols ) ] ) <EOL> if not sym : <EOL> scale = ( r1 * rv [ : , <NUM_LIT:0> ] ) [ <NUM_LIT:0> , <NUM_LIT:0> ] <EOL> rv /= scale <EOL> return self . _new ( rv ) <EOL> def __eq__ ( self , other ) : <EOL> try : <EOL> if self . shape != other . shape : <EOL> return False <EOL> if isinstance ( other , SparseMatrix ) : <EOL> return self . _smat == other . _smat <EOL> elif isinstance ( other , MatrixBase ) : <EOL> return self . _smat == MutableSparseMatrix ( other ) . _smat <EOL> except AttributeError : <EOL> return False <EOL> def __ne__ ( self , other ) : <EOL> return not self == other <EOL> def as_mutable ( self ) : <EOL> """<STR_LIT>""" <EOL> return MutableSparseMatrix ( self ) <EOL> def as_immutable ( self ) : <EOL> """<STR_LIT>""" <EOL> from . immutable import ImmutableSparseMatrix <EOL> return ImmutableSparseMatrix ( self ) <EOL> def nnz ( self ) : <EOL> """<STR_LIT>""" <EOL> return len ( self . _smat ) <EOL> @ classmethod <EOL> def zeros ( cls , r , c = None ) : <EOL> """<STR_LIT>""" <EOL> c = r if c is None else c <EOL> r = as_int ( r ) <EOL> c = as_int ( c ) <EOL> return cls ( r , c , { } ) <EOL> @ classmethod <EOL> def eye ( cls , n ) : <EOL> """<STR_LIT>""" <EOL> n = as_int ( n ) <EOL> return cls ( n , n , { ( i , i ) : S . One for i in range ( n ) } ) <EOL> class MutableSparseMatrix ( SparseMatrix , MatrixBase ) : <EOL> @ classmethod <EOL> def _new ( cls , * args , ** kwargs ) : <EOL> return cls ( * args ) <EOL> def as_mutable ( self ) : <EOL> return self . copy ( ) <EOL> def __setitem__ ( self , key , value ) : <EOL> """<STR_LIT>""" <EOL> rv = self . _setitem ( key , value ) <EOL> if rv is not None : <EOL> i , j , value = rv <EOL> if value : <EOL> self . _smat [ ( i , j ) ] = value <EOL> elif ( i , j ) in self . _smat : <EOL> del self . _smat [ ( i , j ) ] <EOL> __hash__ = None <EOL> def row_del ( self , k ) : <EOL> """<STR_LIT>""" <EOL> newD = { } <EOL> k = a2idx ( k , self . rows ) <EOL> for ( i , j ) in self . _smat : <EOL> if i == k : <EOL> pass <EOL> elif i > k : <EOL> newD [ i - <NUM_LIT:1> , j ] = self . _smat [ i , j ] <EOL> else : <EOL> newD [ i , j ] = self . _smat [ i , j ] <EOL> self . _smat = newD <EOL> self . rows -= <NUM_LIT:1> <EOL> def col_del ( self , k ) : <EOL> """<STR_LIT>""" <EOL> newD = { } <EOL> k = a2idx ( k , self . cols ) <EOL> for ( i , j ) in self . _smat : <EOL> if j == k : <EOL> pass <EOL> elif j > k : <EOL> newD [ i , j - <NUM_LIT:1> ] = self . _smat [ i , j ] <EOL> else : <EOL> newD [ i , j ] = self . _smat [ i , j ] <EOL> self . _smat = newD <EOL> self . cols -= <NUM_LIT:1> <EOL> def row_swap ( self , i , j ) : <EOL> """<STR_LIT>""" <EOL> if i > j : <EOL> i , j = j , i <EOL> rows = self . row_list ( ) <EOL> temp = [ ] <EOL> for ii , jj , v in rows : <EOL> if ii == i : <EOL> self . _smat . pop ( ( ii , jj ) ) <EOL> temp . append ( ( jj , v ) ) <EOL> elif ii == j : <EOL> self . _smat . pop ( ( ii , jj ) ) <EOL> self . _smat [ i , jj ] = v <EOL> elif ii > j : <EOL> break <EOL> for k , v in temp : <EOL> self . _smat [ j , k ] = v <EOL> def col_swap ( self , i , j ) : <EOL> """<STR_LIT>""" <EOL> if i > j : <EOL> i , j = j , i <EOL> rows = self . col_list ( ) <EOL> temp = [ ] <EOL> for ii , jj , v in rows : <EOL> if jj == i : <EOL> self . _smat . pop ( ( ii , jj ) ) <EOL> temp . append ( ( ii , v ) ) <EOL> elif jj == j : <EOL> self . _smat . pop ( ( ii , jj ) ) <EOL> self . _smat [ ii , i ] = v <EOL> elif jj > j : <EOL> break <EOL> for k , v in temp : <EOL> self . _smat [ k , j ] = v <EOL> def row_join ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if not self : <EOL> return type ( self ) ( other ) <EOL> A , B = self , other <EOL> if not A . rows == B . rows : <EOL> raise ShapeError ( ) <EOL> A = A . copy ( ) <EOL> if not isinstance ( B , SparseMatrix ) : <EOL> k = <NUM_LIT:0> <EOL> b = B . _mat <EOL> for i in range ( B . rows ) : <EOL> for j in range ( B . cols ) : <EOL> v = b [ k ] <EOL> if v : <EOL> A . _smat [ ( i , j + A . cols ) ] = v <EOL> k += <NUM_LIT:1> <EOL> else : <EOL> for ( i , j ) , v in B . _smat . items ( ) : <EOL> A . _smat [ ( i , j + A . cols ) ] = v <EOL> A . cols += B . cols <EOL> return A <EOL> def col_join ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if not self : <EOL> return type ( self ) ( other ) <EOL> A , B = self , other <EOL> if not A . cols == B . cols : <EOL> raise ShapeError ( ) <EOL> A = A . copy ( ) <EOL> if not isinstance ( B , SparseMatrix ) : <EOL> k = <NUM_LIT:0> <EOL> b = B . _mat <EOL> for i in range ( B . rows ) : <EOL> for j in range ( B . cols ) : <EOL> v = b [ k ] <EOL> if v : <EOL> A . _smat [ ( i + A . rows , j ) ] = v <EOL> k += <NUM_LIT:1> <EOL> else : <EOL> for ( i , j ) , v in B . _smat . items ( ) : <EOL> A . _smat [ i + A . rows , j ] = v <EOL> A . rows += B . rows <EOL> return A <EOL> def copyin_list ( self , key , value ) : <EOL> if not is_sequence ( value ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> self . copyin_matrix ( key , Matrix ( value ) ) <EOL> def copyin_matrix ( self , key , value ) : <EOL> rlo , rhi , clo , chi = self . key2bounds ( key ) <EOL> shape = value . shape <EOL> dr , dc = rhi - rlo , chi - clo <EOL> if shape != ( dr , dc ) : <EOL> raise ShapeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if not isinstance ( value , SparseMatrix ) : <EOL> for i in range ( value . rows ) : <EOL> for j in range ( value . cols ) : <EOL> self [ i + rlo , j + clo ] = value [ i , j ] <EOL> else : <EOL> if ( rhi - rlo ) * ( chi - clo ) < len ( self ) : <EOL> for i in range ( rlo , rhi ) : <EOL> for j in range ( clo , chi ) : <EOL> self . _smat . pop ( ( i , j ) , None ) <EOL> else : <EOL> for i , j , v in self . row_list ( ) : <EOL> if rlo <= i < rhi and clo <= j < chi : <EOL> self . _smat . pop ( ( i , j ) , None ) <EOL> for k , v in value . _smat . items ( ) : <EOL> i , j = k <EOL> self [ i + rlo , j + clo ] = value [ i , j ] <EOL> def zip_row_op ( self , i , k , f ) : <EOL> """<STR_LIT>""" <EOL> self . row_op ( i , lambda v , j : f ( v , self [ k , j ] ) ) <EOL> def row_op ( self , i , f ) : <EOL> """<STR_LIT>""" <EOL> for j in range ( self . cols ) : <EOL> v = self . _smat . get ( ( i , j ) , S . Zero ) <EOL> fv = f ( v , j ) <EOL> if fv : <EOL> self . _smat [ ( i , j ) ] = fv <EOL> elif v : <EOL> self . _smat . pop ( ( i , j ) ) <EOL> def col_op ( self , j , f ) : <EOL> """<STR_LIT>""" <EOL> for i in range ( self . rows ) : <EOL> v = self . _smat . get ( ( i , j ) , S . Zero ) <EOL> fv = f ( v , i ) <EOL> if fv : <EOL> self . _smat [ ( i , j ) ] = fv <EOL> elif v : <EOL> self . _smat . pop ( ( i , j ) ) <EOL> def fill ( self , value ) : <EOL> """<STR_LIT>""" <EOL> if not value : <EOL> self . _smat = { } <EOL> else : <EOL> v = self . _sympify ( value ) <EOL> self . _smat = dict ( [ ( ( i , j ) , v ) <EOL> for i in range ( self . rows ) for j in range ( self . cols ) ] ) </s>
