Exemplo n.º 1
0
def test_compatible():
    assert compatible(B.ones(5, 5), B.ones(5, 5))
    assert compatible(B.ones(5, 5), B.ones(5, 1))
    assert not compatible(B.ones(5, 5), B.ones(5))
    assert not compatible(B.ones(5, 5), B.ones(5, 4))

    with pytest.raises(AssertionError):
        assert_compatible(B.ones(5), B.ones(4))
Exemplo n.º 2
0
def test_lowertriangular_formatting():
    assert (str(LowerTriangular(B.ones(
        3, 3))) == "<lower-triangular matrix: shape=3x3, dtype=float64>")
    assert (repr(LowerTriangular(B.ones(
        3, 3))) == "<lower-triangular matrix: shape=3x3, dtype=float64\n"
            " mat=[[1. 1. 1.]\n"
            "      [1. 1. 1.]\n"
            "      [1. 1. 1.]]>")
Exemplo n.º 3
0
def test_normal_logpdf(normal1):
    normal1_sp = multivariate_normal(normal1.mean[:, 0], B.dense(normal1.var))
    x = B.randn(3, 10)
    approx(normal1.logpdf(x), normal1_sp.logpdf(x.T))

    # Test the the output of `logpdf` is flattened appropriately.
    assert B.shape(normal1.logpdf(B.ones(3, 1))) == ()
    assert B.shape(normal1.logpdf(B.ones(3, 2))) == (2, )
Exemplo n.º 4
0
def test_dense_formatting():
    assert str(Dense(B.ones(3, 3))) == "<dense matrix: shape=3x3, dtype=float64>"
    assert (
        repr(Dense(B.ones(3, 3))) == "<dense matrix: shape=3x3, dtype=float64\n"
        " mat=[[1. 1. 1.]\n"
        "      [1. 1. 1.]\n"
        "      [1. 1. 1.]]>"
    )
Exemplo n.º 5
0
def sum(a: Constant, axis=None):
    if axis is None:
        return a.const * a.rows * a.cols
    elif axis == 0:
        return a.const * a.rows * B.ones(B.dtype(a.const), a.cols)
    elif axis == 1:
        return a.const * a.cols * B.ones(B.dtype(a.const), a.rows)
    else:
        _raise(axis)
Exemplo n.º 6
0
def test_downrank(rank, preserve, shape, expected_shape, check_lazy_shapes):
    kw_args = {}
    if rank is not None:
        kw_args["rank"] = rank
    if preserve is not None:
        kw_args["preserve"] = preserve
    approx(
        B.downrank(B.ones(*shape), **kw_args),
        B.ones(*expected_shape),
    )
Exemplo n.º 7
0
def test_normal_lazy_nonzero_mean():
    dist = Normal(lambda: B.ones(3, 1), lambda: B.eye(3))
    # Nothing should be populated yet.
    assert dist._mean is None
    assert dist._var is None

    # But they should be populated upon request.
    approx(dist.mean, B.ones(3, 1))
    assert dist._var is None
    approx(dist.var, B.eye(3))
Exemplo n.º 8
0
def constant_to_lowrank(a):
    dtype = B.dtype(a)
    rows, cols = B.shape(a)
    middle = B.fill_diag(a.const, 1)
    if rows == cols:
        return LowRank(B.ones(dtype, rows, 1), middle=middle)
    else:
        return LowRank(B.ones(dtype, rows, 1),
                       B.ones(dtype, cols, 1),
                       middle=middle)
Exemplo n.º 9
0
def test_normal_lazy_nonzero_mean():
    dist = Normal(lambda: B.ones(3, 1), lambda: B.eye(3))

    assert not dist.mean_is_zero
    approx(dist._mean, B.ones(3, 1))
    assert dist._var is None

    approx(dist.mean, B.ones(3, 1))
    assert dist._var is None

    approx(dist.var, B.eye(3))
Exemplo n.º 10
0
def test_kronecker_formatting():
    left = Diagonal(B.ones(2))
    right = Diagonal(B.ones(3))
    assert (str(Kronecker(
        left, right)) == "<Kronecker product: shape=6x6, dtype=float64>")
    assert (repr(Kronecker(
        left, right)) == "<Kronecker product: shape=6x6, dtype=float64\n"
            " left=<diagonal matrix: shape=2x2, dtype=float64\n"
            "       diag=[1. 1.]>\n"
            " right=<diagonal matrix: shape=3x3, dtype=float64\n"
            "        diag=[1. 1. 1.]>>")
