Ejemplo n.º 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()
Ejemplo n.º 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()
Ejemplo n.º 3
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
Ejemplo n.º 4
0
    >>> A = MatrixSymbol('A', 2, 2)
    >>> B = eye(2)
    >>> C = Matrix([[1, 2], [3, 4]])
    >>> X = MatAdd(A, B, C)
    >>> pprint(X, use_unicode=False)
        [1  0]   [1  2]
    A + [    ] + [    ]
        [0  1]   [3  4]
    >>> pprint(merge_explicit(X), use_unicode=False)
        [2  2]
    A + [    ]
        [3  5]
    """
    groups = sift(matadd.args, lambda arg: isinstance(arg, MatrixBase))
    if len(groups[True]) > 1:
        return MatAdd(*(groups[False] + [reduce(add, groups[True])]))
    else:
        return matadd


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

canonicalize = exhaust(condition(lambda x: isinstance(x, MatAdd),
                                 do_one(rules)))
Ejemplo n.º 5
0
    """ Merge explicit MatrixBase arguments

    >>> from diofant import MatrixSymbol, eye, Matrix, MatAdd, pprint
    >>> from diofant.matrices.expressions.matadd import merge_explicit
    >>> A = MatrixSymbol('A', 2, 2)
    >>> B = eye(2)
    >>> C = Matrix([[1, 2], [3, 4]])
    >>> X = MatAdd(A, B, C)
    >>> pprint(X, use_unicode=False)
    A + [1  0] + [1  2]
        [    ]   [    ]
        [0  1]   [3  4]
    >>> pprint(merge_explicit(X), use_unicode=False)
    A + [2  2]
        [    ]
        [3  5]
    """
    groups = sift(matadd.args, lambda arg: isinstance(arg, MatrixBase))
    if len(groups[True]) > 1:
        return MatAdd(*(groups[False] + [reduce(add, groups[True])]))
    else:
        return matadd


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

canonicalize = exhaust(
    condition(lambda x: isinstance(x, MatAdd), do_one(rules)))
Ejemplo n.º 6
0
    >>> A = MatrixSymbol('A', 2, 2)
    >>> B = eye(2)
    >>> C = Matrix([[1, 2], [3, 4]])
    >>> X = MatAdd(A, B, C)
    >>> pprint(X, use_unicode=False)
    A + [1  0] + [1  2]
        [    ]   [    ]
        [0  1]   [3  4]
    >>> pprint(merge_explicit(X), use_unicode=False)
    A + [2  2]
        [    ]
        [3  5]
    """
    groups = sift(matadd.args, lambda arg: isinstance(arg, MatrixBase))
    if len(groups[True]) > 1:
        return MatAdd(*(groups[False] + [reduce(add, groups[True])]))
    else:
        return matadd


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

canonicalize = exhaust(condition(lambda x: isinstance(x, MatAdd),
                                 do_one(rules)))
Ejemplo n.º 7
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
Ejemplo n.º 8
0
        return super().__new__(cls, *args)

    @property
    def shape(self):
        return self.args[0].shape

    def _entry(self, i, j):
        return Mul(*[arg._entry(i, j) for arg in self.args])

    def _eval_transpose(self):
        from .transpose import transpose
        return HadamardProduct(*list(map(transpose, self.args)))

    def doit(self, **ignored):
        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))


rules = (unpack, flatten)

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