def test_momean(): m = Graph() p1 = GP(1 * EQ(), lambda x: 2 * x, graph=m) p2 = GP(2 * EQ().stretch(2), 1, graph=m) mom = MultiOutputMean(p1, p2) ms = m.means x = np.linspace(0, 1, 10) yield eq, str(mom), 'MultiOutputMean(<lambda>, 1)' yield assert_allclose, mom(x), \ np.concatenate([ms[p1](x), ms[p2](x)], axis=0) yield assert_allclose, mom(p1(x)), ms[p1](x) yield assert_allclose, mom(p2(x)), ms[p2](x) yield assert_allclose, mom(MultiInput(p2(x), p1(x))), \ np.concatenate([ms[p2](x), ms[p1](x)], axis=0)
def test_case_fd_derivative(): x = np.linspace(0, 10, 50)[:, None] y = np.sin(x) model = Graph() p = GP(.7 * EQ().stretch(1.), graph=model) dp = (p.shift(-1e-3) - p.shift(1e-3)) / 2e-3 yield le, abs_err(np.cos(x) - dp.condition(p(x), y)(x).mean), 1e-4
def test_cache_performance(): c = Cache() k1 = EQ() k2 = EQ() x = np.linspace(0, 1, 2000) dur1, y1 = benchmark(k1, (x, c), n=1, get_output=True) dur2, y2 = benchmark(k1, (x, c), n=1, get_output=True) dur3, y3 = benchmark(k2, (x, c), n=1, get_output=True) yield assert_allclose, y1, y2 yield assert_allclose, y1, y3 # Test performance of call cache. yield le, dur2, dur1 / 500 # Test performance of LAB cache. yield le, dur3, dur1 / 20
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
def test_properties(): model = Graph() p1 = GP(EQ(), graph=model) p2 = GP(EQ().stretch(2), graph=model) p3 = GP(EQ().periodic(10), graph=model) p = p1 + 2 * p2 assert p.stationary == True p = p3 + p assert p.stationary == True p = p + GP(Linear(), graph=model) assert p.stationary == False
def test_posterior_kernel(): k = PosteriorKernel( EQ(), EQ(), EQ(), np.random.randn(5, 2), matrix(EQ()(np.random.randn(5, 1))) ) # Verify that the kernel has the right properties. assert not k.stationary with pytest.raises(RuntimeError): k.var with pytest.raises(RuntimeError): k.length_scale with pytest.raises(RuntimeError): k.period assert str(k) == 'PosteriorKernel()' # Standard tests: standard_kernel_tests(k, shapes=[((10, 2), (5, 2))])
def test_factors(): k = EQ() * Linear() assert k.num_factors == 2 assert str(k.factor(0)) == 'EQ()' assert str(k.factor(1)) == 'Linear()' with pytest.raises(IndexError): k.factor(2) k = (EQ() + EQ()) * Delta() * (RQ(1) + Linear()) assert k.num_factors == 4 assert str(k.factor(0)) == '2' assert str(k.factor(1)) == 'EQ()' assert str(k.factor(2)) == 'Delta()' assert str(k.factor(3)) == 'RQ(1) + Linear()' with pytest.raises(IndexError): k.factor(4) with pytest.raises(IndexError): EQ().factor(1)
def test_case_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)
def test_corrective_kernel(): a, b = np.random.randn(3, 3), np.random.randn(3, 3) a, b = a.dot(a.T), b.dot(b.T) z = np.random.randn(3, 2) k = CorrectiveKernel(EQ(), EQ(), z, a, matrix(b)) # Verify that the kernel has the right properties. assert not k.stationary with pytest.raises(RuntimeError): k.var with pytest.raises(RuntimeError): k.length_scale with pytest.raises(RuntimeError): k.period assert str(k) == 'CorrectiveKernel()' # Standard tests: standard_kernel_tests(k, shapes=[((10, 2), (5, 2))])
def test_reversal(): x1 = np.random.randn(10, 2) x2 = np.random.randn(5, 2) x3 = np.random.randn() # Test with a stationary and non-stationary kernel. for k in [EQ(), Linear()]: allclose(k(x1), reversed(k)(x1)) allclose(k(x3), reversed(k)(x3)) allclose(k(x1, x2), reversed(k)(x1, x2)) allclose(k(x1, x2), reversed(k)(x2, x1).T) # Test double reversal does the right thing. allclose(k(x1), reversed(reversed(k))(x1)) allclose(k(x3), reversed(reversed(k))(x3)) allclose(k(x1, x2), reversed(reversed(k))(x1, x2)) allclose(k(x1, x2), reversed(reversed(k))(x2, x1).T) # Verify that the kernel has the right properties. k = reversed(EQ()) assert k.stationary assert k.var == 1 assert k.length_scale == 1 assert k.period == np.inf k = reversed(Linear()) assert not k.stationary with pytest.raises(RuntimeError): k.var with pytest.raises(RuntimeError): k.length_scale assert k.period == np.inf assert str(k) == 'Reversed(Linear())' # Check equality. assert reversed(Linear()) == reversed(Linear()) assert reversed(Linear()) != Linear() assert reversed(Linear()) != reversed(EQ()) assert reversed(Linear()) != reversed(DecayingKernel(1, 1)) # Standard tests: standard_kernel_tests(k)
def test_case_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)
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
def test_derivative(): # Test construction: p = GP(EQ(), TensorProductMean(lambda x: x ** 2), graph=Graph()) assert str(p.diff(1)) == 'GP(d(1) EQ(), d(1) <lambda>)' # Test case: model = Graph() x = B.linspace(tf.float64, 0, 1, 100)[:, None] y = 2 * x p = GP(EQ(), graph=model) dp = p.diff() # Test conditioning on function. assert abs_err(dp.condition(p(x), y)(x).mean, 2) <= 1e-3 # Test conditioning on derivative. post = p.condition((B.cast(tf.float64, 0), B.cast(tf.float64, 0)), (dp(x), y)) assert abs_err(post(x).mean, x ** 2) <= 1e-3
def test_case_reflection(): model = Graph() p = GP(EQ(), graph=model) p2 = 5 - p x = np.linspace(0, 1, 10)[:, None] y = p(x).sample() yield le, abs_err(p2.condition(p(x), y)(x).mean - (5 - y)), 1e-5 yield le, abs_err(p.condition(p2(x), 5 - y)(x).mean - y), 1e-5 model = Graph() p = GP(EQ(), graph=model) p2 = -p x = np.linspace(0, 1, 10)[:, None] y = p(x).sample() yield le, abs_err(p2.condition(p(x), y)(x).mean + y), 1e-5 yield le, abs_err(p.condition(p2(x), -y)(x).mean - y), 1e-5
def test_selection(): yield assert_allclose, _to_list((1, 2)), [1, 2] yield assert_allclose, _to_list([1, 2]), [1, 2] yield assert_allclose, _to_list(np.array([1, 2])), [1, 2] yield assert_allclose, _to_list(1), [1] yield raises, ValueError, lambda: _to_list(np.ones((1, 1))) yield eq, str(EQ().select(0)), 'EQ() : [0]' yield eq, str(EQ().select([0, 2])), 'EQ() : [0, 2]' yield eq, str(EQ().select(0, 2)), 'EQ() : ([0], [2])' yield eq, str(EQ().select([0], 2)), 'EQ() : ([0], [2])' yield eq, str(EQ().select(0, [2])), 'EQ() : ([0], [2])' yield eq, str(EQ().select([0, 1], [2])), 'EQ() : ([0, 1], [2])' yield eq, str(EQ().select(None, [2])), 'EQ() : (None, [2])' yield eq, str(EQ().select(None)), 'EQ() : None' yield eq, str(EQ().select(None, None)), 'EQ() : (None, None)' yield eq, str(EQ().select([1], None)), 'EQ() : ([1], None)' yield eq, str(ZeroKernel().select(0)), '0' yield eq, str(OneMean().select(0)), '1'
def test_product(): k = (2 * EQ().stretch(10)) * (3 * RQ(1e-2).stretch(20)) assert k.stationary # Test equality. assert EQ() * Linear() == EQ() * Linear() assert EQ() * Linear() == Linear() * EQ() assert EQ() * Linear() != EQ() * RQ(1e-1) assert EQ() * Linear() != RQ(1e-1) * Linear() # Standard tests: standard_kernel_tests(k)
def test_component_kernel(): x = np.random.randn(10, 2) k1 = EQ() k2 = RQ(1e-1) kzero = ZeroKernel() kc = ComponentKernel({ (Component(1), Component(1)): k1, (Component(1), Component(2)): kzero, (Component(2), Component(1)): kzero, (Component(2), Component(2)): k2 }) yield ok, allclose(kc(Component(1)(x)), k1(x)) yield ok, allclose(kc(Component(2)(x)), k2(x)) yield ok, allclose(kc(Component(1)(x), Component(2)(x)), kzero(x)) yield ok, allclose(kc(Component(2)(x), Component(1)(x)), kzero(x)) yield eq, str(ComponentKernel({Component(1): EQ(), Component(2): EQ()})), \ 'ComponentKernel(EQ(), EQ())'
def test_delta(): k = Delta() # Verify that the kernel has the right properties. assert k.stationary assert str(k) == 'Delta()' # Check equality. assert Delta() == Delta() assert Delta() != Delta(epsilon=k.epsilon * 10) assert Delta() != EQ()
def test_reversal(): x1 = np.random.randn(10, 2) x2 = np.random.randn(5, 2) x3 = np.random.randn() # Test with a stationary and non-stationary kernel. for k in [EQ(), Linear()]: yield assert_allclose, k(x1), reversed(k)(x1) yield assert_allclose, k(x3), reversed(k)(x3) yield assert_allclose, k(x1, x2), reversed(k)(x1, x2) yield assert_allclose, k(x1, x2), reversed(k)(x2, x1).T # Test double reversal does the right thing. yield assert_allclose, k(x1), reversed(reversed(k))(x1) yield assert_allclose, k(x3), reversed(reversed(k))(x3) yield assert_allclose, k(x1, x2), reversed(reversed(k))(x1, x2) yield assert_allclose, k(x1, x2), reversed(reversed(k))(x2, x1).T # Verify that the kernel has the right properties. k = reversed(EQ()) yield eq, k.stationary, True yield eq, k.var, 1 yield eq, k.length_scale, 1 yield eq, k.period, np.inf k = reversed(Linear()) yield eq, k.stationary, False yield raises, RuntimeError, lambda: k.var yield raises, RuntimeError, lambda: k.length_scale yield eq, k.period, np.inf yield eq, str(k), 'Reversed(Linear())' # Check equality. yield eq, reversed(Linear()), reversed(Linear()) yield neq, reversed(Linear()), Linear() yield neq, reversed(Linear()), reversed(EQ()) yield neq, reversed(Linear()), reversed(DecayingKernel(1, 1)) # Standard tests: for x in kernel_generator(k): yield x
def test_construction(): model = Graph() p = GP(EQ(), graph=model) x = np.random.randn(10, 1) p.mean(x) p.mean(p(x)) p.kernel(x) p.kernel(p(x)) p.kernel(x, x) p.kernel(p(x), x) p.kernel(x, p(x)) p.kernel(p(x), p(x)) p.kernel.elwise(x) p.kernel.elwise(p(x)) p.kernel.elwise(x, x) p.kernel.elwise(p(x), x) p.kernel.elwise(x, p(x)) p.kernel.elwise(p(x), p(x)) # Test resolution of kernel and mean. k = EQ() m = TensorProductMean(lambda x: x ** 2) assert isinstance(GP(k, graph=model).mean, ZeroMean) assert isinstance(GP(k, 5, graph=model).mean, ScaledMean) assert isinstance(GP(k, 1, graph=model).mean, OneMean) assert isinstance(GP(k, 0, graph=model).mean, ZeroMean) assert isinstance(GP(k, m, graph=model).mean, TensorProductMean) assert isinstance(GP(k, graph=model).kernel, EQ) assert isinstance(GP(5, graph=model).kernel, ScaledKernel) assert isinstance(GP(1, graph=model).kernel, OneKernel) assert isinstance(GP(0, graph=model).kernel, ZeroKernel) # Test construction of finite-dimensional distribution. d = GP(k, m, graph=model)(x) allclose(d.var, k(x)) allclose(d.mean, m(x))
def test_naming(): model = Graph() p1 = GP(EQ(), 1, graph=model) p2 = GP(EQ(), 2, graph=model) # Test setting and getting names. p1.name = 'name' assert model['name'] is p1 assert p1.name == 'name' assert model[p1] == 'name' with pytest.raises(KeyError): model['other_name'] with pytest.raises(KeyError): model[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 model['name'] is p2 assert p2.name == 'name' assert model[p2] == 'name' assert model['other_name'] is p1 assert p1.name == 'other_name' assert model[p1] == 'other_name' # Test giving a name to the constructor. p3 = GP(EQ(), name='yet_another_name', graph=model) assert model['yet_another_name'] is p3 assert p3.name == 'yet_another_name' assert model[p3] == 'yet_another_name'
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"
def test_case_summation_with_itself(): # Test summing the same GP with itself. model = Graph() p1 = GP(EQ(), graph=model) p2 = p1 + p1 + p1 + p1 + p1 x = np.linspace(0, 10, 5)[:, None] yield assert_allclose, p2(x).var, 25 * p1(x).var yield assert_allclose, p2(x).mean, np.zeros((5, 1)) y = np.random.randn(5, 1) yield assert_allclose, p2.condition(p1(x), y)(x).mean, 5 * y
def test_selection(): allclose(_to_list((1, 2)), [1, 2]) allclose(_to_list([1, 2]), [1, 2]) allclose(_to_list(np.array([1, 2])), [1, 2]) allclose(_to_list(1), [1]) with pytest.raises(ValueError): _to_list(np.ones((1, 1))) assert str(EQ().select(0)) == 'EQ() : [0]' assert str(EQ().select([0, 2])) == 'EQ() : [0, 2]' assert str(EQ().select(0, 2)) == 'EQ() : ([0], [2])' assert str(EQ().select([0], 2)) == 'EQ() : ([0], [2])' assert str(EQ().select(0, [2])) == 'EQ() : ([0], [2])' assert str(EQ().select([0, 1], [2])) == 'EQ() : ([0, 1], [2])' assert str(EQ().select(None, [2])) == 'EQ() : (None, [2])' assert str(EQ().select(None)) == 'EQ() : None' assert str(EQ().select(None, None)) == 'EQ() : (None, None)' assert str(EQ().select([1], None)) == 'EQ() : ([1], None)' assert str(ZeroKernel().select(0)) == '0' assert str(OneMean().select(0)) == '1'
def test_case_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)
def test_sum(): k1 = EQ().stretch(2) k2 = 3 * RQ(1e-2).stretch(5) k = k1 + k2 assert k.stationary assert EQ() + Linear() == EQ() + Linear() assert EQ() + Linear() == Linear() + EQ() assert EQ() + Linear() != EQ() + RQ(1e-1) assert EQ() + Linear() != RQ(1e-1) + Linear() # Standard tests: standard_kernel_tests(k)
def test_construction(): p = GP(EQ()) x = B.randn(10, 1) p.mean(x) p.mean(Input(x)) p.kernel(x) p.kernel(Input(x)) p.kernel(x, x) p.kernel(Input(x), x) p.kernel(x, Input(x)) p.kernel(Input(x), Input(x)) p.kernel.elwise(x) p.kernel.elwise(Input(x)) p.kernel.elwise(x, x) p.kernel.elwise(Input(x), x) p.kernel.elwise(x, Input(x)) p.kernel.elwise(Input(x), Input(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. d = GP(m, k)(x) approx(d.var, k(x)) approx(d.mean, m(x))
def test_product(): k = (2 * EQ().stretch(10)) * (3 * RQ(1e-2).stretch(20)) # Verify that the kernel has the right properties. assert k.stationary # Test equality. assert EQ() * Linear() == EQ() * Linear() assert EQ() * Linear() == Linear() * EQ() assert EQ() * Linear() != EQ() * RQ(1e-1) assert EQ() * Linear() != RQ(1e-1) * Linear() # Standard tests: standard_kernel_tests(k)
def test_stretching(): model = Graph() # Test construction: p = GP(EQ(), TensorProductMean(lambda x: x ** 2), graph=model) yield eq, str(p.stretch(1)), 'GP(EQ() > 1, <lambda> > 1)' # Test case: p = GP(EQ(), graph=model) p2 = p.stretch(5) n = 5 x = np.linspace(0, 10, n)[:, None] y = p2(x).sample() post = p.condition(p2(x), y) yield assert_allclose, post(x / 5).mean, y yield le, abs_err(B.diag(post(x / 5).var)), 1e-10 post = p2.condition(p(x), y) yield assert_allclose, post(x * 5).mean, y yield le, abs_err(B.diag(post(x * 5).var)), 1e-10
def test_shorthands(): model = Graph() p = GP(EQ(), graph=model) # Construct a normal distribution that serves as in input. x = p(1) yield assert_instance, x, At yield ok, type_parameter(x) is p yield eq, x.get(), 1 yield eq, str(p(x)), '{}({})'.format(str(p), str(x)) yield eq, repr(p(x)), '{}({})'.format(repr(p), repr(x)) # Construct a normal distribution that does not serve as an input. x = Normal(np.ones((1, 1))) yield raises, RuntimeError, lambda: type_parameter(x) yield raises, RuntimeError, lambda: x.get() yield raises, RuntimeError, lambda: p | (x, 1) # Test shorthands for stretching and selection. p = GP(EQ(), graph=Graph()) yield eq, str(p > 2), str(p.stretch(2)) yield eq, str(p[0]), str(p.select(0))