Пример #1
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)
Пример #2
0
def test_dense_wb(wb1):
    lr_dense = B.mm(B.dense(wb1.lr.left),
                    B.dense(wb1.lr.middle),
                    B.dense(wb1.lr.right),
                    tr_c=True)
    approx(B.dense(wb1), B.diag(wb1.diag.diag) + lr_dense)
    _check_cache(wb1)
Пример #3
0
def _attempt_diagonal(rows):
    # Check whether the result is diagonal.

    # Check that the blocks form a square.
    if not all([len(row) == len(rows) for row in rows]):
        return None

    # Collect the diagonal blocks.
    diagonal_blocks = []
    for r in range(len(rows)):
        for c in range(len(rows[0])):
            block_shape = B.shape(rows[r][c])
            if r == c:
                # Keep track of all the diagonal blocks.
                diagonal_blocks.append(rows[r][c])

                # All blocks on the diagonal must be diagonal or zero.
                if not isinstance(rows[r][c], (Diagonal, Zero)):
                    return None

                # All blocks on the diagonal must be square.
                if not block_shape[0] == block_shape[1]:
                    return None
            else:
                # All blocks not on the diagonal must be zero.
                if not isinstance(rows[r][c], Zero):
                    return None

    return Diagonal(B.concat(*[B.diag(x) for x in diagonal_blocks]))
Пример #4
0
def _check_matmul_diag(a, b):
    for tr_a in [False, True]:
        for tr_b in [False, True]:
            approx(
                B.matmul_diag(a, b, tr_a=tr_a, tr_b=tr_b),
                B.diag(B.matmul(B.dense(a), B.dense(b), tr_a=tr_a, tr_b=tr_b)),
            )
Пример #5
0
    def _project_pattern(self, x, y, pattern):
        # Check whether all data is available.
        no_missing = all(pattern)

        if no_missing:
            # All data is available. Nothing to be done.
            u = self.u
        else:
            # Data is missing. Pick the available entries.
            y = B.take(y, pattern, axis=1)
            # Ensure that `u` remains a structured matrix.
            u = Dense(B.take(self.u, pattern))

        # Get number of data points and outputs in this part of the data.
        n = B.shape(x)[0]
        p = sum(pattern)

        # Perform projection.
        proj_y_partial = B.matmul(y, B.pinv(u), tr_b=True)
        proj_y = B.matmul(proj_y_partial, B.inv(self.s_sqrt), tr_b=True)

        # Compute projected noise.
        u_square = B.matmul(u, u, tr_a=True)
        proj_noise = (
            self.noise_obs / B.diag(self.s_sqrt) ** 2 * B.diag(B.pd_inv(u_square))
        )

        # Convert projected noise to weights.
        noises = self.model.noises
        weights = noises / (noises + proj_noise)
        proj_w = B.ones(B.dtype(weights), n, self.m) * weights[None, :]

        # Compute Frobenius norm.
        frob = B.sum(y ** 2)
        frob = frob - B.sum(proj_y_partial * B.matmul(proj_y_partial, u_square))

        # Compute regularising term.
        reg = 0.5 * (
            n * (p - self.m) * B.log(2 * B.pi * self.noise_obs)
            + frob / self.noise_obs
            + n * B.logdet(B.matmul(u, u, tr_a=True))
            + n * 2 * B.logdet(self.s_sqrt)
        )

        return x, proj_y, proj_w, reg
Пример #6
0
def multiply(a: Diagonal, b: AbstractMatrix):
    assert_compatible(a, b)
    # In the case of broadcasting, `B.diag(b)` will not get the diagonal of the
    # broadcasted version of `b`, so we exercise extra caution in that case.
    rows, cols = B.shape(b)
    if rows == 1 or cols == 1:
        b_diag = B.squeeze(B.dense(b))
    else:
        b_diag = B.diag(b)
    return Diagonal(a.diag * b_diag)
Пример #7
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)
Пример #8
0
def root(a: B.Numeric):  # pragma: no cover
    """Compute the positive square root of a positive-definite matrix.

    Args:
        a (matrix): Matrix to compute square root of.

    Returns:
        matrix: Positive square root of `a`.
    """
    _assert_square_root(a)
    u, s, _ = B.svd(a)
    return B.mm(u, B.diag(B.sqrt(s)), u, tr_c=True)