Exemplo n.º 11
0
def test_noise_as_matrix():
    def check(noise, dtype, n, asserted_type):
        noise = _noise_as_matrix(noise, dtype, n)
        assert isinstance(noise, asserted_type)
        assert B.dtype(noise) == dtype
        assert B.shape(noise) == (n, n)

    check(None, int, 5, matrix.Zero)
    check(None, float, 5, matrix.Zero)
    check(1, np.int64, 5, matrix.Diagonal)
    check(1.0, np.float64, 5, matrix.Diagonal)
    check(B.ones(int, 5), np.int64, 5, matrix.Diagonal)
    check(B.ones(float, 5), np.float64, 5, matrix.Diagonal)
    check(matrix.Dense(B.ones(int, 5, 5)), np.int64, 5, matrix.Dense)
    check(matrix.Dense(B.randn(float, 5, 5)), np.float64, 5, matrix.Dense)
Exemplo n.º 12
0
def test_woodbury_formatting():
    diag = Diagonal(B.ones(3))
    lr = LowRank(B.ones(3, 1), 2 * B.ones(3, 1))
    assert str(Woodbury(diag,
                        lr)) == "<Woodbury matrix: shape=3x3, dtype=float64>"
    assert (repr(Woodbury(
        diag, lr)) == "<Woodbury matrix: shape=3x3, dtype=float64\n"
            " diag=<diagonal matrix: shape=3x3, dtype=float64\n"
            "       diag=[1. 1. 1.]>\n"
            " lr=<low-rank matrix: shape=3x3, dtype=float64, rank=1\n"
            "     left=[[1.]\n"
            "           [1.]\n"
            "           [1.]]\n"
            "     right=[[2.]\n"
            "            [2.]\n"
            "            [2.]]>>")
Exemplo n.º 13
0
def test_logpdf_missing_data():
    # Setup model.
    m = 3
    noise = 1e-2
    latent_noises = 2e-2 * B.ones(m)
    kernels = [0.5 * EQ().stretch(0.75) for _ in range(m)]
    x = B.linspace(0, 10, 20)

    # Concatenate two orthogonal matrices, to make the missing data
    # approximation exact.
    u1 = B.svd(B.randn(m, m))[0]
    u2 = B.svd(B.randn(m, m))[0]
    u = Dense(B.concat(u1, u2, axis=0) / B.sqrt(2))

    s_sqrt = Diagonal(B.rand(m))

    # Construct a reference model.
    oilmm_pp = ILMMPP(kernels, u @ s_sqrt, noise, latent_noises)

    # Sample to generate test data.
    y = oilmm_pp.sample(x, latent=False)

    # Throw away data, but retain orthogonality.
    y[5:10, 3:] = np.nan
    y[10:, :3] = np.nan

    # Construct OILMM to test.
    oilmm = OILMM(kernels, u, s_sqrt, noise, latent_noises)

    # Check that evidence is still exact.
    approx(oilmm_pp.logpdf(x, y), oilmm.logpdf(x, y), atol=1e-7)
Exemplo n.º 14
0
def fill_diag(a: B.Numeric, diag_len: B.Int):
    """Fill the diagonal of a diagonal matrix with a particular scalar.

    Args:
        a (scalar): Scalar to fill diagonal with.
        diag_len (int): Length of diagonal.
    """
    return Diagonal(a * B.ones(B.dtype(a), diag_len))
Exemplo n.º 15
0
def test_noise_as_matrix():
    def check(noise, dtype, n, asserted_type):
        noise = _noise_as_matrix(noise, dtype, n)
        assert isinstance(noise, asserted_type)
        assert B.dtype(noise) == dtype
        assert B.shape(noise) == (n, n)

    # Check that the type for `n` is appropriate.
    for d in [5, Dimension(5)]:
        check(None, int, d, matrix.Zero)
        check(None, float, d, matrix.Zero)
        check(1, np.int64, d, matrix.Diagonal)
        check(1.0, np.float64, d, matrix.Diagonal)
        check(B.ones(int, 5), np.int64, d, matrix.Diagonal)
        check(B.ones(float, 5), np.float64, d, matrix.Diagonal)
        check(matrix.Dense(B.ones(int, 5, 5)), np.int64, d, matrix.Dense)
        check(matrix.Dense(B.randn(float, 5, 5)), np.float64, d, matrix.Dense)
