Пример #1
0
def test_selection():
    # Test construction:
    p = GP(lambda x: x**2, EQ())
    assert str(p.select(1)) == "GP(<lambda> : [1], EQ() : [1])"
    assert str(p.select(1, 2)) == "GP(<lambda> : [1, 2], EQ() : [1, 2])"

    # Test case:
    # `p` is 1D.
    p2 = p.select(0)  # `p2` is 2D.

    x = B.linspace(0, 5, 10)
    x21 = B.stack(x, B.randn(10), axis=1)
    x22 = B.stack(x, B.randn(10), axis=1)
    y = p2(x).sample()

    post = p.measure | (p2(x21), y)
    approx(post(p(x)).mean, y)
    assert_equal_normals(post(p(x)), post(p2(x21)))

    post = p.measure | (p2(x22), y)
    approx(post(p(x)).mean, y)
    assert_equal_normals(post(p(x)), post(p2(x22)))

    post = p.measure | (p(x), y)
    approx(post(p2(x21)).mean, y)
    approx(post(p2(x22)).mean, y)
    assert_equal_normals(post(p2(x21)), post(p(x)))
    assert_equal_normals(post(p2(x22)), post(p(x)))
Пример #2
0
def test_manual_new_gp():
    m = Measure()
    p1 = GP(1, EQ(), measure=m)
    p2 = GP(2, EQ(), measure=m)
    p_sum = p1 + p2

    p1_equivalent = m.add_gp(
        m.means[p_sum] - m.means[p2],
        (m.kernels[p_sum] + m.kernels[p2] - m.kernels[p_sum, p2] -
         m.kernels[p2, p_sum]),
        lambda j: m.kernels[p_sum, j] - m.kernels[p2, j],
    )

    x = B.linspace(0, 10, 5)
    s1, s2 = m.sample(p1(x), p1_equivalent(x))
    approx(s1, s2, atol=1e-4)
Пример #3
0
def test_logpdf(PseudoObs):
    m = Measure()
    p1 = GP(1, EQ(), measure=m)
    p2 = GP(2, Exp(), measure=m)
    p3 = p1 + p2

    x1 = B.linspace(0, 2, 5)
    x2 = B.linspace(1, 3, 6)
    x3 = B.linspace(2, 4, 7)
    y1, y2, y3 = m.sample(p1(x1), p2(x2), p3(x3))

    # Test case that only one process is fed.
    approx(p1(x1).logpdf(y1), m.logpdf(p1(x1), y1))
    approx(p1(x1).logpdf(y1), m.logpdf((p1(x1), y1)))

    # Compute the logpdf with the product rule.
    d1 = m
    d2 = d1 | (p1(x1), y1)
    d3 = d2 | (p2(x2), y2)
    approx(
        d1(p1)(x1).logpdf(y1) + d2(p2)(x2).logpdf(y2) + d3(p3)(x3).logpdf(y3),
        m.logpdf((p1(x1), y1), (p2(x2), y2), (p3(x3), y3)),
    )

    # Check that `Measure.logpdf` allows `Obs` and `PseudoObs`.
    obs = Obs(p3(x3), y3)
    approx(m.logpdf(obs), p3(x3).logpdf(y3))
    obs = PseudoObs(p3(x3), p3(x3, 1), y3)
    approx(m.logpdf(obs), p3(x3, 1).logpdf(y3))
Пример #4
0
def test_conditioning_missing_data():
    p = GP(1, EQ())
    x = B.linspace(0, 5, 10)
    y = p(x).sample()
    y[:3] = B.nan
    post1 = p | (p(x), y)
    post2 = p | (p(x[3:]), y[3:])
    assert_equal_normals(post1(x), post2(x))
Пример #5
0
def test_sample_correct_measure():
    m = Measure()
    p1 = GP(1, EQ(), measure=m)

    post = m | (p1(0), 1)

    # Test that `post.sample` indeed samples under `post`.
    approx(post.sample(10, p1(0)), B.ones(1, 10), atol=1e-4)
