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

    >>> 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]])
    >>> B
    Matrix([
    [X, Z],
    [0, Y]])

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

    >>> block_collapse(C*B)
    Matrix([[X, Z + Z*Y]])

    """
    def hasbm(expr):
        return isinstance(expr, MatrixExpr) and expr.has(BlockMatrix)
    rule = exhaust(
        bottom_up(exhaust(condition(hasbm, typed(
            {MatAdd: do_one([bc_matadd, bc_block_plus_ident]),
             MatMul: do_one([bc_matmul, bc_dist]),
             Transpose: bc_transpose,
             Inverse: bc_inverse,
             BlockMatrix: do_one([bc_unpack, deblock])})))))
    result = rule(expr)
    return result.doit()
예제 #2
0
def block_collapse(expr):
    """Evaluates a block matrix expression

    >>> 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]])
    >>> B
    Matrix([
    [X, Z],
    [0, Y]])

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

    >>> block_collapse(C*B)
    Matrix([[X, Z + Z*Y]])

    """
    def hasbm(expr):
        return isinstance(expr, MatrixExpr) and expr.has(BlockMatrix)
    rule = exhaust(
        bottom_up(exhaust(condition(hasbm, typed(
            {MatAdd: do_one([bc_matadd, bc_block_plus_ident]),
             MatMul: do_one([bc_matmul, bc_dist]),
             Transpose: bc_transpose,
             Inverse: bc_inverse,
             BlockMatrix: do_one([bc_unpack, deblock])})))))
    result = rule(expr)
    return result.doit()
예제 #3
0
파일: matmul.py 프로젝트: Blendify/diofant
    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),
         merge_explicit, factor_in_front, flatten)

canonicalize = exhaust(typed({MatMul: do_one(rules)}))


def only_squares(*matrices):
    """ factor matrices only if they are square """
    if matrices[0].rows != matrices[-1].cols:
        raise RuntimeError("Invalid matrices being multiplied")
    out = []
    start = 0
    for i, M in enumerate(matrices):
        if M.cols == matrices[start].rows:
            out.append(MatMul(*matrices[start:i + 1]).doit())
            start = i + 1
    return out
예제 #4
0
    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),
         merge_explicit, factor_in_front, flatten)

canonicalize = exhaust(typed({MatMul: do_one(rules)}))


def only_squares(*matrices):
    """factor matrices only if they are square."""
    if matrices[0].rows != matrices[-1].cols:
        raise RuntimeError("Invalid matrices being multiplied")
    out = []
    start = 0
    for i, M in enumerate(matrices):
        if M.cols == matrices[start].rows:
            out.append(MatMul(*matrices[start:i+1]).doit())
            start = i+1
    return out