Exemplo n.º 16
0
 def f(x, option=None):
     # Check that keyword arguments are passed on correctly. Only the compilation
     # with PyTorch does not pass on its keyword arguments.
     if not isinstance(x, B.TorchNumeric):
         assert option is not None
     # This requires lazy shapes:
     x = B.ones(B.dtype(x), *B.shape(x))
     # This requires control flow cache:
     return B.cond(x[0, 0] > 0, lambda: x[1], lambda: x[2])
Exemplo n.º 17
0
def matmul(a: AbstractMatrix, b: Constant, tr_a=False, tr_b=False):
    _assert_composable(a, b, tr_a=tr_a, tr_b=tr_b)
    a = _tr(a, tr_a)
    b = _tr(b, tr_b)
    return LowRank(
        B.expand_dims(B.sum(a, axis=1), axis=1),
        B.ones(B.dtype(b), b.cols, 1),
        B.fill_diag(b.const, 1),
    )
Exemplo n.º 18
0
def test_normal_lazy_var_diag():
    # If `var_diag` isn't set, the variance will be constructed to get the diagonal.
    dist = Normal(lambda: B.eye(3))
    approx(dist.var_diag, B.ones(3))
    approx(dist._var, B.eye(3))

    # If `var_diag` is set, the variance will _not_ be constructed to get the diagonal.
    dist = Normal(lambda: B.eye(3), var_diag=lambda: 9)
    approx(dist.var_diag, 9)
    assert dist._var is None
Exemplo n.º 19
0
    def _integrate_half2(self, name1, name2, **var_map):
        if self.poly.highest_power(name1) != 2 or self.poly.highest_power(
                name2) != 2:
            raise RuntimeError(f'Dependency on "{name1}" and {name2}" must '
                               f"be quadratic.")

        a11 = self.poly.collect_for(Factor(name1, 2))
        a22 = self.poly.collect_for(Factor(name2, 2))
        a12 = self.poly.collect_for(Factor(name1,
                                           1)).collect_for(Factor(name2, 1))
        b1 = self.poly.collect_for(Factor(name1, 1)).reject(name2)
        b2 = self.poly.collect_for(Factor(name2, 1)).reject(name1)
        c = self.poly.reject(name1).reject(name2)

        # Evaluate and scale A.
        a11 = -2 * a11.eval(**var_map)
        a22 = -2 * a22.eval(**var_map)
        a12 = -1 * a12.eval(**var_map)
        b1 = b1.eval(**var_map)
        b2 = b2.eval(**var_map)
        c = c.eval(**var_map)

        # Determinant of A:
        a_det = a11 * a22 - a12**2

        # Inverse of A, which corresponds to variance of distribution after
        # completing the square:
        ia11 = a22 / a_det
        ia12 = -a12 / a_det
        ia22 = a11 / a_det

        # Mean of distribution after completing the square:
        mu1 = ia11 * b1 + ia12 * b2
        mu2 = ia12 * b1 + ia22 * b2

        # Normalise and compute CDF part.
        x1 = -mu1 / safe_sqrt(ia11)
        x2 = -mu2 / safe_sqrt(ia22)
        rho = ia12 / safe_sqrt(ia11 * ia22)

        # Evaluate CDF for all `x1` and `x2`.
        orig_shape = B.shape(mu1)
        num = reduce(operator.mul, orig_shape, 1)
        x1 = B.reshape(x1, num)
        x2 = B.reshape(x2, num)
        rho = rho * B.ones(x1)
        cdf_part = B.reshape(B.bvn_cdf(x1, x2, rho), *orig_shape)

        # Compute exponentiated part.
        quad_form = 0.5 * (ia11 * b1**2 + ia22 * b2**2 + 2 * ia12 * b1 * b2)
        det_part = 2 * B.pi / safe_sqrt(a_det)
        exp_part = det_part * B.exp(quad_form + c)

        return self.const * cdf_part * exp_part