Пример #6
0
def test_fd_derivative():
    x = B.linspace(0, 10, 50)
    y = np.sin(x)

    p = GP(0.7 * EQ().stretch(1.0))
    dp = (p.shift(-1e-3) - p.shift(1e-3)) / 2e-3

    post = p.measure | (p(x), y)
    approx(post(dp)(x).mean, np.cos(x)[:, None], atol=1e-4)
Пример #7
0
def test_stationarity():
    m = Measure()

    p1 = GP(EQ(), measure=m)
    p2 = GP(EQ().stretch(2), measure=m)
    p3 = GP(EQ().periodic(10), measure=m)

    p = p1 + 2 * p2

    assert p.stationary

    p = p3 + p

    assert p.stationary

    p = p + GP(Linear(), measure=m)

    assert not p.stationary
Пример #8
0
def test_mo_batched():
    x = B.randn(16, 10, 1)

    with Measure():
        p = cross(GP(1, 2 * EQ().stretch(0.5)), GP(2, 2 * EQ().stretch(0.5)))
    y = p(x).sample()
    logpdf = p(x, 0.1).logpdf(y)

    assert B.shape(logpdf) == (16, )
    assert B.shape(y) == (16, 20, 1)

    p = p | (p(x), y)
    y2 = p(x).sample()
    logpdf2 = p(x, 0.1).logpdf(y)

    assert B.shape(y2) == (16, 20, 1)
    assert B.shape(logpdf2) == (16, )
    assert B.all(logpdf2 > logpdf)
    approx(y, y2, atol=1e-5)
Пример #9
0
def test_conditioning_empty_observations(shape):
    p = GP(1, EQ())

    x = B.randn(*shape)
    y = p(x).sample()

    # Conditioning should just return the prior exactly.
    p_post = p | (p(x), y)
    assert p_post.mean is p.mean
    assert p_post.kernel is p.kernel
Пример #10
0
def test_marginal_credible_bounds_efficiency():
    p = GP(EQ())
    x = B.linspace(0, 5, 5)
    y = p(x, 0.1).sample()
    p = p | (p(x, 0.1), y)

    # Check that the computation at 10_000 points takes at most one second.
    x = B.linspace(0, 5, 10_000)
    start = time()
    p(x, 0.2).marginal_credible_bounds()
    assert time() - start < 1
Пример #11
0
def test_summation_with_itself():
    p = GP(EQ())
    p_many = p + p + p + p + p

    x = B.linspace(0, 10, 5)
    approx(p_many(x).var, 25 * p(x).var)
    approx(p_many(x).mean, B.zeros(5, 1))

    y = B.randn(5, 1)
    post = p.measure | (p(x), y)
    approx(post(p_many)(x).mean, 5 * y)
Пример #12
0
def test_corner_cases():
    p1 = GP(EQ())
    p2 = GP(EQ())
    x = B.randn(10, 2)

    # Test check for measure group.
    with pytest.raises(AssertionError):
        p1 + p2
    with pytest.raises(AssertionError):
        p1 * p2

    # Test incompatible operations.
    with pytest.raises(NotFoundLookupError):
        p1 + p1(x)
    with pytest.raises(NotFoundLookupError):
        p1 * p1(x)

    # Check test for prior.
    with pytest.raises(RuntimeError):
        GP().measure
Пример #13
0
def test_approximate_multiplication():
    m = Measure()
    p1 = GP(20, EQ(), measure=m)
    p2 = GP(20, EQ(), measure=m)
    p_prod = p1 * p2

    # Sample functions.
    x = B.linspace(0, 10, 50)
    s1, s2 = m.sample(p1(x), p2(x))

    # Perform product.
    post = m | ((p1(x), s1), (p2(x), s2))
    approx(post(p_prod)(x).mean, s1 * s2, rtol=1e-2)

    # Perform division.
    cur_epsilon = B.epsilon
    B.epsilon = 1e-8
    post = m | ((p1(x), s1), (p_prod(x), s1 * s2))
    approx(post(p2)(x).mean, s2, rtol=1e-2)
    B.epsilon = cur_epsilon
