Exemplo n.º 1
0
def test_BlockMatrix():
    A = MatrixSymbol("A", n, m)
    B = MatrixSymbol("B", n, k)
    C = MatrixSymbol("C", l, m)
    D = MatrixSymbol("D", l, k)
    M = MatrixSymbol("M", m + k, p)
    N = MatrixSymbol("N", l + n, k + m)
    X = BlockMatrix(Matrix([[A, B], [C, D]]))

    assert X.__class__(*X.args) == X

    # block_collapse does nothing on normal inputs
    E = MatrixSymbol("E", n, m)
    assert block_collapse(A + 2 * E) == A + 2 * E
    F = MatrixSymbol("F", m, m)
    assert block_collapse(E.T * A * F) == E.T * A * F

    assert X.shape == (l + n, k + m)
    assert X.blockshape == (2, 2)
    assert transpose(X) == BlockMatrix(Matrix([[A.T, C.T], [B.T, D.T]]))
    assert transpose(X).shape == X.shape[::-1]

    # Test that BlockMatrices and MatrixSymbols can still mix
    assert (X * M).is_MatMul
    assert X._blockmul(M).is_MatMul
    assert (X * M).shape == (n + l, p)
    assert (X + N).is_MatAdd
    assert X._blockadd(N).is_MatAdd
    assert (X + N).shape == X.shape

    E = MatrixSymbol("E", m, 1)
    F = MatrixSymbol("F", k, 1)

    Y = BlockMatrix(Matrix([[E], [F]]))

    assert (X * Y).shape == (l + n, 1)
    assert block_collapse(X * Y).blocks[0, 0] == A * E + B * F
    assert block_collapse(X * Y).blocks[1, 0] == C * E + D * F

    # block_collapse passes down into container objects, transposes, and inverse
    assert block_collapse(transpose(X * Y)) == transpose(block_collapse(X * Y))
    assert block_collapse(Tuple(X * Y, 2 * X)) == (
        block_collapse(X * Y),
        block_collapse(2 * X),
    )

    # Make sure that MatrixSymbols will enter 1x1 BlockMatrix if it simplifies
    Ab = BlockMatrix([[A]])
    Z = MatrixSymbol("Z", *A.shape)
    assert block_collapse(Ab + Z) == A + Z
Exemplo n.º 2
0
def test_BlockMatrix():
    A = MatrixSymbol('A', n, m)
    B = MatrixSymbol('B', n, k)
    C = MatrixSymbol('C', l, m)
    D = MatrixSymbol('D', l, k)
    M = MatrixSymbol('M', m + k, p)
    N = MatrixSymbol('N', l + n, k + m)
    X = BlockMatrix(Matrix([[A, B], [C, D]]))

    assert X.__class__(*X.args) == X

    # block_collapse does nothing on normal inputs
    E = MatrixSymbol('E', n, m)
    assert block_collapse(A + 2*E) == A + 2*E
    F = MatrixSymbol('F', m, m)
    assert block_collapse(E.T*A*F) == E.T*A*F

    assert X.shape == (l + n, k + m)
    assert X.blockshape == (2, 2)
    assert transpose(X) == BlockMatrix(Matrix([[A.T, C.T], [B.T, D.T]]))
    assert transpose(X).shape == X.shape[::-1]

    # Test that BlockMatrices and MatrixSymbols can still mix
    assert (X*M).is_MatMul
    assert X._blockmul(M).is_MatMul
    assert (X*M).shape == (n + l, p)
    assert (X + N).is_MatAdd
    assert X._blockadd(N).is_MatAdd
    assert (X + N).shape == X.shape

    E = MatrixSymbol('E', m, 1)
    F = MatrixSymbol('F', k, 1)

    Y = BlockMatrix(Matrix([[E], [F]]))

    assert (X*Y).shape == (l + n, 1)
    assert block_collapse(X*Y).blocks[0, 0] == A*E + B*F
    assert block_collapse(X*Y).blocks[1, 0] == C*E + D*F

    # block_collapse passes down into container objects, transposes, and inverse
    assert block_collapse(transpose(X*Y)) == transpose(block_collapse(X*Y))
    assert block_collapse(Tuple(X*Y, 2*X)) == (
        block_collapse(X*Y), block_collapse(2*X))

    # Make sure that MatrixSymbols will enter 1x1 BlockMatrix if it simplifies
    Ab = BlockMatrix([[A]])
    Z = MatrixSymbol('Z', *A.shape)
    assert block_collapse(Ab + Z) == A + Z