Beispiel #1
0
def test_doit_args():
    A = ImmutableMatrix([[1, 2], [3, 4]])
    B = ImmutableMatrix([[2, 3], [4, 5]])
    assert MatAdd(A, MatPow(B, 2)).doit() == A + B**2
    assert MatAdd(A, MatMul(A, B)).doit() == A + A*B
    assert (MatAdd(A, X, MatMul(A, B), Y, MatAdd(2*A, B)).doit() ==
            MatAdd(3*A + A*B + B, X, Y))
Beispiel #2
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy.core.expr import ExprBuilder
        from sympy.codegen.array_utils import (
            CodegenArrayContraction,
            CodegenArrayTensorProduct,
        )
        from .matmul import MatMul
        from .inverse import Inverse

        exp = self.exp
        if self.base.shape == (1, 1) and not exp.has(x):
            lr = self.base._eval_derivative_matrix_lines(x)
            for i in lr:
                subexpr = ExprBuilder(
                    CodegenArrayContraction,
                    [
                        ExprBuilder(
                            CodegenArrayTensorProduct,
                            [
                                Identity(1),
                                i._lines[0],
                                exp * self.base**(exp - 1),
                                i._lines[1],
                                Identity(1),
                            ],
                        ),
                        (0, 3, 4),
                        (5, 7, 8),
                    ],
                    validator=CodegenArrayContraction._validate,
                )
                i._first_pointer_parent = subexpr.args[0].args
                i._first_pointer_index = 0
                i._second_pointer_parent = subexpr.args[0].args
                i._second_pointer_index = 4
                i._lines = [subexpr]
            return lr
        if (exp > 0) == True:
            newexpr = MatMul.fromiter([self.base for i in range(exp)])
        elif (exp == -1) == True:
            return Inverse(self.base)._eval_derivative_matrix_lines(x)
        elif (exp < 0) == True:
            newexpr = MatMul.fromiter(
                [Inverse(self.base) for i in range(-exp)])
        elif (exp == 0) == True:
            return self.doit()._eval_derivative_matrix_lines(x)
        else:
            raise NotImplementedError("cannot evaluate %s derived by %s" %
                                      (self, x))
        return newexpr._eval_derivative_matrix_lines(x)
Beispiel #3
0
 def _eval_derivative_matrix_lines(self, x):
     from .matmul import MatMul
     exp = self.exp
     if (exp > 0) == True:
         newexpr = MatMul.fromiter([self.base for i in range(exp)])
     elif (exp == -1) == True:
         return Inverse(self.base)._eval_derivative_matrix_lines(x)
     elif (exp < 0) == True:
         newexpr = MatMul.fromiter([Inverse(self.base) for i in range(-exp)])
     elif (exp == 0) == True:
         return self.doit()._eval_derivative_matrix_lines(x)
     else:
         raise NotImplementedError("cannot evaluate %s derived by %s" % (self, x))
     return newexpr._eval_derivative_matrix_lines(x)
Beispiel #4
0
 def _entry(self, i, j, **kwargs):
     from sympy.matrices.expressions import MatMul
     A = self.doit()
     if isinstance(A, MatPow):
         # We still have a MatPow, make an explicit MatMul out of it.
         if A.exp.is_Integer and A.exp.is_positive:
             A = MatMul(*[A.base for k in range(A.exp)])
         elif not self._is_shape_symbolic():
             return A._get_explicit_matrix()[i, j]
         else:
             # Leave the expression unevaluated:
             from sympy.matrices.expressions.matexpr import MatrixElement
             return MatrixElement(self, i, j)
     return A[i, j]
 def _eval_derivative_matrix_lines(self, x):
     from .matmul import MatMul
     from .inverse import Inverse
     exp = self.exp
     if (exp > 0) == True:
         newexpr = MatMul.fromiter([self.base for i in range(exp)])
     elif (exp == -1) == True:
         return Inverse(self.base)._eval_derivative_matrix_lines(x)
     elif (exp < 0) == True:
         newexpr = MatMul.fromiter([Inverse(self.base) for i in range(-exp)])
     elif (exp == 0) == True:
         return self.doit()._eval_derivative_matrix_lines(x)
     else:
         raise NotImplementedError("cannot evaluate %s derived by %s" % (self, x))
     return newexpr._eval_derivative_matrix_lines(x)
Beispiel #6
0
def test_Trace_doit_deep_False():
    X = Matrix([[1, 2], [3, 4]])
    q = MatPow(X, 2)
    assert Trace(q).doit(deep=False).arg == q
    q = MatAdd(X, 2 * X)
    assert Trace(q).doit(deep=False).arg == q
    q = MatMul(X, 2 * X)
    assert Trace(q).doit(deep=False).arg == q
Beispiel #7
0
def _(expr, assumptions):
    factor, mmul = expr.as_coeff_mmul()
    if (all(ask(Q.positive_definite(arg), assumptions) for arg in mmul.args)
            and factor > 0):
        return True
    if (len(mmul.args) >= 2 and mmul.args[0] == mmul.args[-1].T
            and ask(Q.fullrank(mmul.args[0]), assumptions)):
        return ask(Q.positive_definite(MatMul(*mmul.args[1:-1])), assumptions)
Beispiel #8
0
 def MatMul(expr, assumptions):
     factor, mmul = expr.as_coeff_mmul()
     if all(ask(Q.symmetric(arg), assumptions) for arg in mmul.args):
         return True
     if len(mmul.args) >= 2 and mmul.args[0] == mmul.args[-1].T:
         if len(mmul.args) == 2:
             return True
         return ask(Q.symmetric(MatMul(*mmul.args[1:-1])), assumptions)