Пример #9
0
def test_fdd_properties():
    p = GP(1, EQ())

    # Sample observations.
    x = B.linspace(0, 5, 5)
    y = p(x, 0.1).sample()

    # Compute posterior.
    p = p | (p(x, 0.1), y)

    fdd = p(B.linspace(0, 5, 10), 0.2)
    mean, var = fdd.mean, fdd.var

    # Check `var_diag`.
    fdd = p(B.linspace(0, 5, 10), 0.2)
    approx(fdd.var_diag, B.diag(var))

    # Check `mean_var`.
    fdd = p(B.linspace(0, 5, 10), 0.2)
    approx(fdd.mean_var, (mean, var))

    # Check `marginals()`.
    fdd = p(B.linspace(0, 5, 10), 0.2)
    approx(fdd.marginals(), (B.flatten(mean), B.diag(var)))
Пример #10
0
def closest_psd(a, inv=False):
    """Map a matrix to the closest PSD matrix.

    Args:
        a (tensor): Matrix.
        inv (bool, optional): Also invert `a`.

    Returns:
        tensor: PSD matrix closest to `a` or the inverse of `a`.
    """
    a = B.dense(a)
    a = (a + B.transpose(a)) / 2
    u, s, v = B.svd(a)
    signs = B.matmul(u, v, tr_a=True)
    s = B.maximum(B.diag(signs) * s, 0)
    if inv:
        s = B.where(s == 0, 0, 1 / s)
    return B.mm(u * B.expand_dims(s, axis=-2), v, tr_b=True)
Пример #11
0
def matmul_diag(a: LowRank, b: LowRank, tr_a=False, tr_b=False):
    return B.diag(B.matmul(a, b, tr_a=tr_a, tr_b=tr_b))
Пример #12
0
def dense(a: Diagonal):
    if a.dense is None:
        a.dense = B.diag(a.diag)
    return a.dense
Пример #13
0
def diag(a: Kronecker):
    return B.kron(B.diag(a.left), B.diag(a.right))
Пример #14
0
def diag(a: Woodbury):
    return B.diag(a.diag) + B.diag(a.lr)
Пример #15
0
def diag(a: Union[Dense, LowerTriangular, UpperTriangular]):
    return B.diag(a.mat)
Пример #16
0
 def __init__(self, mat: AbstractMatrix):
     Diagonal.__init__(self, B.diag(mat))
Пример #17
0
 def inverse_transform(x):
     chol = B.cholesky(B.reg(x))
     return B.concat(B.log(B.diag(chol)), B.tril_to_vec(chol,
                                                        offset=-1))
Пример #18
0
def logdet(a: Union[Diagonal, LowerTriangular, UpperTriangular]):
    return B.sum(B.log(B.diag(a)))
Пример #19
0
def trace(a: AbstractMatrix):
    # The implementation of diagonal is optimised, so this should be efficient.
    return B.sum(B.diag(a))
Пример #20
0
def test_dense_diag(diag1):
    approx(B.dense(diag1), B.diag(diag1.diag))
    _check_cache(diag1)
Пример #21
0
def test_diag(check_lazy_shapes):
    check_function(B.diag, (Tensor(3),))
    check_function(B.diag, (Tensor(3, 3),))
    # Test rank check for TensorFlow.
    with pytest.raises(ValueError):
        B.diag(Tensor().tf())
Пример #22
0
def test_normal_diagonalise(normal1):
    approx(
        normal1.diagonalise(),
        Normal(normal1.mean, B.diag(B.diag(B.dense(normal1.var)))),
    )
Пример #23
0
def multiply(a: UpperTriangular, b: LowerTriangular):
    return Diagonal(B.multiply(B.diag(a), B.diag(b)))
Пример #24
0
def test_conversion_to_diagonal(dense1):
    approx(Diagonal(dense1), B.diag(B.diag(dense1)))
Пример #25
0
def _check_iqf(a, b, c):
    res = B.iqf_diag(a, b, c)

    # Check correctness.
    approx(res, B.diag(B.iqf(a, b, c)))
Пример #26
0
def test_normal_marginals(normal1):
    mean, var = normal1.marginals()
    approx(mean, normal1.mean.squeeze())
    approx(var, B.diag(normal1.var))
Пример #27
0
def test_normal_marginal_credible_bounds(normal1):
    mean, lower, upper = normal1.marginal_credible_bounds()
    approx(mean, normal1.mean.squeeze())
    approx(lower, normal1.mean.squeeze() - 1.96 * B.diag(normal1.var)**0.5)
    approx(upper, normal1.mean.squeeze() + 1.96 * B.diag(normal1.var)**0.5)
Пример #28
0
 def transform(x):
     log_diag = x[:side]
     chol = B.vec_to_tril(x[side:], offset=-1) + B.diag(B.exp(log_diag))
     return B.matmul(chol, chol, tr_b=True)