Пример #14
0
def test_naming():
    m = Measure()

    p1 = GP(EQ(), 1, measure=m)
    p2 = GP(EQ(), 2, measure=m)

    # Test setting and getting names.
    p1.name = "name"

    assert m["name"] is p1
    assert p1.name == "name"
    assert m[p1] == "name"
    with pytest.raises(KeyError):
        m["other_name"]
    with pytest.raises(KeyError):
        m[p2]

    # Check that names can not be doubly assigned.
    def doubly_assign():
        p2.name = "name"

    with pytest.raises(RuntimeError):
        doubly_assign()

    # Move name to other GP.
    p1.name = "other_name"
    p2.name = "name"

    # Check that everything has been properly assigned.
    assert m["name"] is p2
    assert p2.name == "name"
    assert m[p2] == "name"
    assert m["other_name"] is p1
    assert p1.name == "other_name"
    assert m[p1] == "other_name"

    # Test giving a name to the constructor.
    p3 = GP(EQ(), name="yet_another_name", measure=m)
    assert m["yet_another_name"] is p3
    assert p3.name == "yet_another_name"
    assert m[p3] == "yet_another_name"
Пример #15
0
def test_negation():
    p = GP(EQ())
    p2 = -p

    x = B.linspace(0, 5, 10)
    y = p(x).sample()

    post = p.measure | (p(x), y)
    approx(post(p2)(x).mean, -y)

    post = p.measure | (p2(x), -y)
    approx(post(p)(x).mean, y)
Пример #16
0
def test_mom():
    x = B.linspace(0, 1, 10)

    prior = Measure()
    p1 = GP(lambda x: 2 * x, 1 * EQ(), measure=prior)
    p2 = GP(1, 2 * EQ().stretch(2), measure=prior)

    m = MultiOutputMean(prior, p1, p2)
    ms = prior.means

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

    # Check representation.
    assert str(m) == "MultiOutputMean(<lambda>, 1)"

    # Check computation.
    approx(m(x), B.concat(ms[p1](x), ms[p2](x), axis=0))
    approx(m(p1(x)), ms[p1](x))
    approx(m(p2(x)), ms[p2](x))
    approx(m((p2(x), p1(x))), B.concat(ms[p2](x), ms[p1](x), axis=0))
Пример #17
0
def test_reflection():
    p = GP(1, EQ())
    p2 = 5 - p

    x = B.linspace(0, 5, 10)
    y = p(x).sample()

    post = p.measure | (p(x), y)
    approx(post(p2)(x).mean, 5 - y)

    post = p.measure | (p2(x), 5 - y)
    approx(post(p)(x).mean, y)
Пример #18
0
    def k_h(self):
        """Get the kernel function of the filter.

        Returns:
            :class:`mlkernels.Kernel`: Kernel for :math:`h`.
        """
        # Convert `self.gamma` to a regular length scale.
        gamma_scale = B.sqrt(1 / (2 * self.gamma))
        k_h = EQ().stretch(gamma_scale)  # Kernel of filter before window
        k_h *= lambda t: B.exp(-self.alpha * t**2)  # Window
        if self.causal:
            k_h *= lambda t: B.cast(self.dtype, t >= 0)  # Causality constraint
        return k_h
