示例#1
0
def test_inverse_non_invertible():
    raises(NonSquareMatrixError, lambda: Inverse(A))
    raises(NonSquareMatrixError, lambda: Inverse(A*B))
    raises(NonSquareMatrixError, lambda: ZeroMatrix(n, m).I)
    raises(NonInvertibleMatrixError, lambda: ZeroMatrix(n, n).I)
    raises(NonSquareMatrixError, lambda: OneMatrix(n, m).I)
    raises(NonInvertibleMatrixError, lambda: OneMatrix(2, 2).I)
示例#2
0
def test_block_collapse_type():
    bm1 = BlockDiagMatrix(ImmutableMatrix([1]), ImmutableMatrix([2]))
    bm2 = BlockDiagMatrix(ImmutableMatrix([3]), ImmutableMatrix([4]))

    assert bm1.T.__class__ == BlockDiagMatrix
    assert block_collapse(bm1 - bm2).__class__ == BlockDiagMatrix
    assert block_collapse(Inverse(bm1)).__class__ == BlockDiagMatrix
    assert block_collapse(Transpose(bm1)).__class__ == BlockDiagMatrix
    assert bc_transpose(Transpose(bm1)).__class__ == BlockDiagMatrix
    assert bc_inverse(Inverse(bm1)).__class__ == BlockDiagMatrix
示例#3
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)
 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)
示例#5
0
    def doit(self, **kwargs):
        if kwargs.get('deep', True):
            base, exp = [arg.doit(**kwargs) for arg in self.args]
        else:
            base, exp = self.args

        # combine all powers, e.g. (A ** 2) ** 3 -> A ** 6
        while isinstance(base, MatPow):
            exp *= base.args[1]
            base = base.args[0]

        if isinstance(base, MatrixBase):
            # Delegate
            return base**exp

        # Handle simple cases so that _eval_power() in MatrixExpr sub-classes can ignore them
        if exp == S.One:
            return base
        if exp == S.Zero:
            return Identity(base.rows)
        if exp == S.NegativeOne:
            from sympy.matrices.expressions import Inverse
            return Inverse(base).doit(**kwargs)

        eval_power = getattr(base, '_eval_power', None)
        if eval_power is not None:
            return eval_power(exp)

        return MatPow(base, exp)
示例#6
0
    def doit(self, **kwargs):
        from sympy.matrices.expressions import Inverse
        deep = kwargs.get('deep', True)
        if deep:
            args = [arg.doit(**kwargs) for arg in self.args]
        else:
            args = self.args

        base, exp = args
        # combine all powers, e.g. (A**2)**3 = A**6
        while isinstance(base, MatPow):
            exp = exp * base.args[1]
            base = base.args[0]

        if exp.is_zero and base.is_square:
            if isinstance(base, MatrixBase):
                return base.func(Identity(base.shape[0]))
            return Identity(base.shape[0])
        elif isinstance(base, ZeroMatrix) and exp.is_negative:
            raise ValueError("Matrix determinant is 0, not invertible.")
        elif isinstance(base, (Identity, ZeroMatrix)):
            return base
        elif isinstance(base, MatrixBase):
            if exp is S.One:
                return base
            return base**exp
        # Note: just evaluate cases we know, return unevaluated on others.
        # E.g., MatrixSymbol('x', n, m) to power 0 is not an error.
        elif exp is S.NegativeOne and base.is_square:
            return Inverse(base).doit(**kwargs)
        elif exp is S.One:
            return base
        return MatPow(base, exp)
示例#7
0
def test_squareBlockMatrix():
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', n, m)
    C = MatrixSymbol('C', m, n)
    D = MatrixSymbol('D', m, m)
    X = BlockMatrix([[A, B], [C, D]])
    Y = BlockMatrix([[A]])

    assert X.is_square

    assert (block_collapse(X + Identity(m + n)) ==
        BlockMatrix([[A + Identity(n), B], [C, D + Identity(m)]]))
    Q = X + Identity(m + n)

    assert block_collapse(Q.inverse()) == Inverse(block_collapse(Q))

    assert (X + MatrixSymbol('Q', n + m, n + m)).is_MatAdd
    assert (X * MatrixSymbol('Q', n + m, n + m)).is_MatMul

    assert Y.I.blocks[0, 0] == A.I
    assert X.inverse(expand=True) == BlockMatrix([
        [(-B*D.I*C + A).I, -A.I*B*(D + -C*A.I*B).I],
        [-(D - C*A.I*B).I*C*A.I, (D - C*A.I*B).I]])

    assert isinstance(X.inverse(expand=False), Inverse)
    assert isinstance(X.inverse(), Inverse)

    assert not X.is_Identity

    Z = BlockMatrix([[Identity(n), B], [C, D]])
    assert not Z.is_Identity