Beispiel #9
0
 def _eval_derivative_matrix_lines(self, x):
     from sympy.core.expr import ExprBuilder
     from sympy.codegen.array_utils import CodegenArrayContraction, CodegenArrayTensorProduct
     from .matmul import MatMul
     from .inverse import Inverse
     exp = self.exp
     if self.base.shape == (1, 1) and not exp.has(x):
         lr = self.base._eval_derivative_matrix_lines(x)
         for i in lr:
             subexpr = ExprBuilder(
                 CodegenArrayContraction,
                 [
                     ExprBuilder(
                         CodegenArrayTensorProduct,
                         [
                             Identity(1),
                             i._lines[0],
                             exp*self.base**(exp-1),
                             i._lines[1],
                             Identity(1),
                         ]
                     ),
                     (0, 3, 4), (5, 7, 8)
                 ],
                 validator=CodegenArrayContraction._validate
             )
             i._first_pointer_parent = subexpr.args[0].args
             i._first_pointer_index = 0
             i._second_pointer_parent = subexpr.args[0].args
             i._second_pointer_index = 4
             i._lines = [subexpr]
         return lr
     if (exp > 0) == True:
         newexpr = MatMul.fromiter([self.base for i in range(exp)])
     elif (exp == -1) == True:
         return Inverse(self.base)._eval_derivative_matrix_lines(x)
     elif (exp < 0) == True:
         newexpr = MatMul.fromiter([Inverse(self.base) for i in range(-exp)])
     elif (exp == 0) == True:
         return self.doit()._eval_derivative_matrix_lines(x)
     else:
         raise NotImplementedError("cannot evaluate %s derived by %s" % (self, x))
     return newexpr._eval_derivative_matrix_lines(x)
Beispiel #10
0
 def _entry(self, i, j, **kwargs):
     from sympy.matrices.expressions import MatMul
     A = self.doit()
     if isinstance(A, MatPow):
         # We still have a MatPow, make an explicit MatMul out of it.
         if not A.base.is_square:
             raise ShapeError("Power of non-square matrix %s" % A.base)
         elif A.exp.is_Integer and A.exp.is_positive:
             A = MatMul(*[A.base for k in range(A.exp)])
         #elif A.exp.is_Integer and self.exp.is_negative:
         # Note: possible future improvement: in principle we can take
         # positive powers of the inverse, but carefully avoid recursion,
         # perhaps by adding `_entry` to Inverse (as it is our subclass).
         # T = A.base.as_explicit().inverse()
         # A = MatMul(*[T for k in range(-A.exp)])
         else:
             # Leave the expression unevaluated:
             from sympy.matrices.expressions.matexpr import MatrixElement
             return MatrixElement(self, i, j)
     return A._entry(i, j)
Beispiel #11
0
 def _entry(self, i, j, **kwargs):
     from sympy.matrices.expressions import MatMul
     A = self.doit()
     if isinstance(A, MatPow):
         # We still have a MatPow, make an explicit MatMul out of it.
         if not A.base.is_square:
             raise ShapeError("Power of non-square matrix %s" % A.base)
         elif A.exp.is_Integer and A.exp.is_positive:
             A = MatMul(*[A.base for k in range(A.exp)])
         #elif A.exp.is_Integer and self.exp.is_negative:
         # Note: possible future improvement: in principle we can take
         # positive powers of the inverse, but carefully avoid recursion,
         # perhaps by adding `_entry` to Inverse (as it is our subclass).
         # T = A.base.as_explicit().inverse()
         # A = MatMul(*[T for k in range(-A.exp)])
         else:
             # Leave the expression unevaluated:
             from sympy.matrices.expressions.matexpr import MatrixElement
             return MatrixElement(self, i, j)
     return A._entry(i, j)
Beispiel #12
0
 def MatMul(expr, assumptions):
     factor, mmul = expr.as_coeff_mmul()
     if all(ask(Q.symmetric(arg), assumptions) for arg in mmul.args):
         return True
     # TODO: implement sathandlers system for the matrices.
     # Now it duplicates the general fact: Implies(Q.diagonal, Q.symmetric).
     if ask(Q.diagonal(expr), assumptions):
         return True
     if len(mmul.args) >= 2 and mmul.args[0] == mmul.args[-1].T:
         if len(mmul.args) == 2:
             return True
         return ask(Q.symmetric(MatMul(*mmul.args[1:-1])), assumptions)
Beispiel #13
0
def test_doit_nested_MatrixExpr():
    X = ImmutableMatrix([[1, 2], [3, 4]])
    Y = ImmutableMatrix([[2, 3], [4, 5]])
    assert MatPow(MatMul(X, Y), 2).doit() == (X*Y)**2
    assert MatPow(MatAdd(X, Y), 2).doit() == (X + Y)**2
Beispiel #14
0
def test_trace_constant_factor():
    # Issue 9052: gave 2*Trace(MatMul(A)) instead of 2*Trace(A)
    assert trace(2 * A) == 2 * Trace(A)
    X = ImmutableMatrix([[1, 2], [3, 4]])
    assert trace(MatMul(2, X)) == 10
Beispiel #15
0
def test_bc_matpow():
    A = MatrixSymbol('A', n, n)
    assert bc_matpow(A**2) == MatMul(A, A, evaluate=False)
    assert bc_matpow(A**n) == A**n
Beispiel #16
0
def test_trace_constant_factor():
    # Issue 9052: LHS gives Trace(MatMul(A))
    assert trace(2 * A) == 2 * Trace(A)
    X = ImmutableMatrix([[1, 2], [3, 4]])
    assert trace(MatMul(2, X)) == 10