Spaces:
Sleeping
Sleeping
File size: 5,530 Bytes
6a86ad5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
from mpmath.matrices.matrices import _matrix
from sympy.core import Basic, Dict, Tuple
from sympy.core.numbers import Integer
from sympy.core.cache import cacheit
from sympy.core.sympify import _sympy_converter as sympify_converter, _sympify
from sympy.matrices.dense import DenseMatrix
from sympy.matrices.expressions import MatrixExpr
from sympy.matrices.matrixbase import MatrixBase
from sympy.matrices.repmatrix import RepMatrix
from sympy.matrices.sparse import SparseRepMatrix
from sympy.multipledispatch import dispatch
def sympify_matrix(arg):
return arg.as_immutable()
sympify_converter[MatrixBase] = sympify_matrix
def sympify_mpmath_matrix(arg):
mat = [_sympify(x) for x in arg]
return ImmutableDenseMatrix(arg.rows, arg.cols, mat)
sympify_converter[_matrix] = sympify_mpmath_matrix
class ImmutableRepMatrix(RepMatrix, MatrixExpr): # type: ignore
"""Immutable matrix based on RepMatrix
Uses DomainMAtrix as the internal representation.
"""
#
# This is a subclass of RepMatrix that adds/overrides some methods to make
# the instances Basic and immutable. ImmutableRepMatrix is a superclass for
# both ImmutableDenseMatrix and ImmutableSparseMatrix.
#
def __new__(cls, *args, **kwargs):
return cls._new(*args, **kwargs)
__hash__ = MatrixExpr.__hash__
def copy(self):
return self
@property
def cols(self):
return self._cols
@property
def rows(self):
return self._rows
@property
def shape(self):
return self._rows, self._cols
def as_immutable(self):
return self
def _entry(self, i, j, **kwargs):
return self[i, j]
def __setitem__(self, *args):
raise TypeError("Cannot set values of {}".format(self.__class__))
def is_diagonalizable(self, reals_only=False, **kwargs):
return super().is_diagonalizable(
reals_only=reals_only, **kwargs)
is_diagonalizable.__doc__ = SparseRepMatrix.is_diagonalizable.__doc__
is_diagonalizable = cacheit(is_diagonalizable)
def analytic_func(self, f, x):
return self.as_mutable().analytic_func(f, x).as_immutable()
class ImmutableDenseMatrix(DenseMatrix, ImmutableRepMatrix): # type: ignore
"""Create an immutable version of a matrix.
Examples
========
>>> from sympy import eye, 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
@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
rep = cls._flat_list_to_DomainMatrix(rows, cols, flat_list)
return cls._fromrep(rep)
@classmethod
def _fromrep(cls, rep):
rows, cols = rep.shape
flat_list = rep.to_sympy().to_list_flat()
obj = Basic.__new__(cls,
Integer(rows),
Integer(cols),
Tuple(*flat_list, sympify=False))
obj._rows = rows
obj._cols = cols
obj._rep = rep
return obj
# make sure ImmutableDenseMatrix is aliased as ImmutableMatrix
ImmutableMatrix = ImmutableDenseMatrix
class ImmutableSparseMatrix(SparseRepMatrix, ImmutableRepMatrix): # type:ignore
"""Create an immutable version of a sparse matrix.
Examples
========
>>> from sympy import eye, 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):
rows, cols, smat = cls._handle_creation_inputs(*args, **kwargs)
rep = cls._smat_to_DomainMatrix(rows, cols, smat)
return cls._fromrep(rep)
@classmethod
def _fromrep(cls, rep):
rows, cols = rep.shape
smat = rep.to_sympy().to_dok()
obj = Basic.__new__(cls, Integer(rows), Integer(cols), Dict(smat))
obj._rows = rows
obj._cols = cols
obj._rep = rep
return obj
@dispatch(ImmutableDenseMatrix, ImmutableDenseMatrix)
def _eval_is_eq(lhs, rhs): # noqa:F811
"""Helper method for Equality with matrices.sympy.
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 lhs.shape != rhs.shape:
return False
return (lhs - rhs).is_zero_matrix
|