示例#8
0
def test_tensorflow_matrices():
    if not tf:
        skip("TensorFlow not installed")

    expr = M
    assert tensorflow_code(expr) == "M"
    _compare_tensorflow_matrix((M, ), expr)

    expr = M + N
    assert tensorflow_code(expr) == "tensorflow.math.add(M, N)"
    _compare_tensorflow_matrix((M, N), expr)

    expr = M * N
    assert tensorflow_code(expr) == "tensorflow.linalg.matmul(M, N)"
    _compare_tensorflow_matrix((M, N), expr)

    expr = HadamardProduct(M, N)
    assert tensorflow_code(expr) == "tensorflow.math.multiply(M, N)"
    _compare_tensorflow_matrix((M, N), expr)

    expr = M * N * P * Q
    assert tensorflow_code(expr) == \
        "tensorflow.linalg.matmul(" \
            "tensorflow.linalg.matmul(" \
                "tensorflow.linalg.matmul(M, N), P), Q)"
    _compare_tensorflow_matrix((M, N, P, Q), expr)

    expr = M**3
    assert tensorflow_code(expr) == \
        "tensorflow.linalg.matmul(tensorflow.linalg.matmul(M, M), M)"
    _compare_tensorflow_matrix((M, ), expr)

    expr = Trace(M)
    assert tensorflow_code(expr) == "tensorflow.linalg.trace(M)"
    _compare_tensorflow_matrix((M, ), expr)

    expr = Determinant(M)
    assert tensorflow_code(expr) == "tensorflow.linalg.det(M)"
    _compare_tensorflow_matrix_scalar((M, ), expr)

    expr = Inverse(M)
    assert tensorflow_code(expr) == "tensorflow.linalg.inv(M)"
    _compare_tensorflow_matrix_inverse((M, ), expr, use_float=True)

    expr = M.T
    assert tensorflow_code(expr, tensorflow_version='1.14') == \
        "tensorflow.linalg.matrix_transpose(M)"
    assert tensorflow_code(expr, tensorflow_version='1.13') == \
        "tensorflow.matrix_transpose(M)"

    _compare_tensorflow_matrix((M, ), expr)
示例#9
0
def test_inverse():
    raises(ShapeError, lambda: Inverse(A))
    raises(ShapeError, lambda: Inverse(A * B))

    assert Inverse(C).shape == (n, n)
    assert Inverse(A * E).shape == (n, n)
    assert Inverse(E * A).shape == (m, m)
    assert Inverse(C).inverse() == C
    assert isinstance(Inverse(Inverse(C)), Inverse)

    assert C.inverse().inverse() == C

    assert C.inverse() * C == Identity(C.rows)

    assert Identity(n).inverse() == Identity(n)
    assert (3 * Identity(n)).inverse() == Identity(n) / 3

    # Simplifies Muls if possible (i.e. submatrices are square)
    assert (C * D).inverse() == D.I * C.I
    # But still works when not possible
    assert isinstance((A * E).inverse(), Inverse)

    assert Inverse(eye(3)).doit() == eye(3)
    assert Inverse(eye(3)).doit(deep=False) == eye(3)
示例#10
0
def test_PermutationMatrix_inverse():
    P = PermutationMatrix(Permutation(0, 1, 2))
    assert Inverse(P).doit() == PermutationMatrix(Permutation(0, 2, 1))
示例#11
0
def test_inverse_matpow_canonicalization():
    A = MatrixSymbol('A', 3, 3)
    assert Inverse(MatPow(A, 3)).doit() == MatPow(Inverse(A), 3).doit()
示例#12
0
def test_inverse():
    assert Inverse(C).args == (C, S.NegativeOne)
    assert Inverse(C).shape == (n, n)
    assert Inverse(A*E).shape == (n, n)
    assert Inverse(E*A).shape == (m, m)
    assert Inverse(C).inverse() == C
    assert isinstance(Inverse(Inverse(C)), Inverse)

    assert Inverse(*Inverse(E*A).args) == Inverse(E*A)

    assert C.inverse().inverse() == C

    assert C.inverse()*C == Identity(C.rows)

    assert Identity(n).inverse() == Identity(n)
    assert (3*Identity(n)).inverse() == Identity(n)/3

    # Simplifies Muls if possible (i.e. submatrices are square)
    assert (C*D).inverse() == D.I*C.I
    # But still works when not possible
    assert isinstance((A*E).inverse(), Inverse)
    assert Inverse(C*D).doit(inv_expand=False) == Inverse(C*D)

    assert Inverse(eye(3)).doit() == eye(3)
    assert Inverse(eye(3)).doit(deep=False) == eye(3)

    assert OneMatrix(1, 1).I == Identity(1)
    assert isinstance(OneMatrix(n, n).I, Inverse)