| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759 | 
							- from collections import defaultdict
 
- from operator import index as index_
 
- from sympy.core.expr import Expr
 
- from sympy.core.kind import Kind, NumberKind, UndefinedKind
 
- from sympy.core.numbers import Integer, Rational
 
- from sympy.core.sympify import _sympify, SympifyError
 
- from sympy.core.singleton import S
 
- from sympy.polys.domains import ZZ, QQ, EXRAW
 
- from sympy.polys.matrices import DomainMatrix
 
- from sympy.utilities.exceptions import sympy_deprecation_warning
 
- from sympy.utilities.iterables import is_sequence
 
- from sympy.utilities.misc import filldedent
 
- from .common import classof
 
- from .matrices import MatrixBase, MatrixKind, ShapeError
 
- class RepMatrix(MatrixBase):
 
-     """Matrix implementation based on DomainMatrix as an internal representation.
 
-     The RepMatrix class is a superclass for Matrix, ImmutableMatrix,
 
-     SparseMatrix and ImmutableSparseMatrix which are the main usable matrix
 
-     classes in SymPy. Most methods on this class are simply forwarded to
 
-     DomainMatrix.
 
-     """
 
-     #
 
-     # MatrixBase is the common superclass for all of the usable explicit matrix
 
-     # classes in SymPy. The idea is that MatrixBase is an abstract class though
 
-     # and that subclasses will implement the lower-level methods.
 
-     #
 
-     # RepMatrix is a subclass of MatrixBase that uses DomainMatrix as an
 
-     # internal representation and delegates lower-level methods to
 
-     # DomainMatrix. All of SymPy's standard explicit matrix classes subclass
 
-     # RepMatrix and so use DomainMatrix internally.
 
-     #
 
-     # A RepMatrix uses an internal DomainMatrix with the domain set to ZZ, QQ
 
-     # or EXRAW. The EXRAW domain is equivalent to the previous implementation
 
-     # of Matrix that used Expr for the elements. The ZZ and QQ domains are used
 
-     # when applicable just because they are compatible with the previous
 
-     # implementation but are much more efficient. Other domains such as QQ[x]
 
-     # are not used because they differ from Expr in some way (e.g. automatic
 
-     # expansion of powers and products).
 
-     #
 
-     _rep: DomainMatrix
 
-     def __eq__(self, other):
 
-         # Skip sympify for mutable matrices...
 
-         if not isinstance(other, RepMatrix):
 
-             try:
 
-                 other = _sympify(other)
 
-             except SympifyError:
 
-                 return NotImplemented
 
-             if not isinstance(other, RepMatrix):
 
-                 return NotImplemented
 
-         return self._rep.unify_eq(other._rep)
 
-     @classmethod
 
-     def _unify_element_sympy(cls, rep, element):
 
-         domain = rep.domain
 
-         element = _sympify(element)
 
-         if domain != EXRAW:
 
-             # The domain can only be ZZ, QQ or EXRAW
 
-             if element.is_Integer:
 
-                 new_domain = domain
 
-             elif element.is_Rational:
 
-                 new_domain = QQ
 
-             else:
 
-                 new_domain = EXRAW
 
-             # XXX: This converts the domain for all elements in the matrix
 
-             # which can be slow. This happens e.g. if __setitem__ changes one
 
-             # element to something that does not fit in the domain
 
-             if new_domain != domain:
 
-                 rep = rep.convert_to(new_domain)
 
-                 domain = new_domain
 
-             if domain != EXRAW:
 
-                 element = new_domain.from_sympy(element)
 
-         if domain == EXRAW and not isinstance(element, Expr):
 
-             sympy_deprecation_warning(
 
-                 """
 
-                 non-Expr objects in a Matrix is deprecated. Matrix represents
 
-                 a mathematical matrix. To represent a container of non-numeric
 
-                 entities, Use a list of lists, TableForm, NumPy array, or some
 
-                 other data structure instead.
 
-                 """,
 
-                 deprecated_since_version="1.9",
 
-                 active_deprecations_target="deprecated-non-expr-in-matrix",
 
-                 stacklevel=4,
 
-             )
 
-         return rep, element
 
-     @classmethod
 
-     def _dod_to_DomainMatrix(cls, rows, cols, dod, types):
 
-         if not all(issubclass(typ, Expr) for typ in types):
 
