Example #1
0
def block(*rows):
    """Construct a matrix from its blocks, preserving structure when possible.

    Assumes that every row has an equal number of blocks and that the sizes
    of the blocks align to form a grid.

    Args:
        *rows (list): Rows of the block matrix.

    Returns:
        matrix: Assembled matrix with as much structured as possible.
    """
    if len(rows) == 1 and len(rows[0]) == 1:
        # There is just one block. Return it.
        return rows[0][0]

    res = _attempt_zero(rows)
    if res is not None:
        return res

    res = _attempt_diagonal(rows)
    if res is not None:
        return res

    # Could not preserve any structure. Simply concatenate them all densely.
    warn_upmodule(
        "Could not preserve structure in block matrix: converting to dense.",
        category=ToDenseWarning,
    )
    return Dense(B.concat2d(*[[B.dense(x) for x in row] for row in rows]))
Example #2
0
def test_diag_block_diag(diag1, diag2):
    approx(
        B.diag(diag1, diag2),
        B.concat2d(
            [B.dense(diag1), B.zeros(B.dense(diag2))],
            [B.zeros(B.dense(diag2)), B.dense(diag2)],
        ),
    )
    assert isinstance(B.diag(diag1, diag2), Diagonal)
Example #3
0
def test_diag_block_dense(dense1, dense2):
    with AssertDenseWarning(concat_warnings):
        res = B.diag(dense1, dense2)
        approx(
            res,
            B.concat2d(
                [B.dense(dense1), B.zeros(B.dense(dense1))],
                [B.zeros(B.dense(dense2)),
                 B.dense(dense2)],
            ),
        )
        assert isinstance(res, Dense)
Example #4
0
def test_block_diag():
    rows = [
        [generate("diag:6"),
         generate("zero:6,6"),
         generate("zero:6,3")],
        [generate("zero:6,6"),
         generate("zero:6,6"),
         generate("zero:6,3")],
        [generate("zero:3,6"),
         generate("zero:3,6"),
         generate("diag:3")],
    ]
    res = B.block(*rows)
    approx(res, B.concat2d(*_dense(rows)))
    assert isinstance(res, Diagonal)
Example #5
0
def diag(a, b):
    # We could merge this with `block`, but `block` has a lot of overhead. It
    # seems advantageous to optimise this common case.
    warn_upmodule(
        f"Constructing a dense block-diagonal matrix from "
        f"{a} and {b}: converting to dense.",
        category=ToDenseWarning,
    )
    a = B.dense(a)
    b = B.dense(b)

    dtype = B.dtype(a)
    ar, ac = B.shape(a)
    br, bc = B.shape(b)
    return Dense(
        B.concat2d([a, B.zeros(dtype, ar, bc)], [B.zeros(dtype, br, ac), b]))