Exemplo n.º 20
0
def sample(model, t, noise_f):
    """Sample from a model.

    Args:
        model (:class:`gpcm.model.AbstractGPCM`): Model to sample from.
        t (vector): Time points to sample at.
        noise_f (vector): Noise for the sample of the function. Should have the
            same size as `t`.

    Returns:
        tuple[vector, ...]: Tuple containing kernel samples, filter samples, and
            function samples.
    """
    ks, us, fs = [], [], []

    # In the below, we look at the third inducing point, because that is the one
    # determining the value of the filter at zero: the CGPCM adds two extra inducing
    # points to the left.

    # Get a smooth sample.
    u1 = B.ones(model.n_u)
    while B.abs(u1[2]) > 1e-2:
        u1 = B.sample(model.compute_K_u())[:, 0]
    u = GP(model.k_h())
    u = u | (u(model.t_u), u1)
    u1_full = u(t).mean.flatten()

    # Get a rough sample.
    u2 = B.zeros(model.n_u)
    while u2[2] < 0.5:
        u2 = B.sample(model.compute_K_u())[:, 0]
    u = GP(model.k_h())
    u = u | (u(model.t_u), u2)
    u2_full = u(t).mean.flatten()

    with wbml.out.Progress(name="Sampling", total=5) as progress:
        for c in [0, 0.1, 0.23, 0.33, 0.5]:
            # Sample kernel.
            K = model.kernel_approx(t, t, c * u2 + (1 - c) * u1)
            wbml.out.kv("Sampled variance", K[0, 0])
            K = K / K[0, 0]
            ks.append(K[0, :])

            # Store filter.
            us.append(c * u2_full + (1 - c) * u1_full)

            # Sample function.
            f = B.matmul(B.chol(closest_psd(K)), noise_f)
            fs.append(f)

            progress()

    return ks, us, fs
Exemplo n.º 21
0
def test_dtype_kron_promotion():
    kron = Kronecker(B.ones(int, 5, 5), B.ones(int, 5, 5))
    assert B.dtype(kron) == np.int64
    kron = Kronecker(B.ones(float, 5, 5), B.ones(int, 5, 5))
    assert B.dtype(kron) == np.float64
    kron = Kronecker(B.ones(int, 5, 5), B.ones(float, 5, 5))
    assert B.dtype(kron) == np.float64
Exemplo n.º 22
0
def test_dtype_wb_promotion():
    wb = LowRank(B.ones(int, 5, 5)) + Diagonal(B.ones(int, 5))
    assert B.dtype(wb) == np.int64
    wb = LowRank(B.ones(float, 5, 5)) + Diagonal(B.ones(int, 5))
    assert B.dtype(wb) == np.float64
    wb = LowRank(B.ones(int, 5, 5)) + Diagonal(B.ones(float, 5))
    assert B.dtype(wb) == np.float64
Exemplo n.º 23
0
def test_broadcast():
    s = Shape(Dimension(5), Dimension(4))
    assert broadcast(B.ones(5, 4), B.ones(5, 4)) == s
    assert broadcast(B.ones(5, 4), B.ones(5, 1)) == s

    with pytest.raises(AssertionError):
        broadcast(B.ones(5, 5), B.ones(5, 4))
    with pytest.raises(RuntimeError):
        broadcast(Dimension(5), Dimension(4))
Exemplo n.º 24
0
def test_normal_lazy_mean_var():
    # The lazy `mean_var` should only be called when neither the mean nor the variance
    # exists. Otherwise, it's more efficient to just construct the other one. We
    # go over all branches in the `if`-statement.

    dist = Normal(lambda: B.ones(3, 1), lambda: B.eye(3), mean_var=lambda: (8, 9))
    approx(dist.mean_var, (8, 9))
    approx(dist.mean, 8)
    approx(dist.var, 9)

    dist = Normal(lambda: B.ones(3, 1), lambda: B.eye(3), mean_var=lambda: (8, 9))
    approx(dist.mean, B.ones(3, 1))
    approx(dist.mean_var, (B.ones(3, 1), B.eye(3)))
    approx(dist.var, B.eye(3))

    dist = Normal(lambda: B.ones(3, 1), lambda: B.eye(3), mean_var=lambda: (8, 9))
    approx(dist.var, B.eye(3))
    approx(dist.mean_var, (B.ones(3, 1), B.eye(3)))
    approx(dist.mean, B.ones(3, 1))

    dist = Normal(lambda: B.ones(3, 1), lambda: B.eye(3), mean_var=lambda: (8, 9))
    approx(dist.var, B.eye(3))
    approx(dist.mean, B.ones(3, 1))
    approx(dist.mean_var, (B.ones(3, 1), B.eye(3)))
Exemplo n.º 25
0
def test_normalise():
    layer = Normalise(epsilon=0)
    x = B.randn(10, 5, 3)

    # Check number of weights and width.
    assert layer.num_weights(10) == 0
    assert layer.width == 10

    # Check initialisation and width.
    layer.initialise(3, None)
    assert layer.width == 3

    # Check correctness
    out = layer(x)
    approx(B.std(out, axis=2), B.ones(10, 5), rtol=1e-4)
    approx(B.mean(out, axis=2), B.zeros(10, 5), atol=1e-4)
