def test_as_explicit(): c0, c1, c2 = symbols('c0:3') x = Symbol('x') assert CompanionMatrix(Poly([1, c0], x)).as_explicit() == \ ImmutableDenseMatrix([-c0]) assert CompanionMatrix(Poly([1, c1, c0], x)).as_explicit() == \ ImmutableDenseMatrix([[0, -c0], [1, -c1]]) assert CompanionMatrix(Poly([1, c2, c1, c0], x)).as_explicit() == \ ImmutableDenseMatrix([[0, 0, -c0], [1, 0, -c1], [0, 1, -c2]])
def __new__(cls, *args): from sympy.matrices.immutable import ImmutableDenseMatrix args = map(sympify, args) mat = ImmutableDenseMatrix(*args) obj = Basic.__new__(cls, mat) return obj
def as_explicit(self): """ Returns a dense Matrix with elements represented explicitly Returns an object of type ImmutableDenseMatrix. Examples ======== >>> from sympy import Identity >>> I = Identity(3) >>> I I >>> I.as_explicit() Matrix([ [1, 0, 0], [0, 1, 0], [0, 0, 1]]) See Also ======== as_mutable: returns mutable Matrix type """ if (not isinstance(self.rows, (SYMPY_INTS, Integer)) or not isinstance(self.cols, (SYMPY_INTS, Integer))): raise ValueError('Matrix with symbolic shape ' 'cannot be represented explicitly.') from sympy.matrices.immutable import ImmutableDenseMatrix return ImmutableDenseMatrix([[self[i, j] for j in range(self.cols)] for i in range(self.rows)])
def test_Identity(): n, m = symbols('n m', integer=True) A = MatrixSymbol('A', n, m) i, j = symbols('i j') In = Identity(n) Im = Identity(m) assert A * Im == A assert In * A == A assert In.transpose() == In assert In.inverse() == In assert In.conjugate() == In assert In[i, j] != 0 assert Sum(In[i, j], (i, 0, n - 1), (j, 0, n - 1)).subs(n, 3).doit() == 3 assert Sum(Sum(In[i, j], (i, 0, n - 1)), (j, 0, n - 1)).subs(n, 3).doit() == 3 # If range exceeds the limit `(0, n-1)`, do not remove `Piecewise`: expr = Sum(In[i, j], (i, 0, n - 1)) assert expr.doit() == 1 expr = Sum(In[i, j], (i, 0, n - 2)) assert expr.doit().dummy_eq( Piecewise((1, (j >= 0) & (j <= n - 2)), (0, True))) expr = Sum(In[i, j], (i, 1, n - 1)) assert expr.doit().dummy_eq( Piecewise((1, (j >= 1) & (j <= n - 1)), (0, True))) assert Identity(3).as_explicit() == ImmutableDenseMatrix.eye(3)
def test_OneMatrix(): n, m = symbols('n m', integer=True) A = MatrixSymbol('A', n, m) a = MatrixSymbol('a', n, 1) U = OneMatrix(n, m) assert U.shape == (n, m) assert isinstance(A + U, Add) assert U.transpose() == OneMatrix(m, n) assert U.conjugate() == U assert OneMatrix(n, n)**0 == Identity(n) with raises(NonSquareMatrixError): U**0 with raises(NonSquareMatrixError): U**1 with raises(NonSquareMatrixError): U**2 with raises(ShapeError): a + U U = OneMatrix(n, n) assert U[1, 2] == 1 U = OneMatrix(2, 3) assert U.as_explicit() == ImmutableDenseMatrix.ones(2, 3)
def blocks(self): from sympy.matrices.immutable import ImmutableDenseMatrix mats = self.args data = [[mats[i] if i == j else ZeroMatrix(mats[i].rows, mats[j].cols) for j in range(len(mats))] for i in range(len(mats))] return ImmutableDenseMatrix(data, evaluate=False)
def as_explicit(self): """ Returns a dense Matrix with elements represented explicitly Returns an object of type ImmutableDenseMatrix. Examples ======== >>> from sympy import Identity >>> I = Identity(3) >>> I I >>> I.as_explicit() Matrix([ [1, 0, 0], [0, 1, 0], [0, 0, 1]]) See Also ======== as_mutable: returns mutable Matrix type """ from sympy.matrices.immutable import ImmutableDenseMatrix return ImmutableDenseMatrix([[ self[i, j] for j in range(self.cols)] for i in range(self.rows)])
def __new__(cls, *args, **kwargs): from sympy.matrices.immutable import ImmutableDenseMatrix from sympy.matrices import zeros from sympy.matrices.matrices import MatrixBase from sympy.utilities.iterables import is_sequence isMat = lambda i: getattr(i, 'is_Matrix', False) if len(args) != 1 or \ not is_sequence(args[0]) or \ len(set([isMat(r) for r in args[0]])) != 1: raise ValueError( filldedent(''' expecting a sequence of 1 or more rows containing Matrices.''')) rows = args[0] if args else [] if not isMat(rows): if rows and isMat(rows[0]): rows = [rows] # rows is not list of lists or [] # regularity check # same number of matrices in each row blocky = ok = len(set([len(r) for r in rows])) == 1 if ok: # same number of rows for each matrix in a row for r in rows: ok = len(set([i.rows for i in r])) == 1 if not ok: break blocky = ok # same number of cols for each matrix in each col for c in range(len(rows[0])): ok = len(set([rows[i][c].cols for i in range(len(rows))])) == 1 if not ok: break if not ok: # same total cols in each row ok = len(set([sum([i.cols for i in r]) for r in rows])) == 1 if blocky and ok: raise ValueError( filldedent(''' Although this matrix is comprised of blocks, the blocks do not fill the matrix in a size-symmetric fashion. To create a full matrix from these arguments, pass them directly to Matrix.''')) raise ValueError( filldedent(''' When there are not the same number of rows in each row's matrices or there are not the same number of total columns in each row, the matrix is not a block matrix. If this matrix is known to consist of blocks fully filling a 2-D space then see Matrix.irregular.''')) mat = ImmutableDenseMatrix(rows, evaluate=False) obj = Basic.__new__(cls, mat) return obj
def _check_orthogonality(equations): """ Helper method for _connect_to_cartesian. It checks if set of transformation equations create orthogonal curvilinear coordinate system Parameters ========== equations : Lambda Lambda of transformation equations """ x1, x2, x3 = symbols("x1, x2, x3", cls=Dummy) equations = equations(x1, x2, x3) v1 = Matrix([diff(equations[0], x1), diff(equations[1], x1), diff(equations[2], x1)]) v2 = Matrix([diff(equations[0], x2), diff(equations[1], x2), diff(equations[2], x2)]) v3 = Matrix([diff(equations[0], x3), diff(equations[1], x3), diff(equations[2], x3)]) if any(simplify(i[0] + i[1] + i[2]) == 0 for i in (v1, v2, v3)): return False else: if simplify(v1.dot(v2)) == 0 and simplify(v2.dot(v3)) == 0 \ and simplify(v3.dot(v1)) == 0: return True else: return False
def test_ZeroMatrix(): n, m = symbols('n m', integer=True) A = MatrixSymbol('A', n, m) Z = ZeroMatrix(n, m) assert A + Z == A assert A * Z.T == ZeroMatrix(n, n) assert Z * A.T == ZeroMatrix(n, n) assert A - A == ZeroMatrix(*A.shape) assert Z assert Z.transpose() == ZeroMatrix(m, n) assert Z.conjugate() == Z assert ZeroMatrix(n, n)**0 == Identity(n) with raises(NonSquareMatrixError): Z**0 with raises(NonSquareMatrixError): Z**1 with raises(NonSquareMatrixError): Z**2 assert ZeroMatrix(3, 3).as_explicit() == ImmutableDenseMatrix.zeros(3, 3)
def _make_matrix(x): from sympy import ImmutableDenseMatrix if isinstance(x, MatrixExpr): return x return ImmutableDenseMatrix([[x]])
def as_explicit(self): from sympy import ImmutableDenseMatrix return ImmutableDenseMatrix.ones(*self.shape)
def test_slicing(): assert IM[1, :] == ImmutableDenseMatrix([[4, 5, 6]]) assert IM[:2, :2] == ImmutableDenseMatrix([[1, 2], [4, 5]]) assert ISM[1, :] == ImmutableSparseMatrix([[4, 5, 6]]) assert ISM[:2, :2] == ImmutableSparseMatrix([[1, 2], [4, 5]])
def as_explicit(self): from sympy import ImmutableDenseMatrix return ImmutableDenseMatrix.ones(*self.shape)
def __new__(cls, name, transformation=None, parent=None, location=None, rotation_matrix=None, vector_names=None, variable_names=None): """ The orientation/location parameters are necessary if this system is being defined at a certain orientation or location wrt another. Parameters ========== name : str The name of the new CoordSys3D instance. transformation : Lambda, Tuple, str Transformation defined by transformation equations or chosen from predefined ones. location : Vector The position vector of the new system's origin wrt the parent instance. rotation_matrix : SymPy ImmutableMatrix The rotation matrix of the new coordinate system with respect to the parent. In other words, the output of new_system.rotation_matrix(parent). parent : CoordSys3D The coordinate system wrt which the orientation/location (or both) is being defined. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. """ name = str(name) Vector = sympy.vector.Vector Point = sympy.vector.Point if not isinstance(name, str): raise TypeError("name should be a string") if transformation is not None: if (location is not None) or (rotation_matrix is not None): raise ValueError("specify either `transformation` or " "`location`/`rotation_matrix`") if isinstance(transformation, (Tuple, tuple, list)): if isinstance(transformation[0], MatrixBase): rotation_matrix = transformation[0] location = transformation[1] else: transformation = Lambda(transformation[0], transformation[1]) elif isinstance(transformation, Callable): x1, x2, x3 = symbols('x1 x2 x3', cls=Dummy) transformation = Lambda((x1, x2, x3), transformation(x1, x2, x3)) elif isinstance(transformation, str): transformation = Str(transformation) elif isinstance(transformation, (Str, Lambda)): pass else: raise TypeError("transformation: " "wrong type {}".format(type(transformation))) # If orientation information has been provided, store # the rotation matrix accordingly if rotation_matrix is None: rotation_matrix = ImmutableDenseMatrix(eye(3)) else: if not isinstance(rotation_matrix, MatrixBase): raise TypeError("rotation_matrix should be an Immutable" + "Matrix instance") rotation_matrix = rotation_matrix.as_immutable() # If location information is not given, adjust the default # location as Vector.zero if parent is not None: if not isinstance(parent, CoordSys3D): raise TypeError("parent should be a " + "CoordSys3D/None") if location is None: location = Vector.zero else: if not isinstance(location, Vector): raise TypeError("location should be a Vector") # Check that location does not contain base # scalars for x in location.free_symbols: if isinstance(x, BaseScalar): raise ValueError("location should not contain" + " BaseScalars") origin = parent.origin.locate_new(name + '.origin', location) else: location = Vector.zero origin = Point(name + '.origin') if transformation is None: transformation = Tuple(rotation_matrix, location) if isinstance(transformation, Tuple): lambda_transformation = CoordSys3D._compose_rotation_and_translation( transformation[0], transformation[1], parent ) r, l = transformation l = l._projections lambda_lame = CoordSys3D._get_lame_coeff('cartesian') lambda_inverse = lambda x, y, z: r.inv()*Matrix( [x-l[0], y-l[1], z-l[2]]) elif isinstance(transformation, Str): trname = transformation.name lambda_transformation = CoordSys3D._get_transformation_lambdas(trname) if parent is not None: if parent.lame_coefficients() != (S.One, S.One, S.One): raise ValueError('Parent for pre-defined coordinate ' 'system should be Cartesian.') lambda_lame = CoordSys3D._get_lame_coeff(trname) lambda_inverse = CoordSys3D._set_inv_trans_equations(trname) elif isinstance(transformation, Lambda): if not CoordSys3D._check_orthogonality(transformation): raise ValueError("The transformation equation does not " "create orthogonal coordinate system") lambda_transformation = transformation lambda_lame = CoordSys3D._calculate_lame_coeff(lambda_transformation) lambda_inverse = None else: lambda_transformation = lambda x, y, z: transformation(x, y, z) lambda_lame = CoordSys3D._get_lame_coeff(transformation) lambda_inverse = None if variable_names is None: if isinstance(transformation, Lambda): variable_names = ["x1", "x2", "x3"] elif isinstance(transformation, Str): if transformation.name == 'spherical': variable_names = ["r", "theta", "phi"] elif transformation.name == 'cylindrical': variable_names = ["r", "theta", "z"] else: variable_names = ["x", "y", "z"] else: variable_names = ["x", "y", "z"] if vector_names is None: vector_names = ["i", "j", "k"] # All systems that are defined as 'roots' are unequal, unless # they have the same name. # Systems defined at same orientation/position wrt the same # 'parent' are equal, irrespective of the name. # This is true even if the same orientation is provided via # different methods like Axis/Body/Space/Quaternion. # However, coincident systems may be seen as unequal if # positioned/oriented wrt different parents, even though # they may actually be 'coincident' wrt the root system. if parent is not None: obj = super().__new__( cls, Str(name), transformation, parent) else: obj = super().__new__( cls, Str(name), transformation) obj._name = name # Initialize the base vectors _check_strings('vector_names', vector_names) vector_names = list(vector_names) latex_vects = [(r'\mathbf{\hat{%s}_{%s}}' % (x, name)) for x in vector_names] pretty_vects = ['%s_%s' % (x, name) for x in vector_names] obj._vector_names = vector_names v1 = BaseVector(0, obj, pretty_vects[0], latex_vects[0]) v2 = BaseVector(1, obj, pretty_vects[1], latex_vects[1]) v3 = BaseVector(2, obj, pretty_vects[2], latex_vects[2]) obj._base_vectors = (v1, v2, v3) # Initialize the base scalars _check_strings('variable_names', vector_names) variable_names = list(variable_names) latex_scalars = [(r"\mathbf{{%s}_{%s}}" % (x, name)) for x in variable_names] pretty_scalars = ['%s_%s' % (x, name) for x in variable_names] obj._variable_names = variable_names obj._vector_names = vector_names x1 = BaseScalar(0, obj, pretty_scalars[0], latex_scalars[0]) x2 = BaseScalar(1, obj, pretty_scalars[1], latex_scalars[1]) x3 = BaseScalar(2, obj, pretty_scalars[2], latex_scalars[2]) obj._base_scalars = (x1, x2, x3) obj._transformation = transformation obj._transformation_lambda = lambda_transformation obj._lame_coefficients = lambda_lame(x1, x2, x3) obj._transformation_from_parent_lambda = lambda_inverse setattr(obj, variable_names[0], x1) setattr(obj, variable_names[1], x2) setattr(obj, variable_names[2], x3) setattr(obj, vector_names[0], v1) setattr(obj, vector_names[1], v2) setattr(obj, vector_names[2], v3) # Assign params obj._parent = parent if obj._parent is not None: obj._root = obj._parent._root else: obj._root = obj obj._parent_rotation_matrix = rotation_matrix obj._origin = origin # Return the instance return obj
from itertools import product from sympy.core.relational import (Equality, Unequality) from sympy.core.singleton import S from sympy.core.sympify import sympify from sympy.integrals.integrals import integrate from sympy.matrices.dense import (Matrix, eye, zeros) from sympy.matrices.immutable import ImmutableMatrix from sympy.matrices import SparseMatrix from sympy.matrices.immutable import \ ImmutableDenseMatrix, ImmutableSparseMatrix from sympy.abc import x, y from sympy.testing.pytest import raises IM = ImmutableDenseMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) ISM = ImmutableSparseMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) ieye = ImmutableDenseMatrix(eye(3)) def test_creation(): assert IM.shape == ISM.shape == (3, 3) assert IM[1, 2] == ISM[1, 2] == 6 assert IM[2, 2] == ISM[2, 2] == 9 def test_immutability(): with raises(TypeError): IM[2, 2] = 5 with raises(TypeError): ISM[2, 2] = 5
def as_explicit(self): from sympy.matrices.immutable import ImmutableDenseMatrix return ImmutableDenseMatrix.companion(self.args[0])