-             sympy_deprecation_warning(
 
-                 """
 
-                 non-Expr objects in a Matrix is deprecated. Matrix represents
 
-                 a mathematical matrix. To represent a container of non-numeric
 
-                 entities, Use a list of lists, TableForm, NumPy array, or some
 
-                 other data structure instead.
 
-                 """,
 
-                 deprecated_since_version="1.9",
 
-                 active_deprecations_target="deprecated-non-expr-in-matrix",
 
-                 stacklevel=6,
 
-             )
 
-         rep = DomainMatrix(dod, (rows, cols), EXRAW)
 
-         if all(issubclass(typ, Rational) for typ in types):
 
-             if all(issubclass(typ, Integer) for typ in types):
 
-                 rep = rep.convert_to(ZZ)
 
-             else:
 
-                 rep = rep.convert_to(QQ)
 
-         return rep
 
-     @classmethod
 
-     def _flat_list_to_DomainMatrix(cls, rows, cols, flat_list):
 
-         elements_dod = defaultdict(dict)
 
-         for n, element in enumerate(flat_list):
 
-             if element != 0:
 
-                 i, j = divmod(n, cols)
 
-                 elements_dod[i][j] = element
 
-         types = set(map(type, flat_list))
 
-         rep = cls._dod_to_DomainMatrix(rows, cols, elements_dod, types)
 
-         return rep
 
-     @classmethod
 
-     def _smat_to_DomainMatrix(cls, rows, cols, smat):
 
-         elements_dod = defaultdict(dict)
 
-         for (i, j), element in smat.items():
 
-             if element != 0:
 
-                 elements_dod[i][j] = element
 
-         types = set(map(type, smat.values()))
 
-         rep = cls._dod_to_DomainMatrix(rows, cols, elements_dod, types)
 
-         return rep
 
-     def flat(self):
 
-         return self._rep.to_sympy().to_list_flat()
 
-     def _eval_tolist(self):
 
-         return self._rep.to_sympy().to_list()
 
-     def _eval_todok(self):
 
-         return self._rep.to_sympy().to_dok()
 
-     def _eval_values(self):
 
-         return list(self.todok().values())
 
-     def copy(self):
 
-         return self._fromrep(self._rep.copy())
 
-     @property
 
-     def kind(self) -> MatrixKind:
 
-         domain = self._rep.domain
 
-         element_kind: Kind
 
-         if domain in (ZZ, QQ):
 
-             element_kind = NumberKind
 
-         elif domain == EXRAW:
 
-             kinds = {e.kind for e in self.values()}
 
-             if len(kinds) == 1:
 
-                 [element_kind] = kinds
 
-             else:
 
-                 element_kind = UndefinedKind
 
-         else: # pragma: no cover
 
-             raise RuntimeError("Domain should only be ZZ, QQ or EXRAW")
 
-         return MatrixKind(element_kind)
 
-     def _eval_has(self, *patterns):
 
-         # if the matrix has any zeros, see if S.Zero
 
-         # has the pattern.  If _smat is full length,
 
-         # the matrix has no zeros.
 
-         zhas = False
 
-         dok = self.todok()
 
-         if len(dok) != self.rows*self.cols:
 
-             zhas = S.Zero.has(*patterns)
 
-         return zhas or any(value.has(*patterns) for value in dok.values())
 
-     def _eval_is_Identity(self):
 
-         if not all(self[i, i] == 1 for i in range(self.rows)):
 
-             return False
 
-         return len(self.todok()) == self.rows
 
-     def _eval_is_symmetric(self, simpfunc):
 
-         diff = (self - self.T).applyfunc(simpfunc)
 
-         return len(diff.values()) == 0
 
-     def _eval_transpose(self):
 
-         """Returns the transposed SparseMatrix of this SparseMatrix.
 
-         Examples
 
-         ========
 
-         >>> from sympy import SparseMatrix
 
-         >>> a = SparseMatrix(((1, 2), (3, 4)))
 
-         >>> a
 
-         Matrix([
 
-         [1, 2],
 
-         [3, 4]])
 
-         >>> a.T
 
-         Matrix([
 
-         [1, 3],
 
-         [2, 4]])
 
-         """
 
-         return self._fromrep(self._rep.transpose())
 
-     def _eval_col_join(self, other):
 
-         return self._fromrep(self._rep.vstack(other._rep))
 
-     def _eval_row_join(self, other):
 
