Source code for sympy.matrices.immutable

from __future__ import division, print_function

from sympy.core import Basic, Dict, Integer, S, Tuple, sympify
from sympy.core.cache import cacheit
from sympy.core.sympify import converter as sympify_converter
from sympy.matrices.dense import DenseMatrix
from sympy.matrices.expressions import MatrixExpr
from sympy.matrices.matrices import MatrixBase
from sympy.matrices.sparse import MutableSparseMatrix, SparseMatrix


def sympify_matrix(arg):
    return arg.as_immutable()
sympify_converter[MatrixBase] = sympify_matrix

[docs]class ImmutableDenseMatrix(DenseMatrix, MatrixExpr): """Create an immutable version of a matrix. Examples ======== >>> from sympy import eye >>> from sympy.matrices import ImmutableMatrix >>> ImmutableMatrix(eye(3)) Matrix([ [1, 0, 0], [0, 1, 0], [0, 0, 1]]) >>> _[0, 0] = 42 Traceback (most recent call last): ... TypeError: Cannot set values of ImmutableDenseMatrix """ # MatrixExpr is set as NotIterable, but we want explicit matrices to be # iterable _iterable = True _class_priority = 8 _op_priority = 10.001 def __new__(cls, *args, **kwargs): return cls._new(*args, **kwargs) __hash__ = MatrixExpr.__hash__ @classmethod def _new(cls, *args, **kwargs): if len(args) == 1 and isinstance(args[0], ImmutableDenseMatrix): return args[0] if kwargs.get('copy', True) is False: 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 rows = Integer(rows) cols = Integer(cols) if not isinstance(flat_list, Tuple): flat_list = Tuple(*flat_list) return Basic.__new__(cls, rows, cols, flat_list) @property def _mat(self): # self.args[2] is a Tuple. Access to the elements # of a tuple are significantly faster than Tuple, # so return the internal tuple. return self.args[2].args def _entry(self, i, j): return DenseMatrix.__getitem__(self, (i, j)) def __setitem__(self, *args): raise TypeError("Cannot set values of {}".format(self.__class__)) def _eval_Eq(self, other): """Helper method for Equality with matrices. Relational automatically converts matrices to ImmutableDenseMatrix instances, so this method only applies here. Returns True if the matrices are definitively the same, False if they are definitively different, and None if undetermined (e.g. if they contain Symbols). Returning None triggers default handling of Equalities. """ if not hasattr(other, 'shape') or self.shape != other.shape: return S.false if isinstance(other, MatrixExpr) and not isinstance( other, ImmutableDenseMatrix): return None diff = self - other return sympify(diff.is_zero) def _eval_extract(self, rowsList, colsList): # self._mat is a Tuple. It is slightly faster to index a # tuple over a Tuple, so grab the internal tuple directly mat = self._mat cols = self.cols indices = (i * cols + j for i in rowsList for j in colsList) return self._new(len(rowsList), len(colsList), Tuple(*(mat[i] for i in indices), sympify=False), copy=False) @property def cols(self): return int(self.args[1]) @property def rows(self): return int(self.args[0]) @property def shape(self): return tuple(int(i) for i in self.args[:2])
[docs] def is_diagonalizable(self, reals_only=False, **kwargs): return super(ImmutableDenseMatrix, self).is_diagonalizable( reals_only=reals_only, **kwargs)
is_diagonalizable.__doc__ = DenseMatrix.is_diagonalizable.__doc__ is_diagonalizable = cacheit(is_diagonalizable)
# This is included after the class definition as a workaround for issue 7213. # See https://github.com/sympy/sympy/issues/7213 # the object is non-zero # See https://github.com/sympy/sympy/issues/7213 ImmutableDenseMatrix.is_zero = DenseMatrix.is_zero # make sure ImmutableDenseMatrix is aliased as ImmutableMatrix ImmutableMatrix = ImmutableDenseMatrix
[docs]class ImmutableSparseMatrix(SparseMatrix, Basic): """Create an immutable version of a sparse matrix. Examples ======== >>> from sympy import eye >>> from sympy.matrices.immutable import ImmutableSparseMatrix >>> ImmutableSparseMatrix(1, 1, {}) Matrix([[0]]) >>> ImmutableSparseMatrix(eye(3)) Matrix([ [1, 0, 0], [0, 1, 0], [0, 0, 1]]) >>> _[0, 0] = 42 Traceback (most recent call last): ... TypeError: Cannot set values of ImmutableSparseMatrix >>> _.shape (3, 3) """ is_Matrix = True _class_priority = 9 @classmethod def _new(cls, *args, **kwargs): s = MutableSparseMatrix(*args) rows = Integer(s.rows) cols = Integer(s.cols) mat = Dict(s._smat) obj = Basic.__new__(cls, rows, cols, mat) obj.rows = s.rows obj.cols = s.cols obj._smat = s._smat return obj def __new__(cls, *args, **kwargs): return cls._new(*args, **kwargs) def __setitem__(self, *args): raise TypeError("Cannot set values of ImmutableSparseMatrix") def __hash__(self): return hash((type(self).__name__,) + (self.shape, tuple(self._smat))) _eval_Eq = ImmutableDenseMatrix._eval_Eq
[docs] def is_diagonalizable(self, reals_only=False, **kwargs): return super(ImmutableSparseMatrix, self).is_diagonalizable( reals_only=reals_only, **kwargs)
is_diagonalizable.__doc__ = SparseMatrix.is_diagonalizable.__doc__ is_diagonalizable = cacheit(is_diagonalizable)