Example #1
0
def test_BlockDiagMatrix():
    n,m,l = symbols('n m l', integer=True)
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', m, m)
    C = MatrixSymbol('C', l, l)
    M = MatrixSymbol('M', n+m+l, n+m+l)

    X = BlockDiagMatrix(A,B,C)
    Y = BlockDiagMatrix(A, 2*B, 3*C)

    assert X[1,1] == B
    assert X.shape == (n+m+l, n+m+l)
    assert all(X[i,j].is_ZeroMatrix if i!=j else X[i,j] in [A,B,C]
            for i in range(3) for j in range(3))

    assert block_collapse(X.I * X).is_Identity

    assert block_collapse(X*X) == BlockDiagMatrix(A**2, B**2, C**2)

    assert block_collapse(X+X) == BlockDiagMatrix(2*A, 2*B, 2*C)

    assert block_collapse(X*Y) == BlockDiagMatrix(A**2, 2*B**2, 3*C**2)

    assert block_collapse(X+Y) == BlockDiagMatrix(2*A, 3*B, 4*C)

    # Ensure that BlockDiagMatrices can still interact with normal MatrixExprs
    assert (X*(2*M)).is_Mul
    assert (X+(2*M)).is_Add

    assert (X._blockmul(M)).is_Mul
    assert (X._blockadd(M)).is_Add
Example #2
0
def test_squareBlockMatrix():
    n,m,l,k = symbols('n m l k', integer=True)
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', n, m)
    C = MatrixSymbol('C', m, n)
    D = MatrixSymbol('D', m, m)
    X = BlockMatrix([[A,B],[C,D]])
    Y = BlockMatrix([[A]])

    assert X.is_square

    assert block_collapse(X+Identity(m+n)) == BlockMatrix(
        [[A+Identity(n), B], [C, D+Identity(m)]])
    Q = X+Identity(m+n)
    assert block_collapse(Inverse(Q)) == Inverse(block_collapse(Q))

    assert (X + MatrixSymbol('Q', n+m, n+m)).is_Add
    assert (X * MatrixSymbol('Q', n+m, n+m)).is_Mul

    assert Y.I[0,0] == A.I
    assert Inverse(X, expand=True) == BlockMatrix([
        [(-B*D.I*C + A).I, -A.I*B*(D+-C*A.I*B).I],
        [-(D-C*A.I*B).I*C*A.I, (D-C*A.I*B).I]])

    assert Inverse(X, expand=False).is_Inverse
    assert X.inverse().is_Inverse

    assert not X.is_Identity

    Z = BlockMatrix([[Identity(n),B],[C,D]])
    assert not Z.is_Identity
Example #3
0
def test_BlockDiagMatrix():
    n, m, l = symbols('n m l', integer=True)
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', m, m)
    C = MatrixSymbol('C', l, l)
    M = MatrixSymbol('M', n + m + l, n + m + l)

    X = BlockDiagMatrix(A, B, C)
    Y = BlockDiagMatrix(A, 2 * B, 3 * C)

    assert X.blocks[1, 1] == B
    assert X.shape == (n + m + l, n + m + l)
    assert all(
        X.blocks[i, j].is_ZeroMatrix if i != j else X.blocks[i,
                                                             j] in [A, B, C]
        for i in range(3) for j in range(3))

    assert block_collapse(X.I * X).is_Identity

    assert block_collapse(X * X) == BlockDiagMatrix(A * A, B * B, C * C)

    assert block_collapse(X + X) == BlockDiagMatrix(2 * A, 2 * B, 2 * C)

    assert block_collapse(X * Y) == BlockDiagMatrix(A * A, 2 * B * B,
                                                    3 * C * C)

    assert block_collapse(X + Y) == BlockDiagMatrix(2 * A, 3 * B, 4 * C)

    # Ensure that BlockDiagMatrices can still interact with normal MatrixExprs
    assert (X * (2 * M)).is_Mul
    assert (X + (2 * M)).is_Add

    assert (X._blockmul(M)).is_Mul
    assert (X._blockadd(M)).is_Add
Example #4
0
def test_squareBlockMatrix():
    n, m, l, k = symbols('n m l k', integer=True)
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', n, m)
    C = MatrixSymbol('C', m, n)
    D = MatrixSymbol('D', m, m)
    X = BlockMatrix([[A, B], [C, D]])
    Y = BlockMatrix([[A]])

    assert X.is_square

    assert block_collapse(X + Identity(m + n)) == BlockMatrix(
        [[A + Identity(n), B], [C, D + Identity(m)]])
    Q = X + Identity(m + n)
    assert block_collapse(Inverse(Q)) == Inverse(block_collapse(Q))

    assert (X + MatrixSymbol('Q', n + m, n + m)).is_Add
    assert (X * MatrixSymbol('Q', n + m, n + m)).is_Mul

    assert Y.I.blocks[0, 0] == A.I
    assert Inverse(X, expand=True) == BlockMatrix([[
        (-B * D.I * C + A).I, -A.I * B * (D + -C * A.I * B).I
    ], [-(D - C * A.I * B).I * C * A.I, (D - C * A.I * B).I]])

    assert Inverse(X, expand=False).is_Inverse
    assert X.inverse().is_Inverse

    assert not X.is_Identity

    Z = BlockMatrix([[Identity(n), B], [C, D]])
    assert not Z.is_Identity
Example #5
0
def test_BlockMatrix():
    n,m,l,k,p = symbols('n m l k p', integer=True)
    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]]))

    # 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 (block_collapse(Transpose(X)) ==
            BlockMatrix(Matrix([[A.T, C.T], [B.T, D.T]])))
    assert Transpose(X).shape == X.shape[::-1]
    assert X.blockshape == (2,2)

    # Test that BlockMatrices and MatrixSymbols can still mix
    assert (X*M).is_Mul
    assert X._blockmul(M).is_Mul
    assert (X*M).shape == (n+l, p)
    assert (X+N).is_Add
    assert X._blockadd(N).is_Add
    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)[0,0] == A*E + B*F
    assert block_collapse(X*Y)[1,0] == C*E + D*F
    assert (block_collapse(Transpose(block_collapse(Transpose(X*Y)))) ==
            block_collapse(X*Y))

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

    Ab = BlockMatrix([[A]])
    Z = MatrixSymbol('Z', *A.shape)

    # Make sure that MatrixSymbols will enter 1x1 BlockMatrix if it simplifies
    assert block_collapse(Ab+Z) == BlockMatrix([[A+Z]])
Example #6
0
def test_BlockMatrix():
    n, m, l, k, p = symbols('n m l k p', integer=True)
    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]]))

    # 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 (block_collapse(Transpose(X)) == BlockMatrix(
        Matrix([[A.T, C.T], [B.T, D.T]])))
    assert Transpose(X).shape == X.shape[::-1]
    assert X.blockshape == (2, 2)

    # Test that BlockMatrices and MatrixSymbols can still mix
    assert (X * M).is_Mul
    assert X._blockmul(M).is_Mul
    assert (X * M).shape == (n + l, p)
    assert (X + N).is_Add
    assert X._blockadd(N).is_Add
    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
    assert (block_collapse(Transpose(block_collapse(Transpose(
        X * Y)))) == block_collapse(X * Y))

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

    Ab = BlockMatrix([[A]])
    Z = MatrixSymbol('Z', *A.shape)

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