Beispiel #1
0
def block_collapse(expr):
    """Evaluates a block matrix expression

    >>> from sympy import MatrixSymbol, BlockMatrix, symbols, \
                          Identity, Matrix, ZeroMatrix, block_collapse
    >>> n,m,l = symbols('n m l')
    >>> X = MatrixSymbol('X', n, n)
    >>> Y = MatrixSymbol('Y', m ,m)
    >>> Z = MatrixSymbol('Z', n, m)
    >>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]])
    >>> print B
    [X, Z]
    [0, Y]

    >>> C = BlockMatrix([[Identity(n), Z]])
    >>> print C
    [I, Z]

    >>> print block_collapse(C*B)
    [X, Z + Z*Y]
    """
    rule = canon(typed({MatAdd: do_one(bc_matadd, bc_block_plus_ident),
                        MatMul: do_one(bc_matmul, bc_dist),
                        MatPow: bc_matpow,
                        BlockMatrix: bc_unpack}))
    result = rule(expr)
    try:
        return result.canonicalize()
    except AttributeError:
        return result
Beispiel #2
0
def block_collapse(expr):
    """Evaluates a block matrix expression

    >>> from sympy import MatrixSymbol, BlockMatrix, symbols, \
                          Identity, Matrix, ZeroMatrix, block_collapse
    >>> n,m,l = symbols('n m l')
    >>> X = MatrixSymbol('X', n, n)
    >>> Y = MatrixSymbol('Y', m ,m)
    >>> Z = MatrixSymbol('Z', n, m)
    >>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]])
    >>> print B
    [X, Z]
    [0, Y]

    >>> C = BlockMatrix([[Identity(n), Z]])
    >>> print C
    [I, Z]

    >>> print block_collapse(C*B)
    [X, Z + Z*Y]
    """
    rule = canon(
        typed({
            MatAdd: do_one(bc_matadd, bc_block_plus_ident),
            MatMul: do_one(bc_matmul, bc_dist),
            BlockMatrix: bc_unpack
        }))
    result = rule(expr)
    try:
        return result.doit()
    except AttributeError:
        return result
Beispiel #3
0
def test_do_one():
    rl1 = lambda x: 2 if x == 1 else x
    rl2 = lambda x: 3 if x == 2 else x

    rule = do_one(rl1, rl2)
    assert rule(1) == 2
    assert rule(rule(1)) == 3
Beispiel #4
0
def test_do_one():
    rl1 = lambda x: 2 if x == 1 else x
    rl2 = lambda x: 3 if x == 2 else x

    rule = do_one(rl1, rl2)
    assert rule(1) == 2
    assert rule(rule(1)) == 3
Beispiel #5
0
    """ Remove Identities from a MatMul

    This is a modified version of sympy.rules.rm_id.
    This is necesssary because MatMul may contain both MatrixExprs and Exprs
    as args.

    See Also
    --------
        sympy.rules.rm_id
    """
    # Separate Exprs from MatrixExprs in args
    factor, mmul = mul.as_coeff_mmul()
    # Apply standard rm_id for MatMuls
    result = rm_id(lambda x: x.is_Identity is True)(mmul)
    if result != mmul:
        return newmul(factor, *result.args)  # Recombine and return
    else:
        return mul

def factor_in_front(mul):
    factor, matrices = mul.as_coeff_matrices()
    if factor != 1:
        return newmul(factor, *matrices)
    return mul

rules = (any_zeros, remove_ids, xxinv, unpack, rm_id(lambda x: x == 1),
         factor_in_front, flatten)

canonicalize = exhaust(condition(lambda x: isinstance(x, MatMul),
                                 do_one(*rules)))
Beispiel #6
0
    """ Remove Identities from a MatMul

    This is a modified version of sympy.rules.rm_id.
    This is necesssary because MatMul may contain both MatrixExprs and Exprs
    as args.

    See Also
    --------
        sympy.rules.rm_id
    """
    # Separate Exprs from MatrixExprs in args
    factor, mmul = mul.as_coeff_mmul()
    # Apply standard rm_id for MatMuls
    result = rm_id(lambda x: x.is_Identity is True)(mmul)
    if result != mmul:
        return newmul(factor, *result.args)  # Recombine and return
    else:
        return mul


def factor_in_front(mul):
    factor, matrices = mul.as_coeff_matrices()
    if factor != 1:
        return newmul(factor, *matrices)
    return mul


rules = (any_zeros, remove_ids, xxinv, unpack, rm_id(lambda x: x == 1), factor_in_front, flatten)

canonicalize = exhaust(condition(lambda x: isinstance(x, MatMul), do_one(*rules)))
Beispiel #7
0
    def canonicalize(self):
        return canonicalize(self)


def validate(*args):
    if not all(arg.is_Matrix for arg in args):
        raise TypeError("Mix of Matrix and Scalar symbols")
    A = args[0]
    for B in args[1:]:
        if A.shape != B.shape:
            raise ShapeError("Matrices %s and %s are not aligned" % (A, B))


factor_of = lambda arg: arg.as_coeff_mmul()[0]
matrix_of = lambda arg: unpack(arg.as_coeff_mmul()[1])


def combine(cnt, mat):
    from matmul import MatMul
    if cnt == 1:
        return mat
    else:
        return cnt * mat


rules = (rm_id(lambda x: x == 0 or isinstance(x, ZeroMatrix)), unpack, flatten,
         glom(matrix_of, factor_of, combine), sort(str))

canonicalize = exhaust(
    condition(lambda x: isinstance(x, MatAdd), do_one(*rules)))