Example #6
0
def test_mokernel(x1, x2, x3):
    m = Measure()
    p1 = GP(1 * EQ(), measure=m)
    p2 = GP(2 * EQ().stretch(2), measure=m)

    k = MultiOutputKernel(m, p1, p2)
    ks = m.kernels

    # Check representation.
    assert str(k) == "MultiOutputKernel(EQ(), 2 * (EQ() > 2))"

    # Input versus input:
    approx(
        k(x1, x2),
        B.concat2d(
            [ks[p1, p1](x1, x2), ks[p1, p2](x1, x2)],
            [ks[p2, p1](x1, x2), ks[p2, p2](x1, x2)],
        ),
    )
    approx(
        k.elwise(x1, x3),
        B.concat(ks[p1, p1].elwise(x1, x3), ks[p2, p2].elwise(x1, x3), axis=0),
    )

    # Input versus `FDD`:
    approx(k(p1(x1), x2),
           B.concat(ks[p1, p1](x1, x2), ks[p1, p2](x1, x2), axis=1))
    approx(k(p2(x1), x2),
           B.concat(ks[p2, p1](x1, x2), ks[p2, p2](x1, x2), axis=1))
    approx(k(x1, p1(x2)),
           B.concat(ks[p1, p1](x1, x2), ks[p2, p1](x1, x2), axis=0))
    approx(k(x1, p2(x2)),
           B.concat(ks[p1, p2](x1, x2), ks[p2, p2](x1, x2), axis=0))
    with pytest.raises(ValueError):
        k.elwise(x1, p2(x3))
    with pytest.raises(ValueError):
        k.elwise(p1(x1), x3)

    # `FDD` versus `FDD`:
    approx(k(p1(x1), p1(x2)), ks[p1](x1, x2))
    approx(k(p1(x1), p2(x2)), ks[p1, p2](x1, x2))
    approx(k.elwise(p1(x1), p1(x3)), ks[p1].elwise(x1, x3))
    approx(k.elwise(p1(x1), p2(x3)), ks[p1, p2].elwise(x1, x3))

    # `MultiInput` versus input:
    approx(
        k(MultiInput(p2(x1), p1(x2)), x1),
        B.concat2d(
            [ks[p2, p1](x1, x1), ks[p2, p2](x1, x1)],
            [ks[p1, p1](x2, x1), ks[p1, p2](x2, x1)],
        ),
    )
    approx(
        k(x1, MultiInput(p2(x1), p1(x2))),
        B.concat2d(
            [ks[p1, p2](x1, x1), ks[p1, p1](x1, x2)],
            [ks[p2, p2](x1, x1), ks[p2, p1](x1, x2)],
        ),
    )
    with pytest.raises(ValueError):
        k.elwise(MultiInput(p2(x1), p1(x3)), p2(x1))
    with pytest.raises(ValueError):
        k.elwise(p2(x1), MultiInput(p2(x1), p1(x3)))

    # `MultiInput` versus `FDD`:
    approx(
        k(MultiInput(p2(x1), p1(x2)), p2(x1)),
        B.concat(ks[p2, p2](x1, x1), ks[p1, p2](x2, x1), axis=0),
    )
    approx(
        k(p2(x1), MultiInput(p2(x1), p1(x2))),
        B.concat(ks[p2, p2](x1, x1), ks[p2, p1](x1, x2), axis=1),
    )
    with pytest.raises(ValueError):
        k.elwise(MultiInput(p2(x1), p1(x3)), p2(x1))
    with pytest.raises(ValueError):
        k.elwise(p2(x1), MultiInput(p2(x1), p1(x3)))

    # `MultiInput` versus `MultiInput`:
    approx(
        k(MultiInput(p2(x1), p1(x2)), MultiInput(p2(x1))),
        B.concat(ks[p2, p2](x1, x1), ks[p1, p2](x2, x1), axis=0),
    )
    with pytest.raises(ValueError):
        k.elwise(MultiInput(p2(x1), p1(x3)), MultiInput(p2(x1)))
    approx(
        k.elwise(MultiInput(p2(x1), p1(x3)), MultiInput(p2(x1), p1(x3))),
        B.concat(ks[p2, p2].elwise(x1, x1), ks[p1, p1].elwise(x3, x3), axis=0),
    )
Example #7
0
def test_block_zero():
    rows = [[generate("zero:6,6") for _ in range(3)] for _ in range(3)]
    res = B.block(*rows)
    approx(res, B.concat2d(*_dense(rows)))
    assert isinstance(res, Zero)
Example #8
0
def test_block_dense():
    rows = [[generate("dense:6,6") for _ in range(3)] for _ in range(3)]
    with AssertDenseWarning("could not preserve structure"):
        res = B.block(*rows)
    approx(res, B.concat2d(*_dense(rows)))