Пример #19
0
def test_derivative():
    # Test construction:
    p = GP(TensorProductMean(lambda x: x**2), EQ())
    assert str(p.diff(1)) == "GP(d(1) <lambda>, d(1) EQ())"

    # Test case:
    p = GP(EQ())
    dp = p.diff()

    x = B.linspace(tf.float64, 0, 1, 100)
    y = 2 * x

    x_check = B.linspace(tf.float64, 0.2, 0.8, 100)

    # Test conditioning on function.
    post = p.measure | (p(x), y)
    approx(post(dp)(x_check).mean, 2 * B.ones(100, 1), atol=1e-4)

    # Test conditioning on derivative.
    zero = B.cast(tf.float64, 0)
    post = p.measure | ((p(zero), zero), (dp(x), y))
    approx(post(p)(x_check).mean, x_check[:, None]**2, atol=1e-4)
Пример #20
0
def test_measure_groups():
    prior = Measure()
    f1 = GP(EQ(), measure=prior)
    f2 = GP(EQ(), measure=prior)

    assert f1._measures == f2._measures

    x = B.linspace(0, 5, 10)
    y = f1(x).sample()

    post = prior | (f1(x), y)

    assert f1._measures == f2._measures == [prior, post]

    # Further extend the prior.

    f_sum = f1 + f2
    assert f_sum._measures == [prior, post]

    f3 = GP(EQ(), measure=prior)
    f_sum = f1 + f3
    assert f3._measures == f_sum._measures == [prior]

    with pytest.raises(AssertionError):
        post(f1) + f3

    # Extend the posterior.

    f_sum = post(f1) + post(f2)
    assert f_sum._measures == [post]

    f3 = GP(EQ(), measure=post)
    f_sum = post(f1) + f3
    assert f3._measures == f_sum._measures == [post]

    with pytest.raises(AssertionError):
        f1 + f3
Пример #21
0
def test_construction():
    p = GP(EQ())

    x = B.randn(10, 1)

    p.mean(x)

    p.kernel(x)
    p.kernel(x, x)

    p.kernel.elwise(x)
    p.kernel.elwise(x, x)

    # Test resolution of kernel and mean.
    k = EQ()
    m = TensorProductMean(lambda x: x ** 2)

    assert isinstance(GP(k).mean, ZeroMean)
    assert isinstance(GP(5, k).mean, ScaledMean)
    assert isinstance(GP(1, k).mean, OneMean)
    assert isinstance(GP(0, k).mean, ZeroMean)
    assert isinstance(GP(m, k).mean, TensorProductMean)
    assert isinstance(GP(k).kernel, EQ)
    assert isinstance(GP(5).kernel, ScaledKernel)
    assert isinstance(GP(1).kernel, OneKernel)
    assert isinstance(GP(0).kernel, ZeroKernel)

    # Test construction of finite-dimensional distribution without noise.
    d = GP(m, k)(x)
    approx(d.var, k(x))
    approx(d.mean, m(x))

    # Test construction of finite-dimensional distribution with noise.
    d = GP(m, k)(x, 1)
    approx(d.var, k(x) + B.eye(k(x)))
    approx(d.mean, m(x))
Пример #22
0
def test_conditioning_consistency():
    m = Measure()
    p = GP(EQ(), measure=m)
    e = GP(0.1 * Delta(), measure=m)
    e2 = GP(e.kernel, measure=m)

    x = B.linspace(0, 5, 10)
    y = (p + e)(x).sample()

    post1 = m | ((p + e)(x), y)
    post2 = m | (p(x, 0.1), y)

    assert_equal_measures([p(x), (p + e2)(x)], post1, post2)
    with pytest.raises(AssertionError):
        assert_equal_normals(post1((p + e)(x)), post2((p + e)(x)))
Пример #23
0
def test_shifting():
    # Test construction:
    p = GP(TensorProductMean(lambda x: x**2), Linear())
    assert str(p.shift(1)) == "GP(<lambda> shift 1, Linear() shift 1)"

    # Test case:
    p = GP(EQ())
    p_shifted = p.shift(5)

    x = B.linspace(0, 5, 10)
    y = p_shifted(x).sample()

    post = p.measure | (p_shifted(x), y)
    assert_equal_normals(post(p(x - 5)), post(p_shifted(x)))
    assert_equal_normals(post(p(x)), post(p_shifted(x + 5)))
