Example #1
0
def _choose_2x2_inversion_formula(A, B, C, D):
    """
    Assuming [[A, B], [C, D]] would form a valid square block matrix, find
    which of the classical 2x2 block matrix inversion formulas would be
    best suited.

    Returns 'A', 'B', 'C', 'D' to represent the algorithm involving inversion
    of the given argument or None if the matrix cannot be inverted using
    any of those formulas.
    """
    # Try to find a known invertible matrix.  Note that the Schur complement
    # is currently not being considered for this
    A_inv = ask(Q.invertible(A))
    if A_inv == True:
        return 'A'
    B_inv = ask(Q.invertible(B))
    if B_inv == True:
        return 'B'
    C_inv = ask(Q.invertible(C))
    if C_inv == True:
        return 'C'
    D_inv = ask(Q.invertible(D))
    if D_inv == True:
        return 'D'
    # Otherwise try to find a matrix that isn't known to be non-invertible
    if A_inv != False:
        return 'A'
    if B_inv != False:
        return 'B'
    if C_inv != False:
        return 'C'
    if D_inv != False:
        return 'D'
    return None
Example #2
0
def refine_MatMul(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine
    >>> X = MatrixSymbol('X', 2, 2)
    >>> expr = X * X.T
    >>> print(expr)
    X*X.T
    >>> with assuming(Q.orthogonal(X)):
    ...     print(refine(expr))
    I
    """
    newargs = []
    exprargs = []

    for args in expr.args:
        if args.is_Matrix:
            exprargs.append(args)
        else:
            newargs.append(args)

    last = exprargs[0]
    for arg in exprargs[1:]:
        if arg == last.T and ask(Q.orthogonal(arg), assumptions):
            last = Identity(arg.shape[0])
        elif arg == last.conjugate() and ask(Q.unitary(arg), assumptions):
            last = Identity(arg.shape[0])
        else:
            newargs.append(last)
            last = arg
    newargs.append(last)

    return MatMul(*newargs)
Example #3
0
def test_non_trivial_implies():
    X = MatrixSymbol('X', 3, 3)
    Y = MatrixSymbol('Y', 3, 3)
    assert ask(Q.lower_triangular(X + Y),
               Q.lower_triangular(X) & Q.lower_triangular(Y)) is True
    assert ask(Q.triangular(X), Q.lower_triangular(X)) is True
    assert ask(Q.triangular(X + Y),
               Q.lower_triangular(X) & Q.lower_triangular(Y)) is True
Example #4
0
 def _eval_determinant(self):
     if self.blockshape == (1, 1):
         return det(self.blocks[0, 0])
     if self.blockshape == (2, 2):
         [[A, B], [C, D]] = self.blocks.tolist()
         if ask(Q.invertible(A)):
             return det(A) * det(D - C * A.I * B)
         elif ask(Q.invertible(D)):
             return det(D) * det(A - B * D.I * C)
     return Determinant(self)
Example #5
0
def test_MatrixSlice():
    X = MatrixSymbol('X', 4, 4)
    B = MatrixSlice(X, (1, 3), (1, 3))
    C = MatrixSlice(X, (0, 3), (1, 3))
    assert ask(Q.symmetric(B), Q.symmetric(X))
    assert ask(Q.invertible(B), Q.invertible(X))
    assert ask(Q.diagonal(B), Q.diagonal(X))
    assert ask(Q.orthogonal(B), Q.orthogonal(X))
    assert ask(Q.upper_triangular(B), Q.upper_triangular(X))

    assert not ask(Q.symmetric(C), Q.symmetric(X))
    assert not ask(Q.invertible(C), Q.invertible(X))
    assert not ask(Q.diagonal(C), Q.diagonal(X))
    assert not ask(Q.orthogonal(C), Q.orthogonal(X))
    assert not ask(Q.upper_triangular(C), Q.upper_triangular(X))
Example #6
0
def test_dft():
    n, i, j = symbols('n i j')
    assert DFT(4).shape == (4, 4)
    assert ask(Q.unitary(DFT(4)))
    assert Abs(simplify(det(Matrix(DFT(4))))) == 1
    assert DFT(n) * IDFT(n) == Identity(n)
    assert DFT(n)[i, j] == exp(-2 * S.Pi * I / n)**(i * j) / sqrt(n)
Example #7
0
def refine_Determinant(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine, det
    >>> X = MatrixSymbol('X', 2, 2)
    >>> det(X)
    Determinant(X)
    >>> with assuming(Q.orthogonal(X)):
    ...     print(refine(det(X)))
    1
    """
    if ask(Q.orthogonal(expr.arg), assumptions):
        return S.One
    elif ask(Q.singular(expr.arg), assumptions):
        return S.Zero
    elif ask(Q.unit_triangular(expr.arg), assumptions):
        return S.One

    return expr
Example #8
0
def refine_Determinant(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine, det
    >>> X = MatrixSymbol('X', 2, 2)
    >>> det(X)
    Determinant(X)
    >>> with assuming(Q.orthogonal(X)):
    ...     print(refine(det(X)))
    1
    """
    if ask(Q.orthogonal(expr.arg), assumptions):
        return S.One
    elif ask(Q.singular(expr.arg), assumptions):
        return S.Zero
    elif ask(Q.unit_triangular(expr.arg), assumptions):
        return S.One

    return expr
Example #9
0
def refine_Inverse(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine
    >>> X = MatrixSymbol('X', 2, 2)
    >>> X.I
    X**(-1)
    >>> with assuming(Q.orthogonal(X)):
    ...     print(refine(X.I))
    X.T
    """
    if ask(Q.orthogonal(expr), assumptions):
        return expr.arg.T
    elif ask(Q.unitary(expr), assumptions):
        return expr.arg.conjugate()
    elif ask(Q.singular(expr), assumptions):
        raise ValueError("Inverse of singular matrix %s" % expr.arg)

    return expr
Example #10
0
def refine_Inverse(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine
    >>> X = MatrixSymbol('X', 2, 2)
    >>> X.I
    X^-1
    >>> with assuming(Q.orthogonal(X)):
    ...     print(refine(X.I))
    X.T
    """
    if ask(Q.orthogonal(expr), assumptions):
        return expr.arg.T
    elif ask(Q.unitary(expr), assumptions):
        return expr.arg.conjugate()
    elif ask(Q.singular(expr), assumptions):
        raise ValueError("Inverse of singular matrix %s" % expr.arg)

    return expr
Example #11
0
 def _eval_power(self, exp):
     # exp = -1, 0, 1 are already handled at this stage
     if self._is_1x1() == True:
         return Identity(1)
     if (exp < 0) == True:
         raise NonInvertibleMatrixError("Matrix det == 0; not invertible")
     if ask(Q.integer(exp)):
         return self.shape[0]**(exp - 1) * OneMatrix(*self.shape)
     return super(OneMatrix, self)._eval_power(exp)
Example #12
0
def test_matrix_element_sets():
    X = MatrixSymbol('X', 4, 4)
    assert ask(Q.real(X[1, 2]), Q.real_elements(X))
    assert ask(Q.integer(X[1, 2]), Q.integer_elements(X))
    assert ask(Q.complex(X[1, 2]), Q.complex_elements(X))
    assert ask(Q.integer_elements(Identity(3)))
    assert ask(Q.integer_elements(ZeroMatrix(3, 3)))
    assert ask(Q.integer_elements(OneMatrix(3, 3)))
    from sympy.matrices.expressions.fourier import DFT
    assert ask(Q.complex_elements(DFT(3)))
Example #13
0
def test_invertible_BlockMatrix():
    assert ask(Q.invertible(BlockMatrix([Identity(3)]))) == True
    assert ask(Q.invertible(BlockMatrix([ZeroMatrix(3, 3)]))) == False

    X = Matrix([[1, 2, 3], [3, 5, 4]])
    Y = Matrix([[4, 2, 7], [2, 3, 5]])
    # non-invertible A block
    assert ask(
        Q.invertible(
            BlockMatrix([
                [Matrix.ones(3, 3), Y.T],
                [X, Matrix.eye(2)],
            ]))) == True
    # non-invertible B block
    assert ask(
        Q.invertible(
            BlockMatrix([
                [Y.T, Matrix.ones(3, 3)],
                [Matrix.eye(2), X],
            ]))) == True
    # non-invertible C block
    assert ask(
        Q.invertible(
            BlockMatrix([
                [X, Matrix.eye(2)],
                [Matrix.ones(3, 3), Y.T],
            ]))) == True
    # non-invertible D block
    assert ask(
        Q.invertible(
            BlockMatrix([
                [Matrix.eye(2), X],
                [Y.T, Matrix.ones(3, 3)],
            ]))) == True
Example #14
0
def refine_Transpose(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine
    >>> X = MatrixSymbol('X', 2, 2)
    >>> X.T
    X.T
    >>> with assuming(Q.symmetric(X)):
    ...     print(refine(X.T))
    X
    """
    if ask(Q.symmetric(expr), assumptions):
        return expr.arg

    return expr
Example #15
0
def refine_Transpose(expr, assumptions):
    """
    >>> from sympy import MatrixSymbol, Q, assuming, refine
    >>> X = MatrixSymbol('X', 2, 2)
    >>> X.T
    X.T
    >>> with assuming(Q.symmetric(X)):
    ...     print(refine(X.T))
    X
    """
    if ask(Q.symmetric(expr), assumptions):
        return expr.arg

    return expr
Example #16
0
def test_invertible_BlockDiagMatrix():
    assert ask(Q.invertible(BlockDiagMatrix(Identity(3), Identity(5)))) == True
    assert ask(Q.invertible(BlockDiagMatrix(ZeroMatrix(3, 3),
                                            Identity(5)))) == False
    assert ask(Q.invertible(BlockDiagMatrix(Identity(3),
                                            OneMatrix(5, 5)))) == False
Example #17
0
def test_diagonal():
    assert ask(Q.diagonal(X + Z.T + Identity(2)),
               Q.diagonal(X) & Q.diagonal(Z)) is True
    assert ask(Q.diagonal(ZeroMatrix(3, 3)))
    assert ask(Q.diagonal(OneMatrix(1, 1))) is True
    assert ask(Q.diagonal(OneMatrix(3, 3))) is False
    assert ask(Q.lower_triangular(X) & Q.upper_triangular(X), Q.diagonal(X))
    assert ask(Q.diagonal(X), Q.lower_triangular(X) & Q.upper_triangular(X))
    assert ask(Q.symmetric(X), Q.diagonal(X))
    assert ask(Q.triangular(X), Q.diagonal(X))
    assert ask(Q.diagonal(C0x0))
    assert ask(Q.diagonal(A1x1))
    assert ask(Q.diagonal(A1x1 + B1x1))
    assert ask(Q.diagonal(A1x1 * B1x1))
    assert ask(Q.diagonal(V1.T * V2))
    assert ask(Q.diagonal(V1.T * (X + Z) * V1))
    assert ask(Q.diagonal(MatrixSlice(Y, (0, 1), (1, 2)))) is True
    assert ask(Q.diagonal(V1.T * (V1 + V2))) is True
    assert ask(Q.diagonal(X**3), Q.diagonal(X))
    assert ask(Q.diagonal(Identity(3)))
    assert ask(Q.diagonal(DiagMatrix(V1)))
    assert ask(Q.diagonal(DiagonalMatrix(X)))
Example #18
0
def test_det_trace_positive():
    X = MatrixSymbol('X', 4, 4)
    assert ask(Q.positive(Trace(X)), Q.positive_definite(X))
    assert ask(Q.positive(Determinant(X)), Q.positive_definite(X))
Example #19
0
def test_field_assumptions():
    X = MatrixSymbol('X', 4, 4)
    Y = MatrixSymbol('Y', 4, 4)
    assert ask(Q.real_elements(X), Q.real_elements(X))
    assert not ask(Q.integer_elements(X), Q.real_elements(X))
    assert ask(Q.complex_elements(X), Q.real_elements(X))
    assert ask(Q.complex_elements(X**2), Q.real_elements(X))
    assert ask(Q.real_elements(X**2), Q.integer_elements(X))
    assert ask(Q.real_elements(X + Y), Q.real_elements(X)) is None
    assert ask(Q.real_elements(X + Y), Q.real_elements(X) & Q.real_elements(Y))
    from sympy.matrices.expressions.hadamard import HadamardProduct
    assert ask(Q.real_elements(HadamardProduct(X, Y)),
               Q.real_elements(X) & Q.real_elements(Y))
    assert ask(Q.complex_elements(X + Y),
               Q.real_elements(X) & Q.complex_elements(Y))

    assert ask(Q.real_elements(X.T), Q.real_elements(X))
    assert ask(Q.real_elements(X.I), Q.real_elements(X) & Q.invertible(X))
    assert ask(Q.real_elements(Trace(X)), Q.real_elements(X))
    assert ask(Q.integer_elements(Determinant(X)), Q.integer_elements(X))
    assert not ask(Q.integer_elements(X.I), Q.integer_elements(X))
    alpha = Symbol('alpha')
    assert ask(Q.real_elements(alpha * X), Q.real_elements(X) & Q.real(alpha))
    assert ask(Q.real_elements(LofLU(X)), Q.real_elements(X))
    e = Symbol('e', integer=True, negative=True)
    assert ask(Q.real_elements(X**e), Q.real_elements(X) & Q.invertible(X))
    assert ask(Q.real_elements(X**e), Q.real_elements(X)) is None
Example #20
0
def test_invertible():
    assert ask(Q.invertible(X), Q.invertible(X))
    assert ask(Q.invertible(Y)) is False
    assert ask(Q.invertible(X * Y), Q.invertible(X)) is False
    assert ask(Q.invertible(X * Z), Q.invertible(X)) is None
    assert ask(Q.invertible(X * Z), Q.invertible(X) & Q.invertible(Z)) is True
    assert ask(Q.invertible(X.T)) is None
    assert ask(Q.invertible(X.T), Q.invertible(X)) is True
    assert ask(Q.invertible(X.I)) is True
    assert ask(Q.invertible(Identity(3))) is True
    assert ask(Q.invertible(ZeroMatrix(3, 3))) is False
    assert ask(Q.invertible(OneMatrix(1, 1))) is True
    assert ask(Q.invertible(OneMatrix(3, 3))) is False
    assert ask(Q.invertible(X), Q.fullrank(X) & Q.square(X))
Example #21
0
def identify_removable_identity_matrices(expr):
    editor = _EditArrayContraction(expr)

    flag: bool = True
    while flag:
        flag = False
        for arg_with_ind in editor.args_with_ind:
            if isinstance(arg_with_ind.element, Identity):
                k = arg_with_ind.element.shape[0]
                # Candidate for removal:
                if arg_with_ind.indices == [None, None]:
                    # Free identity matrix, will be cleared by _remove_trivial_dims:
                    continue
                elif None in arg_with_ind.indices:
                    ind = [j for j in arg_with_ind.indices if j is not None][0]
                    counted = editor.count_args_with_index(ind)
                    if counted == 1:
                        # Identity matrix contracted only on one index with itself,
                        # transform to a OneArray(k) element:
                        editor.insert_after(arg_with_ind, OneArray(k))
                        editor.args_with_ind.remove(arg_with_ind)
                        flag = True
                        break
                    elif counted > 2:
                        # Case counted = 2 is a matrix multiplication by identity matrix, skip it.
                        # Case counted > 2 is a multiple contraction,
                        # this is a case where the contraction becomes a diagonalization if the
                        # identity matrix is dropped.
                        continue
                elif arg_with_ind.indices[0] == arg_with_ind.indices[1]:
                    ind = arg_with_ind.indices[0]
                    counted = editor.count_args_with_index(ind)
                    if counted > 1:
                        editor.args_with_ind.remove(arg_with_ind)
                        flag = True
                        break
                    else:
                        # This is a trace, skip it as it will be recognized somewhere else:
                        pass
            elif ask(Q.diagonal(arg_with_ind.element)):
                if arg_with_ind.indices == [None, None]:
                    continue
                elif None in arg_with_ind.indices:
                    pass
                elif arg_with_ind.indices[0] == arg_with_ind.indices[1]:
                    ind = arg_with_ind.indices[0]
                    counted = editor.count_args_with_index(ind)
                    if counted == 3:
                        # A_ai B_bi D_ii ==> A_ai D_ij B_bj
                        ind_new = editor.get_new_contraction_index()
                        other_args = [
                            j for j in editor.args_with_ind
                            if j != arg_with_ind
                        ]
                        other_args[1].indices = [
                            ind_new if j == ind else j
                            for j in other_args[1].indices
                        ]
                        arg_with_ind.indices = [ind, ind_new]
                        flag = True
                        break

    return editor.to_array_contraction()
Example #22
0
 def _contains(self, other):
     if ask(Q.negative(other)) == False and ask(Q.integer(other)):
         return True
     return False
Example #23
0
 def _contains(self, other):
     if ask(Q.positive(other)) and ask(Q.integer(other)):
         return True
     return False
Example #24
0
 def _contains(self, other):
     return (other >= self.inf and other <= self.sup and
             ask(Q.integer((self.start - other)/self.step)))
Example #25
0
def test_non_atoms():
    assert ask(Q.real(Trace(X)), Q.positive(Trace(X)))
Example #26
0
 def _contains(self, other):
     from sympy.assumptions.ask import ask, Q
     return (other >= self.inf and other <= self.sup and
             ask(Q.integer((self.start - other)/self.step)))
Example #27
0
def test_matrix_element_sets_slices_blocks():
    X = MatrixSymbol('X', 4, 4)
    assert ask(Q.integer_elements(X[:, 3]), Q.integer_elements(X))
    assert ask(Q.integer_elements(BlockMatrix([[X], [X]])),
               Q.integer_elements(X))
Example #28
0
def test_matrix_element_sets_determinant_trace():
    assert ask(Q.integer(Determinant(X)), Q.integer_elements(X))
    assert ask(Q.integer(Trace(X)), Q.integer_elements(X))
Example #29
0
def test_invertible_fullrank():
    assert ask(Q.invertible(X), Q.fullrank(X)) is True
Example #30
0
def test_singular():
    assert ask(Q.singular(X)) is None
    assert ask(Q.singular(X), Q.invertible(X)) is False
    assert ask(Q.singular(X), ~Q.invertible(X)) is True
Example #31
0
def test_triangular():
    assert ask(Q.upper_triangular(X + Z.T + Identity(2)),
               Q.upper_triangular(X) & Q.lower_triangular(Z)) is True
    assert ask(Q.upper_triangular(X * Z.T),
               Q.upper_triangular(X) & Q.lower_triangular(Z)) is True
    assert ask(Q.lower_triangular(Identity(3))) is True
    assert ask(Q.lower_triangular(ZeroMatrix(3, 3))) is True
    assert ask(Q.upper_triangular(ZeroMatrix(3, 3))) is True
    assert ask(Q.lower_triangular(OneMatrix(1, 1))) is True
    assert ask(Q.upper_triangular(OneMatrix(1, 1))) is True
    assert ask(Q.lower_triangular(OneMatrix(3, 3))) is False
    assert ask(Q.upper_triangular(OneMatrix(3, 3))) is False
    assert ask(Q.triangular(X), Q.unit_triangular(X))
    assert ask(Q.upper_triangular(X**3), Q.upper_triangular(X))
    assert ask(Q.lower_triangular(X**3), Q.lower_triangular(X))
Example #32
0
def test_positive_definite():
    assert ask(Q.positive_definite(X), Q.positive_definite(X))
    assert ask(Q.positive_definite(X.T), Q.positive_definite(X)) is True
    assert ask(Q.positive_definite(X.I), Q.positive_definite(X)) is True
    assert ask(Q.positive_definite(Y)) is False
    assert ask(Q.positive_definite(X)) is None
    assert ask(Q.positive_definite(X**3), Q.positive_definite(X))
    assert ask(Q.positive_definite(X * Z * X),
               Q.positive_definite(X) & Q.positive_definite(Z)) is True
    assert ask(Q.positive_definite(X), Q.orthogonal(X))
    assert ask(Q.positive_definite(Y.T * X * Y),
               Q.positive_definite(X) & Q.fullrank(Y)) is True
    assert not ask(Q.positive_definite(Y.T * X * Y), Q.positive_definite(X))
    assert ask(Q.positive_definite(Identity(3))) is True
    assert ask(Q.positive_definite(ZeroMatrix(3, 3))) is False
    assert ask(Q.positive_definite(OneMatrix(1, 1))) is True
    assert ask(Q.positive_definite(OneMatrix(3, 3))) is False
    assert ask(Q.positive_definite(X + Z),
               Q.positive_definite(X) & Q.positive_definite(Z)) is True
    assert not ask(Q.positive_definite(-X), Q.positive_definite(X))
    assert ask(Q.positive(X[1, 1]), Q.positive_definite(X))
Example #33
0
 def _contains(self, other):
     from sympy.assumptions.ask import ask, Q
     if ask(Q.negative(other)) == False and ask(Q.integer(other)):
         return True
     return False
Example #34
0
 def _contains(self, other):
     from sympy.assumptions.ask import ask, Q
     if ask(Q.negative(other)) == False and ask(Q.integer(other)):
         return True
     return False
Example #35
0
def test_symmetric():
    assert ask(Q.symmetric(X), Q.symmetric(X))
    assert ask(Q.symmetric(X * Z), Q.symmetric(X)) is None
    assert ask(Q.symmetric(X * Z), Q.symmetric(X) & Q.symmetric(Z)) is True
    assert ask(Q.symmetric(X + Z), Q.symmetric(X) & Q.symmetric(Z)) is True
    assert ask(Q.symmetric(Y)) is False
    assert ask(Q.symmetric(Y * Y.T)) is True
    assert ask(Q.symmetric(Y.T * X * Y)) is None
    assert ask(Q.symmetric(Y.T * X * Y), Q.symmetric(X)) is True
    assert ask(Q.symmetric(X**10), Q.symmetric(X)) is True
    assert ask(Q.symmetric(A1x1)) is True
    assert ask(Q.symmetric(A1x1 + B1x1)) is True
    assert ask(Q.symmetric(A1x1 * B1x1)) is True
    assert ask(Q.symmetric(V1.T * V1)) is True
    assert ask(Q.symmetric(V1.T * (V1 + V2))) is True
    assert ask(Q.symmetric(V1.T * (V1 + V2) + A1x1)) is True
    assert ask(Q.symmetric(MatrixSlice(Y, (0, 1), (1, 2)))) is True
    assert ask(Q.symmetric(Identity(3))) is True
    assert ask(Q.symmetric(ZeroMatrix(3, 3))) is True
    assert ask(Q.symmetric(OneMatrix(3, 3))) is True
Example #36
0
def test_square():
    assert ask(Q.square(X))
    assert not ask(Q.square(Y))
    assert ask(Q.square(Y * Y.T))
Example #37
0
 def _contains(self, other):
     from sympy.assumptions.ask import ask, Q
     return (other >= self.inf and other <= self.sup
             and ask(Q.integer((self.start - other) / self.step)))
Example #38
0
def test_fullrank():
    assert ask(Q.fullrank(X), Q.fullrank(X))
    assert ask(Q.fullrank(X**2), Q.fullrank(X))
    assert ask(Q.fullrank(X.T), Q.fullrank(X)) is True
    assert ask(Q.fullrank(X)) is None
    assert ask(Q.fullrank(Y)) is None
    assert ask(Q.fullrank(X * Z), Q.fullrank(X) & Q.fullrank(Z)) is True
    assert ask(Q.fullrank(Identity(3))) is True
    assert ask(Q.fullrank(ZeroMatrix(3, 3))) is False
    assert ask(Q.fullrank(OneMatrix(1, 1))) is True
    assert ask(Q.fullrank(OneMatrix(3, 3))) is False
    assert ask(Q.invertible(X), ~Q.fullrank(X)) == False