-         return self._fromrep(self._rep.hstack(other._rep))
 
-     def _eval_extract(self, rowsList, colsList):
 
-         return self._fromrep(self._rep.extract(rowsList, colsList))
 
-     def __getitem__(self, key):
 
-         return _getitem_RepMatrix(self, key)
 
-     @classmethod
 
-     def _eval_zeros(cls, rows, cols):
 
-         rep = DomainMatrix.zeros((rows, cols), ZZ)
 
-         return cls._fromrep(rep)
 
-     @classmethod
 
-     def _eval_eye(cls, rows, cols):
 
-         rep = DomainMatrix.eye((rows, cols), ZZ)
 
-         return cls._fromrep(rep)
 
-     def _eval_add(self, other):
 
-         return classof(self, other)._fromrep(self._rep + other._rep)
 
-     def _eval_matrix_mul(self, other):
 
-         return classof(self, other)._fromrep(self._rep * other._rep)
 
-     def _eval_matrix_mul_elementwise(self, other):
 
-         selfrep, otherrep = self._rep.unify(other._rep)
 
-         newrep = selfrep.mul_elementwise(otherrep)
 
-         return classof(self, other)._fromrep(newrep)
 
-     def _eval_scalar_mul(self, other):
 
-         rep, other = self._unify_element_sympy(self._rep, other)
 
-         return self._fromrep(rep.scalarmul(other))
 
-     def _eval_scalar_rmul(self, other):
 
-         rep, other = self._unify_element_sympy(self._rep, other)
 
-         return self._fromrep(rep.rscalarmul(other))
 
-     def _eval_Abs(self):
 
-         return self._fromrep(self._rep.applyfunc(abs))
 
-     def _eval_conjugate(self):
 
-         rep = self._rep
 
-         domain = rep.domain
 
-         if domain in (ZZ, QQ):
 
-             return self.copy()
 
-         else:
 
-             return self._fromrep(rep.applyfunc(lambda e: e.conjugate()))
 
-     def equals(self, other, failing_expression=False):
 
-         """Applies ``equals`` to corresponding elements of the matrices,
 
-         trying to prove that the elements are equivalent, returning True
 
-         if they are, False if any pair is not, and None (or the first
 
-         failing expression if failing_expression is True) if it cannot
 
-         be decided if the expressions are equivalent or not. This is, in
 
-         general, an expensive operation.
 
-         Examples
 
-         ========
 
-         >>> from sympy import Matrix
 
-         >>> from sympy.abc import x
 
-         >>> A = Matrix([x*(x - 1), 0])
 
-         >>> B = Matrix([x**2 - x, 0])
 
-         >>> A == B
 
-         False
 
-         >>> A.simplify() == B.simplify()
 
-         True
 
-         >>> A.equals(B)
 
-         True
 
-         >>> A.equals(2)
 
-         False
 
-         See Also
 
-         ========
 
-         sympy.core.expr.Expr.equals
 
-         """
 
-         if self.shape != getattr(other, 'shape', None):
 
-             return False
 
-         rv = True
 
-         for i in range(self.rows):
 
-             for j in range(self.cols):
 
-                 ans = self[i, j].equals(other[i, j], failing_expression)
 
-                 if ans is False:
 
-                     return False
 
-                 elif ans is not True and rv is True:
 
-                     rv = ans
 
-         return rv
 
- class MutableRepMatrix(RepMatrix):
 
-     """Mutable matrix based on DomainMatrix as the internal representation"""
 
-     #
 
-     # MutableRepMatrix is a subclass of RepMatrix that adds/overrides methods
 
-     # to make the instances mutable. MutableRepMatrix is a superclass for both
 
-     # MutableDenseMatrix and MutableSparseMatrix.
 
-     #
 
-     is_zero = False
 
-     def __new__(cls, *args, **kwargs):
 
-         return cls._new(*args, **kwargs)
 
-     @classmethod
 
-     def _new(cls, *args, copy=True, **kwargs):
 
-         if copy is False:
 
-             # The input was rows, cols, [list].
 
-             # It should be used directly without creating a copy.
 
-             if len(args) != 3:
 
-                 raise TypeError("'copy=False' requires a matrix be initialized as rows,cols,[list]")
 
-             rows, cols, flat_list = args
 
-         else:
 
-             rows, cols, flat_list = cls._handle_creation_inputs(*args, **kwargs)
 