Пример #24
0
def test_conditioning(generate_noise_tuple):
    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(Exp(), measure=m)
    p_sum = p1 + p2

    # Sample some data to condition on.
    x1 = B.linspace(0, 2, 3)
    n1 = generate_noise_tuple(x1)
    y1 = p1(x1, *n1).sample()
    tup1 = (p1(x1, *n1), y1)
    x_sum = B.linspace(3, 5, 3)
    n_sum = generate_noise_tuple(x_sum)
    y_sum = p_sum(x_sum, *n_sum).sample()
    tup_sum = (p_sum(x_sum, *n_sum), y_sum)

    # Determine FDDs to check.
    x_check = B.linspace(0, 5, 5)
    fdds_check = [
        cross(p1, p2, p_sum)(x_check),
        p1(x_check),
        p2(x_check),
        p_sum(x_check),
    ]

    assert_equal_measures(
        fdds_check,
        m.condition(*tup_sum),
        m.condition(tup_sum),
        m | tup_sum,
        m | (tup_sum, ),
        m | Obs(*tup_sum),
        m | Obs(tup_sum),
    )

    assert_equal_measures(
        fdds_check,
        m.condition(tup1, tup_sum),
        m | (tup1, tup_sum),
        m | Obs(tup1, tup_sum),
    )

    # Check that conditioning gives an FDD and that it is consistent.
    post = m | tup1
    assert isinstance(post(p1(x1, 0.1)), FDD)
    assert_equal_measures(post(p1(x1, 0.1)), post(p1)(x1, 0.1))
Пример #25
0
def test_fdd():
    p = GP(1, EQ())

    # Test specification without noise.
    for fdd in [p(1), FDD(p, 1)]:
        assert isinstance(fdd, FDD)
        assert identical(fdd.x, 1)
        assert fdd.p is p
        assert isinstance(fdd.noise, matrix.Zero)
        rep = ("<FDD:\n"
               " process=GP(1, EQ()),\n"
               " input=1,\n"
               " noise=<zero matrix: batch=(), shape=(1, 1), dtype=int>>")
        assert str(fdd) == rep
        assert repr(fdd) == rep

        # Check `dtype` and `num_elements`.
        assert B.dtype(fdd) == int
        assert num_elements(fdd) == 1

    # Test specification with noise.
    fdd = p(1.0, np.array([1, 2]))
    assert isinstance(fdd, FDD)
    assert identical(fdd.x, 1.0)
    assert fdd.p is p
    assert isinstance(fdd.noise, matrix.Diagonal)
    assert str(fdd) == (
        "<FDD:\n"
        " process=GP(1, EQ()),\n"
        " input=1.0,\n"
        " noise=<diagonal matrix: batch=(), shape=(2, 2), dtype=int64>>")
    assert repr(fdd) == (
        "<FDD:\n"
        " process=GP(1, EQ()),\n"
        " input=1.0,\n"
        " noise=<diagonal matrix: batch=(), shape=(2, 2), dtype=int64\n"
        "        diag=[1 2]>>")
    assert B.dtype(fdd) == float
    assert num_elements(fdd) == 1

    # Test construction with `id`.
    fdd = FDD(5, 1)
    assert fdd.p is 5
    assert identical(fdd.x, 1)
    assert fdd.noise is None
Пример #26
0
def test_conditioning_shorthand():
    p = GP(EQ())

    # Test conditioning once.
    x = B.linspace(0, 5, 10)
    y = p(x).sample()
    p_post1 = p.condition(p(x), y)
    p_post2 = p | (p(x), y)
    approx(p_post1.mean(x), y)
    approx(p_post2.mean(x), y)

    # Test conditioning twice.
    x = B.linspace(10, 20, 10)
    y = p(x).sample()
    p_post1 = p_post1.condition(p(x), y)
    p_post2 = p_post2 | (p(x), y)
    approx(p_post1.mean(x), y)
    approx(p_post2.mean(x), y)