Example #9
0
def test_mok():
    x1 = B.linspace(0, 1, 10)
    x2 = B.linspace(1, 2, 5)
    x3 = B.linspace(1, 2, 10)

    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(2 * EQ().stretch(2), measure=m)

    k = MultiOutputKernel(m, p1, p2)
    ks = m.kernels

    # Check dimensionality.
    assert dimensionality(k) == 2

    # Check representation.
    assert str(k) == "MultiOutputKernel(EQ(), 2 * (EQ() > 2))"

    # Input versus input:
    approx(
        k(x1, x2),
        B.concat2d(
            [ks[p1, p1](x1, x2), ks[p1, p2](x1, x2)],
            [ks[p2, p1](x1, x2), ks[p2, p2](x1, x2)],
        ),
    )
    approx(
        k.elwise(x1, x3),
        B.concat(ks[p1, p1].elwise(x1, x3), ks[p2, p2].elwise(x1, x3), axis=0),
    )

    # Input versus `FDD`:
    approx(k(p1(x1), x2), B.concat(ks[p1, p1](x1, x2), ks[p1, p2](x1, x2), axis=1))
    approx(k(p2(x1), x2), B.concat(ks[p2, p1](x1, x2), ks[p2, p2](x1, x2), axis=1))
    approx(k(x1, p1(x2)), B.concat(ks[p1, p1](x1, x2), ks[p2, p1](x1, x2), axis=0))
    approx(k(x1, p2(x2)), B.concat(ks[p1, p2](x1, x2), ks[p2, p2](x1, x2), axis=0))
    with pytest.raises(ValueError):
        k.elwise(x1, p2(x3))
    with pytest.raises(ValueError):
        k.elwise(p1(x1), x3)

    # `FDD` versus `FDD`:
    approx(k(p1(x1), p1(x2)), ks[p1](x1, x2))
    approx(k(p1(x1), p2(x2)), ks[p1, p2](x1, x2))
    approx(k.elwise(p1(x1), p1(x3)), ks[p1].elwise(x1, x3))
    approx(k.elwise(p1(x1), p2(x3)), ks[p1, p2].elwise(x1, x3))

    # Multiple inputs versus input:
    approx(
        k((p2(x1), p1(x2)), x1),
        B.concat2d(
            [ks[p2, p1](x1, x1), ks[p2, p2](x1, x1)],
            [ks[p1, p1](x2, x1), ks[p1, p2](x2, x1)],
        ),
    )
    approx(
        k(x1, (p2(x1), p1(x2))),
        B.concat2d(
            [ks[p1, p2](x1, x1), ks[p1, p1](x1, x2)],
            [ks[p2, p2](x1, x1), ks[p2, p1](x1, x2)],
        ),
    )
    with pytest.raises(ValueError):
        k.elwise((p2(x1), p1(x3)), p2(x1))
    with pytest.raises(ValueError):
        k.elwise(p2(x1), (p2(x1), p1(x3)))

    # Multiple inputs versus `FDD`:
    approx(
        k((p2(x1), p1(x2)), p2(x1)),
        B.concat(ks[p2, p2](x1, x1), ks[p1, p2](x2, x1), axis=0),
    )
    approx(
        k(p2(x1), (p2(x1), p1(x2))),
        B.concat(ks[p2, p2](x1, x1), ks[p2, p1](x1, x2), axis=1),
    )
    with pytest.raises(ValueError):
        k.elwise((p2(x1), p1(x3)), p2(x1))
    with pytest.raises(ValueError):
        k.elwise(p2(x1), (p2(x1), p1(x3)))

    # Multiple inputs versus multiple inputs:
    approx(
        k((p2(x1), p1(x2)), (p2(x1))),
        B.concat(ks[p2, p2](x1, x1), ks[p1, p2](x2, x1), axis=0),
    )
    with pytest.raises(ValueError):
        k.elwise((p2(x1), p1(x3)), (p2(x1),))
    approx(
        k.elwise((p2(x1), p1(x3)), (p2(x1), p1(x3))),
        B.concat(ks[p2, p2].elwise(x1, x1), ks[p1, p1].elwise(x3, x3), axis=0),
    )