-             flat_list = list(flat_list) # create a shallow copy
 
-         rep = cls._flat_list_to_DomainMatrix(rows, cols, flat_list)
 
-         return cls._fromrep(rep)
 
-     @classmethod
 
-     def _fromrep(cls, rep):
 
-         obj = super().__new__(cls)
 
-         obj.rows, obj.cols = rep.shape
 
-         obj._rep = rep
 
-         return obj
 
-     def copy(self):
 
-         return self._fromrep(self._rep.copy())
 
-     def as_mutable(self):
 
-         return self.copy()
 
-     def __setitem__(self, key, value):
 
-         """
 
-         Examples
 
-         ========
 
-         >>> from sympy import Matrix, I, zeros, ones
 
-         >>> m = Matrix(((1, 2+I), (3, 4)))
 
-         >>> m
 
-         Matrix([
 
-         [1, 2 + I],
 
-         [3,     4]])
 
-         >>> m[1, 0] = 9
 
-         >>> m
 
-         Matrix([
 
-         [1, 2 + I],
 
-         [9,     4]])
 
-         >>> m[1, 0] = [[0, 1]]
 
-         To replace row r you assign to position r*m where m
 
-         is the number of columns:
 
-         >>> M = zeros(4)
 
-         >>> m = M.cols
 
-         >>> M[3*m] = ones(1, m)*2; M
 
-         Matrix([
 
-         [0, 0, 0, 0],
 
-         [0, 0, 0, 0],
 
-         [0, 0, 0, 0],
 
-         [2, 2, 2, 2]])
 
-         And to replace column c you can assign to position c:
 
-         >>> M[2] = ones(m, 1)*4; M
 
-         Matrix([
 
-         [0, 0, 4, 0],
 
-         [0, 0, 4, 0],
 
-         [0, 0, 4, 0],
 
-         [2, 2, 4, 2]])
 
-         """
 
-         rv = self._setitem(key, value)
 
-         if rv is not None:
 
-             i, j, value = rv
 
-             self._rep, value = self._unify_element_sympy(self._rep, value)
 
-             self._rep.rep.setitem(i, j, value)
 
-     def _eval_col_del(self, col):
 
-         self._rep = DomainMatrix.hstack(self._rep[:,:col], self._rep[:,col+1:])
 
-         self.cols -= 1
 
-     def _eval_row_del(self, row):
 
-         self._rep = DomainMatrix.vstack(self._rep[:row,:], self._rep[row+1:, :])
 
-         self.rows -= 1
 
-     def _eval_col_insert(self, col, other):
 
-         other = self._new(other)
 
-         return self.hstack(self[:,:col], other, self[:,col:])
 
-     def _eval_row_insert(self, row, other):
 
-         other = self._new(other)
 
-         return self.vstack(self[:row,:], other, self[row:,:])
 
-     def col_op(self, j, f):
 
-         """In-place operation on col j using two-arg functor whose args are
 
-         interpreted as (self[i, j], i).
 
-         Examples
 
-         ========
 
-         >>> from sympy import eye
 
-         >>> M = eye(3)
 
-         >>> M.col_op(1, lambda v, i: v + 2*M[i, 0]); M
 
-         Matrix([
 
-         [1, 2, 0],
 
-         [0, 1, 0],
 
-         [0, 0, 1]])
 
-         See Also
 
-         ========
 
-         col
 
-         row_op
 
-         """
 
-         for i in range(self.rows):
 
-             self[i, j] = f(self[i, j], i)
 
-     def col_swap(self, i, j):
 
-         """Swap the two given columns of the matrix in-place.
 
-         Examples
 
-         ========
 
-         >>> from sympy import Matrix
 
-         >>> M = Matrix([[1, 0], [1, 0]])
 
-         >>> M
 
-         Matrix([
 
-         [1, 0],
 
-         [1, 0]])
 
-         >>> M.col_swap(0, 1)
 
-         >>> M
 
-         Matrix([
 
-         [0, 1],
 
-         [0, 1]])
 
-         See Also
 
-         ========
 
-         col
 
-         row_swap
 
-         """
 
-         for k in range(0, self.rows):
 
-             self[k, i], self[k, j] = self[k, j], self[k, i]
 
-     def row_op(self, i, f):
 