Exemplo n.º 26
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
Exemplo n.º 27
0
def test_expand_dims(check_lazy_shapes):
    check_function(B.expand_dims, (Tensor(3, 4, 5),), {"axis": Value(0, 1)})

    # Test keyword `times`.
    assert B.shape(B.expand_dims(B.ones(2), axis=-1, times=1)) == (2, 1)
    assert B.shape(B.expand_dims(B.ones(2), axis=-1, times=2)) == (2, 1, 1)
    assert B.shape(B.expand_dims(B.ones(2), axis=-1, times=3)) == (2, 1, 1, 1)
    assert B.shape(B.expand_dims(B.ones(2), axis=0, times=1)) == (1, 2)
    assert B.shape(B.expand_dims(B.ones(2), axis=0, times=2)) == (1, 1, 2)
    assert B.shape(B.expand_dims(B.ones(2), axis=0, times=3)) == (1, 1, 1, 2)

    # Test keyword `ignore_scalar`.
    assert B.expand_dims(1, axis=-1, ignore_scalar=False) is not 1
    assert B.expand_dims(1, axis=-1, ignore_scalar=True) is 1
Exemplo n.º 28
0
def test_lowrank_formatting():
    assert (str(LowRank(B.ones(3, 1), 2 * B.ones(
        3, 1))) == "<low-rank matrix: shape=3x3, dtype=float64, rank=1>")
    assert (repr(LowRank(B.ones(3, 2), 2 * B.ones(
        3, 2))) == "<low-rank matrix: shape=3x3, dtype=float64, rank=2\n"
            " left=[[1. 1.]\n"
            "       [1. 1.]\n"
            "       [1. 1.]]\n"
            " right=[[2. 2.]\n"
            "        [2. 2.]\n"
            "        [2. 2.]]>")
    assert (repr(LowRank(B.ones(
        3, 2))) == "<low-rank matrix: shape=3x3, dtype=float64, rank=2\n"
            " left=[[1. 1.]\n"
            "       [1. 1.]\n"
            "       [1. 1.]]>")
    assert (repr(LowRank(B.ones(3, 2), middle=B.ones(
        2, 2))) == "<low-rank matrix: shape=3x3, dtype=float64, rank=2\n"
            " left=[[1. 1.]\n"
            "       [1. 1.]\n"
            "       [1. 1.]]\n"
            " middle=[[1. 1.]\n"
            "         [1. 1.]]>")
Exemplo n.º 29
0
def test_lowrank_shape_checks():
    # Check that matrices must be given.
    with pytest.raises(AssertionError):
        LowRank(B.ones(3))
    with pytest.raises(AssertionError):
        LowRank(B.ones(3, 1), B.ones(3))
    with pytest.raises(AssertionError):
        LowRank(B.ones(3, 1), B.ones(3, 1), B.ones(1))

    # Check that needs need to be compatible
    with pytest.raises(AssertionError):
        LowRank(B.ones(3, 1), B.ones(3, 2))
    with pytest.raises(AssertionError):
        LowRank(B.ones(3, 1), B.ones(3, 2), B.ones(1, 1))
    with pytest.raises(AssertionError):
        LowRank(B.ones(3, 1), middle=B.ones(2, 1))
Exemplo n.º 30
0
def test_lowrank_attributes():
    # Check default right and middle factor.
    left = B.ones(3, 2)
    lr = LowRank(left)
    assert lr.left is left
    assert lr.right is left
    approx(lr.middle, B.eye(2))
    assert lr.rank == 2

    # Check given identical right.
    lr = LowRank(left, left)
    assert lr.left is left
    assert lr.right is left
    approx(lr.middle, B.eye(2))
    assert lr.rank == 2

    # Check given identical right and middle.
    middle = B.ones(2, 2)
    lr = LowRank(left, left, middle=middle)
    assert lr.left is left
    assert lr.right is left
    approx(lr.middle, B.ones(2, 2))
    assert lr.rank == 2

    # Check given other right and middle factor.
    right = 2 * B.ones(3, 2)
    lr = LowRank(left, right, middle=middle)
    assert lr.left is left
    assert lr.right is right
    approx(lr.middle, B.ones(2, 2))
    assert lr.rank == 2

    # Check rank in non-square case.
    assert LowRank(B.ones(3, 2), B.ones(3, 2), B.ones(2, 2)).rank == 2
    assert LowRank(B.ones(3, 2), B.ones(3, 1), B.ones(2, 1)).rank == 1