Пример #27
0
def test_approximate_derivative():
    p = GP(EQ().stretch(1.0))
    dp = p.diff_approx()

    x = B.linspace(0, 1, 100)
    y = 2 * x

    x_check = B.linspace(0.2, 0.8, 100)

    # Test conditioning on function.
    post = p.measure | (p(x), y)
    approx(post(dp)(x_check).mean, 2 * B.ones(100, 1), atol=1e-3)

    # Test conditioning on derivative.
    orig_epsilon = B.epsilon
    B.epsilon = 1e-10
    post = p.measure | ((p(0), 0), (dp(x), y))
    approx(post(p)(x_check).mean, x_check[:, None]**2, atol=1e-3)
    B.epsilon = orig_epsilon
Пример #28
0
def test_batched():
    x1 = B.randn(16, 10, 1)
    x2 = B.randn(16, 5, 1)

    p = GP(1, 2 * EQ().stretch(0.5))
    y1, y2 = p.measure.sample(p(x1), p(x2))
    logpdf = p.measure.logpdf((p(x1, 0.1), y1), (p(x2, 0.1), y2))

    assert B.shape(y1) == (16, 10, 1)
    assert B.shape(y2) == (16, 5, 1)
    assert B.shape(logpdf) == (16, )

    p = p | ((p(x1), y1), (p(x2), y2))
    y1_2, y2_2 = p.measure.sample(p(x1), p(x2))
    logpdf2 = p.measure.logpdf((p(x1, 0.1), y1), (p(x2, 0.1), y2))

    assert B.shape(y1_2) == (16, 10, 1)
    assert B.shape(y2_2) == (16, 5, 1)
    approx(y1, y1_2, atol=1e-5)
    approx(y2, y2_2, atol=1e-5)
    assert B.shape(logpdf2) == (16, )
    assert B.all(logpdf2 > logpdf)
Пример #29
0
def test_marginals():
    p = GP(lambda x: x**2, EQ())
    x = B.linspace(0, 5, 10)

    # Check that `marginals` outputs the right thing.
    mean, var = p(x).marginals()
    approx(mean, p.mean(x)[:, 0])
    approx(var, B.diag(p.kernel(x)))

    # Test correctness.
    y = p(x).sample()
    post = p.measure | (p(x), y)

    # Concentration on data:
    mean, var = post(p)(x).marginals()
    approx(mean, y[:, 0])
    approx(var, B.zeros(10), atol=1e-5)

    # Reversion to prior:
    mean, var = post(p)(x + 100).marginals()
    approx(mean, p.mean(x + 100)[:, 0])
    approx(var, B.diag(p.kernel(x + 100)))
Пример #30
0
def test_fdd_take():
    with Measure():
        f1 = GP(1, EQ())
        f2 = GP(2, Exp())
        f = cross(f1, f2)

    x = B.linspace(0, 3, 5)
    # Build an FDD with a very complicated input specification.
    fdd = f((x, (f2(x), x), f1(x), (f2(x), (f1(x), x))))
    n = infer_size(fdd.p.kernel, fdd.x)
    fdd = f(fdd.x, matrix.Diagonal(B.rand(n)))

    # Flip a coin for every element.
    mask = B.randn(n) > 0
    taken_fdd = B.take(fdd, mask)

    approx(taken_fdd.mean, B.take(fdd.mean, mask))
    approx(taken_fdd.var, B.submatrix(fdd.var, mask))
    approx(taken_fdd.noise, B.submatrix(fdd.noise, mask))
    assert isinstance(taken_fdd.noise, matrix.Diagonal)

    # Test that only masks are supported, for now.
    with pytest.raises(AssertionError):
        B.take(fdd, np.array([1, 2]))