-         """In-place operation on row ``i`` using two-arg functor whose args are
 
-         interpreted as ``(self[i, j], j)``.
 
-         Examples
 
-         ========
 
-         >>> from sympy import eye
 
-         >>> M = eye(3)
 
-         >>> M.row_op(1, lambda v, j: v + 2*M[0, j]); M
 
-         Matrix([
 
-         [1, 0, 0],
 
-         [2, 1, 0],
 
-         [0, 0, 1]])
 
-         See Also
 
-         ========
 
-         row
 
-         zip_row_op
 
-         col_op
 
-         """
 
-         for j in range(self.cols):
 
-             self[i, j] = f(self[i, j], j)
 
-     def row_swap(self, i, j):
 
-         """Swap the two given rows of the matrix in-place.
 
-         Examples
 
-         ========
 
-         >>> from sympy import Matrix
 
-         >>> M = Matrix([[0, 1], [1, 0]])
 
-         >>> M
 
-         Matrix([
 
-         [0, 1],
 
-         [1, 0]])
 
-         >>> M.row_swap(0, 1)
 
-         >>> M
 
-         Matrix([
 
-         [1, 0],
 
-         [0, 1]])
 
-         See Also
 
-         ========
 
-         row
 
-         col_swap
 
-         """
 
-         for k in range(0, self.cols):
 
-             self[i, k], self[j, k] = self[j, k], self[i, k]
 
-     def zip_row_op(self, i, k, f):
 
-         """In-place operation on row ``i`` using two-arg functor whose args are
 
-         interpreted as ``(self[i, j], self[k, j])``.
 
-         Examples
 
-         ========
 
-         >>> from sympy import eye
 
-         >>> M = eye(3)
 
-         >>> M.zip_row_op(1, 0, lambda v, u: v + 2*u); M
 
-         Matrix([
 
-         [1, 0, 0],
 
-         [2, 1, 0],
 
-         [0, 0, 1]])
 
-         See Also
 
-         ========
 
-         row
 
-         row_op
 
-         col_op
 
-         """
 
-         for j in range(self.cols):
 
-             self[i, j] = f(self[i, j], self[k, j])
 
-     def copyin_list(self, key, value):
 
-         """Copy in elements from a list.
 
-         Parameters
 
-         ==========
 
-         key : slice
 
-             The section of this matrix to replace.
 
-         value : iterable
 
-             The iterable to copy values from.
 
-         Examples
 
-         ========
 
-         >>> from sympy import eye
 
-         >>> I = eye(3)
 
-         >>> I[:2, 0] = [1, 2] # col
 
-         >>> I
 
-         Matrix([
 
-         [1, 0, 0],
 
-         [2, 1, 0],
 
-         [0, 0, 1]])
 
-         >>> I[1, :2] = [[3, 4]]
 
-         >>> I
 
-         Matrix([
 
-         [1, 0, 0],
 
-         [3, 4, 0],
 
-         [0, 0, 1]])
 
-         See Also
 
-         ========
 
-         copyin_matrix
 
-         """
 
-         if not is_sequence(value):
 
-             raise TypeError("`value` must be an ordered iterable, not %s." % type(value))
 
-         return self.copyin_matrix(key, type(self)(value))
 
-     def copyin_matrix(self, key, value):
 
-         """Copy in values from a matrix into the given bounds.
 
-         Parameters
 
-         ==========
 
-         key : slice
 
-             The section of this matrix to replace.
 
-         value : Matrix
 
-             The matrix to copy values from.
 
-         Examples
 
-         ========
 
-         >>> from sympy import Matrix, eye
 
-         >>> M = Matrix([[0, 1], [2, 3], [4, 5]])
 
-         >>> I = eye(3)
 
-         >>> I[:3, :2] = M
 
-         >>> I
 
-         Matrix([
 
-         [0, 1, 0],
 
-         [2, 3, 0],
 
-         [4, 5, 1]])
 
-         >>> I[0, 1] = M
 
-         >>> I
 
-         Matrix([
 
-         [0, 0, 1],
 
-         [2, 2, 3],
 
-         [4, 4, 5]])
 
-         See Also
 
-         ========
 
-         copyin_list
 
-         """
 
-         rlo, rhi, clo, chi = self.key2bounds(key)
 
-         shape = value.shape
 
-         dr, dc = rhi - rlo, chi - clo
 
-         if shape != (dr, dc):
 
