def test_nonsquare(): A = MatrixSymbol('A', 2, 3) B = ImmutableMatrix([[1, 2, 3], [4, 5, 6]]) for r in [-1, 0, 1, 2, S.Half, S.Pi, n]: raises(NonSquareMatrixError, lambda: MatPow(A, r)) raises(NonSquareMatrixError, lambda: MatPow(B, r))
def test_dense_conversion(): X = MatrixSymbol('X', 2,2) x00,x01,x10,x11 = symbols('X_00 X_01 X_10 X_11') assert ImmutableMatrix(X) == ImmutableMatrix([[x00, x01], [x10, x11]]) assert Matrix(X) == Matrix([[x00, x01], [x10, x11]])
from sympy.core import S, symbols, Add, Mul, SympifyError, Rational from sympy.core.expr import unchanged from sympy.functions import transpose, sin, cos, sqrt, cbrt, exp from sympy.simplify import simplify from sympy.matrices import (Identity, ImmutableMatrix, Inverse, MatAdd, MatMul, MatPow, Matrix, MatrixExpr, MatrixSymbol, ShapeError, ZeroMatrix, SparseMatrix, Transpose, Adjoint, NonSquareMatrixError) from sympy.matrices.expressions.matexpr import (MatrixElement, GenericZeroMatrix, GenericIdentity, OneMatrix) from sympy.testing.pytest import raises, XFAIL n, m, l, k, p = symbols('n m l k p', integer=True) x = symbols('x') A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', m, l) C = MatrixSymbol('C', n, n) D = MatrixSymbol('D', n, n) E = MatrixSymbol('E', m, n) w = MatrixSymbol('w', n, 1) def test_matrix_symbol_creation(): assert MatrixSymbol('A', 2, 2) assert MatrixSymbol('A', 0, 0) raises(ValueError, lambda: MatrixSymbol('A', -1, 2)) raises(ValueError, lambda: MatrixSymbol('A', 2.0, 2)) raises(ValueError, lambda: MatrixSymbol('A', 2j, 2)) raises(ValueError, lambda: MatrixSymbol('A', 2, -1)) raises(ValueError, lambda: MatrixSymbol('A', 2, 2.0))
""" We have a few different kind of Matrices Matrix, ImmutableMatrix, MatrixExpr Here we test the extent to which they cooperate """ from sympy import symbols from sympy.matrices import Matrix, MatrixSymbol, eye, Identity, ImmutableMatrix from sympy.matrices.expressions import MatrixExpr, MatAdd from sympy.matrices.common import classof from sympy.testing.pytest import raises SM = MatrixSymbol("X", 3, 3) SV = MatrixSymbol("v", 3, 1) MM = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) IM = ImmutableMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) meye = eye(3) imeye = ImmutableMatrix(eye(3)) ideye = Identity(3) a, b, c = symbols("a,b,c") def test_IM_MM(): assert isinstance(MM + IM, ImmutableMatrix) assert isinstance(IM + MM, ImmutableMatrix) assert isinstance(2 * IM + MM, ImmutableMatrix) assert MM.equals(IM) def test_ME_MM():
def test_MatrixSymbol(): n,m,t = symbols('n,m,t') X = MatrixSymbol('X', n, m) assert X.shape == (n,m) raises(TypeError, lambda: MatrixSymbol('X', n, m)(t)) # issue 2756
def test_issue_12950(): M = Matrix([[Symbol("x")]]) * MatrixSymbol("A", 1, 1) assert MatrixSymbol("A", 1, 1).as_explicit()[0] * Symbol('x') == M.as_explicit()[0]
def test_KroneckerProduct_entry(): A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', o, p) assert KroneckerProduct(A, B)._entry(i, j) == A[Mod(floor(i/o), n), Mod(floor(j/p), m)]*B[Mod(i, o), Mod(j, p)]
def test_zero_matmul(): assert isinstance(S.Zero * MatrixSymbol('X', 2, 2), MatrixExpr)
def test_matmul_simplify(): A = MatrixSymbol('A', 1, 1) assert simplify(MatMul(A, ImmutableMatrix([[sin(x)**2 + cos(x)**2]]))) == \ MatMul(A, Matrix([[1]]))
def test_BlockMatrix_Trace(): A, B, C, D = map(lambda s: MatrixSymbol(s, 3, 3), 'ABCD') X = BlockMatrix([[A, B], [C, D]]) assert Trace(X) == Trace(A) + Trace(D)
def test_dense_conversion(): X = MatrixSymbol('X', 2, 2) assert ImmutableMatrix(X) == ImmutableMatrix(2, 2, lambda i, j: X[i, j]) assert Matrix(X) == Matrix(2, 2, lambda i, j: X[i, j])
def test_MatrixSolve(): n = Symbol('n', integer=True) A = MatrixSymbol('A', n, n) x = MatrixSymbol('x', n, 1) assert mcode(MatrixSolve(A, x)) == "A \\ x"
def routine(self, name, expr, argument_sequence, global_vars): """Creates an Routine object that is appropriate for this language. This implementation is appropriate for at least C/Fortran. Subclasses can override this if necessary. Here, we assume at most one return value (the l-value) which must be scalar. Additional outputs are OutputArguments (e.g., pointers on right-hand-side or pass-by-reference). Matrices are always returned via OutputArguments. If ``argument_sequence`` is None, arguments will be ordered alphabetically, but with all InputArguments first, and then OutputArgument and InOutArguments. This implementation is almost the same as the CodeGen class, but expensive calls to Basic.atoms() have been replaced with cheaper equivalents. """ if is_sequence(expr) and not isinstance(expr, (MatrixBase, MatrixExpr)): if not expr: raise ValueError("No expression given") expressions = Tuple(*expr) else: expressions = Tuple(expr) expr_free_symbols = expressions.free_symbols # local variables local_vars = {i.label for i in expr_free_symbols if isinstance(i, Idx)} # global variables global_vars = set() if global_vars is None else set(global_vars) # symbols that should be arguments symbols = expr_free_symbols - local_vars - global_vars new_symbols = set([]) new_symbols.update(symbols) for symbol in symbols: if isinstance(symbol, Idx): new_symbols.remove(symbol) new_symbols.update(symbol.args[1].free_symbols) if isinstance(symbol, Indexed): new_symbols.remove(symbol) symbols = new_symbols # Decide whether to use output argument or return value return_val = [] output_args = [] for expr in expressions: if isinstance(expr, Equality): out_arg = expr.lhs expr = expr.rhs if isinstance(out_arg, Indexed): dims = tuple([ (S.Zero, dim - 1) for dim in out_arg.shape]) symbol = out_arg.base.label elif isinstance(out_arg, Symbol): dims = [] symbol = out_arg elif isinstance(out_arg, MatrixSymbol): dims = tuple([ (S.Zero, dim - 1) for dim in out_arg.shape]) symbol = out_arg else: raise CodeGenError("Only Indexed, Symbol, or MatrixSymbol " "can define output arguments.") if expr.has(symbol): output_args.append( InOutArgument(symbol, out_arg, expr, dimensions=dims)) else: output_args.append( OutputArgument(symbol, out_arg, expr, dimensions=dims)) # avoid duplicate arguments symbols.remove(symbol) elif isinstance(expr, (ImmutableMatrix, MatrixSlice)): # Create a "dummy" MatrixSymbol to use as the Output arg out_arg = MatrixSymbol('out_%s' % abs(hash(expr)), *expr.shape) dims = tuple([(S.Zero, dim - 1) for dim in out_arg.shape]) output_args.append( OutputArgument(out_arg, out_arg, expr, dimensions=dims)) else: return_val.append(Result(expr)) arg_list = [] # setup input argument list array_symbols = {} for array in [i for i in expr_free_symbols if isinstance(i, Indexed)]: array_symbols[array.base.label] = array for array in [i for i in expr_free_symbols if isinstance(i, MatrixSymbol)]: array_symbols[array] = array for symbol in sorted(symbols, key=str): if symbol in array_symbols: dims = [] array = array_symbols[symbol] for dim in array.shape: dims.append((S.Zero, dim - 1)) metadata = {'dimensions': dims} else: metadata = {} arg_list.append(InputArgument(symbol, **metadata)) output_args.sort(key=lambda x: str(x.name)) arg_list.extend(output_args) if argument_sequence is not None: # if the user has supplied IndexedBase instances, we'll accept that new_sequence = [] for arg in argument_sequence: if isinstance(arg, IndexedBase): new_sequence.append(arg.label) else: new_sequence.append(arg) argument_sequence = new_sequence missing = [x for x in arg_list if x.name not in argument_sequence] if missing: msg = "Argument list didn't specify: {0} " msg = msg.format(", ".join([str(m.name) for m in missing])) raise CodeGenArgumentListError(msg, missing) # create redundant arguments to produce the requested sequence name_arg_dict = {x.name: x for x in arg_list} new_args = [] for symbol in argument_sequence: try: new_args.append(name_arg_dict[symbol]) except KeyError: new_args.append(InputArgument(symbol)) arg_list = new_args return Routine(name, arg_list, return_val, local_vars, global_vars)
""" We have a few different kind of Matrices MutableMatrix, ImmutableMatrix, MatrixExpr Here we test the extent to which they cooperate """ from sympy import symbols from sympy.matrices import (Matrix, MatrixSymbol, eye, Identity, ImmutableMatrix) from sympy.matrices.matrices import MutableMatrix, classof from sympy.utilities.pytest import raises, XFAIL SM = MatrixSymbol('X', 3, 3) MM = Matrix([[1,2,3], [4,5,6], [7,8,9]]) IM = ImmutableMatrix([[1,2,3], [4,5,6], [7,8,9]]) meye = eye(3) imeye = ImmutableMatrix(eye(3)) ideye = Identity(3) a,b,c = symbols('a,b,c') def test_IM_MM(): assert (MM+IM).__class__ is MutableMatrix assert (IM+MM).__class__ is MutableMatrix assert (2*IM + MM).__class__ is MutableMatrix assert MM.equals(IM) def test_ME_MM(): assert (Identity(3) + MM).__class__ is MutableMatrix
def test_as_explicit_nonsquare_symbol(): X = MatrixSymbol('X', 2, 3) assert MatPow(X, 1).as_explicit() == X.as_explicit() for r in [0, 2, S.Half, S.Pi]: raises(ShapeError, lambda: MatPow(X, r).as_explicit())
def test_indexing(): A = MatrixSymbol('A', n, m) A[1, 2] A[l, k] A[l + 1, k + 1]
def __init__(self, name, expr, argument_sequence=None): """Initialize a Routine instance. ``name`` A string with the name of this routine in the generated code ``expr`` The sympy expression that the Routine instance will represent. If given a list or tuple of expressions, the routine will be considered to have multiple return values. ``argument_sequence`` Optional list/tuple containing arguments for the routine in a preferred order. If omitted, arguments will be ordered alphabetically, but with all input aguments first, and then output or in-out arguments. A decision about whether to use output arguments or return values, is made depending on the mathematical expressions. For an expression of type Equality, the left hand side is made into an OutputArgument (or an InOutArgument if appropriate). Else, the calculated expression is the return values of the routine. A tuple of exressions can be used to create a routine with both return value(s) and output argument(s). """ arg_list = [] if is_sequence(expr) and not isinstance(expr, MatrixBase): if not expr: raise ValueError("No expression given") expressions = Tuple(*expr) else: expressions = Tuple(expr) # local variables local_vars = set([i.label for i in expressions.atoms(Idx)]) # symbols that should be arguments symbols = expressions.free_symbols - local_vars # Decide whether to use output argument or return value return_val = [] output_args = [] for expr in expressions: if isinstance(expr, Equality): out_arg = expr.lhs expr = expr.rhs if isinstance(out_arg, Indexed): dims = tuple([(S.Zero, dim - 1) for dim in out_arg.shape]) symbol = out_arg.base.label elif isinstance(out_arg, Symbol): dims = [] symbol = out_arg elif isinstance(out_arg, MatrixSymbol): dims = tuple([(S.Zero, dim - 1) for dim in out_arg.shape]) symbol = out_arg else: raise CodeGenError("Only Indexed, Symbol, or MatrixSymbol " "can define output arguments.") if expr.has(symbol): output_args.append( InOutArgument(symbol, out_arg, expr, dimensions=dims)) else: output_args.append( OutputArgument(symbol, out_arg, expr, dimensions=dims)) # avoid duplicate arguments symbols.remove(symbol) elif isinstance(expr, ImmutableMatrix): # Create a "dummy" MatrixSymbol to use as the Output arg out_arg = MatrixSymbol('out_%s' % abs(hash(expr)), *expr.shape) dims = tuple([(S.Zero, dim - 1) for dim in out_arg.shape]) output_args.append( OutputArgument(out_arg, out_arg, expr, dimensions=dims)) else: return_val.append(Result(expr)) # setup input argument list array_symbols = {} for array in expressions.atoms(Indexed): array_symbols[array.base.label] = array for array in expressions.atoms(MatrixSymbol): array_symbols[array] = array for symbol in sorted(symbols, key=str): if symbol in array_symbols: dims = [] array = array_symbols[symbol] for dim in array.shape: dims.append((S.Zero, dim - 1)) metadata = {'dimensions': dims} else: metadata = {} arg_list.append(InputArgument(symbol, **metadata)) output_args.sort(key=lambda x: str(x.name)) arg_list.extend(output_args) if argument_sequence is not None: # if the user has supplied IndexedBase instances, we'll accept that new_sequence = [] for arg in argument_sequence: if isinstance(arg, IndexedBase): new_sequence.append(arg.label) else: new_sequence.append(arg) argument_sequence = new_sequence missing = [x for x in arg_list if x.name not in argument_sequence] if missing: raise CodeGenArgumentListError( "Argument list didn't specify: %s" % ", ".join([str(m.name) for m in missing]), missing) # create redundant arguments to produce the requested sequence name_arg_dict = dict([(x.name, x) for x in arg_list]) new_args = [] for symbol in argument_sequence: try: new_args.append(name_arg_dict[symbol]) except KeyError: new_args.append(InputArgument(symbol)) arg_list = new_args self.name = name self.arguments = arg_list self.results = return_val self.local_vars = local_vars
def test_MatrixElement_doit(): u = MatrixSymbol('u', 2, 1) v = ImmutableMatrix([3, 5]) assert u[0, 0].subs(u, v).doit() == v[0, 0]
def test_KroneckerProduct_combine_mul(): X = MatrixSymbol('X', m, n) Y = MatrixSymbol('Y', m, n) kp1 = kronecker_product(A, X) kp2 = kronecker_product(B, Y) assert combine_kronecker(kp1+kp2) == kronecker_product(A+B, X+Y)
def test_inv(): B = MatrixSymbol('B', 3, 3) assert B.inv() == B**-1
from sympy import Identity, OneMatrix, ZeroMatrix from sympy.core import symbols from sympy.utilities.pytest import raises from sympy.matrices import ShapeError, MatrixSymbol from sympy.matrices.expressions import (HadamardProduct, hadamard_product, HadamardPower, hadamard_power) n, m, k = symbols('n,m,k') Z = MatrixSymbol('Z', n, n) A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', n, m) C = MatrixSymbol('C', m, k) def test_HadamardProduct(): assert HadamardProduct(A, B, A).shape == A.shape raises(ShapeError, lambda: HadamardProduct(A, B.T)) raises(TypeError, lambda: HadamardProduct(A, n)) raises(TypeError, lambda: HadamardProduct(A, 1)) assert HadamardProduct(A, 2*B, -A)[1, 1] == \ -2 * A[1, 1] * B[1, 1] * A[1, 1] mix = HadamardProduct(Z*A, B)*C assert mix.shape == (n, k) assert set(HadamardProduct(A, B, A).T.args) == set((A.T, A.T, B.T)) def test_HadamardProduct_isnt_commutative():
def test_issue_2749(): A = MatrixSymbol("A", 5, 2) assert (A.T * A).I.as_explicit() == Matrix([[(A.T * A).I[0, 0], (A.T * A).I[0, 1]], \ [(A.T * A).I[1, 0], (A.T * A).I[1, 1]]])
def test_matrix_symbol_MM(): X = MatrixSymbol("X", 3, 3) Y = eye(3) + X assert Y[1, 1] == 1 + X[1, 1]
def test_issue_2750(): x = MatrixSymbol('x', 1, 1) assert (x.T * x).as_explicit()**-1 == Matrix([[x[0, 0]**(-2)]])
def test_matrixify(): n, m, l = symbols('n m l') A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', m, l) assert matrixify(n+m) == n+m assert matrixify(Mul(A,B)) == MatMul(A,B)
def test_invalid_args(): raises(SympifyError, lambda: MatrixSymbol(1, 2, 'A'))
def test_BlockMatrix(): n,m,l,k,p = symbols('n m l k p', integer=True) A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', n, k) C = MatrixSymbol('C', l, m) D = MatrixSymbol('D', l, k) M = MatrixSymbol('M', m+k, p) N = MatrixSymbol('N', l+n, k+m) X = BlockMatrix(Matrix([[A,B],[C,D]])) # block_collapse does nothing on normal inputs E = MatrixSymbol('E', n, m) assert block_collapse(A+2*E) == A+2*E F = MatrixSymbol('F', m, m) assert block_collapse(E.T*A*F) == E.T*A*F assert X.shape == (l+n, k+m) assert (block_collapse(Transpose(X)) == BlockMatrix(Matrix([[A.T, C.T], [B.T, D.T]]))) assert Transpose(X).shape == X.shape[::-1] assert X.blockshape == (2,2) # Test that BlockMatrices and MatrixSymbols can still mix assert (X*M).is_Mul assert X._blockmul(M).is_Mul assert (X*M).shape == (n+l, p) assert (X+N).is_Add assert X._blockadd(N).is_Add assert (X+N).shape == X.shape E = MatrixSymbol('E', m, 1) F = MatrixSymbol('F', k, 1) Y = BlockMatrix(Matrix([[E], [F]])) assert (X*Y).shape == (l+n, 1) assert block_collapse(X*Y).blocks[0,0] == A*E + B*F assert block_collapse(X*Y).blocks[1,0] == C*E + D*F assert (block_collapse(Transpose(block_collapse(Transpose(X*Y)))) == block_collapse(X*Y)) # block_collapse passes down into container objects, transposes, and inverse assert block_collapse((X*Y, 2*X)) == (block_collapse(X*Y), block_collapse(2*X)) assert block_collapse(Tuple(X*Y, 2*X)) == ( block_collapse(X*Y), block_collapse(2*X)) assert (block_collapse(Transpose(X*Y)) == block_collapse(Transpose(block_collapse(X*Y)))) Ab = BlockMatrix([[A]]) Z = MatrixSymbol('Z', *A.shape) # Make sure that MatrixSymbols will enter 1x1 BlockMatrix if it simplifies assert block_collapse(Ab+Z) == BlockMatrix([[A+Z]])
def test_as_explicit_symbol(): X = MatrixSymbol('X', 2, 2) assert MatPow(X, 0).as_explicit() == ImmutableMatrix(Identity(2)) assert MatPow(X, 1).as_explicit() == X.as_explicit() assert MatPow(X, 2).as_explicit() == (X.as_explicit())**2
def test_matrix_symbol_creation(): assert MatrixSymbol('A', 2, 2) assert MatrixSymbol('A', 0, 0) raises(ValueError, lambda: MatrixSymbol('A', -1, 2)) raises(ValueError, lambda: MatrixSymbol('A', 2.0, 2)) raises(ValueError, lambda: MatrixSymbol('A', 2j, 2)) raises(ValueError, lambda: MatrixSymbol('A', 2, -1)) raises(ValueError, lambda: MatrixSymbol('A', 2, 2.0)) raises(ValueError, lambda: MatrixSymbol('A', 2, 2j)) n = symbols('n') assert MatrixSymbol('A', n, n) n = symbols('n', integer=False) raises(ValueError, lambda: MatrixSymbol('A', n, n)) n = symbols('n', negative=True) raises(ValueError, lambda: MatrixSymbol('A', n, n))
def test_canonicalize(): X = MatrixSymbol('X', 2, 2) expr = HadamardProduct(X, check=False) assert isinstance(expr, HadamardProduct) expr2 = expr.doit() # unpack is called assert isinstance(expr2, MatrixSymbol)