def test_BlockDiagMatrix(): A = MatrixSymbol('A', n, n) B = MatrixSymbol('B', m, m) C = MatrixSymbol('C', l, l) M = MatrixSymbol('M', n + m + l, n + m + l) X = BlockDiagMatrix(A, B, C) Y = BlockDiagMatrix(A, 2 * B, 3 * C) assert X.diag == (A, B, C) assert X.blocks[1, 1] == B assert X.shape == (n + m + l, n + m + l) assert all( X.blocks[i, j].is_ZeroMatrix if i != j else X.blocks[i, j] in [A, B, C] for i in range(3) for j in range(3)) assert X.__class__(*X.args) == X assert isinstance(block_collapse(X.inverse() * X), Identity) assert bc_matmul(X * X) == BlockDiagMatrix(A * A, B * B, C * C) assert block_collapse(X * X) == BlockDiagMatrix(A * A, B * B, C * C) # XXX: should be == ?? assert block_collapse(X + X).equals(BlockDiagMatrix(2 * A, 2 * B, 2 * C)) assert block_collapse(X * Y) == BlockDiagMatrix(A * A, 2 * B * B, 3 * C * C) assert block_collapse(X + Y) == BlockDiagMatrix(2 * A, 3 * B, 4 * C) # Ensure that BlockDiagMatrices can still interact with normal MatrixExprs assert (X * (2 * M)).is_MatMul assert (X + (2 * M)).is_MatAdd assert (X._blockmul(M)).is_MatMul assert (X._blockadd(M)).is_MatAdd
def test_BlockMatrix(): n, m = symbols('n m', integer=True) X = MatrixSymbol('X', n, n) Y = MatrixSymbol('Y', m, m) Z = MatrixSymbol('Z', n, m) B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]]) assert str(B) == "Matrix([\n[X, Z],\n[0, Y]])"
def test_Matrix_printing(): # Test returning a Matrix mat = Matrix([x * y, Piecewise((2 + x, y > 0), (y, True)), sin(z)]) A = MatrixSymbol('A', 3, 1) assert fcode(mat, A) == (' A(1, 1) = x*y\n' ' if (y > 0) then\n' ' A(2, 1) = x + 2\n' ' else\n' ' A(2, 1) = y\n' ' end if\n' ' A(3, 1) = sin(z)') # Test using MatrixElements in expressions expr = Piecewise((2 * A[2, 0], x > 0), (A[2, 0], True)) + sin(A[1, 0]) + A[0, 0] assert fcode(expr, standard=95) == ( ' merge(2*A(3, 1), A(3, 1), x > 0) + sin(A(2, 1)) + A(1, 1)') # Test using MatrixElements in a Matrix q = MatrixSymbol('q', 5, 1) M = MatrixSymbol('M', 3, 3) m = Matrix([[sin(q[1, 0]), 0, cos(q[2, 0])], [q[1, 0] + q[2, 0], q[3, 0], 5], [2 * q[4, 0] / q[1, 0], sqrt(q[0, 0]) + 4, 0]]) assert fcode(m, M) == (' M(1, 1) = sin(q(2, 1))\n' ' M(2, 1) = q(2, 1) + q(3, 1)\n' ' M(3, 1) = 2*q(5, 1)*1.0/q(2, 1)\n' ' M(1, 2) = 0\n' ' M(2, 2) = q(4, 1)\n' ' M(3, 2) = 4 + sqrt(q(1, 1))\n' ' M(1, 3) = cos(q(3, 1))\n' ' M(2, 3) = 5\n' ' M(3, 3) = 0')
def test_mixed_indexing(): X = MatrixSymbol('X', 2, 2) Y = MatrixSymbol('Y', 2, 2) Z = MatrixSymbol('Z', 2, 2) assert (X*HadamardProduct(Y, Z))[0, 0] == \ X[0, 0]*Y[0, 0]*Z[0, 0] + X[0, 1]*Y[1, 0]*Z[1, 0]
def test_cse_MatrixSymbol(): A = MatrixSymbol('A', 3, 3) y = MatrixSymbol('y', 3, 1) expr1 = (A.T * A).inverse() * A * y expr2 = (A.T * A) * A * y replacements, reduced_exprs = cse([expr1, expr2]) assert len(replacements) > 0
def test_octave_matrix_assign_to_more(): # assigning to Symbol or MatrixSymbol requires lhs/rhs match A = Matrix([[1, 2, 3]]) B = MatrixSymbol('B', 1, 3) C = MatrixSymbol('C', 2, 3) assert octave_code(A, assign_to=B) == 'B = [1 2 3];' pytest.raises(ValueError, lambda: octave_code(A, assign_to=x)) pytest.raises(ValueError, lambda: octave_code(A, assign_to=C))
def test_octave_matrix_1x1(): A = Matrix([[3]]) B = MatrixSymbol('B', 1, 1) C = MatrixSymbol('C', 1, 2) assert octave_code(A, assign_to=B) == 'B = 3;' # FIXME? # assert octave_code(A, assign_to=x) == 'x = 3;' pytest.raises(ValueError, lambda: octave_code(A, assign_to=C))
def test_single_indexing(): A = MatrixSymbol('A', 2, 3) assert A[1] == A[0, 1] assert A[3] == A[1, 0] assert list(A[:2, :2]) == [A[0, 0], A[0, 1], A[1, 0], A[1, 1]] pytest.raises(IndexError, lambda: A[6]) pytest.raises(IndexError, lambda: A[n]) B = MatrixSymbol('B', n, m) pytest.raises(IndexError, lambda: B[1])
def test_cse_MatrixSymbol(): from diofant import MatrixSymbol A = MatrixSymbol('A', 3, 3) y = MatrixSymbol('y', 3, 1) expr1 = (A.T*A).I * A * y expr2 = (A.T*A) * A * y replacements, reduced_exprs = cse([expr1, expr2]) assert len(replacements) > 0
def test_invariants(): A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', m, l) X = MatrixSymbol('X', n, n) objs = [Identity(n), ZeroMatrix(m, n), MatMul(A, B), MatAdd(A, A), Transpose(A), Adjoint(A), Inverse(X), MatPow(X, 2), MatPow(X, -1), MatPow(X, 0)] for obj in objs: assert obj == obj.__class__(*obj.args)
def test_subs(): A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', m, l) C = MatrixSymbol('C', m, l) assert A.subs({n: m}).shape == (m, m) assert (A*B).subs({B: C}) == A*C assert (A*B).subs({l: n}).is_square
def test_mul_index(): assert (A*y)[0, 0] == A[0, 0]*y[0, 0] + A[0, 1]*y[1, 0] assert (A*B).as_mutable() == (A.as_mutable() * B.as_mutable()) X = MatrixSymbol('X', n, m) Y = MatrixSymbol('Y', m, k) result = (X*Y)[4, 2] expected = Sum(X[4, i]*Y[i, 2], (i, 0, m - 1)) assert result.args[0].subs({result.limits[0][0]: i}) == expected.args[0] assert result.args[1][1:] == expected.args[1][1:]
def test_bc_dist_diag(): A = MatrixSymbol('A', n, n) B = MatrixSymbol('B', m, m) C = MatrixSymbol('C', l, l) X = BlockDiagMatrix(A, B, C) D = MatrixSymbol('D', l, l) Y = BlockDiagMatrix(A, B, D) assert bc_dist(X + X).equals(BlockDiagMatrix(2 * A, 2 * B, 2 * C)) assert bc_dist(X + Y) == X + Y
def test_block_plus_ident(): A = MatrixSymbol('A', n, n) B = MatrixSymbol('B', n, m) C = MatrixSymbol('C', m, n) D = MatrixSymbol('D', m, m) E = MatrixSymbol('E', n, n) X = BlockMatrix([[A, B], [C, D]]) assert bc_block_plus_ident(X+Identity(m+n)) == \ BlockDiagMatrix(Identity(n), Identity(m)) + X assert bc_block_plus_ident(A + Identity(n)) == A + Identity(n) assert bc_block_plus_ident(A + E) == A + E
def test_haramard(): A = MatrixSymbol('A', 3, 3) B = MatrixSymbol('B', 3, 3) v = MatrixSymbol('v', 3, 1) h = MatrixSymbol('h', 1, 3) C = HadamardProduct(A, B) assert octave_code(C) == 'A.*B' assert octave_code(C * v) == '(A.*B)*v' assert octave_code(h * C * v) == 'h*(A.*B)*v' assert octave_code(C * A) == '(A.*B)*A' # mixing Hadamard and scalar strange b/c we vectorize scalars assert octave_code(C * x * y) == '(x.*y)*(A.*B)'
def test_MatrixSymbol(): n = Symbol('n', integer=True) A = MatrixSymbol('A', n, n) B = MatrixSymbol('B', n, n) assert octave_code(A * B) == 'A*B' assert octave_code(B * A) == 'B*A' assert octave_code(2 * A * B) == '2*A*B' assert octave_code(B * 2 * A) == '2*B*A' assert octave_code(A * (B + 3 * Identity(n))) == 'A*(B + 3*eye(n))' assert octave_code(A**(x**2)) == 'A^(x.^2)' assert octave_code(A**3) == 'A^3' assert octave_code(A**Rational(1, 2)) == 'A^(1/2)'
def test_sympyissue_6249(): A = MatrixSymbol('A', 3, 3) B = MatrixSymbol('B', 3, 3) p = A * B - B * A assert cancel(p) == p assert combsimp(p) == p assert factor(p) == p assert separatevars(p) == p assert sqrtdenest(p) == p M = MatrixSymbol('M', 2, 1) assert simplify(M[0] / 2) == M[0] / 2
def test_hadamard(): m, n, p = symbols('m, n, p', integer=True) A = MatrixSymbol('A', m, n) B = MatrixSymbol('B', m, n) C = MatrixSymbol('C', m, p) with pytest.raises(TypeError): hadamard_product() assert hadamard_product(A) == A assert isinstance(hadamard_product(A, B), HadamardProduct) assert hadamard_product(A, B).doit() == hadamard_product(A, B) with pytest.raises(ShapeError): hadamard_product(A, C)
def test_m_matrixsymbol_slice3(): A = MatrixSymbol('A', 8, 7) B = MatrixSymbol('B', 2, 2) C = MatrixSymbol('C', 4, 2) name_expr = ('test', [Equality(B, A[6:, 1::3]), Equality(C, A[::2, ::3])]) result, = codegen(name_expr, 'Octave', header=False, empty=False) source = result[1] expected = ('function [B, C] = test(A)\n' ' B = A(7:end, 2:3:end);\n' ' C = A(1:2:end, 1:3:end);\n' 'end\n') assert source == expected
def test_m_matrixsymbol_slice_autoname(): A = MatrixSymbol('A', 2, 3) B = MatrixSymbol('B', 1, 3) name_expr = ('test', [Equality(B, A[0, :]), A[1, :], A[:, 0], A[:, 1]]) result, = codegen(name_expr, 'Octave', header=False, empty=False) source = result[1] expected = ('function [B, out2, out3, out4] = test(A)\n' ' B = A(1, :);\n' ' out2 = A(2, :);\n' ' out3 = A(:, 1);\n' ' out4 = A(:, 2);\n' 'end\n') assert source == expected
def test_MatPow(): A = MatrixSymbol('A', n, n) AA = MatPow(A, 2) assert AA.exp == 2 assert AA.base == A assert (A**n).exp == n assert A**0 == Identity(n) assert A**1 == A assert A**2 == AA assert A**-1 == Inverse(A) assert A**Rational(1, 2) == sqrt(A) pytest.raises(ShapeError, lambda: MatrixSymbol('B', 3, 2)**2)
def test_sympyissue_9324(): def count(val): return count_ops(val, visual=False) M = MatrixSymbol('M', 10, 10) assert count(M[0, 0]) == 0 assert count(2 * M[0, 0] + M[5, 7]) == 2 P = MatrixSymbol('P', 3, 3) Q = MatrixSymbol('Q', 3, 3) assert count(P + Q) == 9 m = Symbol('m', integer=True) n = Symbol('n', integer=True) M = MatrixSymbol('M', m + n, m * m) assert count(M[0, 1]) == 0
def test_Assignment(): x, y = symbols('x, y') A = MatrixSymbol('A', 3, 1) mat = Matrix([1, 2, 3]) B = IndexedBase('B') n = symbols('n', integer=True) i = Idx('i', n) # Here we just do things to show they don't error Assignment(x, y) Assignment(x, 0) Assignment(A, mat) Assignment(A[1, 0], 0) Assignment(A[1, 0], x) Assignment(B[i], x) Assignment(B[i], 0) # Here we test things to show that they error # Matrix to scalar pytest.raises(ValueError, lambda: Assignment(B[i], A)) pytest.raises(ValueError, lambda: Assignment(B[i], mat)) pytest.raises(ValueError, lambda: Assignment(x, mat)) pytest.raises(ValueError, lambda: Assignment(x, A)) pytest.raises(ValueError, lambda: Assignment(A[1, 0], mat)) # Scalar to matrix pytest.raises(ValueError, lambda: Assignment(A, x)) pytest.raises(ValueError, lambda: Assignment(A, 0)) # Non-atomic lhs pytest.raises(TypeError, lambda: Assignment(mat, A)) pytest.raises(TypeError, lambda: Assignment(0, x)) pytest.raises(TypeError, lambda: Assignment(x * x, 1)) pytest.raises(TypeError, lambda: Assignment(A + A, mat)) pytest.raises(TypeError, lambda: Assignment(B, 0))
def test_MatrixElement_with_values(): M = Matrix([[x, y], [z, w]]) Mij = M[i, j] assert isinstance(Mij, MatrixElement) Ms = SparseMatrix([[2, 3], [4, 5]]) msij = Ms[i, j] assert isinstance(msij, MatrixElement) for oi, oj in [(0, 0), (0, 1), (1, 0), (1, 1)]: assert Mij.subs({i: oi, j: oj}) == M[oi, oj] assert msij.subs({i: oi, j: oj}) == Ms[oi, oj] A = MatrixSymbol('A', 2, 2) assert A[0, 0].subs({A: M}) == x assert A[i, j].subs({A: M}) == M[i, j] assert M[i, j].subs([(M, A)]) == A[i, j] assert isinstance(M[3*i - 2, j], MatrixElement) assert M[3*i - 2, j].subs({i: 1, j: 0}) == M[1, 0] assert isinstance(M[i, 0], MatrixElement) assert M[i, 0].subs({i: 0}) == M[0, 0] assert M[0, i].subs({i: 1}) == M[0, 1] pytest.raises(ValueError, lambda: M[i, 2]) pytest.raises(ValueError, lambda: M[i, -1]) pytest.raises(ValueError, lambda: M[2, i]) pytest.raises(ValueError, lambda: M[-1, i]) pytest.raises(ValueError, lambda: Ms[i, 2]) pytest.raises(ValueError, lambda: Ms[i, -1]) pytest.raises(ValueError, lambda: Ms[2, i]) pytest.raises(ValueError, lambda: Ms[-1, i])
def test_adjoint(): Sq = MatrixSymbol('Sq', n, n) assert Adjoint(A).shape == (m, n) assert Adjoint(A * B).shape == (l, n) assert adjoint(Adjoint(A)) == A assert isinstance(Adjoint(Adjoint(A)), Adjoint) assert conjugate(Adjoint(A)) == Transpose(A) == Adjoint(A).conjugate() assert transpose(Adjoint(A)) == Adjoint( Transpose(A)) == Transpose(A).adjoint() assert Adjoint(eye(3)).doit() == Adjoint(eye(3)).doit(deep=False) == eye(3) assert Adjoint(Integer(5)).doit() == Integer(5) assert Adjoint(Matrix([[1, 2], [3, 4]])).doit() == Matrix([[1, 3], [2, 4]]) assert adjoint(trace(Sq)) == conjugate(trace(Sq)) assert trace(adjoint(Sq)) == conjugate(trace(Sq)) assert Adjoint(Sq)[0, 1] == conjugate(Sq[1, 0]) assert Adjoint(A * B).doit() == Adjoint(B) * Adjoint(A) assert Adjoint(C + D).doit() == Adjoint(C) + Adjoint(D)
def test_addition(): A = MatrixSymbol('A', n, m) B = MatrixSymbol('B', n, m) assert isinstance(A + B, MatAdd) assert (A + B).shape == A.shape assert isinstance(A - A + 2*B, MatMul) pytest.raises(ShapeError, lambda: A + B.T) pytest.raises(TypeError, lambda: A + 1) pytest.raises(TypeError, lambda: 5 + A) pytest.raises(TypeError, lambda: 5 - A) assert A + ZeroMatrix(n, m) - A == ZeroMatrix(n, m) with pytest.raises(TypeError): ZeroMatrix(n, m) + Integer(0) # pylint: disable=expression-not-assigned
def test_Trace_MatAdd_doit(): # See issue sympy/sympy#9028 X = ImmutableMatrix([[1, 2, 3]] * 3) Y = MatrixSymbol('Y', 3, 3) q = MatAdd(X, 2 * X, Y, -3 * Y) assert Trace(q).arg == q assert Trace(q).doit() == 18 - 2 * Trace(Y)
def test_indexing(): A = MatrixSymbol('A', n, m) A[1, 2] A[l, k] A[l + 1, k + 1] assert A[:] == MatrixSlice(A, (0, n, 1), (0, m, 1))
def test_indexing(): A = MatrixSymbol('A', n, m) assert isinstance(A[1, 2], MatrixElement) assert isinstance(A[l, k], MatrixElement) assert isinstance(A[l+1, k+1], MatrixElement) assert A[:] == MatrixSlice(A, (0, n, 1), (0, m, 1))
def test_octave_matrix_elements(): A = Matrix([[x, 2, x * y]]) assert octave_code(A[0, 0]**2 + A[0, 1] + A[0, 2]) == 'x.^2 + x.*y + 2' A = MatrixSymbol('AA', 1, 3) assert octave_code(A) == 'AA' assert octave_code(A[0, 0]**2 + sin(A[0, 1]) + A[0, 2]) == \ 'sin(AA(1, 2)) + AA(1, 1).^2 + AA(1, 3)' assert octave_code(sum(A)) == 'AA(1, 1) + AA(1, 2) + AA(1, 3)'