-             raise ShapeError(filldedent("The Matrix `value` doesn't have the "
 
-                                         "same dimensions "
 
-                                         "as the in sub-Matrix given by `key`."))
 
-         for i in range(value.rows):
 
-             for j in range(value.cols):
 
-                 self[i + rlo, j + clo] = value[i, j]
 
-     def fill(self, value):
 
-         """Fill self with the given value.
 
-         Notes
 
-         =====
 
-         Unless many values are going to be deleted (i.e. set to zero)
 
-         this will create a matrix that is slower than a dense matrix in
 
-         operations.
 
-         Examples
 
-         ========
 
-         >>> from sympy import SparseMatrix
 
-         >>> M = SparseMatrix.zeros(3); M
 
-         Matrix([
 
-         [0, 0, 0],
 
-         [0, 0, 0],
 
-         [0, 0, 0]])
 
-         >>> M.fill(1); M
 
-         Matrix([
 
-         [1, 1, 1],
 
-         [1, 1, 1],
 
-         [1, 1, 1]])
 
-         See Also
 
-         ========
 
-         zeros
 
-         ones
 
-         """
 
-         value = _sympify(value)
 
-         if not value:
 
-             self._rep = DomainMatrix.zeros(self.shape, EXRAW)
 
-         else:
 
-             elements_dod = {i: {j: value for j in range(self.cols)} for i in range(self.rows)}
 
-             self._rep = DomainMatrix(elements_dod, self.shape, EXRAW)
 
- def _getitem_RepMatrix(self, key):
 
-     """Return portion of self defined by key. If the key involves a slice
 
-     then a list will be returned (if key is a single slice) or a matrix
 
-     (if key was a tuple involving a slice).
 
-     Examples
 
-     ========
 
-     >>> from sympy import Matrix, I
 
-     >>> m = Matrix([
 
-     ... [1, 2 + I],
 
-     ... [3, 4    ]])
 
-     If the key is a tuple that does not involve a slice then that element
 
-     is returned:
 
-     >>> m[1, 0]
 
-     3
 
-     When a tuple key involves a slice, a matrix is returned. Here, the
 
-     first column is selected (all rows, column 0):
 
-     >>> m[:, 0]
 
-     Matrix([
 
-     [1],
 
-     [3]])
 
-     If the slice is not a tuple then it selects from the underlying
 
-     list of elements that are arranged in row order and a list is
 
-     returned if a slice is involved:
 
-     >>> m[0]
 
-     1
 
-     >>> m[::2]
 
-     [1, 3]
 
-     """
 
-     if isinstance(key, tuple):
 
-         i, j = key
 
-         try:
 
-             return self._rep.getitem_sympy(index_(i), index_(j))
 
-         except (TypeError, IndexError):
 
-             if (isinstance(i, Expr) and not i.is_number) or (isinstance(j, Expr) and not j.is_number):
 
-                 if ((j < 0) is True) or ((j >= self.shape[1]) is True) or\
 
-                    ((i < 0) is True) or ((i >= self.shape[0]) is True):
 
-                     raise ValueError("index out of boundary")
 
-                 from sympy.matrices.expressions.matexpr import MatrixElement
 
-                 return MatrixElement(self, i, j)
 
-             if isinstance(i, slice):
 
-                 i = range(self.rows)[i]
 
-             elif is_sequence(i):
 
-                 pass
 
-             else:
 
-                 i = [i]
 
-             if isinstance(j, slice):
 
-                 j = range(self.cols)[j]
 
-             elif is_sequence(j):
 
-                 pass
 
-             else:
 
-                 j = [j]
 
-             return self.extract(i, j)
 
-     else:
 
-         # Index/slice like a flattened list
 
-         rows, cols = self.shape
 
-         # Raise the appropriate exception:
 
-         if not rows * cols:
 
-             return [][key]
 
-         rep = self._rep.rep
 
-         domain = rep.domain
 
-         is_slice = isinstance(key, slice)
 
-         if is_slice:
 
-             values = [rep.getitem(*divmod(n, cols)) for n in range(rows * cols)[key]]
 
-         else:
 
-             values = [rep.getitem(*divmod(index_(key), cols))]
 
-         if domain != EXRAW:
 
-             to_sympy = domain.to_sympy
 
-             values = [to_sympy(val) for val in values]
 
-         if is_slice:
 
-             return values
 
-         else:
 
-             return values[0]
 
 
  |