From c82ef3b3a1cd3ad8632749d04471ad4ce2293d8d Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 20:27:22 +0200 Subject: [PATCH 001/101] update gitignore --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 950eecdd..b05b1a6b 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,9 @@ iterate.dat GPy*.rst # vscode -settings.json \ No newline at end of file +settings.json + +# local dev +.eggs +.venv +.env From 1dc7e90cd9aa7f9b443815f915ff917859519664 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 20:30:15 +0200 Subject: [PATCH 002/101] format on save --- GPy/testing/cython_tests.py | 43 ++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/GPy/testing/cython_tests.py b/GPy/testing/cython_tests.py index dc41c44a..1ad23121 100644 --- a/GPy/testing/cython_tests.py +++ b/GPy/testing/cython_tests.py @@ -8,13 +8,15 @@ from ..util.config import config try: from ..util import choleskies_cython - choleskies_cython_working = config.getboolean('cython', 'working') + + choleskies_cython_working = config.getboolean("cython", "working") except ImportError: choleskies_cython_working = False try: from ..kern.src import stationary_cython - stationary_cython_working = config.getboolean('cython', 'working') + + stationary_cython_working = config.getboolean("cython", "working") except ImportError: stationary_cython_working = False @@ -22,29 +24,39 @@ except ImportError: These tests make sure that the pure python and cython codes work the same """ -@unittest.skipIf(not choleskies_cython_working,"Cython cholesky module has not been built on this machine") + +@unittest.skipIf( + not choleskies_cython_working, + "Cython cholesky module has not been built on this machine", +) class CythonTestChols(np.testing.TestCase): def setUp(self): - self.flat = np.random.randn(45,5) + self.flat = np.random.randn(45, 5) self.triang = np.array([np.eye(20) for i in range(3)]) + def test_flat_to_triang(self): L1 = choleskies._flat_to_triang_pure(self.flat) L2 = choleskies._flat_to_triang_cython(self.flat) np.testing.assert_allclose(L1, L2) + def test_triang_to_flat(self): A1 = choleskies._triang_to_flat_pure(self.triang) A2 = choleskies._triang_to_flat_cython(self.triang) np.testing.assert_allclose(A1, A2) -@unittest.skipIf(not stationary_cython_working,"Cython stationary module has not been built on this machine") + +@unittest.skipIf( + not stationary_cython_working, + "Cython stationary module has not been built on this machine", +) class test_stationary(np.testing.TestCase): def setUp(self): self.k = GPy.kern.RBF(10) - self.X = np.random.randn(300,10) - self.Z = np.random.randn(20,10) - self.dKxx = np.random.randn(300,300) - self.dKzz = np.random.randn(20,20) - self.dKxz = np.random.randn(300,20) + self.X = np.random.randn(300, 10) + self.Z = np.random.randn(20, 10) + self.dKxx = np.random.randn(300, 300) + self.dKzz = np.random.randn(20, 20) + self.dKxz = np.random.randn(300, 20) def test_square_gradX(self): g1 = self.k._gradients_X_cython(self.dKxx, self.X) @@ -66,13 +78,18 @@ class test_stationary(np.testing.TestCase): g2 = self.k._lengthscale_grads_cython(self.dKxz, self.X, self.Z) np.testing.assert_allclose(g1, g2) -@unittest.skipIf(not choleskies_cython_working,"Cython cholesky module has not been built on this machine") + +@unittest.skipIf( + not choleskies_cython_working, + "Cython cholesky module has not been built on this machine", +) class test_choleskies_backprop(np.testing.TestCase): def setUp(self): - a =np.random.randn(10,12) + a = np.random.randn(10, 12) A = a.dot(a.T) self.L = GPy.util.linalg.jitchol(A) - self.dL = np.random.randn(10,10) + self.dL = np.random.randn(10, 10) + def test(self): r1 = choleskies._backprop_gradient_pure(self.dL, self.L) r2 = choleskies_cython.backprop_gradient(self.dL, self.L) From 4edfff6596fc6e67279a4753af631aad9f5278d3 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 20:37:49 +0200 Subject: [PATCH 003/101] migrate cython test to pytest --- GPy/testing/cython_tests.py | 44 ++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/GPy/testing/cython_tests.py b/GPy/testing/cython_tests.py index 1ad23121..e885482e 100644 --- a/GPy/testing/cython_tests.py +++ b/GPy/testing/cython_tests.py @@ -1,8 +1,7 @@ import numpy as np -import scipy as sp from GPy.util import choleskies import GPy -import unittest +import pytest from ..util.config import config @@ -25,32 +24,32 @@ These tests make sure that the pure python and cython codes work the same """ -@unittest.skipIf( +@pytest.skipIf( not choleskies_cython_working, "Cython cholesky module has not been built on this machine", ) -class CythonTestChols(np.testing.TestCase): - def setUp(self): +class CythonTestChols: + def setup(self): self.flat = np.random.randn(45, 5) self.triang = np.array([np.eye(20) for i in range(3)]) def test_flat_to_triang(self): L1 = choleskies._flat_to_triang_pure(self.flat) L2 = choleskies._flat_to_triang_cython(self.flat) - np.testing.assert_allclose(L1, L2) + assert np.allclose(L1, L2), "Triang mismatch!" def test_triang_to_flat(self): A1 = choleskies._triang_to_flat_pure(self.triang) A2 = choleskies._triang_to_flat_cython(self.triang) - np.testing.assert_allclose(A1, A2) + assert np.allclose(A1, A2), "Flat mismatch!" -@unittest.skipIf( +@pytest.skipIf( not stationary_cython_working, "Cython stationary module has not been built on this machine", ) -class test_stationary(np.testing.TestCase): - def setUp(self): +class TestStationary: + def setup(self): self.k = GPy.kern.RBF(10) self.X = np.random.randn(300, 10) self.Z = np.random.randn(20, 10) @@ -59,40 +58,45 @@ class test_stationary(np.testing.TestCase): self.dKxz = np.random.randn(300, 20) def test_square_gradX(self): + self.setup() g1 = self.k._gradients_X_cython(self.dKxx, self.X) g2 = self.k._gradients_X_pure(self.dKxx, self.X) - np.testing.assert_allclose(g1, g2) + assert np.allclose(g1, g2), "Gradient mismatch on square X!" def test_rect_gradx(self): + self.setup() g1 = self.k._gradients_X_cython(self.dKxz, self.X, self.Z) g2 = self.k._gradients_X_pure(self.dKxz, self.X, self.Z) - np.testing.assert_allclose(g1, g2) + assert np.allclose(g1, g2), "Gradient mismatch on rect X!" def test_square_lengthscales(self): + self.setup() g1 = self.k._lengthscale_grads_pure(self.dKxx, self.X, self.X) g2 = self.k._lengthscale_grads_cython(self.dKxx, self.X, self.X) - np.testing.assert_allclose(g1, g2) + assert np.allclose(g1, g2), "Gradient mismatch on square lengthscale!" def test_rect_lengthscales(self): + self.setup() g1 = self.k._lengthscale_grads_pure(self.dKxz, self.X, self.Z) g2 = self.k._lengthscale_grads_cython(self.dKxz, self.X, self.Z) - np.testing.assert_allclose(g1, g2) + assert np.allclose(g1, g2), "Gradient mismatch on rect lengthscale!" -@unittest.skipIf( +@pytest.skipIf( not choleskies_cython_working, "Cython cholesky module has not been built on this machine", ) -class test_choleskies_backprop(np.testing.TestCase): - def setUp(self): +class TestCholeskiesBackprop: + def setup(self): a = np.random.randn(10, 12) A = a.dot(a.T) self.L = GPy.util.linalg.jitchol(A) self.dL = np.random.randn(10, 10) - def test(self): + def test_backprop(self): + self.setup() r1 = choleskies._backprop_gradient_pure(self.dL, self.L) r2 = choleskies_cython.backprop_gradient(self.dL, self.L) r3 = choleskies_cython.backprop_gradient_par_c(self.dL, self.L) - np.testing.assert_allclose(r1, r2) - np.testing.assert_allclose(r1, r3) + assert np.allclose(r1, r2), "Gradient mismatch!" + assert np.allclose(r1, r3), "Gradient mismatch!" From 1e5dd36bc7cf2a1060f03efcc219a3ce3f49a19c Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 20:38:20 +0200 Subject: [PATCH 004/101] format on save --- GPy/testing/ep_likelihood_tests.py | 95 ++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/GPy/testing/ep_likelihood_tests.py b/GPy/testing/ep_likelihood_tests.py index cce22390..cf880c6e 100644 --- a/GPy/testing/ep_likelihood_tests.py +++ b/GPy/testing/ep_likelihood_tests.py @@ -1,4 +1,3 @@ - import numpy as np import unittest import GPy @@ -31,18 +30,18 @@ class TestObservationModels(unittest.TestCase): self.Y_noisy[75] += 1.3 self.init_var = 0.15 - self.deg_free = 4. + self.deg_free = 4.0 censored = np.zeros_like(self.Y) random_inds = np.random.choice(self.N, int(self.N / 2), replace=True) censored[random_inds] = 1 self.Y_metadata = dict() - self.Y_metadata['censored'] = censored + self.Y_metadata["censored"] = censored self.kernel1 = GPy.kern.RBF(self.X.shape[1]) + GPy.kern.White(self.X.shape[1]) def tearDown(self): self.Y = None self.X = None - self.binary_Y =None + self.binary_Y = None self.positive_Y = None self.kernel1 = None @@ -51,25 +50,51 @@ class TestObservationModels(unittest.TestCase): bernoulli = GPy.likelihoods.Bernoulli() laplace_inf = GPy.inference.latent_function_inference.Laplace() - ep_inf_alt = GPy.inference.latent_function_inference.EP(ep_mode='alternated') - ep_inf_nested = GPy.inference.latent_function_inference.EP(ep_mode='nested') - ep_inf_fractional = GPy.inference.latent_function_inference.EP(ep_mode='nested', eta=0.9) + ep_inf_alt = GPy.inference.latent_function_inference.EP(ep_mode="alternated") + ep_inf_nested = GPy.inference.latent_function_inference.EP(ep_mode="nested") + ep_inf_fractional = GPy.inference.latent_function_inference.EP( + ep_mode="nested", eta=0.9 + ) - m1 = GPy.core.GP(self.X, self.binary_Y.copy(), kernel=self.kernel1.copy(), likelihood=bernoulli.copy(), inference_method=laplace_inf) + m1 = GPy.core.GP( + self.X, + self.binary_Y.copy(), + kernel=self.kernel1.copy(), + likelihood=bernoulli.copy(), + inference_method=laplace_inf, + ) m1.randomize() - m2 = GPy.core.GP(self.X, self.binary_Y.copy(), kernel=self.kernel1.copy(), likelihood=bernoulli.copy(), inference_method=ep_inf_alt) + m2 = GPy.core.GP( + self.X, + self.binary_Y.copy(), + kernel=self.kernel1.copy(), + likelihood=bernoulli.copy(), + inference_method=ep_inf_alt, + ) m2.randomize() - m3 = GPy.core.GP(self.X, self.binary_Y.copy(), kernel=self.kernel1.copy(), likelihood=bernoulli.copy(), inference_method=ep_inf_nested) + m3 = GPy.core.GP( + self.X, + self.binary_Y.copy(), + kernel=self.kernel1.copy(), + likelihood=bernoulli.copy(), + inference_method=ep_inf_nested, + ) m3.randomize() # - m4 = GPy.core.GP(self.X, self.binary_Y.copy(), kernel=self.kernel1.copy(), likelihood=bernoulli.copy(), inference_method=ep_inf_fractional) + m4 = GPy.core.GP( + self.X, + self.binary_Y.copy(), + kernel=self.kernel1.copy(), + likelihood=bernoulli.copy(), + inference_method=ep_inf_fractional, + ) m4.randomize() - optimizer = 'bfgs' + optimizer = "bfgs" - #do gradcheck here ... + # do gradcheck here ... # self.assertTrue(m1.checkgrad()) # self.assertTrue(m2.checkgrad()) # self.assertTrue(m3.checkgrad()) @@ -86,7 +111,7 @@ class TestObservationModels(unittest.TestCase): probs_mean_ep_nested, probs_var_ep_nested = m3.predict(self.X) # for simple single dimension data , marginal likelihood for laplace and EP approximations should not be so far apart. - self.assertAlmostEqual(m1.log_likelihood(), m2.log_likelihood(),delta=1) + self.assertAlmostEqual(m1.log_likelihood(), m2.log_likelihood(), delta=1) self.assertAlmostEqual(m1.log_likelihood(), m3.log_likelihood(), delta=1) self.assertAlmostEqual(m1.log_likelihood(), m4.log_likelihood(), delta=5) @@ -99,22 +124,40 @@ class TestObservationModels(unittest.TestCase): return np.sqrt(np.mean((Y - Ystar) ** 2)) @with_setup(setUp, tearDown) - @unittest.skip("Fails as a consequence of fixing the DSYR function. Needs to be reviewed!") + @unittest.skip( + "Fails as a consequence of fixing the DSYR function. Needs to be reviewed!" + ) def test_EP_with_StudentT(self): - studentT = GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.init_var) + studentT = GPy.likelihoods.StudentT( + deg_free=self.deg_free, sigma2=self.init_var + ) laplace_inf = GPy.inference.latent_function_inference.Laplace() - ep_inf_alt = GPy.inference.latent_function_inference.EP(ep_mode='alternated') - ep_inf_nested = GPy.inference.latent_function_inference.EP(ep_mode='nested') - ep_inf_frac = GPy.inference.latent_function_inference.EP(ep_mode='nested', eta=0.7) + ep_inf_alt = GPy.inference.latent_function_inference.EP(ep_mode="alternated") + ep_inf_nested = GPy.inference.latent_function_inference.EP(ep_mode="nested") + ep_inf_frac = GPy.inference.latent_function_inference.EP( + ep_mode="nested", eta=0.7 + ) - m1 = GPy.core.GP(self.X.copy(), self.Y_noisy.copy(), kernel=self.kernel1.copy(), likelihood=studentT.copy(), inference_method=laplace_inf) + m1 = GPy.core.GP( + self.X.copy(), + self.Y_noisy.copy(), + kernel=self.kernel1.copy(), + likelihood=studentT.copy(), + inference_method=laplace_inf, + ) # optimize - m1['.*white'].constrain_fixed(1e-5) + m1[".*white"].constrain_fixed(1e-5) m1.randomize() - m2 = GPy.core.GP(self.X.copy(), self.Y_noisy.copy(), kernel=self.kernel1.copy(), likelihood=studentT.copy(), inference_method=ep_inf_alt) - m2['.*white'].constrain_fixed(1e-5) + m2 = GPy.core.GP( + self.X.copy(), + self.Y_noisy.copy(), + kernel=self.kernel1.copy(), + likelihood=studentT.copy(), + inference_method=ep_inf_alt, + ) + m2[".*white"].constrain_fixed(1e-5) # m2.constrain_bounded('.*t_scale2', 0.001, 10) m2.randomize() @@ -123,12 +166,12 @@ class TestObservationModels(unittest.TestCase): # # m3.constrain_bounded('.*t_scale2', 0.001, 10) # m3.randomize() - optimizer='bfgs' - m1.optimize(optimizer=optimizer,max_iters=400) + optimizer = "bfgs" + m1.optimize(optimizer=optimizer, max_iters=400) m2.optimize(optimizer=optimizer, max_iters=400) # m3.optimize(optimizer=optimizer, max_iters=500) - self.assertAlmostEqual(m1.log_likelihood(), m2.log_likelihood(),delta=200) + self.assertAlmostEqual(m1.log_likelihood(), m2.log_likelihood(), delta=200) # self.assertAlmostEqual(m1.log_likelihood(), m3.log_likelihood(), 3) From 4d41594e1815176b63aac801ffe05dfc3198dd6c Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 20:42:54 +0200 Subject: [PATCH 005/101] migrate ep_likelihood_test to pytest --- GPy/testing/ep_likelihood_tests.py | 47 ++++++++++++++++-------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/GPy/testing/ep_likelihood_tests.py b/GPy/testing/ep_likelihood_tests.py index cf880c6e..ea908cd5 100644 --- a/GPy/testing/ep_likelihood_tests.py +++ b/GPy/testing/ep_likelihood_tests.py @@ -3,14 +3,18 @@ import unittest import GPy from GPy.models import GradientChecker + fixed_seed = 10 -from nose.tools import with_setup, nottest + + +def rmse(Y, Ystar): + return np.sqrt(np.mean((Y - Ystar) ** 2)) # this file will contain some high level tests, this is not unit testing, but will give us a higher level estimate # if things are going well under the hood. -class TestObservationModels(unittest.TestCase): - def setUp(self): +class TestObservationModels: + def setup(self): np.random.seed(fixed_seed) self.N = 100 self.D = 2 @@ -38,15 +42,17 @@ class TestObservationModels(unittest.TestCase): self.Y_metadata["censored"] = censored self.kernel1 = GPy.kern.RBF(self.X.shape[1]) + GPy.kern.White(self.X.shape[1]) - def tearDown(self): + def tear_down(self): self.Y = None self.X = None self.binary_Y = None self.positive_Y = None self.kernel1 = None - @with_setup(setUp, tearDown) - def testEPClassification(self): + def test_epccassification(self): + self.setup() + self.tear_down() + bernoulli = GPy.likelihoods.Bernoulli() laplace_inf = GPy.inference.latent_function_inference.Laplace() @@ -111,23 +117,22 @@ class TestObservationModels(unittest.TestCase): probs_mean_ep_nested, probs_var_ep_nested = m3.predict(self.X) # for simple single dimension data , marginal likelihood for laplace and EP approximations should not be so far apart. - self.assertAlmostEqual(m1.log_likelihood(), m2.log_likelihood(), delta=1) - self.assertAlmostEqual(m1.log_likelihood(), m3.log_likelihood(), delta=1) - self.assertAlmostEqual(m1.log_likelihood(), m4.log_likelihood(), delta=5) + # TODO: the below were assertAlmostEqual, not sure if allclose will do the job here + assert np.allclose(m1.log_likelihood(), m2.log_likelihood()) # , delta=1 + assert np.allcose(m1.log_likelihood(), m3.log_likelihood()) # , delta=1 + assert np.allclose(m1.log_likelihood(), m4.log_likelihood()) # , delta=5 GPy.util.classification.conf_matrix(probs_mean_lap, self.binary_Y) GPy.util.classification.conf_matrix(probs_mean_ep_alt, self.binary_Y) GPy.util.classification.conf_matrix(probs_mean_ep_nested, self.binary_Y) - @nottest - def rmse(self, Y, Ystar): - return np.sqrt(np.mean((Y - Ystar) ** 2)) - - @with_setup(setUp, tearDown) - @unittest.skip( + @pytest.skip( "Fails as a consequence of fixing the DSYR function. Needs to be reviewed!" ) - def test_EP_with_StudentT(self): + def test_ep_with_studentt(self): + self.setup() + self.tear_down() + studentT = GPy.likelihoods.StudentT( deg_free=self.deg_free, sigma2=self.init_var ) @@ -171,7 +176,8 @@ class TestObservationModels(unittest.TestCase): m2.optimize(optimizer=optimizer, max_iters=400) # m3.optimize(optimizer=optimizer, max_iters=500) - self.assertAlmostEqual(m1.log_likelihood(), m2.log_likelihood(), delta=200) + # TODO: this was assertAlmostEqual, not sure if allclose will do the job here + assert np.allclose(m1.log_likelihood(), m2.log_likelihood()) # , delta=200 # self.assertAlmostEqual(m1.log_likelihood(), m3.log_likelihood(), 3) @@ -183,9 +189,6 @@ class TestObservationModels(unittest.TestCase): # rmse_nested = self.rmse(preds_mean_nested, self.Y_noisy) if rmse_alt > rmse_lap: - self.assertAlmostEqual(rmse_lap, rmse_alt, delta=1.5) + # TODO: this was assertAlmostEqual, not sure if allclose will do the job here + assert np.allclose(rmse_lap, rmse_alt) # , delta=1.5 # m3.optimize(optimizer=optimizer, max_iters=500) - - -if __name__ == "__main__": - unittest.main() From 2eb237f6560f634862007061a7cd74355a932832 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:16:20 +0200 Subject: [PATCH 006/101] update ep_likelihood_tests --- GPy/testing/ep_likelihood_tests.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/GPy/testing/ep_likelihood_tests.py b/GPy/testing/ep_likelihood_tests.py index ea908cd5..4559ddf1 100644 --- a/GPy/testing/ep_likelihood_tests.py +++ b/GPy/testing/ep_likelihood_tests.py @@ -118,9 +118,10 @@ class TestObservationModels: # for simple single dimension data , marginal likelihood for laplace and EP approximations should not be so far apart. # TODO: the below were assertAlmostEqual, not sure if allclose will do the job here - assert np.allclose(m1.log_likelihood(), m2.log_likelihood()) # , delta=1 - assert np.allcose(m1.log_likelihood(), m3.log_likelihood()) # , delta=1 - assert np.allclose(m1.log_likelihood(), m4.log_likelihood()) # , delta=5 + # I replace the old delta with the atol + assert np.allclose(m1.log_likelihood(), m2.log_likelihood(), atol=1.0) + assert np.allclose(m1.log_likelihood(), m3.log_likelihood(), atol=1) + assert np.allclose(m1.log_likelihood(), m4.log_likelihood(), atol=5.0) GPy.util.classification.conf_matrix(probs_mean_lap, self.binary_Y) GPy.util.classification.conf_matrix(probs_mean_ep_alt, self.binary_Y) @@ -177,7 +178,8 @@ class TestObservationModels: # m3.optimize(optimizer=optimizer, max_iters=500) # TODO: this was assertAlmostEqual, not sure if allclose will do the job here - assert np.allclose(m1.log_likelihood(), m2.log_likelihood()) # , delta=200 + # I replace the old delta with the atol + assert np.allclose(m1.log_likelihood(), m2.log_likelihood(), atol=200.0) # self.assertAlmostEqual(m1.log_likelihood(), m3.log_likelihood(), 3) @@ -190,5 +192,6 @@ class TestObservationModels: if rmse_alt > rmse_lap: # TODO: this was assertAlmostEqual, not sure if allclose will do the job here - assert np.allclose(rmse_lap, rmse_alt) # , delta=1.5 + # I replace the old delta with the atol + assert np.allclose(rmse_lap, rmse_alt, atol=1.5) # m3.optimize(optimizer=optimizer, max_iters=500) From f48837e01d875ba6bab24f6880e98be674cad8ec Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:16:50 +0200 Subject: [PATCH 007/101] format on save --- GPy/testing/examples_tests.py | 39 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/GPy/testing/examples_tests.py b/GPy/testing/examples_tests.py index 48a18119..c0106a9a 100644 --- a/GPy/testing/examples_tests.py +++ b/GPy/testing/examples_tests.py @@ -12,6 +12,7 @@ from nose.tools import nottest import sys import itertools + class ExamplesTests(unittest.TestCase): def _checkgrad(self, Model): self.assertTrue(Model.checkgrad()) @@ -19,27 +20,31 @@ class ExamplesTests(unittest.TestCase): def _model_instance(self, Model): self.assertTrue(isinstance(Model, GPy.models)) + def model_checkgrads(model): model.randomize() - #NOTE: Step as 1e-4, this should be acceptable for more peaky models + # NOTE: Step as 1e-4, this should be acceptable for more peaky models return model.checkgrad(step=1e-4) + def model_instance(model): return isinstance(model, GPy.core.model.Model) + def flatten_nested(lst): result = [] for element in lst: - if hasattr(element, '__iter__'): + if hasattr(element, "__iter__"): result.extend(flatten_nested(element)) else: result.append(element) return result + @nottest def test_models(): - optimize=False - plot=True + optimize = False + plot = True examples_path = os.path.dirname(GPy.examples.__file__) # Load modules failing_models = {} @@ -49,13 +54,19 @@ def test_models(): print("MODULE", module_examples) print("Before") print(inspect.getmembers(module_examples, predicate=inspect.isfunction)) - functions = [ func for func in inspect.getmembers(module_examples, predicate=inspect.isfunction) if func[0].startswith('_') is False ][::-1] + functions = [ + func + for func in inspect.getmembers( + module_examples, predicate=inspect.isfunction + ) + if func[0].startswith("_") is False + ][::-1] print("After") print(functions) for example in functions: - if example[0] in ['epomeo_gpx']: - #These are the edge cases that we might want to handle specially - if example[0] == 'epomeo_gpx' and not GPy.util.datasets.gpxpy_available: + if example[0] in ["epomeo_gpx"]: + # These are the edge cases that we might want to handle specially + if example[0] == "epomeo_gpx" and not GPy.util.datasets.gpxpy_available: print("Skipping as gpxpy is not available to parse GPS") continue @@ -63,14 +74,14 @@ def test_models(): # Generate model try: - models = [ example[1](optimize=optimize, plot=plot) ] - #If more than one model returned, flatten them + models = [example[1](optimize=optimize, plot=plot)] + # If more than one model returned, flatten them models = flatten_nested(models) except Exception as e: failing_models[example[0]] = "Cannot make model: \n{e}".format(e=e) else: print(models) - model_checkgrads.description = 'test_checkgrads_%s' % example[0] + model_checkgrads.description = "test_checkgrads_%s" % example[0] try: for model in models: if not model_checkgrads(model): @@ -78,7 +89,7 @@ def test_models(): except Exception as e: failing_models[model_checkgrads.description] = e - model_instance.description = 'test_instance_%s' % example[0] + model_instance.description = "test_instance_%s" % example[0] try: for model in models: if not model_instance(model): @@ -86,8 +97,8 @@ def test_models(): except Exception as e: failing_models[model_instance.description] = e - #yield model_checkgrads, model - #yield model_instance, model + # yield model_checkgrads, model + # yield model_instance, model print("Finished checking module {m}".format(m=module_name)) if len(failing_models.keys()) > 0: From d82100278b60fabb2bd018e0dd7cf4926e5bd964 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:24:08 +0200 Subject: [PATCH 008/101] migrate examples_tests to pytest --- GPy/testing/examples_tests.py | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/GPy/testing/examples_tests.py b/GPy/testing/examples_tests.py index c0106a9a..f8f12179 100644 --- a/GPy/testing/examples_tests.py +++ b/GPy/testing/examples_tests.py @@ -1,24 +1,18 @@ # Copyright (c) 2012, GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest -import numpy as np import GPy import inspect import pkgutil import os -import random -from nose.tools import nottest -import sys -import itertools -class ExamplesTests(unittest.TestCase): - def _checkgrad(self, Model): - self.assertTrue(Model.checkgrad()) +def check_grad(Model): + assert Model.checkgrad(), "Gradient check failed!" - def _model_instance(self, Model): - self.assertTrue(isinstance(Model, GPy.models)) + +def check_model_instance(Model): + assert isinstance(Model, GPy.models), "Wrong type!" def model_checkgrads(model): @@ -41,14 +35,14 @@ def flatten_nested(lst): return result -@nottest def test_models(): + # TODO: testing setup is not that clear to me yet... optimize = False plot = True examples_path = os.path.dirname(GPy.examples.__file__) # Load modules failing_models = {} - for loader, module_name, is_pkg in pkgutil.iter_modules([examples_path]): + for loader, module_name, _is_pkg in pkgutil.iter_modules([examples_path]): # Load examples module_examples = loader.find_module(module_name).load_module(module_name) print("MODULE", module_examples) @@ -108,9 +102,3 @@ def test_models(): if len(failing_models.keys()) > 0: print(failing_models) raise Exception(failing_models) - - -if __name__ == "__main__": - print("Running unit tests, please be (very) patient...") - # unittest.main() - test_models() From ba1c5d8b4907f661d39fe723bbe6944bdd2ff04e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:25:16 +0200 Subject: [PATCH 009/101] format on save --- GPy/testing/fitc.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/GPy/testing/fitc.py b/GPy/testing/fitc.py index 58f009d2..d1b82cc8 100644 --- a/GPy/testing/fitc.py +++ b/GPy/testing/fitc.py @@ -5,6 +5,7 @@ import unittest import numpy as np import GPy + class FITCtest(unittest.TestCase): def setUp(self): ###################################### @@ -12,23 +13,25 @@ class FITCtest(unittest.TestCase): N = 20 # sample inputs and outputs - self.X1D = np.random.uniform(-3., 3., (N, 1)) + self.X1D = np.random.uniform(-3.0, 3.0, (N, 1)) self.Y1D = np.sin(self.X1D) + np.random.randn(N, 1) * 0.05 ###################################### # # 2 dimensional example # sample inputs and outputs - self.X2D = np.random.uniform(-3., 3., (N, 2)) - self.Y2D = np.sin(self.X2D[:, 0:1]) * np.sin(self.X2D[:, 1:2]) + np.random.randn(N, 1) * 0.05 + self.X2D = np.random.uniform(-3.0, 3.0, (N, 2)) + self.Y2D = ( + np.sin(self.X2D[:, 0:1]) * np.sin(self.X2D[:, 1:2]) + + np.random.randn(N, 1) * 0.05 + ) def test_fitc_1d(self): m = GPy.models.SparseGPRegression(self.X1D, self.Y1D) - m.inference_method=GPy.inference.latent_function_inference.FITC() + m.inference_method = GPy.inference.latent_function_inference.FITC() self.assertTrue(m.checkgrad()) def test_fitc_2d(self): m = GPy.models.SparseGPRegression(self.X2D, self.Y2D) - m.inference_method=GPy.inference.latent_function_inference.FITC() + m.inference_method = GPy.inference.latent_function_inference.FITC() self.assertTrue(m.checkgrad()) - From 59657bc49d0fa6edd7bd9ae3e5c3761453b24a4e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:35:09 +0200 Subject: [PATCH 010/101] migrate fitc to pytest --- GPy/testing/fitc.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/GPy/testing/fitc.py b/GPy/testing/fitc.py index d1b82cc8..f069a90d 100644 --- a/GPy/testing/fitc.py +++ b/GPy/testing/fitc.py @@ -1,13 +1,12 @@ # Copyright (c) 2014, James Hensman # Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest import numpy as np import GPy -class FITCtest(unittest.TestCase): - def setUp(self): +class FITCtest: + def setup(self): ###################################### # # 1 dimensional example @@ -27,11 +26,13 @@ class FITCtest(unittest.TestCase): ) def test_fitc_1d(self): + self.setup() m = GPy.models.SparseGPRegression(self.X1D, self.Y1D) m.inference_method = GPy.inference.latent_function_inference.FITC() - self.assertTrue(m.checkgrad()) + assert m.checkgrad(), "Gradient check failed!" def test_fitc_2d(self): + self.setup() m = GPy.models.SparseGPRegression(self.X2D, self.Y2D) m.inference_method = GPy.inference.latent_function_inference.FITC() - self.assertTrue(m.checkgrad()) + assert m.checkgrad(), "Gradient check failed!" From 9263f572ebaa6c0c498b57f30ccfe4d1871855b3 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:35:48 +0200 Subject: [PATCH 011/101] format on save --- GPy/testing/gp_tests.py | 63 +++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/GPy/testing/gp_tests.py b/GPy/testing/gp_tests.py index 1f44304d..60dbe673 100644 --- a/GPy/testing/gp_tests.py +++ b/GPy/testing/gp_tests.py @@ -1,24 +1,22 @@ -''' +""" Created on 4 Sep 2015 @author: maxz -''' +""" import unittest import numpy as np, GPy from GPy.core.parameterization.variational import NormalPosterior + class Test(unittest.TestCase): - - def setUp(self): np.random.seed(12345) self.N = 20 self.N_new = 50 self.D = 1 - self.X = np.random.uniform(-3., 3., (self.N, 1)) + self.X = np.random.uniform(-3.0, 3.0, (self.N, 1)) self.Y = np.sin(self.X) + np.random.randn(self.N, self.D) * 0.05 - self.X_new = np.random.uniform(-3., 3., (self.N_new, 1)) - + self.X_new = np.random.uniform(-3.0, 3.0, (self.N_new, 1)) def test_setxy_bgplvm(self): k = GPy.kern.RBF(1) @@ -27,10 +25,10 @@ class Test(unittest.TestCase): X = m.X Xnew = NormalPosterior(m.X.mean[:10].copy(), m.X.variance[:10].copy()) m.set_XY(Xnew, m.Y[:10].copy()) - assert(m.checkgrad()) + assert m.checkgrad() - assert(m.num_data == m.X.shape[0]) - assert(m.input_dim == m.X.shape[1]) + assert m.num_data == m.X.shape[0] + assert m.input_dim == m.X.shape[1] m.set_XY(X, self.Y) mu2, var2 = m.predict(m.X) @@ -44,10 +42,10 @@ class Test(unittest.TestCase): X = m.X.copy() Xnew = X[:10].copy() m.set_XY(Xnew, m.Y[:10].copy()) - assert(m.checkgrad()) + assert m.checkgrad() - assert(m.num_data == m.X.shape[0]) - assert(m.input_dim == m.X.shape[1]) + assert m.num_data == m.X.shape[0] + assert m.input_dim == m.X.shape[1] m.set_XY(X, self.Y) mu2, var2 = m.predict(m.X) @@ -60,10 +58,10 @@ class Test(unittest.TestCase): mu, var = m.predict(m.X) X = m.X.copy() m.set_XY(m.X[:10], m.Y[:10]) - assert(m.checkgrad()) + assert m.checkgrad() - assert(m.num_data == m.X.shape[0]) - assert(m.input_dim == m.X.shape[1]) + assert m.num_data == m.X.shape[0] + assert m.input_dim == m.X.shape[1] m.set_XY(X, self.Y) mu2, var2 = m.predict(m.X) @@ -73,39 +71,48 @@ class Test(unittest.TestCase): def test_mean_function(self): from GPy.core.parameterization.param import Param from GPy.core.mapping import Mapping + class Parabola(Mapping): - def __init__(self, variance, degree=2, name='parabola'): + def __init__(self, variance, degree=2, name="parabola"): super(Parabola, self).__init__(1, 1, name) - self.variance = Param('variance', np.ones(degree+1) * variance) + self.variance = Param("variance", np.ones(degree + 1) * variance) self.degree = degree self.link_parameter(self.variance) def f(self, X): p = self.variance[0] * np.ones(X.shape) - for i in range(1, self.degree+1): - p += self.variance[i] * X**(i) + for i in range(1, self.degree + 1): + p += self.variance[i] * X ** (i) return p def gradients_X(self, dL_dF, X): grad = np.zeros(X.shape) - for i in range(1, self.degree+1): - grad += (i) * self.variance[i] * X**(i-1) + for i in range(1, self.degree + 1): + grad += (i) * self.variance[i] * X ** (i - 1) return grad def update_gradients(self, dL_dF, X): - for i in range(self.degree+1): - self.variance.gradient[i] = (dL_dF * X**(i)).sum(0) + for i in range(self.degree + 1): + self.variance.gradient[i] = (dL_dF * X ** (i)).sum(0) + X = np.linspace(-2, 2, 100)[:, None] k = GPy.kern.RBF(1) k.randomize() - p = Parabola(.3) + p = Parabola(0.3) p.randomize() - Y = p.f(X) + np.random.multivariate_normal(np.zeros(X.shape[0]), k.K(X)+np.eye(X.shape[0])*1e-8)[:,None] + np.random.normal(0, .1, (X.shape[0], 1)) + Y = ( + p.f(X) + + np.random.multivariate_normal( + np.zeros(X.shape[0]), k.K(X) + np.eye(X.shape[0]) * 1e-8 + )[:, None] + + np.random.normal(0, 0.1, (X.shape[0], 1)) + ) m = GPy.models.GPRegression(X, Y, mean_function=p) m.randomize() - assert(m.checkgrad()) + assert m.checkgrad() _ = m.predict(m.X) + if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.testName'] + # import sys;sys.argv = ['', 'Test.testName'] unittest.main() From d0c65eaa285ff835920825ee5820a46f7eb61b69 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:37:21 +0200 Subject: [PATCH 012/101] migrate gp_tests to pytest --- GPy/testing/gp_tests.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/GPy/testing/gp_tests.py b/GPy/testing/gp_tests.py index 60dbe673..32a6c89f 100644 --- a/GPy/testing/gp_tests.py +++ b/GPy/testing/gp_tests.py @@ -3,13 +3,13 @@ Created on 4 Sep 2015 @author: maxz """ -import unittest -import numpy as np, GPy +import numpy as np +import GPy from GPy.core.parameterization.variational import NormalPosterior -class Test(unittest.TestCase): - def setUp(self): +class TestGP: + def setup(self): np.random.seed(12345) self.N = 20 self.N_new = 50 @@ -19,6 +19,8 @@ class Test(unittest.TestCase): self.X_new = np.random.uniform(-3.0, 3.0, (self.N_new, 1)) def test_setxy_bgplvm(self): + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.BayesianGPLVM(self.Y, 1, kernel=k) mu, var = m.predict(m.X) @@ -36,6 +38,8 @@ class Test(unittest.TestCase): np.testing.assert_allclose(var, var2) def test_setxy_gplvm(self): + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.GPLVM(self.Y, 1, kernel=k) mu, var = m.predict(m.X) @@ -53,6 +57,8 @@ class Test(unittest.TestCase): np.testing.assert_allclose(var, var2) def test_setxy_gp(self): + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.GPRegression(self.X, self.Y, kernel=k) mu, var = m.predict(m.X) @@ -72,6 +78,8 @@ class Test(unittest.TestCase): from GPy.core.parameterization.param import Param from GPy.core.mapping import Mapping + self.setup() + class Parabola(Mapping): def __init__(self, variance, degree=2, name="parabola"): super(Parabola, self).__init__(1, 1, name) @@ -111,8 +119,3 @@ class Test(unittest.TestCase): m.randomize() assert m.checkgrad() _ = m.predict(m.X) - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.testName'] - unittest.main() From d88ff47e37ff546c2157070fcef215016cf6970c Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 4 Oct 2023 21:37:35 +0200 Subject: [PATCH 013/101] format on save --- GPy/testing/gpy_kernels_state_space_tests.py | 1113 ++++++++++++++---- 1 file changed, 853 insertions(+), 260 deletions(-) diff --git a/GPy/testing/gpy_kernels_state_space_tests.py b/GPy/testing/gpy_kernels_state_space_tests.py index 1e48b168..f6013f79 100644 --- a/GPy/testing/gpy_kernels_state_space_tests.py +++ b/GPy/testing/gpy_kernels_state_space_tests.py @@ -8,315 +8,725 @@ import unittest import numpy as np import GPy import GPy.models.state_space_model as SS_model -from .state_space_main_tests import generate_x_points, generate_sine_data, \ - generate_linear_data, generate_brownian_data, generate_linear_plus_sin +from .state_space_main_tests import ( + generate_x_points, + generate_sine_data, + generate_linear_data, + generate_brownian_data, + generate_linear_plus_sin, +) from nose import SkipTest -#from state_space_main_tests import generate_x_points, generate_sine_data, \ +# from state_space_main_tests import generate_x_points, generate_sine_data, \ # generate_linear_data, generate_brownian_data, generate_linear_plus_sin + class StateSpaceKernelsTests(np.testing.TestCase): def setUp(self): pass - def run_for_model(self, X, Y, ss_kernel, kalman_filter_type = 'regular', - use_cython=False, check_gradients=True, - optimize=True, optimize_max_iters=250, predict_X=None, - compare_with_GP=True, gp_kernel=None, - mean_compare_decimal=10, var_compare_decimal=7): + def run_for_model( + self, + X, + Y, + ss_kernel, + kalman_filter_type="regular", + use_cython=False, + check_gradients=True, + optimize=True, + optimize_max_iters=250, + predict_X=None, + compare_with_GP=True, + gp_kernel=None, + mean_compare_decimal=10, + var_compare_decimal=7, + ): + m1 = SS_model.StateSpace( + X, + Y, + ss_kernel, + kalman_filter_type=kalman_filter_type, + use_cython=use_cython, + ) - m1 = SS_model.StateSpace(X,Y, ss_kernel, - kalman_filter_type=kalman_filter_type, - use_cython=use_cython) - - m1.likelihood[:] = Y.var()/100. + m1.likelihood[:] = Y.var() / 100.0 if check_gradients: self.assertTrue(m1.checkgrad()) - if 1:#optimize: - m1.optimize(optimizer='lbfgsb', max_iters=1) + if 1: # optimize: + m1.optimize(optimizer="lbfgsb", max_iters=1) if compare_with_GP and (predict_X is None): predict_X = X self.assertTrue(compare_with_GP) if compare_with_GP: - m2 = GPy.models.GPRegression(X,Y, gp_kernel) + m2 = GPy.models.GPRegression(X, Y, gp_kernel) m2[:] = m1[:] - if (predict_X is not None): + if predict_X is not None: x_pred_reg_1 = m1.predict(predict_X) x_quant_reg_1 = m1.predict_quantiles(predict_X) x_pred_reg_2 = m2.predict(predict_X) x_quant_reg_2 = m2.predict_quantiles(predict_X) - np.testing.assert_array_almost_equal(x_pred_reg_1[0], x_pred_reg_2[0], mean_compare_decimal) - np.testing.assert_array_almost_equal(x_pred_reg_1[1], x_pred_reg_2[1], var_compare_decimal) - np.testing.assert_array_almost_equal(x_quant_reg_1[0], x_quant_reg_2[0], mean_compare_decimal) - np.testing.assert_array_almost_equal(x_quant_reg_1[1], x_quant_reg_2[1], mean_compare_decimal) - np.testing.assert_array_almost_equal(m1.gradient, m2.gradient, var_compare_decimal) - np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), var_compare_decimal) + np.testing.assert_array_almost_equal( + x_pred_reg_1[0], x_pred_reg_2[0], mean_compare_decimal + ) + np.testing.assert_array_almost_equal( + x_pred_reg_1[1], x_pred_reg_2[1], var_compare_decimal + ) + np.testing.assert_array_almost_equal( + x_quant_reg_1[0], x_quant_reg_2[0], mean_compare_decimal + ) + np.testing.assert_array_almost_equal( + x_quant_reg_1[1], x_quant_reg_2[1], mean_compare_decimal + ) + np.testing.assert_array_almost_equal( + m1.gradient, m2.gradient, var_compare_decimal + ) + np.testing.assert_almost_equal( + m1.log_likelihood(), m2.log_likelihood(), var_compare_decimal + ) + def test_Matern32_kernel( + self, + ): + np.random.seed(234) # seed the random number generator + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - def test_Matern32_kernel(self,): - np.random.seed(234) # seed the random number generator - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + ss_kernel = GPy.kern.sde_Matern32( + 1, + active_dims=[ + 0, + ], + ) + gp_kernel = GPy.kern.Matern32( + 1, + active_dims=[ + 0, + ], + ) - ss_kernel = GPy.kern.sde_Matern32(1,active_dims=[0,]) - gp_kernel = GPy.kern.Matern32(1,active_dims=[0,]) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + predict_X=X, + compare_with_GP=True, + gp_kernel=gp_kernel, + mean_compare_decimal=5, + var_compare_decimal=5, + ) - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - predict_X=X, - compare_with_GP=True, - gp_kernel=gp_kernel, - mean_compare_decimal=5, var_compare_decimal=5) + def test_Matern52_kernel( + self, + ): + np.random.seed(234) # seed the random number generator + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - def test_Matern52_kernel(self,): - np.random.seed(234) # seed the random number generator - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + ss_kernel = GPy.kern.sde_Matern52( + 1, + active_dims=[ + 0, + ], + ) + gp_kernel = GPy.kern.Matern52( + 1, + active_dims=[ + 0, + ], + ) - ss_kernel = GPy.kern.sde_Matern52(1,active_dims=[0,]) - gp_kernel = GPy.kern.Matern52(1,active_dims=[0,]) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + optimize=True, + predict_X=X, + compare_with_GP=True, + gp_kernel=gp_kernel, + mean_compare_decimal=5, + var_compare_decimal=5, + ) - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - optimize = True, predict_X=X, - compare_with_GP=True, gp_kernel=gp_kernel, - mean_compare_decimal=5, var_compare_decimal=5) + def test_RBF_kernel( + self, + ): + # import pdb;pdb.set_trace() - def test_RBF_kernel(self,): - #import pdb;pdb.set_trace() - - np.random.seed(234) # seed the random number generator - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + np.random.seed(234) # seed the random number generator + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - ss_kernel = GPy.kern.sde_RBF(1, 110., 1.5, active_dims=[0,], balance=True, approx_order=10) - gp_kernel = GPy.kern.RBF(1, 110., 1.5, active_dims=[0,]) + ss_kernel = GPy.kern.sde_RBF( + 1, + 110.0, + 1.5, + active_dims=[ + 0, + ], + balance=True, + approx_order=10, + ) + gp_kernel = GPy.kern.RBF( + 1, + 110.0, + 1.5, + active_dims=[ + 0, + ], + ) - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - optimize_max_iters=1000, - mean_compare_decimal=2, var_compare_decimal=1) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + optimize_max_iters=1000, + mean_compare_decimal=2, + var_compare_decimal=1, + ) - def test_periodic_kernel(self,): - np.random.seed(322) # seed the random number generator - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + def test_periodic_kernel( + self, + ): + np.random.seed(322) # seed the random number generator + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - ss_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) + ss_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) ss_kernel.lengthscale.constrain_bounded(0.27, 1000) ss_kernel.period.constrain_bounded(0.17, 100) - gp_kernel = GPy.kern.StdPeriodic(1,active_dims=[0,]) + gp_kernel = GPy.kern.StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) gp_kernel.lengthscale.constrain_bounded(0.27, 1000) gp_kernel.period.constrain_bounded(0.17, 100) - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=3, var_compare_decimal=3) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=3, + var_compare_decimal=3, + ) - def test_quasi_periodic_kernel(self,): - np.random.seed(329) # seed the random number generator - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + def test_quasi_periodic_kernel( + self, + ): + np.random.seed(329) # seed the random number generator + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - ss_kernel = GPy.kern.sde_Matern32(1)*GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) + ss_kernel = GPy.kern.sde_Matern32(1) * GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) ss_kernel.std_periodic.period.constrain_bounded(0.15, 100) - gp_kernel = GPy.kern.Matern32(1)*GPy.kern.StdPeriodic(1,active_dims=[0,]) + gp_kernel = GPy.kern.Matern32(1) * GPy.kern.StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) gp_kernel.std_periodic.period.constrain_bounded(0.15, 100) - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=1, var_compare_decimal=2) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=1, + var_compare_decimal=2, + ) - def test_linear_kernel(self,): + def test_linear_kernel( + self, + ): + np.random.seed(234) # seed the random number generator + (X, Y) = generate_linear_data( + x_points=None, + tangent=2.0, + add_term=20.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) - np.random.seed(234) # seed the random number generator - (X,Y) = generate_linear_data(x_points=None, tangent=2.0, add_term=20.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + ss_kernel = GPy.kern.sde_Linear( + 1, + X, + active_dims=[ + 0, + ], + ) + GPy.kern.sde_Bias( + 1, + active_dims=[ + 0, + ], + ) + gp_kernel = GPy.kern.Linear( + 1, + active_dims=[ + 0, + ], + ) + GPy.kern.Bias( + 1, + active_dims=[ + 0, + ], + ) - ss_kernel = GPy.kern.sde_Linear(1,X,active_dims=[0,]) + GPy.kern.sde_Bias(1, active_dims=[0,]) - gp_kernel = GPy.kern.Linear(1, active_dims=[0,]) + GPy.kern.Bias(1, active_dims=[0,]) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=False, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=5, + var_compare_decimal=5, + ) - self.run_for_model(X, Y, ss_kernel, check_gradients= False, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=5, var_compare_decimal=5) + def test_brownian_kernel( + self, + ): + np.random.seed(234) # seed the random number generator + (X, Y) = generate_brownian_data( + x_points=None, + kernel_var=2.0, + noise_var=0.1, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) - def test_brownian_kernel(self,): - np.random.seed(234) # seed the random number generator - (X,Y) = generate_brownian_data(x_points=None, kernel_var=2.0, noise_var = 0.1, - plot = False, points_num=50, x_interval = (0, 20), random=True) - - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) ss_kernel = GPy.kern.sde_Brownian() gp_kernel = GPy.kern.Brownian() - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=4, var_compare_decimal=4) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=4, + var_compare_decimal=4, + ) - def test_exponential_kernel(self,): - np.random.seed(12345) # seed the random number generator - (X,Y) = generate_linear_data(x_points=None, tangent=1.0, add_term=20.0, noise_var=2.0, - plot = False, points_num=10, x_interval = (0, 20), random=True) + def test_exponential_kernel( + self, + ): + np.random.seed(12345) # seed the random number generator + (X, Y) = generate_linear_data( + x_points=None, + tangent=1.0, + add_term=20.0, + noise_var=2.0, + plot=False, + points_num=10, + x_interval=(0, 20), + random=True, + ) - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) - ss_kernel = GPy.kern.sde_Exponential(1, Y.var(), X.ptp()/2., active_dims=[0,]) - gp_kernel = GPy.kern.Exponential(1, Y.var(), X.ptp()/2., active_dims=[0,]) + ss_kernel = GPy.kern.sde_Exponential( + 1, + Y.var(), + X.ptp() / 2.0, + active_dims=[ + 0, + ], + ) + gp_kernel = GPy.kern.Exponential( + 1, + Y.var(), + X.ptp() / 2.0, + active_dims=[ + 0, + ], + ) Y -= Y.mean() - self.run_for_model(X, Y, ss_kernel, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - optimize_max_iters=1000, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X, + Y, + ss_kernel, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + optimize_max_iters=1000, + mean_compare_decimal=2, + var_compare_decimal=2, + ) - def test_kernel_addition_svd(self,): - #np.random.seed(329) # seed the random number generator + def test_kernel_addition_svd( + self, + ): + # np.random.seed(329) # seed the random number generator np.random.seed(42) - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=5.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=5.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) - (X1,Y1) = generate_linear_data(x_points=X, tangent=1.0, add_term=20.0, noise_var=0.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X1, Y1) = generate_linear_data( + x_points=X, + tangent=1.0, + add_term=20.0, + noise_var=0.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) # Sine data <- Y = Y + Y1 Y -= Y.mean() - - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) def get_new_kernels(): - ss_kernel = GPy.kern.sde_Linear(1, X, variances=1) + GPy.kern.sde_StdPeriodic(1, period=5.0, variance=300, lengthscale=3, active_dims=[0,]) - #ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) - #ss_kernel.std_periodic.period.constrain_bounded(3, 8) + ss_kernel = GPy.kern.sde_Linear( + 1, X, variances=1 + ) + GPy.kern.sde_StdPeriodic( + 1, + period=5.0, + variance=300, + lengthscale=3, + active_dims=[ + 0, + ], + ) + # ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) + # ss_kernel.std_periodic.period.constrain_bounded(3, 8) - gp_kernel = GPy.kern.Linear(1, variances=1) + GPy.kern.StdPeriodic(1, period=5.0, variance=300, lengthscale=3, active_dims=[0,]) - #gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) - #gp_kernel.std_periodic.period.constrain_bounded(3, 8) + gp_kernel = GPy.kern.Linear(1, variances=1) + GPy.kern.StdPeriodic( + 1, + period=5.0, + variance=300, + lengthscale=3, + active_dims=[ + 0, + ], + ) + # gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) + # gp_kernel.std_periodic.period.constrain_bounded(3, 8) return ss_kernel, gp_kernel # Cython is available only with svd. ss_kernel, gp_kernel = get_new_kernels() - self.run_for_model(X, Y, ss_kernel, kalman_filter_type = 'svd', - use_cython=True, optimize_max_iters=10, check_gradients=False, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=3, var_compare_decimal=3) + self.run_for_model( + X, + Y, + ss_kernel, + kalman_filter_type="svd", + use_cython=True, + optimize_max_iters=10, + check_gradients=False, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=3, + var_compare_decimal=3, + ) ss_kernel, gp_kernel = get_new_kernels() - self.run_for_model(X, Y, ss_kernel, kalman_filter_type = 'svd', - use_cython=False, optimize_max_iters=10, check_gradients=False, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=3, var_compare_decimal=3) + self.run_for_model( + X, + Y, + ss_kernel, + kalman_filter_type="svd", + use_cython=False, + optimize_max_iters=10, + check_gradients=False, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=3, + var_compare_decimal=3, + ) - def test_kernel_addition_regular(self,): - #np.random.seed(329) # seed the random number generator + def test_kernel_addition_regular( + self, + ): + # np.random.seed(329) # seed the random number generator np.random.seed(42) - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=5.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=5.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) - (X1,Y1) = generate_linear_data(x_points=X, tangent=1.0, add_term=20.0, noise_var=0.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X1, Y1) = generate_linear_data( + x_points=X, + tangent=1.0, + add_term=20.0, + noise_var=0.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) # Sine data <- Y = Y + Y1 Y -= Y.mean() - - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) def get_new_kernels(): - ss_kernel = GPy.kern.sde_Linear(1, X, variances=1) + GPy.kern.sde_StdPeriodic(1, period=5.0, variance=300, lengthscale=3, active_dims=[0,]) - #ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) - #ss_kernel.std_periodic.period.constrain_bounded(3, 8) + ss_kernel = GPy.kern.sde_Linear( + 1, X, variances=1 + ) + GPy.kern.sde_StdPeriodic( + 1, + period=5.0, + variance=300, + lengthscale=3, + active_dims=[ + 0, + ], + ) + # ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) + # ss_kernel.std_periodic.period.constrain_bounded(3, 8) - gp_kernel = GPy.kern.Linear(1, variances=1) + GPy.kern.StdPeriodic(1, period=5.0, variance=300, lengthscale=3, active_dims=[0,]) - #gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) - #gp_kernel.std_periodic.period.constrain_bounded(3, 8) + gp_kernel = GPy.kern.Linear(1, variances=1) + GPy.kern.StdPeriodic( + 1, + period=5.0, + variance=300, + lengthscale=3, + active_dims=[ + 0, + ], + ) + # gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) + # gp_kernel.std_periodic.period.constrain_bounded(3, 8) return ss_kernel, gp_kernel ss_kernel, gp_kernel = get_new_kernels() try: - self.run_for_model(X, Y, ss_kernel, kalman_filter_type = 'regular', - use_cython=False, optimize_max_iters=10, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X, + Y, + ss_kernel, + kalman_filter_type="regular", + use_cython=False, + optimize_max_iters=10, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) except AssertionError: - raise SkipTest("Skipping Regular kalman filter for kernel addition, because it is not stable (normal situation) for this data.") + raise SkipTest( + "Skipping Regular kalman filter for kernel addition, because it is not stable (normal situation) for this data." + ) + def test_kernel_multiplication( + self, + ): + np.random.seed(329) # seed the random number generator + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=50, + x_interval=(0, 20), + random=True, + ) - def test_kernel_multiplication(self,): - np.random.seed(329) # seed the random number generator - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=50, x_interval = (0, 20), random=True) - - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) def get_new_kernels(): - ss_kernel = GPy.kern.sde_Matern32(1)*GPy.kern.sde_Matern52(1) - gp_kernel = GPy.kern.Matern32(1)*GPy.kern.sde_Matern52(1) + ss_kernel = GPy.kern.sde_Matern32(1) * GPy.kern.sde_Matern52(1) + gp_kernel = GPy.kern.Matern32(1) * GPy.kern.sde_Matern52(1) return ss_kernel, gp_kernel ss_kernel, gp_kernel = get_new_kernels() - #import ipdb;ipdb.set_trace() - self.run_for_model(X, Y, ss_kernel, kalman_filter_type = 'svd', - use_cython=True, optimize_max_iters=10, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + # import ipdb;ipdb.set_trace() + self.run_for_model( + X, + Y, + ss_kernel, + kalman_filter_type="svd", + use_cython=True, + optimize_max_iters=10, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) ss_kernel, gp_kernel = get_new_kernels() - self.run_for_model(X, Y, ss_kernel, kalman_filter_type = 'regular', - use_cython=False, optimize_max_iters=10, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X, + Y, + ss_kernel, + kalman_filter_type="regular", + use_cython=False, + optimize_max_iters=10, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) ss_kernel, gp_kernel = get_new_kernels() - self.run_for_model(X, Y, ss_kernel, kalman_filter_type = 'svd', - use_cython=False, optimize_max_iters=10, check_gradients=True, - predict_X=X, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X, + Y, + ss_kernel, + kalman_filter_type="svd", + use_cython=False, + optimize_max_iters=10, + check_gradients=True, + predict_X=X, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) - def test_forecast_regular(self,): + def test_forecast_regular( + self, + ): # Generate data -> - np.random.seed(339) # seed the random number generator - #import pdb; pdb.set_trace() - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=5.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + np.random.seed(339) # seed the random number generator + # import pdb; pdb.set_trace() + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=5.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) - (X1,Y1) = generate_linear_data(x_points=X, tangent=1.0, add_term=20.0, noise_var=0.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X1, Y1) = generate_linear_data( + x_points=X, + tangent=1.0, + add_term=20.0, + noise_var=0.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) Y = Y + Y1 @@ -325,40 +735,107 @@ class StateSpaceKernelsTests(np.testing.TestCase): X_test = X[X > 20] Y_test = Y[X > 20] - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) - X_train.shape = (X_train.shape[0],1); Y_train.shape = (Y_train.shape[0],1) - X_test.shape = (X_test.shape[0],1); Y_test.shape = (Y_test.shape[0],1) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) + X_train.shape = (X_train.shape[0], 1) + Y_train.shape = (Y_train.shape[0], 1) + X_test.shape = (X_test.shape[0], 1) + Y_test.shape = (Y_test.shape[0], 1) # Generate data <- - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() - periodic_kernel = GPy.kern.StdPeriodic(1,active_dims=[0,]) - gp_kernel = GPy.kern.Linear(1, active_dims=[0,]) + GPy.kern.Bias(1, active_dims=[0,]) + periodic_kernel + periodic_kernel = GPy.kern.StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + gp_kernel = ( + GPy.kern.Linear( + 1, + active_dims=[ + 0, + ], + ) + + GPy.kern.Bias( + 1, + active_dims=[ + 0, + ], + ) + + periodic_kernel + ) gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) gp_kernel.std_periodic.period.constrain_bounded(0.15, 100) - periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) - ss_kernel = GPy.kern.sde_Linear(1,X,active_dims=[0,]) + \ - GPy.kern.sde_Bias(1, active_dims=[0,]) + periodic_kernel + periodic_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + ss_kernel = ( + GPy.kern.sde_Linear( + 1, + X, + active_dims=[ + 0, + ], + ) + + GPy.kern.sde_Bias( + 1, + active_dims=[ + 0, + ], + ) + + periodic_kernel + ) ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) ss_kernel.std_periodic.period.constrain_bounded(0.15, 100) - self.run_for_model(X_train, Y_train, ss_kernel, kalman_filter_type = 'regular', - use_cython=False, optimize_max_iters=30, check_gradients=True, - predict_X=X_test, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X_train, + Y_train, + ss_kernel, + kalman_filter_type="regular", + use_cython=False, + optimize_max_iters=30, + check_gradients=True, + predict_X=X_test, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) - def test_forecast_svd(self,): + def test_forecast_svd( + self, + ): # Generate data -> - np.random.seed(339) # seed the random number generator - #import pdb; pdb.set_trace() - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=5.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + np.random.seed(339) # seed the random number generator + # import pdb; pdb.set_trace() + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=5.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) - (X1,Y1) = generate_linear_data(x_points=X, tangent=1.0, add_term=20.0, noise_var=0.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X1, Y1) = generate_linear_data( + x_points=X, + tangent=1.0, + add_term=20.0, + noise_var=0.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) Y = Y + Y1 @@ -367,40 +844,107 @@ class StateSpaceKernelsTests(np.testing.TestCase): X_test = X[X > 20] Y_test = Y[X > 20] - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) - X_train.shape = (X_train.shape[0],1); Y_train.shape = (Y_train.shape[0],1) - X_test.shape = (X_test.shape[0],1); Y_test.shape = (Y_test.shape[0],1) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) + X_train.shape = (X_train.shape[0], 1) + Y_train.shape = (Y_train.shape[0], 1) + X_test.shape = (X_test.shape[0], 1) + Y_test.shape = (Y_test.shape[0], 1) # Generate data <- - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() - periodic_kernel = GPy.kern.StdPeriodic(1,active_dims=[0,]) - gp_kernel = GPy.kern.Linear(1, active_dims=[0,]) + GPy.kern.Bias(1, active_dims=[0,]) + periodic_kernel + periodic_kernel = GPy.kern.StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + gp_kernel = ( + GPy.kern.Linear( + 1, + active_dims=[ + 0, + ], + ) + + GPy.kern.Bias( + 1, + active_dims=[ + 0, + ], + ) + + periodic_kernel + ) gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) gp_kernel.std_periodic.period.constrain_bounded(0.15, 100) - periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) - ss_kernel = GPy.kern.sde_Linear(1,X,active_dims=[0,]) + \ - GPy.kern.sde_Bias(1, active_dims=[0,]) + periodic_kernel + periodic_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + ss_kernel = ( + GPy.kern.sde_Linear( + 1, + X, + active_dims=[ + 0, + ], + ) + + GPy.kern.sde_Bias( + 1, + active_dims=[ + 0, + ], + ) + + periodic_kernel + ) ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) ss_kernel.std_periodic.period.constrain_bounded(0.15, 100) - self.run_for_model(X_train, Y_train, ss_kernel, kalman_filter_type = 'svd', - use_cython=False, optimize_max_iters=30, check_gradients=False, - predict_X=X_test, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X_train, + Y_train, + ss_kernel, + kalman_filter_type="svd", + use_cython=False, + optimize_max_iters=30, + check_gradients=False, + predict_X=X_test, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) - def test_forecast_svd_cython(self,): + def test_forecast_svd_cython( + self, + ): # Generate data -> - np.random.seed(339) # seed the random number generator - #import pdb; pdb.set_trace() - (X,Y) = generate_sine_data(x_points=None, sin_period=5.0, sin_ampl=5.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + np.random.seed(339) # seed the random number generator + # import pdb; pdb.set_trace() + (X, Y) = generate_sine_data( + x_points=None, + sin_period=5.0, + sin_ampl=5.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) - (X1,Y1) = generate_linear_data(x_points=X, tangent=1.0, add_term=20.0, noise_var=0.0, - plot = False, points_num=100, x_interval = (0, 40), random=True) + (X1, Y1) = generate_linear_data( + x_points=X, + tangent=1.0, + add_term=20.0, + noise_var=0.0, + plot=False, + points_num=100, + x_interval=(0, 40), + random=True, + ) Y = Y + Y1 @@ -409,46 +953,95 @@ class StateSpaceKernelsTests(np.testing.TestCase): X_test = X[X > 20] Y_test = Y[X > 20] - X.shape = (X.shape[0],1); Y.shape = (Y.shape[0],1) - X_train.shape = (X_train.shape[0],1); Y_train.shape = (Y_train.shape[0],1) - X_test.shape = (X_test.shape[0],1); Y_test.shape = (Y_test.shape[0],1) + X.shape = (X.shape[0], 1) + Y.shape = (Y.shape[0], 1) + X_train.shape = (X_train.shape[0], 1) + Y_train.shape = (Y_train.shape[0], 1) + X_test.shape = (X_test.shape[0], 1) + Y_test.shape = (Y_test.shape[0], 1) # Generate data <- - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() - periodic_kernel = GPy.kern.StdPeriodic(1,active_dims=[0,]) - gp_kernel = GPy.kern.Linear(1, active_dims=[0,]) + GPy.kern.Bias(1, active_dims=[0,]) + periodic_kernel + periodic_kernel = GPy.kern.StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + gp_kernel = ( + GPy.kern.Linear( + 1, + active_dims=[ + 0, + ], + ) + + GPy.kern.Bias( + 1, + active_dims=[ + 0, + ], + ) + + periodic_kernel + ) gp_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) gp_kernel.std_periodic.period.constrain_bounded(0.15, 100) - periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) - ss_kernel = GPy.kern.sde_Linear(1,X,active_dims=[0,]) + \ - GPy.kern.sde_Bias(1, active_dims=[0,]) + periodic_kernel + periodic_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + ss_kernel = ( + GPy.kern.sde_Linear( + 1, + X, + active_dims=[ + 0, + ], + ) + + GPy.kern.sde_Bias( + 1, + active_dims=[ + 0, + ], + ) + + periodic_kernel + ) ss_kernel.std_periodic.lengthscale.constrain_bounded(0.25, 1000) ss_kernel.std_periodic.period.constrain_bounded(0.15, 100) - self.run_for_model(X_train, Y_train, ss_kernel, kalman_filter_type = 'svd', - use_cython=True, optimize_max_iters=30, check_gradients=False, - predict_X=X_test, - gp_kernel=gp_kernel, - mean_compare_decimal=2, var_compare_decimal=2) + self.run_for_model( + X_train, + Y_train, + ss_kernel, + kalman_filter_type="svd", + use_cython=True, + optimize_max_iters=30, + check_gradients=False, + predict_X=X_test, + gp_kernel=gp_kernel, + mean_compare_decimal=2, + var_compare_decimal=2, + ) + if __name__ == "__main__": print("Running state-space inference tests...") unittest.main() - #tt = StateSpaceKernelsTests('test_RBF_kernel') - #import pdb; pdb.set_trace() - #tt.test_Matern32_kernel() - #tt.test_Matern52_kernel() - #tt.test_RBF_kernel() - #tt.test_periodic_kernel() - #tt.test_quasi_periodic_kernel() - #tt.test_linear_kernel() - #tt.test_brownian_kernel() - #tt.test_exponential_kernel() - #tt.test_kernel_addition() - #tt.test_kernel_multiplication() - #tt.test_forecast() - + # tt = StateSpaceKernelsTests('test_RBF_kernel') + # import pdb; pdb.set_trace() + # tt.test_Matern32_kernel() + # tt.test_Matern52_kernel() + # tt.test_RBF_kernel() + # tt.test_periodic_kernel() + # tt.test_quasi_periodic_kernel() + # tt.test_linear_kernel() + # tt.test_brownian_kernel() + # tt.test_exponential_kernel() + # tt.test_kernel_addition() + # tt.test_kernel_multiplication() + # tt.test_forecast() From 6fcb9e48fdde4d969bed2ada06565aade5696956 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:06:52 +0200 Subject: [PATCH 014/101] migrate gpy_kernsl-state_space_tests --- GPy/testing/gpy_kernels_state_space_tests.py | 34 ++++---------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/GPy/testing/gpy_kernels_state_space_tests.py b/GPy/testing/gpy_kernels_state_space_tests.py index f6013f79..f5a3f89e 100644 --- a/GPy/testing/gpy_kernels_state_space_tests.py +++ b/GPy/testing/gpy_kernels_state_space_tests.py @@ -21,10 +21,7 @@ from nose import SkipTest # generate_linear_data, generate_brownian_data, generate_linear_plus_sin -class StateSpaceKernelsTests(np.testing.TestCase): - def setUp(self): - pass - +class TestStateSpaceKernels: def run_for_model( self, X, @@ -52,7 +49,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): m1.likelihood[:] = Y.var() / 100.0 if check_gradients: - self.assertTrue(m1.checkgrad()) + assert m1.checkgrad() if 1: # optimize: m1.optimize(optimizer="lbfgsb", max_iters=1) @@ -60,7 +57,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): if compare_with_GP and (predict_X is None): predict_X = X - self.assertTrue(compare_with_GP) + assert compare_with_GP if compare_with_GP: m2 = GPy.models.GPRegression(X, Y, gp_kernel) @@ -92,7 +89,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): m1.log_likelihood(), m2.log_likelihood(), var_compare_decimal ) - def test_Matern32_kernel( + def test_matern32_kernel( self, ): np.random.seed(234) # seed the random number generator @@ -134,7 +131,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): var_compare_decimal=5, ) - def test_Matern52_kernel( + def test_matern52_kernel( self, ): np.random.seed(234) # seed the random number generator @@ -177,7 +174,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): var_compare_decimal=5, ) - def test_RBF_kernel( + def test_rbf_kernel( self, ): # import pdb;pdb.set_trace() @@ -1026,22 +1023,3 @@ class StateSpaceKernelsTests(np.testing.TestCase): mean_compare_decimal=2, var_compare_decimal=2, ) - - -if __name__ == "__main__": - print("Running state-space inference tests...") - unittest.main() - - # tt = StateSpaceKernelsTests('test_RBF_kernel') - # import pdb; pdb.set_trace() - # tt.test_Matern32_kernel() - # tt.test_Matern52_kernel() - # tt.test_RBF_kernel() - # tt.test_periodic_kernel() - # tt.test_quasi_periodic_kernel() - # tt.test_linear_kernel() - # tt.test_brownian_kernel() - # tt.test_exponential_kernel() - # tt.test_kernel_addition() - # tt.test_kernel_multiplication() - # tt.test_forecast() From 2568201d1b87c1187ccf0d0519671059b2d1ec5e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:12:38 +0200 Subject: [PATCH 015/101] format on save --- GPy/testing/grid_tests.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/GPy/testing/grid_tests.py b/GPy/testing/grid_tests.py index e55efb18..c6aaf049 100644 --- a/GPy/testing/grid_tests.py +++ b/GPy/testing/grid_tests.py @@ -7,13 +7,25 @@ import unittest import numpy as np import GPy + class GridModelTest(unittest.TestCase): def setUp(self): ###################################### # # 3 dimensional example # sample inputs and outputs - self.X = np.array([[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]) + self.X = np.array( + [ + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ] + ) self.Y = np.random.randn(8, 1) * 100 self.dim = self.X.shape[1] @@ -33,10 +45,15 @@ class GridModelTest(unittest.TestCase): kernel2 = GPy.kern.RBF(input_dim=self.dim, variance=1, ARD=True) m2 = GPy.models.GPRegression(self.X, self.Y, kernel2) - np.testing.assert_almost_equal(kernel.variance.gradient, kernel2.variance.gradient) - np.testing.assert_almost_equal(kernel.lengthscale.gradient, kernel2.lengthscale.gradient) - np.testing.assert_almost_equal(m.likelihood.variance.gradient, m2.likelihood.variance.gradient) - + np.testing.assert_almost_equal( + kernel.variance.gradient, kernel2.variance.gradient + ) + np.testing.assert_almost_equal( + kernel.lengthscale.gradient, kernel2.lengthscale.gradient + ) + np.testing.assert_almost_equal( + m.likelihood.variance.gradient, m2.likelihood.variance.gradient + ) def test_prediction_match(self): kernel = GPy.kern.RBF(input_dim=self.dim, variance=1, ARD=True) @@ -45,7 +62,6 @@ class GridModelTest(unittest.TestCase): kernel2 = GPy.kern.RBF(input_dim=self.dim, variance=1, ARD=True) m2 = GPy.models.GPRegression(self.X, self.Y, kernel2) - test = np.array([[0,0,2],[-1,3,-4]]) + test = np.array([[0, 0, 2], [-1, 3, -4]]) np.testing.assert_almost_equal(m.predict(test), m2.predict(test)) - From 779f31da9c4ddb5ace48403c4b2cf9aa721477d0 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:13:24 +0200 Subject: [PATCH 016/101] migrate grid tests to pytest --- GPy/testing/grid_tests.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/GPy/testing/grid_tests.py b/GPy/testing/grid_tests.py index c6aaf049..7739f233 100644 --- a/GPy/testing/grid_tests.py +++ b/GPy/testing/grid_tests.py @@ -3,13 +3,12 @@ # Kurt Cutajar -import unittest import numpy as np import GPy -class GridModelTest(unittest.TestCase): - def setUp(self): +class GridModelTest: + def setup(self): ###################################### # # 3 dimensional example From 0b92d3a57c14c03ee3a4830fd44b3b01b39c3b7f Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:13:42 +0200 Subject: [PATCH 017/101] format on save --- GPy/testing/inference_tests.py | 237 +++++++++++++++++++++++---------- 1 file changed, 169 insertions(+), 68 deletions(-) diff --git a/GPy/testing/inference_tests.py b/GPy/testing/inference_tests.py index 28156053..fcb4bd39 100644 --- a/GPy/testing/inference_tests.py +++ b/GPy/testing/inference_tests.py @@ -8,18 +8,21 @@ The test cases for various inference algorithms import unittest import numpy as np import GPy -#np.seterr(invalid='raise') + +# np.seterr(invalid='raise') + class InferenceXTestCase(unittest.TestCase): - def genData(self): np.random.seed(1111) - Ylist = GPy.examples.dimensionality_reduction._simulate_matern(5, 1, 1, 10, 3, False)[0] + Ylist = GPy.examples.dimensionality_reduction._simulate_matern( + 5, 1, 1, 10, 3, False + )[0] return Ylist[0] def test_inferenceX_BGPLVM_Linear(self): Ys = self.genData() - m = GPy.models.BayesianGPLVM(Ys,3,kernel=GPy.kern.Linear(3,ARD=True)) + m = GPy.models.BayesianGPLVM(Ys, 3, kernel=GPy.kern.Linear(3, ARD=True)) m.optimize() x, mi = m.infer_newX(m.Y, optimize=True) np.testing.assert_array_almost_equal(m.X.mean, mi.X.mean, decimal=2) @@ -27,8 +30,9 @@ class InferenceXTestCase(unittest.TestCase): def test_inferenceX_BGPLVM_RBF(self): Ys = self.genData() - m = GPy.models.BayesianGPLVM(Ys,3,kernel=GPy.kern.RBF(3,ARD=True)) + m = GPy.models.BayesianGPLVM(Ys, 3, kernel=GPy.kern.RBF(3, ARD=True)) import warnings + with warnings.catch_warnings(): warnings.simplefilter("ignore") m.optimize() @@ -38,67 +42,110 @@ class InferenceXTestCase(unittest.TestCase): def test_inferenceX_GPLVM_Linear(self): Ys = self.genData() - m = GPy.models.GPLVM(Ys,3,kernel=GPy.kern.Linear(3,ARD=True)) + m = GPy.models.GPLVM(Ys, 3, kernel=GPy.kern.Linear(3, ARD=True)) m.optimize() x, mi = m.infer_newX(m.Y, optimize=True) np.testing.assert_array_almost_equal(m.X, mi.X, decimal=2) def test_inferenceX_GPLVM_RBF(self): Ys = self.genData() - m = GPy.models.GPLVM(Ys,3,kernel=GPy.kern.RBF(3,ARD=True)) + m = GPy.models.GPLVM(Ys, 3, kernel=GPy.kern.RBF(3, ARD=True)) m.optimize() x, mi = m.infer_newX(m.Y, optimize=True) np.testing.assert_array_almost_equal(m.X, mi.X, decimal=2) -class InferenceGPEP(unittest.TestCase): +class InferenceGPEP(unittest.TestCase): def genData(self): np.random.seed(1) - k = GPy.kern.RBF(1, variance=7., lengthscale=0.2) - X = np.random.rand(200,1) - f = np.random.multivariate_normal(np.zeros(200), k.K(X) + 1e-5 * np.eye(X.shape[0])) + k = GPy.kern.RBF(1, variance=7.0, lengthscale=0.2) + X = np.random.rand(200, 1) + f = np.random.multivariate_normal( + np.zeros(200), k.K(X) + 1e-5 * np.eye(X.shape[0]) + ) lik = GPy.likelihoods.Bernoulli() - p = lik.gp_link.transf(f) # squash the latent function - Y = lik.samples(f).reshape(-1,1) + p = lik.gp_link.transf(f) # squash the latent function + Y = lik.samples(f).reshape(-1, 1) return X, Y def genNoisyData(self): np.random.seed(1) - X = np.random.rand(100,1) + X = np.random.rand(100, 1) self.real_std = 0.1 - noise = np.random.randn(*X[:, 0].shape)*self.real_std - Y = (np.sin(X[:, 0]*2*np.pi) + noise)[:, None] - self.f = np.random.rand(X.shape[0],1) + noise = np.random.randn(*X[:, 0].shape) * self.real_std + Y = (np.sin(X[:, 0] * 2 * np.pi) + noise)[:, None] + self.f = np.random.rand(X.shape[0], 1) Y_extra_noisy = Y.copy() - Y_extra_noisy[50] += 4. + Y_extra_noisy[50] += 4.0 # Y_extra_noisy[80:83] -= 2. return X, Y, Y_extra_noisy def test_inference_EP(self): from paramz import ObsAr + X, Y = self.genData() lik = GPy.likelihoods.Bernoulli() - k = GPy.kern.RBF(1, variance=7., lengthscale=0.2) - inf = GPy.inference.latent_function_inference.expectation_propagation.EP(max_iters=30, delta=0.5) - self.model = GPy.core.GP(X=X, - Y=Y, - kernel=k, - inference_method=inf, - likelihood=lik) + k = GPy.kern.RBF(1, variance=7.0, lengthscale=0.2) + inf = GPy.inference.latent_function_inference.expectation_propagation.EP( + max_iters=30, delta=0.5 + ) + self.model = GPy.core.GP( + X=X, Y=Y, kernel=k, inference_method=inf, likelihood=lik + ) K = self.model.kern.K(X) mean_prior = np.zeros(K.shape[0]) - post_params, ga_approx, cav_params, log_Z_tilde = self.model.inference_method.expectation_propagation(mean_prior, K, ObsAr(Y), lik, None) + ( + post_params, + ga_approx, + cav_params, + log_Z_tilde, + ) = self.model.inference_method.expectation_propagation( + mean_prior, K, ObsAr(Y), lik, None + ) mu_tilde = ga_approx.v / ga_approx.tau.astype(float) - p, m, d = self.model.inference_method._inference(Y, mean_prior, K, ga_approx, cav_params, lik, Y_metadata=None, Z_tilde=log_Z_tilde) - p0, m0, d0 = super(GPy.inference.latent_function_inference.expectation_propagation.EP, inf).inference(k, X,lik ,mu_tilde[:,None], mean_function=None, variance=1./ga_approx.tau, K=K, Z_tilde=log_Z_tilde + np.sum(- 0.5*np.log(ga_approx.tau) + 0.5*(ga_approx.v*ga_approx.v*1./ga_approx.tau))) + p, m, d = self.model.inference_method._inference( + Y, + mean_prior, + K, + ga_approx, + cav_params, + lik, + Y_metadata=None, + Z_tilde=log_Z_tilde, + ) + p0, m0, d0 = super( + GPy.inference.latent_function_inference.expectation_propagation.EP, inf + ).inference( + k, + X, + lik, + mu_tilde[:, None], + mean_function=None, + variance=1.0 / ga_approx.tau, + K=K, + Z_tilde=log_Z_tilde + + np.sum( + -0.5 * np.log(ga_approx.tau) + + 0.5 * (ga_approx.v * ga_approx.v * 1.0 / ga_approx.tau) + ), + ) - assert (np.sum(np.array([m - m0, - np.sum(d['dL_dK'] - d0['dL_dK']), - np.sum(d['dL_dthetaL'] - d0['dL_dthetaL']), - np.sum(d['dL_dm'] - d0['dL_dm']), - np.sum(p._woodbury_vector - p0._woodbury_vector), - np.sum(p.woodbury_inv - p0.woodbury_inv)])) < 1e6) + assert ( + np.sum( + np.array( + [ + m - m0, + np.sum(d["dL_dK"] - d0["dL_dK"]), + np.sum(d["dL_dthetaL"] - d0["dL_dthetaL"]), + np.sum(d["dL_dm"] - d0["dL_dm"]), + np.sum(p._woodbury_vector - p0._woodbury_vector), + np.sum(p.woodbury_inv - p0.woodbury_inv), + ] + ) + ) + < 1e6 + ) # NOTE: adding a test like above for parameterized likelihood- the above test is # only for probit likelihood which does not have any tunable hyperparameter which is why @@ -110,70 +157,124 @@ class InferenceGPEP(unittest.TestCase): # and it is possible that any error might creep up because of quadrature implementation. def test_inference_EP_non_classification(self): from paramz import ObsAr + X, Y, Y_extra_noisy = self.genNoisyData() - deg_freedom = 5. + deg_freedom = 5.0 init_noise_var = 0.08 - lik_studentT = GPy.likelihoods.StudentT(deg_free=deg_freedom, sigma2=init_noise_var) + lik_studentT = GPy.likelihoods.StudentT( + deg_free=deg_freedom, sigma2=init_noise_var + ) # like_gaussian_noise = GPy.likelihoods.MixedNoise() - k = GPy.kern.RBF(1, variance=2., lengthscale=1.1) - ep_inf_alt = GPy.inference.latent_function_inference.expectation_propagation.EP(max_iters=4, delta=0.5) + k = GPy.kern.RBF(1, variance=2.0, lengthscale=1.1) + ep_inf_alt = GPy.inference.latent_function_inference.expectation_propagation.EP( + max_iters=4, delta=0.5 + ) # ep_inf_nested = GPy.inference.latent_function_inference.expectation_propagation.EP(ep_mode='nested', max_iters=100, delta=0.5) - m = GPy.core.GP(X=X,Y=Y_extra_noisy,kernel=k,likelihood=lik_studentT,inference_method=ep_inf_alt) + m = GPy.core.GP( + X=X, + Y=Y_extra_noisy, + kernel=k, + likelihood=lik_studentT, + inference_method=ep_inf_alt, + ) K = m.kern.K(X) mean_prior = np.zeros(K.shape[0]) - post_params, ga_approx, cav_params, log_Z_tilde = m.inference_method.expectation_propagation(mean_prior, K, ObsAr(Y_extra_noisy), lik_studentT, None) + ( + post_params, + ga_approx, + cav_params, + log_Z_tilde, + ) = m.inference_method.expectation_propagation( + mean_prior, K, ObsAr(Y_extra_noisy), lik_studentT, None + ) mu_tilde = ga_approx.v / ga_approx.tau.astype(float) - p, m, d = m.inference_method._inference(Y_extra_noisy, mean_prior, K, ga_approx, cav_params, lik_studentT, Y_metadata=None, Z_tilde=log_Z_tilde) - p0, m0, d0 = super(GPy.inference.latent_function_inference.expectation_propagation.EP, ep_inf_alt).inference(k, X,lik_studentT ,mu_tilde[:,None], mean_function=None, variance=1./ga_approx.tau, K=K, Z_tilde=log_Z_tilde + np.sum(- 0.5*np.log(ga_approx.tau) + 0.5*(ga_approx.v*ga_approx.v*1./ga_approx.tau))) + p, m, d = m.inference_method._inference( + Y_extra_noisy, + mean_prior, + K, + ga_approx, + cav_params, + lik_studentT, + Y_metadata=None, + Z_tilde=log_Z_tilde, + ) + p0, m0, d0 = super( + GPy.inference.latent_function_inference.expectation_propagation.EP, + ep_inf_alt, + ).inference( + k, + X, + lik_studentT, + mu_tilde[:, None], + mean_function=None, + variance=1.0 / ga_approx.tau, + K=K, + Z_tilde=log_Z_tilde + + np.sum( + -0.5 * np.log(ga_approx.tau) + + 0.5 * (ga_approx.v * ga_approx.v * 1.0 / ga_approx.tau) + ), + ) + + assert ( + np.sum( + np.array( + [ + m - m0, + np.sum(d["dL_dK"] - d0["dL_dK"]), + np.sum(d["dL_dthetaL"] - d0["dL_dthetaL"]), + np.sum(d["dL_dm"] - d0["dL_dm"]), + np.sum(p._woodbury_vector - p0._woodbury_vector), + np.sum(p.woodbury_inv - p0.woodbury_inv), + ] + ) + ) + < 1e6 + ) - assert (np.sum(np.array([m - m0, - np.sum(d['dL_dK'] - d0['dL_dK']), - np.sum(d['dL_dthetaL'] - d0['dL_dthetaL']), - np.sum(d['dL_dm'] - d0['dL_dm']), - np.sum(p._woodbury_vector - p0._woodbury_vector), - np.sum(p.woodbury_inv - p0.woodbury_inv)])) < 1e6) class VarDtcTest(unittest.TestCase): - def test_var_dtc_inference_with_mean(self): - """ Check dL_dm in var_dtc is calculated correctly""" + """Check dL_dm in var_dtc is calculated correctly""" np.random.seed(1) - x = np.linspace(0.,2*np.pi,100)[:,None] - y = -np.cos(x)+np.random.randn(*x.shape)*0.3+1 - m = GPy.models.SparseGPRegression(x,y, mean_function=GPy.mappings.Linear(input_dim=1, output_dim=1)) + x = np.linspace(0.0, 2 * np.pi, 100)[:, None] + y = -np.cos(x) + np.random.randn(*x.shape) * 0.3 + 1 + m = GPy.models.SparseGPRegression( + x, y, mean_function=GPy.mappings.Linear(input_dim=1, output_dim=1) + ) self.assertTrue(m.checkgrad()) class HMCSamplerTest(unittest.TestCase): - def test_sampling(self): np.random.seed(1) - x = np.linspace(0.,2*np.pi,100)[:,None] - y = -np.cos(x)+np.random.randn(*x.shape)*0.3+1 + x = np.linspace(0.0, 2 * np.pi, 100)[:, None] + y = -np.cos(x) + np.random.randn(*x.shape) * 0.3 + 1 - m = GPy.models.GPRegression(x,y) - m.kern.lengthscale.set_prior(GPy.priors.Gamma.from_EV(1.,10.)) - m.kern.variance.set_prior(GPy.priors.Gamma.from_EV(1.,10.)) - m.likelihood.variance.set_prior(GPy.priors.Gamma.from_EV(1.,10.)) + m = GPy.models.GPRegression(x, y) + m.kern.lengthscale.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) + m.kern.variance.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) + m.likelihood.variance.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) - hmc = GPy.inference.mcmc.HMC(m,stepsize=1e-2) + hmc = GPy.inference.mcmc.HMC(m, stepsize=1e-2) s = hmc.sample(num_samples=3) -class MCMCSamplerTest(unittest.TestCase): +class MCMCSamplerTest(unittest.TestCase): def test_sampling(self): np.random.seed(1) - x = np.linspace(0.,2*np.pi,100)[:,None] - y = -np.cos(x)+np.random.randn(*x.shape)*0.3+1 + x = np.linspace(0.0, 2 * np.pi, 100)[:, None] + y = -np.cos(x) + np.random.randn(*x.shape) * 0.3 + 1 - m = GPy.models.GPRegression(x,y) - m.kern.lengthscale.set_prior(GPy.priors.Gamma.from_EV(1.,10.)) - m.kern.variance.set_prior(GPy.priors.Gamma.from_EV(1.,10.)) - m.likelihood.variance.set_prior(GPy.priors.Gamma.from_EV(1.,10.)) + m = GPy.models.GPRegression(x, y) + m.kern.lengthscale.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) + m.kern.variance.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) + m.likelihood.variance.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) mcmc = GPy.inference.mcmc.Metropolis_Hastings(m) mcmc.sample(Ntotal=100, Nburn=10) + if __name__ == "__main__": unittest.main() From 03fcf7311db34143c4ccd27780c0be6eb8b04167 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:16:39 +0200 Subject: [PATCH 018/101] mirgrate inference_tests to pytest --- GPy/testing/inference_tests.py | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/GPy/testing/inference_tests.py b/GPy/testing/inference_tests.py index fcb4bd39..96be2834 100644 --- a/GPy/testing/inference_tests.py +++ b/GPy/testing/inference_tests.py @@ -12,8 +12,8 @@ import GPy # np.seterr(invalid='raise') -class InferenceXTestCase(unittest.TestCase): - def genData(self): +class TestInferenceXCase: + def get_data(self): np.random.seed(1111) Ylist = GPy.examples.dimensionality_reduction._simulate_matern( 5, 1, 1, 10, 3, False @@ -21,7 +21,7 @@ class InferenceXTestCase(unittest.TestCase): return Ylist[0] def test_inferenceX_BGPLVM_Linear(self): - Ys = self.genData() + Ys = self.get_data() m = GPy.models.BayesianGPLVM(Ys, 3, kernel=GPy.kern.Linear(3, ARD=True)) m.optimize() x, mi = m.infer_newX(m.Y, optimize=True) @@ -29,34 +29,34 @@ class InferenceXTestCase(unittest.TestCase): np.testing.assert_array_almost_equal(m.X.variance, mi.X.variance, decimal=2) def test_inferenceX_BGPLVM_RBF(self): - Ys = self.genData() + Ys = self.get_data() m = GPy.models.BayesianGPLVM(Ys, 3, kernel=GPy.kern.RBF(3, ARD=True)) import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") m.optimize() - x, mi = m.infer_newX(m.Y, optimize=True) + _x, mi = m.infer_newX(m.Y, optimize=True) np.testing.assert_array_almost_equal(m.X.mean, mi.X.mean, decimal=2) np.testing.assert_array_almost_equal(m.X.variance, mi.X.variance, decimal=2) def test_inferenceX_GPLVM_Linear(self): - Ys = self.genData() + Ys = self.get_data() m = GPy.models.GPLVM(Ys, 3, kernel=GPy.kern.Linear(3, ARD=True)) m.optimize() - x, mi = m.infer_newX(m.Y, optimize=True) + _x, mi = m.infer_newX(m.Y, optimize=True) np.testing.assert_array_almost_equal(m.X, mi.X, decimal=2) def test_inferenceX_GPLVM_RBF(self): - Ys = self.genData() + Ys = self.get_data() m = GPy.models.GPLVM(Ys, 3, kernel=GPy.kern.RBF(3, ARD=True)) m.optimize() - x, mi = m.infer_newX(m.Y, optimize=True) + _x, mi = m.infer_newX(m.Y, optimize=True) np.testing.assert_array_almost_equal(m.X, mi.X, decimal=2) -class InferenceGPEP(unittest.TestCase): - def genData(self): +class TestInferenceGPEP: + def get_data(self): np.random.seed(1) k = GPy.kern.RBF(1, variance=7.0, lengthscale=0.2) X = np.random.rand(200, 1) @@ -64,11 +64,11 @@ class InferenceGPEP(unittest.TestCase): np.zeros(200), k.K(X) + 1e-5 * np.eye(X.shape[0]) ) lik = GPy.likelihoods.Bernoulli() - p = lik.gp_link.transf(f) # squash the latent function + _p = lik.gp_link.transf(f) # squash the latent function Y = lik.samples(f).reshape(-1, 1) return X, Y - def genNoisyData(self): + def get_noisy_data(self): np.random.seed(1) X = np.random.rand(100, 1) self.real_std = 0.1 @@ -83,7 +83,7 @@ class InferenceGPEP(unittest.TestCase): def test_inference_EP(self): from paramz import ObsAr - X, Y = self.genData() + X, Y = self.get_data() lik = GPy.likelihoods.Bernoulli() k = GPy.kern.RBF(1, variance=7.0, lengthscale=0.2) inf = GPy.inference.latent_function_inference.expectation_propagation.EP( @@ -158,7 +158,7 @@ class InferenceGPEP(unittest.TestCase): def test_inference_EP_non_classification(self): from paramz import ObsAr - X, Y, Y_extra_noisy = self.genNoisyData() + X, _Y, Y_extra_noisy = self.get_noisy_data() deg_freedom = 5.0 init_noise_var = 0.08 lik_studentT = GPy.likelihoods.StudentT( @@ -234,7 +234,7 @@ class InferenceGPEP(unittest.TestCase): ) -class VarDtcTest(unittest.TestCase): +class TestVarDtc: def test_var_dtc_inference_with_mean(self): """Check dL_dm in var_dtc is calculated correctly""" np.random.seed(1) @@ -243,10 +243,10 @@ class VarDtcTest(unittest.TestCase): m = GPy.models.SparseGPRegression( x, y, mean_function=GPy.mappings.Linear(input_dim=1, output_dim=1) ) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() -class HMCSamplerTest(unittest.TestCase): +class TestHMCSampler: def test_sampling(self): np.random.seed(1) x = np.linspace(0.0, 2 * np.pi, 100)[:, None] @@ -258,10 +258,11 @@ class HMCSamplerTest(unittest.TestCase): m.likelihood.variance.set_prior(GPy.priors.Gamma.from_EV(1.0, 10.0)) hmc = GPy.inference.mcmc.HMC(m, stepsize=1e-2) - s = hmc.sample(num_samples=3) + _s = hmc.sample(num_samples=3) + # TODO: seems like there is no test here? -class MCMCSamplerTest(unittest.TestCase): +class TestMCMCSampler: def test_sampling(self): np.random.seed(1) x = np.linspace(0.0, 2 * np.pi, 100)[:, None] @@ -274,7 +275,4 @@ class MCMCSamplerTest(unittest.TestCase): mcmc = GPy.inference.mcmc.Metropolis_Hastings(m) mcmc.sample(Ntotal=100, Nburn=10) - - -if __name__ == "__main__": - unittest.main() + # TODO: seems like there is no test here? From a02f4039fa3f5f604a5b2551fa83169fff80d2e4 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:16:56 +0200 Subject: [PATCH 019/101] format on save --- GPy/testing/kernel_tests.py | 712 +++++++++++++++++++++++++----------- 1 file changed, 501 insertions(+), 211 deletions(-) diff --git a/GPy/testing/kernel_tests.py b/GPy/testing/kernel_tests.py index 6490f809..4f6016e0 100644 --- a/GPy/testing/kernel_tests.py +++ b/GPy/testing/kernel_tests.py @@ -15,7 +15,8 @@ verbose = 0 try: from ..kern.src import coregionalize_cython - cython_coregionalize_working = config.getboolean('cython', 'working') + + cython_coregionalize_working = config.getboolean("cython", "working") except ImportError: cython_coregionalize_working = False @@ -26,9 +27,10 @@ class Kern_check_model(GPy.core.Model): gradients of a given kernel are implemented correctly. It enables checkgrad() to be called independently on a kernel. """ + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): - super(Kern_check_model, self).__init__('kernel_test_model') - if kernel==None: + super(Kern_check_model, self).__init__("kernel_test_model") + if kernel == None: kernel = GPy.kern.RBF(1) kernel.randomize(loc=1, scale=0.1) if X is None: @@ -46,22 +48,26 @@ class Kern_check_model(GPy.core.Model): def is_positive_semi_definite(self): v = np.linalg.eig(self.kernel.K(self.X))[0] - if any(v.real<=-1e-10): + if any(v.real <= -1e-10): print(v.real.min()) return False else: return True def log_likelihood(self): - return np.sum(self.dL_dK*self.kernel.K(self.X, self.X2)) + return np.sum(self.dL_dK * self.kernel.K(self.X, self.X2)) + class Kern_check_dK_dtheta(Kern_check_model): """ This class allows gradient checks for the gradient of a kernel with respect to parameters. """ + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): - super(Kern_check_dK_dtheta, self).__init__(kernel=kernel,dL_dK=dL_dK, X=X, X2=X2) + super(Kern_check_dK_dtheta, self).__init__( + kernel=kernel, dL_dK=dL_dK, X=X, X2=X2 + ) self.link_parameter(self.kernel) def parameters_changed(self): @@ -73,42 +79,55 @@ class Kern_check_dKdiag_dtheta(Kern_check_model): This class allows gradient checks of the gradient of the diagonal of a kernel with respect to the parameters. """ + def __init__(self, kernel=None, dL_dK=None, X=None): - super(Kern_check_dKdiag_dtheta, self).__init__(kernel=kernel,dL_dK=dL_dK, X=X, X2=None) + super(Kern_check_dKdiag_dtheta, self).__init__( + kernel=kernel, dL_dK=dL_dK, X=X, X2=None + ) self.link_parameter(self.kernel) def log_likelihood(self): - return (np.diag(self.dL_dK)*self.kernel.Kdiag(self.X)).sum() + return (np.diag(self.dL_dK) * self.kernel.Kdiag(self.X)).sum() def parameters_changed(self): self.kernel.update_gradients_diag(np.diag(self.dL_dK), self.X) + class Kern_check_dK_dX(Kern_check_model): - """This class allows gradient checks for the gradient of a kernel with respect to X. """ + """This class allows gradient checks for the gradient of a kernel with respect to X.""" + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): - super(Kern_check_dK_dX, self).__init__(kernel=kernel,dL_dK=dL_dK, X=X, X2=X2) - self.X = Param('X',X) + super(Kern_check_dK_dX, self).__init__(kernel=kernel, dL_dK=dL_dK, X=X, X2=X2) + self.X = Param("X", X) self.link_parameter(self.X) def parameters_changed(self): - self.X.gradient[:] = self.kernel.gradients_X(self.dL_dK, self.X, self.X2) + self.X.gradient[:] = self.kernel.gradients_X(self.dL_dK, self.X, self.X2) + class Kern_check_dKdiag_dX(Kern_check_dK_dX): - """This class allows gradient checks for the gradient of a kernel diagonal with respect to X. """ + """This class allows gradient checks for the gradient of a kernel diagonal with respect to X.""" + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): - super(Kern_check_dKdiag_dX, self).__init__(kernel=kernel,dL_dK=dL_dK, X=X, X2=None) + super(Kern_check_dKdiag_dX, self).__init__( + kernel=kernel, dL_dK=dL_dK, X=X, X2=None + ) def log_likelihood(self): - return (np.diag(self.dL_dK)*self.kernel.Kdiag(self.X)).sum() + return (np.diag(self.dL_dK) * self.kernel.Kdiag(self.X)).sum() def parameters_changed(self): - self.X.gradient[:] = self.kernel.gradients_X_diag(self.dL_dK.diagonal(), self.X) + self.X.gradient[:] = self.kernel.gradients_X_diag(self.dL_dK.diagonal(), self.X) + class Kern_check_d2K_dXdX(Kern_check_model): - """This class allows gradient checks for the secondderivative of a kernel with respect to X. """ + """This class allows gradient checks for the secondderivative of a kernel with respect to X.""" + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): - super(Kern_check_d2K_dXdX, self).__init__(kernel=kernel,dL_dK=dL_dK, X=X, X2=X2) - self.X = Param('X',X.copy()) + super(Kern_check_d2K_dXdX, self).__init__( + kernel=kernel, dL_dK=dL_dK, X=X, X2=X2 + ) + self.X = Param("X", X.copy()) self.link_parameter(self.X) self.Xc = X.copy() @@ -118,33 +137,42 @@ class Kern_check_d2K_dXdX(Kern_check_model): return self.kernel.gradients_X(self.dL_dK, self.X, self.X2).sum() def parameters_changed(self): - #if self.kernel.name == 'rbf': + # if self.kernel.name == 'rbf': # import ipdb;ipdb.set_trace() if self.X2 is None: grads = -self.kernel.gradients_XX(self.dL_dK, self.X).sum(1).sum(1) else: - grads = -self.kernel.gradients_XX(self.dL_dK.T, self.X2, self.X).sum(0).sum(1) + grads = ( + -self.kernel.gradients_XX(self.dL_dK.T, self.X2, self.X).sum(0).sum(1) + ) self.X.gradient[:] = grads + class Kern_check_d2Kdiag_dXdX(Kern_check_model): - """This class allows gradient checks for the second derivative of a kernel with respect to X. """ + """This class allows gradient checks for the second derivative of a kernel with respect to X.""" + def __init__(self, kernel=None, dL_dK=None, X=None): - super(Kern_check_d2Kdiag_dXdX, self).__init__(kernel=kernel,dL_dK=dL_dK, X=X) - self.X = Param('X',X) + super(Kern_check_d2Kdiag_dXdX, self).__init__(kernel=kernel, dL_dK=dL_dK, X=X) + self.X = Param("X", X) self.link_parameter(self.X) self.Xc = X.copy() def log_likelihood(self): - l = 0. + l = 0.0 for i in range(self.X.shape[0]): - l += self.kernel.gradients_X(self.dL_dK[[i],[i]], self.X[[i]], self.Xc[[i]]).sum() + l += self.kernel.gradients_X( + self.dL_dK[[i], [i]], self.X[[i]], self.Xc[[i]] + ).sum() return l def parameters_changed(self): grads = -self.kernel.gradients_XX_diag(self.dL_dK.diagonal(), self.X) self.X.gradient[:] = grads.sum(-1) -def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verbose=False, fixed_X_dims=None): + +def check_kernel_gradient_functions( + kern, X=None, X2=None, output_ind=None, verbose=False, fixed_X_dims=None +): """ This function runs on kernels to check the correctness of their implementation. It checks that the covariance function is positive definite @@ -174,9 +202,15 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb if result and verbose: print("Check passed.") if not result: - print(("Positive definite check failed for " + kern.name + " covariance function.")) + print( + ( + "Positive definite check failed for " + + kern.name + + " covariance function." + ) + ) pass_checks = False - assert(result) + assert result return False if verbose: @@ -185,10 +219,16 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb if result and verbose: print("Check passed.") if not result: - print(("Gradient of K(X, X) wrt theta failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of K(X, X) wrt theta failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) Kern_check_dK_dtheta(kern, X=X, X2=None).checkgrad(verbose=True) pass_checks = False - assert(result) + assert result return False if verbose: @@ -196,16 +236,27 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: result = Kern_check_dK_dtheta(kern, X=X, X2=X2).checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: - print(("update_gradients_full, with differing X and X2, not implemented for " + kern.name)) + print( + ( + "update_gradients_full, with differing X and X2, not implemented for " + + kern.name + ) + ) if result and verbose: print("Check passed.") if not result: - print(("Gradient of K(X, X) wrt theta failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of K(X, X) wrt theta failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) Kern_check_dK_dtheta(kern, X=X, X2=X2).checkgrad(verbose=True) pass_checks = False - assert(result) + assert result return False if verbose: @@ -213,16 +264,22 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: result = Kern_check_dKdiag_dtheta(kern, X=X).checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("update_gradients_diag not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of Kdiag(X) wrt theta failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of Kdiag(X) wrt theta failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) Kern_check_dKdiag_dtheta(kern, X=X).checkgrad(verbose=True) pass_checks = False - assert(result) + assert result return False if verbose: @@ -230,18 +287,24 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: testmodel = Kern_check_dK_dX(kern, X=X, X2=None) if fixed_X_dims is not None: - testmodel.X[:,fixed_X_dims].fix() + testmodel.X[:, fixed_X_dims].fix() result = testmodel.checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("gradients_X not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of K(X, X) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of K(X, X) wrt X failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) testmodel.checkgrad(verbose=True) - assert(result) + assert result pass_checks = False return False @@ -250,18 +313,24 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: testmodel = Kern_check_dK_dX(kern, X=X, X2=X2) if fixed_X_dims is not None: - testmodel.X[:,fixed_X_dims].fix() + testmodel.X[:, fixed_X_dims].fix() result = testmodel.checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("gradients_X not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of K(X, X2) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of K(X, X2) wrt X failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) testmodel.checkgrad(verbose=True) - assert(result) + assert result pass_checks = False return False @@ -270,19 +339,25 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: testmodel = Kern_check_dKdiag_dX(kern, X=X) if fixed_X_dims is not None: - testmodel.X[:,fixed_X_dims].fix() + testmodel.X[:, fixed_X_dims].fix() result = testmodel.checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("gradients_X not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of Kdiag(X) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of Kdiag(X) wrt X failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) Kern_check_dKdiag_dX(kern, X=X).checkgrad(verbose=True) pass_checks = False - assert(result) + assert result return False if verbose: @@ -290,18 +365,24 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: testmodel = Kern_check_d2K_dXdX(kern, X=X, X2=X2) if fixed_X_dims is not None: - testmodel.X[:,fixed_X_dims].fix() + testmodel.X[:, fixed_X_dims].fix() result = testmodel.checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("gradients_X not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of dK(X, X2) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of dK(X, X2) wrt X failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) testmodel.checkgrad(verbose=True) - assert(result) + assert result pass_checks = False return False @@ -310,18 +391,24 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: testmodel = Kern_check_d2K_dXdX(kern, X=X, X2=None) if fixed_X_dims is not None: - testmodel.X[:,fixed_X_dims].fix() + testmodel.X[:, fixed_X_dims].fix() result = testmodel.checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("gradients_X not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of dK(X, X) wrt X with full cov in dimensions failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of dK(X, X) wrt X with full cov in dimensions failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) testmodel.checkgrad(verbose=True) - assert(result) + assert result pass_checks = False return False @@ -330,80 +417,123 @@ def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verb try: testmodel = Kern_check_d2Kdiag_dXdX(kern, X=X) if fixed_X_dims is not None: - testmodel.X[:,fixed_X_dims].fix() + testmodel.X[:, fixed_X_dims].fix() result = testmodel.checkgrad(verbose=verbose) except NotImplementedError: - result=True + result = True if verbose: print(("gradients_X not implemented for " + kern.name)) if result and verbose: print("Check passed.") if not result: - print(("Gradient of dKdiag(X, X) wrt X with cov in dimensions failed for " + kern.name + " covariance function. Gradient values as follows:")) + print( + ( + "Gradient of dKdiag(X, X) wrt X with cov in dimensions failed for " + + kern.name + + " covariance function. Gradient values as follows:" + ) + ) testmodel.checkgrad(verbose=True) - assert(result) + assert result pass_checks = False return False return pass_checks - class KernelGradientTestsContinuous(unittest.TestCase): def setUp(self): self.N, self.D = 10, 5 - self.X = np.random.randn(self.N,self.D+1) - self.X2 = np.random.randn(self.N+10,self.D+1) + self.X = np.random.randn(self.N, self.D + 1) + self.X2 = np.random.randn(self.N + 10, self.D + 1) - continuous_kerns = ['RBF', 'Linear'] + continuous_kerns = ["RBF", "Linear"] self.kernclasses = [getattr(GPy.kern, s) for s in continuous_kerns] def test_MLP(self): - k = GPy.kern.MLP(self.D,ARD=True) + k = GPy.kern.MLP(self.D, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Matern32(self): k = GPy.kern.Matern32(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Prod(self): - k = GPy.kern.Matern32(2, active_dims=[2,3]) * GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k = GPy.kern.Matern32(2, active_dims=[2, 3]) * GPy.kern.RBF( + 2, active_dims=[0, 4] + ) + GPy.kern.Linear(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Prod1(self): k = GPy.kern.RBF(self.D) * GPy.kern.Linear(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Prod2(self): - k = GPy.kern.RBF(2, active_dims=[0,4]) * GPy.kern.Linear(self.D) + k = GPy.kern.RBF(2, active_dims=[0, 4]) * GPy.kern.Linear(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Prod3(self): k = GPy.kern.RBF(self.D) * GPy.kern.Linear(self.D) * GPy.kern.Bias(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Prod4(self): - k = GPy.kern.RBF(2, active_dims=[0,4]) * GPy.kern.Linear(self.D) * GPy.kern.Matern32(2, active_dims=[0,1]) + k = ( + GPy.kern.RBF(2, active_dims=[0, 4]) + * GPy.kern.Linear(self.D) + * GPy.kern.Matern32(2, active_dims=[0, 1]) + ) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Add(self): - k = GPy.kern.Matern32(2, active_dims=[2,3]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) - k += GPy.kern.Matern32(2, active_dims=[2,3]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k = ( + GPy.kern.Matern32(2, active_dims=[2, 3]) + + GPy.kern.RBF(2, active_dims=[0, 4]) + + GPy.kern.Linear(self.D) + ) + k += ( + GPy.kern.Matern32(2, active_dims=[2, 3]) + + GPy.kern.RBF(2, active_dims=[0, 4]) + + GPy.kern.Linear(self.D) + ) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Add_dims(self): - k = GPy.kern.Matern32(2, active_dims=[2,self.D]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k = ( + GPy.kern.Matern32(2, active_dims=[2, self.D]) + + GPy.kern.RBF(2, active_dims=[0, 4]) + + GPy.kern.Linear(self.D) + ) k.randomize() - self.assertRaises(IndexError, k.K, self.X[:, :self.D]) - k = GPy.kern.Matern32(2, active_dims=[2,self.D-1]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + self.assertRaises(IndexError, k.K, self.X[:, : self.D]) + k = ( + GPy.kern.Matern32(2, active_dims=[2, self.D - 1]) + + GPy.kern.RBF(2, active_dims=[0, 4]) + + GPy.kern.Linear(self.D) + ) k.randomize() # assert it runs: try: @@ -414,101 +544,135 @@ class KernelGradientTestsContinuous(unittest.TestCase): def test_Matern52(self): k = GPy.kern.Matern52(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_RBF(self): - k = GPy.kern.RBF(self.D-1, ARD=True) + k = GPy.kern.RBF(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_OU(self): - k = GPy.kern.OU(self.D-1, ARD=True) + k = GPy.kern.OU(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Cosine(self): # Don't test Cosine directly as it fails positive definite test. - k = GPy.kern.RBF(self.D-1, ARD=False)*GPy.kern.Cosine(self.D-1, ARD=True) + k = GPy.kern.RBF(self.D - 1, ARD=False) * GPy.kern.Cosine(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_ExpQuadCosine(self): - k = GPy.kern.ExpQuadCosine(self.D-1, ARD=True) + k = GPy.kern.ExpQuadCosine(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Sinc(self): - k = GPy.kern.Sinc(self.D-1, ARD=True) + k = GPy.kern.Sinc(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_RatQuad(self): - k = GPy.kern.RatQuad(self.D-1, ARD=True) + k = GPy.kern.RatQuad(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_ExpQuad(self): - k = GPy.kern.ExpQuad(self.D-1, ARD=True) + k = GPy.kern.ExpQuad(self.D - 1, ARD=True) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_integral(self): k = GPy.kern.Integral(1) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_multidimensional_integral_limits(self): k = GPy.kern.Multidimensional_Integral_Limits(2) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_integral_limits(self): k = GPy.kern.Integral_Limits(2) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Linear(self): k = GPy.kern.Linear(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_LinearFull(self): - k = GPy.kern.LinearFull(self.D, self.D-1) + k = GPy.kern.LinearFull(self.D, self.D - 1) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_Fixed(self): cov = np.dot(self.X, self.X.T) X = np.arange(self.N).reshape(self.N, 1) k = GPy.kern.Fixed(1, cov) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=X, X2=None, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=X, X2=None, verbose=verbose) + ) def test_Poly(self): k = GPy.kern.Poly(self.D, order=5) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_WhiteHeteroscedastic(self): k = GPy.kern.WhiteHeteroscedastic(self.D, self.X.shape[0]) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_standard_periodic(self): k = GPy.kern.StdPeriodic(self.D) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_symmetric_even(self): k_base = GPy.kern.Linear(1) + GPy.kern.RBF(1) transform = -np.array([[1.0]]) - k = GPy.kern.Symmetric(k_base, transform, 'even') + k = GPy.kern.Symmetric(k_base, transform, "even") self.assertTrue(check_kernel_gradient_functions(k)) def test_symmetric_odd(self): k_base = GPy.kern.Linear(1) + GPy.kern.RBF(1) transform = -np.array([[1.0]]) - k = GPy.kern.Symmetric(k_base, transform, 'odd') + k = GPy.kern.Symmetric(k_base, transform, "odd") self.assertTrue(check_kernel_gradient_functions(k)) def test_MultioutputKern(self): @@ -518,155 +682,244 @@ class KernelGradientTestsContinuous(unittest.TestCase): k2.randomize() k = GPy.kern.MultioutputKern([k1, k2]) - Xt,_,_ = GPy.util.multioutput.build_XY([self.X, self.X]) - X2t,_,_ = GPy.util.multioutput.build_XY([self.X2, self.X2]) - self.assertTrue(check_kernel_gradient_functions(k, X=Xt, X2=X2t, verbose=verbose, fixed_X_dims=-1)) + Xt, _, _ = GPy.util.multioutput.build_XY([self.X, self.X]) + X2t, _, _ = GPy.util.multioutput.build_XY([self.X2, self.X2]) + self.assertTrue( + check_kernel_gradient_functions( + k, X=Xt, X2=X2t, verbose=verbose, fixed_X_dims=-1 + ) + ) def test_Precomputed(self): Xall = np.concatenate([self.X, self.X2]) cov = np.dot(Xall, Xall.T) X = np.arange(self.N).reshape(self.N, 1) - X2 = np.arange(self.N,2*self.N+10).reshape(self.N+10, 1) + X2 = np.arange(self.N, 2 * self.N + 10).reshape(self.N + 10, 1) k = GPy.kern.Precomputed(1, cov) k.randomize() - self.assertTrue(check_kernel_gradient_functions(k, X=X, X2=X2, verbose=verbose, fixed_X_dims=[0])) + self.assertTrue( + check_kernel_gradient_functions( + k, X=X, X2=X2, verbose=verbose, fixed_X_dims=[0] + ) + ) def test_basis_func_linear_slope(self): - start_stop = np.random.uniform(self.X.min(0), self.X.max(0), (4, self.X.shape[1])).T + start_stop = np.random.uniform( + self.X.min(0), self.X.max(0), (4, self.X.shape[1]) + ).T start_stop.sort(axis=1) ks = [] for i in range(start_stop.shape[0]): start, stop = np.split(start_stop[i], 2) - ks.append(GPy.kern.LinearSlopeBasisFuncKernel(1, start, stop, ARD=i%2==0, active_dims=[i])) + ks.append( + GPy.kern.LinearSlopeBasisFuncKernel( + 1, start, stop, ARD=i % 2 == 0, active_dims=[i] + ) + ) k = GPy.kern.Add(ks) - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_basis_func_changepoint(self): points = np.random.uniform(self.X.min(0), self.X.max(0), (self.X.shape[1])) ks = [] for i in range(points.shape[0]): - ks.append(GPy.kern.ChangePointBasisFuncKernel(1, points[i], ARD=i%2==0, active_dims=[i])) + ks.append( + GPy.kern.ChangePointBasisFuncKernel( + 1, points[i], ARD=i % 2 == 0, active_dims=[i] + ) + ) k = GPy.kern.Add(ks) - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_basis_func_poly(self): ks = [] for i in range(self.X.shape[1]): - ks.append(GPy.kern.PolynomialBasisFuncKernel(1, 5, ARD=i%2==0, active_dims=[i])) + ks.append( + GPy.kern.PolynomialBasisFuncKernel( + 1, 5, ARD=i % 2 == 0, active_dims=[i] + ) + ) k = GPy.kern.Add(ks) - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) def test_basis_func_domain(self): - start_stop = np.random.uniform(self.X.min(0), self.X.max(0), (4, self.X.shape[1])).T + start_stop = np.random.uniform( + self.X.min(0), self.X.max(0), (4, self.X.shape[1]) + ).T start_stop.sort(axis=1) ks = [] for i in range(start_stop.shape[0]): start, stop = np.split(start_stop[i], 2) - ks.append(GPy.kern.DomainKernel(1, start, stop, ARD=i%2==0, active_dims=[i])) + ks.append( + GPy.kern.DomainKernel(1, start, stop, ARD=i % 2 == 0, active_dims=[i]) + ) k = GPy.kern.Add(ks) - self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) + self.assertTrue( + check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) + ) + class KernelTestsMiscellaneous(unittest.TestCase): def setUp(self): N, D = 100, 10 - self.X = np.linspace(-np.pi, +np.pi, N)[:,None] * np.random.uniform(-10,10,D) - self.rbf = GPy.kern.RBF(2, active_dims=np.arange(0,4,2)) + self.X = np.linspace(-np.pi, +np.pi, N)[:, None] * np.random.uniform(-10, 10, D) + self.rbf = GPy.kern.RBF(2, active_dims=np.arange(0, 4, 2)) self.rbf.randomize() - self.linear = GPy.kern.Linear(2, active_dims=(3,9)) + self.linear = GPy.kern.Linear(2, active_dims=(3, 9)) self.linear.randomize() - self.matern = GPy.kern.Matern32(3, active_dims=np.array([1,7,9])) + self.matern = GPy.kern.Matern32(3, active_dims=np.array([1, 7, 9])) self.matern.randomize() self.sumkern = self.rbf + self.linear self.sumkern += self.matern - #self.sumkern.randomize() + # self.sumkern.randomize() def test_which_parts(self): - self.assertTrue(np.allclose(self.sumkern.K(self.X, which_parts=[self.linear, self.matern]), self.linear.K(self.X)+self.matern.K(self.X))) - self.assertTrue(np.allclose(self.sumkern.K(self.X, which_parts=[self.linear, self.rbf]), self.linear.K(self.X)+self.rbf.K(self.X))) - self.assertTrue(np.allclose(self.sumkern.K(self.X, which_parts=self.sumkern.parts[0]), self.rbf.K(self.X))) + self.assertTrue( + np.allclose( + self.sumkern.K(self.X, which_parts=[self.linear, self.matern]), + self.linear.K(self.X) + self.matern.K(self.X), + ) + ) + self.assertTrue( + np.allclose( + self.sumkern.K(self.X, which_parts=[self.linear, self.rbf]), + self.linear.K(self.X) + self.rbf.K(self.X), + ) + ) + self.assertTrue( + np.allclose( + self.sumkern.K(self.X, which_parts=self.sumkern.parts[0]), + self.rbf.K(self.X), + ) + ) def test_active_dims(self): - np.testing.assert_array_equal(self.sumkern.active_dims, [0,1,2,3,7,9]) + np.testing.assert_array_equal(self.sumkern.active_dims, [0, 1, 2, 3, 7, 9]) np.testing.assert_array_equal(self.sumkern._all_dims_active, range(10)) - tmp = self.linear+self.rbf - np.testing.assert_array_equal(tmp.active_dims, [0,2,3,9]) + tmp = self.linear + self.rbf + np.testing.assert_array_equal(tmp.active_dims, [0, 2, 3, 9]) np.testing.assert_array_equal(tmp._all_dims_active, range(10)) - tmp = self.matern+self.rbf - np.testing.assert_array_equal(tmp.active_dims, [0,1,2,7,9]) + tmp = self.matern + self.rbf + np.testing.assert_array_equal(tmp.active_dims, [0, 1, 2, 7, 9]) np.testing.assert_array_equal(tmp._all_dims_active, range(10)) - tmp = self.matern+self.rbf*self.linear - np.testing.assert_array_equal(tmp.active_dims, [0,1,2,3,7,9]) + tmp = self.matern + self.rbf * self.linear + np.testing.assert_array_equal(tmp.active_dims, [0, 1, 2, 3, 7, 9]) np.testing.assert_array_equal(tmp._all_dims_active, range(10)) - tmp = self.matern+self.rbf+self.linear - np.testing.assert_array_equal(tmp.active_dims, [0,1,2,3,7,9]) + tmp = self.matern + self.rbf + self.linear + np.testing.assert_array_equal(tmp.active_dims, [0, 1, 2, 3, 7, 9]) np.testing.assert_array_equal(tmp._all_dims_active, range(10)) - tmp = self.matern*self.rbf*self.linear - np.testing.assert_array_equal(tmp.active_dims, [0,1,2,3,7,9]) + tmp = self.matern * self.rbf * self.linear + np.testing.assert_array_equal(tmp.active_dims, [0, 1, 2, 3, 7, 9]) np.testing.assert_array_equal(tmp._all_dims_active, range(10)) + class KernelTestsNonContinuous(unittest.TestCase): def setUp(self): N0 = 3 N1 = 9 N2 = 4 - N = N0+N1+N2 + N = N0 + N1 + N2 self.D = 3 - self.X = np.random.randn(N, self.D+1) + self.X = np.random.randn(N, self.D + 1) indices = np.random.random_integers(0, 2, size=N) - self.X[indices==0, -1] = 0 - self.X[indices==1, -1] = 1 - self.X[indices==2, -1] = 2 - #self.X = self.X[self.X[:, -1].argsort(), :] - self.X2 = np.random.randn((N0+N1)*2, self.D+1) - self.X2[:(N0*2), -1] = 0 - self.X2[(N0*2):, -1] = 1 + self.X[indices == 0, -1] = 0 + self.X[indices == 1, -1] = 1 + self.X[indices == 2, -1] = 2 + # self.X = self.X[self.X[:, -1].argsort(), :] + self.X2 = np.random.randn((N0 + N1) * 2, self.D + 1) + self.X2[: (N0 * 2), -1] = 0 + self.X2[(N0 * 2) :, -1] = 1 def test_IndependentOutputs(self): - k = [GPy.kern.RBF(1, active_dims=[1], name='rbf1'), GPy.kern.RBF(self.D, active_dims=range(self.D), name='rbf012'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf02')] - kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') - np.testing.assert_array_equal(kern.active_dims, [-1,0,1,2]) - np.testing.assert_array_equal(kern._all_dims_active, [0,1,2,-1]) + k = [ + GPy.kern.RBF(1, active_dims=[1], name="rbf1"), + GPy.kern.RBF(self.D, active_dims=range(self.D), name="rbf012"), + GPy.kern.RBF(2, active_dims=[0, 2], name="rbf02"), + ] + kern = GPy.kern.IndependentOutputs(k, -1, name="ind_split") + np.testing.assert_array_equal(kern.active_dims, [-1, 0, 1, 2]) + np.testing.assert_array_equal(kern._all_dims_active, [0, 1, 2, -1]) def testIndependendGradients(self): k = GPy.kern.RBF(self.D, active_dims=range(self.D)) - kern = GPy.kern.IndependentOutputs(k, -1, 'ind_single') - self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) - k = [GPy.kern.RBF(1, active_dims=[1], name='rbf1'), GPy.kern.RBF(self.D, active_dims=range(self.D), name='rbf012'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf02')] - kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') - self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) + kern = GPy.kern.IndependentOutputs(k, -1, "ind_single") + self.assertTrue( + check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 + ) + ) + k = [ + GPy.kern.RBF(1, active_dims=[1], name="rbf1"), + GPy.kern.RBF(self.D, active_dims=range(self.D), name="rbf012"), + GPy.kern.RBF(2, active_dims=[0, 2], name="rbf02"), + ] + kern = GPy.kern.IndependentOutputs(k, -1, name="ind_split") + self.assertTrue( + check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 + ) + ) def test_Hierarchical(self): - k = [GPy.kern.RBF(2, active_dims=[0,2], name='rbf1'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf2')] - kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') - np.testing.assert_array_equal(kern.active_dims, [-1,0,2]) - np.testing.assert_array_equal(kern._all_dims_active, [0,1,2,-1]) + k = [ + GPy.kern.RBF(2, active_dims=[0, 2], name="rbf1"), + GPy.kern.RBF(2, active_dims=[0, 2], name="rbf2"), + ] + kern = GPy.kern.IndependentOutputs(k, -1, name="ind_split") + np.testing.assert_array_equal(kern.active_dims, [-1, 0, 2]) + np.testing.assert_array_equal(kern._all_dims_active, [0, 1, 2, -1]) def test_Hierarchical_gradients(self): - k = [GPy.kern.RBF(2, active_dims=[0,2], name='rbf1'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf2')] - kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') - self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) - + k = [ + GPy.kern.RBF(2, active_dims=[0, 2], name="rbf1"), + GPy.kern.RBF(2, active_dims=[0, 2], name="rbf2"), + ] + kern = GPy.kern.IndependentOutputs(k, -1, name="ind_split") + self.assertTrue( + check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 + ) + ) def test_ODE_UY(self): kern = GPy.kern.ODE_UY(2, active_dims=[0, self.D]) - X = self.X[self.X[:,-1]!=2] - X2 = self.X2[self.X2[:,-1]!=2] - self.assertTrue(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1)) + X = self.X[self.X[:, -1] != 2] + X2 = self.X2[self.X2[:, -1] != 2] + self.assertTrue( + check_kernel_gradient_functions( + kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1 + ) + ) def test_Coregionalize(self): kern = GPy.kern.Coregionalize(1, output_dim=3, active_dims=[-1]) - self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) + self.assertTrue( + check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 + ) + ) -@unittest.skipIf(not cython_coregionalize_working,"Cython coregionalize module has not been built on this machine") + +@unittest.skipIf( + not cython_coregionalize_working, + "Cython coregionalize module has not been built on this machine", +) class Coregionalize_cython_test(unittest.TestCase): """ Make sure that the coregionalize kernel work with and without cython enabled """ + def setUp(self): self.k = GPy.kern.Coregionalize(1, output_dim=12) self.N1, self.N2 = 100, 200 - self.X = np.random.randint(0,12,(self.N1,1)) - self.X2 = np.random.randint(0,12,(self.N2,1)) + self.X = np.random.randint(0, 12, (self.N1, 1)) + self.X2 = np.random.randint(0, 12, (self.N2, 1)) def test_sym(self): dL_dK = np.random.randn(self.N1, self.N1) @@ -691,12 +944,12 @@ class Coregionalize_cython_test(unittest.TestCase): def test_nonsym(self): dL_dK = np.random.randn(self.N1, self.N2) K_cython = self.k._K_cython(self.X, self.X2) - self.k.gradient = 0. + self.k.gradient = 0.0 self.k.update_gradients_full(dL_dK, self.X, self.X2) grads_cython = self.k.gradient.copy() K_numpy = self.k._K_numpy(self.X, self.X2) - self.k.gradient = 0. + self.k.gradient = 0.0 # Same hack as in test_sym (Line 639) _gradient_reduce_cython = self.k._gradient_reduce_cython self.k._gradient_reduce_cython = self.k._gradient_reduce_numpy @@ -709,46 +962,52 @@ class Coregionalize_cython_test(unittest.TestCase): self.assertTrue(np.allclose(grads_numpy, grads_cython)) - class KernelTestsProductWithZeroValues(unittest.TestCase): - def setUp(self): - self.X = np.array([[0,1],[1,0]]) + self.X = np.array([[0, 1], [1, 0]]) self.k = GPy.kern.Linear(2) * GPy.kern.Bias(2) def test_zero_valued_kernel_full(self): self.k.update_gradients_full(1, self.X) - self.assertFalse(np.isnan(self.k['linear.variances'].gradient), - "Gradient resulted in NaN") + self.assertFalse( + np.isnan(self.k["linear.variances"].gradient), "Gradient resulted in NaN" + ) def test_zero_valued_kernel_gradients_X(self): target = self.k.gradients_X(1, self.X) - self.assertFalse(np.any(np.isnan(target)), - "Gradient resulted in NaN") + self.assertFalse(np.any(np.isnan(target)), "Gradient resulted in NaN") + class Kernel_Psi_statistics_GradientTests(unittest.TestCase): - def setUp(self): from GPy.core.parameterization.variational import NormalPosterior - N,M,Q = 100,20,3 - X = np.random.randn(N,Q) - X_var = np.random.rand(N,Q)+0.01 - self.Z = np.random.randn(M,Q) + N, M, Q = 100, 20, 3 + + X = np.random.randn(N, Q) + X_var = np.random.rand(N, Q) + 0.01 + self.Z = np.random.randn(M, Q) self.qX = NormalPosterior(X, X_var) self.w1 = np.random.randn(N) - self.w2 = np.random.randn(N,M) - self.w3 = np.random.randn(M,M) - self.w3 = self.w3#+self.w3.T - self.w3n = np.random.randn(N,M,M) - self.w3n = self.w3n+np.swapaxes(self.w3n, 1,2) + self.w2 = np.random.randn(N, M) + self.w3 = np.random.randn(M, M) + self.w3 = self.w3 # +self.w3.T + self.w3n = np.random.randn(N, M, M) + self.w3n = self.w3n + np.swapaxes(self.w3n, 1, 2) def test_kernels(self): - from GPy.kern import RBF,Linear,MLP,Bias,White + from GPy.kern import RBF, Linear, MLP, Bias, White + Q = self.Z.shape[1] - kernels = [RBF(Q,ARD=True), Linear(Q,ARD=True),MLP(Q,ARD=True), RBF(Q,ARD=True)+Linear(Q,ARD=True)+Bias(Q)+White(Q) - ,RBF(Q,ARD=True)+Bias(Q)+White(Q), Linear(Q,ARD=True)+Bias(Q)+White(Q)] + kernels = [ + RBF(Q, ARD=True), + Linear(Q, ARD=True), + MLP(Q, ARD=True), + RBF(Q, ARD=True) + Linear(Q, ARD=True) + Bias(Q) + White(Q), + RBF(Q, ARD=True) + Bias(Q) + White(Q), + Linear(Q, ARD=True) + Bias(Q) + White(Q), + ] for k in kernels: k.randomize() @@ -760,50 +1019,69 @@ class Kernel_Psi_statistics_GradientTests(unittest.TestCase): self._test_qX(k, psi2n=True) def _test_kernel_param(self, kernel, psi2n=False): - def f(p): kernel.param_array[:] = p psi0 = kernel.psi0(self.Z, self.qX) psi1 = kernel.psi1(self.Z, self.qX) if not psi2n: psi2 = kernel.psi2(self.Z, self.qX) - return (self.w1*psi0).sum() + (self.w2*psi1).sum() + (self.w3*psi2).sum() + return ( + (self.w1 * psi0).sum() + + (self.w2 * psi1).sum() + + (self.w3 * psi2).sum() + ) else: psi2 = kernel.psi2n(self.Z, self.qX) - return (self.w1*psi0).sum() + (self.w2*psi1).sum() + (self.w3n*psi2).sum() + return ( + (self.w1 * psi0).sum() + + (self.w2 * psi1).sum() + + (self.w3n * psi2).sum() + ) def df(p): kernel.param_array[:] = p - kernel.update_gradients_expectations(self.w1, self.w2, self.w3 if not psi2n else self.w3n, self.Z, self.qX) + kernel.update_gradients_expectations( + self.w1, self.w2, self.w3 if not psi2n else self.w3n, self.Z, self.qX + ) return kernel.gradient.copy() from GPy.models import GradientChecker + m = GradientChecker(f, df, kernel.param_array.copy()) m.checkgrad(verbose=1) self.assertTrue(m.checkgrad()) def _test_Z(self, kernel, psi2n=False): - def f(p): psi0 = kernel.psi0(p, self.qX) psi1 = kernel.psi1(p, self.qX) psi2 = kernel.psi2(p, self.qX) if not psi2n: psi2 = kernel.psi2(p, self.qX) - return (self.w1*psi0).sum() + (self.w2*psi1).sum() + (self.w3*psi2).sum() + return ( + (self.w1 * psi0).sum() + + (self.w2 * psi1).sum() + + (self.w3 * psi2).sum() + ) else: psi2 = kernel.psi2n(p, self.qX) - return (self.w1*psi0).sum() + (self.w2*psi1).sum() + (self.w3n*psi2).sum() + return ( + (self.w1 * psi0).sum() + + (self.w2 * psi1).sum() + + (self.w3n * psi2).sum() + ) def df(p): - return kernel.gradients_Z_expectations(self.w1, self.w2, self.w3 if not psi2n else self.w3n, p, self.qX) + return kernel.gradients_Z_expectations( + self.w1, self.w2, self.w3 if not psi2n else self.w3n, p, self.qX + ) from GPy.models import GradientChecker + m = GradientChecker(f, df, self.Z.copy()) self.assertTrue(m.checkgrad()) def _test_qX(self, kernel, psi2n=False): - def f(p): self.qX.param_array[:] = p self.qX._trigger_params_changed() @@ -811,22 +1089,34 @@ class Kernel_Psi_statistics_GradientTests(unittest.TestCase): psi1 = kernel.psi1(self.Z, self.qX) if not psi2n: psi2 = kernel.psi2(self.Z, self.qX) - return (self.w1*psi0).sum() + (self.w2*psi1).sum() + (self.w3*psi2).sum() + return ( + (self.w1 * psi0).sum() + + (self.w2 * psi1).sum() + + (self.w3 * psi2).sum() + ) else: psi2 = kernel.psi2n(self.Z, self.qX) - return (self.w1*psi0).sum() + (self.w2*psi1).sum() + (self.w3n*psi2).sum() + return ( + (self.w1 * psi0).sum() + + (self.w2 * psi1).sum() + + (self.w3n * psi2).sum() + ) def df(p): self.qX.param_array[:] = p self.qX._trigger_params_changed() - grad = kernel.gradients_qX_expectations(self.w1, self.w2, self.w3 if not psi2n else self.w3n, self.Z, self.qX) + grad = kernel.gradients_qX_expectations( + self.w1, self.w2, self.w3 if not psi2n else self.w3n, self.Z, self.qX + ) self.qX.set_gradients(grad) return self.qX.gradient.copy() from GPy.models import GradientChecker + m = GradientChecker(f, df, self.qX.param_array.copy()) self.assertTrue(m.checkgrad()) + if __name__ == "__main__": print("Running unit tests, please be (very) patient...") unittest.main() From b9df83a4d256cf398e9402370ac3c27927f361b0 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 08:54:48 +0200 Subject: [PATCH 020/101] migrate kernel_tests to pytest --- GPy/testing/kernel_tests.py | 306 +++++++++++++++--------------------- 1 file changed, 123 insertions(+), 183 deletions(-) diff --git a/GPy/testing/kernel_tests.py b/GPy/testing/kernel_tests.py index 4f6016e0..c7ef9f09 100644 --- a/GPy/testing/kernel_tests.py +++ b/GPy/testing/kernel_tests.py @@ -1,13 +1,9 @@ # Copyright (c) 2012, 2013 GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) - -import unittest -from unittest.case import skip - import GPy +import pytest from GPy.core.parameterization.param import Param import numpy as np -import random from ..util.config import config @@ -441,8 +437,8 @@ def check_kernel_gradient_functions( return pass_checks -class KernelGradientTestsContinuous(unittest.TestCase): - def setUp(self): +class TestKernelGradientContinuous: + def setup(self): self.N, self.D = 10, 5 self.X = np.random.randn(self.N, self.D + 1) self.X2 = np.random.randn(self.N + 10, self.D + 1) @@ -451,61 +447,55 @@ class KernelGradientTestsContinuous(unittest.TestCase): self.kernclasses = [getattr(GPy.kern, s) for s in continuous_kerns] def test_MLP(self): + self.setup() k = GPy.kern.MLP(self.D, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Matern32(self): + self.setup() k = GPy.kern.Matern32(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Prod(self): + self.setup() k = GPy.kern.Matern32(2, active_dims=[2, 3]) * GPy.kern.RBF( 2, active_dims=[0, 4] ) + GPy.kern.Linear(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Prod1(self): + self.setup() k = GPy.kern.RBF(self.D) * GPy.kern.Linear(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Prod2(self): + self.setup() k = GPy.kern.RBF(2, active_dims=[0, 4]) * GPy.kern.Linear(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Prod3(self): + self.setup() k = GPy.kern.RBF(self.D) * GPy.kern.Linear(self.D) * GPy.kern.Bias(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Prod4(self): + self.setup() k = ( GPy.kern.RBF(2, active_dims=[0, 4]) * GPy.kern.Linear(self.D) * GPy.kern.Matern32(2, active_dims=[0, 1]) ) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Add(self): + self.setup() k = ( GPy.kern.Matern32(2, active_dims=[2, 3]) + GPy.kern.RBF(2, active_dims=[0, 4]) @@ -517,18 +507,18 @@ class KernelGradientTestsContinuous(unittest.TestCase): + GPy.kern.Linear(self.D) ) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Add_dims(self): + self.setup() k = ( GPy.kern.Matern32(2, active_dims=[2, self.D]) + GPy.kern.RBF(2, active_dims=[0, 4]) + GPy.kern.Linear(self.D) ) k.randomize() - self.assertRaises(IndexError, k.K, self.X[:, : self.D]) + with pytest.raises(IndexError): + self.X[:, : self.D] k = ( GPy.kern.Matern32(2, active_dims=[2, self.D - 1]) + GPy.kern.RBF(2, active_dims=[0, 4]) @@ -542,18 +532,16 @@ class KernelGradientTestsContinuous(unittest.TestCase): raise AssertionError("k.K(X) should run on self.D-1 dimension") def test_Matern52(self): + self.setup() k = GPy.kern.Matern52(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_RBF(self): + self.setup() k = GPy.kern.RBF(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_OU(self): k = GPy.kern.OU(self.D - 1, ARD=True) @@ -563,119 +551,108 @@ class KernelGradientTestsContinuous(unittest.TestCase): ) def test_Cosine(self): + self.setup() # Don't test Cosine directly as it fails positive definite test. k = GPy.kern.RBF(self.D - 1, ARD=False) * GPy.kern.Cosine(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_ExpQuadCosine(self): + self.setup() k = GPy.kern.ExpQuadCosine(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Sinc(self): + self.setup() k = GPy.kern.Sinc(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_RatQuad(self): + self.setup() k = GPy.kern.RatQuad(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_ExpQuad(self): + self.setup() k = GPy.kern.ExpQuad(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_integral(self): + self.setup() k = GPy.kern.Integral(1) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_multidimensional_integral_limits(self): + self.setup() k = GPy.kern.Multidimensional_Integral_Limits(2) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_integral_limits(self): + self.setup() k = GPy.kern.Integral_Limits(2) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Linear(self): + self.setup() k = GPy.kern.Linear(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_LinearFull(self): + self.setup() k = GPy.kern.LinearFull(self.D, self.D - 1) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Fixed(self): + self.setup() cov = np.dot(self.X, self.X.T) X = np.arange(self.N).reshape(self.N, 1) k = GPy.kern.Fixed(1, cov) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=X, X2=None, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=X, X2=None, verbose=verbose) def test_Poly(self): + self.setup() k = GPy.kern.Poly(self.D, order=5) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_WhiteHeteroscedastic(self): + self.setup() k = GPy.kern.WhiteHeteroscedastic(self.D, self.X.shape[0]) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_standard_periodic(self): + self.setup() k = GPy.kern.StdPeriodic(self.D) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_symmetric_even(self): + self.setup() k_base = GPy.kern.Linear(1) + GPy.kern.RBF(1) transform = -np.array([[1.0]]) k = GPy.kern.Symmetric(k_base, transform, "even") - self.assertTrue(check_kernel_gradient_functions(k)) + assert check_kernel_gradient_functions(k) def test_symmetric_odd(self): + self.setup() k_base = GPy.kern.Linear(1) + GPy.kern.RBF(1) transform = -np.array([[1.0]]) k = GPy.kern.Symmetric(k_base, transform, "odd") - self.assertTrue(check_kernel_gradient_functions(k)) + assert check_kernel_gradient_functions(k) def test_MultioutputKern(self): + self.setup() k1 = GPy.kern.RBF(self.D, ARD=True) k1.randomize() k2 = GPy.kern.RBF(self.D, ARD=True) @@ -684,26 +661,24 @@ class KernelGradientTestsContinuous(unittest.TestCase): k = GPy.kern.MultioutputKern([k1, k2]) Xt, _, _ = GPy.util.multioutput.build_XY([self.X, self.X]) X2t, _, _ = GPy.util.multioutput.build_XY([self.X2, self.X2]) - self.assertTrue( - check_kernel_gradient_functions( - k, X=Xt, X2=X2t, verbose=verbose, fixed_X_dims=-1 - ) + assert check_kernel_gradient_functions( + k, X=Xt, X2=X2t, verbose=verbose, fixed_X_dims=-1 ) def test_Precomputed(self): + self.setup() Xall = np.concatenate([self.X, self.X2]) cov = np.dot(Xall, Xall.T) X = np.arange(self.N).reshape(self.N, 1) X2 = np.arange(self.N, 2 * self.N + 10).reshape(self.N + 10, 1) k = GPy.kern.Precomputed(1, cov) k.randomize() - self.assertTrue( - check_kernel_gradient_functions( - k, X=X, X2=X2, verbose=verbose, fixed_X_dims=[0] - ) + assert check_kernel_gradient_functions( + k, X=X, X2=X2, verbose=verbose, fixed_X_dims=[0] ) def test_basis_func_linear_slope(self): + self.setup() start_stop = np.random.uniform( self.X.min(0), self.X.max(0), (4, self.X.shape[1]) ).T @@ -717,11 +692,10 @@ class KernelGradientTestsContinuous(unittest.TestCase): ) ) k = GPy.kern.Add(ks) - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_basis_func_changepoint(self): + self.setup() points = np.random.uniform(self.X.min(0), self.X.max(0), (self.X.shape[1])) ks = [] for i in range(points.shape[0]): @@ -731,11 +705,10 @@ class KernelGradientTestsContinuous(unittest.TestCase): ) ) k = GPy.kern.Add(ks) - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_basis_func_poly(self): + self.setup() ks = [] for i in range(self.X.shape[1]): ks.append( @@ -744,11 +717,10 @@ class KernelGradientTestsContinuous(unittest.TestCase): ) ) k = GPy.kern.Add(ks) - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_basis_func_domain(self): + self.setup() start_stop = np.random.uniform( self.X.min(0), self.X.max(0), (4, self.X.shape[1]) ).T @@ -760,13 +732,11 @@ class KernelGradientTestsContinuous(unittest.TestCase): GPy.kern.DomainKernel(1, start, stop, ARD=i % 2 == 0, active_dims=[i]) ) k = GPy.kern.Add(ks) - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) -class KernelTestsMiscellaneous(unittest.TestCase): - def setUp(self): +class TestKernelMiscellaneous: + def setup(self): N, D = 100, 10 self.X = np.linspace(-np.pi, +np.pi, N)[:, None] * np.random.uniform(-10, 10, D) self.rbf = GPy.kern.RBF(2, active_dims=np.arange(0, 4, 2)) @@ -780,26 +750,22 @@ class KernelTestsMiscellaneous(unittest.TestCase): # self.sumkern.randomize() def test_which_parts(self): - self.assertTrue( - np.allclose( - self.sumkern.K(self.X, which_parts=[self.linear, self.matern]), - self.linear.K(self.X) + self.matern.K(self.X), - ) + self.setup() + assert np.allclose( + self.sumkern.K(self.X, which_parts=[self.linear, self.matern]), + self.linear.K(self.X) + self.matern.K(self.X), ) - self.assertTrue( - np.allclose( - self.sumkern.K(self.X, which_parts=[self.linear, self.rbf]), - self.linear.K(self.X) + self.rbf.K(self.X), - ) + assert np.allclose( + self.sumkern.K(self.X, which_parts=[self.linear, self.rbf]), + self.linear.K(self.X) + self.rbf.K(self.X), ) - self.assertTrue( - np.allclose( - self.sumkern.K(self.X, which_parts=self.sumkern.parts[0]), - self.rbf.K(self.X), - ) + assert np.allclose( + self.sumkern.K(self.X, which_parts=self.sumkern.parts[0]), + self.rbf.K(self.X), ) def test_active_dims(self): + self.setup() np.testing.assert_array_equal(self.sumkern.active_dims, [0, 1, 2, 3, 7, 9]) np.testing.assert_array_equal(self.sumkern._all_dims_active, range(10)) tmp = self.linear + self.rbf @@ -819,8 +785,8 @@ class KernelTestsMiscellaneous(unittest.TestCase): np.testing.assert_array_equal(tmp._all_dims_active, range(10)) -class KernelTestsNonContinuous(unittest.TestCase): - def setUp(self): +class TestKernelNonContinuous: + def setup(self): N0 = 3 N1 = 9 N2 = 4 @@ -837,6 +803,7 @@ class KernelTestsNonContinuous(unittest.TestCase): self.X2[(N0 * 2) :, -1] = 1 def test_IndependentOutputs(self): + self.setup() k = [ GPy.kern.RBF(1, active_dims=[1], name="rbf1"), GPy.kern.RBF(self.D, active_dims=range(self.D), name="rbf012"), @@ -846,7 +813,8 @@ class KernelTestsNonContinuous(unittest.TestCase): np.testing.assert_array_equal(kern.active_dims, [-1, 0, 1, 2]) np.testing.assert_array_equal(kern._all_dims_active, [0, 1, 2, -1]) - def testIndependendGradients(self): + def test_IndependendGradients(self): + self.setup() k = GPy.kern.RBF(self.D, active_dims=range(self.D)) kern = GPy.kern.IndependentOutputs(k, -1, "ind_single") self.assertTrue( @@ -860,13 +828,12 @@ class KernelTestsNonContinuous(unittest.TestCase): GPy.kern.RBF(2, active_dims=[0, 2], name="rbf02"), ] kern = GPy.kern.IndependentOutputs(k, -1, name="ind_split") - self.assertTrue( - check_kernel_gradient_functions( - kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 - ) + assert check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 ) def test_Hierarchical(self): + self.setup() k = [ GPy.kern.RBF(2, active_dims=[0, 2], name="rbf1"), GPy.kern.RBF(2, active_dims=[0, 2], name="rbf2"), @@ -876,52 +843,50 @@ class KernelTestsNonContinuous(unittest.TestCase): np.testing.assert_array_equal(kern._all_dims_active, [0, 1, 2, -1]) def test_Hierarchical_gradients(self): + self.setup() k = [ GPy.kern.RBF(2, active_dims=[0, 2], name="rbf1"), GPy.kern.RBF(2, active_dims=[0, 2], name="rbf2"), ] kern = GPy.kern.IndependentOutputs(k, -1, name="ind_split") - self.assertTrue( - check_kernel_gradient_functions( - kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 - ) + assert check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 ) def test_ODE_UY(self): + self.setup() kern = GPy.kern.ODE_UY(2, active_dims=[0, self.D]) X = self.X[self.X[:, -1] != 2] X2 = self.X2[self.X2[:, -1] != 2] - self.assertTrue( - check_kernel_gradient_functions( - kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1 - ) + assert check_kernel_gradient_functions( + kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1 ) def test_Coregionalize(self): + self.setup() kern = GPy.kern.Coregionalize(1, output_dim=3, active_dims=[-1]) - self.assertTrue( - check_kernel_gradient_functions( - kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 - ) + assert check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 ) -@unittest.skipIf( +@pytest.skipIf( not cython_coregionalize_working, "Cython coregionalize module has not been built on this machine", ) -class Coregionalize_cython_test(unittest.TestCase): +class TestCoregionalizeCython: """ Make sure that the coregionalize kernel work with and without cython enabled """ - def setUp(self): + def setup(self): self.k = GPy.kern.Coregionalize(1, output_dim=12) self.N1, self.N2 = 100, 200 self.X = np.random.randint(0, 12, (self.N1, 1)) self.X2 = np.random.randint(0, 12, (self.N2, 1)) def test_sym(self): + self.setup() dL_dK = np.random.randn(self.N1, self.N1) K_cython = self.k._K_cython(self.X) self.k.update_gradients_full(dL_dK, self.X) @@ -938,10 +903,11 @@ class Coregionalize_cython_test(unittest.TestCase): self.k._gradient_reduce_cython = _gradient_reduce_cython grads_numpy = self.k.gradient.copy() - self.assertTrue(np.allclose(K_numpy, K_cython)) - self.assertTrue(np.allclose(grads_numpy, grads_cython)) + assert np.allclose(K_numpy, K_cython) + assert np.allclose(grads_numpy, grads_cython) def test_nonsym(self): + self.setup() dL_dK = np.random.randn(self.N1, self.N2) K_cython = self.k._K_cython(self.X, self.X2) self.k.gradient = 0.0 @@ -958,28 +924,28 @@ class Coregionalize_cython_test(unittest.TestCase): self.k._gradient_reduce_cython = _gradient_reduce_cython grads_numpy = self.k.gradient.copy() - self.assertTrue(np.allclose(K_numpy, K_cython)) - self.assertTrue(np.allclose(grads_numpy, grads_cython)) + assert np.allclose(K_numpy, K_cython) + assert np.allclose(grads_numpy, grads_cython) -class KernelTestsProductWithZeroValues(unittest.TestCase): - def setUp(self): +class TestKernelProductWithZeroValues: + def setup(self): self.X = np.array([[0, 1], [1, 0]]) self.k = GPy.kern.Linear(2) * GPy.kern.Bias(2) def test_zero_valued_kernel_full(self): + self.setup() self.k.update_gradients_full(1, self.X) - self.assertFalse( - np.isnan(self.k["linear.variances"].gradient), "Gradient resulted in NaN" - ) + assert np.isnan(self.k["linear.variances"].gradient), "Gradient resulted in NaN" def test_zero_valued_kernel_gradients_X(self): + self.seutp() target = self.k.gradients_X(1, self.X) - self.assertFalse(np.any(np.isnan(target)), "Gradient resulted in NaN") + assert np.any(np.isnan(target)), "Gradient resulted in NaN" -class Kernel_Psi_statistics_GradientTests(unittest.TestCase): - def setUp(self): +class TestKernelPsiStatisticsGradient: + def setup(self): from GPy.core.parameterization.variational import NormalPosterior N, M, Q = 100, 20, 3 @@ -997,6 +963,7 @@ class Kernel_Psi_statistics_GradientTests(unittest.TestCase): self.w3n = self.w3n + np.swapaxes(self.w3n, 1, 2) def test_kernels(self): + self.setup() from GPy.kern import RBF, Linear, MLP, Bias, White Q = self.Z.shape[1] @@ -1049,7 +1016,7 @@ class Kernel_Psi_statistics_GradientTests(unittest.TestCase): m = GradientChecker(f, df, kernel.param_array.copy()) m.checkgrad(verbose=1) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def _test_Z(self, kernel, psi2n=False): def f(p): @@ -1079,7 +1046,7 @@ class Kernel_Psi_statistics_GradientTests(unittest.TestCase): from GPy.models import GradientChecker m = GradientChecker(f, df, self.Z.copy()) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def _test_qX(self, kernel, psi2n=False): def f(p): @@ -1114,31 +1081,4 @@ class Kernel_Psi_statistics_GradientTests(unittest.TestCase): from GPy.models import GradientChecker m = GradientChecker(f, df, self.qX.param_array.copy()) - self.assertTrue(m.checkgrad()) - - -if __name__ == "__main__": - print("Running unit tests, please be (very) patient...") - unittest.main() - -# np.random.seed(0) -# N0 = 3 -# N1 = 9 -# N2 = 4 -# N = N0+N1+N2 -# D = 3 -# X = np.random.randn(N, D+1) -# indices = np.random.random_integers(0, 2, size=N) -# X[indices==0, -1] = 0 -# X[indices==1, -1] = 1 -# X[indices==2, -1] = 2 -# #X = X[X[:, -1].argsort(), :] -# X2 = np.random.randn((N0+N1)*2, D+1) -# X2[:(N0*2), -1] = 0 -# X2[(N0*2):, -1] = 1 -# k = [GPy.kern.RBF(1, active_dims=[1], name='rbf1'), GPy.kern.RBF(D, name='rbf012'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf02')] -# kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') -# assert(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1)) -# k = GPy.kern.RBF(D) -# kern = GPy.kern.IndependentOutputs(k, -1, 'ind_single') -# assert(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1)) + assert m.checkgrad() From 4df152048c3aa5157977c91fe0e83d407d00617f Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:28:35 +0200 Subject: [PATCH 021/101] format on save --- GPy/testing/likelihood_tests.py | 701 ++++++++++++++++++++------------ 1 file changed, 440 insertions(+), 261 deletions(-) diff --git a/GPy/testing/likelihood_tests.py b/GPy/testing/likelihood_tests.py index c665d6ab..4ed694d8 100644 --- a/GPy/testing/likelihood_tests.py +++ b/GPy/testing/likelihood_tests.py @@ -1,16 +1,17 @@ # Copyright (c) 2014, Alan Saul # Licensed under the BSD 3-clause license (see LICENSE.txt) import numpy as np -import unittest import GPy from GPy.models import GradientChecker import functools import inspect from GPy.likelihoods import link_functions from functools import partial + fixed_seed = 7 -#np.seterr(divide='raise') + +# np.seterr(divide='raise') def dparam_partial(inst_func, *args): """ If we have a instance method that needs to be called but that doesn't @@ -24,14 +25,26 @@ def dparam_partial(inst_func, *args): the f or Y that are being used in the function whilst we tweak the param """ + def param_func(param_val, param_name, inst_func, args): - #inst_func.__self__._set_params(param) - #inst_func.__self__.add_parameter(Param(param_name, param_val)) + # inst_func.__self__._set_params(param) + # inst_func.__self__.add_parameter(Param(param_name, param_val)) inst_func.__self__[param_name] = param_val return inst_func(*args) + return functools.partial(param_func, inst_func=inst_func, args=args) -def dparam_checkgrad(func, dfunc, params, params_names, args, constraints=None, randomize=False, verbose=False): + +def dparam_checkgrad( + func, + dfunc, + params, + params_names, + args, + constraints=None, + randomize=False, + verbose=False, +): """ checkgrad expects a f: R^N -> R^1 and df: R^N -> R^N However if we are holding other parameters fixed and moving something else @@ -42,38 +55,49 @@ def dparam_checkgrad(func, dfunc, params, params_names, args, constraints=None, The number of parameters and N is the number of data Need to take a slice out from f and a slice out of df """ - print("\n{} likelihood: {} vs {}".format(func.__self__.__class__.__name__, - func.__name__, dfunc.__name__)) + print( + "\n{} likelihood: {} vs {}".format( + func.__self__.__class__.__name__, func.__name__, dfunc.__name__ + ) + ) partial_f = dparam_partial(func, *args) partial_df = dparam_partial(dfunc, *args) gradchecking = True zipped_params = zip(params, params_names) for param_ind, (param_val, param_name) in enumerate(zipped_params): - #Check one parameter at a time, make sure it is 2d (as some gradients only return arrays) then strip out the parameter + # Check one parameter at a time, make sure it is 2d (as some gradients only return arrays) then strip out the parameter f_ = partial_f(param_val, param_name) df_ = partial_df(param_val, param_name) - #Reshape it such that we have a 3d matrix incase, that is we want it (?, N, D) regardless of whether ? is num_params or not + # Reshape it such that we have a 3d matrix incase, that is we want it (?, N, D) regardless of whether ? is num_params or not f_ = f_.reshape(-1, f_.shape[0], f_.shape[1]) df_ = df_.reshape(-1, f_.shape[0], f_.shape[1]) - #Get the number of f and number of dimensions + # Get the number of f and number of dimensions fnum = f_.shape[-2] fdim = f_.shape[-1] dfnum = df_.shape[-2] for fixed_val in range(dfnum): - #dlik and dlik_dvar gives back 1 value for each - f_ind = min(fnum, fixed_val+1) - 1 - print("fnum: {} dfnum: {} f_ind: {} fixed_val: {}".format(fnum, dfnum, f_ind, fixed_val)) - #Make grad checker with this param moving, note that set_params is NOT being called - #The parameter is being set directly with __setattr__ - #Check only the parameter and function value we wish to check at a time - #func = lambda p_val, fnum, fdim, param_ind, f_ind, param_ind: partial_f(p_val, param_name).reshape(-1, fnum, fdim)[param_ind, f_ind, :] - #dfunc_dparam = lambda d_val, fnum, fdim, param_ind, fixed_val: partial_df(d_val, param_name).reshape(-1, fnum, fdim)[param_ind, fixed_val, :] + # dlik and dlik_dvar gives back 1 value for each + f_ind = min(fnum, fixed_val + 1) - 1 + print( + "fnum: {} dfnum: {} f_ind: {} fixed_val: {}".format( + fnum, dfnum, f_ind, fixed_val + ) + ) + # Make grad checker with this param moving, note that set_params is NOT being called + # The parameter is being set directly with __setattr__ + # Check only the parameter and function value we wish to check at a time + # func = lambda p_val, fnum, fdim, param_ind, f_ind, param_ind: partial_f(p_val, param_name).reshape(-1, fnum, fdim)[param_ind, f_ind, :] + # dfunc_dparam = lambda d_val, fnum, fdim, param_ind, fixed_val: partial_df(d_val, param_name).reshape(-1, fnum, fdim)[param_ind, fixed_val, :] - #First we reshape the output such that it is (num_params, N, D) then we pull out the relavent parameter-findex and checkgrad just this index at a time - func = lambda p_val: partial_f(p_val, param_name).reshape(-1, fnum, fdim)[param_ind, f_ind, :] - dfunc_dparam = lambda d_val: partial_df(d_val, param_name).reshape(-1, fnum, fdim)[param_ind, fixed_val, :] + # First we reshape the output such that it is (num_params, N, D) then we pull out the relavent parameter-findex and checkgrad just this index at a time + func = lambda p_val: partial_f(p_val, param_name).reshape(-1, fnum, fdim)[ + param_ind, f_ind, : + ] + dfunc_dparam = lambda d_val: partial_df(d_val, param_name).reshape( + -1, fnum, fdim + )[param_ind, fixed_val, :] grad = GradientChecker(func, dfunc_dparam, param_val, [param_name]) if constraints is not None: @@ -98,47 +122,59 @@ def dparam_checkgrad(func, dfunc, params, params_names, args, constraints=None, from nose.tools import with_setup + + class TestNoiseModels(object): """ Generic model checker """ + def setUp(self): np.random.seed(fixed_seed) self.N = 15 self.D = 3 - self.X = np.random.rand(self.N, self.D)*10 + self.X = np.random.rand(self.N, self.D) * 10 self.real_std = 0.1 - noise = np.random.randn(*self.X[:, 0].shape)*self.real_std - self.Y = (np.sin(self.X[:, 0]*2*np.pi) + noise)[:, None] + noise = np.random.randn(*self.X[:, 0].shape) * self.real_std + self.Y = (np.sin(self.X[:, 0] * 2 * np.pi) + noise)[:, None] self.f = np.random.rand(self.N, 1) self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None] self.binary_Y[self.binary_Y == 0.0] = -1.0 self.positive_Y = np.exp(self.Y.copy()) - tmp = np.round(self.X[:, 0]*3-3)[:, None] + np.random.randint(0,3, self.X.shape[0])[:, None] + tmp = ( + np.round(self.X[:, 0] * 3 - 3)[:, None] + + np.random.randint(0, 3, self.X.shape[0])[:, None] + ) self.integer_Y = np.where(tmp > 0, tmp, 0) self.ns = np.random.poisson(50, size=self.N)[:, None] - p = np.abs(np.cos(2*np.pi*self.X + np.random.normal(scale=.2, size=(self.N, self.D)))).mean(1) - self.binomial_Y = np.array([np.random.binomial(int(self.ns[i]), p[i]) for i in range(p.shape[0])])[:, None] - + p = np.abs( + np.cos( + 2 * np.pi * self.X + np.random.normal(scale=0.2, size=(self.N, self.D)) + ) + ).mean(1) + self.binomial_Y = np.array( + [np.random.binomial(int(self.ns[i]), p[i]) for i in range(p.shape[0])] + )[:, None] + self.var = 0.2 self.deg_free = 4.0 censored = np.zeros_like(self.Y) random_inds = np.random.choice(self.N, int(self.N / 2), replace=True) censored[random_inds] = 1 self.Y_metadata = dict() - self.Y_metadata['censored'] = censored - self.Y_metadata['output_index'] = np.zeros((self.N,1), dtype=int) + self.Y_metadata["censored"] = censored + self.Y_metadata["output_index"] = np.zeros((self.N, 1), dtype=int) self.Y_metadata2 = dict() - self.Y_metadata2['censored'] = censored - inds = np.zeros((self.N,1), dtype=int) + self.Y_metadata2["censored"] = censored + inds = np.zeros((self.N, 1), dtype=int) inds[5:10] = 1 inds[10:] = 2 - self.Y_metadata2['output_index'] = inds + self.Y_metadata2["output_index"] = inds self.combY = self.Y - self.combY[10:] = np.where(self.binary_Y[10:] >0, self.binary_Y[10:], 0) + self.combY[10:] = np.where(self.binary_Y[10:] > 0, self.binary_Y[10:], 0) print(self.combY) - #Make a bigger step as lower bound can be quite curved + # Make a bigger step as lower bound can be quite curved self.step = 1e-4 """ @@ -155,118 +191,146 @@ class TestNoiseModels(object): "link_f_constraints": [constraint_wrappers, listed_here] } """ - self.noise_models = {"Student_t_default": { - "model": GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.var), - "grad_params": { - "names": [".*t_scale2"], - "vals": [self.var], - "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] + self.noise_models = { + "Student_t_default": { + "model": GPy.likelihoods.StudentT( + deg_free=self.deg_free, sigma2=self.var + ), + "grad_params": { + "names": [".*t_scale2"], + "vals": [self.var], + "constraints": [ + (".*t_scale2", self.constrain_positive), + (".*deg_free", self.constrain_fixed), + ], + }, + "laplace": True, }, - "laplace": True - }, - #"Student_t_deg_free": { - #"model": GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.var), - #"grad_params": { - #"names": [".*deg_free"], - #"vals": [self.deg_free], - #"constraints": [(".*t_scale2", self.constrain_fixed), (".*deg_free", self.constrain_positive)] - #}, - #"laplace": True - #}, + # "Student_t_deg_free": { + # "model": GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.var), + # "grad_params": { + # "names": [".*deg_free"], + # "vals": [self.deg_free], + # "constraints": [(".*t_scale2", self.constrain_fixed), (".*deg_free", self.constrain_positive)] + # }, + # "laplace": True + # }, "Student_t_1_var": { - "model": GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.var), + "model": GPy.likelihoods.StudentT( + deg_free=self.deg_free, sigma2=self.var + ), "grad_params": { "names": [".*t_scale2"], "vals": [1.0], - "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] + "constraints": [ + (".*t_scale2", self.constrain_positive), + (".*deg_free", self.constrain_fixed), + ], }, - "laplace": True + "laplace": True, }, # FIXME: This is a known failure point, when the degrees of freedom # are very small, and the variance is relatively small, the # likelihood is log-concave and problems occur # "Student_t_small_deg_free": { - # "model": GPy.likelihoods.StudentT(deg_free=1.5, sigma2=self.var), - # "grad_params": { - # "names": [".*t_scale2"], - # "vals": [self.var], - # "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] - # }, - # "laplace": True + # "model": GPy.likelihoods.StudentT(deg_free=1.5, sigma2=self.var), + # "grad_params": { + # "names": [".*t_scale2"], + # "vals": [self.var], + # "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] + # }, + # "laplace": True # }, "Student_t_small_var": { - "model": GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.var), + "model": GPy.likelihoods.StudentT( + deg_free=self.deg_free, sigma2=self.var + ), "grad_params": { "names": [".*t_scale2"], "vals": [0.001], - "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] + "constraints": [ + (".*t_scale2", self.constrain_positive), + (".*deg_free", self.constrain_fixed), + ], }, - "laplace": True + "laplace": True, }, "Student_t_large_var": { - "model": GPy.likelihoods.StudentT(deg_free=self.deg_free, sigma2=self.var), + "model": GPy.likelihoods.StudentT( + deg_free=self.deg_free, sigma2=self.var + ), "grad_params": { "names": [".*t_scale2"], "vals": [10.0], - "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] + "constraints": [ + (".*t_scale2", self.constrain_positive), + (".*deg_free", self.constrain_fixed), + ], }, - "laplace": True + "laplace": True, }, "Student_t_approx_gauss": { "model": GPy.likelihoods.StudentT(deg_free=1000, sigma2=self.var), "grad_params": { "names": [".*t_scale2"], "vals": [self.var], - "constraints": [(".*t_scale2", self.constrain_positive), (".*deg_free", self.constrain_fixed)] + "constraints": [ + (".*t_scale2", self.constrain_positive), + (".*deg_free", self.constrain_fixed), + ], }, - "laplace": True + "laplace": True, }, "Gaussian_default": { "model": GPy.likelihoods.Gaussian(variance=self.var), "grad_params": { "names": [".*variance"], "vals": [self.var], - "constraints": [(".*variance", self.constrain_positive)] + "constraints": [(".*variance", self.constrain_positive)], }, "laplace": True, - "ep": False, # FIXME: Should be True when we have it working again + "ep": False, # FIXME: Should be True when we have it working again "variational_expectations": True, }, "Gaussian_log": { - "model": GPy.likelihoods.Gaussian(gp_link=link_functions.Log(), variance=self.var), + "model": GPy.likelihoods.Gaussian( + gp_link=link_functions.Log(), variance=self.var + ), "grad_params": { "names": [".*variance"], "vals": [self.var], - "constraints": [(".*variance", self.constrain_positive)] + "constraints": [(".*variance", self.constrain_positive)], }, "laplace": True, - "variational_expectations": True + "variational_expectations": True, }, - #"Gaussian_probit": { - #"model": GPy.likelihoods.gaussian(gp_link=link_functions.Probit(), variance=self.var, D=self.D, N=self.N), - #"grad_params": { - #"names": ["noise_model_variance"], - #"vals": [self.var], - #"constraints": [constrain_positive] - #}, - #"laplace": True - #}, - #"Gaussian_log_ex": { - #"model": GPy.likelihoods.gaussian(gp_link=link_functions.Log_ex_1(), variance=self.var, D=self.D, N=self.N), - #"grad_params": { - #"names": ["noise_model_variance"], - #"vals": [self.var], - #"constraints": [constrain_positive] - #}, - #"laplace": True - #}, + # "Gaussian_probit": { + # "model": GPy.likelihoods.gaussian(gp_link=link_functions.Probit(), variance=self.var, D=self.D, N=self.N), + # "grad_params": { + # "names": ["noise_model_variance"], + # "vals": [self.var], + # "constraints": [constrain_positive] + # }, + # "laplace": True + # }, + # "Gaussian_log_ex": { + # "model": GPy.likelihoods.gaussian(gp_link=link_functions.Log_ex_1(), variance=self.var, D=self.D, N=self.N), + # "grad_params": { + # "names": ["noise_model_variance"], + # "vals": [self.var], + # "constraints": [constrain_positive] + # }, + # "laplace": True + # }, "Bernoulli_default": { "model": GPy.likelihoods.Bernoulli(), - "link_f_constraints": [partial(self.constrain_bounded, lower=0, upper=1)], + "link_f_constraints": [ + partial(self.constrain_bounded, lower=0, upper=1) + ], "laplace": True, "Y": self.binary_Y, - "ep": True, # FIXME: Should be True when we have it working again - "variational_expectations": True + "ep": True, # FIXME: Should be True when we have it working again + "variational_expectations": True, }, "Exponential_default": { "model": GPy.likelihoods.Exponential(), @@ -279,13 +343,15 @@ class TestNoiseModels(object): "link_f_constraints": [self.constrain_positive], "Y": self.integer_Y, "laplace": True, - "ep": False #Should work though... + "ep": False, # Should work though... }, "Binomial_default": { "model": GPy.likelihoods.Binomial(), - "link_f_constraints": [partial(self.constrain_bounded, lower=0, upper=1)], + "link_f_constraints": [ + partial(self.constrain_bounded, lower=0, upper=1) + ], "Y": self.binomial_Y, - "Y_metadata": {'trials': self.ns}, + "Y_metadata": {"trials": self.ns}, "laplace": True, }, "loglogistic_censored": { @@ -293,34 +359,41 @@ class TestNoiseModels(object): "link_f_constraints": [self.constrain_positive], "Y": self.positive_Y, "Y_metadata": self.Y_metadata, - "laplace": True + "laplace": True, }, "weibull_censored": { "model": GPy.likelihoods.Weibull(), "link_f_constraints": [self.constrain_positive], "Y": self.positive_Y, "Y_metadata": self.Y_metadata, - "laplace": True + "laplace": True, }, "multioutput_default": { - "model": GPy.likelihoods.MultioutputLikelihood([GPy.likelihoods.Gaussian(), GPy.likelihoods.Poisson(), GPy.likelihoods.Bernoulli()]), - "link_f_constraints": [partial(self.constrain_bounded, lower=0, upper=1)], + "model": GPy.likelihoods.MultioutputLikelihood( + [ + GPy.likelihoods.Gaussian(), + GPy.likelihoods.Poisson(), + GPy.likelihoods.Bernoulli(), + ] + ), + "link_f_constraints": [ + partial(self.constrain_bounded, lower=0, upper=1) + ], "laplace": True, "Y": self.combY, "Y_metadata": self.Y_metadata2, "ep": True, "variational_expectations": True, } - #, - #GAMMA needs some work!"Gamma_default": { - #"model": GPy.likelihoods.Gamma(), - #"link_f_constraints": [constrain_positive], - #"Y": self.positive_Y, - #"laplace": True - #} + # , + # GAMMA needs some work!"Gamma_default": { + # "model": GPy.likelihoods.Gamma(), + # "link_f_constraints": [constrain_positive], + # "Y": self.positive_Y, + # "laplace": True + # } } - #################################################### # Constraint wrappers so we can just list them off # #################################################### @@ -345,7 +418,6 @@ class TestNoiseModels(object): """ model[regex].constrain_bounded(lower, upper) - def tearDown(self): self.Y = None self.f = None @@ -359,7 +431,7 @@ class TestNoiseModels(object): if "grad_params" in attributes: params = attributes["grad_params"] param_vals = params["vals"] - param_names= params["names"] + param_names = params["names"] param_constraints = params["constraints"] else: params = [] @@ -396,42 +468,41 @@ class TestNoiseModels(object): else: var_exp = False - #if len(param_vals) > 1: - #raise NotImplementedError("Cannot support multiple params in likelihood yet!") + # if len(param_vals) > 1: + # raise NotImplementedError("Cannot support multiple params in likelihood yet!") - #Required by all - #Normal derivatives + # Required by all + # Normal derivatives yield self.t_logpdf, model, Y, f, Y_metadata yield self.t_dlogpdf_df, model, Y, f, Y_metadata yield self.t_d2logpdf_df2, model, Y, f, Y_metadata - #Link derivatives + # Link derivatives yield self.t_dlogpdf_dlink, model, Y, f, Y_metadata, link_f_constraints yield self.t_d2logpdf_dlink2, model, Y, f, Y_metadata, link_f_constraints if laplace: - #Laplace only derivatives + # Laplace only derivatives yield self.t_d3logpdf_df3, model, Y, f, Y_metadata yield self.t_d3logpdf_dlink3, model, Y, f, Y_metadata, link_f_constraints - #Params + # Params yield self.t_dlogpdf_dparams, model, Y, f, Y_metadata, param_vals, param_names, param_constraints yield self.t_dlogpdf_df_dparams, model, Y, f, Y_metadata, param_vals, param_names, param_constraints yield self.t_d2logpdf2_df2_dparams, model, Y, f, Y_metadata, param_vals, param_names, param_constraints - #Link params + # Link params yield self.t_dlogpdf_link_dparams, model, Y, f, Y_metadata, param_vals, param_names, param_constraints yield self.t_dlogpdf_dlink_dparams, model, Y, f, Y_metadata, param_vals, param_names, param_constraints yield self.t_d2logpdf2_dlink2_dparams, model, Y, f, Y_metadata, param_vals, param_names, param_constraints - #laplace likelihood gradcheck + # laplace likelihood gradcheck yield self.t_laplace_fit_rbf_white, model, self.X, Y, f, Y_metadata, self.step, param_vals, param_names, param_constraints if ep: - #ep likelihood gradcheck + # ep likelihood gradcheck yield self.t_ep_fit_rbf_white, model, self.X, Y, f, Y_metadata, self.step, param_vals, param_names, param_constraints if var_exp: - #Need to specify mu and var! + # Need to specify mu and var! yield self.t_varexp, model, Y, Y_metadata yield self.t_dexp_dmu, model, Y, Y_metadata yield self.t_dexp_dvar, model, Y, Y_metadata - self.tearDown() ############# @@ -441,11 +512,11 @@ class TestNoiseModels(object): def t_logpdf(self, model, Y, f, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) print(model) - #print model._get_params() + # print model._get_params() np.testing.assert_almost_equal( - model.pdf(f.copy(), Y.copy(), Y_metadata=Y_metadata).prod(), - np.exp(model.logpdf(f.copy(), Y.copy(), Y_metadata=Y_metadata).sum()) - ) + model.pdf(f.copy(), Y.copy(), Y_metadata=Y_metadata).prod(), + np.exp(model.logpdf(f.copy(), Y.copy(), Y_metadata=Y_metadata).sum()), + ) @with_setup(setUp, tearDown) def t_dlogpdf_df(self, model, Y, f, Y_metadata): @@ -453,7 +524,7 @@ class TestNoiseModels(object): self.description = "\n{}".format(inspect.stack()[0][3]) logpdf = functools.partial(np.sum(model.logpdf), y=Y, Y_metadata=Y_metadata) dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y, Y_metadata=Y_metadata) - grad = GradientChecker(logpdf, dlogpdf_df, f.copy(), 'g') + grad = GradientChecker(logpdf, dlogpdf_df, f.copy(), "g") grad.randomize() print(model) assert grad.checkgrad(verbose=1) @@ -463,7 +534,7 @@ class TestNoiseModels(object): print("\n{}".format(inspect.stack()[0][3])) dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y, Y_metadata=Y_metadata) d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y, Y_metadata=Y_metadata) - grad = GradientChecker(dlogpdf_df, d2logpdf_df2, f.copy(), 'g') + grad = GradientChecker(dlogpdf_df, d2logpdf_df2, f.copy(), "g") grad.randomize() print(model) assert grad.checkgrad(verbose=1) @@ -473,7 +544,7 @@ class TestNoiseModels(object): print("\n{}".format(inspect.stack()[0][3])) d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y, Y_metadata=Y_metadata) d3logpdf_df3 = functools.partial(model.d3logpdf_df3, y=Y, Y_metadata=Y_metadata) - grad = GradientChecker(d2logpdf_df2, d3logpdf_df3, f.copy(), 'g') + grad = GradientChecker(d2logpdf_df2, d3logpdf_df3, f.copy(), "g") grad.randomize() print(model) assert grad.checkgrad(verbose=1) @@ -482,34 +553,55 @@ class TestNoiseModels(object): # df_dparams # ############## @with_setup(setUp, tearDown) - def t_dlogpdf_dparams(self, model, Y, f, Y_metadata, params, params_names, param_constraints): + def t_dlogpdf_dparams( + self, model, Y, f, Y_metadata, params, params_names, param_constraints + ): print("\n{}".format(inspect.stack()[0][3])) print(model) - assert ( - dparam_checkgrad(model.logpdf, model.dlogpdf_dtheta, - params, params_names, args=(f, Y, Y_metadata), constraints=param_constraints, - randomize=False, verbose=True) - ) + assert dparam_checkgrad( + model.logpdf, + model.dlogpdf_dtheta, + params, + params_names, + args=(f, Y, Y_metadata), + constraints=param_constraints, + randomize=False, + verbose=True, + ) @with_setup(setUp, tearDown) - def t_dlogpdf_df_dparams(self, model, Y, f, Y_metadata, params, params_names, param_constraints): + def t_dlogpdf_df_dparams( + self, model, Y, f, Y_metadata, params, params_names, param_constraints + ): print("\n{}".format(inspect.stack()[0][3])) print(model) - assert ( - dparam_checkgrad(model.dlogpdf_df, model.dlogpdf_df_dtheta, - params, params_names, args=(f, Y, Y_metadata), constraints=param_constraints, - randomize=False, verbose=True) - ) + assert dparam_checkgrad( + model.dlogpdf_df, + model.dlogpdf_df_dtheta, + params, + params_names, + args=(f, Y, Y_metadata), + constraints=param_constraints, + randomize=False, + verbose=True, + ) @with_setup(setUp, tearDown) - def t_d2logpdf2_df2_dparams(self, model, Y, f, Y_metadata, params, params_names, param_constraints): + def t_d2logpdf2_df2_dparams( + self, model, Y, f, Y_metadata, params, params_names, param_constraints + ): print("\n{}".format(inspect.stack()[0][3])) print(model) - assert ( - dparam_checkgrad(model.d2logpdf_df2, model.d2logpdf_df2_dtheta, - params, params_names, args=(f, Y, Y_metadata), constraints=param_constraints, - randomize=False, verbose=True) - ) + assert dparam_checkgrad( + model.d2logpdf_df2, + model.d2logpdf_df2_dtheta, + params, + params_names, + args=(f, Y, Y_metadata), + constraints=param_constraints, + randomize=False, + verbose=True, + ) ################ # dpdf_dlink's # @@ -518,12 +610,14 @@ class TestNoiseModels(object): def t_dlogpdf_dlink(self, model, Y, f, Y_metadata, link_f_constraints): print("\n{}".format(inspect.stack()[0][3])) logpdf = functools.partial(model.logpdf_link, y=Y, Y_metadata=Y_metadata) - dlogpdf_dlink = functools.partial(model.dlogpdf_dlink, y=Y, Y_metadata=Y_metadata) - grad = GradientChecker(logpdf, dlogpdf_dlink, f.copy(), 'g') + dlogpdf_dlink = functools.partial( + model.dlogpdf_dlink, y=Y, Y_metadata=Y_metadata + ) + grad = GradientChecker(logpdf, dlogpdf_dlink, f.copy(), "g") - #Apply constraints to link_f values + # Apply constraints to link_f values for constraint in link_f_constraints: - constraint('g', grad) + constraint("g", grad) grad.randomize() print(grad) @@ -533,13 +627,17 @@ class TestNoiseModels(object): @with_setup(setUp, tearDown) def t_d2logpdf_dlink2(self, model, Y, f, Y_metadata, link_f_constraints): print("\n{}".format(inspect.stack()[0][3])) - dlogpdf_dlink = functools.partial(model.dlogpdf_dlink, y=Y, Y_metadata=Y_metadata) - d2logpdf_dlink2 = functools.partial(model.d2logpdf_dlink2, y=Y, Y_metadata=Y_metadata) - grad = GradientChecker(dlogpdf_dlink, d2logpdf_dlink2, f.copy(), 'g') + dlogpdf_dlink = functools.partial( + model.dlogpdf_dlink, y=Y, Y_metadata=Y_metadata + ) + d2logpdf_dlink2 = functools.partial( + model.d2logpdf_dlink2, y=Y, Y_metadata=Y_metadata + ) + grad = GradientChecker(dlogpdf_dlink, d2logpdf_dlink2, f.copy(), "g") - #Apply constraints to link_f values + # Apply constraints to link_f values for constraint in link_f_constraints: - constraint('g', grad) + constraint("g", grad) grad.randomize() print(grad) @@ -549,13 +647,17 @@ class TestNoiseModels(object): @with_setup(setUp, tearDown) def t_d3logpdf_dlink3(self, model, Y, f, Y_metadata, link_f_constraints): print("\n{}".format(inspect.stack()[0][3])) - d2logpdf_dlink2 = functools.partial(model.d2logpdf_dlink2, y=Y, Y_metadata=Y_metadata) - d3logpdf_dlink3 = functools.partial(model.d3logpdf_dlink3, y=Y, Y_metadata=Y_metadata) - grad = GradientChecker(d2logpdf_dlink2, d3logpdf_dlink3, f.copy(), 'g') + d2logpdf_dlink2 = functools.partial( + model.d2logpdf_dlink2, y=Y, Y_metadata=Y_metadata + ) + d3logpdf_dlink3 = functools.partial( + model.d3logpdf_dlink3, y=Y, Y_metadata=Y_metadata + ) + grad = GradientChecker(d2logpdf_dlink2, d3logpdf_dlink3, f.copy(), "g") - #Apply constraints to link_f values + # Apply constraints to link_f values for constraint in link_f_constraints: - constraint('g', grad) + constraint("g", grad) grad.randomize() print(grad) @@ -566,57 +668,87 @@ class TestNoiseModels(object): # dlink_dparams # ################# @with_setup(setUp, tearDown) - def t_dlogpdf_link_dparams(self, model, Y, f, Y_metadata, params, param_names, param_constraints): + def t_dlogpdf_link_dparams( + self, model, Y, f, Y_metadata, params, param_names, param_constraints + ): print("\n{}".format(inspect.stack()[0][3])) print(model) - assert ( - dparam_checkgrad(model.logpdf_link, model.dlogpdf_link_dtheta, - params, param_names, args=(f, Y, Y_metadata), constraints=param_constraints, - randomize=False, verbose=True) - ) + assert dparam_checkgrad( + model.logpdf_link, + model.dlogpdf_link_dtheta, + params, + param_names, + args=(f, Y, Y_metadata), + constraints=param_constraints, + randomize=False, + verbose=True, + ) @with_setup(setUp, tearDown) - def t_dlogpdf_dlink_dparams(self, model, Y, f, Y_metadata, params, param_names, param_constraints): + def t_dlogpdf_dlink_dparams( + self, model, Y, f, Y_metadata, params, param_names, param_constraints + ): print("\n{}".format(inspect.stack()[0][3])) print(model) - assert ( - dparam_checkgrad(model.dlogpdf_dlink, model.dlogpdf_dlink_dtheta, - params, param_names, args=(f, Y, Y_metadata), constraints=param_constraints, - randomize=False, verbose=True) - ) + assert dparam_checkgrad( + model.dlogpdf_dlink, + model.dlogpdf_dlink_dtheta, + params, + param_names, + args=(f, Y, Y_metadata), + constraints=param_constraints, + randomize=False, + verbose=True, + ) @with_setup(setUp, tearDown) - def t_d2logpdf2_dlink2_dparams(self, model, Y, f, Y_metadata, params, param_names, param_constraints): + def t_d2logpdf2_dlink2_dparams( + self, model, Y, f, Y_metadata, params, param_names, param_constraints + ): print("\n{}".format(inspect.stack()[0][3])) print(model) - assert ( - dparam_checkgrad(model.d2logpdf_dlink2, model.d2logpdf_dlink2_dtheta, - params, param_names, args=(f, Y, Y_metadata), constraints=param_constraints, - randomize=False, verbose=True) - ) + assert dparam_checkgrad( + model.d2logpdf_dlink2, + model.d2logpdf_dlink2_dtheta, + params, + param_names, + args=(f, Y, Y_metadata), + constraints=param_constraints, + randomize=False, + verbose=True, + ) ################ # laplace test # ################ @with_setup(setUp, tearDown) - def t_laplace_fit_rbf_white(self, model, X, Y, f, Y_metadata, step, param_vals, param_names, constraints): + def t_laplace_fit_rbf_white( + self, model, X, Y, f, Y_metadata, step, param_vals, param_names, constraints + ): print("\n{}".format(inspect.stack()[0][3])) np.random.seed(111) - #Normalize + # Normalize # Y = Y/Y.max() white_var = 1e-4 kernel = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) laplace_likelihood = GPy.inference.latent_function_inference.Laplace() - m = GPy.core.GP(X.copy(), Y.copy(), kernel, likelihood=model, Y_metadata=Y_metadata, inference_method=laplace_likelihood) + m = GPy.core.GP( + X.copy(), + Y.copy(), + kernel, + likelihood=model, + Y_metadata=Y_metadata, + inference_method=laplace_likelihood, + ) m.kern.white.constrain_fixed(white_var) - #Set constraints + # Set constraints for constrain_param, constraint in constraints: constraint(constrain_param, m) m.randomize() - #Set params + # Set params for param_num in range(len(param_names)): name = param_names[param_num] m[name] = param_vals[param_num] @@ -630,16 +762,25 @@ class TestNoiseModels(object): # EP test # ########### @with_setup(setUp, tearDown) - def t_ep_fit_rbf_white(self, model, X, Y, f, Y_metadata, step, param_vals, param_names, constraints): + def t_ep_fit_rbf_white( + self, model, X, Y, f, Y_metadata, step, param_vals, param_names, constraints + ): print("\n{}".format(inspect.stack()[0][3])) - #Normalize + # Normalize # Y = Y/Y.max() white_var = 1e-4 kernel = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) ep_inf = GPy.inference.latent_function_inference.EP(always_reset=True) - m = GPy.core.GP(X.copy(), Y.copy(), kernel=kernel, likelihood=model, Y_metadata=Y_metadata, inference_method=ep_inf) - m['.*white'].constrain_fixed(white_var) + m = GPy.core.GP( + X.copy(), + Y.copy(), + kernel=kernel, + likelihood=model, + Y_metadata=Y_metadata, + inference_method=ep_inf, + ) + m[".*white"].constrain_fixed(white_var) for param_num in range(len(param_names)): name = param_names[param_num] @@ -655,30 +796,32 @@ class TestNoiseModels(object): ################ @with_setup(setUp, tearDown) def t_varexp(self, model, Y, Y_metadata): - #Test that the analytic implementation (if it exists) matches the generic gauss - #hermite implementation + # Test that the analytic implementation (if it exists) matches the generic gauss + # hermite implementation print("\n{}".format(inspect.stack()[0][3])) - #Make mu and var (marginal means and variances of q(f)) draws from a GP - k = GPy.kern.RBF(1).K(np.linspace(0,1,Y.shape[0])[:, None]) + # Make mu and var (marginal means and variances of q(f)) draws from a GP + k = GPy.kern.RBF(1).K(np.linspace(0, 1, Y.shape[0])[:, None]) L = GPy.util.linalg.jitchol(k) mu = L.dot(np.random.randn(*Y.shape)) - #Variance must be positive + # Variance must be positive var = np.abs(L.dot(np.random.randn(*Y.shape))) + 0.01 - expectation = model.variational_expectations(Y=Y, m=mu, v=var, gh_points=None, Y_metadata=Y_metadata)[0] + expectation = model.variational_expectations( + Y=Y, m=mu, v=var, gh_points=None, Y_metadata=Y_metadata + )[0] - #Implementation of gauss hermite integration + # Implementation of gauss hermite integration shape = mu.shape - gh_x, gh_w= np.polynomial.hermite.hermgauss(50) - m,v,Y = mu.flatten(), var.flatten(), Y.flatten() - #make a grid of points - X = gh_x[None,:]*np.sqrt(2.*v[:,None]) + m[:,None] - #evaluate the likelhood for the grid. First ax indexes the data (and mu, var) and the second indexes the grid. + gh_x, gh_w = np.polynomial.hermite.hermgauss(50) + m, v, Y = mu.flatten(), var.flatten(), Y.flatten() + # make a grid of points + X = gh_x[None, :] * np.sqrt(2.0 * v[:, None]) + m[:, None] + # evaluate the likelhood for the grid. First ax indexes the data (and mu, var) and the second indexes the grid. # broadcast needs to be handled carefully. - logp = model.logpdf(X, Y[:,None], Y_metadata=Y_metadata) - #average over the gird to get derivatives of the Gaussian's parameters - #division by pi comes from fact that for each quadrature we need to scale by 1/sqrt(pi) - expectation_gh = np.dot(logp, gh_w)/np.sqrt(np.pi) + logp = model.logpdf(X, Y[:, None], Y_metadata=Y_metadata) + # average over the gird to get derivatives of the Gaussian's parameters + # division by pi comes from fact that for each quadrature we need to scale by 1/sqrt(pi) + expectation_gh = np.dot(logp, gh_w) / np.sqrt(np.pi) expectation_gh = expectation_gh.reshape(*shape) np.testing.assert_almost_equal(expectation, expectation_gh, decimal=5) @@ -686,21 +829,28 @@ class TestNoiseModels(object): @with_setup(setUp, tearDown) def t_dexp_dmu(self, model, Y, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) - #Make mu and var (marginal means and variances of q(f)) draws from a GP - k = GPy.kern.RBF(1).K(np.linspace(0,1,Y.shape[0])[:, None]) + # Make mu and var (marginal means and variances of q(f)) draws from a GP + k = GPy.kern.RBF(1).K(np.linspace(0, 1, Y.shape[0])[:, None]) L = GPy.util.linalg.jitchol(k) mu = L.dot(np.random.randn(*Y.shape)) - #Variance must be positive + # Variance must be positive var = np.abs(L.dot(np.random.randn(*Y.shape))) + 0.01 - expectation = functools.partial(model.variational_expectations, Y=Y, v=var, gh_points=None, Y_metadata=Y_metadata) + expectation = functools.partial( + model.variational_expectations, + Y=Y, + v=var, + gh_points=None, + Y_metadata=Y_metadata, + ) - #Function to get the nth returned value + # Function to get the nth returned value def F(mu): return expectation(m=mu)[0] + def dmu(mu): return expectation(m=mu)[1] - grad = GradientChecker(F, dmu, mu.copy(), 'm') + grad = GradientChecker(F, dmu, mu.copy(), "m") grad.randomize() print(grad) @@ -710,28 +860,36 @@ class TestNoiseModels(object): @with_setup(setUp, tearDown) def t_dexp_dvar(self, model, Y, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) - #Make mu and var (marginal means and variances of q(f)) draws from a GP - k = GPy.kern.RBF(1).K(np.linspace(0,1,Y.shape[0])[:, None]) + # Make mu and var (marginal means and variances of q(f)) draws from a GP + k = GPy.kern.RBF(1).K(np.linspace(0, 1, Y.shape[0])[:, None]) L = GPy.util.linalg.jitchol(k) mu = L.dot(np.random.randn(*Y.shape)) - #Variance must be positive + # Variance must be positive var = np.abs(L.dot(np.random.randn(*Y.shape))) + 0.01 - expectation = functools.partial(model.variational_expectations, Y=Y, m=mu, gh_points=None, Y_metadata=Y_metadata) + expectation = functools.partial( + model.variational_expectations, + Y=Y, + m=mu, + gh_points=None, + Y_metadata=Y_metadata, + ) - #Function to get the nth returned value + # Function to get the nth returned value def F(var): return expectation(v=var)[0] + def dvar(var): return expectation(v=var)[2] - grad = GradientChecker(F, dvar, var.copy(), 'v') + grad = GradientChecker(F, dvar, var.copy(), "v") - self.constrain_positive('v', grad) - #grad.randomize() + self.constrain_positive("v", grad) + # grad.randomize() print(grad) print(model) assert grad.checkgrad(verbose=1) + class LaplaceTests(unittest.TestCase): """ Specific likelihood tests, not general enough for the above tests @@ -741,21 +899,21 @@ class LaplaceTests(unittest.TestCase): np.random.seed(fixed_seed) self.N = 15 self.D = 1 - self.X = np.random.rand(self.N, self.D)*10 + self.X = np.random.rand(self.N, self.D) * 10 self.real_std = 0.1 - noise = np.random.randn(*self.X[:, 0].shape)*self.real_std - self.Y = (np.sin(self.X[:, 0]*2*np.pi) + noise)[:, None] + noise = np.random.randn(*self.X[:, 0].shape) * self.real_std + self.Y = (np.sin(self.X[:, 0] * 2 * np.pi) + noise)[:, None] self.f = np.random.rand(self.N, 1) self.var = 0.2 self.var = np.random.rand(1) self.stu_t = GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var) - #TODO: gaussians with on Identity link. self.gauss = GPy.likelihoods.Gaussian(gp_link=link_functions.Log(), variance=self.var) + # TODO: gaussians with on Identity link. self.gauss = GPy.likelihoods.Gaussian(gp_link=link_functions.Log(), variance=self.var) self.gauss = GPy.likelihoods.Gaussian(variance=self.var) - #Make a bigger step as lower bound can be quite curved + # Make a bigger step as lower bound can be quite curved self.step = 1e-6 def tearDown(self): @@ -773,13 +931,13 @@ class LaplaceTests(unittest.TestCase): self.D = 1 self.X = np.linspace(0, self.D, self.N)[:, None] self.real_std = 0.2 - noise = np.random.randn(*self.X.shape)*self.real_std - self.Y = np.sin(self.X*2*np.pi) + noise + noise = np.random.randn(*self.X.shape) * self.real_std + self.Y = np.sin(self.X * 2 * np.pi) + noise self.f = np.random.rand(self.N, 1) dlogpdf_df = functools.partial(self.gauss.dlogpdf_df, y=self.Y) d2logpdf_df2 = functools.partial(self.gauss.d2logpdf_df2, y=self.Y) - grad = GradientChecker(dlogpdf_df, d2logpdf_df2, self.f.copy(), 'g') + grad = GradientChecker(dlogpdf_df, d2logpdf_df2, self.f.copy(), "g") grad.randomize() self.assertTrue(grad.checkgrad(verbose=1)) @@ -789,36 +947,48 @@ class LaplaceTests(unittest.TestCase): real_std = 0.1 initial_var_guess = 0.5 - #Start a function, any function - X = np.linspace(0.0, np.pi*2, 100)[:, None] - Y = np.sin(X) + np.random.randn(*X.shape)*real_std - Y = Y/Y.max() - #Yc = Y.copy() - #Yc[75:80] += 1 + # Start a function, any function + X = np.linspace(0.0, np.pi * 2, 100)[:, None] + Y = np.sin(X) + np.random.randn(*X.shape) * real_std + Y = Y / Y.max() + # Yc = Y.copy() + # Yc[75:80] += 1 kernel1 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) - #FIXME: Make sure you can copy kernels when params is fixed - #kernel2 = kernel1.copy() + # FIXME: Make sure you can copy kernels when params is fixed + # kernel2 = kernel1.copy() kernel2 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) gauss_distr1 = GPy.likelihoods.Gaussian(variance=initial_var_guess) exact_inf = GPy.inference.latent_function_inference.ExactGaussianInference() - m1 = GPy.core.GP(X, Y.copy(), kernel=kernel1, likelihood=gauss_distr1, inference_method=exact_inf) - m1['.*white'].constrain_fixed(1e-6) - m1['.*Gaussian_noise.variance'].constrain_bounded(1e-4, 10) + m1 = GPy.core.GP( + X, + Y.copy(), + kernel=kernel1, + likelihood=gauss_distr1, + inference_method=exact_inf, + ) + m1[".*white"].constrain_fixed(1e-6) + m1[".*Gaussian_noise.variance"].constrain_bounded(1e-4, 10) m1.randomize() gauss_distr2 = GPy.likelihoods.Gaussian(variance=initial_var_guess) laplace_inf = GPy.inference.latent_function_inference.Laplace() - m2 = GPy.core.GP(X, Y.copy(), kernel=kernel2, likelihood=gauss_distr2, inference_method=laplace_inf) - m2['.*white'].constrain_fixed(1e-6) - m2['.*Gaussian_noise.variance'].constrain_bounded(1e-4, 10) + m2 = GPy.core.GP( + X, + Y.copy(), + kernel=kernel2, + likelihood=gauss_distr2, + inference_method=laplace_inf, + ) + m2[".*white"].constrain_fixed(1e-6) + m2[".*Gaussian_noise.variance"].constrain_bounded(1e-4, 10) m2.randomize() if debug: print(m1) print(m2) - optimizer = 'scg' + optimizer = "scg" print("Gaussian") m1.optimize(optimizer, messages=debug, ipython_notebook=False) print("Laplace Gaussian") @@ -829,48 +999,57 @@ class LaplaceTests(unittest.TestCase): m2[:] = m1[:] - #Predict for training points to get posterior mean and variance + # Predict for training points to get posterior mean and variance post_mean, post_var = m1.predict(X) - post_mean_approx, post_var_approx, = m2.predict(X) + ( + post_mean_approx, + post_var_approx, + ) = m2.predict(X) if debug: from matplotlib import pyplot as pb + pb.figure(5) - pb.title('posterior means') - pb.scatter(X, post_mean, c='g') - pb.scatter(X, post_mean_approx, c='r', marker='x') + pb.title("posterior means") + pb.scatter(X, post_mean, c="g") + pb.scatter(X, post_mean_approx, c="r", marker="x") pb.figure(6) - pb.title('plot_f') + pb.title("plot_f") m1.plot_f(fignum=6) m2.plot_f(fignum=6) fig, axes = pb.subplots(2, 1) - fig.suptitle('Covariance matricies') + fig.suptitle("Covariance matricies") a1 = pb.subplot(121) a1.matshow(m1.likelihood.covariance_matrix) a2 = pb.subplot(122) a2.matshow(m2.likelihood.covariance_matrix) pb.figure(8) - pb.scatter(X, m1.likelihood.Y, c='g') - pb.scatter(X, m2.likelihood.Y, c='r', marker='x') + pb.scatter(X, m1.likelihood.Y, c="g") + pb.scatter(X, m2.likelihood.Y, c="r", marker="x") - #Check Y's are the same + # Check Y's are the same np.testing.assert_almost_equal(m1.Y, m2.Y, decimal=5) - #Check marginals are the same - np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), decimal=2) - #Check marginals are the same with random + # Check marginals are the same + np.testing.assert_almost_equal( + m1.log_likelihood(), m2.log_likelihood(), decimal=2 + ) + # Check marginals are the same with random m1.randomize() m2[:] = m1[:] - np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), decimal=2) + np.testing.assert_almost_equal( + m1.log_likelihood(), m2.log_likelihood(), decimal=2 + ) - #Check they are checkgradding - #m1.checkgrad(verbose=1) - #m2.checkgrad(verbose=1) + # Check they are checkgradding + # m1.checkgrad(verbose=1) + # m2.checkgrad(verbose=1) self.assertTrue(m1.checkgrad(verbose=True)) self.assertTrue(m2.checkgrad(verbose=True)) + if __name__ == "__main__": print("Running unit tests") unittest.main() From 58f61d5a5cc4e840c0e5ec567db23562a2822f2e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:50:21 +0200 Subject: [PATCH 022/101] migrate likelihood_tests to pytest --- GPy/testing/likelihood_tests.py | 61 ++++++++------------------------- 1 file changed, 14 insertions(+), 47 deletions(-) diff --git a/GPy/testing/likelihood_tests.py b/GPy/testing/likelihood_tests.py index 4ed694d8..ce82b9c0 100644 --- a/GPy/testing/likelihood_tests.py +++ b/GPy/testing/likelihood_tests.py @@ -121,15 +121,12 @@ def dparam_checkgrad( return gradchecking -from nose.tools import with_setup - - -class TestNoiseModels(object): +class TestNoiseModels: """ Generic model checker """ - def setUp(self): + def setup(self): np.random.seed(fixed_seed) self.N = 15 self.D = 3 @@ -418,13 +415,8 @@ class TestNoiseModels(object): """ model[regex].constrain_bounded(lower, upper) - def tearDown(self): - self.Y = None - self.f = None - self.X = None - def test_scale2_models(self): - self.setUp() + self.setup() for name, attributes in self.noise_models.items(): model = attributes["model"] @@ -503,12 +495,12 @@ class TestNoiseModels(object): yield self.t_dexp_dmu, model, Y, Y_metadata yield self.t_dexp_dvar, model, Y, Y_metadata - self.tearDown() + # TODO: how to now run all of the tests? ############# - # dpdf_df's # + # dpdf + # _df's # ############# - @with_setup(setUp, tearDown) def t_logpdf(self, model, Y, f, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) print(model) @@ -518,7 +510,6 @@ class TestNoiseModels(object): np.exp(model.logpdf(f.copy(), Y.copy(), Y_metadata=Y_metadata).sum()), ) - @with_setup(setUp, tearDown) def t_dlogpdf_df(self, model, Y, f, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) self.description = "\n{}".format(inspect.stack()[0][3]) @@ -529,7 +520,6 @@ class TestNoiseModels(object): print(model) assert grad.checkgrad(verbose=1) - @with_setup(setUp, tearDown) def t_d2logpdf_df2(self, model, Y, f, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y, Y_metadata=Y_metadata) @@ -539,7 +529,6 @@ class TestNoiseModels(object): print(model) assert grad.checkgrad(verbose=1) - @with_setup(setUp, tearDown) def t_d3logpdf_df3(self, model, Y, f, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y, Y_metadata=Y_metadata) @@ -552,7 +541,6 @@ class TestNoiseModels(object): ############## # df_dparams # ############## - @with_setup(setUp, tearDown) def t_dlogpdf_dparams( self, model, Y, f, Y_metadata, params, params_names, param_constraints ): @@ -569,7 +557,6 @@ class TestNoiseModels(object): verbose=True, ) - @with_setup(setUp, tearDown) def t_dlogpdf_df_dparams( self, model, Y, f, Y_metadata, params, params_names, param_constraints ): @@ -586,7 +573,6 @@ class TestNoiseModels(object): verbose=True, ) - @with_setup(setUp, tearDown) def t_d2logpdf2_df2_dparams( self, model, Y, f, Y_metadata, params, params_names, param_constraints ): @@ -606,7 +592,6 @@ class TestNoiseModels(object): ################ # dpdf_dlink's # ################ - @with_setup(setUp, tearDown) def t_dlogpdf_dlink(self, model, Y, f, Y_metadata, link_f_constraints): print("\n{}".format(inspect.stack()[0][3])) logpdf = functools.partial(model.logpdf_link, y=Y, Y_metadata=Y_metadata) @@ -624,7 +609,6 @@ class TestNoiseModels(object): print(model) assert grad.checkgrad(verbose=1) - @with_setup(setUp, tearDown) def t_d2logpdf_dlink2(self, model, Y, f, Y_metadata, link_f_constraints): print("\n{}".format(inspect.stack()[0][3])) dlogpdf_dlink = functools.partial( @@ -644,7 +628,6 @@ class TestNoiseModels(object): print(model) assert grad.checkgrad(verbose=1) - @with_setup(setUp, tearDown) def t_d3logpdf_dlink3(self, model, Y, f, Y_metadata, link_f_constraints): print("\n{}".format(inspect.stack()[0][3])) d2logpdf_dlink2 = functools.partial( @@ -667,7 +650,6 @@ class TestNoiseModels(object): ################# # dlink_dparams # ################# - @with_setup(setUp, tearDown) def t_dlogpdf_link_dparams( self, model, Y, f, Y_metadata, params, param_names, param_constraints ): @@ -684,7 +666,6 @@ class TestNoiseModels(object): verbose=True, ) - @with_setup(setUp, tearDown) def t_dlogpdf_dlink_dparams( self, model, Y, f, Y_metadata, params, param_names, param_constraints ): @@ -701,7 +682,6 @@ class TestNoiseModels(object): verbose=True, ) - @with_setup(setUp, tearDown) def t_d2logpdf2_dlink2_dparams( self, model, Y, f, Y_metadata, params, param_names, param_constraints ): @@ -721,7 +701,6 @@ class TestNoiseModels(object): ################ # laplace test # ################ - @with_setup(setUp, tearDown) def t_laplace_fit_rbf_white( self, model, X, Y, f, Y_metadata, step, param_vals, param_names, constraints ): @@ -761,7 +740,6 @@ class TestNoiseModels(object): ########### # EP test # ########### - @with_setup(setUp, tearDown) def t_ep_fit_rbf_white( self, model, X, Y, f, Y_metadata, step, param_vals, param_names, constraints ): @@ -794,7 +772,6 @@ class TestNoiseModels(object): ################ # variational expectations # ################ - @with_setup(setUp, tearDown) def t_varexp(self, model, Y, Y_metadata): # Test that the analytic implementation (if it exists) matches the generic gauss # hermite implementation @@ -826,7 +803,6 @@ class TestNoiseModels(object): np.testing.assert_almost_equal(expectation, expectation_gh, decimal=5) - @with_setup(setUp, tearDown) def t_dexp_dmu(self, model, Y, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) # Make mu and var (marginal means and variances of q(f)) draws from a GP @@ -857,7 +833,6 @@ class TestNoiseModels(object): print(model) assert grad.checkgrad(verbose=1) - @with_setup(setUp, tearDown) def t_dexp_dvar(self, model, Y, Y_metadata): print("\n{}".format(inspect.stack()[0][3])) # Make mu and var (marginal means and variances of q(f)) draws from a GP @@ -890,12 +865,12 @@ class TestNoiseModels(object): assert grad.checkgrad(verbose=1) -class LaplaceTests(unittest.TestCase): +class LaplaceTests: """ Specific likelihood tests, not general enough for the above tests """ - def setUp(self): + def setup(self): np.random.seed(fixed_seed) self.N = 15 self.D = 1 @@ -916,14 +891,9 @@ class LaplaceTests(unittest.TestCase): # Make a bigger step as lower bound can be quite curved self.step = 1e-6 - def tearDown(self): - self.stu_t = None - self.gauss = None - self.Y = None - self.f = None - self.X = None - def test_gaussian_d2logpdf_df2_2(self): + self.setup() + print("\n{}".format(inspect.stack()[0][3])) self.Y = None @@ -943,6 +913,8 @@ class LaplaceTests(unittest.TestCase): self.assertTrue(grad.checkgrad(verbose=1)) def test_laplace_log_likelihood(self): + self.setup() + debug = False real_std = 0.1 initial_var_guess = 0.5 @@ -1046,10 +1018,5 @@ class LaplaceTests(unittest.TestCase): # Check they are checkgradding # m1.checkgrad(verbose=1) # m2.checkgrad(verbose=1) - self.assertTrue(m1.checkgrad(verbose=True)) - self.assertTrue(m2.checkgrad(verbose=True)) - - -if __name__ == "__main__": - print("Running unit tests") - unittest.main() + assert m1.checkgrad(verbose=True) + assert m2.checkgrad(verbose=True) From 8af7c8286c10fab269b2db12600fae018dae6688 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:50:55 +0200 Subject: [PATCH 023/101] format on save --- GPy/testing/linalg_test.py | 41 ++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/GPy/testing/linalg_test.py b/GPy/testing/linalg_test.py index fd818433..94b9a345 100644 --- a/GPy/testing/linalg_test.py +++ b/GPy/testing/linalg_test.py @@ -1,18 +1,19 @@ import numpy as np import scipy as sp -from ..util.linalg import jitchol,trace_dot, ijk_jlk_to_il, ijk_ljk_to_ilk +from ..util.linalg import jitchol, trace_dot, ijk_jlk_to_il, ijk_ljk_to_ilk -class LinalgTests(np.testing.TestCase): - def setUp(self): - #Create PD matrix - A = np.random.randn(20,100) + +class LinalgTests: + def setup(self): + # Create PD matrix + A = np.random.randn(20, 100) self.A = A.dot(A.T) - #compute Eigdecomp + # compute Eigdecomp vals, vectors = np.linalg.eig(self.A) - #Set smallest eigenval to be negative with 5 rounds worth of jitter + # Set smallest eigenval to be negative with 5 rounds worth of jitter vals[vals.argmin()] = 0 - default_jitter = 1e-6*np.mean(vals) - vals[vals.argmin()] = -default_jitter*(10**3.5) + default_jitter = 1e-6 * np.mean(vals) + vals[vals.argmin()] = -default_jitter * (10**3.5) self.A_corrupt = (vectors * vals).dot(vectors.T) def test_jitchol_success(self): @@ -23,7 +24,9 @@ class LinalgTests(np.testing.TestCase): L = jitchol(self.A_corrupt, maxtries=5) A_new = L.dot(L.T) diff = A_new - self.A_corrupt - np.testing.assert_allclose(diff, np.eye(A_new.shape[0])*np.diag(diff).mean(), atol=1e-13) + np.testing.assert_allclose( + diff, np.eye(A_new.shape[0]) * np.diag(diff).mean(), atol=1e-13 + ) def test_jitchol_failure(self): try: @@ -38,23 +41,23 @@ class LinalgTests(np.testing.TestCase): def test_trace_dot(self): N = 5 - A = np.random.rand(N,N) - B = np.random.rand(N,N) + A = np.random.rand(N, N) + B = np.random.rand(N, N) trace = np.trace(A.dot(B)) - test_trace = trace_dot(A,B) - np.testing.assert_allclose(trace,test_trace,atol=1e-13) + test_trace = trace_dot(A, B) + np.testing.assert_allclose(trace, test_trace, atol=1e-13) def test_einsum_ij_jlk_to_ilk(self): A = np.random.randn(15, 150, 5) B = np.random.randn(150, 50, 5) - pure = np.einsum('ijk,jlk->il', A, B) - quick = ijk_jlk_to_il(A,B) + pure = np.einsum("ijk,jlk->il", A, B) + quick = ijk_jlk_to_il(A, B) np.testing.assert_allclose(pure, quick) def test_einsum_ijk_ljk_to_ilk(self): A = np.random.randn(150, 20, 5) B = np.random.randn(150, 20, 5) - #B = A.copy() - pure = np.einsum('ijk,ljk->ilk', A, B) - quick = ijk_ljk_to_ilk(A,B) + # B = A.copy() + pure = np.einsum("ijk,ljk->ilk", A, B) + quick = ijk_ljk_to_ilk(A, B) np.testing.assert_allclose(pure, quick) From ef7d2f299ceb8a2d37c310ad425961cd7b155862 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:51:48 +0200 Subject: [PATCH 024/101] migrate linalg test to pytest --- GPy/testing/linalg_test.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/GPy/testing/linalg_test.py b/GPy/testing/linalg_test.py index 94b9a345..1bd6aa8f 100644 --- a/GPy/testing/linalg_test.py +++ b/GPy/testing/linalg_test.py @@ -3,7 +3,7 @@ import scipy as sp from ..util.linalg import jitchol, trace_dot, ijk_jlk_to_il, ijk_ljk_to_ilk -class LinalgTests: +class TestLinalg: def setup(self): # Create PD matrix A = np.random.randn(20, 100) @@ -21,6 +21,7 @@ class LinalgTests: Expect 5 rounds of jitter to be added and for the recovered matrix to be identical to the corrupted matrix apart from the jitter added to the diagonal """ + self.setup() L = jitchol(self.A_corrupt, maxtries=5) A_new = L.dot(L.T) diff = A_new - self.A_corrupt @@ -29,6 +30,7 @@ class LinalgTests: ) def test_jitchol_failure(self): + self.setup() try: """ Expecting an exception to be thrown as we expect it to require @@ -40,6 +42,7 @@ class LinalgTests: return True def test_trace_dot(self): + self.setup() N = 5 A = np.random.rand(N, N) B = np.random.rand(N, N) @@ -48,6 +51,7 @@ class LinalgTests: np.testing.assert_allclose(trace, test_trace, atol=1e-13) def test_einsum_ij_jlk_to_ilk(self): + self.setup() A = np.random.randn(15, 150, 5) B = np.random.randn(150, 50, 5) pure = np.einsum("ijk,jlk->il", A, B) @@ -55,6 +59,7 @@ class LinalgTests: np.testing.assert_allclose(pure, quick) def test_einsum_ijk_ljk_to_ilk(self): + self.setup() A = np.random.randn(150, 20, 5) B = np.random.randn(150, 20, 5) # B = A.copy() From 393f9938ea90da47d553bb30ddf50bea8ea0daf9 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:52:02 +0200 Subject: [PATCH 025/101] format on save --- GPy/testing/link_function_tests.py | 96 ++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/GPy/testing/link_function_tests.py b/GPy/testing/link_function_tests.py index 8f3525b0..0db85413 100644 --- a/GPy/testing/link_function_tests.py +++ b/GPy/testing/link_function_tests.py @@ -3,11 +3,22 @@ import scipy from scipy.special import cbrt from GPy.models import GradientChecker import random + _lim_val = np.finfo(np.float64).max _lim_val_exp = np.log(_lim_val) _lim_val_square = np.sqrt(_lim_val) _lim_val_cube = cbrt(_lim_val) -from GPy.likelihoods.link_functions import Identity, Probit, Cloglog, Log, Log_ex_1, Reciprocal, Heaviside, ScaledProbit +from GPy.likelihoods.link_functions import ( + Identity, + Probit, + Cloglog, + Log, + Log_ex_1, + Reciprocal, + Heaviside, + ScaledProbit, +) + class LinkFunctionTests(np.testing.TestCase): def setUp(self): @@ -21,48 +32,70 @@ class LinkFunctionTests(np.testing.TestCase): def check_gradient(self, link_func, lim_of_inf, test_lim=False): grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=self.mid_f) self.assertTrue(grad.checkgrad(verbose=True)) - grad2 = GradientChecker(link_func.dtransf_df, link_func.d2transf_df2, x0=self.mid_f) + grad2 = GradientChecker( + link_func.dtransf_df, link_func.d2transf_df2, x0=self.mid_f + ) self.assertTrue(grad2.checkgrad(verbose=True)) - grad3 = GradientChecker(link_func.d2transf_df2, link_func.d3transf_df3, x0=self.mid_f) + grad3 = GradientChecker( + link_func.d2transf_df2, link_func.d3transf_df3, x0=self.mid_f + ) self.assertTrue(grad3.checkgrad(verbose=True)) grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=self.small_f) self.assertTrue(grad.checkgrad(verbose=True)) - grad2 = GradientChecker(link_func.dtransf_df, link_func.d2transf_df2, x0=self.small_f) + grad2 = GradientChecker( + link_func.dtransf_df, link_func.d2transf_df2, x0=self.small_f + ) self.assertTrue(grad2.checkgrad(verbose=True)) - grad3 = GradientChecker(link_func.d2transf_df2, link_func.d3transf_df3, x0=self.small_f) + grad3 = GradientChecker( + link_func.d2transf_df2, link_func.d3transf_df3, x0=self.small_f + ) self.assertTrue(grad3.checkgrad(verbose=True)) grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=self.zero_f) self.assertTrue(grad.checkgrad(verbose=True)) - grad2 = GradientChecker(link_func.dtransf_df, link_func.d2transf_df2, x0=self.zero_f) + grad2 = GradientChecker( + link_func.dtransf_df, link_func.d2transf_df2, x0=self.zero_f + ) self.assertTrue(grad2.checkgrad(verbose=True)) - grad3 = GradientChecker(link_func.d2transf_df2, link_func.d3transf_df3, x0=self.zero_f) + grad3 = GradientChecker( + link_func.d2transf_df2, link_func.d3transf_df3, x0=self.zero_f + ) self.assertTrue(grad3.checkgrad(verbose=True)) - #Do a limit test if the large f value is too large - large_f = np.clip(self.large_f, -np.inf, lim_of_inf-1e-3) + # Do a limit test if the large f value is too large + large_f = np.clip(self.large_f, -np.inf, lim_of_inf - 1e-3) grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=large_f) self.assertTrue(grad.checkgrad(verbose=True)) - grad2 = GradientChecker(link_func.dtransf_df, link_func.d2transf_df2, x0=large_f) + grad2 = GradientChecker( + link_func.dtransf_df, link_func.d2transf_df2, x0=large_f + ) self.assertTrue(grad2.checkgrad(verbose=True)) - grad3 = GradientChecker(link_func.d2transf_df2, link_func.d3transf_df3, x0=large_f) + grad3 = GradientChecker( + link_func.d2transf_df2, link_func.d3transf_df3, x0=large_f + ) self.assertTrue(grad3.checkgrad(verbose=True)) if test_lim: print("Testing limits") - #Remove some otherwise we are too close to the limit for gradcheck to work effectively + # Remove some otherwise we are too close to the limit for gradcheck to work effectively lim_of_inf = lim_of_inf - 1e-4 - grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=lim_of_inf) + grad = GradientChecker( + link_func.transf, link_func.dtransf_df, x0=lim_of_inf + ) self.assertTrue(grad.checkgrad(verbose=True)) - grad2 = GradientChecker(link_func.dtransf_df, link_func.d2transf_df2, x0=lim_of_inf) + grad2 = GradientChecker( + link_func.dtransf_df, link_func.d2transf_df2, x0=lim_of_inf + ) self.assertTrue(grad2.checkgrad(verbose=True)) - grad3 = GradientChecker(link_func.d2transf_df2, link_func.d3transf_df3, x0=lim_of_inf) + grad3 = GradientChecker( + link_func.d2transf_df2, link_func.d3transf_df3, x0=lim_of_inf + ) self.assertTrue(grad3.checkgrad(verbose=True)) def check_overflow(self, link_func, lim_of_inf): - #Check that it does something sensible beyond this limit, - #note this is not checking the value is correct, just that it isn't nan + # Check that it does something sensible beyond this limit, + # note this is not checking the value is correct, just that it isn't nan beyond_lim_of_inf = lim_of_inf + 100.0 self.assertFalse(np.isinf(link_func.transf(beyond_lim_of_inf))) self.assertFalse(np.isinf(link_func.dtransf_df(beyond_lim_of_inf))) @@ -78,14 +111,14 @@ class LinkFunctionTests(np.testing.TestCase): np.testing.assert_almost_equal(np.exp(self.mid_f), link.transf(self.mid_f)) assert np.isinf(np.exp(np.log(self.f_upper_lim))) - #Check the clipping works + # Check the clipping works np.testing.assert_almost_equal(link.transf(self.f_lower_lim), 0, decimal=5) self.assertTrue(np.isfinite(link.transf(self.f_upper_lim))) self.check_overflow(link, lim_of_inf) - #Check that it would otherwise fail + # Check that it would otherwise fail beyond_lim_of_inf = lim_of_inf + 10.0 - old_err_state = np.seterr(over='ignore') + old_err_state = np.seterr(over="ignore") self.assertTrue(np.isinf(np.exp(beyond_lim_of_inf))) np.seterr(**old_err_state) @@ -93,21 +126,24 @@ class LinkFunctionTests(np.testing.TestCase): link = Log_ex_1() lim_of_inf = _lim_val_exp - np.testing.assert_almost_equal(scipy.special.log1p(np.exp(self.mid_f)), link.transf(self.mid_f)) + np.testing.assert_almost_equal( + scipy.special.log1p(np.exp(self.mid_f)), link.transf(self.mid_f) + ) assert np.isinf(scipy.special.log1p(np.exp(np.log(self.f_upper_lim)))) - #Check the clipping works + # Check the clipping works np.testing.assert_almost_equal(link.transf(self.f_lower_lim), 0, decimal=5) - #Need to look at most significant figures here rather than the decimals - np.testing.assert_approx_equal(link.transf(self.f_upper_lim), scipy.special.log1p(_lim_val), significant=5) + # Need to look at most significant figures here rather than the decimals + np.testing.assert_approx_equal( + link.transf(self.f_upper_lim), scipy.special.log1p(_lim_val), significant=5 + ) self.check_overflow(link, lim_of_inf) - #Check that it would otherwise fail + # Check that it would otherwise fail beyond_lim_of_inf = lim_of_inf + 10.0 - old_err_state = np.seterr(over='ignore') + old_err_state = np.seterr(over="ignore") self.assertTrue(np.isinf(scipy.special.log1p(np.exp(beyond_lim_of_inf)))) np.seterr(**old_err_state) - def test_log_gradients(self): # transf dtransf_df d2transf_df2 d3transf_df3 link = Log() @@ -117,14 +153,14 @@ class LinkFunctionTests(np.testing.TestCase): def test_identity_gradients(self): link = Identity() lim_of_inf = _lim_val - #FIXME: Should be able to think of a way to test the limits of this + # FIXME: Should be able to think of a way to test the limits of this self.check_gradient(link, lim_of_inf, test_lim=False) def test_probit_gradients(self): link = Probit() lim_of_inf = _lim_val self.check_gradient(link, lim_of_inf, test_lim=True) - + def test_scaledprobit_gradients(self): link = ScaledProbit(nu=random.random()) lim_of_inf = _lim_val @@ -144,5 +180,5 @@ class LinkFunctionTests(np.testing.TestCase): def test_reciprocal_gradients(self): link = Reciprocal() lim_of_inf = _lim_val - #Does not work with much smaller values, and values closer to zero than 1e-5 + # Does not work with much smaller values, and values closer to zero than 1e-5 self.check_gradient(link, lim_of_inf, test_lim=True) From 7340cf7f7f823ec2558adb3ff67399dd20d837c6 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:56:26 +0200 Subject: [PATCH 026/101] migrate link_function_tests to pytest --- GPy/testing/link_function_tests.py | 64 ++++++++++++++++++------------ 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/GPy/testing/link_function_tests.py b/GPy/testing/link_function_tests.py index 0db85413..d4aeefa6 100644 --- a/GPy/testing/link_function_tests.py +++ b/GPy/testing/link_function_tests.py @@ -20,8 +20,8 @@ from GPy.likelihoods.link_functions import ( ) -class LinkFunctionTests(np.testing.TestCase): - def setUp(self): +class TestLinkFunction: + def setup(self): self.small_f = np.array([[-1e-4]]) self.zero_f = np.array([[1e-4]]) self.mid_f = np.array([[5.0]]) @@ -31,50 +31,50 @@ class LinkFunctionTests(np.testing.TestCase): def check_gradient(self, link_func, lim_of_inf, test_lim=False): grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=self.mid_f) - self.assertTrue(grad.checkgrad(verbose=True)) + assert grad.checkgrad(verbose=True) grad2 = GradientChecker( link_func.dtransf_df, link_func.d2transf_df2, x0=self.mid_f ) - self.assertTrue(grad2.checkgrad(verbose=True)) + assert grad2.checkgrad(verbose=True) grad3 = GradientChecker( link_func.d2transf_df2, link_func.d3transf_df3, x0=self.mid_f ) - self.assertTrue(grad3.checkgrad(verbose=True)) + assert grad3.checkgrad(verbose=True) grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=self.small_f) - self.assertTrue(grad.checkgrad(verbose=True)) + assert grad.checkgrad(verbose=True) grad2 = GradientChecker( link_func.dtransf_df, link_func.d2transf_df2, x0=self.small_f ) - self.assertTrue(grad2.checkgrad(verbose=True)) + assert grad2.checkgrad(verbose=True) grad3 = GradientChecker( link_func.d2transf_df2, link_func.d3transf_df3, x0=self.small_f ) - self.assertTrue(grad3.checkgrad(verbose=True)) + assert grad3.checkgrad(verbose=True) grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=self.zero_f) - self.assertTrue(grad.checkgrad(verbose=True)) + assert grad.checkgrad(verbose=True) grad2 = GradientChecker( link_func.dtransf_df, link_func.d2transf_df2, x0=self.zero_f ) - self.assertTrue(grad2.checkgrad(verbose=True)) + assert grad2.checkgrad(verbose=True) grad3 = GradientChecker( link_func.d2transf_df2, link_func.d3transf_df3, x0=self.zero_f ) - self.assertTrue(grad3.checkgrad(verbose=True)) + assert grad3.checkgrad(verbose=True) # Do a limit test if the large f value is too large large_f = np.clip(self.large_f, -np.inf, lim_of_inf - 1e-3) grad = GradientChecker(link_func.transf, link_func.dtransf_df, x0=large_f) - self.assertTrue(grad.checkgrad(verbose=True)) + assert grad.checkgrad(verbose=True) grad2 = GradientChecker( link_func.dtransf_df, link_func.d2transf_df2, x0=large_f ) - self.assertTrue(grad2.checkgrad(verbose=True)) + assert grad2.checkgrad(verbose=True) grad3 = GradientChecker( link_func.d2transf_df2, link_func.d3transf_df3, x0=large_f ) - self.assertTrue(grad3.checkgrad(verbose=True)) + assert grad3.checkgrad(verbose=True) if test_lim: print("Testing limits") @@ -83,29 +83,31 @@ class LinkFunctionTests(np.testing.TestCase): grad = GradientChecker( link_func.transf, link_func.dtransf_df, x0=lim_of_inf ) - self.assertTrue(grad.checkgrad(verbose=True)) + assert grad.checkgrad(verbose=True) grad2 = GradientChecker( link_func.dtransf_df, link_func.d2transf_df2, x0=lim_of_inf ) - self.assertTrue(grad2.checkgrad(verbose=True)) + assert grad2.checkgrad(verbose=True) grad3 = GradientChecker( link_func.d2transf_df2, link_func.d3transf_df3, x0=lim_of_inf ) - self.assertTrue(grad3.checkgrad(verbose=True)) + assert grad3.checkgrad(verbose=True) def check_overflow(self, link_func, lim_of_inf): # Check that it does something sensible beyond this limit, # note this is not checking the value is correct, just that it isn't nan beyond_lim_of_inf = lim_of_inf + 100.0 - self.assertFalse(np.isinf(link_func.transf(beyond_lim_of_inf))) - self.assertFalse(np.isinf(link_func.dtransf_df(beyond_lim_of_inf))) - self.assertFalse(np.isinf(link_func.d2transf_df2(beyond_lim_of_inf))) + assert np.isinf(link_func.transf(beyond_lim_of_inf)) + assert np.isinf(link_func.dtransf_df(beyond_lim_of_inf)) + assert np.isinf(link_func.d2transf_df2(beyond_lim_of_inf)) - self.assertFalse(np.isnan(link_func.transf(beyond_lim_of_inf))) - self.assertFalse(np.isnan(link_func.dtransf_df(beyond_lim_of_inf))) - self.assertFalse(np.isnan(link_func.d2transf_df2(beyond_lim_of_inf))) + assert np.isnan(link_func.transf(beyond_lim_of_inf)) + assert np.isnan(link_func.dtransf_df(beyond_lim_of_inf)) + assert np.isnan(link_func.d2transf_df2(beyond_lim_of_inf)) def test_log_overflow(self): + self.setup() + link = Log() lim_of_inf = _lim_val_exp @@ -113,16 +115,18 @@ class LinkFunctionTests(np.testing.TestCase): assert np.isinf(np.exp(np.log(self.f_upper_lim))) # Check the clipping works np.testing.assert_almost_equal(link.transf(self.f_lower_lim), 0, decimal=5) - self.assertTrue(np.isfinite(link.transf(self.f_upper_lim))) + assert np.isfinite(link.transf(self.f_upper_lim)) self.check_overflow(link, lim_of_inf) # Check that it would otherwise fail beyond_lim_of_inf = lim_of_inf + 10.0 old_err_state = np.seterr(over="ignore") - self.assertTrue(np.isinf(np.exp(beyond_lim_of_inf))) + assert np.isinf(np.exp(beyond_lim_of_inf)) np.seterr(**old_err_state) def test_log_ex_1_overflow(self): + self.setup() + link = Log_ex_1() lim_of_inf = _lim_val_exp @@ -141,43 +145,51 @@ class LinkFunctionTests(np.testing.TestCase): # Check that it would otherwise fail beyond_lim_of_inf = lim_of_inf + 10.0 old_err_state = np.seterr(over="ignore") - self.assertTrue(np.isinf(scipy.special.log1p(np.exp(beyond_lim_of_inf)))) + assert np.isinf(scipy.special.log1p(np.exp(beyond_lim_of_inf))) np.seterr(**old_err_state) def test_log_gradients(self): # transf dtransf_df d2transf_df2 d3transf_df3 + self.setup() + link = Log() lim_of_inf = _lim_val_exp self.check_gradient(link, lim_of_inf, test_lim=True) def test_identity_gradients(self): + self.setup() link = Identity() lim_of_inf = _lim_val # FIXME: Should be able to think of a way to test the limits of this self.check_gradient(link, lim_of_inf, test_lim=False) def test_probit_gradients(self): + self.setup() link = Probit() lim_of_inf = _lim_val self.check_gradient(link, lim_of_inf, test_lim=True) def test_scaledprobit_gradients(self): + self.setup() link = ScaledProbit(nu=random.random()) lim_of_inf = _lim_val self.check_gradient(link, lim_of_inf, test_lim=True) def test_Cloglog_gradients(self): + self.setup() link = Cloglog() lim_of_inf = _lim_val_exp self.check_gradient(link, lim_of_inf, test_lim=True) def test_Log_ex_1_gradients(self): + self.setup() link = Log_ex_1() lim_of_inf = _lim_val_exp self.check_gradient(link, lim_of_inf, test_lim=True) self.check_overflow(link, lim_of_inf) def test_reciprocal_gradients(self): + self.setup() link = Reciprocal() lim_of_inf = _lim_val # Does not work with much smaller values, and values closer to zero than 1e-5 From 618f35531d1aa439aa741f6460d3a7a150eec25c Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:56:50 +0200 Subject: [PATCH 027/101] format on save --- GPy/testing/mapping_tests.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/GPy/testing/mapping_tests.py b/GPy/testing/mapping_tests.py index d07561ab..0c10e53b 100644 --- a/GPy/testing/mapping_tests.py +++ b/GPy/testing/mapping_tests.py @@ -5,6 +5,7 @@ import unittest import numpy as np import GPy + class MappingGradChecker(GPy.core.Model): """ This class has everything we need to check the gradient of a mapping. It @@ -12,63 +13,65 @@ class MappingGradChecker(GPy.core.Model): mapping. the gradients are checked against the parameters of the mapping and the input. """ - def __init__(self, mapping, X, name='map_grad_check'): + + def __init__(self, mapping, X, name="map_grad_check"): super(MappingGradChecker, self).__init__(name) self.mapping = mapping self.link_parameter(self.mapping) - self.X = GPy.core.Param('X',X) + self.X = GPy.core.Param("X", X) self.link_parameter(self.X) self.dL_dY = np.random.randn(self.X.shape[0], self.mapping.output_dim) + def log_likelihood(self): return np.sum(self.mapping.f(self.X) * self.dL_dY) + def parameters_changed(self): self.X.gradient = self.mapping.gradients_X(self.dL_dY, self.X) self.mapping.update_gradients(self.dL_dY, self.X) class MappingTests(unittest.TestCase): - def test_kernelmapping(self): - X = np.random.randn(100,3) - Z = np.random.randn(10,3) + X = np.random.randn(100, 3) + Z = np.random.randn(10, 3) mapping = GPy.mappings.Kernel(3, 2, Z, GPy.kern.RBF(3)) self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) def test_linearmapping(self): mapping = GPy.mappings.Linear(3, 2) - X = np.random.randn(100,3) + X = np.random.randn(100, 3) self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) def test_mlpmapping(self): mapping = GPy.mappings.MLP(input_dim=3, hidden_dim=5, output_dim=2) - X = np.random.randn(100,3) + X = np.random.randn(100, 3) self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) def test_mlpextmapping(self): np.random.seed(42) - X = np.random.randn(100,3) - for activation in ['tanh', 'relu', 'sigmoid']: - mapping = GPy.mappings.MLPext(input_dim=3, hidden_dims=[5,5], output_dim=2, activation=activation) + X = np.random.randn(100, 3) + for activation in ["tanh", "relu", "sigmoid"]: + mapping = GPy.mappings.MLPext( + input_dim=3, hidden_dims=[5, 5], output_dim=2, activation=activation + ) self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) def test_addmapping(self): m1 = GPy.mappings.MLP(input_dim=3, hidden_dim=5, output_dim=2) m2 = GPy.mappings.Linear(input_dim=3, output_dim=2) mapping = GPy.mappings.Additive(m1, m2) - X = np.random.randn(100,3) + X = np.random.randn(100, 3) self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) def test_compoundmapping(self): m1 = GPy.mappings.MLP(input_dim=3, hidden_dim=5, output_dim=2) - Z = np.random.randn(10,2) + Z = np.random.randn(10, 2) m2 = GPy.mappings.Kernel(2, 4, Z, GPy.kern.RBF(2)) mapping = GPy.mappings.Compound(m1, m2) - X = np.random.randn(100,3) + X = np.random.randn(100, 3) self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) - - if __name__ == "__main__": print("Running unit tests, please be (very) patient...") unittest.main() From c20a361179e0339cfdad5d3f4e6918a05ed390c6 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:58:00 +0200 Subject: [PATCH 028/101] migrate mapping_tests to pytest --- GPy/testing/mapping_tests.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/GPy/testing/mapping_tests.py b/GPy/testing/mapping_tests.py index 0c10e53b..6b829f06 100644 --- a/GPy/testing/mapping_tests.py +++ b/GPy/testing/mapping_tests.py @@ -30,22 +30,22 @@ class MappingGradChecker(GPy.core.Model): self.mapping.update_gradients(self.dL_dY, self.X) -class MappingTests(unittest.TestCase): +class TestMapping: def test_kernelmapping(self): X = np.random.randn(100, 3) Z = np.random.randn(10, 3) mapping = GPy.mappings.Kernel(3, 2, Z, GPy.kern.RBF(3)) - self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) + assert MappingGradChecker(mapping, X).checkgrad() def test_linearmapping(self): mapping = GPy.mappings.Linear(3, 2) X = np.random.randn(100, 3) - self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) + assert MappingGradChecker(mapping, X).checkgrad() def test_mlpmapping(self): mapping = GPy.mappings.MLP(input_dim=3, hidden_dim=5, output_dim=2) X = np.random.randn(100, 3) - self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) + assert MappingGradChecker(mapping, X).checkgrad() def test_mlpextmapping(self): np.random.seed(42) @@ -54,14 +54,14 @@ class MappingTests(unittest.TestCase): mapping = GPy.mappings.MLPext( input_dim=3, hidden_dims=[5, 5], output_dim=2, activation=activation ) - self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) + assert MappingGradChecker(mapping, X).checkgrad() def test_addmapping(self): m1 = GPy.mappings.MLP(input_dim=3, hidden_dim=5, output_dim=2) m2 = GPy.mappings.Linear(input_dim=3, output_dim=2) mapping = GPy.mappings.Additive(m1, m2) X = np.random.randn(100, 3) - self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) + assert MappingGradChecker(mapping, X).checkgrad() def test_compoundmapping(self): m1 = GPy.mappings.MLP(input_dim=3, hidden_dim=5, output_dim=2) @@ -69,9 +69,4 @@ class MappingTests(unittest.TestCase): m2 = GPy.mappings.Kernel(2, 4, Z, GPy.kern.RBF(2)) mapping = GPy.mappings.Compound(m1, m2) X = np.random.randn(100, 3) - self.assertTrue(MappingGradChecker(mapping, X).checkgrad()) - - -if __name__ == "__main__": - print("Running unit tests, please be (very) patient...") - unittest.main() + assert MappingGradChecker(mapping, X).checkgrad() From 3935b7203eb7654cdea1d424307d84d77737f823 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Fri, 6 Oct 2023 18:59:10 +0200 Subject: [PATCH 029/101] format on save --- GPy/testing/meanfunc_tests.py | 82 +++++++++++++++++------------------ 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/GPy/testing/meanfunc_tests.py b/GPy/testing/meanfunc_tests.py index 53482a7a..40064dff 100644 --- a/GPy/testing/meanfunc_tests.py +++ b/GPy/testing/meanfunc_tests.py @@ -5,91 +5,87 @@ import unittest import numpy as np import GPy + class MFtests(unittest.TestCase): def test_simple_mean_function(self): """ The simplest possible mean function. No parameters, just a simple Sinusoid. """ - #create simple mean function - mf = GPy.core.Mapping(1,1) + # create simple mean function + mf = GPy.core.Mapping(1, 1) mf.f = np.sin - mf.update_gradients = lambda a,b: None + mf.update_gradients = lambda a, b: None - X = np.linspace(0,10,50).reshape(-1,1) - Y = np.sin(X) + 0.5*np.cos(3*X) + 0.1*np.random.randn(*X.shape) + X = np.linspace(0, 10, 50).reshape(-1, 1) + Y = np.sin(X) + 0.5 * np.cos(3 * X) + 0.1 * np.random.randn(*X.shape) - k =GPy.kern.RBF(1) + k = GPy.kern.RBF(1) lik = GPy.likelihoods.Gaussian() m = GPy.core.GP(X, Y, kernel=k, likelihood=lik, mean_function=mf) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_parametric_mean_function(self): """ A linear mean function with parameters that we'll learn alongside the kernel """ - X = np.linspace(-1,10,50).reshape(-1,1) - - Y = 3-np.abs((X-6)) - Y += .5*np.cos(3*X) + 0.3*np.random.randn(*X.shape) + X = np.linspace(-1, 10, 50).reshape(-1, 1) - mf = GPy.mappings.PiecewiseLinear(1, 1, [-1,1], [9,2]) + Y = 3 - np.abs((X - 6)) + Y += 0.5 * np.cos(3 * X) + 0.3 * np.random.randn(*X.shape) - k =GPy.kern.RBF(1) + mf = GPy.mappings.PiecewiseLinear(1, 1, [-1, 1], [9, 2]) + + k = GPy.kern.RBF(1) lik = GPy.likelihoods.Gaussian() m = GPy.core.GP(X, Y, kernel=k, likelihood=lik, mean_function=mf) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_parametric_mean_function_composition(self): """ A linear mean function with parameters that we'll learn alongside the kernel """ - X = np.linspace(0,10,50).reshape(-1,1) - Y = np.sin(X) + 0.5*np.cos(3*X) + 0.1*np.random.randn(*X.shape) + 3*X + X = np.linspace(0, 10, 50).reshape(-1, 1) + Y = np.sin(X) + 0.5 * np.cos(3 * X) + 0.1 * np.random.randn(*X.shape) + 3 * X - mf = GPy.mappings.Compound(GPy.mappings.Linear(1,1), - GPy.mappings.Kernel(1, 1, np.random.normal(0,1,(1,1)), - GPy.kern.RBF(1)) - ) + mf = GPy.mappings.Compound( + GPy.mappings.Linear(1, 1), + GPy.mappings.Kernel(1, 1, np.random.normal(0, 1, (1, 1)), GPy.kern.RBF(1)), + ) - k =GPy.kern.RBF(1) + k = GPy.kern.RBF(1) lik = GPy.likelihoods.Gaussian() m = GPy.core.GP(X, Y, kernel=k, likelihood=lik, mean_function=mf) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_parametric_mean_function_additive(self): """ A linear mean function with parameters that we'll learn alongside the kernel """ - X = np.linspace(0,10,50).reshape(-1,1) - Y = np.sin(X) + 0.5*np.cos(3*X) + 0.1*np.random.randn(*X.shape) + 3*X + X = np.linspace(0, 10, 50).reshape(-1, 1) + Y = np.sin(X) + 0.5 * np.cos(3 * X) + 0.1 * np.random.randn(*X.shape) + 3 * X - mf = GPy.mappings.Additive(GPy.mappings.Constant(1,1,3), - GPy.mappings.Additive(GPy.mappings.MLP(1,1), - GPy.mappings.Identity(1,1) - ) - ) + mf = GPy.mappings.Additive( + GPy.mappings.Constant(1, 1, 3), + GPy.mappings.Additive(GPy.mappings.MLP(1, 1), GPy.mappings.Identity(1, 1)), + ) - k =GPy.kern.RBF(1) + k = GPy.kern.RBF(1) lik = GPy.likelihoods.Gaussian() m = GPy.core.GP(X, Y, kernel=k, likelihood=lik, mean_function=mf) - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_svgp_mean_function(self): - # an instance of the SVIGOP with a men function - X = np.linspace(0,10,500).reshape(-1,1) - Y = np.sin(X) + 0.5*np.cos(3*X) + 0.1*np.random.randn(*X.shape) - Y = np.where(Y>0, 1,0) # make aclassificatino problem + X = np.linspace(0, 10, 500).reshape(-1, 1) + Y = np.sin(X) + 0.5 * np.cos(3 * X) + 0.1 * np.random.randn(*X.shape) + Y = np.where(Y > 0, 1, 0) # make aclassificatino problem - mf = GPy.mappings.Linear(1,1) - Z = np.linspace(0,10,50).reshape(-1,1) + mf = GPy.mappings.Linear(1, 1) + Z = np.linspace(0, 10, 50).reshape(-1, 1) lik = GPy.likelihoods.Bernoulli() - k =GPy.kern.RBF(1) + GPy.kern.White(1, 1e-4) - m = GPy.core.SVGP(X, Y,Z=Z, kernel=k, likelihood=lik, mean_function=mf) - self.assertTrue(m.checkgrad()) - - - + k = GPy.kern.RBF(1) + GPy.kern.White(1, 1e-4) + m = GPy.core.SVGP(X, Y, Z=Z, kernel=k, likelihood=lik, mean_function=mf) + assert m.checkgrad() From 4d66d8b34fca68e44c7e710569358063dae74c8e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Sun, 8 Oct 2023 23:29:01 +0200 Subject: [PATCH 030/101] migrate meanfunc_test to pytest --- GPy/testing/meanfunc_tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/GPy/testing/meanfunc_tests.py b/GPy/testing/meanfunc_tests.py index 40064dff..d4ec2d98 100644 --- a/GPy/testing/meanfunc_tests.py +++ b/GPy/testing/meanfunc_tests.py @@ -1,12 +1,11 @@ # Copyright (c) 2015, James Hensman # Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest import numpy as np import GPy -class MFtests(unittest.TestCase): +class TestMF: def test_simple_mean_function(self): """ The simplest possible mean function. No parameters, just a simple Sinusoid. From 4070fd68ff6c5aa76832e09524b2f003968cca02 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Sun, 8 Oct 2023 23:29:28 +0200 Subject: [PATCH 031/101] format on save --- GPy/testing/minibatch_tests.py | 360 ++++++++++++++++++++++++--------- 1 file changed, 265 insertions(+), 95 deletions(-) diff --git a/GPy/testing/minibatch_tests.py b/GPy/testing/minibatch_tests.py index 09bcc1dc..88db1669 100644 --- a/GPy/testing/minibatch_tests.py +++ b/GPy/testing/minibatch_tests.py @@ -1,37 +1,48 @@ -''' +""" Created on 4 Sep 2015 @author: maxz -''' +""" import unittest import numpy as np import GPy + class BGPLVMTest(unittest.TestCase): - - def setUp(self): np.random.seed(12345) - X, W = np.random.normal(0,1,(100,6)), np.random.normal(0,1,(6,13)) - Y = X.dot(W) + np.random.normal(0, .1, (X.shape[0], W.shape[1])) - self.inan = np.random.binomial(1, .1, Y.shape).astype(bool) - self.X, self.W, self.Y = X,W,Y + X, W = np.random.normal(0, 1, (100, 6)), np.random.normal(0, 1, (6, 13)) + Y = X.dot(W) + np.random.normal(0, 0.1, (X.shape[0], W.shape[1])) + self.inan = np.random.binomial(1, 0.1, Y.shape).astype(bool) + self.X, self.W, self.Y = X, W, Y self.Q = 3 self.m_full = GPy.models.BayesianGPLVM(Y, self.Q) def test_lik_comparisons_m1_s0(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=False) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, missing_data=True, stochastic=False + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_predict_missing_data(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + missing_data=True, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) self.assertRaises(NotImplementedError, m.predict, m.X, full_cov=True) @@ -44,85 +55,136 @@ class BGPLVMTest(unittest.TestCase): mu1, var1 = m.predict(m.X.mean, full_cov=True) mu2, var2 = self.m_full.predict(self.m_full.X.mean, full_cov=True) np.testing.assert_allclose(mu1, mu2) - np.testing.assert_allclose(var1[:,:,0], var2) + np.testing.assert_allclose(var1[:, :, 0], var2) mu1, var1 = m.predict(m.X.mean, full_cov=False) mu2, var2 = self.m_full.predict(self.m_full.X.mean, full_cov=False) np.testing.assert_allclose(mu1, mu2) - np.testing.assert_allclose(var1[:,[0]], var2) + np.testing.assert_allclose(var1[:, [0]], var2) def test_lik_comparisons_m0_s0(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=self.m_full.X.variance.values, missing_data=False, stochastic=False) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=self.m_full.X.variance.values, + missing_data=False, + stochastic=False, + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_lik_comparisons_m1_s1(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + missing_data=True, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_lik_comparisons_m0_s1(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=False, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + missing_data=False, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_gradients_missingdata(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=False, batchsize=self.Y.shape[1]) - assert(m.checkgrad()) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + missing_data=True, + stochastic=False, + batchsize=self.Y.shape[1], + ) + assert m.checkgrad() def test_gradients_missingdata_stochastics(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=True, batchsize=1) - assert(m.checkgrad()) - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=True, batchsize=4) - assert(m.checkgrad()) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, missing_data=True, stochastic=True, batchsize=1 + ) + assert m.checkgrad() + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, missing_data=True, stochastic=True, batchsize=4 + ) + assert m.checkgrad() def test_gradients_stochastics(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=False, stochastic=True, batchsize=1) - assert(m.checkgrad()) - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=False, stochastic=True, batchsize=4) - assert(m.checkgrad()) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, missing_data=False, stochastic=True, batchsize=1 + ) + assert m.checkgrad() + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, missing_data=False, stochastic=True, batchsize=4 + ) + assert m.checkgrad() def test_predict(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, missing_data=True, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + missing_data=True, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() + class SparseGPMinibatchTest(unittest.TestCase): - - def setUp(self): np.random.seed(12345) - X, W = np.random.normal(0,1,(100,6)), np.random.normal(0,1,(6,13)) - Y = X.dot(W) + np.random.normal(0, .1, (X.shape[0], W.shape[1])) - self.inan = np.random.binomial(1, .1, Y.shape).astype(bool) - self.X, self.W, self.Y = X,W,Y + X, W = np.random.normal(0, 1, (100, 6)), np.random.normal(0, 1, (6, 13)) + Y = X.dot(W) + np.random.normal(0, 0.1, (X.shape[0], W.shape[1])) + self.inan = np.random.binomial(1, 0.1, Y.shape).astype(bool) + self.X, self.W, self.Y = X, W, Y self.Q = 3 - self.m_full = GPy.models.SparseGPLVM(Y, self.Q, kernel=GPy.kern.RBF(self.Q, ARD=True)) + self.m_full = GPy.models.SparseGPLVM( + Y, self.Q, kernel=GPy.kern.RBF(self.Q, ARD=True) + ) def test_lik_comparisons_m1_s0(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=False) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, X_variance=False, missing_data=True, stochastic=False + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_sparsegp_init(self): # Test if the different implementations give the exact same likelihood as the full model. @@ -131,100 +193,208 @@ class SparseGPMinibatchTest(unittest.TestCase): np.random.seed(1234) Z = self.X[np.random.choice(self.X.shape[0], replace=False, size=10)].copy() Q = Z.shape[1] - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch(self.X, self.Y, Z, GPy.kern.RBF(Q)+GPy.kern.Matern32(Q)+GPy.kern.Bias(Q), GPy.likelihoods.Gaussian(), missing_data=True, stochastic=False) - assert(m.checkgrad()) - m.optimize('adadelta', max_iters=10) - assert(m.checkgrad()) - - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch(self.X, self.Y, Z, GPy.kern.RBF(Q)+GPy.kern.Matern32(Q)+GPy.kern.Bias(Q), GPy.likelihoods.Gaussian(), missing_data=True, stochastic=True) - assert(m.checkgrad()) - m.optimize('rprop', max_iters=10) - assert(m.checkgrad()) - - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch(self.X, self.Y, Z, GPy.kern.RBF(Q)+GPy.kern.Matern32(Q)+GPy.kern.Bias(Q), GPy.likelihoods.Gaussian(), missing_data=False, stochastic=False) - assert(m.checkgrad()) - m.optimize('rprop', max_iters=10) - assert(m.checkgrad()) - - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch(self.X, self.Y, Z, GPy.kern.RBF(Q)+GPy.kern.Matern32(Q)+GPy.kern.Bias(Q), GPy.likelihoods.Gaussian(), missing_data=False, stochastic=True) - assert(m.checkgrad()) - m.optimize('adadelta', max_iters=10) - assert(m.checkgrad()) + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=True, + stochastic=False, + ) + assert m.checkgrad() + m.optimize("adadelta", max_iters=10) + assert m.checkgrad() + + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=True, + stochastic=True, + ) + assert m.checkgrad() + m.optimize("rprop", max_iters=10) + assert m.checkgrad() + + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=False, + stochastic=False, + ) + assert m.checkgrad() + m.optimize("rprop", max_iters=10) + assert m.checkgrad() + + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=False, + stochastic=True, + ) + assert m.checkgrad() + m.optimize("adadelta", max_iters=10) + assert m.checkgrad() except ImportError: from nose import SkipTest - raise SkipTest('climin not installed, skipping stochastic gradients') + + raise SkipTest("climin not installed, skipping stochastic gradients") def test_predict_missing_data(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=True, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) mu1, var1 = m.predict(m.X, full_cov=False) mu2, var2 = self.m_full.predict(self.m_full.X, full_cov=False) np.testing.assert_allclose(mu1, mu2) for i in range(var1.shape[1]): - np.testing.assert_allclose(var1[:,[i]], var2) + np.testing.assert_allclose(var1[:, [i]], var2) mu1, var1 = m.predict(m.X, full_cov=True) mu2, var2 = self.m_full.predict(self.m_full.X, full_cov=True) np.testing.assert_allclose(mu1, mu2) for i in range(var1.shape[2]): - np.testing.assert_allclose(var1[:,:,i], var2) - + np.testing.assert_allclose(var1[:, :, i], var2) + def test_lik_comparisons_m0_s0(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=False, stochastic=False) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, self.Q, X_variance=False, missing_data=False, stochastic=False + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_lik_comparisons_m1_s1(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=True, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_lik_comparisons_m0_s1(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=False, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=False, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() def test_gradients_missingdata(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=False, batchsize=self.Y.shape[1]) - assert(m.checkgrad()) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=True, + stochastic=False, + batchsize=self.Y.shape[1], + ) + assert m.checkgrad() def test_gradients_missingdata_stochastics(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=True, batchsize=1) - assert(m.checkgrad()) - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=True, batchsize=4) - assert(m.checkgrad()) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=True, + stochastic=True, + batchsize=1, + ) + assert m.checkgrad() + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=True, + stochastic=True, + batchsize=4, + ) + assert m.checkgrad() def test_gradients_stochastics(self): - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=False, stochastic=True, batchsize=1) - assert(m.checkgrad()) - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=False, stochastic=True, batchsize=4) - assert(m.checkgrad()) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=False, + stochastic=True, + batchsize=1, + ) + assert m.checkgrad() + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=False, + stochastic=True, + batchsize=4, + ) + assert m.checkgrad() def test_predict(self): # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(self.Y, self.Q, X_variance=False, missing_data=True, stochastic=True, batchsize=self.Y.shape[1]) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + self.Y, + self.Q, + X_variance=False, + missing_data=True, + stochastic=True, + batchsize=self.Y.shape[1], + ) m[:] = self.m_full[:] - np.testing.assert_almost_equal(m.log_likelihood(), self.m_full.log_likelihood(), 7) + np.testing.assert_almost_equal( + m.log_likelihood(), self.m_full.log_likelihood(), 7 + ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - assert(m.checkgrad()) + assert m.checkgrad() if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.testName'] + # import sys;sys.argv = ['', 'Test.testName'] unittest.main() From 4685d10463903070ff9be1021c844305318802b4 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Sun, 8 Oct 2023 23:41:44 +0200 Subject: [PATCH 032/101] migrate minibatch_tests to pytest --- GPy/testing/minibatch_tests.py | 147 ++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 66 deletions(-) diff --git a/GPy/testing/minibatch_tests.py b/GPy/testing/minibatch_tests.py index 88db1669..96ab617f 100644 --- a/GPy/testing/minibatch_tests.py +++ b/GPy/testing/minibatch_tests.py @@ -3,13 +3,18 @@ Created on 4 Sep 2015 @author: maxz """ -import unittest +import pytest import numpy as np import GPy +try: + import climin +except ImportError: + climin = None -class BGPLVMTest(unittest.TestCase): - def setUp(self): + +class TestBGPLVM: + def setup(self): np.random.seed(12345) X, W = np.random.normal(0, 1, (100, 6)), np.random.normal(0, 1, (6, 13)) Y = X.dot(W) + np.random.normal(0, 0.1, (X.shape[0], W.shape[1])) @@ -19,6 +24,7 @@ class BGPLVMTest(unittest.TestCase): self.m_full = GPy.models.BayesianGPLVM(Y, self.Q) def test_lik_comparisons_m1_s0(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -32,6 +38,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_predict_missing_data(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, @@ -63,6 +70,7 @@ class BGPLVMTest(unittest.TestCase): np.testing.assert_allclose(var1[:, [0]], var2) def test_lik_comparisons_m0_s0(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -80,6 +88,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_lik_comparisons_m1_s1(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -97,6 +106,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_lik_comparisons_m0_s1(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -114,6 +124,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_gradients_missingdata(self): + self.seutp() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, @@ -124,6 +135,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_gradients_missingdata_stochastics(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, missing_data=True, stochastic=True, batchsize=1 ) @@ -134,6 +146,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_gradients_stochastics(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, missing_data=False, stochastic=True, batchsize=1 ) @@ -144,6 +157,7 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() def test_predict(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -161,8 +175,8 @@ class BGPLVMTest(unittest.TestCase): assert m.checkgrad() -class SparseGPMinibatchTest(unittest.TestCase): - def setUp(self): +class TestSparseGPMinibatch: + def setup(self): np.random.seed(12345) X, W = np.random.normal(0, 1, (100, 6)), np.random.normal(0, 1, (6, 13)) Y = X.dot(W) + np.random.normal(0, 0.1, (X.shape[0], W.shape[1])) @@ -174,6 +188,7 @@ class SparseGPMinibatchTest(unittest.TestCase): ) def test_lik_comparisons_m1_s0(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -186,70 +201,68 @@ class SparseGPMinibatchTest(unittest.TestCase): np.testing.assert_allclose(m.gradient, self.m_full.gradient) assert m.checkgrad() + @pytest.mark.skipif(climin is None, reason="climin not installed") def test_sparsegp_init(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: - try: - np.random.seed(1234) - Z = self.X[np.random.choice(self.X.shape[0], replace=False, size=10)].copy() - Q = Z.shape[1] - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( - self.X, - self.Y, - Z, - GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), - GPy.likelihoods.Gaussian(), - missing_data=True, - stochastic=False, - ) - assert m.checkgrad() - m.optimize("adadelta", max_iters=10) - assert m.checkgrad() + np.random.seed(1234) + Z = self.X[np.random.choice(self.X.shape[0], replace=False, size=10)].copy() + Q = Z.shape[1] + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=True, + stochastic=False, + ) + assert m.checkgrad() + m.optimize("adadelta", max_iters=10) + assert m.checkgrad() - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( - self.X, - self.Y, - Z, - GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), - GPy.likelihoods.Gaussian(), - missing_data=True, - stochastic=True, - ) - assert m.checkgrad() - m.optimize("rprop", max_iters=10) - assert m.checkgrad() + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=True, + stochastic=True, + ) + assert m.checkgrad() + m.optimize("rprop", max_iters=10) + assert m.checkgrad() - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( - self.X, - self.Y, - Z, - GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), - GPy.likelihoods.Gaussian(), - missing_data=False, - stochastic=False, - ) - assert m.checkgrad() - m.optimize("rprop", max_iters=10) - assert m.checkgrad() + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=False, + stochastic=False, + ) + assert m.checkgrad() + m.optimize("rprop", max_iters=10) + assert m.checkgrad() - m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( - self.X, - self.Y, - Z, - GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), - GPy.likelihoods.Gaussian(), - missing_data=False, - stochastic=True, - ) - assert m.checkgrad() - m.optimize("adadelta", max_iters=10) - assert m.checkgrad() - except ImportError: - from nose import SkipTest - - raise SkipTest("climin not installed, skipping stochastic gradients") + m = GPy.models.sparse_gp_minibatch.SparseGPMiniBatch( + self.X, + self.Y, + Z, + GPy.kern.RBF(Q) + GPy.kern.Matern32(Q) + GPy.kern.Bias(Q), + GPy.likelihoods.Gaussian(), + missing_data=False, + stochastic=True, + ) + assert m.checkgrad() + m.optimize("adadelta", max_iters=10) + assert m.checkgrad() def test_predict_missing_data(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, @@ -277,6 +290,7 @@ class SparseGPMinibatchTest(unittest.TestCase): np.testing.assert_allclose(var1[:, :, i], var2) def test_lik_comparisons_m0_s0(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -290,6 +304,7 @@ class SparseGPMinibatchTest(unittest.TestCase): assert m.checkgrad() def test_lik_comparisons_m1_s1(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -308,6 +323,7 @@ class SparseGPMinibatchTest(unittest.TestCase): assert m.checkgrad() def test_lik_comparisons_m0_s1(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -326,6 +342,7 @@ class SparseGPMinibatchTest(unittest.TestCase): assert m.checkgrad() def test_gradients_missingdata(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, @@ -337,6 +354,7 @@ class SparseGPMinibatchTest(unittest.TestCase): assert m.checkgrad() def test_gradients_missingdata_stochastics(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, @@ -357,6 +375,7 @@ class SparseGPMinibatchTest(unittest.TestCase): assert m.checkgrad() def test_gradients_stochastics(self): + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, @@ -377,6 +396,7 @@ class SparseGPMinibatchTest(unittest.TestCase): assert m.checkgrad() def test_predict(self): + self.setup() # Test if the different implementations give the exact same likelihood as the full model. # All of the following settings should give the same likelihood and gradients as the full model: m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( @@ -393,8 +413,3 @@ class SparseGPMinibatchTest(unittest.TestCase): ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) assert m.checkgrad() - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.testName'] - unittest.main() From 3695763a5dd332cc7975a17828673fd730ffcab0 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Sun, 8 Oct 2023 23:42:10 +0200 Subject: [PATCH 033/101] format on save --- GPy/testing/misc_tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GPy/testing/misc_tests.py b/GPy/testing/misc_tests.py index 8f418565..628b688d 100644 --- a/GPy/testing/misc_tests.py +++ b/GPy/testing/misc_tests.py @@ -4,24 +4,26 @@ import scipy as sp import GPy import warnings + class MiscTests(np.testing.TestCase): """ Testing some utilities of misc """ + def setUp(self): self._lim_val = np.finfo(np.float64).max self._lim_val_exp = np.log(self._lim_val) def test_safe_exp_upper(self): with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') # always print + warnings.simplefilter("always") # always print assert np.isfinite(np.exp(self._lim_val_exp)) assert np.isinf(np.exp(self._lim_val_exp + 1)) assert np.isfinite(GPy.util.misc.safe_exp(self._lim_val_exp + 1)) print(w) print(len(w)) - assert len(w)<=1 # should have one overflow warning + assert len(w) <= 1 # should have one overflow warning def test_safe_exp_lower(self): assert GPy.util.misc.safe_exp(1e-10) < np.inf From f95fff1f783538887c9ad3f531e4a7228cf9af1c Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Sun, 8 Oct 2023 23:43:26 +0200 Subject: [PATCH 034/101] migrate misc_tests to pytest --- GPy/testing/misc_tests.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/GPy/testing/misc_tests.py b/GPy/testing/misc_tests.py index 628b688d..74a6a896 100644 --- a/GPy/testing/misc_tests.py +++ b/GPy/testing/misc_tests.py @@ -1,20 +1,19 @@ -from __future__ import print_function import numpy as np -import scipy as sp import GPy import warnings -class MiscTests(np.testing.TestCase): +class TestMisc: """ Testing some utilities of misc """ - def setUp(self): + def setup(self): self._lim_val = np.finfo(np.float64).max self._lim_val_exp = np.log(self._lim_val) def test_safe_exp_upper(self): + self.setup() with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # always print assert np.isfinite(np.exp(self._lim_val_exp)) From 6e497b71ee60c97770c2ad52608fa65a8290206d Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Sun, 8 Oct 2023 23:43:55 +0200 Subject: [PATCH 035/101] format on save --- GPy/testing/model_tests.py | 1072 ++++++++++++++++++++++-------------- 1 file changed, 653 insertions(+), 419 deletions(-) diff --git a/GPy/testing/model_tests.py b/GPy/testing/model_tests.py index bc2005be..a5001a7f 100644 --- a/GPy/testing/model_tests.py +++ b/GPy/testing/model_tests.py @@ -8,20 +8,24 @@ import GPy from GPy.models import GradientChecker from functools import reduce + class MiscTests(unittest.TestCase): def setUp(self): self.N = 20 self.N_new = 50 self.D = 1 - self.X = np.random.uniform(-3., 3., (self.N, 1)) + self.X = np.random.uniform(-3.0, 3.0, (self.N, 1)) self.Y = np.sin(self.X) + np.random.randn(self.N, self.D) * 0.05 - self.X_new = np.random.uniform(-3., 3., (self.N_new, 1)) + self.X_new = np.random.uniform(-3.0, 3.0, (self.N_new, 1)) def test_setXY(self): m = GPy.models.GPRegression(self.X, self.Y) - m.set_XY(np.vstack([self.X, np.random.rand(1,self.X.shape[1])]), np.vstack([self.Y, np.random.rand(1,self.Y.shape[1])])) + m.set_XY( + np.vstack([self.X, np.random.rand(1, self.X.shape[1])]), + np.vstack([self.Y, np.random.rand(1, self.Y.shape[1])]), + ) m._trigger_params_changed() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() m.predict(m.X) def test_raw_predict_numerical_stability(self): @@ -32,43 +36,52 @@ class MiscTests(unittest.TestCase): # set seed for reproducability np.random.seed(3) + # Definition of the Branin test function def branin(X): - y = (X[:,1]-5.1/(4*np.pi**2)*X[:,0]**2+5*X[:,0]/np.pi-6)**2 - y += 10*(1-1/(8*np.pi))*np.cos(X[:,0])+10 - return(y) + y = ( + X[:, 1] + - 5.1 / (4 * np.pi**2) * X[:, 0] ** 2 + + 5 * X[:, 0] / np.pi + - 6 + ) ** 2 + y += 10 * (1 - 1 / (8 * np.pi)) * np.cos(X[:, 0]) + 10 + return y + # Training set defined as a 5*5 grid: - xg1 = np.linspace(-5,10,5) - xg2 = np.linspace(0,15,5) - X = np.zeros((xg1.size * xg2.size,2)) - for i,x1 in enumerate(xg1): - for j,x2 in enumerate(xg2): - X[i+xg1.size*j,:] = [x1,x2] - Y = branin(X)[:,None] + xg1 = np.linspace(-5, 10, 5) + xg2 = np.linspace(0, 15, 5) + X = np.zeros((xg1.size * xg2.size, 2)) + for i, x1 in enumerate(xg1): + for j, x2 in enumerate(xg2): + X[i + xg1.size * j, :] = [x1, x2] + Y = branin(X)[:, None] # Fit a GP # Create an exponentiated quadratic plus bias covariance function - k = GPy.kern.RBF(input_dim=2, ARD = True) + k = GPy.kern.RBF(input_dim=2, ARD=True) # Build a GP model - m = GPy.models.GPRegression(X,Y,k) + m = GPy.models.GPRegression(X, Y, k) # fix the noise variance m.likelihood.variance.fix(1e-5) # Randomize the model and optimize m.randomize() m.optimize() # Compute the mean of model prediction on 1e5 Monte Carlo samples - Xp = np.random.uniform(size=(int(1e5),2)) - Xp[:,0] = Xp[:,0]*15-5 - Xp[:,1] = Xp[:,1]*15 + Xp = np.random.uniform(size=(int(1e5), 2)) + Xp[:, 0] = Xp[:, 0] * 15 - 5 + Xp[:, 1] = Xp[:, 1] * 15 _, var = m.predict(Xp) - self.assertTrue(np.all(var>=0.)) + self.assertTrue(np.all(var >= 0.0)) def test_raw_predict(self): k = GPy.kern.RBF(1) m = GPy.models.GPRegression(self.X, self.Y, kernel=k) m.randomize() - m.likelihood.variance = .5 + m.likelihood.variance = 0.5 Kinv = np.linalg.pinv(k.K(self.X) + np.eye(self.N) * m.likelihood.variance) - K_hat = k.K(self.X_new) - k.K(self.X_new, self.X).dot(Kinv).dot(k.K(self.X, self.X_new)) + K_hat = k.K(self.X_new) - k.K(self.X_new, self.X).dot(Kinv).dot( + k.K(self.X, self.X_new) + ) mu_hat = k.K(self.X_new, self.X).dot(Kinv).dot(m.Y_normalized) mu, covar = m.predict_noiseless(self.X_new, full_cov=True) @@ -89,26 +102,26 @@ class MiscTests(unittest.TestCase): mu, std = Y.mean(0), Y.std(0) m = GPy.models.GPRegression(self.X, Y, kernel=k, normalizer=True) m.optimize(messages=True) - assert(m.checkgrad()) + assert m.checkgrad() k = GPy.kern.RBF(1) - m2 = GPy.models.GPRegression(self.X, (Y-mu)/std, kernel=k, normalizer=False) + m2 = GPy.models.GPRegression(self.X, (Y - mu) / std, kernel=k, normalizer=False) m2[:] = m[:] mu1, var1 = m.predict(m.X, full_cov=True) mu2, var2 = m2.predict(m2.X, full_cov=True) - np.testing.assert_allclose(mu1, (mu2*std)+mu) - np.testing.assert_allclose(var1, var2*std**2) + np.testing.assert_allclose(mu1, (mu2 * std) + mu) + np.testing.assert_allclose(var1, var2 * std**2) mu1, var1 = m.predict(m.X, full_cov=False) mu2, var2 = m2.predict(m2.X, full_cov=False) - np.testing.assert_allclose(mu1, (mu2*std)+mu) - np.testing.assert_allclose(var1, var2*std**2) + np.testing.assert_allclose(mu1, (mu2 * std) + mu) + np.testing.assert_allclose(var1, var2 * std**2) q50n = m.predict_quantiles(m.X, (50,)) q50 = m2.predict_quantiles(m2.X, (50,)) - np.testing.assert_allclose(q50n[0], (q50[0]*std)+mu) + np.testing.assert_allclose(q50n[0], (q50[0] * std) + mu) # Test variance component: qs = np.array([2.5, 97.5]) @@ -118,7 +131,11 @@ class MiscTests(unittest.TestCase): q95 = m2.predict_quantiles(self.X[[c]], qs) mu, var = m2.predict(self.X[[c]]) from scipy.stats import norm - np.testing.assert_allclose((mu+(norm.ppf(qs/100.)*np.sqrt(var))).flatten(), np.array(q95).flatten()) + + np.testing.assert_allclose( + (mu + (norm.ppf(qs / 100.0) * np.sqrt(var))).flatten(), + np.array(q95).flatten(), + ) def test_multioutput_regression_with_normalizer(self): """ @@ -134,26 +151,26 @@ class MiscTests(unittest.TestCase): mu, std = Y.mean(0), Y.std(0) m = GPy.models.GPRegression(X, Y, normalizer=True) m.optimize(messages=True) - assert(m.checkgrad()) + assert m.checkgrad() k = GPy.kern.RBF(1) - m2 = GPy.models.GPRegression(X, (Y-mu)/std, normalizer=False) + m2 = GPy.models.GPRegression(X, (Y - mu) / std, normalizer=False) m2[:] = m[:] mu1, var1 = m.predict(m.X, full_cov=True) mu2, var2 = m2.predict(m2.X, full_cov=True) - np.testing.assert_allclose(mu1, (mu2*std)+mu) - np.testing.assert_allclose(var1, var2[:, :, None]*std[None, None, :]**2) + np.testing.assert_allclose(mu1, (mu2 * std) + mu) + np.testing.assert_allclose(var1, var2[:, :, None] * std[None, None, :] ** 2) mu1, var1 = m.predict(m.X, full_cov=False) mu2, var2 = m2.predict(m2.X, full_cov=False) - np.testing.assert_allclose(mu1, (mu2*std)+mu) - np.testing.assert_allclose(var1, var2*std[None, :]**2) + np.testing.assert_allclose(mu1, (mu2 * std) + mu) + np.testing.assert_allclose(var1, var2 * std[None, :] ** 2) q50n = m.predict_quantiles(m.X, (50,)) q50 = m2.predict_quantiles(m2.X, (50,)) - np.testing.assert_allclose(q50n[0], (q50[0]*std)+mu) + np.testing.assert_allclose(q50n[0], (q50[0] * std) + mu) # Test variance component: qs = np.array([2.5, 97.5]) @@ -163,7 +180,11 @@ class MiscTests(unittest.TestCase): q95 = m2.predict_quantiles(X[[c]], qs) mu, var = m2.predict(X[[c]]) from scipy.stats import norm - np.testing.assert_allclose((mu.T+(norm.ppf(qs/100.)*np.sqrt(var))).T.flatten(), np.array(q95).flatten()) + + np.testing.assert_allclose( + (mu.T + (norm.ppf(qs / 100.0) * np.sqrt(var))).T.flatten(), + np.array(q95).flatten(), + ) def check_jacobian(self): try: @@ -171,49 +192,61 @@ class MiscTests(unittest.TestCase): from GPy.models import GradientChecker, GPRegression except: raise self.skipTest("autograd not available to check gradients") - def k(X, X2, alpha=1., lengthscale=None): + + def k(X, X2, alpha=1.0, lengthscale=None): if lengthscale is None: lengthscale = np.ones(X.shape[1]) - exp = 0. + exp = 0.0 for q in range(X.shape[1]): - exp += ((X[:, [q]] - X2[:, [q]].T)/lengthscale[q])**2 - #exp = np.sqrt(exp) - return alpha * np.exp(-.5*exp) - dk = ag.elementwise_grad(lambda x, x2: k(x, x2, alpha=ke.variance.values, lengthscale=ke.lengthscale.values)) + exp += ((X[:, [q]] - X2[:, [q]].T) / lengthscale[q]) ** 2 + # exp = np.sqrt(exp) + return alpha * np.exp(-0.5 * exp) + + dk = ag.elementwise_grad( + lambda x, x2: k( + x, x2, alpha=ke.variance.values, lengthscale=ke.lengthscale.values + ) + ) dkdk = ag.elementwise_grad(dk, argnum=1) ke = GPy.kern.RBF(1, ARD=True) - #ke.randomize() - ke.variance = .2#.randomize() - ke.lengthscale[:] = .5 + # ke.randomize() + ke.variance = 0.2 # .randomize() + ke.lengthscale[:] = 0.5 ke.randomize() - X = np.linspace(-1, 1, 1000)[:,None] - X2 = np.array([[0.]]).T - np.testing.assert_allclose(ke.gradients_X([[1.]], X, X), dk(X, X)) - np.testing.assert_allclose(ke.gradients_XX([[1.]], X, X).sum(0), dkdk(X, X)) - np.testing.assert_allclose(ke.gradients_X([[1.]], X, X2), dk(X, X2)) - np.testing.assert_allclose(ke.gradients_XX([[1.]], X, X2).sum(0), dkdk(X, X2)) + X = np.linspace(-1, 1, 1000)[:, None] + X2 = np.array([[0.0]]).T + np.testing.assert_allclose(ke.gradients_X([[1.0]], X, X), dk(X, X)) + np.testing.assert_allclose(ke.gradients_XX([[1.0]], X, X).sum(0), dkdk(X, X)) + np.testing.assert_allclose(ke.gradients_X([[1.0]], X, X2), dk(X, X2)) + np.testing.assert_allclose(ke.gradients_XX([[1.0]], X, X2).sum(0), dkdk(X, X2)) m = GPRegression(self.X, self.Y) + def f(x): m.X[:] = x return m.log_likelihood() + def df(x): m.X[:] = x - return m.kern.gradients_X(m.grad_dict['dL_dK'], X) + return m.kern.gradients_X(m.grad_dict["dL_dK"], X) + def ddf(x): m.X[:] = x - return m.kern.gradients_XX(m.grad_dict['dL_dK'], X).sum(0) + return m.kern.gradients_XX(m.grad_dict["dL_dK"], X).sum(0) + gc = GradientChecker(f, df, self.X) gc2 = GradientChecker(df, ddf, self.X) - assert(gc.checkgrad()) - assert(gc2.checkgrad()) + assert gc.checkgrad() + assert gc2.checkgrad() def test_predict_uncertain_inputs(self): - """ Projection of Gaussian through a linear function is still gaussian, and moments are analytical to compute, so we can check this case for predictions easily """ - X = np.linspace(-5,5, 10)[:, None] - Y = 2*X + np.random.randn(*X.shape)*1e-3 - m = GPy.models.BayesianGPLVM(Y, 1, X=X, kernel=GPy.kern.Linear(1), num_inducing=1) + """Projection of Gaussian through a linear function is still gaussian, and moments are analytical to compute, so we can check this case for predictions easily""" + X = np.linspace(-5, 5, 10)[:, None] + Y = 2 * X + np.random.randn(*X.shape) * 1e-3 + m = GPy.models.BayesianGPLVM( + Y, 1, X=X, kernel=GPy.kern.Linear(1), num_inducing=1 + ) m.Gaussian_noise[:] = 1e-4 m.X.mean[:] = X[:] m.X.variance[:] = 1e-5 @@ -222,11 +255,12 @@ class MiscTests(unittest.TestCase): X_pred_mu = np.random.randn(5, 1) X_pred_var = np.random.rand(5, 1) + 1e-5 from GPy.core.parameterization.variational import NormalPosterior + X_pred = NormalPosterior(X_pred_mu, X_pred_var) # mu = \int f(x)q(x|mu,S) dx = \int 2x.q(x|mu,S) dx = 2.mu # S = \int (f(x) - m)^2q(x|mu,S) dx = \int f(x)^2 q(x) dx - mu**2 = 4(mu^2 + S) - (2.mu)^2 = 4S - Y_mu_true = 2*X_pred_mu - Y_var_true = 4*X_pred_var + Y_mu_true = 2 * X_pred_mu + Y_var_true = 4 * X_pred_var Y_mu_pred, Y_var_pred = m.predict_noiseless(X_pred) np.testing.assert_allclose(Y_mu_true, Y_mu_pred, rtol=1e-3) np.testing.assert_allclose(Y_var_true, Y_var_pred, rtol=1e-3) @@ -259,16 +293,16 @@ class MiscTests(unittest.TestCase): m2 = GPy.models.GPRegression(self.X, self.Y) np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) m.randomize() - m2[:] = m[''].values() + m2[:] = m[""].values() np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.randomize() - m2[''] = m[:] + m2[""] = m[:] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.randomize() m2[:] = m[:] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.randomize() - m2[''] = m[''] + m2[""] = m[""] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.lengthscale.randomize() @@ -279,11 +313,10 @@ class MiscTests(unittest.TestCase): m2[:] = m[:] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) - m['.*var'] = 2 - m2['.*var'] = m['.*var'] + m[".*var"] = 2 + m2[".*var"] = m[".*var"] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) - def test_likelihood_set(self): m = GPy.models.GPRegression(self.X, self.Y) m2 = GPy.models.GPRegression(self.X, self.Y) @@ -294,28 +327,30 @@ class MiscTests(unittest.TestCase): np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.lengthscale.randomize() - m2['.*lengthscale'] = m.kern.lengthscale + m2[".*lengthscale"] = m.kern.lengthscale np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.lengthscale.randomize() - m2['.*lengthscale'] = m.kern['.*lengthscale'] + m2[".*lengthscale"] = m.kern[".*lengthscale"] np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.lengthscale.randomize() - m2.kern.lengthscale = m.kern['.*lengthscale'] + m2.kern.lengthscale = m.kern[".*lengthscale"] np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) def test_missing_data(self): Q = 4 - k = GPy.kern.Linear(Q, ARD=True) + GPy.kern.White(Q, np.exp(-2)) # + kern.bias(Q) + k = GPy.kern.Linear(Q, ARD=True) + GPy.kern.White( + Q, np.exp(-2) + ) # + kern.bias(Q) m = _create_missing_data_model(k, Q) - assert(m.checkgrad()) + assert m.checkgrad() mul, varl = m.predict(m.X) - k = GPy.kern.RBF(Q, ARD=True) + GPy.kern.White(Q, np.exp(-2)) # + kern.bias(Q) + k = GPy.kern.RBF(Q, ARD=True) + GPy.kern.White(Q, np.exp(-2)) # + kern.bias(Q) m2 = _create_missing_data_model(k, Q) - assert(m.checkgrad()) + assert m.checkgrad() m2.kern.rbf.lengthscale[:] = 1e6 m2.X[:] = m.X.param_array @@ -328,27 +363,27 @@ class MiscTests(unittest.TestCase): q50 = m.predict_quantiles(m.X, (50,)) np.testing.assert_allclose(mul, q50[0]) - - def test_likelihood_replicate_kern(self): m = GPy.models.GPRegression(self.X, self.Y) m2 = GPy.models.GPRegression(self.X, self.Y) np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.randomize() - m2.kern[''] = m.kern[:] + m2.kern[""] = m.kern[:] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.randomize() m2.kern[:] = m.kern[:] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.randomize() - m2.kern[''] = m.kern[''] + m2.kern[""] = m.kern[""] np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) m.kern.randomize() - m2.kern[:] = m.kern[''].values() + m2.kern[:] = m.kern[""].values() np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) def test_big_model(self): - m = GPy.examples.dimensionality_reduction.mrd_simulation(optimize=0, plot=0, plot_sim=0) + m = GPy.examples.dimensionality_reduction.mrd_simulation( + optimize=0, plot=0, plot_sim=0 + ) m.X.fix() print(m) m.unfix() @@ -367,37 +402,50 @@ class MiscTests(unittest.TestCase): def test_mrd(self): from GPy.inference.latent_function_inference import InferenceMethodList, VarDTC from GPy.likelihoods import Gaussian + Y1 = np.random.normal(0, 1, (40, 13)) Y2 = np.random.normal(0, 1, (40, 6)) Y3 = np.random.normal(0, 1, (40, 8)) Q = 5 - m = GPy.models.MRD(dict(data1=Y1, data2=Y2, data3=Y3), Q, - ) + m = GPy.models.MRD( + dict(data1=Y1, data2=Y2, data3=Y3), + Q, + ) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() - m = GPy.models.MRD(dict(data1=Y1, data2=Y2, data3=Y3), Q, initx='PCA_single', - initz='random', - kernel=[GPy.kern.RBF(Q, ARD=1) for _ in range(3)], - inference_method=InferenceMethodList([VarDTC() for _ in range(3)]), - likelihoods = [Gaussian(name='Gaussian_noise'.format(i)) for i in range(3)]) + m = GPy.models.MRD( + dict(data1=Y1, data2=Y2, data3=Y3), + Q, + initx="PCA_single", + initz="random", + kernel=[GPy.kern.RBF(Q, ARD=1) for _ in range(3)], + inference_method=InferenceMethodList([VarDTC() for _ in range(3)]), + likelihoods=[Gaussian(name="Gaussian_noise".format(i)) for i in range(3)], + ) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() - m = GPy.models.MRD(dict(data1=Y1, data2=Y2, data3=Y3), Q, initx='random', - initz='random', - kernel=GPy.kern.RBF(Q, ARD=1), - ) + m = GPy.models.MRD( + dict(data1=Y1, data2=Y2, data3=Y3), + Q, + initx="random", + initz="random", + kernel=GPy.kern.RBF(Q, ARD=1), + ) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() - m = GPy.models.MRD(dict(data1=Y1, data2=Y2, data3=Y3), Q, X=np.random.normal(0,1,size=(40,Q)), - X_variance=False, - kernel=GPy.kern.RBF(Q, ARD=1), - likelihoods = [Gaussian(name='Gaussian_noise'.format(i)) for i in range(3)]) + m = GPy.models.MRD( + dict(data1=Y1, data2=Y2, data3=Y3), + Q, + X=np.random.normal(0, 1, size=(40, Q)), + X_variance=False, + kernel=GPy.kern.RBF(Q, ARD=1), + likelihoods=[Gaussian(name="Gaussian_noise".format(i)) for i in range(3)], + ) m.randomize() - self.assertTrue(m.checkgrad()) - + assert m.checkgrad() def test_model_set_params(self): m = GPy.models.GPRegression(self.X, self.Y) @@ -405,7 +453,7 @@ class MiscTests(unittest.TestCase): m.kern.lengthscale = lengthscale np.testing.assert_equal(m.kern.lengthscale, lengthscale) m.kern.lengthscale *= 1 - m['.*var'] -= .1 + m[".*var"] -= 0.1 np.testing.assert_equal(m.kern.lengthscale, lengthscale) m.optimize() print(m) @@ -417,19 +465,20 @@ class MiscTests(unittest.TestCase): self.count = 0 m.add_observer(self, self._count_updates, -2000) m.update_model(False) - m['.*Gaussian'] = .001 + m[".*Gaussian"] = 0.001 self.assertEquals(self.count, 0) - m['.*Gaussian'].constrain_bounded(0,.01) + m[".*Gaussian"].constrain_bounded(0, 0.01) self.assertEquals(self.count, 0) m.Z.fix() self.assertEquals(self.count, 0) m.update_model(True) self.assertEquals(self.count, 1) + def _count_updates(self, me, which): - self.count+=1 + self.count += 1 def test_model_optimize(self): - X = np.random.uniform(-3., 3., (20, 1)) + X = np.random.uniform(-3.0, 3.0, (20, 1)) Y = np.sin(X) + np.random.randn(20, 1) * 0.05 m = GPy.models.GPRegression(X, Y) m.optimize() @@ -447,7 +496,9 @@ class MiscTests(unittest.TestCase): warp_k = GPy.kern.RBF(1) warp_f = GPy.util.input_warping_functions.IdentifyWarping() - warp_m = GPy.models.InputWarpedGP(self.X, self.Y, kernel=warp_k, warping_function=warp_f) + warp_m = GPy.models.InputWarpedGP( + self.X, self.Y, kernel=warp_k, warping_function=warp_f + ) warp_m.optimize() warp_preds = warp_m.predict(self.X) @@ -485,17 +536,47 @@ class MiscTests(unittest.TestCase): warping_ind_1 = [0, 1, 2] warping_ind_2 = [-1, 1, 2] warping_ind_3 = [0, 1.5, 2] - self.failUnlessRaises(ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_1) - self.failUnlessRaises(ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_2) - self.failUnlessRaises(ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_3) + self.failUnlessRaises( + ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_1 + ) + self.failUnlessRaises( + ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_2 + ) + self.failUnlessRaises( + ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_3 + ) # testing Xmin and Xmax Xmin_1, Xmax_1 = None, [1, 1] Xmin_2, Xmax_2 = [0, 0], None Xmin_3, Xmax_3 = [0, 0, 0], [1, 1] - self.failUnlessRaises(ValueError, GPy.util.input_warping_functions.KumarWarping, X, [0, 1], epsilon, Xmin_1, Xmax_1) - self.failUnlessRaises(ValueError, GPy.util.input_warping_functions.KumarWarping, X, [0, 1], epsilon, Xmin_2, Xmax_2) - self.failUnlessRaises(ValueError, GPy.util.input_warping_functions.KumarWarping, X, [0, 1], epsilon, Xmin_3, Xmax_3) + self.failUnlessRaises( + ValueError, + GPy.util.input_warping_functions.KumarWarping, + X, + [0, 1], + epsilon, + Xmin_1, + Xmax_1, + ) + self.failUnlessRaises( + ValueError, + GPy.util.input_warping_functions.KumarWarping, + X, + [0, 1], + epsilon, + Xmin_2, + Xmax_2, + ) + self.failUnlessRaises( + ValueError, + GPy.util.input_warping_functions.KumarWarping, + X, + [0, 1], + epsilon, + Xmin_3, + Xmax_3, + ) def test_warped_gp_identity(self): """ @@ -509,15 +590,17 @@ class MiscTests(unittest.TestCase): warp_k = GPy.kern.RBF(1) warp_f = GPy.util.warping_functions.IdentityFunction(closed_inverse=False) - warp_m = GPy.models.WarpedGP(self.X, self.Y, kernel=warp_k, - warping_function=warp_f) + warp_m = GPy.models.WarpedGP( + self.X, self.Y, kernel=warp_k, warping_function=warp_f + ) warp_m.optimize() warp_preds = warp_m.predict(self.X) warp_k_exact = GPy.kern.RBF(1) warp_f_exact = GPy.util.warping_functions.IdentityFunction() - warp_m_exact = GPy.models.WarpedGP(self.X, self.Y, kernel=warp_k_exact, - warping_function=warp_f_exact) + warp_m_exact = GPy.models.WarpedGP( + self.X, self.Y, kernel=warp_k_exact, warping_function=warp_f_exact + ) warp_m_exact.optimize() warp_preds_exact = warp_m_exact.predict(self.X) @@ -539,15 +622,15 @@ class MiscTests(unittest.TestCase): warp_k = GPy.kern.RBF(1) warp_f = GPy.util.warping_functions.LogFunction(closed_inverse=False) - warp_m = GPy.models.WarpedGP(self.X, Y, kernel=warp_k, - warping_function=warp_f) + warp_m = GPy.models.WarpedGP(self.X, Y, kernel=warp_k, warping_function=warp_f) warp_m.optimize() warp_preds = warp_m.predict(self.X, median=True)[0] warp_k_exact = GPy.kern.RBF(1) warp_f_exact = GPy.util.warping_functions.LogFunction() - warp_m_exact = GPy.models.WarpedGP(self.X, Y, kernel=warp_k_exact, - warping_function=warp_f_exact) + warp_m_exact = GPy.models.WarpedGP( + self.X, Y, kernel=warp_k_exact, warping_function=warp_f_exact + ) warp_m_exact.optimize(messages=True) warp_preds_exact = warp_m_exact.predict(self.X, median=True)[0] @@ -561,15 +644,18 @@ class MiscTests(unittest.TestCase): just to ensure coverage of the tanh warping function code. """ X = (2 * np.pi) * np.random.random(151) - np.pi - Y = np.sin(X) + np.random.normal(0,0.2,151) - Y = np.array([np.power(abs(y),float(1)/3) * (1,-1)[y<0] for y in Y]) + Y = np.sin(X) + np.random.normal(0, 0.2, 151) + Y = np.array([np.power(abs(y), float(1) / 3) * (1, -1)[y < 0] for y in Y]) X = X[:, None] Y = Y[:, None] - warp_m = GPy.models.WarpedGP(X, Y)#, kernel=warp_k)#, warping_function=warp_f) - warp_m['.*\.d'].constrain_fixed(1.0) - warp_m.optimize_restarts(parallel=False, robust=False, num_restarts=5, - max_iters=max_iters) + warp_m = GPy.models.WarpedGP( + X, Y + ) # , kernel=warp_k)#, warping_function=warp_f) + warp_m[".*\.d"].constrain_fixed(1.0) + warp_m.optimize_restarts( + parallel=False, robust=False, num_restarts=5, max_iters=max_iters + ) warp_m.predict(X) warp_m.predict_quantiles(X) warp_m.log_predictive_density(X, Y) @@ -579,34 +665,53 @@ class MiscTests(unittest.TestCase): warp_m.plot() def test_offset_regression(self): - #Tests GPy.models.GPOffsetRegression. Using two small time series - #from a sine wave, we confirm the algorithm determines that the - #likelihood is maximised when the offset hyperparameter is approximately - #equal to the actual offset in X between the two time series. + # Tests GPy.models.GPOffsetRegression. Using two small time series + # from a sine wave, we confirm the algorithm determines that the + # likelihood is maximised when the offset hyperparameter is approximately + # equal to the actual offset in X between the two time series. offset = 3 - X1 = np.arange(0,50,5.0)[:,None] - X2 = np.arange(0+offset,50+offset,5.0)[:,None] - X = np.vstack([X1,X2]) - ind = np.vstack([np.zeros([10,1]),np.ones([10,1])]) - X = np.hstack([X,ind]) - Y = np.sin((X[0:10,0])/30.0)[:,None] - Y = np.vstack([Y,Y]) + X1 = np.arange(0, 50, 5.0)[:, None] + X2 = np.arange(0 + offset, 50 + offset, 5.0)[:, None] + X = np.vstack([X1, X2]) + ind = np.vstack([np.zeros([10, 1]), np.ones([10, 1])]) + X = np.hstack([X, ind]) + Y = np.sin((X[0:10, 0]) / 30.0)[:, None] + Y = np.vstack([Y, Y]) - m = GPy.models.GPOffsetRegression(X,Y) - m.rbf.lengthscale=5.0 #make it something other than one to check our gradients properly! - assert m.checkgrad(), "Gradients of offset parameters don't match numerical approximations." + m = GPy.models.GPOffsetRegression(X, Y) + m.rbf.lengthscale = ( + 5.0 # make it something other than one to check our gradients properly! + ) + assert ( + m.checkgrad() + ), "Gradients of offset parameters don't match numerical approximations." m.optimize() - assert np.abs(m.offset[0]-offset)<0.1, ("GPOffsetRegression model failing to estimate correct offset (value estimated = %0.2f instead of %0.2f)" % (m.offset[0], offset)) + assert np.abs(m.offset[0] - offset) < 0.1, ( + "GPOffsetRegression model failing to estimate correct offset (value estimated = %0.2f instead of %0.2f)" + % (m.offset[0], offset) + ) def test_logistic_basis_func_gradients(self): X = np.random.uniform(-4, 4, (20, 5)) points = np.random.uniform(X.min(0), X.max(0), X.shape[1]) ks = [] for i in range(points.shape[0]): - if (i%2==0) and (i%3!=0): - self.assertRaises(AssertionError, GPy.kern.LogisticBasisFuncKernel, 1, points, ARD=i%2==0, ARD_slope=i%3==0, active_dims=[i]) + if (i % 2 == 0) and (i % 3 != 0): + self.assertRaises( + AssertionError, + GPy.kern.LogisticBasisFuncKernel, + 1, + points, + ARD=i % 2 == 0, + ARD_slope=i % 3 == 0, + active_dims=[i], + ) else: - ks.append(GPy.kern.LogisticBasisFuncKernel(1, points, ARD=i%2==0, ARD_slope=i%3==0, active_dims=[i])) + ks.append( + GPy.kern.LogisticBasisFuncKernel( + 1, points, ARD=i % 2 == 0, ARD_slope=i % 3 == 0, active_dims=[i] + ) + ) k = GPy.kern.Add(ks) k.randomize() @@ -625,26 +730,29 @@ class MiscTests(unittest.TestCase): Y = 0 for w, s, c in zip(true_w, true_slope, k.centers[0]): - Y += w/(1+np.exp(-s*(X-c))) - Y += np.random.normal(0, .000001) + Y += w / (1 + np.exp(-s * (X - c))) + Y += np.random.normal(0, 0.000001) - m = GPy.models.GPRegression(X,Y,kernel=k.copy()) - #m.likelihood.fix(1e-6) + m = GPy.models.GPRegression(X, Y, kernel=k.copy()) + # m.likelihood.fix(1e-6) m.optimize() wu, wv = m.kern.posterior_inf() - #_sort = np.argsort(wu.flat) + # _sort = np.argsort(wu.flat) - #from scipy.stats import norm - #confidence_intervals = np.array(norm.interval(.95, loc=wu.flat[_sort], scale=np.sqrt(np.diag(wv))[_sort])).T - #for i in range(wu.size): + # from scipy.stats import norm + # confidence_intervals = np.array(norm.interval(.95, loc=wu.flat[_sort], scale=np.sqrt(np.diag(wv))[_sort])).T + # for i in range(wu.size): # s,t = confidence_intervals[i] # v = true_w[i] # assert ((s0) -1 + M = 7 + xd = np.array([np.linspace(2, 8, M)]).T + yd = 2 * (fd(xd) > 0) - 1 # squared exponential kernel: - se = GPy.kern.RBF(input_dim = 1, lengthscale=1.5, variance=0.2) + se = GPy.kern.RBF(input_dim=1, lengthscale=1.5, variance=0.2) # We need to generate separate kernel for the derivative observations and give the created kernel as an input: se_der = GPy.kern.DiffKern(se, 0) - #Then + # Then gauss = GPy.likelihoods.Gaussian(variance=sigma**2) - probit = GPy.likelihoods.Binomial(gp_link = GPy.likelihoods.link_functions.ScaledProbit(nu=100)) + probit = GPy.likelihoods.Binomial( + gp_link=GPy.likelihoods.link_functions.ScaledProbit(nu=100) + ) # Then create the model, we give everything in lists - m = GPy.models.MultioutputGP(X_list=[x, xd], Y_list=[y, yd], kernel_list=[se, se_der], likelihood_list = [gauss, probit], inference_method=GPy.inference.latent_function_inference.EP(ep_mode="nested")) - - self.assertTrue(m.checkgrad()) + m = GPy.models.MultioutputGP( + X_list=[x, xd], + Y_list=[y, yd], + kernel_list=[se, se_der], + likelihood_list=[gauss, probit], + inference_method=GPy.inference.latent_function_inference.EP( + ep_mode="nested" + ), + ) + assert m.checkgrad() def test_predictive_gradients_with_normalizer(self): """ Check that model.predictive_gradients returns the gradients of - model.predict when normalizer=True + model.predict when normalizer=True """ N, M, Q = 10, 15, 3 - X = np.random.rand(M,Q) - Y = np.random.rand(M,1) + X = np.random.rand(M, Q) + Y = np.random.rand(M, 1) x = np.random.rand(N, Q) model = GPy.models.GPRegression(X=X, Y=Y, normalizer=True) from GPy.models import GradientChecker - gm = GradientChecker(lambda x: model.predict(x)[0], - lambda x: model.predictive_gradients(x)[0], - x, 'x') - gc = GradientChecker(lambda x: model.predict(x)[1], - lambda x: model.predictive_gradients(x)[1], - x, 'x') - assert(gm.checkgrad()) - assert(gc.checkgrad()) + gm = GradientChecker( + lambda x: model.predict(x)[0], + lambda x: model.predictive_gradients(x)[0], + x, + "x", + ) + gc = GradientChecker( + lambda x: model.predict(x)[1], + lambda x: model.predictive_gradients(x)[1], + x, + "x", + ) + assert gm.checkgrad() + assert gc.checkgrad() def test_posterior_covariance_between_points_with_normalizer(self): """ - Check that model.posterior_covariance_between_points returns + Check that model.posterior_covariance_between_points returns the covariance from model.predict when normalizer=True """ np.random.seed(3) N, M, Q = 10, 15, 3 - X = np.random.rand(M,Q) - Y = np.random.rand(M,1) + X = np.random.rand(M, Q) + Y = np.random.rand(M, 1) x = np.random.rand(2, Q) model = GPy.models.GPRegression(X=X, Y=Y, normalizer=True) - c1 = model.posterior_covariance_between_points(x,x) + c1 = model.posterior_covariance_between_points(x, x) c2 = model.predict(x, full_cov=True)[1] - np.testing.assert_allclose(c1,c2) + np.testing.assert_allclose(c1, c2) + class GradientMultioutputGPModelTests(np.testing.TestCase): def setUp(self): - # standard test function self.period = 3 - self.w = 2*np.pi/self.period - self.f = lambda x: np.sum(np.square(np.sin(self.w*x)), axis=1) - self.df = lambda x: self.w*np.sin(2*self.w*x) + self.w = 2 * np.pi / self.period + self.f = lambda x: np.sum(np.square(np.sin(self.w * x)), axis=1) + self.df = lambda x: self.w * np.sin(2 * self.w * x) self.noise_std = 1e-2 @@ -1293,38 +1508,37 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): self.test_points = 25 def approximate_predictive_gradients(self, model, x_test, D, step=1e-6): - ''' + """ Approximates gradients of predicted posterior means and variances. This function is used as the frameworks for GradientChecker and MultioutputGP do not easily combine when checking gradients of predicted partial derivative posteriors. - ''' + """ - dmdx_aprx = np.zeros((x_test.shape[0]*(D + 1), D)) - dvdx_aprx = np.zeros((x_test.shape[0]*(D + 1), D)) + dmdx_aprx = np.zeros((x_test.shape[0] * (D + 1), D)) + dvdx_aprx = np.zeros((x_test.shape[0] * (D + 1), D)) for d in range(D): - x_over = x_test.copy() - x_over[:,d] += step + x_over[:, d] += step x_undr = x_test.copy() - x_undr[:,d] -= step + x_undr[:, d] -= step - m_over, v_over = model.predict([x_over]*(D + 1)) - m_undr, v_undr = model.predict([x_undr]*(D + 1)) + m_over, v_over = model.predict([x_over] * (D + 1)) + m_undr, v_undr = model.predict([x_undr] * (D + 1)) - dmdx_aprx[:,d,None] = (m_over - m_undr)/(2*step) - dvdx_aprx[:,d,None] = (v_over - v_undr)/(2*step) + dmdx_aprx[:, d, None] = (m_over - m_undr) / (2 * step) + dvdx_aprx[:, d, None] = (v_over - v_undr) / (2 * step) return dmdx_aprx, dvdx_aprx def check_model(self, kern): - ''' + """ Checks predictions, hyperparameter gradients, and gradients of predicted posterior means and variances for MultioutputGP models that incorporate observed latent function gradient information. - ''' + """ D = kern.input_dim @@ -1334,7 +1548,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): # sample inputs for either latent function or partial derivatives X_i = np.random.uniform(*self.bounds, size=(self.train_points, D)) # output of latent function or partial derivatives - Y_i = (self.f(X_i) if (i == 0) else self.df(X_i)[:,i - 1])[:,None] + Y_i = (self.f(X_i) if (i == 0) else self.df(X_i)[:, i - 1])[:, None] # noisy observations Y_i += np.random.normal(scale=self.noise_std, size=Y_i.shape) @@ -1345,7 +1559,9 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): kernel_list = [kern] + [GPy.kern.DiffKern(kern, d) for d in range(D)] # create model and check its hyperparameter gradient - likelihood_list = [GPy.likelihoods.Gaussian(variance=self.noise_std**2)]*(D + 1) + likelihood_list = [GPy.likelihoods.Gaussian(variance=self.noise_std**2)] * ( + D + 1 + ) model = GPy.models.MultioutputGP(X_list, Y_list, kernel_list, likelihood_list) model.likelihood.constrain_fixed() self.assertTrue(model.checkgrad(step=1e-3)) @@ -1355,41 +1571,45 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): self.assertTrue(model.checkgrad(step=1e-3)) # check predictions - np.testing.assert_allclose(model.predict(X_list)[0], model.Y, atol=3*self.noise_std) + np.testing.assert_allclose( + model.predict(X_list)[0], model.Y, atol=3 * self.noise_std + ) # test inputs for checking predictive gradients x_test = np.random.uniform(*self.bounds, size=(self.test_points, D)) # predictive gradients - dmdx, dvdx = model.predictive_gradients([x_test]*(D + 1)) + dmdx, dvdx = model.predictive_gradients([x_test] * (D + 1)) # approximated predictive gradients - dmdx_aprx, dvdx_aprx = self.approximate_predictive_gradients(model, x_test, D, step=1e-3) + dmdx_aprx, dvdx_aprx = self.approximate_predictive_gradients( + model, x_test, D, step=1e-3 + ) # check predictive gradients - np.testing.assert_allclose(dmdx, dmdx_aprx, atol=3*self.noise_std) - np.testing.assert_allclose(dvdx, dvdx_aprx, atol=3*self.noise_std) + np.testing.assert_allclose(dmdx, dmdx_aprx, atol=3 * self.noise_std) + np.testing.assert_allclose(dvdx, dvdx_aprx, atol=3 * self.noise_std) def test_MultioutputGP_gradobs_RBF(self): - ''' + """ Testing gradient observing MultioutputGP model with an RBF kernel. - ''' + """ for D in range(1, 4): kern = GPy.kern.RBF(input_dim=D) kern.randomize() self.check_model(kern) def test_MultioutputGP_gradobs_RBF_ARD(self): - ''' + """ Testing gradient observing MultioutputGP model with an RBF (ARD) kernel. - ''' + """ for D in range(1, 4): kern = GPy.kern.RBF(input_dim=D, ARD=True) kern.randomize() self.check_model(kern) def test_MultioutputGP_gradobs_StdP(self): - ''' + """ Testing gradient observing MultioutputGP model with a StdP kernel. - ''' + """ for D in range(1, 4): kern = GPy.kern.StdPeriodic(input_dim=D, period=self.period) kern.period.constrain_fixed() @@ -1397,19 +1617,21 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): self.check_model(kern) def test_MultioutputGP_gradobs_StdP_ARD(self): - ''' + """ Testing gradient observing MultioutputGP model with a StdP (ARD) kernel. - ''' + """ for D in range(1, 4): - kern = GPy.kern.StdPeriodic(input_dim=D, period=[self.period]*D, ARD1=True, ARD2=True) + kern = GPy.kern.StdPeriodic( + input_dim=D, period=[self.period] * D, ARD1=True, ARD2=True + ) kern.period.constrain_fixed() kern.randomize() self.check_model(kern) def test_MultioutputGP_gradobs_prod_RBF(self): - ''' + """ Testing gradient observing MultioutputGP model with several RBF kernels. - ''' + """ for D in range(2, 4): kerns = [GPy.kern.RBF(input_dim=1) for d in range(D)] kern = reduce(lambda k0, k1: k0 * k1, kerns) @@ -1417,20 +1639,22 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): self.check_model(kern) def test_MultioutputGP_gradobs_prod_StdP(self): - ''' + """ Testing gradient observing MultioutputGP model with several StdP kernels. - ''' + """ for D in range(2, 4): - kerns = [GPy.kern.StdPeriodic(input_dim=1, period=self.period) for d in range(D)] + kerns = [ + GPy.kern.StdPeriodic(input_dim=1, period=self.period) for d in range(D) + ] kern = reduce(lambda k0, k1: k0 * k1, kerns) [k.period.constrain_fixed() for k in kern.parts] kern.randomize() self.check_model(kern) def test_MultioutputGP_gradobs_prod_mix(self): - ''' + """ Testing gradient observing MultioutputGP model with a mix of kernel types. - ''' + """ for D in range(2, 4): kerns = [] for d in range(D): @@ -1444,20 +1668,30 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): kern.randomize() self.check_model(kern) + def _create_missing_data_model(kernel, Q): D1, D2, D3, N, num_inducing = 13, 5, 8, 400, 3 - _, _, Ylist = GPy.examples.dimensionality_reduction._simulate_matern(D1, D2, D3, N, num_inducing, False) + _, _, Ylist = GPy.examples.dimensionality_reduction._simulate_matern( + D1, D2, D3, N, num_inducing, False + ) Y = Ylist[0] - inan = np.random.binomial(1, .9, size=Y.shape).astype(bool) # 80% missing data + inan = np.random.binomial(1, 0.9, size=Y.shape).astype(bool) # 80% missing data Ymissing = Y.copy() Ymissing[inan] = np.nan - m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(Ymissing, Q, init="random", num_inducing=num_inducing, - kernel=kernel, missing_data=True) + m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( + Ymissing, + Q, + init="random", + num_inducing=num_inducing, + kernel=kernel, + missing_data=True, + ) return m + if __name__ == "__main__": print("Running unit tests, please be (very) patient...") unittest.main() From 247b84e90ba332cc09eb5df6793ceb1811b2040d Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 9 Oct 2023 00:01:46 +0200 Subject: [PATCH 036/101] migrate model_tests to pytest --- GPy/testing/model_tests.py | 208 ++++++++++++++++++++++++++++--------- 1 file changed, 161 insertions(+), 47 deletions(-) diff --git a/GPy/testing/model_tests.py b/GPy/testing/model_tests.py index a5001a7f..99a85c38 100644 --- a/GPy/testing/model_tests.py +++ b/GPy/testing/model_tests.py @@ -1,16 +1,18 @@ # Copyright (c) 2012, GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) -from __future__ import division - -import unittest +import pytest import numpy as np import GPy -from GPy.models import GradientChecker from functools import reduce +try: + import autograd +except ImportError: + autograd = None -class MiscTests(unittest.TestCase): - def setUp(self): + +class TestMisc: + def setup(self): self.N = 20 self.N_new = 50 self.D = 1 @@ -19,6 +21,7 @@ class MiscTests(unittest.TestCase): self.X_new = np.random.uniform(-3.0, 3.0, (self.N_new, 1)) def test_setXY(self): + self.setup() m = GPy.models.GPRegression(self.X, self.Y) m.set_XY( np.vstack([self.X, np.random.rand(1, self.X.shape[1])]), @@ -33,6 +36,7 @@ class MiscTests(unittest.TestCase): Test whether the predicted variance of normal GP goes negative under numerical unstable situation. Thanks simbartonels@github for reporting the bug and providing the following example. """ + self.setup() # set seed for reproducability np.random.seed(3) @@ -71,9 +75,10 @@ class MiscTests(unittest.TestCase): Xp[:, 0] = Xp[:, 0] * 15 - 5 Xp[:, 1] = Xp[:, 1] * 15 _, var = m.predict(Xp) - self.assertTrue(np.all(var >= 0.0)) + assert np.all(var >= 0.0)) def test_raw_predict(self): + self.setup() k = GPy.kern.RBF(1) m = GPy.models.GPRegression(self.X, self.Y, kernel=k) m.randomize() @@ -85,18 +90,19 @@ class MiscTests(unittest.TestCase): mu_hat = k.K(self.X_new, self.X).dot(Kinv).dot(m.Y_normalized) mu, covar = m.predict_noiseless(self.X_new, full_cov=True) - self.assertEquals(mu.shape, (self.N_new, self.D)) - self.assertEquals(covar.shape, (self.N_new, self.N_new)) + assert mu.shape == (self.N_new, self.D) + assert covar.shape == (self.N_new, self.N_new) np.testing.assert_almost_equal(K_hat, covar) np.testing.assert_almost_equal(mu_hat, mu) mu, var = m.predict_noiseless(self.X_new) - self.assertEquals(mu.shape, (self.N_new, self.D)) - self.assertEquals(var.shape, (self.N_new, 1)) + assert mu.shape == (self.N_new, self.D) + assert var.shape == (self.N_new, 1) np.testing.assert_almost_equal(np.diag(K_hat)[:, None], var) np.testing.assert_almost_equal(mu_hat, mu) def test_normalizer(self): + self.setup() k = GPy.kern.RBF(1) Y = self.Y mu, std = Y.mean(0), Y.std(0) @@ -141,6 +147,7 @@ class MiscTests(unittest.TestCase): """ Test that normalizing works in multi-output case """ + self.setup() # Create test inputs X = self.X @@ -186,12 +193,12 @@ class MiscTests(unittest.TestCase): np.array(q95).flatten(), ) - def check_jacobian(self): - try: - import autograd.numpy as np, autograd as ag, GPy, matplotlib.pyplot as plt - from GPy.models import GradientChecker, GPRegression - except: - raise self.skipTest("autograd not available to check gradients") + @pytest.mark.skipif( + autograd is None, reason="autograd not available to check gradients" + ) + def test_jacobian(self): + import autograd.numpy as np, autograd as ag, GPy, matplotlib.pyplot as plt + from GPy.models import GradientChecker, GPRegression def k(X, X2, alpha=1.0, lengthscale=None): if lengthscale is None: @@ -242,6 +249,8 @@ class MiscTests(unittest.TestCase): def test_predict_uncertain_inputs(self): """Projection of Gaussian through a linear function is still gaussian, and moments are analytical to compute, so we can check this case for predictions easily""" + self.setup() + X = np.linspace(-5, 5, 10)[:, None] Y = 2 * X + np.random.randn(*X.shape) * 1e-3 m = GPy.models.BayesianGPLVM( @@ -266,6 +275,8 @@ class MiscTests(unittest.TestCase): np.testing.assert_allclose(Y_var_true, Y_var_pred, rtol=1e-3) def test_sparse_raw_predict(self): + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.SparseGPRegression(self.X, self.Y, kernel=k) m.randomize() @@ -277,18 +288,20 @@ class MiscTests(unittest.TestCase): # K_hat = np.clip(K_hat, 1e-15, np.inf) mu, covar = m.predict_noiseless(self.X_new, full_cov=True) - self.assertEquals(mu.shape, (self.N_new, self.D)) - self.assertEquals(covar.shape, (self.N_new, self.N_new)) + assert mu.shape == (self.N_new, self.D) + assert covar.shape == (self.N_new, self.N_new) np.testing.assert_almost_equal(K_hat, covar) # np.testing.assert_almost_equal(mu_hat, mu) mu, var = m.predict_noiseless(self.X_new) - self.assertEquals(mu.shape, (self.N_new, self.D)) - self.assertEquals(var.shape, (self.N_new, 1)) + assert mu.shape == (self.N_new, self.D) + assert var.shape == (self.N_new, 1) np.testing.assert_almost_equal(np.diag(K_hat)[:, None], var) # np.testing.assert_almost_equal(mu_hat, mu) def test_likelihood_replicate(self): + self.setup() + m = GPy.models.GPRegression(self.X, self.Y) m2 = GPy.models.GPRegression(self.X, self.Y) np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) @@ -318,6 +331,8 @@ class MiscTests(unittest.TestCase): np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) def test_likelihood_set(self): + self.setup() + m = GPy.models.GPRegression(self.X, self.Y) m2 = GPy.models.GPRegression(self.X, self.Y) np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) @@ -339,6 +354,8 @@ class MiscTests(unittest.TestCase): np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) def test_missing_data(self): + self.setup() + Q = 4 k = GPy.kern.Linear(Q, ARD=True) + GPy.kern.White( @@ -364,6 +381,8 @@ class MiscTests(unittest.TestCase): np.testing.assert_allclose(mul, q50[0]) def test_likelihood_replicate_kern(self): + self.setup() + m = GPy.models.GPRegression(self.X, self.Y) m2 = GPy.models.GPRegression(self.X, self.Y) np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) @@ -381,6 +400,8 @@ class MiscTests(unittest.TestCase): np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) def test_big_model(self): + self.setup() + m = GPy.examples.dimensionality_reduction.mrd_simulation( optimize=0, plot=0, plot_sim=0 ) @@ -403,6 +424,8 @@ class MiscTests(unittest.TestCase): from GPy.inference.latent_function_inference import InferenceMethodList, VarDTC from GPy.likelihoods import Gaussian + self.setup() + Y1 = np.random.normal(0, 1, (40, 13)) Y2 = np.random.normal(0, 1, (40, 6)) Y3 = np.random.normal(0, 1, (40, 8)) @@ -448,6 +471,8 @@ class MiscTests(unittest.TestCase): assert m.checkgrad() def test_model_set_params(self): + self.setup() + m = GPy.models.GPRegression(self.X, self.Y) lengthscale = np.random.uniform() m.kern.lengthscale = lengthscale @@ -459,6 +484,8 @@ class MiscTests(unittest.TestCase): print(m) def test_model_updates(self): + self.setup() + Y1 = np.random.normal(0, 1, (40, 13)) Y2 = np.random.normal(0, 1, (40, 6)) m = GPy.models.MRD([Y1, Y2], 5) @@ -466,18 +493,20 @@ class MiscTests(unittest.TestCase): m.add_observer(self, self._count_updates, -2000) m.update_model(False) m[".*Gaussian"] = 0.001 - self.assertEquals(self.count, 0) + assert self.count == 0 m[".*Gaussian"].constrain_bounded(0, 0.01) - self.assertEquals(self.count, 0) + assert self.count == 0 m.Z.fix() - self.assertEquals(self.count, 0) + assert self.count == 0 m.update_model(True) - self.assertEquals(self.count, 1) + assert self.count == 1 def _count_updates(self, me, which): self.count += 1 def test_model_optimize(self): + self.setup() + X = np.random.uniform(-3.0, 3.0, (20, 1)) Y = np.sin(X) + np.random.randn(20, 1) * 0.05 m = GPy.models.GPRegression(X, Y) @@ -489,6 +518,8 @@ class MiscTests(unittest.TestCase): A InputWarpedGP with the identity warping function should be equal to a standard GP. """ + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.GPRegression(self.X, self.Y, kernel=k) m.optimize() @@ -505,6 +536,8 @@ class MiscTests(unittest.TestCase): np.testing.assert_almost_equal(preds, warp_preds, decimal=4) def test_kumar_warping_gradient(self): + self.setup() + n_X = 100 np.random.seed(0) X = np.random.randn(n_X, 2) @@ -513,21 +546,23 @@ class MiscTests(unittest.TestCase): k1 = GPy.kern.Linear(2) m1 = GPy.models.InputWarpedGP(X, Y, kernel=k1) m1.randomize() - self.assertEquals(m1.checkgrad(), True) + assert m1.checkgrad() k2 = GPy.kern.RBF(2) m2 = GPy.models.InputWarpedGP(X, Y, kernel=k2) m2.randomize() m2.checkgrad() - self.assertEquals(m2.checkgrad(), True) + assert m2.checkgrad() k3 = GPy.kern.Matern52(2) m3 = GPy.models.InputWarpedGP(X, Y, kernel=k3) m3.randomize() m3.checkgrad() - self.assertEquals(m3.checkgrad(), True) + assert m3.checkgrad() def test_kumar_warping_parameters(self): + self.setup() + np.random.seed(1) X = np.random.rand(5, 2) epsilon = 1e-6 @@ -583,6 +618,8 @@ class MiscTests(unittest.TestCase): A WarpedGP with the identity warping function should be equal to a standard GP. """ + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.GPRegression(self.X, self.Y, kernel=k) m.optimize() @@ -613,6 +650,8 @@ class MiscTests(unittest.TestCase): equal to a standard GP with log labels. Note that we predict the median here. """ + self.setup() + k = GPy.kern.RBF(1) Y = np.abs(self.Y) logY = np.log(Y) @@ -637,12 +676,15 @@ class MiscTests(unittest.TestCase): np.testing.assert_almost_equal(np.exp(preds), warp_preds, decimal=4) np.testing.assert_almost_equal(np.exp(preds), warp_preds_exact, decimal=4) - def test_warped_gp_cubic_sine(self, max_iters=100): + def test_warped_gp_cubic_sine(self): """ A test replicating the cubic sine regression problem from Snelson's paper. This test doesn't have any assertions, it's just to ensure coverage of the tanh warping function code. """ + self.setup() + max_iters = 100 + X = (2 * np.pi) * np.random.random(151) - np.pi Y = np.sin(X) + np.random.normal(0, 0.2, 151) Y = np.array([np.power(abs(y), float(1) / 3) * (1, -1)[y < 0] for y in Y]) @@ -669,6 +711,8 @@ class MiscTests(unittest.TestCase): # from a sine wave, we confirm the algorithm determines that the # likelihood is maximised when the offset hyperparameter is approximately # equal to the actual offset in X between the two time series. + self.setup() + offset = 3 X1 = np.arange(0, 50, 5.0)[:, None] X2 = np.arange(0 + offset, 50 + offset, 5.0)[:, None] @@ -692,6 +736,8 @@ class MiscTests(unittest.TestCase): ) def test_logistic_basis_func_gradients(self): + self.setup() + X = np.random.uniform(-4, 4, (20, 5)) points = np.random.uniform(X.min(0), X.max(0), X.shape[1]) ks = [] @@ -720,6 +766,8 @@ class MiscTests(unittest.TestCase): assert m.checkgrad() def test_posterior_inf_basis_funcs(self): + self.setup() + X = np.random.uniform(-4, 1, (50, 1)) # Logistic: @@ -754,8 +802,8 @@ class MiscTests(unittest.TestCase): ) -class GradientTests(np.testing.TestCase): - def setUp(self): +class TestGradient: + def setup(self): ###################################### # # 1 dimensional example @@ -800,21 +848,25 @@ class GradientTests(np.testing.TestCase): def test_GPRegression_rbf_1d(self): """Testing the GP regression with rbf kernel with white kernel on 1d data""" + self.setup() rbf = GPy.kern.RBF(1) self.check_model(rbf, model_type="GPRegression", dimension=1) def test_GPRegression_rbf_2D(self): """Testing the GP regression with rbf kernel on 2d data""" + self.setup() rbf = GPy.kern.RBF(2) self.check_model(rbf, model_type="GPRegression", dimension=2) def test_GPRegression_rbf_ARD_2D(self): """Testing the GP regression with rbf kernel on 2d data""" + self.setup() k = GPy.kern.RBF(2, ARD=True) self.check_model(k, model_type="GPRegression", dimension=2) def test_GPRegression_mlp_1d(self): """Testing the GP regression with mlp kernel with white kernel on 1d data""" + self.setup() mlp = GPy.kern.MLP(1) self.check_model(mlp, model_type="GPRegression", dimension=1) @@ -826,101 +878,121 @@ class GradientTests(np.testing.TestCase): def test_GPRegression_matern52_1D(self): """Testing the GP regression with matern52 kernel on 1d data""" + self.setup() matern52 = GPy.kern.Matern52(1) self.check_model(matern52, model_type="GPRegression", dimension=1) def test_GPRegression_matern52_2D(self): """Testing the GP regression with matern52 kernel on 2d data""" + self.setup() matern52 = GPy.kern.Matern52(2) self.check_model(matern52, model_type="GPRegression", dimension=2) def test_GPRegression_matern52_ARD_2D(self): """Testing the GP regression with matern52 kernel on 2d data""" + self.setup() matern52 = GPy.kern.Matern52(2, ARD=True) self.check_model(matern52, model_type="GPRegression", dimension=2) def test_GPRegression_matern32_1D(self): """Testing the GP regression with matern32 kernel on 1d data""" + self.setup() matern32 = GPy.kern.Matern32(1) self.check_model(matern32, model_type="GPRegression", dimension=1) def test_GPRegression_matern32_2D(self): """Testing the GP regression with matern32 kernel on 2d data""" + self.setup() matern32 = GPy.kern.Matern32(2) self.check_model(matern32, model_type="GPRegression", dimension=2) def test_GPRegression_matern32_ARD_2D(self): """Testing the GP regression with matern32 kernel on 2d data""" + self.setup() matern32 = GPy.kern.Matern32(2, ARD=True) self.check_model(matern32, model_type="GPRegression", dimension=2) def test_GPRegression_exponential_1D(self): """Testing the GP regression with exponential kernel on 1d data""" + self.setup() exponential = GPy.kern.Exponential(1) self.check_model(exponential, model_type="GPRegression", dimension=1) def test_GPRegression_exponential_2D(self): """Testing the GP regression with exponential kernel on 2d data""" + self.setup() exponential = GPy.kern.Exponential(2) self.check_model(exponential, model_type="GPRegression", dimension=2) def test_GPRegression_exponential_ARD_2D(self): """Testing the GP regression with exponential kernel on 2d data""" + self.setup() exponential = GPy.kern.Exponential(2, ARD=True) self.check_model(exponential, model_type="GPRegression", dimension=2) def test_GPRegression_bias_kern_1D(self): """Testing the GP regression with bias kernel on 1d data""" + self.setup() bias = GPy.kern.Bias(1) self.check_model(bias, model_type="GPRegression", dimension=1) def test_GPRegression_bias_kern_2D(self): """Testing the GP regression with bias kernel on 2d data""" + self.setup() bias = GPy.kern.Bias(2) self.check_model(bias, model_type="GPRegression", dimension=2) def test_GPRegression_linear_kern_1D_ARD(self): """Testing the GP regression with linear kernel on 1d data""" + self.setup() linear = GPy.kern.Linear(1, ARD=True) self.check_model(linear, model_type="GPRegression", dimension=1) def test_GPRegression_linear_kern_2D_ARD(self): """Testing the GP regression with linear kernel on 2d data""" + self.setup() linear = GPy.kern.Linear(2, ARD=True) self.check_model(linear, model_type="GPRegression", dimension=2) def test_GPRegression_linear_kern_1D(self): """Testing the GP regression with linear kernel on 1d data""" + self.setup() linear = GPy.kern.Linear(1) self.check_model(linear, model_type="GPRegression", dimension=1) def test_GPRegression_linear_kern_2D(self): """Testing the GP regression with linear kernel on 2d data""" + self.setup() linear = GPy.kern.Linear(2) self.check_model(linear, model_type="GPRegression", dimension=2) def test_SparseGPRegression_rbf_white_kern_1d(self): """Testing the sparse GP regression with rbf kernel with white kernel on 1d data""" + self.setup() rbf = GPy.kern.RBF(1) self.check_model(rbf, model_type="SparseGPRegression", dimension=1) def test_SparseGPRegression_rbf_white_kern_2D(self): """Testing the sparse GP regression with rbf kernel on 2d data""" + self.setup() rbf = GPy.kern.RBF(2) self.check_model(rbf, model_type="SparseGPRegression", dimension=2) def test_SparseGPRegression_rbf_linear_white_kern_1D(self): """Testing the sparse GP regression with rbf kernel on 1d data""" + self.setup() rbflin = GPy.kern.RBF(1) + GPy.kern.Linear(1) + GPy.kern.White(1, 1e-5) self.check_model(rbflin, model_type="SparseGPRegression", dimension=1) def test_SparseGPRegression_rbf_linear_white_kern_2D(self): """Testing the sparse GP regression with rbf kernel on 2d data""" + self.setup() rbflin = GPy.kern.RBF(2) + GPy.kern.Linear(2) self.check_model(rbflin, model_type="SparseGPRegression", dimension=2) def test_SparseGPRegression_rbf_white_kern_2D_uncertain_inputs(self): """Testing the sparse GP regression with rbf, linear kernel on 2d data with uncertain inputs""" + self.setup() rbflin = GPy.kern.RBF(2) + GPy.kern.White(2) self.check_model( rbflin, model_type="SparseGPRegression", dimension=2, uncertain_inputs=1 @@ -928,6 +1000,7 @@ class GradientTests(np.testing.TestCase): def test_SparseGPRegression_rbf_white_kern_1D_uncertain_inputs(self): """Testing the sparse GP regression with rbf, linear kernel on 1d data with uncertain inputs""" + self.setup() rbflin = GPy.kern.RBF(1) + GPy.kern.White(1) self.check_model( rbflin, model_type="SparseGPRegression", dimension=1, uncertain_inputs=1 @@ -935,46 +1008,55 @@ class GradientTests(np.testing.TestCase): def test_TPRegression_matern52_1D(self): """Testing the TP regression with matern52 kernel on 1d data""" + self.setup() matern52 = GPy.kern.Matern52(1) + GPy.kern.White(1) self.check_model(matern52, model_type="TPRegression", dimension=1) def test_TPRegression_rbf_2D(self): """Testing the TP regression with rbf kernel on 2d data""" + self.setup() rbf = GPy.kern.RBF(2) self.check_model(rbf, model_type="TPRegression", dimension=2) def test_TPRegression_rbf_ARD_2D(self): """Testing the GP regression with rbf kernel on 2d data""" + self.setup() k = GPy.kern.RBF(2, ARD=True) self.check_model(k, model_type="TPRegression", dimension=2) def test_TPRegression_matern52_2D(self): """Testing the TP regression with matern52 kernel on 2d data""" + self.setup() matern52 = GPy.kern.Matern52(2) self.check_model(matern52, model_type="TPRegression", dimension=2) def test_TPRegression_matern52_ARD_2D(self): """Testing the TP regression with matern52 kernel on 2d data""" + self.setup() matern52 = GPy.kern.Matern52(2, ARD=True) self.check_model(matern52, model_type="TPRegression", dimension=2) def test_TPRegression_matern32_1D(self): """Testing the TP regression with matern32 kernel on 1d data""" + self.setup() matern32 = GPy.kern.Matern32(1) self.check_model(matern32, model_type="TPRegression", dimension=1) def test_TPRegression_matern32_2D(self): """Testing the TP regression with matern32 kernel on 2d data""" + self.setup() matern32 = GPy.kern.Matern32(2) self.check_model(matern32, model_type="TPRegression", dimension=2) def test_TPRegression_matern32_ARD_2D(self): """Testing the TP regression with matern32 kernel on 2d data""" + self.setup() matern32 = GPy.kern.Matern32(2, ARD=True) self.check_model(matern32, model_type="TPRegression", dimension=2) def test_GPLVM_rbf_bias_white_kern_2D(self): """Testing GPLVM with rbf + bias kernel""" + self.setup() N, input_dim, D = 50, 1, 2 X = np.random.rand(N, input_dim) k = ( @@ -991,6 +1073,7 @@ class GradientTests(np.testing.TestCase): def test_SparseGPLVM_rbf_bias_white_kern_2D(self): """Testing GPLVM with rbf + bias kernel""" + self.setup() N, input_dim, D = 50, 1, 2 X = np.random.rand(N, input_dim) k = ( @@ -1007,6 +1090,7 @@ class GradientTests(np.testing.TestCase): def test_BCGPLVM_rbf_bias_white_kern_2D(self): """Testing GPLVM with rbf + bias kernel""" + self.setup() N, input_dim, D = 50, 1, 2 X = np.random.rand(N, input_dim) k = ( @@ -1021,6 +1105,7 @@ class GradientTests(np.testing.TestCase): def test_GPLVM_rbf_linear_white_kern_2D(self): """Testing GPLVM with rbf + bias kernel""" + self.setup() N, input_dim, D = 50, 1, 2 X = np.random.rand(N, input_dim) k = ( @@ -1034,6 +1119,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_GP_EP_probit(self): + self.setup() N = 20 Nhalf = int(N / 2) X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ @@ -1045,6 +1131,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_sparse_EP_DTC_probit(self): + self.setup() N = 20 Nhalf = int(N / 2) X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ @@ -1057,6 +1144,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_sparse_EP_DTC_probit_uncertain_inputs(self): + self.setup() N = 20 Nhalf = int(N / 2) X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ @@ -1072,6 +1160,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_multioutput_regression_1D(self): + self.setup() X1 = np.random.rand(50, 1) * 8 X2 = np.random.rand(30, 1) * 5 X = np.vstack((X1, X2)) @@ -1088,6 +1177,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_simple_MultivariateGaussian_prior(self): + self.setup() X = np.random.multivariate_normal( [1, 5], np.diag([0.5, 0.3]), (100, 1) ).reshape(100, 2) @@ -1104,6 +1194,7 @@ class GradientTests(np.testing.TestCase): print(m.kern.lengthscale) def test_simple_MultivariateGaussian_prior_matrixmean(self): + self.setup() X = np.random.multivariate_normal( [1, 5], np.diag([0.5, 0.3]), (100, 1) ).reshape(100, 2) @@ -1120,6 +1211,7 @@ class GradientTests(np.testing.TestCase): print(m.kern.lengthscale) def test_multioutput_sparse_regression_1D(self): + self.setup() X1 = np.random.rand(500, 1) * 8 X2 = np.random.rand(300, 1) * 5 X = np.vstack((X1, X2)) @@ -1134,6 +1226,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_gp_heteroscedastic_regression(self): + self.setup() num_obs = 25 X = np.random.randint(0, 140, num_obs) X = X[:, None] @@ -1143,6 +1236,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_sparse_gp_heteroscedastic_regression(self): + self.setup() num_obs = 25 X = np.random.randint(0, 140, num_obs) X = X[:, None] @@ -1166,6 +1260,7 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_gp_kronecker_gaussian(self): + self.setup() np.random.seed(0) N1, N2 = 30, 20 X1 = np.random.randn(N1, 1) @@ -1188,18 +1283,19 @@ class GradientTests(np.testing.TestCase): m.randomize() mm[:] = m[:] - self.assertTrue(np.allclose(m.log_likelihood(), mm.log_likelihood())) - self.assertTrue(np.allclose(m.gradient, mm.gradient)) + assert np.allclose(m.log_likelihood(), mm.log_likelihood()) + assert np.allclose(m.gradient, mm.gradient) X1test = np.random.randn(100, 1) X2test = np.random.randn(100, 1) mean1, var1 = m.predict(X1test, X2test) yy, xx = np.meshgrid(X2test, X1test) Xgrid = np.vstack((xx.flatten(order="F"), yy.flatten(order="F"))).T mean2, var2 = mm.predict(Xgrid) - self.assertTrue(np.allclose(mean1, mean2)) - self.assertTrue(np.allclose(var1, var2)) + assert np.allclose(mean1, mean2) + assert np.allclose(var1, var2) def test_gp_VGPC(self): + self.setup() np.random.seed(10) num_obs = 25 X = np.random.randint(0, 140, num_obs) @@ -1218,6 +1314,8 @@ class GradientTests(np.testing.TestCase): from GPy.models import SSGPLVM from GPy.examples.dimensionality_reduction import _simulate_matern + self.setup() + np.random.seed(10) D1, D2, D3, N, num_inducing, Q = 13, 5, 8, 45, 3, 9 _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, False) @@ -1234,6 +1332,8 @@ class GradientTests(np.testing.TestCase): np.random.seed(0) import GPy + self.setup() + N = 10 N_train = 5 D = 4 @@ -1272,7 +1372,7 @@ class GradientTests(np.testing.TestCase): ) m_mr.optimize_auto(max_iters=1) m_mr.randomize() - self.assertTrue(m_mr.checkgrad()) + assert m_mr.checkgrad() m_mr = GPy.models.GPMultioutRegression( x, @@ -1284,13 +1384,15 @@ class GradientTests(np.testing.TestCase): ) m_mr.optimize_auto(max_iters=1) m_mr.randomize() - self.assertTrue(m_mr.checkgrad()) + assert m_mr.checkgrad() def test_multiout_regression_md(self): import GPy np.random.seed(0) + self.setup() + N = 20 N_train = 5 D = 8 @@ -1390,6 +1492,8 @@ class GradientTests(np.testing.TestCase): assert m.checkgrad() def test_posterior_covariance(self): + self.setup() + k = GPy.kern.Poly(2, order=1) X1 = np.array([[-2, 2], [-1, 1]]) X2 = np.array([[2, 3], [-1, 3]]) @@ -1399,9 +1503,11 @@ class GradientTests(np.testing.TestCase): result = m._raw_posterior_covariance_between_points(X1, X2) expected = np.array([[0.4, 2.2], [1.0, 1.0]]) / 3.0 - self.assertTrue(np.allclose(result, expected)) + assert np.allclose(result, expected) def test_posterior_covariance_missing_data(self): + self.setup() + Q = 4 k = GPy.kern.Linear(Q, ARD=True) m = _create_missing_data_model(k, Q) @@ -1412,6 +1518,8 @@ class GradientTests(np.testing.TestCase): ) def test_multioutput_model_with_ep(self): + self.setup() + f = lambda x: np.sin(x) + 0.1 * (x - 2.0) ** 2 - 0.005 * x**3 fd = lambda x: np.cos(x) + 0.2 * (x - 2.0) - 0.015 * x**2 N = 10 @@ -1453,6 +1561,8 @@ class GradientTests(np.testing.TestCase): Check that model.predictive_gradients returns the gradients of model.predict when normalizer=True """ + self.setup() + N, M, Q = 10, 15, 3 X = np.random.rand(M, Q) Y = np.random.rand(M, 1) @@ -1480,6 +1590,8 @@ class GradientTests(np.testing.TestCase): Check that model.posterior_covariance_between_points returns the covariance from model.predict when normalizer=True """ + self.setup() + np.random.seed(3) N, M, Q = 10, 15, 3 X = np.random.rand(M, Q) @@ -1492,8 +1604,8 @@ class GradientTests(np.testing.TestCase): np.testing.assert_allclose(c1, c2) -class GradientMultioutputGPModelTests(np.testing.TestCase): - def setUp(self): +class TestGradientMultioutputGPModel: + def setup(self): # standard test function self.period = 3 self.w = 2 * np.pi / self.period @@ -1564,11 +1676,11 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): ) model = GPy.models.MultioutputGP(X_list, Y_list, kernel_list, likelihood_list) model.likelihood.constrain_fixed() - self.assertTrue(model.checkgrad(step=1e-3)) + assert model.checkgrad(step=1e-3) # optimize the model, and check its hyperparameter gradient again model.optimize() - self.assertTrue(model.checkgrad(step=1e-3)) + assert model.checkgrad(step=1e-3) # check predictions np.testing.assert_allclose( @@ -1592,6 +1704,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with an RBF kernel. """ + self.setup() for D in range(1, 4): kern = GPy.kern.RBF(input_dim=D) kern.randomize() @@ -1601,6 +1714,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with an RBF (ARD) kernel. """ + self.setup() for D in range(1, 4): kern = GPy.kern.RBF(input_dim=D, ARD=True) kern.randomize() @@ -1610,6 +1724,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with a StdP kernel. """ + self.setup() for D in range(1, 4): kern = GPy.kern.StdPeriodic(input_dim=D, period=self.period) kern.period.constrain_fixed() @@ -1620,6 +1735,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with a StdP (ARD) kernel. """ + self.setup() for D in range(1, 4): kern = GPy.kern.StdPeriodic( input_dim=D, period=[self.period] * D, ARD1=True, ARD2=True @@ -1632,6 +1748,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with several RBF kernels. """ + self.setup() for D in range(2, 4): kerns = [GPy.kern.RBF(input_dim=1) for d in range(D)] kern = reduce(lambda k0, k1: k0 * k1, kerns) @@ -1642,6 +1759,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with several StdP kernels. """ + self.setup() for D in range(2, 4): kerns = [ GPy.kern.StdPeriodic(input_dim=1, period=self.period) for d in range(D) @@ -1655,6 +1773,7 @@ class GradientMultioutputGPModelTests(np.testing.TestCase): """ Testing gradient observing MultioutputGP model with a mix of kernel types. """ + self.setup() for D in range(2, 4): kerns = [] for d in range(D): @@ -1690,8 +1809,3 @@ def _create_missing_data_model(kernel, Q): ) return m - - -if __name__ == "__main__": - print("Running unit tests, please be (very) patient...") - unittest.main() From 1d7504fdfb2c63ad75b63f3e8e63a2b151f84aed Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 18:48:06 +0200 Subject: [PATCH 037/101] format on save --- GPy/testing/mpi_tests.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/GPy/testing/mpi_tests.py b/GPy/testing/mpi_tests.py index 28a23288..8bde8755 100644 --- a/GPy/testing/mpi_tests.py +++ b/GPy/testing/mpi_tests.py @@ -9,8 +9,7 @@ try: from mpi4py import MPI import subprocess - class MPITests(unittest.TestCase): - + class MPITests: def test_BayesianGPLVM_MPI(self): code = """ import numpy as np @@ -33,17 +32,20 @@ if comm.rank==0: m._trigger_params_changed() print float(m.objective_function()) """ - with open('mpi_test__.py','w') as f: + with open("mpi_test__.py", "w") as f: f.write(code) f.close() - p = subprocess.Popen('mpirun -n 4 python mpi_test__.py',stdout=subprocess.PIPE,shell=True) + p = subprocess.Popen( + "mpirun -n 4 python mpi_test__.py", stdout=subprocess.PIPE, shell=True + ) (stdout, stderr) = p.communicate() - L1 = float(stdout.splitlines()[-2]) - L2 = float(stdout.splitlines()[-1]) - self.assertTrue(np.allclose(L1,L2)) + L1 = float(stdout.splitlines()[-2]) + L2 = float(stdout.splitlines()[-1]) + self.assertTrue(np.allclose(L1, L2)) import os - os.remove('mpi_test__.py') - + + os.remove("mpi_test__.py") + def test_SparseGPRegression_MPI(self): code = """ import numpy as np @@ -66,27 +68,29 @@ if comm.rank==0: m._trigger_params_changed() print float(m.objective_function()) """ - with open('mpi_test__.py','w') as f: + with open("mpi_test__.py", "w") as f: f.write(code) f.close() - p = subprocess.Popen('mpirun -n 4 python mpi_test__.py',stdout=subprocess.PIPE,shell=True) + p = subprocess.Popen( + "mpirun -n 4 python mpi_test__.py", stdout=subprocess.PIPE, shell=True + ) (stdout, stderr) = p.communicate() - L1 = float(stdout.splitlines()[-2]) - L2 = float(stdout.splitlines()[-1]) - self.assertTrue(np.allclose(L1,L2)) + L1 = float(stdout.splitlines()[-2]) + L2 = float(stdout.splitlines()[-1]) + self.assertTrue(np.allclose(L1, L2)) import os - os.remove('mpi_test__.py') + os.remove("mpi_test__.py") except: pass - if __name__ == "__main__": print("Running unit tests, please be (very) patient...") try: import mpi4py + unittest.main() except: pass From b0c5e137a27f6227bec724518243f53e45692ac7 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 18:49:10 +0200 Subject: [PATCH 038/101] migrate mpi_tests to pytest --- GPy/testing/mpi_tests.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/GPy/testing/mpi_tests.py b/GPy/testing/mpi_tests.py index 8bde8755..51a50eef 100644 --- a/GPy/testing/mpi_tests.py +++ b/GPy/testing/mpi_tests.py @@ -3,13 +3,11 @@ import unittest import numpy as np -import GPy try: - from mpi4py import MPI import subprocess - class MPITests: + class TestMPI: def test_BayesianGPLVM_MPI(self): code = """ import numpy as np @@ -38,7 +36,7 @@ if comm.rank==0: p = subprocess.Popen( "mpirun -n 4 python mpi_test__.py", stdout=subprocess.PIPE, shell=True ) - (stdout, stderr) = p.communicate() + (stdout, _stderr) = p.communicate() L1 = float(stdout.splitlines()[-2]) L2 = float(stdout.splitlines()[-1]) self.assertTrue(np.allclose(L1, L2)) @@ -77,20 +75,10 @@ if comm.rank==0: (stdout, stderr) = p.communicate() L1 = float(stdout.splitlines()[-2]) L2 = float(stdout.splitlines()[-1]) - self.assertTrue(np.allclose(L1, L2)) + assert np.allclose(L1, L2) import os os.remove("mpi_test__.py") except: pass - - -if __name__ == "__main__": - print("Running unit tests, please be (very) patient...") - try: - import mpi4py - - unittest.main() - except: - pass From 1df86e22163d39c1a507e40c36b5f1dacb90f4a4 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 18:54:02 +0200 Subject: [PATCH 039/101] format on save --- GPy/testing/pep_tests.py | 59 ++++++++++++++++++------------------- GPy/testing/pickle_tests.py | 50 ++++++++++++++++++------------- 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/GPy/testing/pep_tests.py b/GPy/testing/pep_tests.py index 2aa6a784..03cdf1ec 100644 --- a/GPy/testing/pep_tests.py +++ b/GPy/testing/pep_tests.py @@ -5,6 +5,7 @@ import unittest import numpy as np import GPy + class PEPgradienttest(unittest.TestCase): def setUp(self): ###################################### @@ -13,22 +14,25 @@ class PEPgradienttest(unittest.TestCase): N = 20 # sample inputs and outputs - self.X1D = np.random.uniform(-3., 3., (N, 1)) + self.X1D = np.random.uniform(-3.0, 3.0, (N, 1)) self.Y1D = np.sin(self.X1D) + np.random.randn(N, 1) * 0.05 ###################################### # # 2 dimensional example # sample inputs and outputs - self.X2D = np.random.uniform(-3., 3., (N, 2)) - self.Y2D = np.sin(self.X2D[:, 0:1]) * np.sin(self.X2D[:, 1:2]) + np.random.randn(N, 1) * 0.05 + self.X2D = np.random.uniform(-3.0, 3.0, (N, 2)) + self.Y2D = ( + np.sin(self.X2D[:, 0:1]) * np.sin(self.X2D[:, 1:2]) + + np.random.randn(N, 1) * 0.05 + ) ####################################### # # more datapoints, check in alpha limits, the log marginal likelihood # # is consistent with FITC and VFE/Var_DTC M = 5 np.random.seed(42) - self.X1 = np.c_[np.linspace(-1., 1., N)] + self.X1 = np.c_[np.linspace(-1.0, 1.0, N)] self.Y1 = np.sin(self.X1) + np.random.randn(N, 1) * 0.05 self.kernel = GPy.kern.RBF(input_dim=1, lengthscale=0.5, variance=1) self.Z = np.random.uniform(-1, 1, (M, 1)) @@ -36,59 +40,52 @@ class PEPgradienttest(unittest.TestCase): def test_pep_1d_gradients(self): m = GPy.models.SparseGPRegression(self.X1D, self.Y1D) - m.inference_method = GPy.inference.latent_function_inference.PEP(alpha=np.random.rand()) - self.assertTrue(m.checkgrad()) + m.inference_method = GPy.inference.latent_function_inference.PEP( + alpha=np.random.rand() + ) + assert m.checkgrad() def test_pep_2d_gradients(self): m = GPy.models.SparseGPRegression(self.X2D, self.Y2D) - m.inference_method = GPy.inference.latent_function_inference.PEP(alpha=np.random.rand()) - self.assertTrue(m.checkgrad()) + m.inference_method = GPy.inference.latent_function_inference.PEP( + alpha=np.random.rand() + ) + assert m.checkgrad() def test_pep_vfe_consistency(self): vfe_model = GPy.models.SparseGPRegression( - self.X1, - self.Y1, - kernel=self.kernel, - Z=self.Z + self.X1, self.Y1, kernel=self.kernel, Z=self.Z ) vfe_model.inference_method = GPy.inference.latent_function_inference.VarDTC() vfe_model.Gaussian_noise.variance = self.lik_noise_var vfe_lml = vfe_model.log_likelihood() pep_model = GPy.models.SparseGPRegression( - self.X1, - self.Y1, - kernel=self.kernel, - Z=self.Z + self.X1, self.Y1, kernel=self.kernel, Z=self.Z + ) + pep_model.inference_method = GPy.inference.latent_function_inference.PEP( + alpha=1e-5 ) - pep_model.inference_method = GPy.inference.latent_function_inference.PEP(alpha=1e-5) pep_model.Gaussian_noise.variance = self.lik_noise_var pep_lml = pep_model.log_likelihood() - self.assertAlmostEqual(vfe_lml[0, 0], pep_lml[0], delta=abs(0.01*pep_lml[0])) + self.assertAlmostEqual(vfe_lml[0, 0], pep_lml[0], delta=abs(0.01 * pep_lml[0])) def test_pep_fitc_consistency(self): fitc_model = GPy.models.SparseGPRegression( - self.X1D, - self.Y1D, - kernel=self.kernel, - Z=self.Z + self.X1D, self.Y1D, kernel=self.kernel, Z=self.Z ) fitc_model.inference_method = GPy.inference.latent_function_inference.FITC() fitc_model.Gaussian_noise.variance = self.lik_noise_var fitc_lml = fitc_model.log_likelihood() pep_model = GPy.models.SparseGPRegression( - self.X1D, - self.Y1D, - kernel=self.kernel, - Z=self.Z + self.X1D, self.Y1D, kernel=self.kernel, Z=self.Z + ) + pep_model.inference_method = GPy.inference.latent_function_inference.PEP( + alpha=1 ) - pep_model.inference_method = GPy.inference.latent_function_inference.PEP(alpha=1) pep_model.Gaussian_noise.variance = self.lik_noise_var pep_lml = pep_model.log_likelihood() - self.assertAlmostEqual(fitc_lml, pep_lml[0], delta=abs(0.001*pep_lml[0])) - - - + self.assertAlmostEqual(fitc_lml, pep_lml[0], delta=abs(0.001 * pep_lml[0])) diff --git a/GPy/testing/pickle_tests.py b/GPy/testing/pickle_tests.py index 4c3ecd52..bf7c4044 100644 --- a/GPy/testing/pickle_tests.py +++ b/GPy/testing/pickle_tests.py @@ -1,10 +1,11 @@ -''' +""" Created on 13 Mar 2014 @author: maxz -''' +""" import unittest, itertools -#import cPickle as pickle + +# import cPickle as pickle import pickle import numpy as np import tempfile @@ -14,28 +15,37 @@ from GPy.models.gp_regression import GPRegression import GPy from nose import SkipTest + def toy_model(): - X = np.linspace(0,1,50)[:, None] + X = np.linspace(0, 1, 50)[:, None] Y = np.sin(X) m = GPRegression(X=X, Y=Y) return m + class ListDictTestCase(unittest.TestCase): def assertListDictEquals(self, d1, d2, msg=None): - #py3 fix - #for k,v in d1.iteritems(): - for k,v in d1.items(): + # py3 fix + # for k,v in d1.iteritems(): + for k, v in d1.items(): self.assertListEqual(list(v), list(d2[k]), msg) + def assertArrayListEquals(self, l1, l2): - for a1, a2 in zip(l1,l2): + for a1, a2 in zip(l1, l2): np.testing.assert_array_equal(a1, a2) + class Test(ListDictTestCase): @SkipTest def test_load_pickle(self): import os - m = GPy.load(os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'pickle_test.pickle')) - self.assertTrue(m.checkgrad()) + + m = GPy.load( + os.path.join( + os.path.abspath(os.path.split(__file__)[0]), "pickle_test.pickle" + ) + ) + assert m.checkgrad() self.assertEqual(m.log_likelihood(), -4.7351019830022087) def test_model(self): @@ -47,8 +57,8 @@ class Test(ListDictTestCase): self.assertIsNot(par.param_array, pcopy.param_array) self.assertIsNot(par.gradient_full, pcopy.gradient_full) self.assertTrue(pcopy.checkgrad()) - self.assert_(np.any(pcopy.gradient!=0.0)) - with tempfile.TemporaryFile('w+b') as f: + self.assert_(np.any(pcopy.gradient != 0.0)) + with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) @@ -66,10 +76,10 @@ class Test(ListDictTestCase): self.assertIsNot(par.param_array, pcopy.param_array) self.assertIsNot(par.gradient_full, pcopy.gradient_full) self.assertTrue(pcopy.checkgrad()) - self.assert_(np.any(pcopy.gradient!=0.0)) + self.assert_(np.any(pcopy.gradient != 0.0)) np.testing.assert_allclose(pcopy.param_array, par.param_array, atol=1e-6) par.randomize() - with tempfile.TemporaryFile('w+b') as f: + with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) @@ -79,9 +89,9 @@ class Test(ListDictTestCase): self.assert_(pcopy.checkgrad()) def test_posterior(self): - X = np.random.randn(3,5) + X = np.random.randn(3, 5) Xv = np.random.rand(*X.shape) - par = NormalPosterior(X,Xv) + par = NormalPosterior(X, Xv) par.gradient = 10 pcopy = par.copy() pcopy.gradient = 10 @@ -90,7 +100,7 @@ class Test(ListDictTestCase): self.assertSequenceEqual(str(par), str(pcopy)) self.assertIsNot(par.param_array, pcopy.param_array) self.assertIsNot(par.gradient_full, pcopy.gradient_full) - with tempfile.TemporaryFile('w+b') as f: + with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) @@ -111,8 +121,8 @@ class Test(ListDictTestCase): self.assertIsNot(par.gradient_full, pcopy.gradient_full) self.assertTrue(par.checkgrad()) self.assertTrue(pcopy.checkgrad()) - self.assert_(np.any(pcopy.gradient!=0.0)) - with tempfile.TemporaryFile('w+b') as f: + self.assert_(np.any(pcopy.gradient != 0.0)) + with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) @@ -126,5 +136,5 @@ class Test(ListDictTestCase): if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] + # import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] unittest.main() From b81fe8aaeb574bc6cbfa2757eb734ae60e6a63df Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 18:56:16 +0200 Subject: [PATCH 040/101] migrate pep_tests to pytest --- GPy/testing/pep_tests.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/GPy/testing/pep_tests.py b/GPy/testing/pep_tests.py index 03cdf1ec..92191f38 100644 --- a/GPy/testing/pep_tests.py +++ b/GPy/testing/pep_tests.py @@ -1,13 +1,12 @@ # Copyright (c) 2014, James Hensman, 2016, Thang Bui # Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest import numpy as np import GPy -class PEPgradienttest(unittest.TestCase): - def setUp(self): +class TestPEPgradient: + def setup(self): ###################################### # # 1 dimensional example np.random.seed(10) @@ -39,6 +38,7 @@ class PEPgradienttest(unittest.TestCase): self.lik_noise_var = 0.01 def test_pep_1d_gradients(self): + self.setup() m = GPy.models.SparseGPRegression(self.X1D, self.Y1D) m.inference_method = GPy.inference.latent_function_inference.PEP( alpha=np.random.rand() @@ -46,6 +46,7 @@ class PEPgradienttest(unittest.TestCase): assert m.checkgrad() def test_pep_2d_gradients(self): + self.setup() m = GPy.models.SparseGPRegression(self.X2D, self.Y2D) m.inference_method = GPy.inference.latent_function_inference.PEP( alpha=np.random.rand() @@ -53,6 +54,7 @@ class PEPgradienttest(unittest.TestCase): assert m.checkgrad() def test_pep_vfe_consistency(self): + self.setup() vfe_model = GPy.models.SparseGPRegression( self.X1, self.Y1, kernel=self.kernel, Z=self.Z ) @@ -69,9 +71,12 @@ class PEPgradienttest(unittest.TestCase): pep_model.Gaussian_noise.variance = self.lik_noise_var pep_lml = pep_model.log_likelihood() - self.assertAlmostEqual(vfe_lml[0, 0], pep_lml[0], delta=abs(0.01 * pep_lml[0])) + np.testing.assert_almost_equal( + vfe_lml[0, 0], pep_lml[0], decimal=abs(0.01 * pep_lml[0]) + ) def test_pep_fitc_consistency(self): + self.setup() fitc_model = GPy.models.SparseGPRegression( self.X1D, self.Y1D, kernel=self.kernel, Z=self.Z ) @@ -88,4 +93,6 @@ class PEPgradienttest(unittest.TestCase): pep_model.Gaussian_noise.variance = self.lik_noise_var pep_lml = pep_model.log_likelihood() - self.assertAlmostEqual(fitc_lml, pep_lml[0], delta=abs(0.001 * pep_lml[0])) + np.testing.assert_almost_equal( + fitc_lml, pep_lml[0], decimal=abs(0.001 * pep_lml[0]) + ) From 1464c1253fecbef98956e8615b09ae021df75f35 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 18:56:36 +0200 Subject: [PATCH 041/101] format on save --- GPy/testing/pickle_tests.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/GPy/testing/pickle_tests.py b/GPy/testing/pickle_tests.py index bf7c4044..fd2c6189 100644 --- a/GPy/testing/pickle_tests.py +++ b/GPy/testing/pickle_tests.py @@ -3,8 +3,6 @@ Created on 13 Mar 2014 @author: maxz """ -import unittest, itertools - # import cPickle as pickle import pickle import numpy as np @@ -13,7 +11,6 @@ from GPy.examples.dimensionality_reduction import mrd_simulation from GPy.core.parameterization.variational import NormalPosterior from GPy.models.gp_regression import GPRegression import GPy -from nose import SkipTest def toy_model(): From e4ea3bc8b22ebfd0985ffc9f6e82b2badf3abe95 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:39:19 +0200 Subject: [PATCH 042/101] migrate pickle_tests to pytest --- GPy/testing/pickle_tests.py | 83 ++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/GPy/testing/pickle_tests.py b/GPy/testing/pickle_tests.py index fd2c6189..3565130b 100644 --- a/GPy/testing/pickle_tests.py +++ b/GPy/testing/pickle_tests.py @@ -5,6 +5,7 @@ Created on 13 Mar 2014 """ # import cPickle as pickle import pickle +import pytest import numpy as np import tempfile from GPy.examples.dimensionality_reduction import mrd_simulation @@ -20,7 +21,7 @@ def toy_model(): return m -class ListDictTestCase(unittest.TestCase): +class ListDictTestCase: def assertListDictEquals(self, d1, d2, msg=None): # py3 fix # for k,v in d1.iteritems(): @@ -32,8 +33,9 @@ class ListDictTestCase(unittest.TestCase): np.testing.assert_array_equal(a1, a2) -class Test(ListDictTestCase): - @SkipTest +class TestPickleSupport(ListDictTestCase): + # TODO: why is this test skipped? + @pytest.mark.skip("") # TODO def test_load_pickle(self): import os @@ -43,37 +45,37 @@ class Test(ListDictTestCase): ) ) assert m.checkgrad() - self.assertEqual(m.log_likelihood(), -4.7351019830022087) + assert m.log_likelihood(), -4.7351019830022087 def test_model(self): par = toy_model() pcopy = par.copy() - self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + assert par.param_array.tolist() == pcopy.param_array.tolist() np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assertIsNot(par.param_array, pcopy.param_array) - self.assertIsNot(par.gradient_full, pcopy.gradient_full) - self.assertTrue(pcopy.checkgrad()) - self.assert_(np.any(pcopy.gradient != 0.0)) + assert str(par) == str(pcopy) + assert par.param_array != pcopy.param_array + assert par.gradient_full != pcopy.gradient_full + assert pcopy.checkgrad() + assert np.any(pcopy.gradient != 0.0) with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) - self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + assert par.param_array.tolist() == pcopy.param_array.tolist() np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assert_(pcopy.checkgrad()) + assert str(par) == str(pcopy) + assert pcopy.checkgrad() def test_modelrecreation(self): par = toy_model() pcopy = GPRegression(par.X.copy(), par.Y.copy(), kernel=par.kern.copy()) np.testing.assert_allclose(par.param_array, pcopy.param_array) np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assertIsNot(par.param_array, pcopy.param_array) - self.assertIsNot(par.gradient_full, pcopy.gradient_full) - self.assertTrue(pcopy.checkgrad()) - self.assert_(np.any(pcopy.gradient != 0.0)) + assert str(par) == str(pcopy) + assert par.param_array != pcopy.param_array + assert par.gradient_full != pcopy.gradient_full + assert pcopy.checkgrad() + assert np.any(pcopy.gradient != 0.0) np.testing.assert_allclose(pcopy.param_array, par.param_array, atol=1e-6) par.randomize() with tempfile.TemporaryFile("w+b") as f: @@ -82,8 +84,8 @@ class Test(ListDictTestCase): pcopy = pickle.load(f) np.testing.assert_allclose(par.param_array, pcopy.param_array) np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full, atol=1e-6) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assert_(pcopy.checkgrad()) + assert str(par) == str(pcopy) + assert pcopy.checkgrad() def test_posterior(self): X = np.random.randn(3, 5) @@ -92,46 +94,41 @@ class Test(ListDictTestCase): par.gradient = 10 pcopy = par.copy() pcopy.gradient = 10 - self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) - self.assertListEqual(par.gradient_full.tolist(), pcopy.gradient_full.tolist()) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assertIsNot(par.param_array, pcopy.param_array) - self.assertIsNot(par.gradient_full, pcopy.gradient_full) + assert par.param_array.tolist() == pcopy.param_array.tolist() + assert par.gradient_full.tolist() == pcopy.gradient_full.tolist() + assert str(par) == str(pcopy) + assert par.param_array != pcopy.param_array + assert par.gradient_full != pcopy.gradient_full with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) - self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + assert par.param_array.tolist() == pcopy.param_array.tolist() pcopy.gradient = 10 np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) np.testing.assert_allclose(pcopy.mean.gradient_full, 10) - self.assertSequenceEqual(str(par), str(pcopy)) + assert str(par) == str(pcopy) def test_model_concat(self): par = mrd_simulation(optimize=0, plot=0, plot_sim=0) par.randomize() pcopy = par.copy() - self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) - self.assertListEqual(par.gradient_full.tolist(), pcopy.gradient_full.tolist()) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assertIsNot(par.param_array, pcopy.param_array) - self.assertIsNot(par.gradient_full, pcopy.gradient_full) - self.assertTrue(par.checkgrad()) - self.assertTrue(pcopy.checkgrad()) - self.assert_(np.any(pcopy.gradient != 0.0)) + assert par.param_array.tolist() == pcopy.param_array.tolist() + assert par.gradient_full.tolist() == pcopy.gradient_full.tolist() + assert str(par) == str(pcopy) + assert par.param_array != pcopy.param_array + assert par.gradient_full != pcopy.gradient_full + assert par.checkgrad() + assert pcopy.checkgrad() + assert np.any(pcopy.gradient != 0.0) with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) pcopy = pickle.load(f) - self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + assert par.param_array.tolist() == pcopy.param_array.tolist() np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) - self.assertSequenceEqual(str(par), str(pcopy)) - self.assert_(pcopy.checkgrad()) + assert str(par) == str(pcopy) + assert pcopy.checkgrad() def _callback(self, what, which): what.count += 1 - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] - unittest.main() From aac3fb1c44af703d86d54cd102ee876210e0be88 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:47:10 +0200 Subject: [PATCH 043/101] migrate plotting_tests to pytest --- GPy/testing/plotting_tests.py | 646 ++++++++++++++++++++++------------ 1 file changed, 414 insertions(+), 232 deletions(-) diff --git a/GPy/testing/plotting_tests.py b/GPy/testing/plotting_tests.py index 90dceab0..16c9651c 100644 --- a/GPy/testing/plotting_tests.py +++ b/GPy/testing/plotting_tests.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (c) 2015, Max Zwiessele # All rights reserved. # @@ -26,26 +26,27 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#=============================================================================== +# =============================================================================== -#=============================================================================== +# =============================================================================== # SKIPPING PLOTTING BECAUSE IT BEHAVES DIFFERENTLY ON DIFFERENT # SYSTEMS, AND WILL MISBEHAVE -from nose import SkipTest -#raise SkipTest("Skipping Matplotlib testing") -#=============================================================================== + +# raise SkipTest("Skipping Matplotlib testing") +# =============================================================================== try: import matplotlib - matplotlib.use('agg') + from matplotlib import pyplot as plt + from matplotlib.testing.compare import compare_images + + matplotlib.use("agg") except ImportError: # matplotlib not installed - from nose import SkipTest - raise SkipTest("Error importing matplotlib") - -from unittest.case import TestCase + matplotlib = None +import pytest import numpy as np import GPy, os import logging @@ -53,49 +54,51 @@ import logging from GPy.util.config import config from GPy.plotting import change_plotting_library, plotting_library -class ConfigTest(TestCase): - def tearDown(self): - change_plotting_library('matplotlib') +class TestConfig: + def teardown(self): + change_plotting_library("matplotlib") + + @pytest.mark.skipif(matplotlib is None, reason="Matplotlib not installed") def test_change_plotting(self): - self.assertRaises(ValueError, change_plotting_library, 'not+in9names') - change_plotting_library('none') - self.assertRaises(RuntimeError, plotting_library) + with pytest.raises(ValueError): + change_plotting_library("not+in9names") + change_plotting_library("none") + with pytest.raises(RuntimeError): + plotting_library() + self.teardown() -change_plotting_library('matplotlib') -if config.get('plotting', 'library') != 'matplotlib': - raise SkipTest("Matplotlib not installed, not testing plots") -try: - from matplotlib import cbook, pyplot as plt - from matplotlib.testing.compare import compare_images -except ImportError: - raise SkipTest("Matplotlib not installed, not testing plots") +change_plotting_library("matplotlib") -extensions = ['npz'] +extensions = ["npz"] basedir = os.path.dirname(os.path.relpath(os.path.abspath(__file__))) + def _image_directories(): """ Compute the baseline and result image directories for testing *func*. Create the result directory if it doesn't exist. """ - #module_name = __init__.__module__ - #mods = module_name.split('.') - #basedir = os.path.join(*mods) - result_dir = os.path.join(basedir, 'testresult','.') - baseline_dir = os.path.join(basedir, 'baseline','.') + # module_name = __init__.__module__ + # mods = module_name.split('.') + # basedir = os.path.join(*mods) + result_dir = os.path.join(basedir, "testresult", ".") + baseline_dir = os.path.join(basedir, "baseline", ".") if not os.path.exists(result_dir): os.makedirs(result_dir) return baseline_dir, result_dir + baseline_dir, result_dir = _image_directories() if not os.path.exists(baseline_dir): - raise SkipTest("Not installed from source, baseline not available. Install from source to test plotting") + baseline_dir = None -def _image_comparison(baseline_images, extensions=['pdf','svg','png'], tol=11, rtol=1e-3, **kwargs): +def _image_comparison( + baseline_images, extensions=["pdf", "svg", "png"], tol=11, rtol=1e-3, **kwargs +): for num, base in zip(plt.get_fignums(), baseline_images): for ext in extensions: fig = plt.figure(num) @@ -103,60 +106,86 @@ def _image_comparison(baseline_images, extensions=['pdf','svg','png'], tol=11, r fig.canvas.draw() except Exception as e: logging.error(base) - #raise SkipTest(e) - #fig.axes[0].set_axis_off() - #fig.set_frameon(False) - if ext in ['npz']: + # raise SkipTest(e) + # fig.axes[0].set_axis_off() + # fig.set_frameon(False) + if ext in ["npz"]: figdict = flatten_axis(fig) - np.savez_compressed(os.path.join(result_dir, "{}.{}".format(base, ext)), **figdict) + np.savez_compressed( + os.path.join(result_dir, "{}.{}".format(base, ext)), **figdict + ) try: - fig.savefig(os.path.join(result_dir, "{}.{}".format(base, 'png')), - transparent=True, - edgecolor='none', - facecolor='none', - #bbox='tight' - ) + fig.savefig( + os.path.join(result_dir, "{}.{}".format(base, "png")), + transparent=True, + edgecolor="none", + facecolor="none", + # bbox='tight' + ) except: logging.error(base) # raise else: - fig.savefig(os.path.join(result_dir, "{}.{}".format(base, ext)), - transparent=True, - edgecolor='none', - facecolor='none', - #bbox='tight' - ) + fig.savefig( + os.path.join(result_dir, "{}.{}".format(base, ext)), + transparent=True, + edgecolor="none", + facecolor="none", + # bbox='tight' + ) for num, base in zip(plt.get_fignums(), baseline_images): for ext in extensions: - #plt.close(num) + # plt.close(num) actual = os.path.join(result_dir, "{}.{}".format(base, ext)) expected = os.path.join(baseline_dir, "{}.{}".format(base, ext)) - if ext == 'npz': + if ext == "npz": + def do_test(): + with pytest.skip if not os.path.exists(expected): import shutil + shutil.copy2(actual, expected) - #shutil.copy2(os.path.join(result_dir, "{}.{}".format(base, 'png')), os.path.join(baseline_dir, "{}.{}".format(base, 'png'))) - raise IOError("Baseline file {} not found, copying result {}".format(expected, actual)) + # shutil.copy2(os.path.join(result_dir, "{}.{}".format(base, 'png')), os.path.join(baseline_dir, "{}.{}".format(base, 'png'))) + raise IOError( + "Baseline file {} not found, copying result {}".format( + expected, actual + ) + ) else: exp_dict = dict(np.load(expected).items()) act_dict = dict(np.load(actual).items()) for name in act_dict: if name in exp_dict: try: - np.testing.assert_allclose(exp_dict[name], act_dict[name], err_msg="Mismatch in {}.{}".format(base, name), rtol=rtol, **kwargs) + np.testing.assert_allclose( + exp_dict[name], + act_dict[name], + err_msg="Mismatch in {}.{}".format(base, name), + rtol=rtol, + **kwargs + ) except AssertionError as e: - raise SkipTest(e) + pass + else: + def do_test(): err = compare_images(expected, actual, tol, in_decorator=True) if err: - raise SkipTest("Error between {} and {} is {:.5f}, which is bigger then the tolerance of {:.5f}".format(actual, expected, err['rms'], tol)) - yield do_test - plt.close('all') + print("Error between {} and {} is {:.5f}, which is bigger then the tolerance of {:.5f}".format( + actual, expected, err["rms"], tol + ) + ) + pass -def flatten_axis(ax, prevname=''): + yield do_test + plt.close("all") + + +def flatten_axis(ax, prevname=""): import inspect + members = inspect.getmembers(ax) arrays = {} @@ -168,123 +197,191 @@ def flatten_axis(ax, prevname=''): arr[pre] = np.asarray(l) elif isinstance(l, dict): for _n in l: - _tmp = _flatten(l, pre+"."+_n+".") + _tmp = _flatten(l, pre + "." + _n + ".") for _nt in _tmp.keys(): arrays[_nt] = _tmp[_nt] - elif isinstance(l, list) and len(l)>0: + elif isinstance(l, list) and len(l) > 0: for i in range(len(l)): - _tmp = _flatten(l[i], pre+"[{}]".format(i)) + _tmp = _flatten(l[i], pre + "[{}]".format(i)) for _n in _tmp: arr["{}".format(_n)] = _tmp[_n] else: - return flatten_axis(l, pre+'.') + return flatten_axis(l, pre + ".") return arr - for name, l in members: if isinstance(l, np.ndarray): - arrays[prevname+name] = np.asarray(l) - elif isinstance(l, list) and len(l)>0: + arrays[prevname + name] = np.asarray(l) + elif isinstance(l, list) and len(l) > 0: for i in range(len(l)): - _tmp = _flatten(l[i], prevname+name+"[{}]".format(i)) + _tmp = _flatten(l[i], prevname + name + "[{}]".format(i)) for _n in _tmp: arrays["{}".format(_n)] = _tmp[_n] return arrays -def _a(x,y,decimal): + +def _a(x, y, decimal): np.testing.assert_array_almost_equal(x, y, decimal) + def compare_axis_dicts(x, y, decimal=6): try: - assert(len(x)==len(y)) + assert len(x) == len(y) for name in x: _a(x[name], y[name], decimal) except AssertionError as e: - raise SkipTest(e.message) + print(e.message) + pass + +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_figure(): np.random.seed(1239847) from GPy.plotting import plotting_library as pl - #import matplotlib + + # import matplotlib matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False import warnings + with warnings.catch_warnings(): warnings.simplefilter("ignore") ax, _ = pl().new_canvas(num="imshow_interact") + def test_func(x): - return x[:, 0].reshape(3,3) - pl().imshow_interact(ax, test_func, extent=(-1,1,-1,1), resolution=3) + return x[:, 0].reshape(3, 3) + + pl().imshow_interact(ax, test_func, extent=(-1, 1, -1, 1), resolution=3) ax, _ = pl().new_canvas() + def test_func_2(x): - y = x[:, 0].reshape(3,3) - anno = np.argmax(x, axis=1).reshape(3,3) + y = x[:, 0].reshape(3, 3) + anno = np.argmax(x, axis=1).reshape(3, 3) return y, anno - pl().annotation_heatmap_interact(ax, test_func_2, extent=(-1,1,-1,1), resolution=3) - pl().annotation_heatmap_interact(ax, test_func_2, extent=(-1,1,-1,1), resolution=3, imshow_kwargs=dict(interpolation='nearest')) + pl().annotation_heatmap_interact( + ax, test_func_2, extent=(-1, 1, -1, 1), resolution=3 + ) + pl().annotation_heatmap_interact( + ax, + test_func_2, + extent=(-1, 1, -1, 1), + resolution=3, + imshow_kwargs=dict(interpolation="nearest"), + ) - ax, _ = pl().new_canvas(figsize=(4,3)) - x = np.linspace(0,1,100) - y = [0,1,2] - array = np.array([.4,.5]) - cmap = matplotlib.colors.LinearSegmentedColormap.from_list('WhToColor', ('r', 'b'), N=array.size) + ax, _ = pl().new_canvas(figsize=(4, 3)) + x = np.linspace(0, 1, 100) + y = [0, 1, 2] + array = np.array([0.4, 0.5]) + cmap = matplotlib.colors.LinearSegmentedColormap.from_list( + "WhToColor", ("r", "b"), N=array.size + ) - pl().fill_gradient(ax, x, y, facecolors=['r', 'g'], array=array, cmap=cmap) + pl().fill_gradient(ax, x, y, facecolors=["r", "g"], array=array, cmap=cmap) - ax, _ = pl().new_canvas(num="3d_plot", figsize=(4,3), projection='3d', xlabel='x', ylabel='y', zlabel='z', title='awsome title', xlim=(-1,1), ylim=(-1,1), zlim=(-3,3)) - z = 2-np.abs(np.linspace(-2,2,(100)))+1 - x, y = z*np.sin(np.linspace(-2*np.pi,2*np.pi,(100))), z*np.cos(np.linspace(-np.pi,np.pi,(100))) + ax, _ = pl().new_canvas( + num="3d_plot", + figsize=(4, 3), + projection="3d", + xlabel="x", + ylabel="y", + zlabel="z", + title="awsome title", + xlim=(-1, 1), + ylim=(-1, 1), + zlim=(-3, 3), + ) + z = 2 - np.abs(np.linspace(-2, 2, (100))) + 1 + x, y = z * np.sin(np.linspace(-2 * np.pi, 2 * np.pi, (100))), z * np.cos( + np.linspace(-np.pi, np.pi, (100)) + ) pl().plot(ax, x, y, z, linewidth=2) for do_test in _image_comparison( - baseline_images=['coverage_{}'.format(sub) for sub in ["imshow_interact",'annotation_interact','gradient','3d_plot',]], - extensions=extensions): - yield (do_test, ) - + baseline_images=[ + "coverage_{}".format(sub) + for sub in [ + "imshow_interact", + "annotation_interact", + "gradient", + "3d_plot", + ] + ], + extensions=extensions, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_kernel(): np.random.seed(1239847) - #import matplotlib + # import matplotlib matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False import warnings + with warnings.catch_warnings(): warnings.simplefilter("ignore") - k = GPy.kern.RBF(5, ARD=True) * GPy.kern.Linear(3, active_dims=[0,2,4], ARD=True) + GPy.kern.Bias(2) + k = GPy.kern.RBF(5, ARD=True) * GPy.kern.Linear( + 3, active_dims=[0, 2, 4], ARD=True + ) + GPy.kern.Bias(2) k.randomize() - k2 = GPy.kern.RBF(5, ARD=True) * GPy.kern.Linear(3, active_dims=[0,2,4], ARD=True) + GPy.kern.Bias(2) + GPy.kern.White(4) + k2 = ( + GPy.kern.RBF(5, ARD=True) + * GPy.kern.Linear(3, active_dims=[0, 2, 4], ARD=True) + + GPy.kern.Bias(2) + + GPy.kern.White(4) + ) k2[:-1] = k[:] - k2.plot_ARD(['rbf', 'linear', 'bias'], legend=True) - k2.plot_covariance(visible_dims=[0, 3], plot_limits=(-1,3)) + k2.plot_ARD(["rbf", "linear", "bias"], legend=True) + k2.plot_covariance(visible_dims=[0, 3], plot_limits=(-1, 3)) k2.plot_covariance(visible_dims=[2], plot_limits=(-1, 3)) - k2.plot_covariance(visible_dims=[2, 4], plot_limits=((-1, 0), (5, 3)), projection='3d', rstride=10, cstride=10) + k2.plot_covariance( + visible_dims=[2, 4], + plot_limits=((-1, 0), (5, 3)), + projection="3d", + rstride=10, + cstride=10, + ) k2.plot_covariance(visible_dims=[1, 4]) for do_test in _image_comparison( - baseline_images=['kern_{}'.format(sub) for sub in ["ARD", 'cov_2d', 'cov_1d', 'cov_3d', 'cov_no_lim']], - extensions=extensions): - yield (do_test, ) + baseline_images=[ + "kern_{}".format(sub) + for sub in ["ARD", "cov_2d", "cov_1d", "cov_3d", "cov_no_lim"] + ], + extensions=extensions, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_plot(): np.random.seed(111) import matplotlib + matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False import warnings + with warnings.catch_warnings(): warnings.simplefilter("ignore") X = np.random.uniform(-2, 2, (40, 1)) - f = .2 * np.sin(1.3*X) + 1.3*np.cos(2*X) - Y = f+np.random.normal(0, .1, f.shape) - m = GPy.models.SparseGPRegression(X, Y, X_variance=np.ones_like(X)*[0.06]) - #m.optimize() + f = 0.2 * np.sin(1.3 * X) + 1.3 * np.cos(2 * X) + Y = f + np.random.normal(0, 0.1, f.shape) + m = GPy.models.SparseGPRegression(X, Y, X_variance=np.ones_like(X) * [0.06]) + # m.optimize() m.plot_data() m.plot_mean() m.plot_confidence() @@ -292,88 +389,134 @@ def test_plot(): m.plot_errorbars_trainset() m.plot_samples() m.plot_data_error() - for do_test in _image_comparison(baseline_images=['gp_{}'.format(sub) for sub in ["data", "mean", 'conf', - 'density', - 'out_error', - 'samples', 'in_error']], extensions=extensions): - yield (do_test, ) + for do_test in _image_comparison( + baseline_images=[ + "gp_{}".format(sub) + for sub in [ + "data", + "mean", + "conf", + "density", + "out_error", + "samples", + "in_error", + ] + ], + extensions=extensions, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_twod(): np.random.seed(11111) import matplotlib + matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False X = np.random.uniform(-2, 2, (40, 2)) - f = .2 * np.sin(1.3*X[:,[0]]) + 1.3*np.cos(2*X[:,[1]]) - Y = f+np.random.normal(0, .1, f.shape) - m = GPy.models.SparseGPRegression(X, Y, X_variance=np.ones_like(X)*[0.01, 0.2]) - #m.optimize() + f = 0.2 * np.sin(1.3 * X[:, [0]]) + 1.3 * np.cos(2 * X[:, [1]]) + Y = f + np.random.normal(0, 0.1, f.shape) + m = GPy.models.SparseGPRegression(X, Y, X_variance=np.ones_like(X) * [0.01, 0.2]) + # m.optimize() m.plot_data() m.plot_mean() - m.plot_inducing(legend=False, marker='s') - #m.plot_errorbars_trainset() + m.plot_inducing(legend=False, marker="s") + # m.plot_errorbars_trainset() m.plot_data_error() - for do_test in _image_comparison(baseline_images=['gp_2d_{}'.format(sub) for sub in ["data", "mean", - 'inducing', - #'out_error', - 'in_error', - ]], extensions=extensions): - yield (do_test, ) + for do_test in _image_comparison( + baseline_images=[ + "gp_2d_{}".format(sub) + for sub in [ + "data", + "mean", + "inducing", + #'out_error', + "in_error", + ] + ], + extensions=extensions, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_threed(): np.random.seed(11111) import matplotlib - matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False - X = np.random.uniform(-2, 2, (40, 2)) - f = .2 * np.sin(1.3*X[:,[0]]) + 1.3*np.cos(2*X[:,[1]]) - Y = f+np.random.normal(0, .1, f.shape) - m = GPy.models.SparseGPRegression(X, Y) - m.likelihood.variance = .1 - #m.optimize() - m.plot_samples(projection='3d', samples=1) - m.plot_samples(projection='3d', plot_raw=False, samples=1) - plt.close('all') - m.plot_data(projection='3d') - m.plot_mean(projection='3d', rstride=10, cstride=10) - m.plot_inducing(projection='3d') - #m.plot_errorbars_trainset(projection='3d') - for do_test in _image_comparison(baseline_images=[ - 'gp_3d_{}'.format(sub) for sub in ["data", "mean", 'inducing', - ]], extensions=extensions): - yield (do_test, ) + matplotlib.rcParams.update(matplotlib.rcParamsDefault) + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False + X = np.random.uniform(-2, 2, (40, 2)) + f = 0.2 * np.sin(1.3 * X[:, [0]]) + 1.3 * np.cos(2 * X[:, [1]]) + Y = f + np.random.normal(0, 0.1, f.shape) + m = GPy.models.SparseGPRegression(X, Y) + m.likelihood.variance = 0.1 + # m.optimize() + m.plot_samples(projection="3d", samples=1) + m.plot_samples(projection="3d", plot_raw=False, samples=1) + plt.close("all") + m.plot_data(projection="3d") + m.plot_mean(projection="3d", rstride=10, cstride=10) + m.plot_inducing(projection="3d") + # m.plot_errorbars_trainset(projection='3d') + for do_test in _image_comparison( + baseline_images=[ + "gp_3d_{}".format(sub) + for sub in [ + "data", + "mean", + "inducing", + ] + ], + extensions=extensions, + ): + yield (do_test,) + +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_sparse(): np.random.seed(11111) import matplotlib + matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False X = np.random.uniform(-2, 2, (40, 1)) - f = .2 * np.sin(1.3*X) + 1.3*np.cos(2*X) - Y = f+np.random.normal(0, .1, f.shape) - m = GPy.models.SparseGPRegression(X, Y, X_variance=np.ones_like(X)*0.1) - #m.optimize() - #m.plot_inducing() + f = 0.2 * np.sin(1.3 * X) + 1.3 * np.cos(2 * X) + Y = f + np.random.normal(0, 0.1, f.shape) + m = GPy.models.SparseGPRegression(X, Y, X_variance=np.ones_like(X) * 0.1) + # m.optimize() + # m.plot_inducing() _, ax = plt.subplots() m.plot_data(ax=ax) m.plot_data_error(ax=ax) - for do_test in _image_comparison(baseline_images=['sparse_gp_{}'.format(sub) for sub in ['data_error']], extensions=extensions): - yield (do_test, ) + for do_test in _image_comparison( + baseline_images=["sparse_gp_{}".format(sub) for sub in ["data_error"]], + extensions=extensions, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_classification(): np.random.seed(11111) import matplotlib + matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False X = np.random.uniform(-2, 2, (40, 1)) - f = .2 * np.sin(1.3*X) + 1.3*np.cos(2*X) - Y = f+np.random.normal(0, .1, f.shape) - m = GPy.models.GPClassification(X, Y>Y.mean()) - #m.optimize() + f = 0.2 * np.sin(1.3 * X) + 1.3 * np.cos(2 * X) + Y = f + np.random.normal(0, 0.1, f.shape) + m = GPy.models.GPClassification(X, Y > Y.mean()) + # m.optimize() _, ax = plt.subplots() m.plot(plot_raw=False, apply_link=False, ax=ax, samples=3) m.plot_errorbars_trainset(plot_raw=False, apply_link=False, ax=ax) @@ -383,127 +526,166 @@ def test_classification(): _, ax = plt.subplots() m.plot(plot_raw=True, apply_link=True, ax=ax, samples=3) m.plot_errorbars_trainset(plot_raw=True, apply_link=True, ax=ax) - for do_test in _image_comparison(baseline_images=['gp_class_{}'.format(sub) for sub in ["likelihood", "raw", 'raw_link']], extensions=extensions): - yield (do_test, ) - + for do_test in _image_comparison( + baseline_images=[ + "gp_class_{}".format(sub) for sub in ["likelihood", "raw", "raw_link"] + ], + extensions=extensions, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_sparse_classification(): np.random.seed(11111) import matplotlib + matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False X = np.random.uniform(-2, 2, (40, 1)) - f = .2 * np.sin(1.3*X) + 1.3*np.cos(2*X) - Y = f+np.random.normal(0, .1, f.shape) - m = GPy.models.SparseGPClassification(X, Y>Y.mean()) - #m.optimize() + f = 0.2 * np.sin(1.3 * X) + 1.3 * np.cos(2 * X) + Y = f + np.random.normal(0, 0.1, f.shape) + m = GPy.models.SparseGPClassification(X, Y > Y.mean()) + # m.optimize() m.plot(plot_raw=False, apply_link=False, samples_likelihood=3) np.random.seed(111) m.plot(plot_raw=True, apply_link=False, samples=3) np.random.seed(111) m.plot(plot_raw=True, apply_link=True, samples=3) - for do_test in _image_comparison(baseline_images=['sparse_gp_class_{}'.format(sub) for sub in ["likelihood", "raw", 'raw_link']], extensions=extensions, rtol=2): - yield (do_test, ) + for do_test in _image_comparison( + baseline_images=[ + "sparse_gp_class_{}".format(sub) + for sub in ["likelihood", "raw", "raw_link"] + ], + extensions=extensions, + rtol=2, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_gplvm(): from GPy.models import GPLVM + np.random.seed(12345) matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False - #Q = 3 + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False + # Q = 3 # Define dataset - #N = 60 - #k1 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,10,10,0.1,0.1]), ARD=True) - #k2 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,0.1,10,0.1,10]), ARD=True) - #k3 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[0.1,0.1,10,10,10]), ARD=True) - #X = np.random.normal(0, 1, (N, 5)) - #A = np.random.multivariate_normal(np.zeros(N), k1.K(X), Q).T - #B = np.random.multivariate_normal(np.zeros(N), k2.K(X), Q).T - #C = np.random.multivariate_normal(np.zeros(N), k3.K(X), Q).T - #Y = np.vstack((A,B,C)) - #labels = np.hstack((np.zeros(A.shape[0]), np.ones(B.shape[0]), np.ones(C.shape[0])*2)) + # N = 60 + # k1 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,10,10,0.1,0.1]), ARD=True) + # k2 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,0.1,10,0.1,10]), ARD=True) + # k3 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[0.1,0.1,10,10,10]), ARD=True) + # X = np.random.normal(0, 1, (N, 5)) + # A = np.random.multivariate_normal(np.zeros(N), k1.K(X), Q).T + # B = np.random.multivariate_normal(np.zeros(N), k2.K(X), Q).T + # C = np.random.multivariate_normal(np.zeros(N), k3.K(X), Q).T + # Y = np.vstack((A,B,C)) + # labels = np.hstack((np.zeros(A.shape[0]), np.ones(B.shape[0]), np.ones(C.shape[0])*2)) - #k = RBF(Q, ARD=True, lengthscale=2) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) - pars = np.load(os.path.join(basedir, 'b-gplvm-save.npz')) - Y = pars['Y'] - Q = pars['Q'] - labels = pars['labels'] + # k = RBF(Q, ARD=True, lengthscale=2) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) + pars = np.load(os.path.join(basedir, "b-gplvm-save.npz")) + Y = pars["Y"] + Q = pars["Q"] + labels = pars["labels"] import warnings + with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') # always print + warnings.simplefilter("always") # always print m = GPLVM(Y, Q, initialize=False) m.update_model(False) m.initialize_parameter() - m[:] = pars['gplvm_p'] + m[:] = pars["gplvm_p"] m.update_model(True) - #m.optimize(messages=0) + # m.optimize(messages=0) np.random.seed(111) m.plot_latent(labels=labels) np.random.seed(111) - m.plot_scatter(projection='3d', labels=labels) + m.plot_scatter(projection="3d", labels=labels) np.random.seed(111) m.plot_magnification(labels=labels) m.plot_steepest_gradient_map(resolution=10, data_labels=labels) - for do_test in _image_comparison(baseline_images=['gplvm_{}'.format(sub) for sub in ["latent", "latent_3d", "magnification", 'gradient']], - extensions=extensions, - tol=12): - yield (do_test, ) + for do_test in _image_comparison( + baseline_images=[ + "gplvm_{}".format(sub) + for sub in ["latent", "latent_3d", "magnification", "gradient"] + ], + extensions=extensions, + tol=12, + ): + yield (do_test,) +@pytest.mark.skipif( + matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" +) def test_bayesian_gplvm(): from ..models import BayesianGPLVM + np.random.seed(12345) matplotlib.rcParams.update(matplotlib.rcParamsDefault) - #matplotlib.rcParams[u'figure.figsize'] = (4,3) - matplotlib.rcParams[u'text.usetex'] = False - #Q = 3 + # matplotlib.rcParams[u'figure.figsize'] = (4,3) + matplotlib.rcParams["text.usetex"] = False + # Q = 3 # Define dataset - #N = 10 - #k1 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,10,10,0.1,0.1]), ARD=True) - #k2 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,0.1,10,0.1,10]), ARD=True) - #k3 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[0.1,0.1,10,10,10]), ARD=True) - #X = np.random.normal(0, 1, (N, 5)) - #A = np.random.multivariate_normal(np.zeros(N), k1.K(X), Q).T - #B = np.random.multivariate_normal(np.zeros(N), k2.K(X), Q).T - #C = np.random.multivariate_normal(np.zeros(N), k3.K(X), Q).T + # N = 10 + # k1 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,10,10,0.1,0.1]), ARD=True) + # k2 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[10,0.1,10,0.1,10]), ARD=True) + # k3 = GPy.kern.RBF(5, variance=1, lengthscale=1./np.random.dirichlet(np.r_[0.1,0.1,10,10,10]), ARD=True) + # X = np.random.normal(0, 1, (N, 5)) + # A = np.random.multivariate_normal(np.zeros(N), k1.K(X), Q).T + # B = np.random.multivariate_normal(np.zeros(N), k2.K(X), Q).T + # C = np.random.multivariate_normal(np.zeros(N), k3.K(X), Q).T - #Y = np.vstack((A,B,C)) - #labels = np.hstack((np.zeros(A.shape[0]), np.ones(B.shape[0]), np.ones(C.shape[0])*2)) + # Y = np.vstack((A,B,C)) + # labels = np.hstack((np.zeros(A.shape[0]), np.ones(B.shape[0]), np.ones(C.shape[0])*2)) - #k = RBF(Q, ARD=True, lengthscale=2) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) - pars = np.load(os.path.join(basedir, 'b-gplvm-save.npz')) - Y = pars['Y'] - Q = pars['Q'] - labels = pars['labels'] + # k = RBF(Q, ARD=True, lengthscale=2) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) + pars = np.load(os.path.join(basedir, "b-gplvm-save.npz")) + Y = pars["Y"] + Q = pars["Q"] + labels = pars["labels"] import warnings + with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') # always print + warnings.simplefilter("always") # always print m = BayesianGPLVM(Y, Q, initialize=False) m.update_model(False) m.initialize_parameter() - m[:] = pars['bgplvm_p'] + m[:] = pars["bgplvm_p"] m.update_model(True) - #m.optimize(messages=0) + # m.optimize(messages=0) np.random.seed(111) - m.plot_inducing(projection='2d') + m.plot_inducing(projection="2d") np.random.seed(111) - m.plot_inducing(projection='3d') + m.plot_inducing(projection="3d") np.random.seed(111) - m.plot_latent(projection='2d', labels=labels) + m.plot_latent(projection="2d", labels=labels) np.random.seed(111) - m.plot_scatter(projection='3d', labels=labels) + m.plot_scatter(projection="3d", labels=labels) np.random.seed(111) m.plot_magnification(labels=labels) np.random.seed(111) m.plot_steepest_gradient_map(resolution=10, data_labels=labels) - for do_test in _image_comparison(baseline_images=['bayesian_gplvm_{}'.format(sub) for sub in ["inducing", "inducing_3d", "latent", "latent_3d", "magnification", 'gradient']], extensions=extensions): - yield (do_test, ) - -if __name__ == '__main__': - import nose - nose.main(defaultTest='./plotting_tests.py') + for do_test in _image_comparison( + baseline_images=[ + "bayesian_gplvm_{}".format(sub) + for sub in [ + "inducing", + "inducing_3d", + "latent", + "latent_3d", + "magnification", + "gradient", + ] + ], + extensions=extensions, + ): + yield (do_test,) From 4e5a4fc6050fa40a48c7e298023c80688ae94bfc Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:47:30 +0200 Subject: [PATCH 044/101] format on save --- GPy/testing/prior_tests.py | 101 +++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/GPy/testing/prior_tests.py b/GPy/testing/prior_tests.py index 83dfd0d6..4821584c 100644 --- a/GPy/testing/prior_tests.py +++ b/GPy/testing/prior_tests.py @@ -5,77 +5,78 @@ import unittest import numpy as np import GPy + class PriorTests(unittest.TestCase): def test_studentT(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] studentT = GPy.priors.StudentT(1, 2, 4) - + m = GPy.models.SparseGPRegression(X, y) m.Z.set_prior(studentT) # setting a StudentT prior on non-negative parameters # should raise an assertionerror. self.assertRaises(AssertionError, m.rbf.set_prior, studentT) - + # The gradients need to be checked - self.assertTrue(m.checkgrad()) - + assert m.checkgrad() + # Check the singleton pattern: - self.assertIs(studentT, GPy.priors.StudentT(1,2,4)) - self.assertIsNot(studentT, GPy.priors.StudentT(2,2,4)) - + self.assertIs(studentT, GPy.priors.StudentT(1, 2, 4)) + self.assertIsNot(studentT, GPy.priors.StudentT(2, 2, 4)) + def test_lognormal(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) lognormal = GPy.priors.LogGaussian(1, 2) m.rbf.set_prior(lognormal) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_Gamma(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) Gamma = GPy.priors.Gamma(1, 1) m.rbf.set_prior(Gamma) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_InverseGamma(self): # Test that this prior object can be instantiated and performs its basic functions # in integration. - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) InverseGamma = GPy.priors.InverseGamma(1, 1) m.rbf.set_prior(InverseGamma) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_incompatibility(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) gaussian = GPy.priors.Gaussian(1, 1) @@ -84,55 +85,55 @@ class PriorTests(unittest.TestCase): self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) def test_set_prior(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) gaussian = GPy.priors.Gaussian(1, 1) - #m.rbf.set_prior(gaussian) + # m.rbf.set_prior(gaussian) # setting a Gaussian prior on non-negative parameters # should raise an assertionerror. self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) def test_uniform(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.SparseGPRegression(X, y) uniform = GPy.priors.Uniform(0, 2) m.rbf.set_prior(uniform) m.randomize() - self.assertTrue(m.checkgrad()) - + assert m.checkgrad() + m.Z.set_prior(uniform) m.randomize() - self.assertTrue(m.checkgrad()) - + assert m.checkgrad() + m.Z.unconstrain() uniform = GPy.priors.Uniform(-1, 10) m.Z.set_prior(uniform) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() m.Z.constrain_negative() uniform = GPy.priors.Uniform(-1, 0) m.Z.set_prior(uniform) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_set_gaussian_for_reals(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.SparseGPRegression(X, y) @@ -140,16 +141,15 @@ class PriorTests(unittest.TestCase): m.Z.set_prior(gaussian) # setting a Gaussian prior on non-negative parameters # should raise an assertionerror. - #self.assertRaises(AssertionError, m.Z.set_prior, gaussian) - self.assertTrue(m.checkgrad()) - + # self.assertRaises(AssertionError, m.Z.set_prior, gaussian) + assert m.checkgrad() def test_fixed_domain_check(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) @@ -160,11 +160,11 @@ class PriorTests(unittest.TestCase): self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) def test_fixed_domain_check1(self): - xmin, xmax = 1, 2.5*np.pi + xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 X = np.linspace(xmin, xmax, 500) - y = b*X + C + 1*np.sin(X) - y += 0.05*np.random.randn(len(X)) + y = b * X + C + 1 * np.sin(X) + y += 0.05 * np.random.randn(len(X)) X, y = X[:, None], y[:, None] m = GPy.models.GPRegression(X, y) @@ -174,6 +174,7 @@ class PriorTests(unittest.TestCase): # should raise an assertionerror. self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) + if __name__ == "__main__": print("Running unit tests, please be (very) patient...") unittest.main() From 65d919da06152feaef7ce20d6b9e6ef9a0354d9b Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:49:25 +0200 Subject: [PATCH 045/101] migrate prior_tests to pytest --- GPy/testing/prior_tests.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/GPy/testing/prior_tests.py b/GPy/testing/prior_tests.py index 4821584c..eb12a8d1 100644 --- a/GPy/testing/prior_tests.py +++ b/GPy/testing/prior_tests.py @@ -1,12 +1,11 @@ # Copyright (c) 2012, GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) - -import unittest +import pytest import numpy as np import GPy -class PriorTests(unittest.TestCase): +class TestPrior: def test_studentT(self): xmin, xmax = 1, 2.5 * np.pi b, C, SNR = 1, 0, 0.1 @@ -21,14 +20,16 @@ class PriorTests(unittest.TestCase): # setting a StudentT prior on non-negative parameters # should raise an assertionerror. - self.assertRaises(AssertionError, m.rbf.set_prior, studentT) + + with pytest.raises(AssertionError): + m.rbf.set_prior(studentT) # The gradients need to be checked assert m.checkgrad() # Check the singleton pattern: - self.assertIs(studentT, GPy.priors.StudentT(1, 2, 4)) - self.assertIsNot(studentT, GPy.priors.StudentT(2, 2, 4)) + assert studentT is GPy.priors.StudentT(1, 2, 4) + assert studentT is not GPy.priors.StudentT(2, 2, 4) def test_lognormal(self): xmin, xmax = 1, 2.5 * np.pi @@ -82,7 +83,8 @@ class PriorTests(unittest.TestCase): gaussian = GPy.priors.Gaussian(1, 1) # setting a Gaussian prior on non-negative parameters # should raise an assertionerror. - self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) + with pytest.raises(AssertionError): + m.rbf.set_prior(gaussian) def test_set_prior(self): xmin, xmax = 1, 2.5 * np.pi @@ -97,7 +99,8 @@ class PriorTests(unittest.TestCase): # m.rbf.set_prior(gaussian) # setting a Gaussian prior on non-negative parameters # should raise an assertionerror. - self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) + with pytest.raises(AssertionError): + m.rbf.set_prior(gaussian) def test_uniform(self): xmin, xmax = 1, 2.5 * np.pi @@ -157,7 +160,8 @@ class PriorTests(unittest.TestCase): gaussian = GPy.priors.Gaussian(1, 1) # setting a Gaussian prior on non-negative parameters # should raise an assertionerror. - self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) + with pytest.raises(AssertionError): + m.rbf.set_prior(gaussian) def test_fixed_domain_check1(self): xmin, xmax = 1, 2.5 * np.pi @@ -172,9 +176,5 @@ class PriorTests(unittest.TestCase): gaussian = GPy.priors.Gaussian(1, 1) # setting a Gaussian prior on non-negative parameters # should raise an assertionerror. - self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) - - -if __name__ == "__main__": - print("Running unit tests, please be (very) patient...") - unittest.main() + with pytest.raises(AssertionError): + m.rbf.set_prior(gaussian) From 97741d6b412d50959b9d7f33a0a29c1fa3aa8c43 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:49:55 +0200 Subject: [PATCH 046/101] format on save --- GPy/testing/quadrature_tests.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/GPy/testing/quadrature_tests.py b/GPy/testing/quadrature_tests.py index e519d87e..f6b361e9 100644 --- a/GPy/testing/quadrature_tests.py +++ b/GPy/testing/quadrature_tests.py @@ -1,9 +1,6 @@ from __future__ import print_function, division import numpy as np -import GPy -import warnings -from ..util.quad_integrate import quadgk_int, quadvgk - +from ..util.quad_integrate import quadgk_int, quadvgk class QuadTests(np.testing.TestCase): @@ -12,12 +9,14 @@ class QuadTests(np.testing.TestCase): we will take a function which can be integrated analytically and check if quadgk result is similar or not! through this file we can test how numerically accurate quadrature implementation in native numpy or manual code is. """ + def setUp(self): pass def test_infinite_quad(self): def f(x): - return np.exp(-0.5*x**2)*np.power(x,np.arange(3)[:,None]) + return np.exp(-0.5 * x**2) * np.power(x, np.arange(3)[:, None]) + quad_int_val = quadgk_int(f) real_val = np.sqrt(np.pi * 2) np.testing.assert_almost_equal(real_val, quad_int_val[0], decimal=7) @@ -25,15 +24,18 @@ class QuadTests(np.testing.TestCase): def test_finite_quad(self): def f2(x): return x**2 - quad_int_val = quadvgk(f2, 1.,2.) - real_val = 7/3. + + quad_int_val = quadvgk(f2, 1.0, 2.0) + real_val = 7 / 3.0 np.testing.assert_almost_equal(real_val, quad_int_val, decimal=5) -if __name__ == '__main__': + +if __name__ == "__main__": + def f(x): - return np.exp(-0.5 * x ** 2) * np.power(x, np.arange(3)[:, None]) + return np.exp(-0.5 * x**2) * np.power(x, np.arange(3)[:, None]) quad_int_val = quadgk_int(f) - real_val = np.sqrt(np.pi*2) + real_val = np.sqrt(np.pi * 2) np.testing.assert_almost_equal(real_val, quad_int_val[0], decimal=7) print(quadgk_int(f)) From de670f8bcb5bac11d60bc74e5bde8e4e9d8557d9 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:50:44 +0200 Subject: [PATCH 047/101] migrate quadrature_tests to pytest --- GPy/testing/quadrature_tests.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/GPy/testing/quadrature_tests.py b/GPy/testing/quadrature_tests.py index f6b361e9..5690edfb 100644 --- a/GPy/testing/quadrature_tests.py +++ b/GPy/testing/quadrature_tests.py @@ -3,16 +3,13 @@ import numpy as np from ..util.quad_integrate import quadgk_int, quadvgk -class QuadTests(np.testing.TestCase): +class TestQuad: """ test file for checking implementation of gaussian-kronrod quadrature. we will take a function which can be integrated analytically and check if quadgk result is similar or not! through this file we can test how numerically accurate quadrature implementation in native numpy or manual code is. """ - def setUp(self): - pass - def test_infinite_quad(self): def f(x): return np.exp(-0.5 * x**2) * np.power(x, np.arange(3)[:, None]) From 5fde9d2edd4f5910ff999c5534f5e021f6342028 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:51:04 +0200 Subject: [PATCH 048/101] format on save --- GPy/testing/rv_transformation_tests.py | 63 +++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/GPy/testing/rv_transformation_tests.py b/GPy/testing/rv_transformation_tests.py index f526d3cf..d88f2505 100644 --- a/GPy/testing/rv_transformation_tests.py +++ b/GPy/testing/rv_transformation_tests.py @@ -4,7 +4,6 @@ Test if hyperparameters in models are properly transformed. """ -import unittest import numpy as np import scipy.stats as st import GPy @@ -14,25 +13,25 @@ class TestModel(GPy.core.Model): """ A simple GPy model with one parameter. """ - def __init__(self, theta=1.): - super(TestModel, self).__init__('test_model') - theta = GPy.core.Param('theta', theta) + + def __init__(self, theta=1.0): + super(TestModel, self).__init__("test_model") + theta = GPy.core.Param("theta", theta) self.link_parameter(theta) def log_likelihood(self): - return 0. + return 0.0 class RVTransformationTestCase(unittest.TestCase): - def _test_trans(self, trans): m = TestModel() - prior = GPy.priors.LogGaussian(.5, 0.1) + prior = GPy.priors.LogGaussian(0.5, 0.1) m.theta.set_prior(prior) m.theta.unconstrain() m.theta.constrain(trans) # The PDF of the transformed variables - p_phi = lambda phi : np.exp(-m._objective_grads(phi)[0]) + p_phi = lambda phi: np.exp(-m._objective_grads(phi)[0]) # To the empirical PDF of: theta_s = prior.rvs(1e5) phi_s = trans.finv(theta_s) @@ -43,23 +42,25 @@ class RVTransformationTestCase(unittest.TestCase): # The transformed PDF of phi should be this: pdf_phi = np.array([p_phi(p) for p in phi]) # UNCOMMENT TO SEE GRAPHICAL COMPARISON - #import matplotlib.pyplot as plt - #fig, ax = plt.subplots() - #ax.hist(phi_s, normed=True, bins=100, alpha=0.25, label='Histogram') - #ax.plot(phi, kde(phi), '--', linewidth=2, label='Kernel Density Estimation') - #ax.plot(phi, pdf_phi, ':', linewidth=2, label='Transformed PDF') - #ax.set_xlabel(r'transformed $\theta$', fontsize=16) - #ax.set_ylabel('PDF', fontsize=16) - #plt.legend(loc='best') - #plt.show(block=True) + # import matplotlib.pyplot as plt + # fig, ax = plt.subplots() + # ax.hist(phi_s, normed=True, bins=100, alpha=0.25, label='Histogram') + # ax.plot(phi, kde(phi), '--', linewidth=2, label='Kernel Density Estimation') + # ax.plot(phi, pdf_phi, ':', linewidth=2, label='Transformed PDF') + # ax.set_xlabel(r'transformed $\theta$', fontsize=16) + # ax.set_ylabel('PDF', fontsize=16) + # plt.legend(loc='best') + # plt.show(block=True) # END OF PLOT # The following test cannot be very accurate - self.assertTrue(np.linalg.norm(pdf_phi - kde(phi)) / np.linalg.norm(kde(phi)) <= 1e-1) + self.assertTrue( + np.linalg.norm(pdf_phi - kde(phi)) / np.linalg.norm(kde(phi)) <= 1e-1 + ) def _test_grad(self, trans): np.random.seed(1234) - m = TestModel(np.random.uniform(.5, 1.5, 20)) - prior = GPy.priors.LogGaussian(.5, 0.1) + m = TestModel(np.random.uniform(0.5, 1.5, 20)) + prior = GPy.priors.LogGaussian(0.5, 0.1) m.theta.set_prior(prior) m.theta.constrain(trans) m.randomize() @@ -70,26 +71,26 @@ class RVTransformationTestCase(unittest.TestCase): self._test_trans(GPy.constraints.Logexp()) @unittest.skip("Gradient not checking right, @jameshensman what is going on here?") - def test_Logexp_grad(self): + def test_Logexp_grad(self): self._test_grad(GPy.constraints.Logexp()) - + def test_Exponent(self): self._test_trans(GPy.constraints.Exponent()) - + @unittest.skip("Gradient not checking right, @jameshensman what is going on here?") def test_Exponent_grad(self): self._test_grad(GPy.constraints.Exponent()) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() quit() m = TestModel() - prior = GPy.priors.LogGaussian(0., .9) + prior = GPy.priors.LogGaussian(0.0, 0.9) m.theta.set_prior(prior) # The following should return the PDF in terms of the transformed quantities - p_phi = lambda phi : np.exp(-m._objective_grads(phi)[0]) + p_phi = lambda phi: np.exp(-m._objective_grads(phi)[0]) # Let's look at the transformation phi = log(exp(theta - 1)) trans = GPy.constraints.Exponent() @@ -103,14 +104,14 @@ if __name__ == '__main__': # Transform it to the new variables phi_s = trans.finv(theta_s) # And draw their histogram - ax.hist(phi_s, normed=True, bins=100, alpha=0.25, label='Empirical') + ax.hist(phi_s, normed=True, bins=100, alpha=0.25, label="Empirical") # This is to be compared to the PDF of the model expressed in terms of these new # variables - ax.plot(phi, [p_phi(p) for p in phi], label='Transformed PDF', linewidth=2) + ax.plot(phi, [p_phi(p) for p in phi], label="Transformed PDF", linewidth=2) ax.set_xlim(-3, 10) - ax.set_xlabel(r'transformed $\theta$', fontsize=16) - ax.set_ylabel('PDF', fontsize=16) - plt.legend(loc='best') + ax.set_xlabel(r"transformed $\theta$", fontsize=16) + ax.set_ylabel("PDF", fontsize=16) + plt.legend(loc="best") # Now let's test the gradients m.checkgrad(verbose=True) # And show the plot From ca2092f12ed6fea6015a1cbdf7a6dff3c5df9ecd Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:53:26 +0200 Subject: [PATCH 049/101] migrate rv_transformation_tests to pytest --- GPy/testing/rv_transformation_tests.py | 54 +++++--------------------- 1 file changed, 10 insertions(+), 44 deletions(-) diff --git a/GPy/testing/rv_transformation_tests.py b/GPy/testing/rv_transformation_tests.py index d88f2505..72aab90d 100644 --- a/GPy/testing/rv_transformation_tests.py +++ b/GPy/testing/rv_transformation_tests.py @@ -3,7 +3,7 @@ Test if hyperparameters in models are properly transformed. """ - +import pytest import numpy as np import scipy.stats as st import GPy @@ -23,7 +23,7 @@ class TestModel(GPy.core.Model): return 0.0 -class RVTransformationTestCase(unittest.TestCase): +class TestRVTransformation: def _test_trans(self, trans): m = TestModel() prior = GPy.priors.LogGaussian(0.5, 0.1) @@ -53,9 +53,7 @@ class RVTransformationTestCase(unittest.TestCase): # plt.show(block=True) # END OF PLOT # The following test cannot be very accurate - self.assertTrue( - np.linalg.norm(pdf_phi - kde(phi)) / np.linalg.norm(kde(phi)) <= 1e-1 - ) + assert np.linalg.norm(pdf_phi - kde(phi)) / np.linalg.norm(kde(phi)) <= 1e-1 def _test_grad(self, trans): np.random.seed(1234) @@ -65,54 +63,22 @@ class RVTransformationTestCase(unittest.TestCase): m.theta.constrain(trans) m.randomize() print(m) - self.assertTrue(m.checkgrad(1)) + assert m.checkgrad(1) def test_Logexp(self): self._test_trans(GPy.constraints.Logexp()) - @unittest.skip("Gradient not checking right, @jameshensman what is going on here?") + @pytest.mark.skip( + "Gradient not checking right, @jameshensman what is going on here?" + ) def test_Logexp_grad(self): self._test_grad(GPy.constraints.Logexp()) def test_Exponent(self): self._test_trans(GPy.constraints.Exponent()) - @unittest.skip("Gradient not checking right, @jameshensman what is going on here?") + @pytest.mark.skip( + "Gradient not checking right, @jameshensman what is going on here?" + ) def test_Exponent_grad(self): self._test_grad(GPy.constraints.Exponent()) - - -if __name__ == "__main__": - unittest.main() - quit() - m = TestModel() - prior = GPy.priors.LogGaussian(0.0, 0.9) - m.theta.set_prior(prior) - - # The following should return the PDF in terms of the transformed quantities - p_phi = lambda phi: np.exp(-m._objective_grads(phi)[0]) - - # Let's look at the transformation phi = log(exp(theta - 1)) - trans = GPy.constraints.Exponent() - m.theta.constrain(trans) - # Plot the transformed probability density - phi = np.linspace(-8, 8, 100) - fig, ax = plt.subplots() - # Let's draw some samples of theta and transform them so that we see - # which one is right - theta_s = prior.rvs(10000) - # Transform it to the new variables - phi_s = trans.finv(theta_s) - # And draw their histogram - ax.hist(phi_s, normed=True, bins=100, alpha=0.25, label="Empirical") - # This is to be compared to the PDF of the model expressed in terms of these new - # variables - ax.plot(phi, [p_phi(p) for p in phi], label="Transformed PDF", linewidth=2) - ax.set_xlim(-3, 10) - ax.set_xlabel(r"transformed $\theta$", fontsize=16) - ax.set_ylabel("PDF", fontsize=16) - plt.legend(loc="best") - # Now let's test the gradients - m.checkgrad(verbose=True) - # And show the plot - plt.show(block=True) From 96d8ac0975d67e85f8b7923d87b5ef45c4a4256a Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:54:20 +0200 Subject: [PATCH 050/101] format on save --- GPy/testing/serialization_tests.py | 396 +++++++++++++++++++++-------- 1 file changed, 283 insertions(+), 113 deletions(-) diff --git a/GPy/testing/serialization_tests.py b/GPy/testing/serialization_tests.py index 93ec4b2d..f2af89d3 100644 --- a/GPy/testing/serialization_tests.py +++ b/GPy/testing/serialization_tests.py @@ -1,32 +1,39 @@ -''' +""" Created on 20 April 2017 @author: pgmoren -''' -import unittest, itertools -#import cPickle as pickle -import pickle +""" import numpy as np -import tempfile import GPy -from nose import SkipTest -import numpy as np import os + fixed_seed = 11 class Test(unittest.TestCase): def test_serialize_deserialize_kernels(self): - k1 = GPy.kern.RBF(2, variance=1.0, lengthscale=[1.0,1.0], ARD=True) - k2 = GPy.kern.RatQuad(2, variance=2.0, lengthscale=1.0, power=2.0, active_dims = [0,1]) - k3 = GPy.kern.Bias(2, variance=2.0, active_dims = [1,0]) - k4 = GPy.kern.StdPeriodic(2, variance=2.0, lengthscale=1.0, period=1.0, active_dims = [1,1]) - k5 = GPy.kern.Linear(2, variances=[2.0, 1.0], ARD=True, active_dims = [1,1]) - k6 = GPy.kern.Exponential(2, variance=1., lengthscale=2) - k7 = GPy.kern.Matern32(2, variance=1.0, lengthscale=[1.0,3.0], ARD=True, active_dims = [1,1]) - k8 = GPy.kern.Matern52(2, variance=2.0, lengthscale=[2.0,1.0], ARD=True, active_dims = [1,0]) - k9 = GPy.kern.ExpQuad(2, variance=3.0, lengthscale=[1.0,2.0], ARD=True, active_dims = [0,1]) - k10 = GPy.kern.OU(2, variance=2.0, lengthscale=[2.0, 1.0], ARD=True, active_dims=[1, 0]) + k1 = GPy.kern.RBF(2, variance=1.0, lengthscale=[1.0, 1.0], ARD=True) + k2 = GPy.kern.RatQuad( + 2, variance=2.0, lengthscale=1.0, power=2.0, active_dims=[0, 1] + ) + k3 = GPy.kern.Bias(2, variance=2.0, active_dims=[1, 0]) + k4 = GPy.kern.StdPeriodic( + 2, variance=2.0, lengthscale=1.0, period=1.0, active_dims=[1, 1] + ) + k5 = GPy.kern.Linear(2, variances=[2.0, 1.0], ARD=True, active_dims=[1, 1]) + k6 = GPy.kern.Exponential(2, variance=1.0, lengthscale=2) + k7 = GPy.kern.Matern32( + 2, variance=1.0, lengthscale=[1.0, 3.0], ARD=True, active_dims=[1, 1] + ) + k8 = GPy.kern.Matern52( + 2, variance=2.0, lengthscale=[2.0, 1.0], ARD=True, active_dims=[1, 0] + ) + k9 = GPy.kern.ExpQuad( + 2, variance=3.0, lengthscale=[1.0, 2.0], ARD=True, active_dims=[0, 1] + ) + k10 = GPy.kern.OU( + 2, variance=2.0, lengthscale=[2.0, 1.0], ARD=True, active_dims=[1, 0] + ) k11 = k1 + k1.copy() + k2 + k3 + k4 + k5 + k6 k12 = k1 * k2 * k2.copy() * k3 * k4 * k5 k13 = (k1 + k2) * (k3 + k4 + k5) @@ -34,21 +41,23 @@ class Test(unittest.TestCase): k15 = ((k1 + k2) * k3) + k4 * k5 + k8 * k10 k16 = ((k1 * k2) * k3) + k4 * k5 + k8 + k9 - k_list = [k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16] + k_list = [k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16] for kk in k_list: kk_dict = kk.to_dict() kk_r = GPy.kern.Kern.from_dict(kk_dict) assert type(kk) == type(kk_r) np.testing.assert_array_equal(kk[:], kk_r[:]) - np.testing.assert_array_equal(np.array(kk.active_dims), np.array(kk_r.active_dims)) + np.testing.assert_array_equal( + np.array(kk.active_dims), np.array(kk_r.active_dims) + ) def test_serialize_deserialize_mappings(self): - m1 = GPy.mappings.Identity(3,2) - m2 = GPy.mappings.Constant(3,2,1) + m1 = GPy.mappings.Identity(3, 2) + m2 = GPy.mappings.Constant(3, 2, 1) m2_r = GPy.core.mapping.Mapping.from_dict(m2.to_dict()) np.testing.assert_array_equal(m2.C.values[:], m2_r.C.values[:]) - m3 = GPy.mappings.Linear(3,2) + m3 = GPy.mappings.Linear(3, 2) m3_r = GPy.core.mapping.Mapping.from_dict(m3.to_dict()) assert np.all(m3.A == m3_r.A) @@ -61,7 +70,9 @@ class Test(unittest.TestCase): assert type(mm.output_dim) == type(mm_r.output_dim) def test_serialize_deserialize_likelihoods(self): - l1 = GPy.likelihoods.Gaussian(GPy.likelihoods.link_functions.Identity(),variance=3.0) + l1 = GPy.likelihoods.Gaussian( + GPy.likelihoods.link_functions.Identity(), variance=3.0 + ) l1_r = GPy.likelihoods.likelihood.Likelihood.from_dict(l1.to_dict()) l2 = GPy.likelihoods.Bernoulli(GPy.likelihoods.link_functions.Probit()) l2_r = GPy.likelihoods.likelihood.Likelihood.from_dict(l2.to_dict()) @@ -87,138 +98,252 @@ class Test(unittest.TestCase): assert type(ll) == type(ll_r) def test_serialize_deserialize_inference_methods(self): - - e1 = GPy.inference.latent_function_inference.expectation_propagation.EP(ep_mode="nested") - e1.ga_approx_old = GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation(np.random.rand(10),np.random.rand(10)) + e1 = GPy.inference.latent_function_inference.expectation_propagation.EP( + ep_mode="nested" + ) + e1.ga_approx_old = GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation( + np.random.rand(10), np.random.rand(10) + ) e1._ep_approximation = [] - e1._ep_approximation.append(GPy.inference.latent_function_inference.expectation_propagation.posteriorParams(np.random.rand(10),np.random.rand(100).reshape((10,10)))) - e1._ep_approximation.append(GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation(np.random.rand(10),np.random.rand(10))) - e1._ep_approximation.append(GPy.inference.latent_function_inference.expectation_propagation.cavityParams(10)) + e1._ep_approximation.append( + GPy.inference.latent_function_inference.expectation_propagation.posteriorParams( + np.random.rand(10), np.random.rand(100).reshape((10, 10)) + ) + ) + e1._ep_approximation.append( + GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation( + np.random.rand(10), np.random.rand(10) + ) + ) + e1._ep_approximation.append( + GPy.inference.latent_function_inference.expectation_propagation.cavityParams( + 10 + ) + ) e1._ep_approximation[-1].v = np.random.rand(10) e1._ep_approximation[-1].tau = np.random.rand(10) e1._ep_approximation.append(np.random.rand(10)) - e1_r = GPy.inference.latent_function_inference.LatentFunctionInference.from_dict(e1.to_dict()) + e1_r = ( + GPy.inference.latent_function_inference.LatentFunctionInference.from_dict( + e1.to_dict() + ) + ) assert type(e1) == type(e1_r) - assert e1.epsilon==e1_r.epsilon - assert e1.eta==e1_r.eta - assert e1.delta==e1_r.delta - assert e1.always_reset==e1_r.always_reset - assert e1.max_iters==e1_r.max_iters - assert e1.ep_mode==e1_r.ep_mode - assert e1.parallel_updates==e1_r.parallel_updates + assert e1.epsilon == e1_r.epsilon + assert e1.eta == e1_r.eta + assert e1.delta == e1_r.delta + assert e1.always_reset == e1_r.always_reset + assert e1.max_iters == e1_r.max_iters + assert e1.ep_mode == e1_r.ep_mode + assert e1.parallel_updates == e1_r.parallel_updates - np.testing.assert_array_equal(e1.ga_approx_old.tau[:], e1_r.ga_approx_old.tau[:]) + np.testing.assert_array_equal( + e1.ga_approx_old.tau[:], e1_r.ga_approx_old.tau[:] + ) np.testing.assert_array_equal(e1.ga_approx_old.v[:], e1_r.ga_approx_old.v[:]) - np.testing.assert_array_equal(e1._ep_approximation[0].mu[:], e1_r._ep_approximation[0].mu[:]) - np.testing.assert_array_equal(e1._ep_approximation[0].Sigma[:], e1_r._ep_approximation[0].Sigma[:]) - np.testing.assert_array_equal(e1._ep_approximation[1].tau[:], e1_r._ep_approximation[1].tau[:]) - np.testing.assert_array_equal(e1._ep_approximation[1].v[:], e1_r._ep_approximation[1].v[:]) - np.testing.assert_array_equal(e1._ep_approximation[2].tau[:], e1_r._ep_approximation[2].tau[:]) - np.testing.assert_array_equal(e1._ep_approximation[2].v[:], e1_r._ep_approximation[2].v[:]) - np.testing.assert_array_equal(e1._ep_approximation[3][:], e1_r._ep_approximation[3][:]) + np.testing.assert_array_equal( + e1._ep_approximation[0].mu[:], e1_r._ep_approximation[0].mu[:] + ) + np.testing.assert_array_equal( + e1._ep_approximation[0].Sigma[:], e1_r._ep_approximation[0].Sigma[:] + ) + np.testing.assert_array_equal( + e1._ep_approximation[1].tau[:], e1_r._ep_approximation[1].tau[:] + ) + np.testing.assert_array_equal( + e1._ep_approximation[1].v[:], e1_r._ep_approximation[1].v[:] + ) + np.testing.assert_array_equal( + e1._ep_approximation[2].tau[:], e1_r._ep_approximation[2].tau[:] + ) + np.testing.assert_array_equal( + e1._ep_approximation[2].v[:], e1_r._ep_approximation[2].v[:] + ) + np.testing.assert_array_equal( + e1._ep_approximation[3][:], e1_r._ep_approximation[3][:] + ) - e2 = GPy.inference.latent_function_inference.expectation_propagation.EPDTC(ep_mode="nested") - e2.ga_approx_old = GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation(np.random.rand(10),np.random.rand(10)) + e2 = GPy.inference.latent_function_inference.expectation_propagation.EPDTC( + ep_mode="nested" + ) + e2.ga_approx_old = GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation( + np.random.rand(10), np.random.rand(10) + ) e2._ep_approximation = [] - e2._ep_approximation.append(GPy.inference.latent_function_inference.expectation_propagation.posteriorParamsDTC(np.random.rand(10),np.random.rand(10))) - e2._ep_approximation.append(GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation(np.random.rand(10),np.random.rand(10))) + e2._ep_approximation.append( + GPy.inference.latent_function_inference.expectation_propagation.posteriorParamsDTC( + np.random.rand(10), np.random.rand(10) + ) + ) + e2._ep_approximation.append( + GPy.inference.latent_function_inference.expectation_propagation.gaussianApproximation( + np.random.rand(10), np.random.rand(10) + ) + ) e2._ep_approximation.append(100.0) - e2_r = GPy.inference.latent_function_inference.LatentFunctionInference.from_dict(e2.to_dict()) + e2_r = ( + GPy.inference.latent_function_inference.LatentFunctionInference.from_dict( + e2.to_dict() + ) + ) assert type(e2) == type(e2_r) - assert e2.epsilon==e2_r.epsilon - assert e2.eta==e2_r.eta - assert e2.delta==e2_r.delta - assert e2.always_reset==e2_r.always_reset - assert e2.max_iters==e2_r.max_iters - assert e2.ep_mode==e2_r.ep_mode - assert e2.parallel_updates==e2_r.parallel_updates + assert e2.epsilon == e2_r.epsilon + assert e2.eta == e2_r.eta + assert e2.delta == e2_r.delta + assert e2.always_reset == e2_r.always_reset + assert e2.max_iters == e2_r.max_iters + assert e2.ep_mode == e2_r.ep_mode + assert e2.parallel_updates == e2_r.parallel_updates - np.testing.assert_array_equal(e2.ga_approx_old.tau[:], e2_r.ga_approx_old.tau[:]) + np.testing.assert_array_equal( + e2.ga_approx_old.tau[:], e2_r.ga_approx_old.tau[:] + ) np.testing.assert_array_equal(e2.ga_approx_old.v[:], e2_r.ga_approx_old.v[:]) - np.testing.assert_array_equal(e2._ep_approximation[0].mu[:], e2_r._ep_approximation[0].mu[:]) - np.testing.assert_array_equal(e2._ep_approximation[0].Sigma_diag[:], e2_r._ep_approximation[0].Sigma_diag[:]) - np.testing.assert_array_equal(e2._ep_approximation[1].tau[:], e2_r._ep_approximation[1].tau[:]) - np.testing.assert_array_equal(e2._ep_approximation[1].v[:], e2_r._ep_approximation[1].v[:]) - assert(e2._ep_approximation[2] == e2_r._ep_approximation[2]) + np.testing.assert_array_equal( + e2._ep_approximation[0].mu[:], e2_r._ep_approximation[0].mu[:] + ) + np.testing.assert_array_equal( + e2._ep_approximation[0].Sigma_diag[:], + e2_r._ep_approximation[0].Sigma_diag[:], + ) + np.testing.assert_array_equal( + e2._ep_approximation[1].tau[:], e2_r._ep_approximation[1].tau[:] + ) + np.testing.assert_array_equal( + e2._ep_approximation[1].v[:], e2_r._ep_approximation[1].v[:] + ) + assert e2._ep_approximation[2] == e2_r._ep_approximation[2] - e3 = GPy.inference.latent_function_inference.exact_gaussian_inference.ExactGaussianInference() - e3_r = GPy.inference.latent_function_inference.LatentFunctionInference.from_dict(e3.to_dict()) + e3 = ( + GPy.inference.latent_function_inference.exact_gaussian_inference.ExactGaussianInference() + ) + e3_r = ( + GPy.inference.latent_function_inference.LatentFunctionInference.from_dict( + e3.to_dict() + ) + ) assert type(e3) == type(e3_r) - def test_serialize_deserialize_GP(self): np.random.seed(fixed_seed) N = 20 - Nhalf = int(N/2) - X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[:, None] + Nhalf = int(N / 2) + X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ + :, None + ] Y = np.hstack([np.ones(Nhalf), np.zeros(Nhalf)])[:, None] kernel = GPy.kern.RBF(1) likelihood = GPy.likelihoods.Bernoulli() - inference_method=GPy.inference.latent_function_inference.expectation_propagation.EP(ep_mode="nested") - mean_function=None + inference_method = ( + GPy.inference.latent_function_inference.expectation_propagation.EP( + ep_mode="nested" + ) + ) + mean_function = None - m = GPy.core.GP(X=X, Y=Y, kernel=kernel, likelihood=likelihood, inference_method=inference_method, mean_function=mean_function, normalizer=True, name='gp_classification') + m = GPy.core.GP( + X=X, + Y=Y, + kernel=kernel, + likelihood=likelihood, + inference_method=inference_method, + mean_function=mean_function, + normalizer=True, + name="gp_classification", + ) m.optimize() m.save_model("temp_test_gp_with_data.json", compress=True, save_data=True) m.save_model("temp_test_gp_without_data.json", compress=True, save_data=False) m1_r = GPy.core.GP.load_model("temp_test_gp_with_data.json.zip") - m2_r = GPy.core.GP.load_model("temp_test_gp_without_data.json.zip", (X,Y)) + m2_r = GPy.core.GP.load_model("temp_test_gp_without_data.json.zip", (X, Y)) os.remove("temp_test_gp_with_data.json.zip") os.remove("temp_test_gp_without_data.json.zip") var = m.predict(X)[0] var1_r = m1_r.predict(X)[0] var2_r = m2_r.predict(X)[0] - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var1_r).flatten()) - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var2_r).flatten()) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var1_r).flatten() + ) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var2_r).flatten() + ) def test_serialize_deserialize_SparseGP(self): np.random.seed(fixed_seed) N = 20 - Nhalf = int(N/2) - X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[:, None] + Nhalf = int(N / 2) + X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ + :, None + ] Y = np.hstack([np.ones(Nhalf), np.zeros(Nhalf)])[:, None] kernel = GPy.kern.RBF(1) likelihood = GPy.likelihoods.Bernoulli() - inference_method=GPy.inference.latent_function_inference.expectation_propagation.EPDTC(ep_mode="nested") - mean_function=None + inference_method = ( + GPy.inference.latent_function_inference.expectation_propagation.EPDTC( + ep_mode="nested" + ) + ) + mean_function = None - sm = GPy.core.SparseGP(X=X, Y=Y, Z=X[0:20,:], kernel=kernel, likelihood=likelihood, inference_method=inference_method, mean_function=mean_function, normalizer=True, name='sparse_gp_classification') + sm = GPy.core.SparseGP( + X=X, + Y=Y, + Z=X[0:20, :], + kernel=kernel, + likelihood=likelihood, + inference_method=inference_method, + mean_function=mean_function, + normalizer=True, + name="sparse_gp_classification", + ) sm.optimize() sm.save_model("temp_test_gp_with_data.json", compress=True, save_data=True) sm.save_model("temp_test_gp_without_data.json", compress=True, save_data=False) sm1_r = GPy.core.GP.load_model("temp_test_gp_with_data.json.zip") - sm2_r = GPy.core.GP.load_model("temp_test_gp_without_data.json.zip", (X,Y)) + sm2_r = GPy.core.GP.load_model("temp_test_gp_without_data.json.zip", (X, Y)) os.remove("temp_test_gp_with_data.json.zip") os.remove("temp_test_gp_without_data.json.zip") var = sm.predict(X)[0] var1_r = sm1_r.predict(X)[0] var2_r = sm2_r.predict(X)[0] - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var1_r).flatten()) - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var2_r).flatten()) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var1_r).flatten() + ) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var2_r).flatten() + ) def test_serialize_deserialize_GPRegressor(self): np.random.seed(fixed_seed) N = 50 N_new = 50 D = 1 - X = np.random.uniform(-3., 3., (N, 1)) + X = np.random.uniform(-3.0, 3.0, (N, 1)) Y = np.sin(X) + np.random.randn(N, D) * 0.05 - X_new = np.random.uniform(-3., 3., (N_new, 1)) + X_new = np.random.uniform(-3.0, 3.0, (N_new, 1)) k = GPy.kern.RBF(input_dim=1, lengthscale=10) - m = GPy.models.GPRegression(X,Y,k) + m = GPy.models.GPRegression(X, Y, k) m.optimize() - m.save_model("temp_test_gp_regressor_with_data.json", compress=True, save_data=True) - m.save_model("temp_test_gp_regressor_without_data.json", compress=True, save_data=False) - m1_r = GPy.models.GPRegression.load_model("temp_test_gp_regressor_with_data.json.zip") - m2_r = GPy.models.GPRegression.load_model("temp_test_gp_regressor_without_data.json.zip", (X,Y)) + m.save_model( + "temp_test_gp_regressor_with_data.json", compress=True, save_data=True + ) + m.save_model( + "temp_test_gp_regressor_without_data.json", compress=True, save_data=False + ) + m1_r = GPy.models.GPRegression.load_model( + "temp_test_gp_regressor_with_data.json.zip" + ) + m2_r = GPy.models.GPRegression.load_model( + "temp_test_gp_regressor_without_data.json.zip", (X, Y) + ) os.remove("temp_test_gp_regressor_with_data.json.zip") os.remove("temp_test_gp_regressor_without_data.json.zip") - Xp = np.random.uniform(size=(int(1e5),1)) - Xp[:,0] = Xp[:,0]*15-5 + Xp = np.random.uniform(size=(int(1e5), 1)) + Xp[:, 0] = Xp[:, 0] * 15 - 5 _, var = m.predict(Xp) _, var1_r = m1_r.predict(Xp) @@ -229,51 +354,96 @@ class Test(unittest.TestCase): def test_serialize_deserialize_GPClassification(self): np.random.seed(fixed_seed) N = 50 - Nhalf = int(N/2) - X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[:, None] + Nhalf = int(N / 2) + X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ + :, None + ] Y = np.hstack([np.ones(Nhalf), np.zeros(Nhalf)])[:, None] kernel = GPy.kern.RBF(1) m = GPy.models.GPClassification(X, Y, kernel=kernel) m.optimize() - m.save_model("temp_test_gp_classifier_with_data.json", compress=True, save_data=True) - m.save_model("temp_test_gp_classifier_without_data.json", compress=True, save_data=False) - m1_r = GPy.models.GPClassification.load_model("temp_test_gp_classifier_with_data.json.zip") - self.assertTrue(type(m) == type(m1_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r))) - m2_r = GPy.models.GPClassification.load_model("temp_test_gp_classifier_without_data.json.zip", (X,Y)) - self.assertTrue(type(m) == type(m2_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r))) + m.save_model( + "temp_test_gp_classifier_with_data.json", compress=True, save_data=True + ) + m.save_model( + "temp_test_gp_classifier_without_data.json", compress=True, save_data=False + ) + m1_r = GPy.models.GPClassification.load_model( + "temp_test_gp_classifier_with_data.json.zip" + ) + self.assertTrue( + type(m) == type(m1_r), + "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)), + ) + m2_r = GPy.models.GPClassification.load_model( + "temp_test_gp_classifier_without_data.json.zip", (X, Y) + ) + self.assertTrue( + type(m) == type(m2_r), + "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), + ) os.remove("temp_test_gp_classifier_with_data.json.zip") os.remove("temp_test_gp_classifier_without_data.json.zip") var = m.predict(X)[0] var1_r = m1_r.predict(X)[0] var2_r = m2_r.predict(X)[0] - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var1_r).flatten()) - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var1_r).flatten()) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var1_r).flatten() + ) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var1_r).flatten() + ) def test_serialize_deserialize_SparseGPClassification(self): np.random.seed(fixed_seed) N = 50 - Nhalf = int(N/2) - X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[:, None] + Nhalf = int(N / 2) + X = np.hstack([np.random.normal(5, 2, Nhalf), np.random.normal(10, 2, Nhalf)])[ + :, None + ] Y = np.hstack([np.ones(Nhalf), np.zeros(Nhalf)])[:, None] kernel = GPy.kern.RBF(1) m = GPy.models.SparseGPClassification(X, Y, num_inducing=3, kernel=kernel) m.optimize() - m.save_model("temp_test_sparse_gp_classifier_with_data.json", compress=True, save_data=True) - m.save_model("temp_test_sparse_gp_classifier_without_data.json", compress=True, save_data=False) - m1_r = GPy.models.SparseGPClassification.load_model("temp_test_sparse_gp_classifier_with_data.json.zip") - self.assertTrue(type(m) == type(m1_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r))) - m2_r = GPy.models.SparseGPClassification.load_model("temp_test_sparse_gp_classifier_without_data.json.zip", (X,Y)) - self.assertTrue(type(m) == type(m2_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r))) + m.save_model( + "temp_test_sparse_gp_classifier_with_data.json", + compress=True, + save_data=True, + ) + m.save_model( + "temp_test_sparse_gp_classifier_without_data.json", + compress=True, + save_data=False, + ) + m1_r = GPy.models.SparseGPClassification.load_model( + "temp_test_sparse_gp_classifier_with_data.json.zip" + ) + self.assertTrue( + type(m) == type(m1_r), + "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)), + ) + m2_r = GPy.models.SparseGPClassification.load_model( + "temp_test_sparse_gp_classifier_without_data.json.zip", (X, Y) + ) + self.assertTrue( + type(m) == type(m2_r), + "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), + ) os.remove("temp_test_sparse_gp_classifier_with_data.json.zip") os.remove("temp_test_sparse_gp_classifier_without_data.json.zip") var = m.predict(X)[0] var1_r = m1_r.predict(X)[0] var2_r = m2_r.predict(X)[0] - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var1_r).flatten()) - np.testing.assert_array_equal(np.array(var).flatten(), np.array(var1_r).flatten()) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var1_r).flatten() + ) + np.testing.assert_array_equal( + np.array(var).flatten(), np.array(var1_r).flatten() + ) + if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] + # import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] unittest.main() From c69f68feba97abca23e2aa67b101d6a4d5458d11 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:56:11 +0200 Subject: [PATCH 051/101] migrate serialzation_tests to pytest --- GPy/testing/serialization_tests.py | 31 ++++++++---------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/GPy/testing/serialization_tests.py b/GPy/testing/serialization_tests.py index f2af89d3..f08148f8 100644 --- a/GPy/testing/serialization_tests.py +++ b/GPy/testing/serialization_tests.py @@ -10,7 +10,7 @@ import os fixed_seed = 11 -class Test(unittest.TestCase): +class TestSerialization: def test_serialize_deserialize_kernels(self): k1 = GPy.kern.RBF(2, variance=1.0, lengthscale=[1.0, 1.0], ARD=True) k2 = GPy.kern.RatQuad( @@ -371,23 +371,19 @@ class Test(unittest.TestCase): m1_r = GPy.models.GPClassification.load_model( "temp_test_gp_classifier_with_data.json.zip" ) - self.assertTrue( - type(m) == type(m1_r), - "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)), - ) + assert type(m) == type( + m1_r + ), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)) m2_r = GPy.models.GPClassification.load_model( "temp_test_gp_classifier_without_data.json.zip", (X, Y) ) - self.assertTrue( - type(m) == type(m2_r), - "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), - ) + assert type(m) == type(m2_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), os.remove("temp_test_gp_classifier_with_data.json.zip") os.remove("temp_test_gp_classifier_without_data.json.zip") var = m.predict(X)[0] var1_r = m1_r.predict(X)[0] - var2_r = m2_r.predict(X)[0] + _var2_r = m2_r.predict(X)[0] np.testing.assert_array_equal( np.array(var).flatten(), np.array(var1_r).flatten() ) @@ -419,17 +415,11 @@ class Test(unittest.TestCase): m1_r = GPy.models.SparseGPClassification.load_model( "temp_test_sparse_gp_classifier_with_data.json.zip" ) - self.assertTrue( - type(m) == type(m1_r), - "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)), - ) + assert type(m) == type(m1_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)) m2_r = GPy.models.SparseGPClassification.load_model( "temp_test_sparse_gp_classifier_without_data.json.zip", (X, Y) ) - self.assertTrue( - type(m) == type(m2_r), - "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), - ) + assert type(m) == type(m2_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), os.remove("temp_test_sparse_gp_classifier_with_data.json.zip") os.remove("temp_test_sparse_gp_classifier_without_data.json.zip") @@ -442,8 +432,3 @@ class Test(unittest.TestCase): np.testing.assert_array_equal( np.array(var).flatten(), np.array(var1_r).flatten() ) - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] - unittest.main() From c8a6ca4e4d06203cbec4554acdd4aeccd7902405 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 19:56:32 +0200 Subject: [PATCH 052/101] format on save --- GPy/testing/state_space_main_tests.py | 1915 ++++++++++++++++--------- 1 file changed, 1233 insertions(+), 682 deletions(-) diff --git a/GPy/testing/state_space_main_tests.py b/GPy/testing/state_space_main_tests.py index 5a3e353f..0b8db023 100644 --- a/GPy/testing/state_space_main_tests.py +++ b/GPy/testing/state_space_main_tests.py @@ -5,18 +5,17 @@ Test module for state_space_main.py """ -import unittest import numpy as np import matplotlib.pyplot as plt from scipy.stats import norm - import GPy.models.state_space_setup as ss_setup import GPy.models.state_space_main as ssm -def generate_x_points(points_num=100, x_interval = (0, 20), random=True): + +def generate_x_points(points_num=100, x_interval=(0, 20), random=True): """ Function generates (sorted) points on the x axis. - + Input: --------------------------- points_num: int @@ -25,934 +24,1488 @@ def generate_x_points(points_num=100, x_interval = (0, 20), random=True): On which interval to generate points random: bool Regular points or random - + Output: --------------------------- x_points: np.array Generated points """ - - x_interval = np.asarray( x_interval ) + + x_interval = np.asarray(x_interval) if random: - x_points = np.random.rand(points_num) * ( x_interval[1] - x_interval[0] ) + x_interval[0] - x_points = np.sort( x_points ) + x_points = ( + np.random.rand(points_num) * (x_interval[1] - x_interval[0]) + x_interval[0] + ) + x_points = np.sort(x_points) else: - x_points = np.linspace(x_interval[0], x_interval[1], num=points_num ) + x_points = np.linspace(x_interval[0], x_interval[1], num=points_num) return x_points -def generate_sine_data(x_points=None, sin_period=2.0, sin_ampl=10.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 20), random=True): + +def generate_sine_data( + x_points=None, + sin_period=2.0, + sin_ampl=10.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 20), + random=True, +): """ Function generates sinusoidal data. - + Input: -------------------------------- - + x_points: np.array Previously generated X points sin_period: float - Sine period + Sine period sin_ampl: float Sine amplitude - noise_var: float + noise_var: float Gaussian noise variance added to the sine function plot: bool Whether to plot generated data - + (if x_points is None, the the following parameters are used to generate - those. They are the same as in 'generate_x_points' function) - + those. They are the same as in 'generate_x_points' function) + points_num: int - + x_interval: tuple (a,b) - + random: bool - """ - - sin_function = lambda xx: sin_ampl * np.sin( 2*np.pi/sin_period * xx ) - + """ + + sin_function = lambda xx: sin_ampl * np.sin(2 * np.pi / sin_period * xx) + if x_points is None: x_points = generate_x_points(points_num, x_interval, random) - y_points = sin_function( x_points ) + np.random.randn( len(x_points) ) * np.sqrt(noise_var) + y_points = sin_function(x_points) + np.random.randn(len(x_points)) * np.sqrt( + noise_var + ) if plot: pass - + return x_points, y_points - -def generate_linear_data(x_points=None, tangent=2.0, add_term=1.0, noise_var=2.0, - plot = False, points_num=100, x_interval = (0, 20), random=True): + + +def generate_linear_data( + x_points=None, + tangent=2.0, + add_term=1.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 20), + random=True, +): """ Function generates linear data. - + Input: -------------------------------- - + x_points: np.array Previously generated X points tangent: float Factor with which independent variable is multiplied in linear equation. add_term: float Additive term in linear equation. - noise_var: float + noise_var: float Gaussian noise variance added to the sine function plot: bool Whether to plot generated data - + (if x_points is None, the the following parameters are used to generate - those. They are the same as in 'generate_x_points' function) - + those. They are the same as in 'generate_x_points' function) + points_num: int - + x_interval: tuple (a,b) - + random: bool - """ - - linear_function = lambda xx: tangent*xx + add_term - + """ + + linear_function = lambda xx: tangent * xx + add_term + if x_points is None: x_points = generate_x_points(points_num, x_interval, random) - y_points = linear_function( x_points ) + np.random.randn( len(x_points) ) * np.sqrt(noise_var) + y_points = linear_function(x_points) + np.random.randn(len(x_points)) * np.sqrt( + noise_var + ) if plot: pass - + return x_points, y_points -def generate_brownian_data(x_points=None, kernel_var = 2.0, noise_var = 2.0, - plot = False, points_num=100, x_interval = (0, 20), random=True): + +def generate_brownian_data( + x_points=None, + kernel_var=2.0, + noise_var=2.0, + plot=False, + points_num=100, + x_interval=(0, 20), + random=True, +): """ Generate brownian data - data from Brownian motion. - First point is always 0, and \Beta(0) = 0 - standard conditions for Brownian motion. - + First point is always 0, and \Beta(0) = 0 - standard conditions for Brownian motion. + Input: -------------------------------- - + x_points: np.array Previously generated X points - variance: float + variance: float Gaussian noise variance added to the sine function plot: bool Whether to plot generated data - + (if x_points is None, the the following parameters are used to generate - those. They are the same as in 'generate_x_points' function) - + those. They are the same as in 'generate_x_points' function) + points_num: int - + x_interval: tuple (a,b) - + random: bool - - """ + + """ if x_points is None: x_points = generate_x_points(points_num, x_interval, random) if x_points[0] != 0: x_points[0] = 0 - - y_points = np.zeros( (points_num,) ) + + y_points = np.zeros((points_num,)) for i in range(1, points_num): - noise = np.random.randn() * np.sqrt(kernel_var * (x_points[i] - x_points[i-1])) - y_points[i] = y_points[i-1] + noise - - y_points += np.random.randn( len(x_points) ) * np.sqrt(noise_var) - - return x_points, y_points - -def generate_linear_plus_sin(x_points=None, tangent=2.0, add_term=1.0, noise_var=2.0, - sin_period=2.0, sin_ampl=10.0, plot = False, - points_num=100, x_interval = (0, 20), random=True): + noise = np.random.randn() * np.sqrt( + kernel_var * (x_points[i] - x_points[i - 1]) + ) + y_points[i] = y_points[i - 1] + noise + + y_points += np.random.randn(len(x_points)) * np.sqrt(noise_var) + + return x_points, y_points + + +def generate_linear_plus_sin( + x_points=None, + tangent=2.0, + add_term=1.0, + noise_var=2.0, + sin_period=2.0, + sin_ampl=10.0, + plot=False, + points_num=100, + x_interval=(0, 20), + random=True, +): """ Generate the sum of linear trend and the sine function. - + For parameters see the 'generate_linear' and 'generate_sine'. - + Comment: Gaussian noise variance is added only once (for linear function). """ - x_points, y_linear_points = generate_linear_data(x_points, tangent, add_term, noise_var, - False, points_num, x_interval, random) - - x_points, y_sine_points = generate_sine_data(x_points, sin_period, sin_ampl, 0.0, - False, points_num, x_interval, random) + x_points, y_linear_points = generate_linear_data( + x_points, tangent, add_term, noise_var, False, points_num, x_interval, random + ) + + x_points, y_sine_points = generate_sine_data( + x_points, sin_period, sin_ampl, 0.0, False, points_num, x_interval, random + ) y_points = y_linear_points + y_sine_points if plot: pass - + return x_points, y_points + def generate_random_y_data(samples, dim, ts_no): """ Generate data: - + Input: ------------------ - + samples - how many samples dim - dimensionality of the data ts_no - number of time series - + Output: -------------------------- Y: np.array((samples, dim, ts_no)) """ - - Y = np.empty((samples, dim, ts_no)); - - for i in range(0,samples): - for j in range(0,ts_no): + + Y = np.empty((samples, dim, ts_no)) + + for i in range(0, samples): + for j in range(0, ts_no): sample = np.random.randn(dim) - Y[i,:,j] = sample - - if (Y.shape[2] == 1): # ts_no = 1 - Y.shape=(Y.shape[0], Y.shape[1]) + Y[i, :, j] = sample + + if Y.shape[2] == 1: # ts_no = 1 + Y.shape = (Y.shape[0], Y.shape[1]) return Y class StateSpaceKernelsTests(np.testing.TestCase): def setUp(self): pass - - def run_descr_model(self, measurements, A,Q,H,R, true_states=None, - mean_compare_decimal=8, - m_init=None, P_init=None, dA=None,dQ=None, - dH=None,dR=None, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True): - - #import pdb; pdb.set_trace() - - state_dim = 1 if not isinstance(A,np.ndarray) else A.shape[0] - ts_no = 1 if (len(measurements.shape) < 3) else measurements.shape[2] - grad_params_no = None if dA is None else dA.shape[2] - - - ss_setup.use_cython = use_cython - global ssm - if (ssm.cython_code_available) and (ssm.use_cython != use_cython): - reload(ssm) - - grad_calc_params = None - if calc_grad_log_likelihood: - grad_calc_params = {} - grad_calc_params['dA'] = dA - grad_calc_params['dQ'] = dQ - grad_calc_params['dH'] = dH - grad_calc_params['dR'] = dR - - (f_mean, f_var, loglikelhood, g_loglikelhood, \ - dynamic_callables_smoother) = ssm.DescreteStateSpace.kalman_filter(A, Q, H, R, measurements, index=None, - m_init=m_init, P_init=P_init, p_kalman_filter_type = kalman_filter_type, - calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, - grad_params_no=grad_params_no, - grad_calc_params=grad_calc_params) - - f_mean_squeezed = np.squeeze(f_mean[1:,:]) # exclude initial value - f_var_squeezed = np.squeeze(f_var[1:,:]) # exclude initial value - - if true_states is not None: - #print np.max(np.abs(f_mean_squeezed-true_states)) - np.testing.assert_almost_equal(np.max(np.abs(f_mean_squeezed- \ - true_states)), 0, decimal=mean_compare_decimal) - - np.testing.assert_equal(f_mean.shape, (measurements.shape[0]+1,state_dim,ts_no) ) - np.testing.assert_equal(f_var.shape, (measurements.shape[0]+1,state_dim,state_dim) ) - - (M_smooth, P_smooth) = ssm.DescreteStateSpace.rts_smoother(state_dim, dynamic_callables_smoother, f_mean, - f_var) - - return f_mean, f_var - - def run_continuous_model(self, F, L, Qc, p_H, p_R, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=None, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=0, grad_calc_params=None): - - #import pdb; pdb.set_trace() - - state_dim = 1 if not isinstance(F,np.ndarray) else F.shape[0] + + def run_descr_model( + self, + measurements, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=8, + m_init=None, + P_init=None, + dA=None, + dQ=None, + dH=None, + dR=None, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ): + # import pdb; pdb.set_trace() + + state_dim = 1 if not isinstance(A, np.ndarray) else A.shape[0] + ts_no = 1 if (len(measurements.shape) < 3) else measurements.shape[2] + grad_params_no = None if dA is None else dA.shape[2] + + ss_setup.use_cython = use_cython + global ssm + if (ssm.cython_code_available) and (ssm.use_cython != use_cython): + reload(ssm) + + grad_calc_params = None + if calc_grad_log_likelihood: + grad_calc_params = {} + grad_calc_params["dA"] = dA + grad_calc_params["dQ"] = dQ + grad_calc_params["dH"] = dH + grad_calc_params["dR"] = dR + + ( + f_mean, + f_var, + loglikelhood, + g_loglikelhood, + dynamic_callables_smoother, + ) = ssm.DescreteStateSpace.kalman_filter( + A, + Q, + H, + R, + measurements, + index=None, + m_init=m_init, + P_init=P_init, + p_kalman_filter_type=kalman_filter_type, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + grad_params_no=grad_params_no, + grad_calc_params=grad_calc_params, + ) + + f_mean_squeezed = np.squeeze(f_mean[1:, :]) # exclude initial value + f_var_squeezed = np.squeeze(f_var[1:, :]) # exclude initial value + + if true_states is not None: + # print np.max(np.abs(f_mean_squeezed-true_states)) + np.testing.assert_almost_equal( + np.max(np.abs(f_mean_squeezed - true_states)), + 0, + decimal=mean_compare_decimal, + ) + + np.testing.assert_equal( + f_mean.shape, (measurements.shape[0] + 1, state_dim, ts_no) + ) + np.testing.assert_equal( + f_var.shape, (measurements.shape[0] + 1, state_dim, state_dim) + ) + + (M_smooth, P_smooth) = ssm.DescreteStateSpace.rts_smoother( + state_dim, dynamic_callables_smoother, f_mean, f_var + ) + + return f_mean, f_var + + def run_continuous_model( + self, + F, + L, + Qc, + p_H, + p_R, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=None, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=0, + grad_calc_params=None, + ): + # import pdb; pdb.set_trace() + + state_dim = 1 if not isinstance(F, np.ndarray) else F.shape[0] ts_no = 1 if (len(Y_data.shape) < 3) else Y_data.shape[2] ss_setup.use_cython = use_cython global ssm if (ssm.cython_code_available) and (ssm.use_cython != use_cython): - reload(ssm) - - (f_mean, f_var, loglikelhood, g_loglikelhood, \ - dynamic_callables_smoother) = ssm.ContDescrStateSpace.cont_discr_kalman_filter(F, L, Qc, p_H, p_R, - P_inf, X_data, Y_data, index = None, - m_init=None, P_init=None, - p_kalman_filter_type='regular', - calc_log_likelihood=False, - calc_grad_log_likelihood=False, - grad_params_no=0, grad_calc_params=grad_calc_params) - - f_mean_squeezed = np.squeeze(f_mean[1:,:]) # exclude initial value - f_var_squeezed = np.squeeze(f_var[1:,:]) # exclude initial value - - np.testing.assert_equal(f_mean.shape, (Y_data.shape[0]+1,state_dim,ts_no)) - np.testing.assert_equal(f_var.shape, (Y_data.shape[0]+1,state_dim,state_dim)) - - (M_smooth, P_smooth) = ssm.ContDescrStateSpace.cont_discr_rts_smoother(state_dim, f_mean, \ - f_var,dynamic_callables_smoother) - + reload(ssm) + + ( + f_mean, + f_var, + loglikelhood, + g_loglikelhood, + dynamic_callables_smoother, + ) = ssm.ContDescrStateSpace.cont_discr_kalman_filter( + F, + L, + Qc, + p_H, + p_R, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=None, + p_kalman_filter_type="regular", + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + grad_params_no=0, + grad_calc_params=grad_calc_params, + ) + + f_mean_squeezed = np.squeeze(f_mean[1:, :]) # exclude initial value + f_var_squeezed = np.squeeze(f_var[1:, :]) # exclude initial value + + np.testing.assert_equal(f_mean.shape, (Y_data.shape[0] + 1, state_dim, ts_no)) + np.testing.assert_equal( + f_var.shape, (Y_data.shape[0] + 1, state_dim, state_dim) + ) + + (M_smooth, P_smooth) = ssm.ContDescrStateSpace.cont_discr_rts_smoother( + state_dim, f_mean, f_var, dynamic_callables_smoother + ) + return f_mean, f_var - - def test_discrete_ss_first(self,plot=False): + + def test_discrete_ss_first(self, plot=False): """ Tests discrete State-Space model - first test. """ - np.random.seed(235) # seed the random number generator - - A = 1.0 # For cython code to run properly need float input + np.random.seed(235) # seed the random number generator + + A = 1.0 # For cython code to run properly need float input H = 1.0 - Q = 1.0 + Q = 1.0 R = 1.0 - + steps_num = 100 - + # generate data -> true_states = np.zeros((steps_num,)) init_state = 0 measurements = np.zeros((steps_num,)) - + for s in range(0, steps_num): - if s== 0: - true_states[0] = init_state + np.sqrt(Q)*np.random.randn() + if s == 0: + true_states[0] = init_state + np.sqrt(Q) * np.random.randn() else: - true_states[s] = true_states[s-1] + np.sqrt(R)*np.random.randn() - measurements[s] = true_states[s] + np.sqrt(R)*np.random.randn() + true_states[s] = true_states[s - 1] + np.sqrt(R) * np.random.randn() + measurements[s] = true_states[s] + np.sqrt(R) * np.random.randn() # generate data <- - + # descrete kalman filter -> - m_init = 0; P_init = 1 + m_init = 0 + P_init = 1 d_num = 1000 - state_discr = np.linspace(-10,10,d_num) - - state_trans_matrix = np.empty((d_num,d_num)) + state_discr = np.linspace(-10, 10, d_num) + + state_trans_matrix = np.empty((d_num, d_num)) for i in range(d_num): - state_trans_matrix[:,i] = norm.pdf(state_discr, loc=A*state_discr[i], scale=np.sqrt(Q)) - - m_prev = norm.pdf(state_discr, loc = m_init, scale = np.sqrt(P_init)); #m_prev / np.sum(m_prev) + state_trans_matrix[:, i] = norm.pdf( + state_discr, loc=A * state_discr[i], scale=np.sqrt(Q) + ) + + m_prev = norm.pdf(state_discr, loc=m_init, scale=np.sqrt(P_init)) + # m_prev / np.sum(m_prev) m = np.zeros((d_num, steps_num)) i_mean = np.zeros((steps_num,)) - + for s in range(0, steps_num): # Prediction step: - if (s==0): - m[:,s] = np.dot(state_trans_matrix, m_prev) + if s == 0: + m[:, s] = np.dot(state_trans_matrix, m_prev) else: - m[:,s] = np.dot(state_trans_matrix, m[:,s-1]) + m[:, s] = np.dot(state_trans_matrix, m[:, s - 1]) # Update step: - #meas_ind = np.argmin(np.abs(state_discr - measurements[s]) - y_vec = np.zeros( (d_num,)) + # meas_ind = np.argmin(np.abs(state_discr - measurements[s]) + y_vec = np.zeros((d_num,)) for i in range(d_num): - y_vec[i] = norm.pdf(measurements[s], loc=H*state_discr[i], scale=np.sqrt(R)) - norm_const = np.dot( y_vec, m[:,s] ) - m[:,s] = y_vec * m[:,s] / norm_const - - i_mean[s] = state_discr[ np.argmax(m[:,s]) ] + y_vec[i] = norm.pdf( + measurements[s], loc=H * state_discr[i], scale=np.sqrt(R) + ) + norm_const = np.dot(y_vec, m[:, s]) + m[:, s] = y_vec * m[:, s] / norm_const + + i_mean[s] = state_discr[np.argmax(m[:, s])] # descrete kalman filter <- - - (f_mean, f_var) = self.run_descr_model(measurements, A,Q,H,R, true_states=i_mean, - mean_compare_decimal=1, - m_init=m_init, P_init=P_init,use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=False) - - (f_mean, f_var) = self.run_descr_model(measurements, A,Q,H,R, true_states=i_mean, - mean_compare_decimal=1, - m_init=m_init, P_init=P_init,use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=False) - - (f_mean, f_var) = self.run_descr_model(measurements, A,Q,H,R, true_states=i_mean, - mean_compare_decimal=1, - m_init=m_init, P_init=P_init,use_cython=True, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=False) - + + (f_mean, f_var) = self.run_descr_model( + measurements, + A, + Q, + H, + R, + true_states=i_mean, + mean_compare_decimal=1, + m_init=m_init, + P_init=P_init, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=False, + ) + + (f_mean, f_var) = self.run_descr_model( + measurements, + A, + Q, + H, + R, + true_states=i_mean, + mean_compare_decimal=1, + m_init=m_init, + P_init=P_init, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=False, + ) + + (f_mean, f_var) = self.run_descr_model( + measurements, + A, + Q, + H, + R, + true_states=i_mean, + mean_compare_decimal=1, + m_init=m_init, + P_init=P_init, + use_cython=True, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=False, + ) + if plot: # plotting -> plt.figure() - plt.plot( true_states, 'g.-',label='true states') - #plt.plot( measurements, 'b.-', label='measurements') - plt.plot( f_mean, 'r.-',label='Kalman filter estimates') - plt.plot( i_mean, 'k.-', label='Discretization') - - plt.plot( f_mean + 2*np.sqrt(f_var), 'r.--') - plt.plot( f_mean - 2*np.sqrt(f_var), 'r.--') + plt.plot(true_states, "g.-", label="true states") + # plt.plot( measurements, 'b.-', label='measurements') + plt.plot(f_mean, "r.-", label="Kalman filter estimates") + plt.plot(i_mean, "k.-", label="Discretization") + + plt.plot(f_mean + 2 * np.sqrt(f_var), "r.--") + plt.plot(f_mean - 2 * np.sqrt(f_var), "r.--") plt.legend() plt.show() # plotting <- return None - - def test_discrete_ss_1D(self,plot=False): + + def test_discrete_ss_1D(self, plot=False): """ - This function tests Kalman filter and smoothing when the state + This function tests Kalman filter and smoothing when the state dimensionality is one dimensional. - """ - - np.random.seed(234) # seed the random number generator - - # 1D ss model - state_dim = 1; - param_num = 2 # sigma_Q, sigma_R - parameters - measurement_dim = 1 # dimensionality od measurement - + """ + + np.random.seed(234) # seed the random number generator + + # 1D ss model + state_dim = 1 + param_num = 2 # sigma_Q, sigma_R - parameters + measurement_dim = 1 # dimensionality od measurement + A = 1.0 Q = 2.0 - dA= np.zeros((state_dim,state_dim,param_num)) - dQ = np.zeros((state_dim,state_dim,param_num)); dQ[0,0,0] = 1.0 - + dA = np.zeros((state_dim, state_dim, param_num)) + dQ = np.zeros((state_dim, state_dim, param_num)) + dQ[0, 0, 0] = 1.0 + # measurement related parameters (subject to change) -> - H = np.ones((measurement_dim,state_dim )) - R = 0.5 * np.eye(measurement_dim) - dH = np.zeros((measurement_dim,state_dim,param_num)) - dR = np.zeros((measurement_dim,measurement_dim,param_num)); dR[:,:,1] = np.eye(measurement_dim) + H = np.ones((measurement_dim, state_dim)) + R = 0.5 * np.eye(measurement_dim) + dH = np.zeros((measurement_dim, state_dim, param_num)) + dR = np.zeros((measurement_dim, measurement_dim, param_num)) + dR[:, :, 1] = np.eye(measurement_dim) # measurement related parameters (subject to change) <- - - # 1D measurement, 1 ts_no -> - data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=True, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - if plot: + + # 1D measurement, 1 ts_no -> + data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=True, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + if plot: # plotting -> plt.figure() - plt.plot( np.squeeze(data), 'g.-', label='measurements') - plt.plot( np.squeeze(f_mean[1:]), 'b.-',label='Kalman filter estimates') - plt.plot( np.squeeze(f_mean[1:]+H*f_var[1:]*H), 'b--') - plt.plot( np.squeeze(f_mean[1:]-H*f_var[1:]*H), 'b--') -# plt.plot( np.squeeze(M_sm[1:]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:]+H*P_sm[1:]*H), 'r--') -# plt.plot( np.squeeze(M_sm[1:]-H*P_sm[1:]*H), 'r--') + plt.plot(np.squeeze(data), "g.-", label="measurements") + plt.plot(np.squeeze(f_mean[1:]), "b.-", label="Kalman filter estimates") + plt.plot(np.squeeze(f_mean[1:] + H * f_var[1:] * H), "b--") + plt.plot(np.squeeze(f_mean[1:] - H * f_var[1:] * H), "b--") + # plt.plot( np.squeeze(M_sm[1:]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:]+H*P_sm[1:]*H), 'r--') + # plt.plot( np.squeeze(M_sm[1:]-H*P_sm[1:]*H), 'r--') plt.legend() plt.title("1D state-space, 1D measurements, 1 ts_no") plt.show() # plotting <- # 1D measurement, 1 ts_no <- - - + # 1D measurement, 3 ts_no -> - data = generate_random_y_data(10, 1, 3) # np.array((samples, dim, ts_no)) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=True, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - #import pdb; pdb.set_trace() - if plot: + data = generate_random_y_data(10, 1, 3) # np.array((samples, dim, ts_no)) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=True, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + # import pdb; pdb.set_trace() + if plot: # plotting -> plt.figure() - plt.plot( np.squeeze(data[:,:,1]), 'g.-', label='measurements') - plt.plot( np.squeeze(f_mean[1:,0,1]), 'b.-',label='Kalman filter estimates') - plt.plot( np.squeeze(f_mean[1:,0,1])+np.squeeze(H*f_var[1:]*H), 'b--') - plt.plot( np.squeeze(f_mean[1:,0,1])-np.squeeze(H*f_var[1:]*H), 'b--') -# plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,0,1])+H*np.squeeze(P_sm[1:])*H, 'r--') -# plt.plot( np.squeeze(M_sm[1:,0,1])-H*np.squeeze(P_sm[1:])*H, 'r--') + plt.plot(np.squeeze(data[:, :, 1]), "g.-", label="measurements") + plt.plot( + np.squeeze(f_mean[1:, 0, 1]), "b.-", label="Kalman filter estimates" + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + np.squeeze(H * f_var[1:] * H), "b--" + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) - np.squeeze(H * f_var[1:] * H), "b--" + ) + # plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,0,1])+H*np.squeeze(P_sm[1:])*H, 'r--') + # plt.plot( np.squeeze(M_sm[1:,0,1])-H*np.squeeze(P_sm[1:])*H, 'r--') plt.legend() plt.title("1D state-space, 1D measurements, 3 ts_no. 2-nd ts ploted") plt.show() # plotting <- - # 1D measurement, 3 ts_no <- - measurement_dim = 2 # dimensionality of measurement - - H = np.ones((measurement_dim,state_dim)) - R = 0.5 * np.eye(measurement_dim) - dH = np.zeros((measurement_dim,state_dim,param_num)) - dR = np.zeros((measurement_dim,measurement_dim,param_num)); dR[:,:,1] = np.eye(measurement_dim) + # 1D measurement, 3 ts_no <- + measurement_dim = 2 # dimensionality of measurement + + H = np.ones((measurement_dim, state_dim)) + R = 0.5 * np.eye(measurement_dim) + dH = np.zeros((measurement_dim, state_dim, param_num)) + dR = np.zeros((measurement_dim, measurement_dim, param_num)) + dR[:, :, 1] = np.eye(measurement_dim) # measurement related parameters (subject to change) < - - data = generate_random_y_data(10, 2, 3) # np.array((samples, dim, ts_no)) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - -# (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, -# mean_compare_decimal=16, -# m_init=None, P_init=None, dA=dA,dQ=dQ, -# dH=dH,dR=dR, use_cython=True, -# kalman_filter_type='svd', -# calc_log_likelihood=True, -# calc_grad_log_likelihood=True) - - if plot: + + data = generate_random_y_data(10, 2, 3) # np.array((samples, dim, ts_no)) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + # (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, + # mean_compare_decimal=16, + # m_init=None, P_init=None, dA=dA,dQ=dQ, + # dH=dH,dR=dR, use_cython=True, + # kalman_filter_type='svd', + # calc_log_likelihood=True, + # calc_grad_log_likelihood=True) + + if plot: # plotting -> plt.figure() - plt.plot( np.squeeze(data[:,0,1]), 'g.-', label='measurements') - plt.plot( np.squeeze(f_mean[1:,0,1]), 'b.-',label='Kalman filter estimates') - plt.plot( np.squeeze(f_mean[1:,0,1])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot( np.squeeze(f_mean[1:,0,1])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') -# plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,0,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') -# plt.plot( np.squeeze(M_sm[1:,0,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(np.squeeze(data[:, 0, 1]), "g.-", label="measurements") + plt.plot( + np.squeeze(f_mean[1:, 0, 1]), "b.-", label="Kalman filter estimates" + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,0,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,0,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() - plt.title("1D state-space, 2D measurements, 3 ts_no. 1-st measurement, 2-nd ts ploted") + plt.title( + "1D state-space, 2D measurements, 3 ts_no. 1-st measurement, 2-nd ts ploted" + ) plt.show() # plotting <- # 2D measurement, 3 ts_no <- - - def test_discrete_ss_2D(self,plot=False): - """ - This function tests Kalman filter and smoothing when the state - dimensionality is two dimensional. - """ - np.random.seed(234) # seed the random number generator - - # 1D ss model - state_dim = 2; - param_num = 3 # sigma_Q, sigma_R, one parameters in A - parameters - measurement_dim = 1 # dimensionality od measurement - - A = np.eye(state_dim); A[0,0] = 0.5 - Q = np.ones((state_dim,state_dim)); - dA = np.zeros((state_dim,state_dim,param_num)); dA[1,1,2] = 1 - dQ = np.zeros((state_dim,state_dim,param_num)); dQ[:,:,1] = np.eye(measurement_dim) - + def test_discrete_ss_2D(self, plot=False): + """ + This function tests Kalman filter and smoothing when the state + dimensionality is two dimensional. + """ + + np.random.seed(234) # seed the random number generator + + # 1D ss model + state_dim = 2 + param_num = 3 # sigma_Q, sigma_R, one parameters in A - parameters + measurement_dim = 1 # dimensionality od measurement + + A = np.eye(state_dim) + A[0, 0] = 0.5 + Q = np.ones((state_dim, state_dim)) + dA = np.zeros((state_dim, state_dim, param_num)) + dA[1, 1, 2] = 1 + dQ = np.zeros((state_dim, state_dim, param_num)) + dQ[:, :, 1] = np.eye(measurement_dim) + # measurement related parameters (subject to change) -> - H = np.ones((measurement_dim,state_dim)) - R = 0.5 * np.eye(measurement_dim) - dH = np.zeros((measurement_dim,state_dim,param_num)) - dR = np.zeros((measurement_dim,measurement_dim,param_num)); dR[:,:,1] = np.eye(measurement_dim) + H = np.ones((measurement_dim, state_dim)) + R = 0.5 * np.eye(measurement_dim) + dH = np.zeros((measurement_dim, state_dim, param_num)) + dR = np.zeros((measurement_dim, measurement_dim, param_num)) + dR[:, :, 1] = np.eye(measurement_dim) # measurement related parameters (subject to change) <- # 1D measurement, 1 ts_no -> - data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=True, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - if plot: + data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=True, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + if plot: # plotting -> plt.figure() - plt.plot( np.squeeze(data), 'g.-', label='measurements') - plt.plot( np.squeeze(f_mean[1:,0]), 'b.-',label='Kalman filter estimates') - plt.plot( np.squeeze(f_mean[1:,0])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot( np.squeeze(f_mean[1:,0])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') -# plt.plot( np.squeeze(M_sm[1:,0]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,0])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') -# plt.plot( np.squeeze(M_sm[1:,0])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(np.squeeze(data), "g.-", label="measurements") + plt.plot(np.squeeze(f_mean[1:, 0]), "b.-", label="Kalman filter estimates") + plt.plot( + np.squeeze(f_mean[1:, 0]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + np.squeeze(f_mean[1:, 0]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,0]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,0])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,0])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() plt.title("2D state-space, 1D measurements, 1 ts_no") plt.show() # plotting <- # 1D measurement, 1 ts_no <- - + # 1D measurement, 3 ts_no -> - data = generate_random_y_data(10, 1, 3) # np.array((samples, dim, ts_no)) - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=True, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - if plot: + data = generate_random_y_data(10, 1, 3) # np.array((samples, dim, ts_no)) + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=True, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + if plot: # plotting -> plt.figure() - plt.plot( np.squeeze(data[:,:,1]), 'g.-', label='measurements') - plt.plot( np.squeeze(f_mean[1:,0,1]), 'b.-',label='Kalman filter estimates') - plt.plot( np.squeeze(f_mean[1:,0,1])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot( np.squeeze(f_mean[1:,0,1])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') -# plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,0,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') -# plt.plot( np.squeeze(M_sm[1:,0,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(np.squeeze(data[:, :, 1]), "g.-", label="measurements") + plt.plot( + np.squeeze(f_mean[1:, 0, 1]), "b.-", label="Kalman filter estimates" + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,0,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,0,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() plt.title("2D state-space, 1D measurements, 3 ts_no. 2-nd ts ploted") plt.show() # plotting <- # 1D measurement, 3 ts_no <- - + # 2D measurement, 3 ts_no -> # measurement related parameters (subject to change) -> - measurement_dim = 2 # dimensionality od measurement - - H = np.ones((measurement_dim,state_dim)) - R = 0.5 * np.eye(measurement_dim) - dH = np.zeros((measurement_dim,state_dim,param_num)) - dR = np.zeros((measurement_dim,measurement_dim,param_num)); dR[:,:,1] = np.eye(measurement_dim) + measurement_dim = 2 # dimensionality od measurement + + H = np.ones((measurement_dim, state_dim)) + R = 0.5 * np.eye(measurement_dim) + dH = np.zeros((measurement_dim, state_dim, param_num)) + dR = np.zeros((measurement_dim, measurement_dim, param_num)) + dR[:, :, 1] = np.eye(measurement_dim) # measurement related parameters (subject to change) < - - data = generate_random_y_data(10, 2, 3) # np.array((samples, dim, ts_no)) - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - - (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, - mean_compare_decimal=16, - m_init=None, P_init=None, dA=dA,dQ=dQ, - dH=dH,dR=dR, use_cython=False, - kalman_filter_type='svd', - calc_log_likelihood=True, - calc_grad_log_likelihood=True) - -# (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, -# mean_compare_decimal=16, -# m_init=None, P_init=None, dA=dA,dQ=dQ, -# dH=dH,dR=dR, use_cython=True, -# kalman_filter_type='svd', -# calc_log_likelihood=True, -# calc_grad_log_likelihood=True) - - if plot: + + data = generate_random_y_data(10, 2, 3) # np.array((samples, dim, ts_no)) + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + (f_mean, f_var) = self.run_descr_model( + data, + A, + Q, + H, + R, + true_states=None, + mean_compare_decimal=16, + m_init=None, + P_init=None, + dA=dA, + dQ=dQ, + dH=dH, + dR=dR, + use_cython=False, + kalman_filter_type="svd", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + ) + + # (f_mean, f_var) = self.run_descr_model(data, A,Q,H,R, true_states=None, + # mean_compare_decimal=16, + # m_init=None, P_init=None, dA=dA,dQ=dQ, + # dH=dH,dR=dR, use_cython=True, + # kalman_filter_type='svd', + # calc_log_likelihood=True, + # calc_grad_log_likelihood=True) + + if plot: # plotting -> plt.figure() - plt.plot( np.squeeze(data[:,0,1]), 'g.-', label='measurements') - plt.plot( np.squeeze(f_mean[1:,0,1]), 'b.-',label='Kalman filter estimates') - plt.plot( np.squeeze(f_mean[1:,0,1])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot( np.squeeze(f_mean[1:,0,1])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') -# plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,0,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') -# plt.plot( np.squeeze(M_sm[1:,0,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(np.squeeze(data[:, 0, 1]), "g.-", label="measurements") + plt.plot( + np.squeeze(f_mean[1:, 0, 1]), "b.-", label="Kalman filter estimates" + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + np.squeeze(f_mean[1:, 0, 1]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,0,1]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,0,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,0,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() - plt.title("2D state-space, 2D measurements, 3 ts_no. 1-st measurement, 2-nd ts ploted") + plt.title( + "2D state-space, 2D measurements, 3 ts_no. 1-st measurement, 2-nd ts ploted" + ) plt.show() # plotting <- # 2D measurement, 3 ts_no <- - - def test_continuous_ss(self,plot=False): + + def test_continuous_ss(self, plot=False): """ This function tests the continuous state-space model. - """ - + """ + # 1D measurements, 1 ts_no -> - measurement_dim = 1 # dimensionality of measurement - - X_data = generate_x_points(points_num=10, x_interval = (0, 20), random=True) - Y_data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) - + measurement_dim = 1 # dimensionality of measurement + + X_data = generate_x_points(points_num=10, x_interval=(0, 20), random=True) + Y_data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) + try: import GPy except ImportError as e: return None - - periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) - (F,L,Qc,H,P_inf,P0, dFt,dQct,dP_inft,dP0) = periodic_kernel.sde() - - state_dim = dFt.shape[0]; + + periodic_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + (F, L, Qc, H, P_inf, P0, dFt, dQct, dP_inft, dP0) = periodic_kernel.sde() + + state_dim = dFt.shape[0] param_num = dFt.shape[2] - - + grad_calc_params = {} - grad_calc_params['dP_inf'] = dP_inft - grad_calc_params['dF'] = dFt - grad_calc_params['dQc'] = dQct - grad_calc_params['dR'] = np.zeros((measurement_dim,measurement_dim,param_num)) - grad_calc_params['dP_init'] = dP0 - # dH matrix is None - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, 1.5, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, 1.5, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=False, - kalman_filter_type='rbc', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, 1.5, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=True, - kalman_filter_type='rbc', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - if plot: + grad_calc_params["dP_inf"] = dP_inft + grad_calc_params["dF"] = dFt + grad_calc_params["dQc"] = dQct + grad_calc_params["dR"] = np.zeros((measurement_dim, measurement_dim, param_num)) + grad_calc_params["dP_init"] = dP0 + # dH matrix is None + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + 1.5, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + 1.5, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=False, + kalman_filter_type="rbc", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + 1.5, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=True, + kalman_filter_type="rbc", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + if plot: # plotting -> plt.figure() - plt.plot( X_data, np.squeeze(Y_data[:,0]), 'g.-', label='measurements') - plt.plot( X_data, np.squeeze(f_mean[1:,15]), 'b.-',label='Kalman filter estimates') - plt.plot( X_data, np.squeeze(f_mean[1:,15])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot( X_data, np.squeeze(f_mean[1:,15])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - # plt.plot( np.squeeze(M_sm[1:,15]), 'r.-',label='Smoother Estimates') - # plt.plot( np.squeeze(M_sm[1:,15])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') - # plt.plot( np.squeeze(M_sm[1:,15])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(X_data, np.squeeze(Y_data[:, 0]), "g.-", label="measurements") + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15]), + "b.-", + label="Kalman filter estimates", + ) + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,15]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,15])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,15])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() plt.title("1D measurements, 1 ts_no") plt.show() # plotting <- - # 1D measurements, 1 ts_no <- - + # 1D measurements, 1 ts_no <- + # 1D measurements, 3 ts_no -> - measurement_dim = 1 # dimensionality od measurement - - X_data = generate_x_points(points_num=10, x_interval = (0, 20), random=True) - Y_data = generate_random_y_data(10, 1, 3) # np.array((samples, dim, ts_no)) - - periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) - (F,L,Qc,H,P_inf,P0, dFt,dQct,dP_inft,dP0) = periodic_kernel.sde() - - state_dim = dFt.shape[0]; + measurement_dim = 1 # dimensionality od measurement + + X_data = generate_x_points(points_num=10, x_interval=(0, 20), random=True) + Y_data = generate_random_y_data(10, 1, 3) # np.array((samples, dim, ts_no)) + + periodic_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + (F, L, Qc, H, P_inf, P0, dFt, dQct, dP_inft, dP0) = periodic_kernel.sde() + + state_dim = dFt.shape[0] param_num = dFt.shape[2] - + grad_calc_params = {} - grad_calc_params['dP_inf'] = dP_inft - grad_calc_params['dF'] = dFt - grad_calc_params['dQc'] = dQct - grad_calc_params['dR'] = np.zeros((measurement_dim,measurement_dim,param_num)) - grad_calc_params['dP_init'] = dP0 - # dH matrix is None - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, 1.5, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, 1.5, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=False, - kalman_filter_type='rbc', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, 1.5, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=True, - kalman_filter_type='rbc', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - if plot: + grad_calc_params["dP_inf"] = dP_inft + grad_calc_params["dF"] = dFt + grad_calc_params["dQc"] = dQct + grad_calc_params["dR"] = np.zeros((measurement_dim, measurement_dim, param_num)) + grad_calc_params["dP_init"] = dP0 + # dH matrix is None + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + 1.5, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + 1.5, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=False, + kalman_filter_type="rbc", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + 1.5, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=True, + kalman_filter_type="rbc", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + if plot: # plotting -> plt.figure() - plt.plot(X_data, np.squeeze(Y_data[:,0,1]), 'g.-', label='measurements') - plt.plot(X_data, np.squeeze(f_mean[1:,15,1]), 'b.-',label='Kalman filter estimates') - plt.plot(X_data, np.squeeze(f_mean[1:,15,1])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot(X_data, np.squeeze(f_mean[1:,15,1])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') -# plt.plot( np.squeeze(M_sm[1:,15,1]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,15,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') -# plt.plot( np.squeeze(M_sm[1:,15,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(X_data, np.squeeze(Y_data[:, 0, 1]), "g.-", label="measurements") + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15, 1]), + "b.-", + label="Kalman filter estimates", + ) + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15, 1]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15, 1]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,15,1]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,15,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,15,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() plt.title("1D measurements, 3 ts_no. 2-nd ts ploted") plt.show() # plotting <- - # 1D measurements, 3 ts_no <- - - + # 1D measurements, 3 ts_no <- + # 2D measurements, 3 ts_no -> - measurement_dim = 2 # dimensionality od measurement - - X_data = generate_x_points(points_num=10, x_interval = (0, 20), random=True) - Y_data = generate_random_y_data(10, 2, 3) # np.array((samples, dim, ts_no)) - - periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) - (F,L,Qc,H,P_inf,P0, dFt,dQct,dP_inft,dP0) = periodic_kernel.sde() - H = np.vstack((H,H)) # make 2D measurements - R = 1.5 * np.eye(measurement_dim) - - state_dim = dFt.shape[0]; + measurement_dim = 2 # dimensionality od measurement + + X_data = generate_x_points(points_num=10, x_interval=(0, 20), random=True) + Y_data = generate_random_y_data(10, 2, 3) # np.array((samples, dim, ts_no)) + + periodic_kernel = GPy.kern.sde_StdPeriodic( + 1, + active_dims=[ + 0, + ], + ) + (F, L, Qc, H, P_inf, P0, dFt, dQct, dP_inft, dP0) = periodic_kernel.sde() + H = np.vstack((H, H)) # make 2D measurements + R = 1.5 * np.eye(measurement_dim) + + state_dim = dFt.shape[0] param_num = dFt.shape[2] - - + grad_calc_params = {} - grad_calc_params['dP_inf'] = dP_inft - grad_calc_params['dF'] = dFt - grad_calc_params['dQc'] = dQct - grad_calc_params['dR'] = np.zeros((measurement_dim,measurement_dim,param_num)) - grad_calc_params['dP_init'] = dP0 - # dH matrix is None - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, R, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=False, - kalman_filter_type='regular', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - - (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, R, P_inf, X_data, Y_data, index = None, - m_init=None, P_init=P0, use_cython=False, - kalman_filter_type='rbc', - calc_log_likelihood=True, - calc_grad_log_likelihood=True, - grad_params_no=param_num, grad_calc_params=grad_calc_params) - -# (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, R, P_inf, X_data, Y_data, index = None, -# m_init=None, P_init=P0, use_cython=True, -# kalman_filter_type='rbc', -# calc_log_likelihood=True, -# calc_grad_log_likelihood=True, -# grad_params_no=param_num, grad_calc_params=grad_calc_params) - - if plot: + grad_calc_params["dP_inf"] = dP_inft + grad_calc_params["dF"] = dFt + grad_calc_params["dQc"] = dQct + grad_calc_params["dR"] = np.zeros((measurement_dim, measurement_dim, param_num)) + grad_calc_params["dP_init"] = dP0 + # dH matrix is None + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + R, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=False, + kalman_filter_type="regular", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + (f_mean, f_var) = self.run_continuous_model( + F, + L, + Qc, + H, + R, + P_inf, + X_data, + Y_data, + index=None, + m_init=None, + P_init=P0, + use_cython=False, + kalman_filter_type="rbc", + calc_log_likelihood=True, + calc_grad_log_likelihood=True, + grad_params_no=param_num, + grad_calc_params=grad_calc_params, + ) + + # (f_mean, f_var) = self.run_continuous_model(F, L, Qc, H, R, P_inf, X_data, Y_data, index = None, + # m_init=None, P_init=P0, use_cython=True, + # kalman_filter_type='rbc', + # calc_log_likelihood=True, + # calc_grad_log_likelihood=True, + # grad_params_no=param_num, grad_calc_params=grad_calc_params) + + if plot: # plotting -> plt.figure() - plt.plot(X_data, np.squeeze(Y_data[:,0,1]), 'g.-', label='measurements') - plt.plot(X_data, np.squeeze(f_mean[1:,15,1]), 'b.-',label='Kalman filter estimates') - plt.plot(X_data, np.squeeze(f_mean[1:,15,1])+np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') - plt.plot(X_data, np.squeeze(f_mean[1:,15,1])-np.einsum('ij,ajk,kl', H, f_var[1:], H.T)[:,0,0], 'b--') -# plt.plot( np.squeeze(M_sm[1:,15,1]), 'r.-',label='Smoother Estimates') -# plt.plot( np.squeeze(M_sm[1:,15,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') -# plt.plot( np.squeeze(M_sm[1:,15,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + plt.plot(X_data, np.squeeze(Y_data[:, 0, 1]), "g.-", label="measurements") + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15, 1]), + "b.-", + label="Kalman filter estimates", + ) + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15, 1]) + + np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + plt.plot( + X_data, + np.squeeze(f_mean[1:, 15, 1]) + - np.einsum("ij,ajk,kl", H, f_var[1:], H.T)[:, 0, 0], + "b--", + ) + # plt.plot( np.squeeze(M_sm[1:,15,1]), 'r.-',label='Smoother Estimates') + # plt.plot( np.squeeze(M_sm[1:,15,1])+np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') + # plt.plot( np.squeeze(M_sm[1:,15,1])-np.einsum('ij,ajk,kl', H, P_sm[1:], H.T)[:,0,0], 'r--') plt.legend() plt.title("1D measurements, 3 ts_no. 2-nd ts ploted") plt.show() # plotting <- - # 2D measurements, 3 ts_no <- - -#def test_EM_gradient(plot=False): + # 2D measurements, 3 ts_no <- + + +# def test_EM_gradient(plot=False): # """ # Test EM gradient calculation. This method works (the formulas are such) # that it works only for time invariant matrices A, Q, H, R. For the continuous # model it means that time intervals are the same. -# """ -# +# """ +# # np.random.seed(234) # seed the random number generator -# +# # # 1D measurements, 1 ts_no -> -# measurement_dim = 1 # dimensionality of measurement -# +# measurement_dim = 1 # dimensionality of measurement +# # x_data = generate_x_points(points_num=10, x_interval = (0, 20), random=False) # data = generate_random_y_data(10, 1, 1) # np.array((samples, dim, ts_no)) -# +# # import GPy # #periodic_kernel = GPy.kern.sde_Matern32(1,active_dims=[0,]) # periodic_kernel = GPy.kern.sde_StdPeriodic(1,active_dims=[0,]) -# (F,L,Qc,H,P_inf,P0, dFt,dQct,dP_inft,dP0t) = periodic_kernel.sde() -# -# state_dim = dFt.shape[0]; +# (F,L,Qc,H,P_inf,P0, dFt,dQct,dP_inft,dP0t) = periodic_kernel.sde() +# +# state_dim = dFt.shape[0]; # param_num = dFt.shape[2] -# +# # grad_calc_params = {} # grad_calc_params['dP_inf'] = dP_inft # grad_calc_params['dF'] = dFt # grad_calc_params['dQc'] = dQct # grad_calc_params['dR'] = np.zeros((measurement_dim,measurement_dim,param_num)) # grad_calc_params['dP_init'] = dP0t -# # dH matrix is None -# +# # dH matrix is None +# # # #(F,L,Qc,H,P_inf,dF,dQc,dP_inf) = ssm.balance_ss_model(F,L,Qc,H,P_inf,dF,dQc,dP_inf) # # Use the Kalman filter to evaluate the likelihood -# +# # #import pdb; pdb.set_trace() -# (M_kf, P_kf, log_likelihood, +# (M_kf, P_kf, log_likelihood, # grad_log_likelihood,SmootherMatrObject) = ss.ContDescrStateSpace.cont_discr_kalman_filter(F, # L, Qc, H, 1.5, P_inf, x_data, data, m_init=None, -# P_init=P0, calc_log_likelihood=True, -# calc_grad_log_likelihood=True, -# grad_params_no=param_num, +# P_init=P0, calc_log_likelihood=True, +# calc_grad_log_likelihood=True, +# grad_params_no=param_num, # grad_calc_params=grad_calc_params) -# -# if plot: +# +# if plot: # # plotting -> # plt.figure() # plt.plot( np.squeeze(data[:,0]), 'g.-', label='measurements') @@ -963,15 +1516,13 @@ class StateSpaceKernelsTests(np.testing.TestCase): # plt.show() # # plotting <- # # 1D measurements, 1 ts_no <- - -if __name__ == '__main__': + +if __name__ == "__main__": print("Running state-space inference tests...") unittest.main() - - #tt = StateSpaceKernelsTests('test_discrete_ss_first') - #res = tt.test_discrete_ss_first(plot=True) - #res = tt.test_discrete_ss_1D(plot=True) - #res = tt.test_discrete_ss_2D(plot=False) - #res = tt.test_continuos_ss(plot=True) - - + + # tt = StateSpaceKernelsTests('test_discrete_ss_first') + # res = tt.test_discrete_ss_first(plot=True) + # res = tt.test_discrete_ss_1D(plot=True) + # res = tt.test_discrete_ss_2D(plot=False) + # res = tt.test_continuos_ss(plot=True) From 5f08c2c139fc4d023d00a3e9a60946249c9fd087 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:00:18 +0200 Subject: [PATCH 053/101] migrate state_space_main_tests to pytest --- GPy/testing/state_space_main_tests.py | 33 ++++++++++----------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/GPy/testing/state_space_main_tests.py b/GPy/testing/state_space_main_tests.py index 0b8db023..898eaa90 100644 --- a/GPy/testing/state_space_main_tests.py +++ b/GPy/testing/state_space_main_tests.py @@ -262,10 +262,7 @@ def generate_random_y_data(samples, dim, ts_no): return Y -class StateSpaceKernelsTests(np.testing.TestCase): - def setUp(self): - pass - +class TestStateSpaceKernels: def run_descr_model( self, measurements, @@ -290,12 +287,14 @@ class StateSpaceKernelsTests(np.testing.TestCase): state_dim = 1 if not isinstance(A, np.ndarray) else A.shape[0] ts_no = 1 if (len(measurements.shape) < 3) else measurements.shape[2] + import importlib + grad_params_no = None if dA is None else dA.shape[2] ss_setup.use_cython = use_cython global ssm if (ssm.cython_code_available) and (ssm.use_cython != use_cython): - reload(ssm) + importlib.reload(ssm.DescreteStateSpace) grad_calc_params = None if calc_grad_log_likelihood: @@ -328,7 +327,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): ) f_mean_squeezed = np.squeeze(f_mean[1:, :]) # exclude initial value - f_var_squeezed = np.squeeze(f_var[1:, :]) # exclude initial value + _f_var_squeezed = np.squeeze(f_var[1:, :]) # exclude initial value if true_states is not None: # print np.max(np.abs(f_mean_squeezed-true_states)) @@ -345,7 +344,7 @@ class StateSpaceKernelsTests(np.testing.TestCase): f_var.shape, (measurements.shape[0] + 1, state_dim, state_dim) ) - (M_smooth, P_smooth) = ssm.DescreteStateSpace.rts_smoother( + (_M_smooth, _P_smooth) = ssm.DescreteStateSpace.rts_smoother( state_dim, dynamic_callables_smoother, f_mean, f_var ) @@ -376,10 +375,12 @@ class StateSpaceKernelsTests(np.testing.TestCase): state_dim = 1 if not isinstance(F, np.ndarray) else F.shape[0] ts_no = 1 if (len(Y_data.shape) < 3) else Y_data.shape[2] + import importlib + ss_setup.use_cython = use_cython global ssm if (ssm.cython_code_available) and (ssm.use_cython != use_cython): - reload(ssm) + importlib.reload(ssm) ( f_mean, @@ -406,15 +407,15 @@ class StateSpaceKernelsTests(np.testing.TestCase): grad_calc_params=grad_calc_params, ) - f_mean_squeezed = np.squeeze(f_mean[1:, :]) # exclude initial value - f_var_squeezed = np.squeeze(f_var[1:, :]) # exclude initial value + _f_mean_squeezed = np.squeeze(f_mean[1:, :]) # exclude initial value + _f_var_squeezed = np.squeeze(f_var[1:, :]) # exclude initial value np.testing.assert_equal(f_mean.shape, (Y_data.shape[0] + 1, state_dim, ts_no)) np.testing.assert_equal( f_var.shape, (Y_data.shape[0] + 1, state_dim, state_dim) ) - (M_smooth, P_smooth) = ssm.ContDescrStateSpace.cont_discr_rts_smoother( + (_M_smooth, _P_smooth) = ssm.ContDescrStateSpace.cont_discr_rts_smoother( state_dim, f_mean, f_var, dynamic_callables_smoother ) @@ -1516,13 +1517,3 @@ class StateSpaceKernelsTests(np.testing.TestCase): # plt.show() # # plotting <- # # 1D measurements, 1 ts_no <- - -if __name__ == "__main__": - print("Running state-space inference tests...") - unittest.main() - - # tt = StateSpaceKernelsTests('test_discrete_ss_first') - # res = tt.test_discrete_ss_first(plot=True) - # res = tt.test_discrete_ss_1D(plot=True) - # res = tt.test_discrete_ss_2D(plot=False) - # res = tt.test_continuos_ss(plot=True) From a9e65c965b3c2a6124d17abef4f959d6924fd473 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:00:34 +0200 Subject: [PATCH 054/101] format on save --- GPy/testing/svgp_tests.py | 42 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/GPy/testing/svgp_tests.py b/GPy/testing/svgp_tests.py index beb9c00d..3729d3f0 100644 --- a/GPy/testing/svgp_tests.py +++ b/GPy/testing/svgp_tests.py @@ -1,54 +1,60 @@ import numpy as np -import scipy as sp import GPy + class SVGP_nonconvex(np.testing.TestCase): """ Inference in the SVGP with a student-T likelihood """ + def setUp(self): - X = np.linspace(0,10,100).reshape(-1,1) - Z = np.linspace(0,10,10).reshape(-1,1) - Y = np.sin(X) + np.random.randn(*X.shape)*0.1 + X = np.linspace(0, 10, 100).reshape(-1, 1) + Z = np.linspace(0, 10, 10).reshape(-1, 1) + Y = np.sin(X) + np.random.randn(*X.shape) * 0.1 Y[50] += 3 lik = GPy.likelihoods.StudentT(deg_free=2) - k = GPy.kern.RBF(1, lengthscale=5.) + GPy.kern.White(1, 1e-6) + k = GPy.kern.RBF(1, lengthscale=5.0) + GPy.kern.White(1, 1e-6) self.m = GPy.core.SVGP(X, Y, Z=Z, likelihood=lik, kernel=k) + def test_grad(self): assert self.m.checkgrad(step=1e-4) + class SVGP_classification(np.testing.TestCase): """ Inference in the SVGP with a Bernoulli likelihood """ + def setUp(self): - X = np.linspace(0,10,100).reshape(-1,1) - Z = np.linspace(0,10,10).reshape(-1,1) - Y = np.where((np.sin(X) + np.random.randn(*X.shape)*0.1)>0, 1,0) + X = np.linspace(0, 10, 100).reshape(-1, 1) + Z = np.linspace(0, 10, 10).reshape(-1, 1) + Y = np.where((np.sin(X) + np.random.randn(*X.shape) * 0.1) > 0, 1, 0) lik = GPy.likelihoods.Bernoulli() - k = GPy.kern.RBF(1, lengthscale=5.) + GPy.kern.White(1, 1e-6) + k = GPy.kern.RBF(1, lengthscale=5.0) + GPy.kern.White(1, 1e-6) self.m = GPy.core.SVGP(X, Y, Z=Z, likelihood=lik, kernel=k) + def test_grad(self): assert self.m.checkgrad(step=1e-4) + class SVGP_Poisson_with_meanfunction(np.testing.TestCase): """ Inference in the SVGP with a Bernoulli likelihood """ - def setUp(self): - X = np.linspace(0,10,100).reshape(-1,1) - Z = np.linspace(0,10,10).reshape(-1,1) - latent_f = np.exp(0.1*X * 0.05*X**2) - Y = np.array([np.random.poisson(f) for f in latent_f.flatten()]).reshape(-1,1) - mf = GPy.mappings.Linear(1,1) + def setUp(self): + X = np.linspace(0, 10, 100).reshape(-1, 1) + Z = np.linspace(0, 10, 10).reshape(-1, 1) + latent_f = np.exp(0.1 * X * 0.05 * X**2) + Y = np.array([np.random.poisson(f) for f in latent_f.flatten()]).reshape(-1, 1) + + mf = GPy.mappings.Linear(1, 1) lik = GPy.likelihoods.Poisson() - k = GPy.kern.RBF(1, lengthscale=5.) + GPy.kern.White(1, 1e-6) + k = GPy.kern.RBF(1, lengthscale=5.0) + GPy.kern.White(1, 1e-6) self.m = GPy.core.SVGP(X, Y, Z=Z, likelihood=lik, kernel=k, mean_function=mf) + def test_grad(self): assert self.m.checkgrad(step=1e-4) - - From 4b427de8fa0ad2276f0cb9593b018965b5d941dc Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:01:25 +0200 Subject: [PATCH 055/101] migrate svgp_tests to pytest --- GPy/testing/svgp_tests.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/GPy/testing/svgp_tests.py b/GPy/testing/svgp_tests.py index 3729d3f0..e6785d42 100644 --- a/GPy/testing/svgp_tests.py +++ b/GPy/testing/svgp_tests.py @@ -2,12 +2,12 @@ import numpy as np import GPy -class SVGP_nonconvex(np.testing.TestCase): +class TestSVGP_nonconvex: """ Inference in the SVGP with a student-T likelihood """ - def setUp(self): + def setup(self): X = np.linspace(0, 10, 100).reshape(-1, 1) Z = np.linspace(0, 10, 10).reshape(-1, 1) Y = np.sin(X) + np.random.randn(*X.shape) * 0.1 @@ -18,15 +18,16 @@ class SVGP_nonconvex(np.testing.TestCase): self.m = GPy.core.SVGP(X, Y, Z=Z, likelihood=lik, kernel=k) def test_grad(self): + self.setup() assert self.m.checkgrad(step=1e-4) -class SVGP_classification(np.testing.TestCase): +class TestSVGP_classification: """ Inference in the SVGP with a Bernoulli likelihood """ - def setUp(self): + def setup(self): X = np.linspace(0, 10, 100).reshape(-1, 1) Z = np.linspace(0, 10, 10).reshape(-1, 1) Y = np.where((np.sin(X) + np.random.randn(*X.shape) * 0.1) > 0, 1, 0) @@ -36,15 +37,16 @@ class SVGP_classification(np.testing.TestCase): self.m = GPy.core.SVGP(X, Y, Z=Z, likelihood=lik, kernel=k) def test_grad(self): + self.setup() assert self.m.checkgrad(step=1e-4) -class SVGP_Poisson_with_meanfunction(np.testing.TestCase): +class TestSVGP_Poisson_with_meanfunction: """ Inference in the SVGP with a Bernoulli likelihood """ - def setUp(self): + def setup(self): X = np.linspace(0, 10, 100).reshape(-1, 1) Z = np.linspace(0, 10, 10).reshape(-1, 1) latent_f = np.exp(0.1 * X * 0.05 * X**2) @@ -57,4 +59,5 @@ class SVGP_Poisson_with_meanfunction(np.testing.TestCase): self.m = GPy.core.SVGP(X, Y, Z=Z, likelihood=lik, kernel=k, mean_function=mf) def test_grad(self): + self.setup() assert self.m.checkgrad(step=1e-4) From e92f6df897f44983cb4c4518d33bb4a701986abb Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:01:46 +0200 Subject: [PATCH 056/101] format on save --- GPy/testing/tp_tests.py | 43 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/GPy/testing/tp_tests.py b/GPy/testing/tp_tests.py index 643d67e0..ac35e38f 100644 --- a/GPy/testing/tp_tests.py +++ b/GPy/testing/tp_tests.py @@ -1,10 +1,11 @@ -''' +""" Created on 14 Jul 2017, based on gp_tests @author: javdrher -''' +""" import unittest -import numpy as np, GPy +import numpy as np +import GPy class Test(unittest.TestCase): @@ -13,9 +14,9 @@ class Test(unittest.TestCase): self.N = 20 self.N_new = 50 self.D = 1 - self.X = np.random.uniform(-3., 3., (self.N, 1)) + self.X = np.random.uniform(-3.0, 3.0, (self.N, 1)) self.Y = np.sin(self.X) + np.random.randn(self.N, self.D) * 0.05 - self.X_new = np.random.uniform(-3., 3., (self.N_new, 1)) + self.X_new = np.random.uniform(-3.0, 3.0, (self.N_new, 1)) def test_setxy_gp(self): k = GPy.kern.RBF(1) + GPy.kern.White(1) @@ -23,7 +24,7 @@ class Test(unittest.TestCase): mu, var = m.predict(m.X) X = m.X.copy() m.set_XY(m.X[:10], m.Y[:10]) - assert (m.checkgrad(tolerance=1e-2)) + assert m.checkgrad(tolerance=1e-2) m.set_XY(X, self.Y) mu2, var2 = m.predict(m.X) np.testing.assert_allclose(mu, mu2) @@ -34,9 +35,9 @@ class Test(unittest.TestCase): from GPy.core.mapping import Mapping class Parabola(Mapping): - def __init__(self, variance, degree=2, name='parabola'): + def __init__(self, variance, degree=2, name="parabola"): super(Parabola, self).__init__(1, 1, name) - self.variance = Param('variance', np.ones(degree + 1) * variance) + self.variance = Param("variance", np.ones(degree + 1) * variance) self.degree = degree self.link_parameter(self.variance) @@ -59,12 +60,17 @@ class Test(unittest.TestCase): X = np.linspace(-2, 2, 100)[:, None] k = GPy.kern.RBF(1) + GPy.kern.White(1) k.randomize() - p = Parabola(.3) + p = Parabola(0.3) p.randomize() - Y = p.f(X) + np.random.multivariate_normal(np.zeros(X.shape[0]), k.K(X) + np.eye(X.shape[0]) * 1e-8)[:, - None] + np.random.normal(0, .1, (X.shape[0], 1)) + Y = ( + p.f(X) + + np.random.multivariate_normal( + np.zeros(X.shape[0]), k.K(X) + np.eye(X.shape[0]) * 1e-8 + )[:, None] + + np.random.normal(0, 0.1, (X.shape[0], 1)) + ) m = GPy.models.TPRegression(X, Y, kernel=k, mean_function=p) - assert (m.checkgrad(tolerance=2e-1)) + assert m.checkgrad(tolerance=2e-1) _ = m.predict(m.X) def test_normalizer(self): @@ -73,7 +79,7 @@ class Test(unittest.TestCase): mu, std = Y.mean(0), Y.std(0) m = GPy.models.TPRegression(self.X, Y, kernel=k, normalizer=True) m.optimize() - assert (m.checkgrad()) + assert m.checkgrad() k = GPy.kern.RBF(1) + GPy.kern.White(1) m2 = GPy.models.TPRegression(self.X, (Y - mu) / std, kernel=k, normalizer=False) m2[:] = m[:] @@ -81,13 +87,13 @@ class Test(unittest.TestCase): mu1, var1 = m.predict(m.X, full_cov=True) mu2, var2 = m2.predict(m2.X, full_cov=True) np.testing.assert_allclose(mu1, (mu2 * std) + mu) - np.testing.assert_allclose(var1, var2 * std ** 2) + np.testing.assert_allclose(var1, var2 * std**2) mu1, var1 = m.predict(m.X, full_cov=False) mu2, var2 = m2.predict(m2.X, full_cov=False) np.testing.assert_allclose(mu1, (mu2 * std) + mu) - np.testing.assert_allclose(var1, var2 * std ** 2) + np.testing.assert_allclose(var1, var2 * std**2) q50n = m.predict_quantiles(m.X, (50,)) q50 = m2.predict_quantiles(m2.X, (50,)) @@ -102,8 +108,11 @@ class Test(unittest.TestCase): q95 = m2.predict_quantiles(self.X[[c]], qs) mu, var = m2.predict(self.X[[c]]) from scipy.stats import t - np.testing.assert_allclose((mu + (t.ppf(qs / 100., m2.nu + m2.num_data) * np.sqrt(var))).flatten(), - np.array(q95).flatten()) + + np.testing.assert_allclose( + (mu + (t.ppf(qs / 100.0, m2.nu + m2.num_data) * np.sqrt(var))).flatten(), + np.array(q95).flatten(), + ) def test_predict_equivalence(self): k = GPy.kern.RBF(1) + GPy.kern.White(1) From 323d29bc7d4a052b43a59f484c7fc332acd80370 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:02:59 +0200 Subject: [PATCH 057/101] migrate tp_tests to pytest --- GPy/testing/tp_tests.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/GPy/testing/tp_tests.py b/GPy/testing/tp_tests.py index ac35e38f..c01657c0 100644 --- a/GPy/testing/tp_tests.py +++ b/GPy/testing/tp_tests.py @@ -3,13 +3,12 @@ Created on 14 Jul 2017, based on gp_tests @author: javdrher """ -import unittest import numpy as np import GPy -class Test(unittest.TestCase): - def setUp(self): +class TestTP: + def setup(self): np.random.seed(12345) self.N = 20 self.N_new = 50 @@ -19,6 +18,7 @@ class Test(unittest.TestCase): self.X_new = np.random.uniform(-3.0, 3.0, (self.N_new, 1)) def test_setxy_gp(self): + self.setup() k = GPy.kern.RBF(1) + GPy.kern.White(1) m = GPy.models.TPRegression(self.X, self.Y, kernel=k) mu, var = m.predict(m.X) @@ -34,6 +34,8 @@ class Test(unittest.TestCase): from GPy.core.parameterization.param import Param from GPy.core.mapping import Mapping + self.setup() + class Parabola(Mapping): def __init__(self, variance, degree=2, name="parabola"): super(Parabola, self).__init__(1, 1, name) @@ -74,6 +76,8 @@ class Test(unittest.TestCase): _ = m.predict(m.X) def test_normalizer(self): + self.setup() + k = GPy.kern.RBF(1) + GPy.kern.White(1) Y = self.Y mu, std = Y.mean(0), Y.std(0) @@ -115,6 +119,8 @@ class Test(unittest.TestCase): ) def test_predict_equivalence(self): + self.setup() + k = GPy.kern.RBF(1) + GPy.kern.White(1) m = GPy.models.TPRegression(self.X, self.Y, kernel=k) m.optimize() @@ -133,10 +139,12 @@ class Test(unittest.TestCase): mu3, var3 = m2._raw_predict(m.X) np.testing.assert_allclose(mu1, mu2) np.testing.assert_allclose(var1, var2) - self.assertFalse(np.allclose(mu1, mu3)) - self.assertFalse(np.allclose(var1, var3)) + assert not np.allclose(mu1, mu3) + assert not np.allclose(var1, var3) def test_gp_equivalence(self): + self.setup() + k = GPy.kern.RBF(1) m = GPy.models.GPRegression(self.X, self.Y, kernel=k) m.optimize() @@ -148,7 +156,3 @@ class Test(unittest.TestCase): mu2, var2 = m2.predict(self.X) np.testing.assert_allclose(mu1, mu2) np.testing.assert_allclose(var1, var2) - - -if __name__ == "__main__": - unittest.main() From 975fb7e38335f6cd55152a7e63ca27f04371f779 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:03:23 +0200 Subject: [PATCH 058/101] format on save --- GPy/testing/util_tests.py | 253 +++++++++++++++++++++----------------- 1 file changed, 143 insertions(+), 110 deletions(-) diff --git a/GPy/testing/util_tests.py b/GPy/testing/util_tests.py index bdab63e8..dc21c8ab 100644 --- a/GPy/testing/util_tests.py +++ b/GPy/testing/util_tests.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (c) 2016, Max Zwiessele, Alan Saul # All rights reserved. # @@ -26,150 +26,169 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#=============================================================================== +# =============================================================================== -import unittest import numpy as np import GPy -class TestDebug(unittest.TestCase): + +class UtilTest: def test_checkFinite(self): from GPy.util.debug import checkFinite - array = np.random.normal(0, 1, 100).reshape(25,4) - self.assertTrue(checkFinite(array, name='test')) - array[np.random.binomial(1, .3, array.shape).astype(bool)] = np.nan + array = np.random.normal(0, 1, 100).reshape(25, 4) + self.assertTrue(checkFinite(array, name="test")) + + array[np.random.binomial(1, 0.3, array.shape).astype(bool)] = np.nan self.assertFalse(checkFinite(array)) def test_checkFullRank(self): from GPy.util.debug import checkFullRank from GPy.util.linalg import tdot - array = np.random.normal(0, 1, 100).reshape(25,4) - self.assertFalse(checkFullRank(tdot(array), name='test')) - array = np.random.normal(0, 1, (25,25)) + array = np.random.normal(0, 1, 100).reshape(25, 4) + self.assertFalse(checkFullRank(tdot(array), name="test")) + + array = np.random.normal(0, 1, (25, 25)) self.assertTrue(checkFullRank(tdot(array))) def test_fixed_inputs_median(self): - """ test fixed_inputs convenience function """ + """test fixed_inputs convenience function""" from GPy.plotting.matplot_dep.util import fixed_inputs import GPy + X = np.random.randn(10, 3) - Y = np.sin(X) + np.random.randn(10, 3)*1e-3 + Y = np.sin(X) + np.random.randn(10, 3) * 1e-3 m = GPy.models.GPRegression(X, Y) - fixed = fixed_inputs(m, [1], fix_routine='median', as_list=True, X_all=False) - self.assertTrue((0, np.median(X[:,0])) in fixed) - self.assertTrue((2, np.median(X[:,2])) in fixed) - self.assertTrue(len([t for t in fixed if t[0] == 1]) == 0) # Unfixed input should not be in fixed + fixed = fixed_inputs(m, [1], fix_routine="median", as_list=True, X_all=False) + self.assertTrue((0, np.median(X[:, 0])) in fixed) + self.assertTrue((2, np.median(X[:, 2])) in fixed) + self.assertTrue( + len([t for t in fixed if t[0] == 1]) == 0 + ) # Unfixed input should not be in fixed def test_fixed_inputs_mean(self): from GPy.plotting.matplot_dep.util import fixed_inputs import GPy + X = np.random.randn(10, 3) - Y = np.sin(X) + np.random.randn(10, 3)*1e-3 + Y = np.sin(X) + np.random.randn(10, 3) * 1e-3 m = GPy.models.GPRegression(X, Y) - fixed = fixed_inputs(m, [1], fix_routine='mean', as_list=True, X_all=False) - self.assertTrue((0, np.mean(X[:,0])) in fixed) - self.assertTrue((2, np.mean(X[:,2])) in fixed) - self.assertTrue(len([t for t in fixed if t[0] == 1]) == 0) # Unfixed input should not be in fixed + fixed = fixed_inputs(m, [1], fix_routine="mean", as_list=True, X_all=False) + self.assertTrue((0, np.mean(X[:, 0])) in fixed) + self.assertTrue((2, np.mean(X[:, 2])) in fixed) + self.assertTrue( + len([t for t in fixed if t[0] == 1]) == 0 + ) # Unfixed input should not be in fixed def test_fixed_inputs_zero(self): from GPy.plotting.matplot_dep.util import fixed_inputs import GPy + X = np.random.randn(10, 3) - Y = np.sin(X) + np.random.randn(10, 3)*1e-3 + Y = np.sin(X) + np.random.randn(10, 3) * 1e-3 m = GPy.models.GPRegression(X, Y) - fixed = fixed_inputs(m, [1], fix_routine='zero', as_list=True, X_all=False) + fixed = fixed_inputs(m, [1], fix_routine="zero", as_list=True, X_all=False) self.assertTrue((0, 0.0) in fixed) self.assertTrue((2, 0.0) in fixed) - self.assertTrue(len([t for t in fixed if t[0] == 1]) == 0) # Unfixed input should not be in fixed + self.assertTrue( + len([t for t in fixed if t[0] == 1]) == 0 + ) # Unfixed input should not be in fixed def test_fixed_inputs_uncertain(self): from GPy.plotting.matplot_dep.util import fixed_inputs import GPy from GPy.core.parameterization.variational import NormalPosterior + X_mu = np.random.randn(10, 3) X_var = np.random.randn(10, 3) X = NormalPosterior(X_mu, X_var) - Y = np.sin(X_mu) + np.random.randn(10, 3)*1e-3 + Y = np.sin(X_mu) + np.random.randn(10, 3) * 1e-3 m = GPy.models.BayesianGPLVM(Y, X=X_mu, X_variance=X_var, input_dim=3) - fixed = fixed_inputs(m, [1], fix_routine='median', as_list=True, X_all=False) - self.assertTrue((0, np.median(X.mean.values[:,0])) in fixed) - self.assertTrue((2, np.median(X.mean.values[:,2])) in fixed) - self.assertTrue(len([t for t in fixed if t[0] == 1]) == 0) # Unfixed input should not be in fixed + fixed = fixed_inputs(m, [1], fix_routine="median", as_list=True, X_all=False) + self.assertTrue((0, np.median(X.mean.values[:, 0])) in fixed) + self.assertTrue((2, np.median(X.mean.values[:, 2])) in fixed) + self.assertTrue( + len([t for t in fixed if t[0] == 1]) == 0 + ) # Unfixed input should not be in fixed def test_DSYR(self): from GPy.util.linalg import DSYR, DSYR_numpy - A = np.arange(9.0).reshape(3,3) + + A = np.arange(9.0).reshape(3, 3) A = np.dot(A.T, A) b = np.ones(3, dtype=float) alpha = 1.0 DSYR(A, b, alpha) - R = np.array([ - [46, 55, 64], - [55, 67, 79], - [64, 79, 94]] - ) + R = np.array([[46, 55, 64], [55, 67, 79], [64, 79, 94]]) self.assertTrue(abs(np.sum(A - R)) < 1e-12) def test_subarray(self): import GPy - X = np.zeros((3,6), dtype=bool) - X[[1,1,1],[0,4,5]] = 1 - X[1:,[2,3]] = 1 - d = GPy.util.subarray_and_sorting.common_subarrays(X,axis=1) + + X = np.zeros((3, 6), dtype=bool) + X[[1, 1, 1], [0, 4, 5]] = 1 + X[1:, [2, 3]] = 1 + d = GPy.util.subarray_and_sorting.common_subarrays(X, axis=1) self.assertTrue(len(d) == 3) - X[:, d[tuple(X[:,0])]] - self.assertTrue(d[tuple(X[:,4])] == d[tuple(X[:,0])] == [0, 4, 5]) - self.assertTrue(d[tuple(X[:,1])] == [1]) + X[:, d[tuple(X[:, 0])]] + self.assertTrue(d[tuple(X[:, 4])] == d[tuple(X[:, 0])] == [0, 4, 5]) + self.assertTrue(d[tuple(X[:, 1])] == [1]) def test_offset_cluster(self): - #Tests the GPy.util.cluster_with_offset.cluster utility with a small - #test data set. Not using random noise just in case it occasionally - #causes it not to cluster correctly. - #groundtruth cluster identifiers are: [0,1,1,0] + # Tests the GPy.util.cluster_with_offset.cluster utility with a small + # test data set. Not using random noise just in case it occasionally + # causes it not to cluster correctly. + # groundtruth cluster identifiers are: [0,1,1,0] - #data contains a list of the four sets of time series (3 per data point) + # data contains a list of the four sets of time series (3 per data point) - data = [np.array([[ 2.18094245, 1.96529789, 2.00265523, 2.18218742, 2.06795428], - [ 1.62254829, 1.75748448, 1.83879347, 1.87531326, 1.52503496], - [ 1.54589609, 1.61607914, 2.00463192, 1.48771394, 1.63339218]]), - np.array([[ 2.86766106, 2.97953437, 2.91958876, 2.92510506, 3.03239241], - [ 2.57368423, 2.59954886, 3.10000395, 2.75806125, 2.89865704], - [ 2.58916318, 2.53698259, 2.63858411, 2.63102504, 2.51853901]]), - np.array([[ 2.77834168, 2.9618564 , 2.88482141, 3.24259745, 2.9716821 ], - [ 2.60675576, 2.67095624, 2.94824436, 2.80520631, 2.87247516], - [ 2.49543562, 2.5492281 , 2.6505866 , 2.65015308, 2.59738616]]), - np.array([[ 1.76783086, 2.21666738, 2.07939706, 1.9268263 , 2.23360121], - [ 1.94305547, 1.94648592, 2.1278921 , 2.09481457, 2.08575238], - [ 1.69336013, 1.72285186, 1.6339506 , 1.61212022, 1.39198698]])] + data = [ + np.array( + [ + [2.18094245, 1.96529789, 2.00265523, 2.18218742, 2.06795428], + [1.62254829, 1.75748448, 1.83879347, 1.87531326, 1.52503496], + [1.54589609, 1.61607914, 2.00463192, 1.48771394, 1.63339218], + ] + ), + np.array( + [ + [2.86766106, 2.97953437, 2.91958876, 2.92510506, 3.03239241], + [2.57368423, 2.59954886, 3.10000395, 2.75806125, 2.89865704], + [2.58916318, 2.53698259, 2.63858411, 2.63102504, 2.51853901], + ] + ), + np.array( + [ + [2.77834168, 2.9618564, 2.88482141, 3.24259745, 2.9716821], + [2.60675576, 2.67095624, 2.94824436, 2.80520631, 2.87247516], + [2.49543562, 2.5492281, 2.6505866, 2.65015308, 2.59738616], + ] + ), + np.array( + [ + [1.76783086, 2.21666738, 2.07939706, 1.9268263, 2.23360121], + [1.94305547, 1.94648592, 2.1278921, 2.09481457, 2.08575238], + [1.69336013, 1.72285186, 1.6339506, 1.61212022, 1.39198698], + ] + ), + ] - #inputs contains their associated X values + # inputs contains their associated X values - inputs = [np.array([[ 0. ], - [ 0.68040097], - [ 1.20316795], - [ 1.798749 ], - [ 2.14891733]]), np.array([[ 0. ], - [ 0.51910637], - [ 0.98259352], - [ 1.57442965], - [ 1.82515098]]), np.array([[ 0. ], - [ 0.66645478], - [ 1.59464591], - [ 1.69769551], - [ 1.80932752]]), np.array([[ 0. ], - [ 0.87512108], - [ 1.71881079], - [ 2.67162871], - [ 3.23761907]])] + inputs = [ + np.array([[0.0], [0.68040097], [1.20316795], [1.798749], [2.14891733]]), + np.array([[0.0], [0.51910637], [0.98259352], [1.57442965], [1.82515098]]), + np.array([[0.0], [0.66645478], [1.59464591], [1.69769551], [1.80932752]]), + np.array([[0.0], [0.87512108], [1.71881079], [2.67162871], [3.23761907]]), + ] - #try doing the clustering - active = GPy.util.cluster_with_offset.cluster(data,inputs) - #check to see that the clustering has correctly clustered the time series. + # try doing the clustering + active = GPy.util.cluster_with_offset.cluster(data, inputs) + # check to see that the clustering has correctly clustered the time series. clusters = set([frozenset(cluster) for cluster in active]) - assert set([1,2]) in clusters, "Offset Clustering algorithm failed" - assert set([0,3]) in clusters, "Offset Clustering algoirthm failed" + assert set([1, 2]) in clusters, "Offset Clustering algorithm failed" + assert set([0, 3]) in clusters, "Offset Clustering algoirthm failed" class TestUnivariateGaussian(unittest.TestCase): @@ -178,65 +197,79 @@ class TestUnivariateGaussian(unittest.TestCase): def test_logPdfNormal(self): from GPy.util.univariate_Gaussian import logPdfNormal - pySols = [-13.4189385332, + + pySols = [ + -13.4189385332, -1.2389385332, -0.918938533205, -1.0439385332, -2.9189385332, - -50.9189385332] + -50.9189385332, + ] diff = 0.0 for i in range(len(pySols)): diff += abs(logPdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-10) + self.assertTrue(diff < 1e-10) def test_cdfNormal(self): from GPy.util.univariate_Gaussian import cdfNormal - pySols = [2.86651571879e-07, - 0.211855398583, - 0.5, - 0.691462461274, - 0.977249868052, - 1.0] + + pySols = [ + 2.86651571879e-07, + 0.211855398583, + 0.5, + 0.691462461274, + 0.977249868052, + 1.0, + ] diff = 0.0 for i in range(len(pySols)): diff += abs(cdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-10) + self.assertTrue(diff < 1e-10) def test_logCdfNormal(self): from GPy.util.univariate_Gaussian import logCdfNormal - pySols = [-15.064998394, - -1.55185131919, - -0.69314718056, - -0.368946415289, - -0.023012909329, - 0.0] + + pySols = [ + -15.064998394, + -1.55185131919, + -0.69314718056, + -0.368946415289, + -0.023012909329, + 0.0, + ] diff = 0.0 for i in range(len(pySols)): diff += abs(logCdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-10) + self.assertTrue(diff < 1e-10) + def test_derivLogCdfNormal(self): from GPy.util.univariate_Gaussian import derivLogCdfNormal - pySols = [5.18650396941, - 1.3674022693, - 0.79788456081, - 0.50916043387, - 0.0552478626962, - 0.0] + + pySols = [ + 5.18650396941, + 1.3674022693, + 0.79788456081, + 0.50916043387, + 0.0552478626962, + 0.0, + ] diff = 0.0 for i in range(len(pySols)): - diff += abs(derivLogCdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-8) + diff += abs(derivLogCdfNormal(self.zz[i]) - pySols[i]) + self.assertTrue(diff < 1e-8) + class TestStandardize(unittest.TestCase): def setUp(self): self.normalizer = GPy.util.normalizer.Standardize() - y = np.stack([np.random.randn(10), 2*np.random.randn(10)], axis=1) + y = np.stack([np.random.randn(10), 2 * np.random.randn(10)], axis=1) self.normalizer.scale_by(y) - + def test_inverse_covariance(self): """ Test inverse covariance outputs correct size """ covariance = np.random.rand(100, 100) output = self.normalizer.inverse_covariance(covariance) - self.assertTrue(output.shape == (100, 100, 2)) \ No newline at end of file + self.assertTrue(output.shape == (100, 100, 2)) From e41274586176347b138c502fc196cae54105fdba Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:06:49 +0200 Subject: [PATCH 059/101] migrate util_tests to pytest --- GPy/testing/util_tests.py | 67 ++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/GPy/testing/util_tests.py b/GPy/testing/util_tests.py index dc21c8ab..04f0ed93 100644 --- a/GPy/testing/util_tests.py +++ b/GPy/testing/util_tests.py @@ -37,20 +37,20 @@ class UtilTest: from GPy.util.debug import checkFinite array = np.random.normal(0, 1, 100).reshape(25, 4) - self.assertTrue(checkFinite(array, name="test")) + assert checkFinite(array, name="test") array[np.random.binomial(1, 0.3, array.shape).astype(bool)] = np.nan - self.assertFalse(checkFinite(array)) + assert not checkFinite(array) def test_checkFullRank(self): from GPy.util.debug import checkFullRank from GPy.util.linalg import tdot array = np.random.normal(0, 1, 100).reshape(25, 4) - self.assertFalse(checkFullRank(tdot(array), name="test")) + assert not checkFullRank(tdot(array), name="test") array = np.random.normal(0, 1, (25, 25)) - self.assertTrue(checkFullRank(tdot(array))) + assert checkFullRank(tdot(array)) def test_fixed_inputs_median(self): """test fixed_inputs convenience function""" @@ -61,9 +61,9 @@ class UtilTest: Y = np.sin(X) + np.random.randn(10, 3) * 1e-3 m = GPy.models.GPRegression(X, Y) fixed = fixed_inputs(m, [1], fix_routine="median", as_list=True, X_all=False) - self.assertTrue((0, np.median(X[:, 0])) in fixed) - self.assertTrue((2, np.median(X[:, 2])) in fixed) - self.assertTrue( + assert (0, np.median(X[:, 0])) in fixed + assert (2, np.median(X[:, 2])) in fixed + assert ( len([t for t in fixed if t[0] == 1]) == 0 ) # Unfixed input should not be in fixed @@ -75,9 +75,9 @@ class UtilTest: Y = np.sin(X) + np.random.randn(10, 3) * 1e-3 m = GPy.models.GPRegression(X, Y) fixed = fixed_inputs(m, [1], fix_routine="mean", as_list=True, X_all=False) - self.assertTrue((0, np.mean(X[:, 0])) in fixed) - self.assertTrue((2, np.mean(X[:, 2])) in fixed) - self.assertTrue( + assert (0, np.mean(X[:, 0])) in fixed + assert (2, np.mean(X[:, 2])) in fixed + assert ( len([t for t in fixed if t[0] == 1]) == 0 ) # Unfixed input should not be in fixed @@ -89,9 +89,9 @@ class UtilTest: Y = np.sin(X) + np.random.randn(10, 3) * 1e-3 m = GPy.models.GPRegression(X, Y) fixed = fixed_inputs(m, [1], fix_routine="zero", as_list=True, X_all=False) - self.assertTrue((0, 0.0) in fixed) - self.assertTrue((2, 0.0) in fixed) - self.assertTrue( + assert (0, 0.0) in fixed + assert (2, 0.0) in fixed + assert ( len([t for t in fixed if t[0] == 1]) == 0 ) # Unfixed input should not be in fixed @@ -106,9 +106,9 @@ class UtilTest: Y = np.sin(X_mu) + np.random.randn(10, 3) * 1e-3 m = GPy.models.BayesianGPLVM(Y, X=X_mu, X_variance=X_var, input_dim=3) fixed = fixed_inputs(m, [1], fix_routine="median", as_list=True, X_all=False) - self.assertTrue((0, np.median(X.mean.values[:, 0])) in fixed) - self.assertTrue((2, np.median(X.mean.values[:, 2])) in fixed) - self.assertTrue( + assert (0, np.median(X.mean.values[:, 0])) in fixed + assert (2, np.median(X.mean.values[:, 2])) in fixed + assert ( len([t for t in fixed if t[0] == 1]) == 0 ) # Unfixed input should not be in fixed @@ -121,7 +121,7 @@ class UtilTest: alpha = 1.0 DSYR(A, b, alpha) R = np.array([[46, 55, 64], [55, 67, 79], [64, 79, 94]]) - self.assertTrue(abs(np.sum(A - R)) < 1e-12) + assert abs(np.sum(A - R)) < 1e-12 def test_subarray(self): import GPy @@ -130,10 +130,10 @@ class UtilTest: X[[1, 1, 1], [0, 4, 5]] = 1 X[1:, [2, 3]] = 1 d = GPy.util.subarray_and_sorting.common_subarrays(X, axis=1) - self.assertTrue(len(d) == 3) + assert len(d) == 3 X[:, d[tuple(X[:, 0])]] - self.assertTrue(d[tuple(X[:, 4])] == d[tuple(X[:, 0])] == [0, 4, 5]) - self.assertTrue(d[tuple(X[:, 1])] == [1]) + assert d[tuple(X[:, 4])] == d[tuple(X[:, 0])] == [0, 4, 5] + assert d[tuple(X[:, 1])] == [1] def test_offset_cluster(self): # Tests the GPy.util.cluster_with_offset.cluster utility with a small @@ -191,13 +191,15 @@ class UtilTest: assert set([0, 3]) in clusters, "Offset Clustering algoirthm failed" -class TestUnivariateGaussian(unittest.TestCase): - def setUp(self): +class TestUnivariateGaussian: + def setup(self): self.zz = [-5.0, -0.8, 0.0, 0.5, 2.0, 10.0] def test_logPdfNormal(self): from GPy.util.univariate_Gaussian import logPdfNormal + self.setup() + pySols = [ -13.4189385332, -1.2389385332, @@ -209,11 +211,13 @@ class TestUnivariateGaussian(unittest.TestCase): diff = 0.0 for i in range(len(pySols)): diff += abs(logPdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-10) + assert diff < 1e-10 def test_cdfNormal(self): from GPy.util.univariate_Gaussian import cdfNormal + self.setup() + pySols = [ 2.86651571879e-07, 0.211855398583, @@ -225,11 +229,13 @@ class TestUnivariateGaussian(unittest.TestCase): diff = 0.0 for i in range(len(pySols)): diff += abs(cdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-10) + assert diff < 1e-10 def test_logCdfNormal(self): from GPy.util.univariate_Gaussian import logCdfNormal + self.setup() + pySols = [ -15.064998394, -1.55185131919, @@ -241,11 +247,13 @@ class TestUnivariateGaussian(unittest.TestCase): diff = 0.0 for i in range(len(pySols)): diff += abs(logCdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-10) + assert diff < 1e-10 def test_derivLogCdfNormal(self): from GPy.util.univariate_Gaussian import derivLogCdfNormal + self.setup() + pySols = [ 5.18650396941, 1.3674022693, @@ -257,11 +265,11 @@ class TestUnivariateGaussian(unittest.TestCase): diff = 0.0 for i in range(len(pySols)): diff += abs(derivLogCdfNormal(self.zz[i]) - pySols[i]) - self.assertTrue(diff < 1e-8) + assert diff < 1e-8 -class TestStandardize(unittest.TestCase): - def setUp(self): +class TestStandardize: + def setup(self): self.normalizer = GPy.util.normalizer.Standardize() y = np.stack([np.random.randn(10), 2 * np.random.randn(10)], axis=1) self.normalizer.scale_by(y) @@ -270,6 +278,7 @@ class TestStandardize(unittest.TestCase): """ Test inverse covariance outputs correct size """ + self.setup() covariance = np.random.rand(100, 100) output = self.normalizer.inverse_covariance(covariance) - self.assertTrue(output.shape == (100, 100, 2)) + assert output.shape == (100, 100, 2) From ae5e53a5b91c896fd57e83b6719e681561eaf940 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:07:05 +0200 Subject: [PATCH 060/101] format on save --- GPy/testing/variational_tests.py | 48 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/GPy/testing/variational_tests.py b/GPy/testing/variational_tests.py index 89053b81..cd266f4d 100644 --- a/GPy/testing/variational_tests.py +++ b/GPy/testing/variational_tests.py @@ -1,4 +1,4 @@ -''' +""" Copyright (c) 2015, Max Zwiessele All rights reserved. @@ -26,38 +26,40 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -''' +""" import unittest import GPy, numpy as np -class KLGrad(GPy.core.Model): - def __init__(self, Xvar, kl): - super(KLGrad, self).__init__(name="klgrad") - self.kl = kl - self.link_parameter(Xvar) - self.Xvar = Xvar - self._obj = 0 - def parameters_changed(self): - self.Xvar.gradient[:] = 0 - self.kl.update_gradients_KL(self.Xvar) - self._obj = self.kl.KL_divergence(self.Xvar) - def objective_function(self): - return self._obj - -class Test(unittest.TestCase): +class KLGrad(GPy.core.Model): + def __init__(self, Xvar, kl): + super(KLGrad, self).__init__(name="klgrad") + self.kl = kl + self.link_parameter(Xvar) + self.Xvar = Xvar + self._obj = 0 + + def parameters_changed(self): + self.Xvar.gradient[:] = 0 + self.kl.update_gradients_KL(self.Xvar) + self._obj = self.kl.KL_divergence(self.Xvar) + + def objective_function(self): + return self._obj + + +class Test(unittest.TestCase): def setUp(self): np.random.seed(12345) self.Xvar = GPy.core.parameterization.variational.NormalPosterior( - np.random.uniform(0,1,(10,3)), - np.random.uniform(1e-5,.01, (10,3)) - ) - + np.random.uniform(0, 1, (10, 3)), np.random.uniform(1e-5, 0.01, (10, 3)) + ) def testNormal(self): klgrad = KLGrad(self.Xvar, GPy.core.parameterization.variational.NormalPrior()) np.testing.assert_(klgrad.checkgrad()) + if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.testNormal'] - unittest.main() \ No newline at end of file + # import sys;sys.argv = ['', 'Test.testNormal'] + unittest.main() From 5bab8ca97667e0ebbc416f7f87ad75fc1edbcf27 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 10 Oct 2023 20:07:46 +0200 Subject: [PATCH 061/101] migrate variational_tests to pytest --- GPy/testing/variational_tests.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/GPy/testing/variational_tests.py b/GPy/testing/variational_tests.py index cd266f4d..33197d03 100644 --- a/GPy/testing/variational_tests.py +++ b/GPy/testing/variational_tests.py @@ -27,7 +27,6 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ -import unittest import GPy, numpy as np @@ -48,18 +47,14 @@ class KLGrad(GPy.core.Model): return self._obj -class Test(unittest.TestCase): - def setUp(self): +class TestVariational: + def setup(self): np.random.seed(12345) self.Xvar = GPy.core.parameterization.variational.NormalPosterior( np.random.uniform(0, 1, (10, 3)), np.random.uniform(1e-5, 0.01, (10, 3)) ) - def testNormal(self): + def test_normal(self): + self.setup() klgrad = KLGrad(self.Xvar, GPy.core.parameterization.variational.NormalPrior()) np.testing.assert_(klgrad.checkgrad()) - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.testNormal'] - unittest.main() From cddde609888fa8a55dbe2e0cb96d49842d963f5f Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 08:06:38 +0200 Subject: [PATCH 062/101] migrate tests to pytest --- GPy/old_tests/bcgplvm_tests.py | 6 +- GPy/old_tests/gplvm_tests.py | 6 +- GPy/old_tests/psi_stat_gradient_tests.py | 302 +++++++++++++++-------- GPy/old_tests/sparse_gplvm_tests.py | 6 +- GPy/testing/pickle_tests.py | 2 +- 5 files changed, 212 insertions(+), 110 deletions(-) diff --git a/GPy/old_tests/bcgplvm_tests.py b/GPy/old_tests/bcgplvm_tests.py index 94282a0b..f2f471fa 100644 --- a/GPy/old_tests/bcgplvm_tests.py +++ b/GPy/old_tests/bcgplvm_tests.py @@ -17,7 +17,7 @@ class BCGPLVMTests(unittest.TestCase): mapping = GPy.mappings.Kernel(output_dim=input_dim, X=Y, kernel=bk) m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_linear_backconstraint(self): num_data, num_inducing, input_dim, output_dim = 10, 3, 2, 4 @@ -30,7 +30,7 @@ class BCGPLVMTests(unittest.TestCase): mapping = GPy.mappings.Linear(output_dim=input_dim, input_dim=output_dim) m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_mlp_backconstraint(self): num_data, num_inducing, input_dim, output_dim = 10, 3, 2, 4 @@ -43,7 +43,7 @@ class BCGPLVMTests(unittest.TestCase): mapping = GPy.mappings.MLP(output_dim=input_dim, input_dim=output_dim, hidden_dim=[5, 4, 7]) m = GPy.models.BCGPLVM(Y, input_dim, kernel = k, mapping=mapping) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() if __name__ == "__main__": print "Running unit tests, please be (very) patient..." diff --git a/GPy/old_tests/gplvm_tests.py b/GPy/old_tests/gplvm_tests.py index a605a96c..77d393e5 100644 --- a/GPy/old_tests/gplvm_tests.py +++ b/GPy/old_tests/gplvm_tests.py @@ -15,7 +15,7 @@ class GPLVMTests(unittest.TestCase): k = GPy.kern.Bias(input_dim) + GPy.kern.White(input_dim, 0.00001) m = GPy.models.GPLVM(Y, input_dim, kernel = k) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_linear_kern(self): num_data, num_inducing, input_dim, output_dim = 10, 3, 2, 4 @@ -26,7 +26,7 @@ class GPLVMTests(unittest.TestCase): k = GPy.kern.Linear(input_dim) + GPy.kern.White(input_dim, 0.00001) m = GPy.models.GPLVM(Y, input_dim, kernel = k) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_rbf_kern(self): num_data, num_inducing, input_dim, output_dim = 10, 3, 2, 4 @@ -37,7 +37,7 @@ class GPLVMTests(unittest.TestCase): k = GPy.kern.RBF(input_dim) + GPy.kern.White(input_dim, 0.00001) m = GPy.models.GPLVM(Y, input_dim, kernel = k) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() if __name__ == "__main__": print "Running unit tests, please be (very) patient..." diff --git a/GPy/old_tests/psi_stat_gradient_tests.py b/GPy/old_tests/psi_stat_gradient_tests.py index d51cd913..99582df6 100644 --- a/GPy/old_tests/psi_stat_gradient_tests.py +++ b/GPy/old_tests/psi_stat_gradient_tests.py @@ -1,8 +1,8 @@ -''' +""" Created on 22 Apr 2013 @author: maxz -''' +""" import unittest import numpy @@ -13,42 +13,66 @@ from GPy.core.parameterization.param import Param from GPy.core.parameterization.transformations import Logexp from GPy.core.parameterization.variational import NormalPosterior + class PsiStatModel(Model): def __init__(self, which, X, X_variance, Z, num_inducing, kernel): - super(PsiStatModel, self).__init__(name='psi stat test') + super(PsiStatModel, self).__init__(name="psi stat test") self.which = which self.X = Param("X", X) - self.X_variance = Param('X_variance', X_variance, Logexp()) + self.X_variance = Param("X_variance", X_variance, Logexp()) self.q = NormalPosterior(self.X, self.X_variance) self.Z = Param("Z", Z) self.N, self.input_dim = X.shape self.num_inducing, input_dim = Z.shape - assert self.input_dim == input_dim, "shape missmatch: Z:{!s} X:{!s}".format(Z.shape, X.shape) + assert self.input_dim == input_dim, "shape missmatch: Z:{!s} X:{!s}".format( + Z.shape, X.shape + ) self.kern = kernel self.psi_ = self.kern.__getattribute__(self.which)(self.Z, self.q) self.add_parameters(self.q, self.Z, self.kern) def log_likelihood(self): - return self.kern.__getattribute__(self.which)(self.Z, self.X, self.X_variance).sum() + return self.kern.__getattribute__(self.which)( + self.Z, self.X, self.X_variance + ).sum() def parameters_changed(self): - psimu, psiS = self.kern.__getattribute__("d" + self.which + "_dmuS")(numpy.ones_like(self.psi_), self.Z, self.q) + psimu, psiS = self.kern.__getattribute__("d" + self.which + "_dmuS")( + numpy.ones_like(self.psi_), self.Z, self.q + ) self.X.gradient = psimu self.X_variance.gradient = psiS - #psimu, psiS = numpy.ones(self.N * self.input_dim), numpy.ones(self.N * self.input_dim) - try: psiZ = self.kern.__getattribute__("d" + self.which + "_dZ")(numpy.ones_like(self.psi_), self.Z, self.q) - except AttributeError: psiZ = numpy.zeros_like(self.Z) + # psimu, psiS = numpy.ones(self.N * self.input_dim), numpy.ones(self.N * self.input_dim) + try: + psiZ = self.kern.__getattribute__("d" + self.which + "_dZ")( + numpy.ones_like(self.psi_), self.Z, self.q + ) + except AttributeError: + psiZ = numpy.zeros_like(self.Z) self.Z.gradient = psiZ - #psiZ = numpy.ones(self.num_inducing * self.input_dim) - N,M = self.X.shape[0], self.Z.shape[0] - dL_dpsi0, dL_dpsi1, dL_dpsi2 = numpy.zeros([N]), numpy.zeros([N,M]), numpy.zeros([N,M,M]) - if self.which == 'psi0': dL_dpsi0 += 1 - if self.which == 'psi1': dL_dpsi1 += 1 - if self.which == 'psi2': dL_dpsi2 += 1 - self.kern.update_gradients_variational(numpy.zeros([1,1]), - dL_dpsi0, - dL_dpsi1, - dL_dpsi2, self.X, self.X_variance, self.Z) + # psiZ = numpy.ones(self.num_inducing * self.input_dim) + N, M = self.X.shape[0], self.Z.shape[0] + dL_dpsi0, dL_dpsi1, dL_dpsi2 = ( + numpy.zeros([N]), + numpy.zeros([N, M]), + numpy.zeros([N, M, M]), + ) + if self.which == "psi0": + dL_dpsi0 += 1 + if self.which == "psi1": + dL_dpsi1 += 1 + if self.which == "psi2": + dL_dpsi2 += 1 + self.kern.update_gradients_variational( + numpy.zeros([1, 1]), + dL_dpsi0, + dL_dpsi1, + dL_dpsi2, + self.X, + self.X_variance, + self.Z, + ) + class DPsiStatTest(unittest.TestCase): input_dim = 5 @@ -56,128 +80,206 @@ class DPsiStatTest(unittest.TestCase): num_inducing = 10 input_dim = 20 X = numpy.random.randn(N, input_dim) - X_var = .5 * numpy.ones_like(X) + .4 * numpy.clip(numpy.random.randn(*X.shape), 0, 1) + X_var = 0.5 * numpy.ones_like(X) + 0.4 * numpy.clip( + numpy.random.randn(*X.shape), 0, 1 + ) Z = numpy.random.permutation(X)[:num_inducing] Y = X.dot(numpy.random.randn(input_dim, input_dim)) -# kernels = [GPy.kern.Linear(input_dim, ARD=True, variances=numpy.random.rand(input_dim)), GPy.kern.RBF(input_dim, ARD=True), GPy.kern.Bias(input_dim)] + # kernels = [GPy.kern.Linear(input_dim, ARD=True, variances=numpy.random.rand(input_dim)), GPy.kern.RBF(input_dim, ARD=True), GPy.kern.Bias(input_dim)] kernels = [ - GPy.kern.Linear(input_dim), - GPy.kern.RBF(input_dim), - #GPy.kern.Bias(input_dim), - #GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim), - #GPy.kern.RBF(input_dim) + GPy.kern.Bias(input_dim) - ] + GPy.kern.Linear(input_dim), + GPy.kern.RBF(input_dim), + # GPy.kern.Bias(input_dim), + # GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim), + # GPy.kern.RBF(input_dim) + GPy.kern.Bias(input_dim) + ] def testPsi0(self): for k in self.kernels: - m = PsiStatModel('psi0', X=self.X, X_variance=self.X_var, Z=self.Z,\ - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi0", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi0".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi0".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) def testPsi1(self): for k in self.kernels: - m = PsiStatModel('psi1', X=self.X, X_variance=self.X_var, Z=self.Z, - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi1", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi1".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) def testPsi2_lin(self): k = self.kernels[0] - m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z, - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi2", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi2".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) + def testPsi2_lin_bia(self): k = self.kernels[3] - m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z, - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi2", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi2".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) + def testPsi2_rbf(self): k = self.kernels[1] - m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z, - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi2", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi2".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) + def testPsi2_rbf_bia(self): k = self.kernels[-1] - m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z, - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi2", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi2".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) + def testPsi2_bia(self): k = self.kernels[2] - m = PsiStatModel('psi2', X=self.X, X_variance=self.X_var, Z=self.Z, - num_inducing=self.num_inducing, kernel=k) + m = PsiStatModel( + "psi2", + X=self.X, + X_variance=self.X_var, + Z=self.Z, + num_inducing=self.num_inducing, + kernel=k, + ) m.randomize() - assert m.checkgrad(), "{} x psi2".format("+".join(map(lambda x: x.name, k._parameters_))) + assert m.checkgrad(), "{} x psi2".format( + "+".join(map(lambda x: x.name, k._parameters_)) + ) if __name__ == "__main__": import sys - interactive = 'i' in sys.argv + + interactive = "i" in sys.argv if interactive: -# N, num_inducing, input_dim, input_dim = 30, 5, 4, 30 -# X = numpy.random.rand(N, input_dim) -# k = GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim) + GPy.kern.White(input_dim, 0.00001) -# K = k.K(X) -# Y = numpy.random.multivariate_normal(numpy.zeros(N), K, input_dim).T -# Y -= Y.mean(axis=0) -# k = GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim) + GPy.kern.White(input_dim, 0.00001) -# m = GPy.models.Bayesian_GPLVM(Y, input_dim, kernel=k, num_inducing=num_inducing) -# m.randomize() -# # self.assertTrue(m.checkgrad()) + # N, num_inducing, input_dim, input_dim = 30, 5, 4, 30 + # X = numpy.random.rand(N, input_dim) + # k = GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim) + GPy.kern.White(input_dim, 0.00001) + # K = k.K(X) + # Y = numpy.random.multivariate_normal(numpy.zeros(N), K, input_dim).T + # Y -= Y.mean(axis=0) + # k = GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim) + GPy.kern.White(input_dim, 0.00001) + # m = GPy.models.Bayesian_GPLVM(Y, input_dim, kernel=k, num_inducing=num_inducing) + # m.randomize() + # # assert m.checkgrad() numpy.random.seed(0) input_dim = 3 N = 3 num_inducing = 2 D = 15 X = numpy.random.randn(N, input_dim) - X_var = .5 * numpy.ones_like(X) + .1 * numpy.clip(numpy.random.randn(*X.shape), 0, 1) + X_var = 0.5 * numpy.ones_like(X) + 0.1 * numpy.clip( + numpy.random.randn(*X.shape), 0, 1 + ) Z = numpy.random.permutation(X)[:num_inducing] Y = X.dot(numpy.random.randn(input_dim, D)) -# kernel = GPy.kern.Bias(input_dim) -# -# kernels = [GPy.kern.Linear(input_dim), GPy.kern.RBF(input_dim), GPy.kern.Bias(input_dim), -# GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim), -# GPy.kern.RBF(input_dim) + GPy.kern.Bias(input_dim)] + # kernel = GPy.kern.Bias(input_dim) + # + # kernels = [GPy.kern.Linear(input_dim), GPy.kern.RBF(input_dim), GPy.kern.Bias(input_dim), + # GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim), + # GPy.kern.RBF(input_dim) + GPy.kern.Bias(input_dim)] -# for k in kernels: -# m = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z, -# num_inducing=num_inducing, kernel=k) -# assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k.parts))) -# - m0 = PsiStatModel('psi0', X=X, X_variance=X_var, Z=Z, - num_inducing=num_inducing, kernel=GPy.kern.RBF(input_dim)+GPy.kern.Bias(input_dim)) -# m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z, -# num_inducing=num_inducing, kernel=kernel) -# m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z, -# num_inducing=num_inducing, kernel=kernel) -# m2 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, -# num_inducing=num_inducing, kernel=GPy.kern.RBF(input_dim)) -# m3 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, -# num_inducing=num_inducing, kernel=GPy.kern.Linear(input_dim, ARD=True, variances=numpy.random.rand(input_dim))) + # for k in kernels: + # m = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z, + # num_inducing=num_inducing, kernel=k) + # assert m.checkgrad(), "{} x psi1".format("+".join(map(lambda x: x.name, k.parts))) + # + m0 = PsiStatModel( + "psi0", + X=X, + X_variance=X_var, + Z=Z, + num_inducing=num_inducing, + kernel=GPy.kern.RBF(input_dim) + GPy.kern.Bias(input_dim), + ) + # m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z, + # num_inducing=num_inducing, kernel=kernel) + # m1 = PsiStatModel('psi1', X=X, X_variance=X_var, Z=Z, + # num_inducing=num_inducing, kernel=kernel) + # m2 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, + # num_inducing=num_inducing, kernel=GPy.kern.RBF(input_dim)) + # m3 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, + # num_inducing=num_inducing, kernel=GPy.kern.Linear(input_dim, ARD=True, variances=numpy.random.rand(input_dim))) # + GPy.kern.Bias(input_dim)) -# m = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, -# num_inducing=num_inducing, -# kernel=( -# GPy.kern.RBF(input_dim, ARD=1) -# +GPy.kern.Linear(input_dim, ARD=1) -# +GPy.kern.Bias(input_dim)) -# ) -# m.ensure_default_constraints() - m2 = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, - num_inducing=num_inducing, kernel=( - GPy.kern.RBF(input_dim, numpy.random.rand(), numpy.random.rand(input_dim), ARD=1) - #+GPy.kern.Linear(input_dim, numpy.random.rand(input_dim), ARD=1) - #+GPy.kern.RBF(input_dim, numpy.random.rand(), numpy.random.rand(input_dim), ARD=1) - #+GPy.kern.RBF(input_dim, numpy.random.rand(), numpy.random.rand(), ARD=0) - +GPy.kern.Bias(input_dim) - +GPy.kern.White(input_dim) - ) - ) - #m2.ensure_default_constraints() + # m = PsiStatModel('psi2', X=X, X_variance=X_var, Z=Z, + # num_inducing=num_inducing, + # kernel=( + # GPy.kern.RBF(input_dim, ARD=1) + # +GPy.kern.Linear(input_dim, ARD=1) + # +GPy.kern.Bias(input_dim)) + # ) + # m.ensure_default_constraints() + m2 = PsiStatModel( + "psi2", + X=X, + X_variance=X_var, + Z=Z, + num_inducing=num_inducing, + kernel=( + GPy.kern.RBF( + input_dim, numpy.random.rand(), numpy.random.rand(input_dim), ARD=1 + ) + # +GPy.kern.Linear(input_dim, numpy.random.rand(input_dim), ARD=1) + # +GPy.kern.RBF(input_dim, numpy.random.rand(), numpy.random.rand(input_dim), ARD=1) + # +GPy.kern.RBF(input_dim, numpy.random.rand(), numpy.random.rand(), ARD=0) + + GPy.kern.Bias(input_dim) + + GPy.kern.White(input_dim) + ), + ) + # m2.ensure_default_constraints() else: unittest.main() diff --git a/GPy/old_tests/sparse_gplvm_tests.py b/GPy/old_tests/sparse_gplvm_tests.py index eb8ccb9c..a210c9ae 100644 --- a/GPy/old_tests/sparse_gplvm_tests.py +++ b/GPy/old_tests/sparse_gplvm_tests.py @@ -16,7 +16,7 @@ class sparse_GPLVMTests(unittest.TestCase): k = GPy.kern.Bias(input_dim) + GPy.kern.White(input_dim, 0.00001) m = SparseGPLVM(Y, input_dim, kernel=k, num_inducing=num_inducing) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_linear_kern(self): N, num_inducing, input_dim, D = 10, 3, 2, 4 @@ -27,7 +27,7 @@ class sparse_GPLVMTests(unittest.TestCase): k = GPy.kern.Linear(input_dim) + GPy.kern.White(input_dim, 0.00001) m = SparseGPLVM(Y, input_dim, kernel=k, num_inducing=num_inducing) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() def test_rbf_kern(self): N, num_inducing, input_dim, D = 10, 3, 2, 4 @@ -38,7 +38,7 @@ class sparse_GPLVMTests(unittest.TestCase): k = GPy.kern.RBF(input_dim) + GPy.kern.White(input_dim, 0.00001) m = SparseGPLVM(Y, input_dim, kernel=k, num_inducing=num_inducing) m.randomize() - self.assertTrue(m.checkgrad()) + assert m.checkgrad() if __name__ == "__main__": print "Running unit tests, please be (very) patient..." diff --git a/GPy/testing/pickle_tests.py b/GPy/testing/pickle_tests.py index 3565130b..dea50889 100644 --- a/GPy/testing/pickle_tests.py +++ b/GPy/testing/pickle_tests.py @@ -35,7 +35,7 @@ class ListDictTestCase: class TestPickleSupport(ListDictTestCase): # TODO: why is this test skipped? - @pytest.mark.skip("") # TODO + @pytest.mark.skip(reason="") def test_load_pickle(self): import os From 6c8fb66656bcf52adf9513d7d399779e2a2ae354 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 08:20:32 +0200 Subject: [PATCH 063/101] rename test files for pytest notation --- GPy/testing/{cython_tests.py => test_cython.py} | 0 ...p_likelihood_tests.py => test_ep_likelihood.py} | 0 .../{examples_tests.py => test_examples.py} | 0 GPy/testing/{gp_tests.py => test_gp.py} | 0 ...ce_tests.py => test_gpy_kernels_state_space.py} | 0 GPy/testing/{grid_tests.py => test_grid.py} | 0 .../{inference_tests.py => test_inference.py} | 0 GPy/testing/{kernel_tests.py => test_kernel.py} | 0 .../{likelihood_tests.py => test_likelihood.py} | 0 GPy/testing/{linalg_test.py => test_linalg.py} | 0 ...ink_function_tests.py => test_link_function.py} | 0 GPy/testing/{mapping_tests.py => test_mapping.py} | 0 .../{meanfunc_tests.py => test_meanfunc.py} | 0 .../{minibatch_tests.py => test_minibatch.py} | 0 GPy/testing/{misc_tests.py => test_misc.py} | 0 GPy/testing/{model_tests.py => test_model.py} | 0 GPy/testing/{mpi_tests.py => test_mpi.py} | 0 GPy/testing/{pep_tests.py => test_pep.py} | 0 GPy/testing/{pickle_tests.py => test_pickle.py} | 0 .../{plotting_tests.py => test_plotting.py} | 0 GPy/testing/{prior_tests.py => test_prior.py} | 0 .../{quadrature_tests.py => test_quadrature.py} | 0 ...ormation_tests.py => test_rv_transformation.py} | 0 ...erialization_tests.py => test_serialization.py} | 0 ...pace_main_tests.py => test_state_space_main.py} | 0 GPy/testing/{svgp_tests.py => test_svgp.py} | 0 GPy/testing/{tp_tests.py => test_tp.py} | 0 GPy/testing/{util_tests.py => test_util.py} | 0 .../{variational_tests.py => test_variational.py} | 0 GPy/testing/todo.md | 14 ++++++++++++++ 30 files changed, 14 insertions(+) rename GPy/testing/{cython_tests.py => test_cython.py} (100%) rename GPy/testing/{ep_likelihood_tests.py => test_ep_likelihood.py} (100%) rename GPy/testing/{examples_tests.py => test_examples.py} (100%) rename GPy/testing/{gp_tests.py => test_gp.py} (100%) rename GPy/testing/{gpy_kernels_state_space_tests.py => test_gpy_kernels_state_space.py} (100%) rename GPy/testing/{grid_tests.py => test_grid.py} (100%) rename GPy/testing/{inference_tests.py => test_inference.py} (100%) rename GPy/testing/{kernel_tests.py => test_kernel.py} (100%) rename GPy/testing/{likelihood_tests.py => test_likelihood.py} (100%) rename GPy/testing/{linalg_test.py => test_linalg.py} (100%) rename GPy/testing/{link_function_tests.py => test_link_function.py} (100%) rename GPy/testing/{mapping_tests.py => test_mapping.py} (100%) rename GPy/testing/{meanfunc_tests.py => test_meanfunc.py} (100%) rename GPy/testing/{minibatch_tests.py => test_minibatch.py} (100%) rename GPy/testing/{misc_tests.py => test_misc.py} (100%) rename GPy/testing/{model_tests.py => test_model.py} (100%) rename GPy/testing/{mpi_tests.py => test_mpi.py} (100%) rename GPy/testing/{pep_tests.py => test_pep.py} (100%) rename GPy/testing/{pickle_tests.py => test_pickle.py} (100%) rename GPy/testing/{plotting_tests.py => test_plotting.py} (100%) rename GPy/testing/{prior_tests.py => test_prior.py} (100%) rename GPy/testing/{quadrature_tests.py => test_quadrature.py} (100%) rename GPy/testing/{rv_transformation_tests.py => test_rv_transformation.py} (100%) rename GPy/testing/{serialization_tests.py => test_serialization.py} (100%) rename GPy/testing/{state_space_main_tests.py => test_state_space_main.py} (100%) rename GPy/testing/{svgp_tests.py => test_svgp.py} (100%) rename GPy/testing/{tp_tests.py => test_tp.py} (100%) rename GPy/testing/{util_tests.py => test_util.py} (100%) rename GPy/testing/{variational_tests.py => test_variational.py} (100%) create mode 100644 GPy/testing/todo.md diff --git a/GPy/testing/cython_tests.py b/GPy/testing/test_cython.py similarity index 100% rename from GPy/testing/cython_tests.py rename to GPy/testing/test_cython.py diff --git a/GPy/testing/ep_likelihood_tests.py b/GPy/testing/test_ep_likelihood.py similarity index 100% rename from GPy/testing/ep_likelihood_tests.py rename to GPy/testing/test_ep_likelihood.py diff --git a/GPy/testing/examples_tests.py b/GPy/testing/test_examples.py similarity index 100% rename from GPy/testing/examples_tests.py rename to GPy/testing/test_examples.py diff --git a/GPy/testing/gp_tests.py b/GPy/testing/test_gp.py similarity index 100% rename from GPy/testing/gp_tests.py rename to GPy/testing/test_gp.py diff --git a/GPy/testing/gpy_kernels_state_space_tests.py b/GPy/testing/test_gpy_kernels_state_space.py similarity index 100% rename from GPy/testing/gpy_kernels_state_space_tests.py rename to GPy/testing/test_gpy_kernels_state_space.py diff --git a/GPy/testing/grid_tests.py b/GPy/testing/test_grid.py similarity index 100% rename from GPy/testing/grid_tests.py rename to GPy/testing/test_grid.py diff --git a/GPy/testing/inference_tests.py b/GPy/testing/test_inference.py similarity index 100% rename from GPy/testing/inference_tests.py rename to GPy/testing/test_inference.py diff --git a/GPy/testing/kernel_tests.py b/GPy/testing/test_kernel.py similarity index 100% rename from GPy/testing/kernel_tests.py rename to GPy/testing/test_kernel.py diff --git a/GPy/testing/likelihood_tests.py b/GPy/testing/test_likelihood.py similarity index 100% rename from GPy/testing/likelihood_tests.py rename to GPy/testing/test_likelihood.py diff --git a/GPy/testing/linalg_test.py b/GPy/testing/test_linalg.py similarity index 100% rename from GPy/testing/linalg_test.py rename to GPy/testing/test_linalg.py diff --git a/GPy/testing/link_function_tests.py b/GPy/testing/test_link_function.py similarity index 100% rename from GPy/testing/link_function_tests.py rename to GPy/testing/test_link_function.py diff --git a/GPy/testing/mapping_tests.py b/GPy/testing/test_mapping.py similarity index 100% rename from GPy/testing/mapping_tests.py rename to GPy/testing/test_mapping.py diff --git a/GPy/testing/meanfunc_tests.py b/GPy/testing/test_meanfunc.py similarity index 100% rename from GPy/testing/meanfunc_tests.py rename to GPy/testing/test_meanfunc.py diff --git a/GPy/testing/minibatch_tests.py b/GPy/testing/test_minibatch.py similarity index 100% rename from GPy/testing/minibatch_tests.py rename to GPy/testing/test_minibatch.py diff --git a/GPy/testing/misc_tests.py b/GPy/testing/test_misc.py similarity index 100% rename from GPy/testing/misc_tests.py rename to GPy/testing/test_misc.py diff --git a/GPy/testing/model_tests.py b/GPy/testing/test_model.py similarity index 100% rename from GPy/testing/model_tests.py rename to GPy/testing/test_model.py diff --git a/GPy/testing/mpi_tests.py b/GPy/testing/test_mpi.py similarity index 100% rename from GPy/testing/mpi_tests.py rename to GPy/testing/test_mpi.py diff --git a/GPy/testing/pep_tests.py b/GPy/testing/test_pep.py similarity index 100% rename from GPy/testing/pep_tests.py rename to GPy/testing/test_pep.py diff --git a/GPy/testing/pickle_tests.py b/GPy/testing/test_pickle.py similarity index 100% rename from GPy/testing/pickle_tests.py rename to GPy/testing/test_pickle.py diff --git a/GPy/testing/plotting_tests.py b/GPy/testing/test_plotting.py similarity index 100% rename from GPy/testing/plotting_tests.py rename to GPy/testing/test_plotting.py diff --git a/GPy/testing/prior_tests.py b/GPy/testing/test_prior.py similarity index 100% rename from GPy/testing/prior_tests.py rename to GPy/testing/test_prior.py diff --git a/GPy/testing/quadrature_tests.py b/GPy/testing/test_quadrature.py similarity index 100% rename from GPy/testing/quadrature_tests.py rename to GPy/testing/test_quadrature.py diff --git a/GPy/testing/rv_transformation_tests.py b/GPy/testing/test_rv_transformation.py similarity index 100% rename from GPy/testing/rv_transformation_tests.py rename to GPy/testing/test_rv_transformation.py diff --git a/GPy/testing/serialization_tests.py b/GPy/testing/test_serialization.py similarity index 100% rename from GPy/testing/serialization_tests.py rename to GPy/testing/test_serialization.py diff --git a/GPy/testing/state_space_main_tests.py b/GPy/testing/test_state_space_main.py similarity index 100% rename from GPy/testing/state_space_main_tests.py rename to GPy/testing/test_state_space_main.py diff --git a/GPy/testing/svgp_tests.py b/GPy/testing/test_svgp.py similarity index 100% rename from GPy/testing/svgp_tests.py rename to GPy/testing/test_svgp.py diff --git a/GPy/testing/tp_tests.py b/GPy/testing/test_tp.py similarity index 100% rename from GPy/testing/tp_tests.py rename to GPy/testing/test_tp.py diff --git a/GPy/testing/util_tests.py b/GPy/testing/test_util.py similarity index 100% rename from GPy/testing/util_tests.py rename to GPy/testing/test_util.py diff --git a/GPy/testing/variational_tests.py b/GPy/testing/test_variational.py similarity index 100% rename from GPy/testing/variational_tests.py rename to GPy/testing/test_variational.py diff --git a/GPy/testing/todo.md b/GPy/testing/todo.md new file mode 100644 index 00000000..4a7833d7 --- /dev/null +++ b/GPy/testing/todo.md @@ -0,0 +1,14 @@ +As off now, I am once through all of the tests and basic migration is done. + +Now, fix the below things and todos before starting to get the tests running using pytest + + ++ update test script names according to pytest conversion ++ check for TODOs ++ + there are many associated with "iscloseto" functions from np.testing. Will have to figure out how these ++ + some tests are not that clear to me tbh ++ check nomenclature of test files and test classes and test functions ++ chatgpt says that I should replace delta with the decimal but a delta of 1e-4 should be decimal=4. Not sure about this yet but that is something I need to fix later on +--> this gives more content to it: https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertAlmostEqual +I need to write a custom function that behaves accordingly as in some cases, np.testing.assert_almost_equal won't be applicable, https://numpy.org/doc/stable/reference/generated/numpy.testing.assert_almost_equal.html +or how about this: `np.testing.assert_allclose(pcopy.param_array, par.param_array, atol=1e-6)` \ No newline at end of file From cec7e999bbf9e0e84f0da34ee3f7bee70b1060d5 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 08:30:32 +0200 Subject: [PATCH 064/101] undo rename --- .../{test_state_space_main.py => state_space_main_tests.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename GPy/testing/{test_state_space_main.py => state_space_main_tests.py} (100%) diff --git a/GPy/testing/test_state_space_main.py b/GPy/testing/state_space_main_tests.py similarity index 100% rename from GPy/testing/test_state_space_main.py rename to GPy/testing/state_space_main_tests.py From d77f140fecd42001d4877cf635981a6ac0f501e8 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 08:30:53 +0200 Subject: [PATCH 065/101] fix test errors after migration --- GPy/__init__.py | 38 ++++++------- GPy/old_tests/gp_transformation_tests.py | 1 - GPy/testing/move_files.py | 24 ++++++++ GPy/testing/test_cython.py | 6 +- GPy/testing/test_ep_likelihood.py | 5 +- GPy/testing/test_gpy_kernels_state_space.py | 1 - GPy/testing/test_kernel.py | 2 +- GPy/testing/test_model.py | 2 +- GPy/testing/test_plotting.py | 62 ++++++++++++--------- GPy/testing/test_serialization.py | 12 +++- 10 files changed, 95 insertions(+), 58 deletions(-) create mode 100644 GPy/testing/move_files.py diff --git a/GPy/__init__.py b/GPy/__init__.py index b5e83566..9c2a7f1b 100644 --- a/GPy/__init__.py +++ b/GPy/__init__.py @@ -1,6 +1,7 @@ # Copyright (c) 2012, GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) import warnings + warnings.filterwarnings("ignore", category=DeprecationWarning) from . import core @@ -18,30 +19,25 @@ from .util import normalizer # backwards compatibility import sys -backwards_compatibility = ['lists_and_dicts', 'observable_array', 'index_operations'] + +backwards_compatibility = ["lists_and_dicts", "observable_array", "index_operations"] for bc in backwards_compatibility: - sys.modules['GPy.core.parameterization.{!s}'.format(bc)] = getattr(core.parameterization, bc) + sys.modules["GPy.core.parameterization.{!s}".format(bc)] = getattr( + core.parameterization, bc + ) # Direct imports for convenience: from .core import Model from .core.parameterization import priors -from .core.parameterization import Param, Parameterized, ObsAr, transformations as constraints +from .core.parameterization import ( + Param, + Parameterized, + ObsAr, + transformations as constraints, +) from .__version__ import __version__ -from numpy.testing import Tester - -with warnings.catch_warnings(): - warnings.simplefilter('ignore') - try: - #Get rid of nose dependency by only ignoring if you have nose installed - from nose.tools import nottest - @nottest - def tests(verbose=10): - Tester(testing).test(verbose=verbose) - except: - def tests(verbose=10): - Tester(testing).test(verbose=verbose) def load(file_or_path): """ @@ -52,10 +48,12 @@ def load(file_or_path): # This is the pickling pain when changing _src -> src import sys import inspect - sys.modules['GPy.kern._src'] = kern.src + + sys.modules["GPy.kern._src"] = kern.src for name, module in inspect.getmembers(kern.src): - if not name.startswith('_'): - sys.modules['GPy.kern._src.{}'.format(name)] = module - sys.modules['GPy.inference.optimization'] = inference.optimization + if not name.startswith("_"): + sys.modules["GPy.kern._src.{}".format(name)] = module + sys.modules["GPy.inference.optimization"] = inference.optimization import paramz + return paramz.load(file_or_path) diff --git a/GPy/old_tests/gp_transformation_tests.py b/GPy/old_tests/gp_transformation_tests.py index 42c0414b..0dbd2a81 100644 --- a/GPy/old_tests/gp_transformation_tests.py +++ b/GPy/old_tests/gp_transformation_tests.py @@ -1,4 +1,3 @@ -from nose.tools import with_setup from GPy.models import GradientChecker from GPy.likelihoods.noise_models import gp_transformations import inspect diff --git a/GPy/testing/move_files.py b/GPy/testing/move_files.py new file mode 100644 index 00000000..ab753fee --- /dev/null +++ b/GPy/testing/move_files.py @@ -0,0 +1,24 @@ +import os +import subprocess + + +python_files = [file for file in os.listdir() if file.endswith(".py")] + +python_test_files = [file for file in python_files if "test" in file] +non_test_python_files = [file for file in python_files if "test" not in file] +print("Python Test Files: ", python_test_files) + +print("Non-test Python Files:\n", non_test_python_files) + +for file in python_test_files: + if file.endswith("_tests.py"): + test_name = file.split("_tests.py")[0] + elif file.endswith("_test.py"): + test_name = file.split("_test.py")[0] + else: + raise ValueError(f"File is not named as expected: {file}") + + to_file = "test_" + test_name + ".py" + + # print(" ".join(["git", "mv", "-f", file, to_file])) + subprocess.run(["git", "mv", "-f", file, to_file]) diff --git a/GPy/testing/test_cython.py b/GPy/testing/test_cython.py index e885482e..9cc12ce0 100644 --- a/GPy/testing/test_cython.py +++ b/GPy/testing/test_cython.py @@ -24,7 +24,7 @@ These tests make sure that the pure python and cython codes work the same """ -@pytest.skipIf( +@pytest.mark.skipif( not choleskies_cython_working, "Cython cholesky module has not been built on this machine", ) @@ -44,7 +44,7 @@ class CythonTestChols: assert np.allclose(A1, A2), "Flat mismatch!" -@pytest.skipIf( +@pytest.mark.skipif( not stationary_cython_working, "Cython stationary module has not been built on this machine", ) @@ -82,7 +82,7 @@ class TestStationary: assert np.allclose(g1, g2), "Gradient mismatch on rect lengthscale!" -@pytest.skipIf( +@pytest.mark.skipif( not choleskies_cython_working, "Cython cholesky module has not been built on this machine", ) diff --git a/GPy/testing/test_ep_likelihood.py b/GPy/testing/test_ep_likelihood.py index 4559ddf1..2ab42617 100644 --- a/GPy/testing/test_ep_likelihood.py +++ b/GPy/testing/test_ep_likelihood.py @@ -1,7 +1,6 @@ +import pytest import numpy as np -import unittest import GPy -from GPy.models import GradientChecker fixed_seed = 10 @@ -127,7 +126,7 @@ class TestObservationModels: GPy.util.classification.conf_matrix(probs_mean_ep_alt, self.binary_Y) GPy.util.classification.conf_matrix(probs_mean_ep_nested, self.binary_Y) - @pytest.skip( + @pytest.mark.skip( "Fails as a consequence of fixing the DSYR function. Needs to be reviewed!" ) def test_ep_with_studentt(self): diff --git a/GPy/testing/test_gpy_kernels_state_space.py b/GPy/testing/test_gpy_kernels_state_space.py index f5a3f89e..154b4378 100644 --- a/GPy/testing/test_gpy_kernels_state_space.py +++ b/GPy/testing/test_gpy_kernels_state_space.py @@ -15,7 +15,6 @@ from .state_space_main_tests import ( generate_brownian_data, generate_linear_plus_sin, ) -from nose import SkipTest # from state_space_main_tests import generate_x_points, generate_sine_data, \ # generate_linear_data, generate_brownian_data, generate_linear_plus_sin diff --git a/GPy/testing/test_kernel.py b/GPy/testing/test_kernel.py index c7ef9f09..44aa306f 100644 --- a/GPy/testing/test_kernel.py +++ b/GPy/testing/test_kernel.py @@ -870,7 +870,7 @@ class TestKernelNonContinuous: ) -@pytest.skipIf( +@pytest.mark.skipif( not cython_coregionalize_working, "Cython coregionalize module has not been built on this machine", ) diff --git a/GPy/testing/test_model.py b/GPy/testing/test_model.py index 99a85c38..44b2c0a6 100644 --- a/GPy/testing/test_model.py +++ b/GPy/testing/test_model.py @@ -75,7 +75,7 @@ class TestMisc: Xp[:, 0] = Xp[:, 0] * 15 - 5 Xp[:, 1] = Xp[:, 1] * 15 _, var = m.predict(Xp) - assert np.all(var >= 0.0)) + assert np.all(var >= 0.0) def test_raw_predict(self): self.setup() diff --git a/GPy/testing/test_plotting.py b/GPy/testing/test_plotting.py index 16c9651c..11a93b81 100644 --- a/GPy/testing/test_plotting.py +++ b/GPy/testing/test_plotting.py @@ -141,39 +141,42 @@ def _image_comparison( if ext == "npz": def do_test(): - with pytest.skip - if not os.path.exists(expected): - import shutil + with pytest.skip: + if not os.path.exists(expected): + import shutil - shutil.copy2(actual, expected) - # shutil.copy2(os.path.join(result_dir, "{}.{}".format(base, 'png')), os.path.join(baseline_dir, "{}.{}".format(base, 'png'))) - raise IOError( - "Baseline file {} not found, copying result {}".format( - expected, actual + shutil.copy2(actual, expected) + # shutil.copy2(os.path.join(result_dir, "{}.{}".format(base, 'png')), os.path.join(baseline_dir, "{}.{}".format(base, 'png'))) + raise IOError( + "Baseline file {} not found, copying result {}".format( + expected, actual + ) ) - ) - else: - exp_dict = dict(np.load(expected).items()) - act_dict = dict(np.load(actual).items()) - for name in act_dict: - if name in exp_dict: - try: - np.testing.assert_allclose( - exp_dict[name], - act_dict[name], - err_msg="Mismatch in {}.{}".format(base, name), - rtol=rtol, - **kwargs - ) - except AssertionError as e: - pass + else: + exp_dict = dict(np.load(expected).items()) + act_dict = dict(np.load(actual).items()) + for name in act_dict: + if name in exp_dict: + try: + np.testing.assert_allclose( + exp_dict[name], + act_dict[name], + err_msg="Mismatch in {}.{}".format( + base, name + ), + rtol=rtol, + **kwargs + ) + except AssertionError as e: + pass else: def do_test(): err = compare_images(expected, actual, tol, in_decorator=True) if err: - print("Error between {} and {} is {:.5f}, which is bigger then the tolerance of {:.5f}".format( + print( + "Error between {} and {} is {:.5f}, which is bigger then the tolerance of {:.5f}".format( actual, expected, err["rms"], tol ) ) @@ -319,6 +322,7 @@ def test_figure(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -363,6 +367,7 @@ def test_kernel(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -406,6 +411,7 @@ def test_plot(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -441,6 +447,7 @@ def test_twod(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -477,6 +484,7 @@ def test_threed(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -502,6 +510,7 @@ def test_sparse(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -534,6 +543,7 @@ def test_classification(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -564,6 +574,7 @@ def test_sparse_classification(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) @@ -621,6 +632,7 @@ def test_gplvm(): ): yield (do_test,) + @pytest.mark.skipif( matplotlib is None or baseline_dir is None, reason="Matplotlib not installed" ) diff --git a/GPy/testing/test_serialization.py b/GPy/testing/test_serialization.py index f08148f8..01666dd9 100644 --- a/GPy/testing/test_serialization.py +++ b/GPy/testing/test_serialization.py @@ -377,7 +377,9 @@ class TestSerialization: m2_r = GPy.models.GPClassification.load_model( "temp_test_gp_classifier_without_data.json.zip", (X, Y) ) - assert type(m) == type(m2_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), + assert type(m) == type( + m2_r + ), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)) os.remove("temp_test_gp_classifier_with_data.json.zip") os.remove("temp_test_gp_classifier_without_data.json.zip") @@ -415,11 +417,15 @@ class TestSerialization: m1_r = GPy.models.SparseGPClassification.load_model( "temp_test_sparse_gp_classifier_with_data.json.zip" ) - assert type(m) == type(m1_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)) + assert type(m) == type( + m1_r + ), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m1_r)) m2_r = GPy.models.SparseGPClassification.load_model( "temp_test_sparse_gp_classifier_without_data.json.zip", (X, Y) ) - assert type(m) == type(m2_r), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)), + assert type(m) == type( + m2_r + ), "Incorrect model type. Expected: {} Actual: {}".format(type(m), type(m2_r)) os.remove("temp_test_sparse_gp_classifier_with_data.json.zip") os.remove("temp_test_sparse_gp_classifier_without_data.json.zip") From a0ced629d33d54048accb9c2040bc132302d7d3a Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 09:05:51 +0200 Subject: [PATCH 066/101] remove move_files file --- GPy/testing/move_files.py | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 GPy/testing/move_files.py diff --git a/GPy/testing/move_files.py b/GPy/testing/move_files.py deleted file mode 100644 index ab753fee..00000000 --- a/GPy/testing/move_files.py +++ /dev/null @@ -1,24 +0,0 @@ -import os -import subprocess - - -python_files = [file for file in os.listdir() if file.endswith(".py")] - -python_test_files = [file for file in python_files if "test" in file] -non_test_python_files = [file for file in python_files if "test" not in file] -print("Python Test Files: ", python_test_files) - -print("Non-test Python Files:\n", non_test_python_files) - -for file in python_test_files: - if file.endswith("_tests.py"): - test_name = file.split("_tests.py")[0] - elif file.endswith("_test.py"): - test_name = file.split("_test.py")[0] - else: - raise ValueError(f"File is not named as expected: {file}") - - to_file = "test_" + test_name + ".py" - - # print(" ".join(["git", "mv", "-f", file, to_file])) - subprocess.run(["git", "mv", "-f", file, to_file]) From a6d78d79aab1894d9be7f040e74a1c9f484e85f4 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 18:53:11 +0200 Subject: [PATCH 067/101] replace np.float by float --- GPy/core/parameterization/priors.py | 303 +++++++++++++++++----------- GPy/likelihoods/student_t.py | 115 ++++++----- benchmarks/regression/evaluation.py | 11 +- 3 files changed, 256 insertions(+), 173 deletions(-) diff --git a/GPy/core/parameterization/priors.py b/GPy/core/parameterization/priors.py index c4dfbc2a..3550a8b5 100644 --- a/GPy/core/parameterization/priors.py +++ b/GPy/core/parameterization/priors.py @@ -13,14 +13,15 @@ import weakref class Prior(object): domain = None _instance = None + def __new__(cls, *args, **kwargs): if not cls._instance or cls._instance.__class__ is not cls: - newfunc = super(Prior, cls).__new__ - if newfunc is object.__new__: - cls._instance = newfunc(cls) - else: - cls._instance = newfunc(cls, *args, **kwargs) - return cls._instance + newfunc = super(Prior, cls).__new__ + if newfunc is object.__new__: + cls._instance = newfunc(cls) + else: + cls._instance = newfunc(cls, *args, **kwargs) + return cls._instance def pdf(self, x): return np.exp(self.lnpdf(x)) @@ -47,6 +48,7 @@ class Gaussian(Prior): .. Note:: Bishop 2006 notation is used throughout the code """ + domain = _REAL _instances = [] @@ -82,6 +84,7 @@ class Gaussian(Prior): def rvs(self, n): return np.random.randn(n) * self.sigma + self.mu + # def __getstate__(self): # return self.mu, self.sigma # @@ -91,6 +94,7 @@ class Gaussian(Prior): # self.sigma2 = np.square(self.sigma) # self.constant = -0.5 * np.log(2 * np.pi * self.sigma2) + class Uniform(Prior): _instances = [] @@ -132,6 +136,7 @@ class Uniform(Prior): def rvs(self, n): return np.random.uniform(self.lower, self.upper, size=n) + # def __getstate__(self): # return self.lower, self.upper # @@ -139,6 +144,7 @@ class Uniform(Prior): # self.lower = state[0] # self.upper = state[1] + class LogGaussian(Gaussian): """ Implementation of the univariate *log*-Gaussian probability function, coupled with random variables. @@ -149,6 +155,7 @@ class LogGaussian(Gaussian): .. Note:: Bishop 2006 notation is used throughout the code """ + domain = _POSITIVE _instances = [] @@ -160,7 +167,7 @@ class LogGaussian(Gaussian): return instance() newfunc = super(Prior, cls).__new__ if newfunc is object.__new__: - o = newfunc(cls) + o = newfunc(cls) else: o = newfunc(cls, mu, sigma) cls._instances.append(weakref.ref(o)) @@ -176,10 +183,14 @@ class LogGaussian(Gaussian): return "lnN({:.2g}, {:.2g})".format(self.mu, self.sigma) def lnpdf(self, x): - return self.constant - 0.5 * np.square(np.log(x) - self.mu) / self.sigma2 - np.log(x) + return ( + self.constant + - 0.5 * np.square(np.log(x) - self.mu) / self.sigma2 + - np.log(x) + ) def lnpdf_grad(self, x): - return -((np.log(x) - self.mu) / self.sigma2 + 1.) / x + return -((np.log(x) - self.mu) / self.sigma2 + 1.0) / x def rvs(self, n): return np.exp(np.random.randn(int(n)) * self.sigma + self.mu) @@ -195,16 +206,15 @@ class MultivariateGaussian(Prior): .. Note:: Bishop 2006 notation is used throughout the code """ + domain = _REAL _instances = [] def __new__(cls, mu=0, var=1): # Singleton: if cls._instances: - cls._instances[:] = [instance for instance in cls._instances if - instance()] + cls._instances[:] = [instance for instance in cls._instances if instance()] for instance in cls._instances: - if np.all(instance().mu == mu) and np.all( - instance().var == var): + if np.all(instance().mu == mu) and np.all(instance().var == var): return instance() newfunc = super(Prior, cls).__new__ if newfunc is object.__new__: @@ -217,16 +227,17 @@ class MultivariateGaussian(Prior): def __init__(self, mu, var): self.mu = np.array(mu).flatten() self.var = np.array(var) - assert len(self.var.shape) == 2, 'Covariance must be a matrix' - assert self.var.shape[0] == self.var.shape[1], \ - 'Covariance must be a square matrix' + assert len(self.var.shape) == 2, "Covariance must be a matrix" + assert ( + self.var.shape[0] == self.var.shape[1] + ), "Covariance must be a square matrix" assert self.var.shape[0] == self.mu.size self.input_dim = self.mu.size self.inv, _, self.hld, _ = pdinv(self.var) self.constant = -0.5 * (self.input_dim * np.log(2 * np.pi) + self.hld) def __str__(self): - return 'MultiN(' + str(self.mu) + ', ' + str(np.diag(self.var)) + ')' + return "MultiN(" + str(self.mu) + ", " + str(np.diag(self.var)) + ")" def summary(self): raise NotImplementedError @@ -243,7 +254,7 @@ class MultivariateGaussian(Prior): def lnpdf_grad(self, x): x = np.array(x).flatten() d = x - self.mu - return - np.dot(self.inv, d) + return -np.dot(self.inv, d) def rvs(self, n): return np.random.multivariate_normal(self.mu, self.var, n) @@ -262,14 +273,16 @@ class MultivariateGaussian(Prior): def __setstate__(self, state): self.mu = np.array(state[0]).flatten() self.var = state[1] - assert len(self.var.shape) == 2, 'Covariance must be a matrix' - assert self.var.shape[0] == self.var.shape[1], \ - 'Covariance must be a square matrix' + assert len(self.var.shape) == 2, "Covariance must be a matrix" + assert ( + self.var.shape[0] == self.var.shape[1] + ), "Covariance must be a square matrix" assert self.var.shape[0] == self.mu.size self.input_dim = self.mu.size self.inv, _, self.hld, _ = pdinv(self.var) self.constant = -0.5 * (self.input_dim * np.log(2 * np.pi) + self.hld) + def gamma_from_EV(E, V): warnings.warn("use Gamma.from_EV to create Gamma Prior", FutureWarning) return Gamma.from_EV(E, V) @@ -285,10 +298,11 @@ class Gamma(Prior): .. Note:: Bishop 2006 notation is used throughout the code """ + domain = _POSITIVE _instances = [] - def __new__(cls, a=1, b=.5): # Singleton: + def __new__(cls, a=1, b=0.5): # Singleton: if cls._instances: cls._instances[:] = [instance for instance in cls._instances if instance()] for instance in cls._instances: @@ -319,24 +333,29 @@ class Gamma(Prior): return "Ga({:.2g}, {:.2g})".format(self.a, self.b) def summary(self): - ret = {"E[x]": self.a / self.b, \ - "E[ln x]": digamma(self.a) - np.log(self.b), \ - "var[x]": self.a / self.b / self.b, \ - "Entropy": gammaln(self.a) - (self.a - 1.) * digamma(self.a) - np.log(self.b) + self.a} + ret = { + "E[x]": self.a / self.b, + "E[ln x]": digamma(self.a) - np.log(self.b), + "var[x]": self.a / self.b / self.b, + "Entropy": gammaln(self.a) + - (self.a - 1.0) * digamma(self.a) + - np.log(self.b) + + self.a, + } if self.a > 1: - ret['Mode'] = (self.a - 1.) / self.b + ret["Mode"] = (self.a - 1.0) / self.b else: - ret['mode'] = np.nan + ret["mode"] = np.nan return ret def lnpdf(self, x): return self.constant + (self.a - 1) * np.log(x) - self.b * x def lnpdf_grad(self, x): - return (self.a - 1.) / x - self.b + return (self.a - 1.0) / x - self.b def rvs(self, n): - return np.random.gamma(scale=1. / self.b, shape=self.a, size=n) + return np.random.gamma(scale=1.0 / self.b, shape=self.a, size=n) @staticmethod def from_EV(E, V): @@ -359,6 +378,7 @@ class Gamma(Prior): self._b = state[1] self.constant = -gammaln(self.a) + self.a * np.log(self.b) + class InverseGamma(Gamma): """ Implementation of the inverse-Gamma probability function, coupled with random variables. @@ -369,6 +389,7 @@ class InverseGamma(Gamma): .. Note:: Bishop 2006 notation is used throughout the code """ + domain = _POSITIVE _instances = [] @@ -386,10 +407,11 @@ class InverseGamma(Gamma): return self.constant - (self.a + 1) * np.log(x) - self.b / x def lnpdf_grad(self, x): - return -(self.a + 1.) / x + self.b / x ** 2 + return -(self.a + 1.0) / x + self.b / x**2 def rvs(self, n): - return 1. / np.random.gamma(scale=1. / self.b, shape=self.a, size=n) + return 1.0 / np.random.gamma(scale=1.0 / self.b, shape=self.a, size=n) + class DGPLVM_KFDA(Prior): """ @@ -403,6 +425,7 @@ class DGPLVM_KFDA(Prior): .. Note:: Surpassing Human-Level Face paper dgplvm implementation """ + domain = _REAL # _instances = [] # def __new__(cls, lambdaa, sigma2): # Singleton: @@ -459,8 +482,8 @@ class DGPLVM_KFDA(Prior): lst_ni = [] lst_ni1 = [] lst_ni2 = [] - f1 = (np.where(self.lbl[:, 0] == 1)[0]) - f2 = (np.where(self.lbl[:, 1] == 1)[0]) + f1 = np.where(self.lbl[:, 0] == 1)[0] + f2 = np.where(self.lbl[:, 1] == 1)[0] for idx in f1: lst_ni1.append(idx) for idx in f2: @@ -474,11 +497,11 @@ class DGPLVM_KFDA(Prior): count = 0 for N_i in lst_ni: if N_i == lst_ni[0]: - a[count:count + N_i] = (float(1) / N_i) * a[count] + a[count : count + N_i] = (float(1) / N_i) * a[count] count += N_i else: if N_i == lst_ni[1]: - a[count: count + N_i] = -(float(1) / N_i) * a[count] + a[count : count + N_i] = -(float(1) / N_i) * a[count] count += N_i return a @@ -486,8 +509,12 @@ class DGPLVM_KFDA(Prior): A = np.zeros((self.datanum, self.datanum)) idx = 0 for N_i in lst_ni: - B = float(1) / np.sqrt(N_i) * (np.eye(N_i) - ((float(1) / N_i) * np.ones((N_i, N_i)))) - A[idx:idx + N_i, idx:idx + N_i] = B + B = ( + float(1) + / np.sqrt(N_i) + * (np.eye(N_i) - ((float(1) / N_i) * np.ones((N_i, N_i)))) + ) + A[idx : idx + N_i, idx : idx + N_i] = B idx += N_i return A @@ -498,9 +525,11 @@ class DGPLVM_KFDA(Prior): a_trans = np.transpose(self.a) paran = self.lambdaa * np.eye(x.shape[0]) + self.A.dot(K).dot(self.A) inv_part = pdinv(paran)[0] - J = a_trans.dot(K).dot(self.a) - a_trans.dot(K).dot(self.A).dot(inv_part).dot(self.A).dot(K).dot(self.a) - J_star = (1. / self.lambdaa) * J - return (-1. / self.sigma2) * J_star + J = a_trans.dot(K).dot(self.a) - a_trans.dot(K).dot(self.A).dot(inv_part).dot( + self.A + ).dot(K).dot(self.a) + J_star = (1.0 / self.lambdaa) * J + return (-1.0 / self.sigma2) * J_star # Here gradient function def lnpdf_grad(self, x): @@ -511,15 +540,15 @@ class DGPLVM_KFDA(Prior): b = self.A.dot(inv_part).dot(self.A).dot(K).dot(self.a) a_Minus_b = self.a - b a_b_trans = np.transpose(a_Minus_b) - DJ_star_DK = (1. / self.lambdaa) * (a_Minus_b.dot(a_b_trans)) + DJ_star_DK = (1.0 / self.lambdaa) * (a_Minus_b.dot(a_b_trans)) DJ_star_DX = self.kern.gradients_X(DJ_star_DK, x) - return (-1. / self.sigma2) * DJ_star_DX + return (-1.0 / self.sigma2) * DJ_star_DX def rvs(self, n): return np.random.rand(n) # A WRONG implementation def __str__(self): - return 'DGPLVM_prior' + return "DGPLVM_prior" def __getstate___(self): return self.lbl, self.lambdaa, self.sigma2, self.kern, self.x_shape @@ -547,6 +576,7 @@ class DGPLVM(Prior): .. Note:: DGPLVM for Classification paper implementation """ + domain = _REAL def __new__(cls, sigma2, lbl, x_shape): @@ -606,7 +636,7 @@ class DGPLVM(Prior): for i in data_idx: if len(lst_idx) == 0: pass - #Do nothing, because it is the first time list is created so is empty + # Do nothing, because it is the first time list is created so is empty else: lst_idx = [] # Here we put indices of each class in to the list called lst_idx_all @@ -631,9 +661,9 @@ class DGPLVM(Prior): N_i = float(len(cls[i])) W_WT = np.zeros((self.dim, self.dim)) for xk in cls[i]: - W = (xk - M_i[i]) + W = xk - M_i[i] W_WT += np.outer(W, W) - Sw += (N_i / self.datanum) * ((1. / N_i) * W_WT) + Sw += (N_i / self.datanum) * ((1.0 / N_i) * W_WT) return Sw # Calculating beta and Bi for Sb @@ -658,7 +688,6 @@ class DGPLVM(Prior): Sig_beta_B_i_all = Sig_beta_B_i_all.transpose() return Sig_beta_B_i_all - # Calculating W_j s separately so we can access all the W_j s anytime def compute_wj(self, data_idx, M_i): W_i = np.zeros((self.datanum, self.dim)) @@ -667,7 +696,7 @@ class DGPLVM(Prior): for tpl in data_idx[i]: xj = tpl[1] j = tpl[0] - W_i[j] = (xj - M_i[i]) + W_i[j] = xj - M_i[i] return W_i # Calculating alpha and Wj for Sw @@ -680,11 +709,11 @@ class DGPLVM(Prior): for j in lst_idx_all[i]: if k == j: alpha = 1 - (float(1) / N_i) - Sig_alpha_W_i[k] += (alpha * W_i[j]) + Sig_alpha_W_i[k] += alpha * W_i[j] else: alpha = 0 - (float(1) / N_i) - Sig_alpha_W_i[k] += (alpha * W_i[j]) - Sig_alpha_W_i = (1. / self.datanum) * np.transpose(Sig_alpha_W_i) + Sig_alpha_W_i[k] += alpha * W_i[j] + Sig_alpha_W_i = (1.0 / self.datanum) * np.transpose(Sig_alpha_W_i) return Sig_alpha_W_i # This function calculates log of our prior @@ -696,9 +725,9 @@ class DGPLVM(Prior): Sb = self.compute_Sb(cls, M_i, M_0) Sw = self.compute_Sw(cls, M_i) # sb_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) - #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) - #Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] - Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0])*0.1)[0] + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + # Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] + Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0]) * 0.1)[0] return (-1 / self.sigma2) * np.trace(Sb_inv_N.dot(Sw)) # This function calculates derivative of the log of prior function @@ -717,19 +746,20 @@ class DGPLVM(Prior): # Calculating inverse of Sb and its transpose and minus # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) - #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) - #Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] - Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0])*0.1)[0] + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + # Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] + Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0]) * 0.1)[0] Sb_inv_N_trans = np.transpose(Sb_inv_N) Sb_inv_N_trans_minus = -1 * Sb_inv_N_trans Sw_trans = np.transpose(Sw) # Calculating DJ/DXk DJ_Dxk = 2 * ( - Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + Sb_inv_N_trans.dot( - Sig_alpha_W_i)) + Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + + Sb_inv_N_trans.dot(Sig_alpha_W_i) + ) # Calculating derivative of the log of the prior - DPx_Dx = ((-1 / self.sigma2) * DJ_Dxk) + DPx_Dx = (-1 / self.sigma2) * DJ_Dxk return DPx_Dx.T # def frb(self, x): @@ -744,7 +774,7 @@ class DGPLVM(Prior): return np.random.rand(n) # A WRONG implementation def __str__(self): - return 'DGPLVM_prior_Raq' + return "DGPLVM_prior_Raq" # ****************************************** @@ -752,6 +782,7 @@ class DGPLVM(Prior): from . import Parameterized from . import Param + class DGPLVM_Lamda(Prior, Parameterized): """ Implementation of the Discriminative Gaussian Process Latent Variable model paper, by Raquel. @@ -761,6 +792,7 @@ class DGPLVM_Lamda(Prior, Parameterized): .. Note:: DGPLVM for Classification paper implementation """ + domain = _REAL # _instances = [] # def __new__(cls, mu, sigma): # Singleton: @@ -773,7 +805,7 @@ class DGPLVM_Lamda(Prior, Parameterized): # cls._instances.append(weakref.ref(o)) # return cls._instances[-1]() - def __init__(self, sigma2, lbl, x_shape, lamda, name='DP_prior'): + def __init__(self, sigma2, lbl, x_shape, lamda, name="DP_prior"): super(DGPLVM_Lamda, self).__init__(name=name) self.sigma2 = sigma2 # self.x = x @@ -783,7 +815,7 @@ class DGPLVM_Lamda(Prior, Parameterized): self.datanum = lbl.shape[0] self.x_shape = x_shape self.dim = x_shape[1] - self.lamda = Param('lamda', np.diag(lamda)) + self.lamda = Param("lamda", np.diag(lamda)) self.link_parameter(self.lamda) def get_class_label(self, y): @@ -831,7 +863,7 @@ class DGPLVM_Lamda(Prior, Parameterized): for i in data_idx: if len(lst_idx) == 0: pass - #Do nothing, because it is the first time list is created so is empty + # Do nothing, because it is the first time list is created so is empty else: lst_idx = [] # Here we put indices of each class in to the list called lst_idx_all @@ -856,9 +888,9 @@ class DGPLVM_Lamda(Prior, Parameterized): N_i = float(len(cls[i])) W_WT = np.zeros((self.dim, self.dim)) for xk in cls[i]: - W = (xk - M_i[i]) + W = xk - M_i[i] W_WT += np.outer(W, W) - Sw += (N_i / self.datanum) * ((1. / N_i) * W_WT) + Sw += (N_i / self.datanum) * ((1.0 / N_i) * W_WT) return Sw # Calculating beta and Bi for Sb @@ -883,7 +915,6 @@ class DGPLVM_Lamda(Prior, Parameterized): Sig_beta_B_i_all = Sig_beta_B_i_all.transpose() return Sig_beta_B_i_all - # Calculating W_j s separately so we can access all the W_j s anytime def compute_wj(self, data_idx, M_i): W_i = np.zeros((self.datanum, self.dim)) @@ -892,7 +923,7 @@ class DGPLVM_Lamda(Prior, Parameterized): for tpl in data_idx[i]: xj = tpl[1] j = tpl[0] - W_i[j] = (xj - M_i[i]) + W_i[j] = xj - M_i[i] return W_i # Calculating alpha and Wj for Sw @@ -905,11 +936,11 @@ class DGPLVM_Lamda(Prior, Parameterized): for j in lst_idx_all[i]: if k == j: alpha = 1 - (float(1) / N_i) - Sig_alpha_W_i[k] += (alpha * W_i[j]) + Sig_alpha_W_i[k] += alpha * W_i[j] else: alpha = 0 - (float(1) / N_i) - Sig_alpha_W_i[k] += (alpha * W_i[j]) - Sig_alpha_W_i = (1. / self.datanum) * np.transpose(Sig_alpha_W_i) + Sig_alpha_W_i[k] += alpha * W_i[j] + Sig_alpha_W_i = (1.0 / self.datanum) * np.transpose(Sig_alpha_W_i) return Sig_alpha_W_i # This function calculates log of our prior @@ -917,7 +948,7 @@ class DGPLVM_Lamda(Prior, Parameterized): x = x.reshape(self.x_shape) #!!!!!!!!!!!!!!!!!!!!!!!!!!! - #self.lamda.values[:] = self.lamda.values/self.lamda.values.sum() + # self.lamda.values[:] = self.lamda.values/self.lamda.values.sum() xprime = x.dot(np.diagflat(self.lamda)) x = xprime @@ -928,9 +959,9 @@ class DGPLVM_Lamda(Prior, Parameterized): Sb = self.compute_Sb(cls, M_i, M_0) Sw = self.compute_Sw(cls, M_i) # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) - #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) - #Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.5))[0] - Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0])*0.9)[0] + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + # Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.5))[0] + Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0]) * 0.9)[0] return (-1 / self.sigma2) * np.trace(Sb_inv_N.dot(Sw)) # This function calculates derivative of the log of prior function @@ -952,19 +983,20 @@ class DGPLVM_Lamda(Prior, Parameterized): # Calculating inverse of Sb and its transpose and minus # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) - #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) - #Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.5))[0] - Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0])*0.9)[0] + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + # Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.5))[0] + Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0]) * 0.9)[0] Sb_inv_N_trans = np.transpose(Sb_inv_N) Sb_inv_N_trans_minus = -1 * Sb_inv_N_trans Sw_trans = np.transpose(Sw) # Calculating DJ/DXk DJ_Dxk = 2 * ( - Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + Sb_inv_N_trans.dot( - Sig_alpha_W_i)) + Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + + Sb_inv_N_trans.dot(Sig_alpha_W_i) + ) # Calculating derivative of the log of the prior - DPx_Dx = ((-1 / self.sigma2) * DJ_Dxk) + DPx_Dx = (-1 / self.sigma2) * DJ_Dxk DPxprim_Dx = np.diagflat(self.lamda).dot(DPx_Dx) @@ -980,7 +1012,6 @@ class DGPLVM_Lamda(Prior, Parameterized): # print DPxprim_Dx return DPxprim_Dx - # def frb(self, x): # from functools import partial # from GPy.models import GradientChecker @@ -993,10 +1024,12 @@ class DGPLVM_Lamda(Prior, Parameterized): return np.random.rand(n) # A WRONG implementation def __str__(self): - return 'DGPLVM_prior_Raq_Lamda' + return "DGPLVM_prior_Raq_Lamda" + # ****************************************** + class DGPLVM_T(Prior): """ Implementation of the Discriminative Gaussian Process Latent Variable model paper, by Raquel. @@ -1006,6 +1039,7 @@ class DGPLVM_T(Prior): .. Note:: DGPLVM for Classification paper implementation """ + domain = _REAL # _instances = [] # def __new__(cls, mu, sigma): # Singleton: @@ -1028,7 +1062,6 @@ class DGPLVM_T(Prior): self.dim = x_shape[1] self.vec = vec - def get_class_label(self, y): for idx, v in enumerate(y): if v == 1: @@ -1075,7 +1108,7 @@ class DGPLVM_T(Prior): for i in data_idx: if len(lst_idx) == 0: pass - #Do nothing, because it is the first time list is created so is empty + # Do nothing, because it is the first time list is created so is empty else: lst_idx = [] # Here we put indices of each class in to the list called lst_idx_all @@ -1100,9 +1133,9 @@ class DGPLVM_T(Prior): N_i = float(len(cls[i])) W_WT = np.zeros((self.dim, self.dim)) for xk in cls[i]: - W = (xk - M_i[i]) + W = xk - M_i[i] W_WT += np.outer(W, W) - Sw += (N_i / self.datanum) * ((1. / N_i) * W_WT) + Sw += (N_i / self.datanum) * ((1.0 / N_i) * W_WT) return Sw # Calculating beta and Bi for Sb @@ -1127,7 +1160,6 @@ class DGPLVM_T(Prior): Sig_beta_B_i_all = Sig_beta_B_i_all.transpose() return Sig_beta_B_i_all - # Calculating W_j s separately so we can access all the W_j s anytime def compute_wj(self, data_idx, M_i): W_i = np.zeros((self.datanum, self.dim)) @@ -1136,7 +1168,7 @@ class DGPLVM_T(Prior): for tpl in data_idx[i]: xj = tpl[1] j = tpl[0] - W_i[j] = (xj - M_i[i]) + W_i[j] = xj - M_i[i] return W_i # Calculating alpha and Wj for Sw @@ -1149,11 +1181,11 @@ class DGPLVM_T(Prior): for j in lst_idx_all[i]: if k == j: alpha = 1 - (float(1) / N_i) - Sig_alpha_W_i[k] += (alpha * W_i[j]) + Sig_alpha_W_i[k] += alpha * W_i[j] else: alpha = 0 - (float(1) / N_i) - Sig_alpha_W_i[k] += (alpha * W_i[j]) - Sig_alpha_W_i = (1. / self.datanum) * np.transpose(Sig_alpha_W_i) + Sig_alpha_W_i[k] += alpha * W_i[j] + Sig_alpha_W_i = (1.0 / self.datanum) * np.transpose(Sig_alpha_W_i) return Sig_alpha_W_i # This function calculates log of our prior @@ -1168,10 +1200,10 @@ class DGPLVM_T(Prior): Sb = self.compute_Sb(cls, M_i, M_0) Sw = self.compute_Sw(cls, M_i) # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) - #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) - #print 'SB_inv: ', Sb_inv_N - #Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] - Sb_inv_N = pdinv(Sb+np.eye(Sb.shape[0])*0.1)[0] + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + # print 'SB_inv: ', Sb_inv_N + # Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] + Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0]) * 0.1)[0] return (-1 / self.sigma2) * np.trace(Sb_inv_N.dot(Sw)) # This function calculates derivative of the log of prior function @@ -1193,20 +1225,21 @@ class DGPLVM_T(Prior): # Calculating inverse of Sb and its transpose and minus # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) - #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) - #print 'SB_inv: ',Sb_inv_N - #Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] - Sb_inv_N = pdinv(Sb+np.eye(Sb.shape[0])*0.1)[0] + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + # print 'SB_inv: ',Sb_inv_N + # Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] + Sb_inv_N = pdinv(Sb + np.eye(Sb.shape[0]) * 0.1)[0] Sb_inv_N_trans = np.transpose(Sb_inv_N) Sb_inv_N_trans_minus = -1 * Sb_inv_N_trans Sw_trans = np.transpose(Sw) # Calculating DJ/DXk DJ_Dxk = 2 * ( - Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + Sb_inv_N_trans.dot( - Sig_alpha_W_i)) + Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + + Sb_inv_N_trans.dot(Sig_alpha_W_i) + ) # Calculating derivative of the log of the prior - DPx_Dx = ((-1 / self.sigma2) * DJ_Dxk) + DPx_Dx = (-1 / self.sigma2) * DJ_Dxk return DPx_Dx.T # def frb(self, x): @@ -1221,9 +1254,7 @@ class DGPLVM_T(Prior): return np.random.rand(n) # A WRONG implementation def __str__(self): - return 'DGPLVM_prior_Raq_TTT' - - + return "DGPLVM_prior_Raq_TTT" class HalfT(Prior): @@ -1234,6 +1265,7 @@ class HalfT(Prior): :param nu: degrees of freedom """ + domain = _POSITIVE _instances = [] @@ -1250,13 +1282,22 @@ class HalfT(Prior): def __init__(self, A, nu): self.A = float(A) self.nu = float(nu) - self.constant = gammaln(.5*(self.nu+1.)) - gammaln(.5*self.nu) - .5*np.log(np.pi*self.A*self.nu) + self.constant = ( + gammaln(0.5 * (self.nu + 1.0)) + - gammaln(0.5 * self.nu) + - 0.5 * np.log(np.pi * self.A * self.nu) + ) def __str__(self): return "hT({:.2g}, {:.2g})".format(self.A, self.nu) def lnpdf(self, theta): - return (theta > 0) * (self.constant - .5*(self.nu + 1) * np.log(1. + (1./self.nu) * (theta/self.A)**2)) + return (theta > 0) * ( + self.constant + - 0.5 + * (self.nu + 1) + * np.log(1.0 + (1.0 / self.nu) * (theta / self.A) ** 2) + ) # theta = theta if isinstance(theta,np.ndarray) else np.array([theta]) # lnpdfs = np.zeros_like(theta) @@ -1268,7 +1309,7 @@ class HalfT(Prior): # lnpdfs[above_zero] = (+ gammaln((v + 1) * 0.5) # - gammaln(v * 0.5) # - 0.5*np.log(sigma2 * v * np.pi) - # - 0.5*(v + 1)*np.log(1 + (1/np.float(v))*((theta[above_zero][0]**2)/sigma2)) + # - 0.5*(v + 1)*np.log(1 + (1/float(v))*((theta[above_zero][0]**2)/sigma2)) # ) # return lnpdfs @@ -1278,12 +1319,18 @@ class HalfT(Prior): above_zero = theta > 1e-6 v = self.nu sigma2 = self.A - grad[above_zero] = -0.5*(v+1)*(2*theta[above_zero])/(v*sigma2 + theta[above_zero][0]**2) + grad[above_zero] = ( + -0.5 + * (v + 1) + * (2 * theta[above_zero]) + / (v * sigma2 + theta[above_zero][0] ** 2) + ) return grad def rvs(self, n): # return np.random.randn(n) * self.sigma + self.mu from scipy.stats import t + # [np.abs(x) for x in t.rvs(df=4,loc=0,scale=50, size=10000)]) ret = t.rvs(self.nu, loc=0, scale=self.A, size=n) ret[ret < 0] = 0 @@ -1298,6 +1345,7 @@ class Exponential(Prior): :param l: shape parameter """ + domain = _POSITIVE _instances = [] @@ -1318,22 +1366,25 @@ class Exponential(Prior): return "Exp({:.2g})".format(self.l) def summary(self): - ret = {"E[x]": 1. / self.l, - "E[ln x]": np.nan, - "var[x]": 1. / self.l**2, - "Entropy": 1. - np.log(self.l), - "Mode": 0.} + ret = { + "E[x]": 1.0 / self.l, + "E[ln x]": np.nan, + "var[x]": 1.0 / self.l**2, + "Entropy": 1.0 - np.log(self.l), + "Mode": 0.0, + } return ret def lnpdf(self, x): return np.log(self.l) - self.l * x def lnpdf_grad(self, x): - return - self.l + return -self.l def rvs(self, n): return np.random.exponential(scale=self.l, size=n) + class StudentT(Prior): """ Implementation of the student t probability function, coupled with random variables. @@ -1345,6 +1396,7 @@ class StudentT(Prior): .. Note:: Bishop 2006 notation is used throughout the code """ + domain = _REAL _instances = [] @@ -1352,7 +1404,11 @@ class StudentT(Prior): if cls._instances: cls._instances[:] = [instance for instance in cls._instances if instance()] for instance in cls._instances: - if instance().mu == mu and instance().sigma == sigma and instance().nu == nu: + if ( + instance().mu == mu + and instance().sigma == sigma + and instance().nu == nu + ): return instance() newfunc = super(Prior, cls).__new__ if newfunc is object.__new__: @@ -1373,13 +1429,18 @@ class StudentT(Prior): def lnpdf(self, x): from scipy.stats import t - return t.logpdf(x,self.nu,self.mu,self.sigma) + + return t.logpdf(x, self.nu, self.mu, self.sigma) def lnpdf_grad(self, x): - return -(self.nu + 1.)*(x - self.mu)/( self.nu*self.sigma2 + np.square(x - self.mu) ) + return ( + -(self.nu + 1.0) + * (x - self.mu) + / (self.nu * self.sigma2 + np.square(x - self.mu)) + ) def rvs(self, n): from scipy.stats import t + ret = t.rvs(self.nu, loc=self.mu, scale=self.sigma, size=n) return ret - diff --git a/GPy/likelihoods/student_t.py b/GPy/likelihoods/student_t.py index e8de3c40..6c97a5d8 100644 --- a/GPy/likelihoods/student_t.py +++ b/GPy/likelihoods/student_t.py @@ -12,6 +12,7 @@ from ..core.parameterization import Param from paramz.transformations import Logexp from scipy.special import psi as digamma + class StudentT(Likelihood): """ Student T likelihood @@ -22,17 +23,18 @@ class StudentT(Likelihood): p(y_{i}|\\lambda(f_{i})) = \\frac{\\Gamma\\left(\\frac{v+1}{2}\\right)}{\\Gamma\\left(\\frac{v}{2}\\right)\\sqrt{v\\pi\\sigma^{2}}}\\left(1 + \\frac{1}{v}\\left(\\frac{(y_{i} - f_{i})^{2}}{\\sigma^{2}}\\right)\\right)^{\\frac{-v+1}{2}} """ - def __init__(self,gp_link=None, deg_free=5, sigma2=2): + + def __init__(self, gp_link=None, deg_free=5, sigma2=2): if gp_link is None: gp_link = link_functions.Identity() - super(StudentT, self).__init__(gp_link, name='Student_T') + super(StudentT, self).__init__(gp_link, name="Student_T") # sigma2 is not a noise parameter, it is a squared scale. - self.sigma2 = Param('t_scale2', float(sigma2), Logexp()) - self.v = Param('deg_free', float(deg_free), Logexp()) + self.sigma2 = Param("t_scale2", float(sigma2), Logexp()) + self.v = Param("deg_free", float(deg_free), Logexp()) self.link_parameter(self.sigma2) self.link_parameter(self.v) - #self.v.constrain_fixed() + # self.v.constrain_fixed() self.log_concave = False @@ -61,11 +63,14 @@ class StudentT(Likelihood): """ assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape e = y - inv_link_f - #Careful gamma(big_number) is infinity! - objective = ((np.exp(gammaln((self.v + 1)*0.5) - gammaln(self.v * 0.5)) - / (np.sqrt(self.v * np.pi * self.sigma2))) - * ((1 + (1./float(self.v))*((e**2)/float(self.sigma2)))**(-0.5*(self.v + 1))) - ) + # Careful gamma(big_number) is infinity! + objective = ( + np.exp(gammaln((self.v + 1) * 0.5) - gammaln(self.v * 0.5)) + / (np.sqrt(self.v * np.pi * self.sigma2)) + ) * ( + (1 + (1.0 / float(self.v)) * ((e**2) / float(self.sigma2))) + ** (-0.5 * (self.v + 1)) + ) return np.prod(objective) def logpdf_link(self, inv_link_f, y, Y_metadata=None): @@ -85,15 +90,16 @@ class StudentT(Likelihood): """ e = y - inv_link_f - #FIXME: - #Why does np.log(1 + (1/self.v)*((y-inv_link_f)**2)/self.sigma2) suppress the divide by zero?! - #But np.log(1 + (1/float(self.v))*((y-inv_link_f)**2)/self.sigma2) throws it correctly - #print - 0.5*(self.v + 1)*np.log(1 + (1/np.float(self.v))*((e**2)/self.sigma2)) - objective = (+ gammaln((self.v + 1) * 0.5) - - gammaln(self.v * 0.5) - - 0.5*np.log(self.sigma2 * self.v * np.pi) - - 0.5*(self.v + 1)*np.log(1 + (1/np.float(self.v))*((e**2)/self.sigma2)) - ) + # FIXME: + # Why does np.log(1 + (1/self.v)*((y-inv_link_f)**2)/self.sigma2) suppress the divide by zero?! + # But np.log(1 + (1/float(self.v))*((y-inv_link_f)**2)/self.sigma2) throws it correctly + # print - 0.5*(self.v + 1)*np.log(1 + (1/(self.v))*((e**2)/self.sigma2)) + objective = ( + +gammaln((self.v + 1) * 0.5) + - gammaln(self.v * 0.5) + - 0.5 * np.log(self.sigma2 * self.v * np.pi) + - 0.5 * (self.v + 1) * np.log(1 + (1 / (self.v)) * ((e**2) / self.sigma2)) + ) return objective def dlogpdf_dlink(self, inv_link_f, y, Y_metadata=None): @@ -138,7 +144,9 @@ class StudentT(Likelihood): (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) """ e = y - inv_link_f - hess = ((self.v + 1)*(e**2 - self.v*self.sigma2)) / ((self.sigma2*self.v + e**2)**2) + hess = ((self.v + 1) * (e**2 - self.v * self.sigma2)) / ( + (self.sigma2 * self.v + e**2) ** 2 + ) return hess def d3logpdf_dlink3(self, inv_link_f, y, Y_metadata=None): @@ -157,9 +165,9 @@ class StudentT(Likelihood): :rtype: Nx1 array """ e = y - inv_link_f - d3lik_dlink3 = ( -(2*(self.v + 1)*(-e)*(e**2 - 3*self.v*self.sigma2)) / - ((e**2 + self.sigma2*self.v)**3) - ) + d3lik_dlink3 = -( + 2 * (self.v + 1) * (-e) * (e**2 - 3 * self.v * self.sigma2) + ) / ((e**2 + self.sigma2 * self.v) ** 3) return d3lik_dlink3 def dlogpdf_link_dvar(self, inv_link_f, y, Y_metadata=None): @@ -179,7 +187,11 @@ class StudentT(Likelihood): """ e = y - inv_link_f e2 = np.square(e) - dlogpdf_dvar = self.v*(e2 - self.sigma2)/(2*self.sigma2*(self.sigma2*self.v + e2)) + dlogpdf_dvar = ( + self.v + * (e2 - self.sigma2) + / (2 * self.sigma2 * (self.sigma2 * self.v + e2)) + ) return dlogpdf_dvar def dlogpdf_dlink_dvar(self, inv_link_f, y, Y_metadata=None): @@ -198,7 +210,9 @@ class StudentT(Likelihood): :rtype: Nx1 array """ e = y - inv_link_f - dlogpdf_dlink_dvar = (self.v*(self.v+1)*(-e))/((self.sigma2*self.v + e**2)**2) + dlogpdf_dlink_dvar = (self.v * (self.v + 1) * (-e)) / ( + (self.sigma2 * self.v + e**2) ** 2 + ) return dlogpdf_dlink_dvar def d2logpdf_dlink2_dvar(self, inv_link_f, y, Y_metadata=None): @@ -217,9 +231,9 @@ class StudentT(Likelihood): :rtype: Nx1 array """ e = y - inv_link_f - d2logpdf_dlink2_dvar = ( (self.v*(self.v+1)*(self.sigma2*self.v - 3*(e**2))) - / ((self.sigma2*self.v + (e**2))**3) - ) + d2logpdf_dlink2_dvar = ( + self.v * (self.v + 1) * (self.sigma2 * self.v - 3 * (e**2)) + ) / ((self.sigma2 * self.v + (e**2)) ** 3) return d2logpdf_dlink2_dvar def dlogpdf_link_dv(self, inv_link_f, y, Y_metadata=None): @@ -227,9 +241,11 @@ class StudentT(Likelihood): e2 = np.square(e) df = float(self.v[:]) s2 = float(self.sigma2[:]) - dlogpdf_dv = 0.5*digamma(0.5*(df+1)) - 0.5*digamma(0.5*df) - 1.0/(2*df) - dlogpdf_dv += 0.5*(df+1)*e2/(df*(e2 + s2*df)) - dlogpdf_dv -= 0.5*np.log1p(e2/(s2*df)) + dlogpdf_dv = ( + 0.5 * digamma(0.5 * (df + 1)) - 0.5 * digamma(0.5 * df) - 1.0 / (2 * df) + ) + dlogpdf_dv += 0.5 * (df + 1) * e2 / (df * (e2 + s2 * df)) + dlogpdf_dv -= 0.5 * np.log1p(e2 / (s2 * df)) return dlogpdf_dv def dlogpdf_dlink_dv(self, inv_link_f, y, Y_metadata=None): @@ -237,7 +253,7 @@ class StudentT(Likelihood): e2 = np.square(e) df = float(self.v[:]) s2 = float(self.sigma2[:]) - dlogpdf_df_dv = e*(e2 - self.sigma2)/(e2 + s2*df)**2 + dlogpdf_df_dv = e * (e2 - self.sigma2) / (e2 + s2 * df) ** 2 return dlogpdf_df_dv def d2logpdf_dlink2_dv(self, inv_link_f, y, Y_metadata=None): @@ -245,8 +261,10 @@ class StudentT(Likelihood): e2 = np.square(e) df = float(self.v[:]) s2 = float(self.sigma2[:]) - e2_s2v = e**2 + s2*df - d2logpdf_df2_dv = (-s2*(df+1) + e2 - s2*df)/e2_s2v**2 - 2*s2*(df+1)*(e2 - s2*df)/e2_s2v**3 + e2_s2v = e**2 + s2 * df + d2logpdf_df2_dv = (-s2 * (df + 1) + e2 - s2 * df) / e2_s2v**2 - 2 * s2 * ( + df + 1 + ) * (e2 - s2 * df) / e2_s2v**3 return d2logpdf_df2_dv def dlogpdf_link_dtheta(self, f, y, Y_metadata=None): @@ -266,19 +284,23 @@ class StudentT(Likelihood): def predictive_mean(self, mu, sigma, Y_metadata=None): # The comment here confuses mean and median. - return self.gp_link.transf(mu) # only true if link is monotonic, which it is. + return self.gp_link.transf(mu) # only true if link is monotonic, which it is. - def predictive_variance(self, mu,variance, predictive_mean=None, Y_metadata=None): - if self.deg_free<=2.: - return np.empty(mu.shape)*np.nan # does not exist for degrees of freedom <= 2. + def predictive_variance(self, mu, variance, predictive_mean=None, Y_metadata=None): + if self.deg_free <= 2.0: + return ( + np.empty(mu.shape) * np.nan + ) # does not exist for degrees of freedom <= 2. else: - return super(StudentT, self).predictive_variance(mu, variance, predictive_mean, Y_metadata) + return super(StudentT, self).predictive_variance( + mu, variance, predictive_mean, Y_metadata + ) def conditional_mean(self, gp): return self.gp_link.transf(gp) def conditional_variance(self, gp): - return self.deg_free/(self.deg_free - 2.) + return self.deg_free / (self.deg_free - 2.0) def samples(self, gp, Y_metadata=None): """ @@ -288,11 +310,10 @@ class StudentT(Likelihood): """ orig_shape = gp.shape gp = gp.flatten() - #FIXME: Very slow as we are computing a new random variable per input! - #Can't get it to sample all at the same time - #student_t_samples = np.array([stats.t.rvs(self.v, self.gp_link.transf(gpj),scale=np.sqrt(self.sigma2), size=1) for gpj in gp]) - dfs = np.ones_like(gp)*self.v - scales = np.ones_like(gp)*np.sqrt(self.sigma2) - student_t_samples = stats.t.rvs(dfs, loc=self.gp_link.transf(gp), - scale=scales) + # FIXME: Very slow as we are computing a new random variable per input! + # Can't get it to sample all at the same time + # student_t_samples = np.array([stats.t.rvs(self.v, self.gp_link.transf(gpj),scale=np.sqrt(self.sigma2), size=1) for gpj in gp]) + dfs = np.ones_like(gp) * self.v + scales = np.ones_like(gp) * np.sqrt(self.sigma2) + student_t_samples = stats.t.rvs(dfs, loc=self.gp_link.transf(gp), scale=scales) return student_t_samples.reshape(orig_shape) diff --git a/benchmarks/regression/evaluation.py b/benchmarks/regression/evaluation.py index c57bce7e..7de8d5ae 100644 --- a/benchmarks/regression/evaluation.py +++ b/benchmarks/regression/evaluation.py @@ -4,18 +4,19 @@ import abc import numpy as np + class Evaluation(object): __metaclass__ = abc.ABCMeta - + @abc.abstractmethod def evaluate(self, gt, pred): """Compute a scalar for access the performance""" return None + class RMSE(Evaluation): "Rooted Mean Square Error" - name = 'RMSE' - + name = "RMSE" + def evaluate(self, gt, pred): - return np.sqrt(np.square(gt-pred).astype(np.float).mean()) - + return np.sqrt(np.square(gt - pred).astype(float).mean()) From 65af6ee35e7800f380293d8339e2cd5e3ac33394 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 16 Oct 2023 21:20:17 +0200 Subject: [PATCH 068/101] replace np.int by int --- GPy/kern/src/coregionalize.py | 97 +- GPy/kern/src/eq_ode1.py | 726 ++--- GPy/kern/src/eq_ode2.py | 1756 ++++++----- GPy/kern/src/todo/eq_ode1.py | 6 +- .../sparse_gp_coregionalized_regression.py | 66 +- GPy/models/ss_mrd.py | 406 ++- GPy/models/state_space_main.py | 2569 +++++++++++------ GPy/plotting/matplot_dep/base_plots.py | 139 +- GPy/plotting/matplot_dep/plot_definitions.py | 375 ++- GPy/testing/test_ep_likelihood.py | 2 +- GPy/testing/test_likelihood.py | 2 +- GPy/testing/test_model.py | 4 +- GPy/testing/test_pickle.py | 8 +- GPy/util/classification.py | 23 +- GPy/util/multioutput.py | 85 +- 15 files changed, 3889 insertions(+), 2375 deletions(-) diff --git a/GPy/kern/src/coregionalize.py b/GPy/kern/src/coregionalize.py index d05f5c6a..7f92d4f7 100644 --- a/GPy/kern/src/coregionalize.py +++ b/GPy/kern/src/coregionalize.py @@ -5,13 +5,16 @@ from .kern import Kern import numpy as np from ...core.parameterization import Param from paramz.transformations import Logexp -from ...util.config import config # for assesing whether to use cython +from ...util.config import config # for assesing whether to use cython try: from . import coregionalize_cython - use_coregionalize_cython = config.getboolean('cython', 'working') + + use_coregionalize_cython = config.getboolean("cython", "working") except ImportError: - print('warning in coregionalize: failed to import cython module: falling back to numpy') + print( + "warning in coregionalize: failed to import cython module: falling back to numpy" + ) use_coregionalize_cython = False @@ -43,22 +46,34 @@ class Coregionalize(Kern): .. note: see coregionalization examples in GPy.examples.regression for some usage. """ - def __init__(self, input_dim, output_dim, rank=1, W=None, kappa=None, active_dims=None, name='coregion'): + + def __init__( + self, + input_dim, + output_dim, + rank=1, + W=None, + kappa=None, + active_dims=None, + name="coregion", + ): super(Coregionalize, self).__init__(input_dim, active_dims, name=name) self.output_dim = output_dim self.rank = rank - if self.rank>output_dim: - print("Warning: Unusual choice of rank, it should normally be less than the output_dim.") + if self.rank > output_dim: + print( + "Warning: Unusual choice of rank, it should normally be less than the output_dim." + ) if W is None: - W = 0.5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank) + W = 0.5 * np.random.randn(self.output_dim, self.rank) / np.sqrt(self.rank) else: - assert W.shape==(self.output_dim, self.rank) - self.W = Param('W', W) + assert W.shape == (self.output_dim, self.rank) + self.W = Param("W", W) if kappa is None: - kappa = 0.5*np.ones(self.output_dim) + kappa = 0.5 * np.ones(self.output_dim) else: - assert kappa.shape==(self.output_dim, ) - self.kappa = Param('kappa', kappa, Logexp()) + assert kappa.shape == (self.output_dim,) + self.kappa = Param("kappa", kappa, Logexp()) self.link_parameters(self.W, self.kappa) def parameters_changed(self): @@ -70,63 +85,69 @@ class Coregionalize(Kern): else: return self._K_numpy(X, X2) - def _K_numpy(self, X, X2=None): - index = np.asarray(X, dtype=np.int) + index = np.asarray(X, dtype=int) if X2 is None: - return self.B[index,index.T] + return self.B[index, index.T] else: - index2 = np.asarray(X2, dtype=np.int) - return self.B[index,index2.T] + index2 = np.asarray(X2, dtype=int) + return self.B[index, index2.T] def _K_cython(self, X, X2=None): if X2 is None: - return coregionalize_cython.K_symmetric(self.B, np.asarray(X, dtype=np.int64)[:,0]) - return coregionalize_cython.K_asymmetric(self.B, np.asarray(X, dtype=np.int64)[:,0], np.asarray(X2, dtype=np.int64)[:,0]) - + return coregionalize_cython.K_symmetric( + self.B, np.asarray(X, dtype=np.int64)[:, 0] + ) + return coregionalize_cython.K_asymmetric( + self.B, + np.asarray(X, dtype=np.int64)[:, 0], + np.asarray(X2, dtype=np.int64)[:, 0], + ) def Kdiag(self, X): - return np.diag(self.B)[np.asarray(X, dtype=np.int).flatten()] + return np.diag(self.B)[np.asarray(X, dtype=int).flatten()] def update_gradients_full(self, dL_dK, X, X2=None): - index = np.asarray(X, dtype=np.int) + index = np.asarray(X, dtype=int) if X2 is None: index2 = index else: - index2 = np.asarray(X2, dtype=np.int) + index2 = np.asarray(X2, dtype=int) - #attempt to use cython for a nasty double indexing loop: fall back to numpy + # attempt to use cython for a nasty double indexing loop: fall back to numpy if use_coregionalize_cython: dL_dK_small = self._gradient_reduce_cython(dL_dK, index, index2) else: dL_dK_small = self._gradient_reduce_numpy(dL_dK, index, index2) - dkappa = np.diag(dL_dK_small).copy() dL_dK_small += dL_dK_small.T - dW = (self.W[:, None, :]*dL_dK_small[:, :, None]).sum(0) + dW = (self.W[:, None, :] * dL_dK_small[:, :, None]).sum(0) self.W.gradient = dW self.kappa.gradient = dkappa def _gradient_reduce_numpy(self, dL_dK, index, index2): - index, index2 = index[:,0], index2[:,0] + index, index2 = index[:, 0], index2[:, 0] dL_dK_small = np.zeros_like(self.B) for i in range(self.output_dim): - tmp1 = dL_dK[index==i] + tmp1 = dL_dK[index == i] for j in range(self.output_dim): - dL_dK_small[j,i] = tmp1[:,index2==j].sum() + dL_dK_small[j, i] = tmp1[:, index2 == j].sum() return dL_dK_small def _gradient_reduce_cython(self, dL_dK, index, index2): - index, index2 = np.int64(index[:,0]), np.int64(index2[:,0]) - return coregionalize_cython.gradient_reduce(self.B.shape[0], dL_dK, index, index2) - + index, index2 = np.int64(index[:, 0]), np.int64(index2[:, 0]) + return coregionalize_cython.gradient_reduce( + self.B.shape[0], dL_dK, index, index2 + ) def update_gradients_diag(self, dL_dKdiag, X): - index = np.asarray(X, dtype=np.int).flatten() - dL_dKdiag_small = np.array([dL_dKdiag[index==i].sum() for i in range(self.output_dim)]) - self.W.gradient = 2.*self.W*dL_dKdiag_small[:, None] + index = np.asarray(X, dtype=int).flatten() + dL_dKdiag_small = np.array( + [dL_dKdiag[index == i].sum() for i in range(self.output_dim)] + ) + self.W.gradient = 2.0 * self.W * dL_dKdiag_small[:, None] self.kappa.gradient = dL_dKdiag_small def gradients_X(self, dL_dK, X, X2=None): @@ -154,8 +175,8 @@ class Coregionalize(Kern): @staticmethod def _build_from_input_dict(kernel_class, input_dict): - useGPU = input_dict.pop('useGPU', None) + useGPU = input_dict.pop("useGPU", None) # W and kappa must be converted back to numpy arrays - input_dict['W'] = np.array(input_dict['W']) - input_dict['kappa'] = np.array(input_dict['kappa']) + input_dict["W"] = np.array(input_dict["W"]) + input_dict["kappa"] = np.array(input_dict["kappa"]) return Coregionalize(**input_dict) diff --git a/GPy/kern/src/eq_ode1.py b/GPy/kern/src/eq_ode1.py index 9c19bead..4361ec23 100644 --- a/GPy/kern/src/eq_ode1.py +++ b/GPy/kern/src/eq_ode1.py @@ -8,6 +8,7 @@ from ...core.parameterization import Param from paramz.transformations import Logexp from paramz.caching import Cache_this + class EQ_ODE1(Kern): """ Covariance function for first order differential equation driven by an exponentiated quadratic covariance. @@ -17,210 +18,236 @@ class EQ_ODE1(Kern): \frac{\text{d}y_j}{\text{d}t} = \sum_{i=1}^R w_{j,i} u_i(t-\delta_j) - d_jy_j(t) where :math:`R` is the rank of the system, :math:`w_{j,i}` is the sensitivity of the :math:`j`th output to the :math:`i`th latent function, :math:`d_j` is the decay rate of the :math:`j`th output and :math:`u_i(t)` are independent latent Gaussian processes goverened by an exponentiated quadratic covariance. - + :param output_dim: number of outputs driven by latent function. :type output_dim: int - :param W: sensitivities of each output to the latent driving function. + :param W: sensitivities of each output to the latent driving function. :type W: ndarray (output_dim x rank). :param rank: If rank is greater than 1 then there are assumed to be a total of rank latent forces independently driving the system, each with identical covariance. :type rank: int - :param decay: decay rates for the first order system. + :param decay: decay rates for the first order system. :type decay: array of length output_dim. :param delay: delay between latent force and output response. :type delay: array of length output_dim. :param kappa: diagonal term that allows each latent output to have an independent component to the response. :type kappa: array of length output_dim. - + .. Note: see first order differential equation examples in GPy.examples.regression for some usage. """ - def __init__(self, input_dim=2, output_dim=1, rank=1, W = None, lengthscale=None, decay=None, active_dims=None, name='eq_ode1'): + + def __init__( + self, + input_dim=2, + output_dim=1, + rank=1, + W=None, + lengthscale=None, + decay=None, + active_dims=None, + name="eq_ode1", + ): assert input_dim == 2, "only defined for 1 input dims" - super(EQ_ODE1, self).__init__(input_dim=input_dim, active_dims=active_dims, name=name) + super(EQ_ODE1, self).__init__( + input_dim=input_dim, active_dims=active_dims, name=name + ) self.rank = rank self.output_dim = output_dim if lengthscale is None: - lengthscale = .5 + np.random.rand(self.rank) + lengthscale = 0.5 + np.random.rand(self.rank) else: lengthscale = np.asarray(lengthscale) assert lengthscale.size in [1, self.rank], "Bad number of lengthscales" if lengthscale.size != self.rank: - lengthscale = np.ones(self.rank)*lengthscale - + lengthscale = np.ones(self.rank) * lengthscale + if W is None: - W = .5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank) + W = 0.5 * np.random.randn(self.output_dim, self.rank) / np.sqrt(self.rank) else: assert W.shape == (self.output_dim, self.rank) - + if decay is None: decay = np.ones(self.output_dim) else: decay = np.asarray(decay) assert decay.size in [1, self.output_dim], "Bad number of decay" if decay.size != self.output_dim: - decay = np.ones(self.output_dim)*decay + decay = np.ones(self.output_dim) * decay -# if kappa is None: -# self.kappa = np.ones(self.output_dim) -# else: -# kappa = np.asarray(kappa) -# assert kappa.size in [1, self.output_dim], "Bad number of kappa" -# if decay.size != self.output_dim: -# decay = np.ones(self.output_dim)*kappa + # if kappa is None: + # self.kappa = np.ones(self.output_dim) + # else: + # kappa = np.asarray(kappa) + # assert kappa.size in [1, self.output_dim], "Bad number of kappa" + # if decay.size != self.output_dim: + # decay = np.ones(self.output_dim)*kappa - #self.kappa = Param('kappa', kappa, Logexp()) - #self.delay = Param('delay', delay, Logexp()) - #self.is_normalized = True - #self.is_stationary = False - #self.gaussian_initial = False + # self.kappa = Param('kappa', kappa, Logexp()) + # self.delay = Param('delay', delay, Logexp()) + # self.is_normalized = True + # self.is_stationary = False + # self.gaussian_initial = False - self.lengthscale = Param('lengthscale', lengthscale, Logexp()) - self.decay = Param('decay', decay, Logexp()) - self.W = Param('W', W) + self.lengthscale = Param("lengthscale", lengthscale, Logexp()) + self.decay = Param("decay", decay, Logexp()) + self.W = Param("W", W) self.link_parameters(self.lengthscale, self.decay, self.W) @Cache_this(limit=3) def K(self, X, X2=None): - #This way is not working, indexes are lost after using k._slice_X - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # This way is not working, indexes are lost after using k._slice_X + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values index = np.int_(np.round(X[:, 1])) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim if X2 is None: if X_flag: - #Calculate covariance function for the latent functions + # Calculate covariance function for the latent functions index -= self.output_dim return self._Kuu(X, index) else: raise NotImplementedError else: - #This way is not working, indexes are lost after using k._slice_X - #index2 = np.asarray(X2, dtype=np.int) - #index2 = index2.reshape(index2.size,) - if hasattr(X2, 'values'): + # This way is not working, indexes are lost after using k._slice_X + # index2 = np.asarray(X2, dtype=int) + # index2 = index2.reshape(index2.size,) + if hasattr(X2, "values"): X2 = X2.values index2 = np.int_(np.round(X2[:, 1])) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) X2_flag = index2[0] >= self.output_dim - #Calculate cross-covariance function + # Calculate cross-covariance function if not X_flag and X2_flag: index2 -= self.output_dim - return self._Kfu(X, index, X2, index2) #Kfu + return self._Kfu(X, index, X2, index2) # Kfu elif X_flag and not X2_flag: index -= self.output_dim - return self._Kfu(X2, index2, X, index).T #Kuf + return self._Kfu(X2, index2, X, index).T # Kuf elif X_flag and X2_flag: index -= self.output_dim index2 -= self.output_dim - return self._Kusu(X, index, X2, index2) #Ku_s u + return self._Kusu(X, index, X2, index2) # Ku_s u else: - raise NotImplementedError #Kf_s f + raise NotImplementedError # Kf_s f - #Calculate the covariance function for diag(Kff(X,X)) + # Calculate the covariance function for diag(Kff(X,X)) def Kdiag(self, X): - if hasattr(X, 'values'): + if hasattr(X, "values"): index = np.int_(np.round(X[:, 1].values)) else: index = np.int_(np.round(X[:, 1])) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim - - if X_flag: #Kuudiag - return np.ones(X[:,0].shape) - else: #Kffdiag + + if X_flag: # Kuudiag + return np.ones(X[:, 0].shape) + else: # Kffdiag kdiag = self._Kdiag(X) return np.sum(kdiag, axis=1) - + def _Kdiag(self, X): - #This way is not working, indexes are lost after using k._slice_X - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # This way is not working, indexes are lost after using k._slice_X + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values index = np.int_(X[:, 1]) - index = index.reshape(index.size,) - - #terms that move along t + index = index.reshape( + index.size, + ) + + # terms that move along t t = X[:, 0].reshape(X.shape[0], 1) - d = np.unique(index) #Output Indexes + d = np.unique(index) # Output Indexes B = self.decay.values[d] S = self.W.values[d, :] - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - + B = B.reshape(B.size, 1) - #Terms that move along q + # Terms that move along q lq = self.lengthscale.values.reshape(1, self.rank) - S2 = S*S - kdiag = np.empty((t.size, )) + S2 = S * S + kdiag = np.empty((t.size,)) - #Dx1 terms - c0 = (S2/B)*((.5*np.sqrt(np.pi))*lq) + # Dx1 terms + c0 = (S2 / B) * ((0.5 * np.sqrt(np.pi)) * lq) - #DxQ terms - nu = lq*(B*.5) - nu2 = nu*nu - #Nx1 terms - gamt = -2.*B - gamt = gamt[index]*t + # DxQ terms + nu = lq * (B * 0.5) + nu2 = nu * nu + # Nx1 terms + gamt = -2.0 * B + gamt = gamt[index] * t - #NxQ terms - t_lq = t/lq + # NxQ terms + t_lq = t / lq # Upsilon Calculations # Using wofz - #erfnu = erf(nu) - - upm = np.exp(nu2[index, :] + lnDifErf( nu[index, :] ,t_lq+nu[index,:] )) - upm[t[:, 0] == 0, :] = 0. + # erfnu = erf(nu) - - upv = np.exp(nu2[index, :] + gamt + lnDifErf( -t_lq+nu[index,:], nu[index, :] ) ) - upv[t[:, 0] == 0, :] = 0. + upm = np.exp(nu2[index, :] + lnDifErf(nu[index, :], t_lq + nu[index, :])) + upm[t[:, 0] == 0, :] = 0.0 - #Covariance calculation - #kdiag = np.sum(c0[index, :]*(upm-upv), axis=1) - kdiag = c0[index, :]*(upm-upv) + upv = np.exp( + nu2[index, :] + gamt + lnDifErf(-t_lq + nu[index, :], nu[index, :]) + ) + upv[t[:, 0] == 0, :] = 0.0 + + # Covariance calculation + # kdiag = np.sum(c0[index, :]*(upm-upv), axis=1) + kdiag = c0[index, :] * (upm - upv) return kdiag - def update_gradients_full(self, dL_dK, X, X2 = None): - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + def update_gradients_full(self, dL_dK, X, X2=None): + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values self.decay.gradient = np.zeros(self.decay.shape) self.W.gradient = np.zeros(self.W.shape) self.lengthscale.gradient = np.zeros(self.lengthscale.shape) index = np.int_(np.round(X[:, 1])) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim if X2 is None: - if X_flag: #Kuu or Kmm + if X_flag: # Kuu or Kmm index -= self.output_dim - tmp = dL_dK*self._gkuu_lq(X, index) + tmp = dL_dK * self._gkuu_lq(X, index) for q in np.unique(index): ind = np.where(index == q) self.lengthscale.gradient[q] = tmp[np.ix_(ind[0], ind[0])].sum() else: raise NotImplementedError - else: #Kfu or Knm - #index2 = np.asarray(X2, dtype=np.int) - #index2 = index2.reshape(index2.size,) - if hasattr(X2, 'values'): + else: # Kfu or Knm + # index2 = np.asarray(X2, dtype=int) + # index2 = index2.reshape(index2.size,) + if hasattr(X2, "values"): X2 = X2.values index2 = np.int_(np.round(X2[:, 1])) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) X2_flag = index2[0] >= self.output_dim - if not X_flag and X2_flag: #Kfu + if not X_flag and X2_flag: # Kfu index2 -= self.output_dim - else: #Kuf - dL_dK = dL_dK.T #so we obtaing dL_Kfu + else: # Kuf + dL_dK = dL_dK.T # so we obtaing dL_Kfu indtemp = index - self.output_dim Xtemp = X X = X2 @@ -228,12 +255,12 @@ class EQ_ODE1(Kern): index = index2 index2 = indtemp glq, gSdq, gB = self._gkfu(X, index, X2, index2) - tmp = dL_dK*glq + tmp = dL_dK * glq for q in np.unique(index2): ind = np.where(index2 == q) self.lengthscale.gradient[q] = tmp[:, ind].sum() - tmpB = dL_dK*gB - tmp = dL_dK*gSdq + tmpB = dL_dK * gB + tmp = dL_dK * gSdq for d in np.unique(index): ind = np.where(index == d) self.decay.gradient[d] = tmpB[ind, :].sum() @@ -242,408 +269,463 @@ class EQ_ODE1(Kern): self.W.gradient[d, q] = tmp[np.ix_(ind[0], ind2[0])].sum() def update_gradients_diag(self, dL_dKdiag, X): - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values self.decay.gradient = np.zeros(self.decay.shape) self.W.gradient = np.zeros(self.W.shape) self.lengthscale.gradient = np.zeros(self.lengthscale.shape) index = np.int_(X[:, 1]) - index = index.reshape(index.size,) - + index = index.reshape( + index.size, + ) + glq, gS, gB = self._gkdiag(X, index) if dL_dKdiag.size == X.shape[0]: dL_dKdiag = np.reshape(dL_dKdiag, (index.size, 1)) - tmp = dL_dKdiag*glq + tmp = dL_dKdiag * glq self.lengthscale.gradient = tmp.sum(0) - tmpB = dL_dKdiag*gB - tmp = dL_dKdiag*gS + tmpB = dL_dKdiag * gB + tmp = dL_dKdiag * gS for d in np.unique(index): ind = np.where(index == d) self.decay.gradient[d] = tmpB[ind, :].sum() self.W.gradient[d, :] = tmp[ind].sum(0) def gradients_X(self, dL_dK, X, X2=None): - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values index = np.int_(np.round(X[:, 1])) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim - #If input_dim == 1, use this - #gX = np.zeros((X.shape[0], 1)) - #Cheat to allow gradient for input_dim==2 + # If input_dim == 1, use this + # gX = np.zeros((X.shape[0], 1)) + # Cheat to allow gradient for input_dim==2 gX = np.zeros(X.shape) - if X2 is None: #Kuu or Kmm + if X2 is None: # Kuu or Kmm if X_flag: index -= self.output_dim - gX[:, 0] = 2.*(dL_dK*self._gkuu_X(X, index)).sum(0) + gX[:, 0] = 2.0 * (dL_dK * self._gkuu_X(X, index)).sum(0) return gX else: raise NotImplementedError - else: #Kuf or Kmn - #index2 = np.asarray(X2, dtype=np.int) - #index2 = index2.reshape(index2.size,) - if hasattr(X2, 'values'): + else: # Kuf or Kmn + # index2 = np.asarray(X2, dtype=int) + # index2 = index2.reshape(index2.size,) + if hasattr(X2, "values"): X2 = X2.values index2 = np.int_(np.round(X2[:, 1])) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) X2_flag = index2[0] >= self.output_dim - if X_flag and not X2_flag: #gradient of Kuf(Z, X) wrt Z + if X_flag and not X2_flag: # gradient of Kuf(Z, X) wrt Z index -= self.output_dim - gX[:, 0] = (dL_dK*self._gkfu_z(X2, index2, X, index).T).sum(1) + gX[:, 0] = (dL_dK * self._gkfu_z(X2, index2, X, index).T).sum(1) return gX else: raise NotImplementedError - #---------------------------------------# + # ---------------------------------------# # Helper functions # - #---------------------------------------# + # ---------------------------------------# - #Evaluation of squared exponential for LFM + # Evaluation of squared exponential for LFM def _Kuu(self, X, index): - index = index.reshape(index.size,) - t = X[:, 0].reshape(X.shape[0],) - lq = self.lengthscale.values.reshape(self.rank,) - lq2 = lq*lq - #Covariance matrix initialization + index = index.reshape( + index.size, + ) + t = X[:, 0].reshape( + X.shape[0], + ) + lq = self.lengthscale.values.reshape( + self.rank, + ) + lq2 = lq * lq + # Covariance matrix initialization kuu = np.zeros((t.size, t.size)) - #Assign 1. to diagonal terms - kuu[np.diag_indices(t.size)] = 1. - #Upper triangular indices + # Assign 1. to diagonal terms + kuu[np.diag_indices(t.size)] = 1.0 + # Upper triangular indices indtri1, indtri2 = np.triu_indices(t.size, 1) - #Block Diagonal indices among Upper Triangular indices + # Block Diagonal indices among Upper Triangular indices ind = np.where(index[indtri1] == index[indtri2]) indr = indtri1[ind] indc = indtri2[ind] r = t[indr] - t[indc] - r2 = r*r - #Calculation of covariance function - kuu[indr, indc] = np.exp(-r2/lq2[index[indr]]) - #Completion of lower triangular part + r2 = r * r + # Calculation of covariance function + kuu[indr, indc] = np.exp(-r2 / lq2[index[indr]]) + # Completion of lower triangular part kuu[indc, indr] = kuu[indr, indc] return kuu def _Kusu(self, X, index, X2, index2): - index = index.reshape(index.size,) - index2 = index2.reshape(index2.size,) - t = X[:, 0].reshape(X.shape[0],1) - t2 = X2[:, 0].reshape(1,X2.shape[0]) - lq = self.lengthscale.values.reshape(self.rank,) - #Covariance matrix initialization + index = index.reshape( + index.size, + ) + index2 = index2.reshape( + index2.size, + ) + t = X[:, 0].reshape(X.shape[0], 1) + t2 = X2[:, 0].reshape(1, X2.shape[0]) + lq = self.lengthscale.values.reshape( + self.rank, + ) + # Covariance matrix initialization kuu = np.zeros((t.size, t2.size)) for q in range(self.rank): ind1 = index == q ind2 = index2 == q - r = t[ind1]/lq[q] - t2[0,ind2]/lq[q] - r2 = r*r - #Calculation of covariance function + r = t[ind1] / lq[q] - t2[0, ind2] / lq[q] + r2 = r * r + # Calculation of covariance function kuu[np.ix_(ind1, ind2)] = np.exp(-r2) return kuu - #Evaluation of cross-covariance function + # Evaluation of cross-covariance function def _Kfu(self, X, index, X2, index2): - #terms that move along t + # terms that move along t t = X[:, 0].reshape(X.shape[0], 1) - d = np.unique(index) #Output Indexes + d = np.unique(index) # Output Indexes B = self.decay.values[d] S = self.W.values[d, :] - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Output related variables must be column-wise + # Output related variables must be column-wise B = B.reshape(B.size, 1) - #Input related variables must be row-wise + # Input related variables must be row-wise z = X2[:, 0].reshape(1, X2.shape[0]) lq = self.lengthscale.values.reshape((1, self.rank)) kfu = np.empty((t.size, z.size)) - #DxQ terms - c0 = S*((.5*np.sqrt(np.pi))*lq) - nu = B*(.5*lq) + # DxQ terms + c0 = S * ((0.5 * np.sqrt(np.pi)) * lq) + nu = B * (0.5 * lq) nu2 = nu**2 - #1xM terms - z_lq = z/lq[0, index2] - #NxM terms - tz = t-z - tz_lq = tz/lq[0, index2] + # 1xM terms + z_lq = z / lq[0, index2] + # NxM terms + tz = t - z + tz_lq = tz / lq[0, index2] # Upsilon Calculations fullind = np.ix_(index, index2) - upsi = np.exp(nu2[fullind] - B[index]*tz + lnDifErf( -tz_lq + nu[fullind], z_lq+nu[fullind])) - upsi[t[:, 0] == 0, :] = 0. - #Covariance calculation - kfu = c0[fullind]*upsi + upsi = np.exp( + nu2[fullind] + - B[index] * tz + + lnDifErf(-tz_lq + nu[fullind], z_lq + nu[fullind]) + ) + upsi[t[:, 0] == 0, :] = 0.0 + # Covariance calculation + kfu = c0[fullind] * upsi return kfu - #Gradient of Kuu wrt lengthscale + # Gradient of Kuu wrt lengthscale def _gkuu_lq(self, X, index): - t = X[:, 0].reshape(X.shape[0],) - index = index.reshape(X.shape[0],) - lq = self.lengthscale.values.reshape(self.rank,) - lq2 = lq*lq - #Covariance matrix initialization + t = X[:, 0].reshape( + X.shape[0], + ) + index = index.reshape( + X.shape[0], + ) + lq = self.lengthscale.values.reshape( + self.rank, + ) + lq2 = lq * lq + # Covariance matrix initialization glq = np.zeros((t.size, t.size)) - #Upper triangular indices + # Upper triangular indices indtri1, indtri2 = np.triu_indices(t.size, 1) - #Block Diagonal indices among Upper Triangular indices + # Block Diagonal indices among Upper Triangular indices ind = np.where(index[indtri1] == index[indtri2]) indr = indtri1[ind] indc = indtri2[ind] r = t[indr] - t[indc] - r2 = r*r - r2_lq2 = r2/lq2[index[indr]] - #Calculation of covariance function + r2 = r * r + r2_lq2 = r2 / lq2[index[indr]] + # Calculation of covariance function er2_lq2 = np.exp(-r2_lq2) - #Gradient wrt lq - c = 2.*r2_lq2/lq[index[indr]] - glq[indr, indc] = er2_lq2*c - #Complete the lower triangular + # Gradient wrt lq + c = 2.0 * r2_lq2 / lq[index[indr]] + glq[indr, indc] = er2_lq2 * c + # Complete the lower triangular glq[indc, indr] = glq[indr, indc] return glq - #Be careful this derivative should be transpose it - def _gkuu_X(self, X, index): #Diagonal terms are always zero - t = X[:, 0].reshape(X.shape[0],) - index = index.reshape(index.size,) - lq = self.lengthscale.values.reshape(self.rank,) - lq2 = lq*lq - #Covariance matrix initialization + # Be careful this derivative should be transpose it + def _gkuu_X(self, X, index): # Diagonal terms are always zero + t = X[:, 0].reshape( + X.shape[0], + ) + index = index.reshape( + index.size, + ) + lq = self.lengthscale.values.reshape( + self.rank, + ) + lq2 = lq * lq + # Covariance matrix initialization gt = np.zeros((t.size, t.size)) - #Upper triangular indices - indtri1, indtri2 = np.triu_indices(t.size, 1) #Offset of 1 from the diagonal - #Block Diagonal indices among Upper Triangular indices + # Upper triangular indices + indtri1, indtri2 = np.triu_indices(t.size, 1) # Offset of 1 from the diagonal + # Block Diagonal indices among Upper Triangular indices ind = np.where(index[indtri1] == index[indtri2]) indr = indtri1[ind] indc = indtri2[ind] r = t[indr] - t[indc] - r2 = r*r - r2_lq2 = r2/(-lq2[index[indr]]) - #Calculation of covariance function + r2 = r * r + r2_lq2 = r2 / (-lq2[index[indr]]) + # Calculation of covariance function er2_lq2 = np.exp(r2_lq2) - #Gradient wrt t - c = 2.*r/lq2[index[indr]] - gt[indr, indc] = er2_lq2*c - #Complete the lower triangular + # Gradient wrt t + c = 2.0 * r / lq2[index[indr]] + gt[indr, indc] = er2_lq2 * c + # Complete the lower triangular gt[indc, indr] = -gt[indr, indc] return gt - #Gradients for Diagonal Kff + # Gradients for Diagonal Kff def _gkdiag(self, X, index): - index = index.reshape(index.size,) - #terms that move along t + index = index.reshape( + index.size, + ) + # terms that move along t d = np.unique(index) B = self.decay[d].values S = self.W[d, :].values - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Output related variables must be column-wise + # Output related variables must be column-wise t = X[:, 0].reshape(X.shape[0], 1) B = B.reshape(B.size, 1) - S2 = S*S + S2 = S * S - #Input related variables must be row-wise + # Input related variables must be row-wise lq = self.lengthscale.values.reshape(1, self.rank) gB = np.empty((t.size,)) glq = np.empty((t.size, lq.size)) gS = np.empty((t.size, lq.size)) - #Dx1 terms - c0 = S2*lq*np.sqrt(np.pi) + # Dx1 terms + c0 = S2 * lq * np.sqrt(np.pi) - #DxQ terms - nu = (.5*lq)*B - nu2 = nu*nu - - #Nx1 terms - gamt = -B[index]*t + # DxQ terms + nu = (0.5 * lq) * B + nu2 = nu * nu + + # Nx1 terms + gamt = -B[index] * t egamt = np.exp(gamt) - e2gamt = egamt*egamt + e2gamt = egamt * egamt - #NxQ terms - t_lq = t/lq - t2_lq2 = -t_lq*t_lq + # NxQ terms + t_lq = t / lq + t2_lq2 = -t_lq * t_lq - etlq2gamt = np.exp(t2_lq2 + gamt) #NXQ + etlq2gamt = np.exp(t2_lq2 + gamt) # NXQ ##Upsilon calculations - #erfnu = erf(nu) #TODO: This can be improved + # erfnu = erf(nu) #TODO: This can be improved - upm = np.exp(nu2[index, :] + lnDifErf( nu[index, :], t_lq + nu[index, :]) ) - upm[t[:, 0] == 0, :] = 0. + upm = np.exp(nu2[index, :] + lnDifErf(nu[index, :], t_lq + nu[index, :])) + upm[t[:, 0] == 0, :] = 0.0 - upv = np.exp(nu2[index, :] + 2.*gamt + lnDifErf(-t_lq + nu[index, :], nu[index, :]) ) #egamt*upv - upv[t[:, 0] == 0, :] = 0. + upv = np.exp( + nu2[index, :] + 2.0 * gamt + lnDifErf(-t_lq + nu[index, :], nu[index, :]) + ) # egamt*upv + upv[t[:, 0] == 0, :] = 0.0 - #Gradient wrt S - c0_S = (S/B)*(lq*np.sqrt(np.pi)) + # Gradient wrt S + c0_S = (S / B) * (lq * np.sqrt(np.pi)) - gS = c0_S[index]*(upm - upv) + gS = c0_S[index] * (upm - upv) + + # For B + CB1 = (0.5 * lq) ** 2 - 0.5 / B**2 # DXQ + lq2_2B = (0.5 * lq**2) * (S2 / B) # DXQ + CB2 = 2.0 * etlq2gamt - e2gamt - 1.0 # NxQ - #For B - CB1 = (.5*lq)**2 - .5/B**2 #DXQ - lq2_2B = (.5*lq**2)*(S2/B) #DXQ - CB2 = 2.*etlq2gamt - e2gamt - 1. #NxQ - # gradient wrt B NxZ - gB = c0[index, :]*(CB1[index, :]*upm - (CB1[index, :] - t/B[index])*upv) + \ - lq2_2B[index, :]*CB2 + gB = ( + c0[index, :] * (CB1[index, :] * upm - (CB1[index, :] - t / B[index]) * upv) + + lq2_2B[index, :] * CB2 + ) - #Gradient wrt lengthscale - #DxQ terms - c0 = (.5*np.sqrt(np.pi))*(S2/B)*(1.+.5*(lq*B)**2) - Clq1 = S2*(lq*.5) - glq = c0[index]*(upm - upv) + Clq1[index]*CB2 + # Gradient wrt lengthscale + # DxQ terms + c0 = (0.5 * np.sqrt(np.pi)) * (S2 / B) * (1.0 + 0.5 * (lq * B) ** 2) + Clq1 = S2 * (lq * 0.5) + glq = c0[index] * (upm - upv) + Clq1[index] * CB2 return glq, gS, gB def _gkfu(self, X, index, Z, index2): - index = index.reshape(index.size,) - #TODO: reduce memory usage - #terms that move along t + index = index.reshape( + index.size, + ) + # TODO: reduce memory usage + # terms that move along t d = np.unique(index) B = self.decay[d].values S = self.W[d, :].values - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #t column + # t column t = X[:, 0].reshape(X.shape[0], 1) B = B.reshape(B.size, 1) - #z row + # z row z = Z[:, 0].reshape(1, Z.shape[0]) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) lq = self.lengthscale.values.reshape((1, self.rank)) - #kfu = np.empty((t.size, z.size)) + # kfu = np.empty((t.size, z.size)) glq = np.empty((t.size, z.size)) gSdq = np.empty((t.size, z.size)) gB = np.empty((t.size, z.size)) - #Dx1 terms - B_2 = B*.5 - S_pi = S*(.5*np.sqrt(np.pi)) - #DxQ terms - c0 = S_pi*lq #lq*Sdq*sqrt(pi) - nu = B*lq*.5 - nu2 = nu*nu + # Dx1 terms + B_2 = B * 0.5 + S_pi = S * (0.5 * np.sqrt(np.pi)) + # DxQ terms + c0 = S_pi * lq # lq*Sdq*sqrt(pi) + nu = B * lq * 0.5 + nu2 = nu * nu + + # 1xM terms + z_lq = z / lq[0, index2] + + # NxM terms + tz = t - z + tz_lq = tz / lq[0, index2] + etz_lq2 = -np.exp(-tz_lq * tz_lq) + ez_lq_Bt = np.exp(-z_lq * z_lq - B[index] * t) - #1xM terms - z_lq = z/lq[0, index2] - - #NxM terms - tz = t-z - tz_lq = tz/lq[0, index2] - etz_lq2 = -np.exp(-tz_lq*tz_lq) - ez_lq_Bt = np.exp(-z_lq*z_lq -B[index]*t) - # Upsilon calculations fullind = np.ix_(index, index2) - upsi = np.exp(nu2[fullind] - B[index]*tz + lnDifErf( -tz_lq + nu[fullind], z_lq+nu[fullind] ) ) - upsi[t[:, 0] == 0., :] = 0. + upsi = np.exp( + nu2[fullind] + - B[index] * tz + + lnDifErf(-tz_lq + nu[fullind], z_lq + nu[fullind]) + ) + upsi[t[:, 0] == 0.0, :] = 0.0 - #Gradient wrt S - #DxQ term - Sa1 = lq*(.5*np.sqrt(np.pi)) + # Gradient wrt S + # DxQ term + Sa1 = lq * (0.5 * np.sqrt(np.pi)) - gSdq = Sa1[0,index2]*upsi + gSdq = Sa1[0, index2] * upsi - #Gradient wrt lq - la1 = S_pi*(1. + 2.*nu2) - Slq = S*lq - uplq = etz_lq2*(tz_lq/lq[0, index2] + B_2[index]) - uplq += ez_lq_Bt*(-z_lq/lq[0, index2] + B_2[index]) + # Gradient wrt lq + la1 = S_pi * (1.0 + 2.0 * nu2) + Slq = S * lq + uplq = etz_lq2 * (tz_lq / lq[0, index2] + B_2[index]) + uplq += ez_lq_Bt * (-z_lq / lq[0, index2] + B_2[index]) - glq = la1[fullind]*upsi - glq += Slq[fullind]*uplq + glq = la1[fullind] * upsi + glq += Slq[fullind] * uplq - #Gradient wrt B - Slq = Slq*lq - nulq = nu*lq + # Gradient wrt B + Slq = Slq * lq + nulq = nu * lq upBd = etz_lq2 + ez_lq_Bt - gB = c0[fullind]*(nulq[fullind] - tz)*upsi + .5*Slq[fullind]*upBd + gB = c0[fullind] * (nulq[fullind] - tz) * upsi + 0.5 * Slq[fullind] * upBd return glq, gSdq, gB - #TODO: reduce memory usage - def _gkfu_z(self, X, index, Z, index2): #Kfu(t,z) - index = index.reshape(index.size,) - #terms that move along t + # TODO: reduce memory usage + def _gkfu_z(self, X, index, Z, index2): # Kfu(t,z) + index = index.reshape( + index.size, + ) + # terms that move along t d = np.unique(index) B = self.decay[d].values S = self.W[d, :].values - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #t column + # t column t = X[:, 0].reshape(X.shape[0], 1) B = B.reshape(B.size, 1) - #z row + # z row z = Z[:, 0].reshape(1, Z.shape[0]) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) lq = self.lengthscale.values.reshape((1, self.rank)) - #kfu = np.empty((t.size, z.size)) + # kfu = np.empty((t.size, z.size)) gz = np.empty((t.size, z.size)) - #Dx1 terms - S_pi =S*(.5*np.sqrt(np.pi)) - #DxQ terms - #Slq = S*lq - c0 = S_pi*lq #lq*Sdq*sqrt(pi) - nu = (.5*lq)*B - nu2 = nu*nu + # Dx1 terms + S_pi = S * (0.5 * np.sqrt(np.pi)) + # DxQ terms + # Slq = S*lq + c0 = S_pi * lq # lq*Sdq*sqrt(pi) + nu = (0.5 * lq) * B + nu2 = nu * nu - #1xM terms - z_lq = z/lq[0, index2] - z_lq2 = -z_lq*z_lq - #NxQ terms - t_lq = t/lq - #NxM terms + # 1xM terms + z_lq = z / lq[0, index2] + z_lq2 = -z_lq * z_lq + # NxQ terms + t_lq = t / lq + # NxM terms zt_lq = z_lq - t_lq[:, index2] - zt_lq2 = -zt_lq*zt_lq + zt_lq2 = -zt_lq * zt_lq # Upsilon calculations fullind = np.ix_(index, index2) z2 = z_lq + nu[fullind] z1 = z2 - t_lq[:, index2] - upsi = np.exp(nu2[fullind] - B[index]*(t-z) + lnDifErf(z1,z2) ) - upsi[t[:, 0] == 0., :] = 0. + upsi = np.exp(nu2[fullind] - B[index] * (t - z) + lnDifErf(z1, z2)) + upsi[t[:, 0] == 0.0, :] = 0.0 - #Gradient wrt z - za1 = c0*B - #za2 = S_w - gz = za1[fullind]*upsi + S[fullind]*( np.exp(z_lq2 - B[index]*t) -np.exp(zt_lq2) ) + # Gradient wrt z + za1 = c0 * B + # za2 = S_w + gz = za1[fullind] * upsi + S[fullind] * ( + np.exp(z_lq2 - B[index] * t) - np.exp(zt_lq2) + ) return gz - -def lnDifErf(z1,z2): - #Z2 is always positive - logdiferf = np.zeros(z1.shape) - ind = np.where(z1>0.) - ind2 = np.where(z1<=0.) + + +def lnDifErf(z1, z2): + # Z2 is always positive + logdiferf = np.zeros(z1.shape) + ind = np.where(z1 > 0.0) + ind2 = np.where(z1 <= 0.0) if ind[0].shape > 0: z1i = z1[ind] - z12 = z1i*z1i + z12 = z1i * z1i z2i = z2[ind] - logdiferf[ind] = -z12 + np.log(erfcx(z1i) - erfcx(z2i)*np.exp(z12-z2i**2)) - + logdiferf[ind] = -z12 + np.log(erfcx(z1i) - erfcx(z2i) * np.exp(z12 - z2i**2)) + if ind2[0].shape > 0: z1i = z1[ind2] z2i = z2[ind2] logdiferf[ind2] = np.log(erf(z2i) - erf(z1i)) - - return logdiferf \ No newline at end of file + + return logdiferf diff --git a/GPy/kern/src/eq_ode2.py b/GPy/kern/src/eq_ode2.py index 0166c511..27b15b87 100644 --- a/GPy/kern/src/eq_ode2.py +++ b/GPy/kern/src/eq_ode2.py @@ -8,6 +8,7 @@ from ...core.parameterization import Param from paramz.transformations import Logexp from paramz.caching import Cache_this + class EQ_ODE2(Kern): """ Covariance function for second order differential equation driven by an exponentiated quadratic covariance. @@ -30,24 +31,38 @@ class EQ_ODE2(Kern): :type B: array of length output_dim. """ - #This code will only work for the sparseGP model, due to limitations in models for this kernel - def __init__(self, input_dim=2, output_dim=1, rank=1, W=None, lengthscale=None, C=None, B=None, active_dims=None, name='eq_ode2'): - #input_dim should be 1, but kern._slice_X is not returning index information required to evaluate kernels + + # This code will only work for the sparseGP model, due to limitations in models for this kernel + def __init__( + self, + input_dim=2, + output_dim=1, + rank=1, + W=None, + lengthscale=None, + C=None, + B=None, + active_dims=None, + name="eq_ode2", + ): + # input_dim should be 1, but kern._slice_X is not returning index information required to evaluate kernels assert input_dim == 2, "only defined for 1 input dims" - super(EQ_ODE2, self).__init__(input_dim=input_dim, active_dims=active_dims, name=name) + super(EQ_ODE2, self).__init__( + input_dim=input_dim, active_dims=active_dims, name=name + ) self.rank = rank self.output_dim = output_dim if lengthscale is None: - lengthscale = .5+np.random.rand(self.rank) + lengthscale = 0.5 + np.random.rand(self.rank) else: lengthscale = np.asarray(lengthscale) assert lengthscale.size in [1, self.rank], "Bad number of lengthscales" if lengthscale.size != self.rank: - lengthscale = np.ones(self.rank)*lengthscale + lengthscale = np.ones(self.rank) * lengthscale if W is None: - #W = 0.5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank) + # W = 0.5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank) W = np.ones((self.output_dim, self.rank)) else: assert W.shape == (self.output_dim, self.rank) @@ -58,270 +73,294 @@ class EQ_ODE2(Kern): if B is None: B = np.ones(self.output_dim) - self.C = Param('C', C, Logexp()) - self.B = Param('B', B, Logexp()) - self.lengthscale = Param('lengthscale', lengthscale, Logexp()) - self.W = Param('W', W) + self.C = Param("C", C, Logexp()) + self.B = Param("B", B, Logexp()) + self.lengthscale = Param("lengthscale", lengthscale, Logexp()) + self.W = Param("W", W) self.link_parameters(self.lengthscale, self.C, self.B, self.W) @Cache_this(limit=3) def K(self, X, X2=None): - #This way is not working, indexes are lost after using k._slice_X - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # This way is not working, indexes are lost after using k._slice_X + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values index = np.int_(np.round(X[:, 1])) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim if X2 is None: if X_flag: - #Calculate covariance function for the latent functions + # Calculate covariance function for the latent functions index -= self.output_dim return self._Kuu(X, index) - else: #Kff full + else: # Kff full raise NotImplementedError else: - #This way is not working, indexes are lost after using k._slice_X - #index2 = np.asarray(X2, dtype=np.int) - #index2 = index2.reshape(index2.size,) - if hasattr(X2, 'values'): + # This way is not working, indexes are lost after using k._slice_X + # index2 = np.asarray(X2, dtype=int) + # index2 = index2.reshape(index2.size,) + if hasattr(X2, "values"): X2 = X2.values index2 = np.int_(np.round(X2[:, 1])) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) X2_flag = index2[0] >= self.output_dim - #Calculate cross-covariance function + # Calculate cross-covariance function if not X_flag and X2_flag: index2 -= self.output_dim - return self._Kfu(X, index, X2, index2) #Kfu + return self._Kfu(X, index, X2, index2) # Kfu elif X_flag and not X2_flag: index -= self.output_dim - return self._Kfu(X2, index2, X, index).T #Kuf + return self._Kfu(X2, index2, X, index).T # Kuf elif X_flag and X2_flag: index -= self.output_dim index2 -= self.output_dim - return self._Kusu(X, index, X2, index2) #Ku_s u + return self._Kusu(X, index, X2, index2) # Ku_s u else: - raise NotImplementedError #Kf_s f + raise NotImplementedError # Kf_s f - #Calculate the covariance function for diag(Kff(X,X)) + # Calculate the covariance function for diag(Kff(X,X)) def Kdiag(self, X): - if hasattr(X, 'values'): + if hasattr(X, "values"): index = np.int_(np.round(X[:, 1].values)) else: index = np.int_(np.round(X[:, 1])) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim - - if X_flag: #Kuudiag - return np.ones(X[:,0].shape) - else: #Kffdiag + + if X_flag: # Kuudiag + return np.ones(X[:, 0].shape) + else: # Kffdiag kdiag = self._Kdiag(X) return np.sum(kdiag, axis=1) - #Calculate the covariance function for diag(Kff(X,X)) + # Calculate the covariance function for diag(Kff(X,X)) def _Kdiag(self, X): - #This way is not working, indexes are lost after using k._slice_X - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # This way is not working, indexes are lost after using k._slice_X + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values index = np.int_(X[:, 1]) - index = index.reshape(index.size,) - - #terms that move along t + index = index.reshape( + index.size, + ) + + # terms that move along t t = X[:, 0].reshape(X.shape[0], 1) - d = np.unique(index) #Output Indexes + d = np.unique(index) # Output Indexes B = self.B.values[d] C = self.C.values[d] S = self.W.values[d, :] - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Check where wd becomes complex - wbool = C*C >= 4.*B + # Check where wd becomes complex + wbool = C * C >= 4.0 * B B = B.reshape(B.size, 1) C = C.reshape(C.size, 1) - alpha = .5*C - C2 = C*C + alpha = 0.5 * C + C2 = C * C wbool2 = wbool[index] ind2t = np.where(wbool2) ind3t = np.where(np.logical_not(wbool2)) - #Terms that move along q + # Terms that move along q lq = self.lengthscale.values.reshape(1, self.lengthscale.size) - S2 = S*S + S2 = S * S kdiag = np.empty((t.size, lq.size)) indD = np.arange(B.size) - #(1) When wd is real + # (1) When wd is real if np.any(np.logical_not(wbool)): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind3t] ind = index[ind3t] - d = np.asarray(np.where(np.logical_not(wbool))[0]) #Selection of outputs + d = np.asarray(np.where(np.logical_not(wbool))[0]) # Selection of outputs indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - S2lq = S2[d]*(.5*lq) - c0 = S2lq*np.sqrt(np.pi) - w = .5*np.sqrt(4.*B[d] - C2[d]) + # Dx1 terms + S2lq = S2[d] * (0.5 * lq) + c0 = S2lq * np.sqrt(np.pi) + w = 0.5 * np.sqrt(4.0 * B[d] - C2[d]) alphad = alpha[d] - w2 = w*w - gam = alphad + 1j*w - gamc = alphad - 1j*w - c1 = .5/(alphad*w2) - c2 = .5/(gam*w2) + w2 = w * w + gam = alphad + 1j * w + gamc = alphad - 1j * w + c1 = 0.5 / (alphad * w2) + c2 = 0.5 / (gam * w2) c = c1 - c2 - #DxQ terms - nu = lq*(gam*.5) - K01 = c0*c - #Nx1 terms - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 + # DxQ terms + nu = lq * (gam * 0.5) + K01 = c0 * c + # Nx1 terms + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 egamt = np.exp(gamt) - ec = egamt*c2[ind] - np.exp(gamct)*c1[ind] - #NxQ terms - t_lq = t1/lq + ec = egamt * c2[ind] - np.exp(gamct) * c1[ind] + # NxQ terms + t_lq = t1 / lq # Upsilon Calculations # Using wofz - wnu = wofz(1j*nu) + wnu = wofz(1j * nu) lwnu = np.log(wnu) - t2_lq2 = -t_lq*t_lq - upm = wnu[ind] - np.exp(t2_lq2 + gamt + np.log(wofz(1j*(t_lq + nu[ind])))) - upm[t1[:, 0] == 0, :] = 0. + t2_lq2 = -t_lq * t_lq + upm = wnu[ind] - np.exp(t2_lq2 + gamt + np.log(wofz(1j * (t_lq + nu[ind])))) + upm[t1[:, 0] == 0, :] = 0.0 - nu2 = nu*nu + nu2 = nu * nu z1 = nu[ind] - t_lq - indv1 = np.where(z1.real >= 0.) - indv2 = np.where(z1.real < 0.) + indv1 = np.where(z1.real >= 0.0) + indv2 = np.where(z1.real < 0.0) upv = -np.exp(lwnu[ind] + gamt) if indv1[0].shape > 0: - upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j*z1[indv1]))) + upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j * z1[indv1]))) if indv2[0].shape > 0: - upv[indv2] += np.exp(nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.))\ - - np.exp(t2_lq2[indv2] + np.log(wofz(-1j*z1[indv2]))) - upv[t1[:, 0] == 0, :] = 0. + upv[indv2] += np.exp( + nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.0) + ) - np.exp(t2_lq2[indv2] + np.log(wofz(-1j * z1[indv2]))) + upv[t1[:, 0] == 0, :] = 0.0 - #Covariance calculation - kdiag[ind3t] = np.real(K01[ind]*upm) - kdiag[ind3t] += np.real((c0[ind]*ec)*upv) + # Covariance calculation + kdiag[ind3t] = np.real(K01[ind] * upm) + kdiag[ind3t] += np.real((c0[ind] * ec) * upv) - #(2) When w_d is complex + # (2) When w_d is complex if np.any(wbool): t1 = t[ind2t] ind = index[ind2t] - #Index transformation + # Index transformation d = np.asarray(np.where(wbool)[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - S2lq = S2[d]*(lq*.25) - c0 = S2lq*np.sqrt(np.pi) - w = .5*np.sqrt(C2[d] - 4.*B[d]) + # Dx1 terms + S2lq = S2[d] * (lq * 0.25) + c0 = S2lq * np.sqrt(np.pi) + w = 0.5 * np.sqrt(C2[d] - 4.0 * B[d]) alphad = alpha[d] gam = alphad - w gamc = alphad + w - w2 = -w*w - c1 = .5/(alphad*w2) - c21 = .5/(gam*w2) - c22 = .5/(gamc*w2) + w2 = -w * w + c1 = 0.5 / (alphad * w2) + c21 = 0.5 / (gam * w2) + c22 = 0.5 / (gamc * w2) c = c1 - c21 c2 = c1 - c22 - #DxQ terms - K011 = c0*c - K012 = c0*c2 - nu = lq*(.5*gam) - nuc = lq*(.5*gamc) - #Nx1 terms - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 + # DxQ terms + K011 = c0 * c + K012 = c0 * c2 + nu = lq * (0.5 * gam) + nuc = lq * (0.5 * gamc) + # Nx1 terms + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 egamt = np.exp(gamt) egamct = np.exp(gamct) - ec = egamt*c21[ind] - egamct*c1[ind] - ec2 = egamct*c22[ind] - egamt*c1[ind] - #NxQ terms - t_lq = t1/lq + ec = egamt * c21[ind] - egamct * c1[ind] + ec2 = egamct * c22[ind] - egamt * c1[ind] + # NxQ terms + t_lq = t1 / lq - #Upsilon Calculations using wofz - t2_lq2 = -t_lq*t_lq #Required when using wofz - wnu = wofz(1j*nu).real + # Upsilon Calculations using wofz + t2_lq2 = -t_lq * t_lq # Required when using wofz + wnu = wofz(1j * nu).real lwnu = np.log(wnu) - upm = wnu[ind] - np.exp(t2_lq2 + gamt + np.log(wofz(1j*(t_lq + nu[ind])).real)) - upm[t1[:, 0] == 0., :] = 0. + upm = wnu[ind] - np.exp( + t2_lq2 + gamt + np.log(wofz(1j * (t_lq + nu[ind])).real) + ) + upm[t1[:, 0] == 0.0, :] = 0.0 - nu2 = nu*nu + nu2 = nu * nu z1 = nu[ind] - t_lq - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) upv = -np.exp(lwnu[ind] + gamt) if indv1[0].shape > 0: - upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real)) if indv2[0].shape > 0: - upv[indv2] += np.exp(nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.))\ - - np.exp(t2_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upv[t1[:, 0] == 0, :] = 0. + upv[indv2] += np.exp( + nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.0) + ) - np.exp(t2_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upv[t1[:, 0] == 0, :] = 0.0 - wnuc = wofz(1j*nuc).real + wnuc = wofz(1j * nuc).real lwnuc = np.log(wnuc) - upmc = wnuc[ind] - np.exp(t2_lq2 + gamct + np.log(wofz(1j*(t_lq + nuc[ind])).real)) - upmc[t1[:, 0] == 0., :] = 0. + upmc = wnuc[ind] - np.exp( + t2_lq2 + gamct + np.log(wofz(1j * (t_lq + nuc[ind])).real) + ) + upmc[t1[:, 0] == 0.0, :] = 0.0 - nuc2 = nuc*nuc + nuc2 = nuc * nuc z1 = nuc[ind] - t_lq - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) - upvc = - np.exp(lwnuc[ind] + gamct) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) + upvc = -np.exp(lwnuc[ind] + gamct) if indv1[0].shape > 0: - upvc[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upvc[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real)) if indv2[0].shape > 0: - upvc[indv2] += np.exp(nuc2[ind[indv2[0]], indv2[1]] + gamct[indv2[0], 0] + np.log(2.))\ - - np.exp(t2_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upvc[t1[:, 0] == 0, :] = 0. + upvc[indv2] += np.exp( + nuc2[ind[indv2[0]], indv2[1]] + gamct[indv2[0], 0] + np.log(2.0) + ) - np.exp(t2_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upvc[t1[:, 0] == 0, :] = 0.0 - #Covariance calculation - kdiag[ind2t] = K011[ind]*upm + K012[ind]*upmc + (c0[ind]*ec)*upv + (c0[ind]*ec2)*upvc + # Covariance calculation + kdiag[ind2t] = ( + K011[ind] * upm + + K012[ind] * upmc + + (c0[ind] * ec) * upv + + (c0[ind] * ec2) * upvc + ) return kdiag - def update_gradients_full(self, dL_dK, X, X2 = None): - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + def update_gradients_full(self, dL_dK, X, X2=None): + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values self.B.gradient = np.zeros(self.B.shape) self.C.gradient = np.zeros(self.C.shape) self.W.gradient = np.zeros(self.W.shape) self.lengthscale.gradient = np.zeros(self.lengthscale.shape) index = np.int_(X[:, 1]) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim if X2 is None: - if X_flag: #Kuu or Kmm + if X_flag: # Kuu or Kmm index -= self.output_dim - tmp = dL_dK*self._gkuu_lq(X, index) + tmp = dL_dK * self._gkuu_lq(X, index) for q in np.unique(index): ind = np.where(index == q) self.lengthscale.gradient[q] = tmp[np.ix_(ind[0], ind[0])].sum() else: raise NotImplementedError - else: #Kfu or Knm - #index2 = np.asarray(X2, dtype=np.int) - #index2 = index2.reshape(index2.size,) - if hasattr(X2, 'values'): + else: # Kfu or Knm + # index2 = np.asarray(X2, dtype=int) + # index2 = index2.reshape(index2.size,) + if hasattr(X2, "values"): X2 = X2.values index2 = np.int_(X2[:, 1]) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) X2_flag = index2[0] >= self.output_dim if not X_flag and X2_flag: index2 -= self.output_dim else: - dL_dK = dL_dK.T #so we obtaing dL_Kfu + dL_dK = dL_dK.T # so we obtaing dL_Kfu indtemp = index - self.output_dim Xtemp = X X = X2 @@ -329,13 +368,13 @@ class EQ_ODE2(Kern): index = index2 index2 = indtemp glq, gSdq, gB, gC = self._gkfu(X, index, X2, index2) - tmp = dL_dK*glq + tmp = dL_dK * glq for q in np.unique(index2): ind = np.where(index2 == q) self.lengthscale.gradient[q] = tmp[:, ind].sum() - tmpB = dL_dK*gB - tmpC = dL_dK*gC - tmp = dL_dK*gSdq + tmpB = dL_dK * gB + tmpC = dL_dK * gC + tmp = dL_dK * gSdq for d in np.unique(index): ind = np.where(index == d) self.B.gradient[d] = tmpB[ind, :].sum() @@ -345,25 +384,27 @@ class EQ_ODE2(Kern): self.W.gradient[d, q] = tmp[np.ix_(ind[0], ind2[0])].sum() def update_gradients_diag(self, dL_dKdiag, X): - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values self.B.gradient = np.zeros(self.B.shape) self.C.gradient = np.zeros(self.C.shape) self.W.gradient = np.zeros(self.W.shape) self.lengthscale.gradient = np.zeros(self.lengthscale.shape) index = np.int_(X[:, 1]) - index = index.reshape(index.size,) - + index = index.reshape( + index.size, + ) + glq, gS, gB, gC = self._gkdiag(X, index) if dL_dKdiag.size == X.shape[0]: dL_dKdiag = np.reshape(dL_dKdiag, (index.size, 1)) - tmp = dL_dKdiag*glq + tmp = dL_dKdiag * glq self.lengthscale.gradient = tmp.sum(0) - tmpB = dL_dKdiag*gB - tmpC = dL_dKdiag*gC - tmp = dL_dKdiag*gS + tmpB = dL_dKdiag * gB + tmpC = dL_dKdiag * gC + tmp = dL_dKdiag * gS for d in np.unique(index): ind = np.where(index == d) self.B.gradient[d] = tmpB[ind, :].sum() @@ -371,107 +412,123 @@ class EQ_ODE2(Kern): self.W.gradient[d, :] = tmp[ind].sum(0) def gradients_X(self, dL_dK, X, X2=None): - #index = np.asarray(X, dtype=np.int) - #index = index.reshape(index.size,) - if hasattr(X, 'values'): + # index = np.asarray(X, dtype=int) + # index = index.reshape(index.size,) + if hasattr(X, "values"): X = X.values index = np.int_(X[:, 1]) - index = index.reshape(index.size,) + index = index.reshape( + index.size, + ) X_flag = index[0] >= self.output_dim - #If input_dim == 1, use this - #gX = np.zeros((X.shape[0], 1)) - #Cheat to allow gradient for input_dim==2 + # If input_dim == 1, use this + # gX = np.zeros((X.shape[0], 1)) + # Cheat to allow gradient for input_dim==2 gX = np.zeros(X.shape) - if X2 is None: #Kuu or Kmm + if X2 is None: # Kuu or Kmm if X_flag: index -= self.output_dim - gX[:, 0] = 2.*(dL_dK*self._gkuu_X(X, index)).sum(0) + gX[:, 0] = 2.0 * (dL_dK * self._gkuu_X(X, index)).sum(0) return gX else: raise NotImplementedError - else: #Kuf or Kmn - #index2 = np.asarray(X2, dtype=np.int) - #index2 = index2.reshape(index2.size,) - if hasattr(X2, 'values'): + else: # Kuf or Kmn + # index2 = np.asarray(X2, dtype=int) + # index2 = index2.reshape(index2.size,) + if hasattr(X2, "values"): X2 = X2.values index2 = np.int_(X2[:, 1]) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) X2_flag = index2[0] >= self.output_dim - if X_flag and not X2_flag: #gradient of Kuf(Z, X) wrt Z + if X_flag and not X2_flag: # gradient of Kuf(Z, X) wrt Z index -= self.output_dim - gX[:, 0] = (dL_dK*self._gkfu_z(X2, index2, X, index).T).sum(1) + gX[:, 0] = (dL_dK * self._gkfu_z(X2, index2, X, index).T).sum(1) return gX else: raise NotImplementedError - #---------------------------------------# + # ---------------------------------------# # Helper functions # - #---------------------------------------# + # ---------------------------------------# - #Evaluation of squared exponential for LFM + # Evaluation of squared exponential for LFM def _Kuu(self, X, index): - index = index.reshape(index.size,) - t = X[:, 0].reshape(X.shape[0],) - lq = self.lengthscale.values.reshape(self.rank,) - lq2 = lq*lq - #Covariance matrix initialization + index = index.reshape( + index.size, + ) + t = X[:, 0].reshape( + X.shape[0], + ) + lq = self.lengthscale.values.reshape( + self.rank, + ) + lq2 = lq * lq + # Covariance matrix initialization kuu = np.zeros((t.size, t.size)) - #Assign 1. to diagonal terms - kuu[np.diag_indices(t.size)] = 1. - #Upper triangular indices + # Assign 1. to diagonal terms + kuu[np.diag_indices(t.size)] = 1.0 + # Upper triangular indices indtri1, indtri2 = np.triu_indices(t.size, 1) - #Block Diagonal indices among Upper Triangular indices + # Block Diagonal indices among Upper Triangular indices ind = np.where(index[indtri1] == index[indtri2]) indr = indtri1[ind] indc = indtri2[ind] r = t[indr] - t[indc] - r2 = r*r - #Calculation of covariance function - kuu[indr, indc] = np.exp(-r2/lq2[index[indr]]) - #Completation of lower triangular part + r2 = r * r + # Calculation of covariance function + kuu[indr, indc] = np.exp(-r2 / lq2[index[indr]]) + # Completation of lower triangular part kuu[indc, indr] = kuu[indr, indc] return kuu def _Kusu(self, X, index, X2, index2): - index = index.reshape(index.size,) - index2 = index2.reshape(index2.size,) - t = X[:, 0].reshape(X.shape[0],1) - t2 = X2[:, 0].reshape(1,X2.shape[0]) - lq = self.lengthscale.values.reshape(self.rank,) - #Covariance matrix initialization + index = index.reshape( + index.size, + ) + index2 = index2.reshape( + index2.size, + ) + t = X[:, 0].reshape(X.shape[0], 1) + t2 = X2[:, 0].reshape(1, X2.shape[0]) + lq = self.lengthscale.values.reshape( + self.rank, + ) + # Covariance matrix initialization kuu = np.zeros((t.size, t2.size)) for q in range(self.rank): ind1 = index == q ind2 = index2 == q - r = t[ind1]/lq[q] - t2[0,ind2]/lq[q] - r2 = r*r - #Calculation of covariance function + r = t[ind1] / lq[q] - t2[0, ind2] / lq[q] + r2 = r * r + # Calculation of covariance function kuu[np.ix_(ind1, ind2)] = np.exp(-r2) return kuu - #Evaluation of cross-covariance function + # Evaluation of cross-covariance function def _Kfu(self, X, index, X2, index2): - #terms that move along t + # terms that move along t t = X[:, 0].reshape(X.shape[0], 1) - d = np.unique(index) #Output Indexes + d = np.unique(index) # Output Indexes B = self.B.values[d] C = self.C.values[d] S = self.W.values[d, :] - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Check where wd becomes complex - wbool = C*C >= 4.*B - #Output related variables must be column-wise + # Check where wd becomes complex + wbool = C * C >= 4.0 * B + # Output related variables must be column-wise C = C.reshape(C.size, 1) B = B.reshape(B.size, 1) - C2 = C*C - #Input related variables must be row-wise + C2 = C * C + # Input related variables must be row-wise z = X2[:, 0].reshape(1, X2.shape[0]) lq = self.lengthscale.values.reshape((1, self.rank)) - #print np.max(z), np.max(z/lq[0, index2]) - alpha = .5*C + # print np.max(z), np.max(z/lq[0, index2]) + alpha = 0.5 * C wbool2 = wbool[index] ind2t = np.where(wbool2) @@ -480,196 +537,214 @@ class EQ_ODE2(Kern): kfu = np.empty((t.size, z.size)) indD = np.arange(B.size) - #(1) when wd is real + # (1) when wd is real if np.any(np.logical_not(wbool)): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind3t] ind = index[ind3t] - #Index transformation + # Index transformation d = np.asarray(np.where(np.logical_not(wbool))[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - w = .5*np.sqrt(4.*B[d] - C2[d]) + # Dx1 terms + w = 0.5 * np.sqrt(4.0 * B[d] - C2[d]) alphad = alpha[d] - gam = alphad - 1j*w + gam = alphad - 1j * w - #DxQ terms - Slq = (S[d]/w)*(.5*lq) - c0 = Slq*np.sqrt(np.pi) - nu = gam*(.5*lq) - #1xM terms - z_lq = z/lq[0, index2] - #NxQ terms - t_lq = t1/lq - #NxM terms + # DxQ terms + Slq = (S[d] / w) * (0.5 * lq) + c0 = Slq * np.sqrt(np.pi) + nu = gam * (0.5 * lq) + # 1xM terms + z_lq = z / lq[0, index2] + # NxQ terms + t_lq = t1 / lq + # NxM terms zt_lq = z_lq - t_lq[:, index2] # Upsilon Calculations - #Using wofz - tz = t1-z + # Using wofz + tz = t1 - z fullind = np.ix_(ind, index2) - zt_lq2 = -zt_lq*zt_lq - z_lq2 = -z_lq*z_lq - gamt = -gam[ind]*t1 + zt_lq2 = -zt_lq * zt_lq + z_lq2 = -z_lq * z_lq + gamt = -gam[ind] * t1 - upsi = - np.exp(z_lq2 + gamt + np.log(wofz(1j*(z_lq + nu[fullind])))) + upsi = -np.exp(z_lq2 + gamt + np.log(wofz(1j * (z_lq + nu[fullind])))) z1 = zt_lq + nu[fullind] - indv1 = np.where(z1.real >= 0.) - indv2 = np.where(z1.real < 0.) + indv1 = np.where(z1.real >= 0.0) + indv2 = np.where(z1.real < 0.0) if indv1[0].shape > 0: - upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]))) + upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]))) if indv2[0].shape > 0: - nua2 = nu[ind[indv2[0]], index2[indv2[1]]]**2 - upsi[indv2] += np.exp(nua2 - gam[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]))) - upsi[t1[:, 0] == 0., :] = 0. + nua2 = nu[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi[indv2] += np.exp( + nua2 - gam[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]))) + upsi[t1[:, 0] == 0.0, :] = 0.0 - #Covariance calculation - kfu[ind3t] = c0[fullind]*upsi.imag + # Covariance calculation + kfu[ind3t] = c0[fullind] * upsi.imag - #(2) when wd is complex + # (2) when wd is complex if np.any(wbool): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind2t] ind = index[ind2t] - #Index transformation + # Index transformation d = np.asarray(np.where(wbool)[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - w = .5*np.sqrt(C2[d] - 4.*B[d]) + # Dx1 terms + w = 0.5 * np.sqrt(C2[d] - 4.0 * B[d]) alphad = alpha[d] gam = alphad - w gamc = alphad + w - #DxQ terms - Slq = S[d]*(lq*.25) - c0 = -Slq*(np.sqrt(np.pi)/w) - nu = gam*(lq*.5) - nuc = gamc*(lq*.5) - #1xM terms - z_lq = z/lq[0, index2] - #NxQ terms - t_lq = t1/lq[0, index2] - #NxM terms + # DxQ terms + Slq = S[d] * (lq * 0.25) + c0 = -Slq * (np.sqrt(np.pi) / w) + nu = gam * (lq * 0.5) + nuc = gamc * (lq * 0.5) + # 1xM terms + z_lq = z / lq[0, index2] + # NxQ terms + t_lq = t1 / lq[0, index2] + # NxM terms zt_lq = z_lq - t_lq # Upsilon Calculations - tz = t1-z - z_lq2 = -z_lq*z_lq - zt_lq2 = -zt_lq*zt_lq - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 + tz = t1 - z + z_lq2 = -z_lq * z_lq + zt_lq2 = -zt_lq * zt_lq + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 fullind = np.ix_(ind, index2) - upsi = np.exp(z_lq2 + gamt + np.log(wofz(1j*(z_lq + nu[fullind])).real))\ - - np.exp(z_lq2 + gamct + np.log(wofz(1j*(z_lq + nuc[fullind])).real)) + upsi = np.exp( + z_lq2 + gamt + np.log(wofz(1j * (z_lq + nu[fullind])).real) + ) - np.exp(z_lq2 + gamct + np.log(wofz(1j * (z_lq + nuc[fullind])).real)) z1 = zt_lq + nu[fullind] - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) if indv1[0].shape > 0: - upsi[indv1] -= np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upsi[indv1] -= np.exp(zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real)) if indv2[0].shape > 0: - nua2 = nu[ind[indv2[0]], index2[indv2[1]]]**2 - upsi[indv2] -= np.exp(nua2 - gam[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) + nua2 = nu[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi[indv2] -= np.exp( + nua2 - gam[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) z1 = zt_lq + nuc[fullind] - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) if indv1[0].shape > 0: - upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real)) if indv2[0].shape > 0: - nuac2 = nuc[ind[indv2[0]], index2[indv2[1]]]**2 - upsi[indv2] += np.exp(nuac2 - gamc[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upsi[t1[:, 0] == 0., :] = 0. + nuac2 = nuc[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi[indv2] += np.exp( + nuac2 - gamc[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upsi[t1[:, 0] == 0.0, :] = 0.0 - kfu[ind2t] = c0[np.ix_(ind, index2)]*upsi + kfu[ind2t] = c0[np.ix_(ind, index2)] * upsi return kfu - #Gradient of Kuu wrt lengthscale + # Gradient of Kuu wrt lengthscale def _gkuu_lq(self, X, index): - t = X[:, 0].reshape(X.shape[0],) - index = index.reshape(X.shape[0],) - lq = self.lengthscale.values.reshape(self.rank,) - lq2 = lq*lq - #Covariance matrix initialization + t = X[:, 0].reshape( + X.shape[0], + ) + index = index.reshape( + X.shape[0], + ) + lq = self.lengthscale.values.reshape( + self.rank, + ) + lq2 = lq * lq + # Covariance matrix initialization glq = np.zeros((t.size, t.size)) - #Upper triangular indices + # Upper triangular indices indtri1, indtri2 = np.triu_indices(t.size, 1) - #Block Diagonal indices among Upper Triangular indices + # Block Diagonal indices among Upper Triangular indices ind = np.where(index[indtri1] == index[indtri2]) indr = indtri1[ind] indc = indtri2[ind] r = t[indr] - t[indc] - r2 = r*r - r2_lq2 = r2/lq2[index[indr]] - #Calculation of covariance function + r2 = r * r + r2_lq2 = r2 / lq2[index[indr]] + # Calculation of covariance function er2_lq2 = np.exp(-r2_lq2) - #Gradient wrt lq - c = 2.*r2_lq2/lq[index[indr]] - glq[indr, indc] = er2_lq2*c - #Complete the lower triangular + # Gradient wrt lq + c = 2.0 * r2_lq2 / lq[index[indr]] + glq[indr, indc] = er2_lq2 * c + # Complete the lower triangular glq[indc, indr] = glq[indr, indc] return glq - #Be careful this derivative should be transpose it - def _gkuu_X(self, X, index): #Diagonal terms are always zero - t = X[:, 0].reshape(X.shape[0],) - index = index.reshape(index.size,) - lq = self.lengthscale.values.reshape(self.rank,) - lq2 = lq*lq - #Covariance matrix initialization + # Be careful this derivative should be transpose it + def _gkuu_X(self, X, index): # Diagonal terms are always zero + t = X[:, 0].reshape( + X.shape[0], + ) + index = index.reshape( + index.size, + ) + lq = self.lengthscale.values.reshape( + self.rank, + ) + lq2 = lq * lq + # Covariance matrix initialization gt = np.zeros((t.size, t.size)) - #Upper triangular indices - indtri1, indtri2 = np.triu_indices(t.size, 1) #Offset of 1 from the diagonal - #Block Diagonal indices among Upper Triangular indices + # Upper triangular indices + indtri1, indtri2 = np.triu_indices(t.size, 1) # Offset of 1 from the diagonal + # Block Diagonal indices among Upper Triangular indices ind = np.where(index[indtri1] == index[indtri2]) indr = indtri1[ind] indc = indtri2[ind] r = t[indr] - t[indc] - r2 = r*r - r2_lq2 = r2/(-lq2[index[indr]]) - #Calculation of covariance function + r2 = r * r + r2_lq2 = r2 / (-lq2[index[indr]]) + # Calculation of covariance function er2_lq2 = np.exp(r2_lq2) - #Gradient wrt t - c = 2.*r/lq2[index[indr]] - gt[indr, indc] = er2_lq2*c - #Complete the lower triangular + # Gradient wrt t + c = 2.0 * r / lq2[index[indr]] + gt[indr, indc] = er2_lq2 * c + # Complete the lower triangular gt[indc, indr] = -gt[indr, indc] return gt - #Gradients for Diagonal Kff + # Gradients for Diagonal Kff def _gkdiag(self, X, index): - index = index.reshape(index.size,) - #terms that move along t + index = index.reshape( + index.size, + ) + # terms that move along t d = np.unique(index) B = self.B[d].values C = self.C[d].values S = self.W[d, :].values - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Check where wd becomes complex - wbool = C*C >= 4.*B - #Output related variables must be column-wise + # Check where wd becomes complex + wbool = C * C >= 4.0 * B + # Output related variables must be column-wise t = X[:, 0].reshape(X.shape[0], 1) B = B.reshape(B.size, 1) C = C.reshape(C.size, 1) - alpha = .5*C - C2 = C*C - S2 = S*S + alpha = 0.5 * C + C2 = C * C + S2 = S * S wbool2 = wbool[index] ind2t = np.where(wbool2) ind3t = np.where(np.logical_not(wbool2)) - #Input related variables must be row-wise + # Input related variables must be row-wise lq = self.lengthscale.values.reshape(1, self.rank) - lq2 = lq*lq + lq2 = lq * lq gB = np.empty((t.size, lq.size)) gC = np.empty((t.size, lq.size)) @@ -677,694 +752,851 @@ class EQ_ODE2(Kern): gS = np.empty((t.size, lq.size)) indD = np.arange(B.size) - #(1) When wd is real + # (1) When wd is real if np.any(np.logical_not(wbool)): - #Indexes of index and t related to (1) + # Indexes of index and t related to (1) t1 = t[ind3t] ind = index[ind3t] - #Index transformation + # Index transformation d = np.asarray(np.where(np.logical_not(wbool))[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - S2lq = S2[d]*(.5*lq) - c0 = S2lq*np.sqrt(np.pi) + # Dx1 terms + S2lq = S2[d] * (0.5 * lq) + c0 = S2lq * np.sqrt(np.pi) - w = .5*np.sqrt(4.*B[d] - C2[d]) + w = 0.5 * np.sqrt(4.0 * B[d] - C2[d]) alphad = alpha[d] - alpha2 = alphad*alphad - w2 = w*w - gam = alphad + 1j*w - gam2 = gam*gam - gamc = alphad - 1j*w - c1 = 0.5/alphad - c2 = 0.5/gam + alpha2 = alphad * alphad + w2 = w * w + gam = alphad + 1j * w + gam2 = gam * gam + gamc = alphad - 1j * w + c1 = 0.5 / alphad + c2 = 0.5 / gam c = c1 - c2 - #DxQ terms - c0 = c0/w2 - nu = (.5*lq)*gam - #Nx1 terms - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 + # DxQ terms + c0 = c0 / w2 + nu = (0.5 * lq) * gam + # Nx1 terms + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 egamt = np.exp(gamt) egamct = np.exp(gamct) - ec = egamt*c2[ind] - egamct*c1[ind] + ec = egamt * c2[ind] - egamct * c1[ind] - #NxQ terms - t_lq = t1/lq - t2_lq2 = -t_lq*t_lq - t_lq2 = t_lq/lq + # NxQ terms + t_lq = t1 / lq + t2_lq2 = -t_lq * t_lq + t_lq2 = t_lq / lq et2_lq2 = np.exp(t2_lq2) etlq2gamt = np.exp(t2_lq2 + gamt) ##Upsilon calculations - #Using wofz - wnu = wofz(1j*nu) + # Using wofz + wnu = wofz(1j * nu) lwnu = np.log(wnu) - t2_lq2 = -t_lq*t_lq - upm = wnu[ind] - np.exp(t2_lq2 + gamt + np.log(wofz(1j*(t_lq + nu[ind])))) - upm[t1[:, 0] == 0, :] = 0. + t2_lq2 = -t_lq * t_lq + upm = wnu[ind] - np.exp(t2_lq2 + gamt + np.log(wofz(1j * (t_lq + nu[ind])))) + upm[t1[:, 0] == 0, :] = 0.0 - nu2 = nu*nu + nu2 = nu * nu z1 = nu[ind] - t_lq - indv1 = np.where(z1.real >= 0.) - indv2 = np.where(z1.real < 0.) + indv1 = np.where(z1.real >= 0.0) + indv2 = np.where(z1.real < 0.0) upv = -np.exp(lwnu[ind] + gamt) if indv1[0].shape > 0: - upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j*z1[indv1]))) + upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j * z1[indv1]))) if indv2[0].shape > 0: - upv[indv2] += np.exp(nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.))\ - - np.exp(t2_lq2[indv2] + np.log(wofz(-1j*z1[indv2]))) - upv[t1[:, 0] == 0, :] = 0. + upv[indv2] += np.exp( + nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.0) + ) - np.exp(t2_lq2[indv2] + np.log(wofz(-1j * z1[indv2]))) + upv[t1[:, 0] == 0, :] = 0.0 - #Gradient wrt S - Slq = S[d]*lq #For grad wrt S - c0_S = Slq*np.sqrt(np.pi)/w2 - K01 = c0_S*c + # Gradient wrt S + Slq = S[d] * lq # For grad wrt S + c0_S = Slq * np.sqrt(np.pi) / w2 + K01 = c0_S * c - gS[ind3t] = np.real(K01[ind]*upm) + np.real((c0_S[ind]*ec)*upv) + gS[ind3t] = np.real(K01[ind] * upm) + np.real((c0_S[ind] * ec) * upv) - #For B and C - upmd = etlq2gamt - 1. + # For B and C + upmd = etlq2gamt - 1.0 upvd = egamt - et2_lq2 # gradient wrt B - dw_dB = 0.5/w - dgam_dB = 1j*dw_dB + dw_dB = 0.5 / w + dgam_dB = 1j * dw_dB - Ba1 = c0*(0.5*dgam_dB/gam2 + (0.5*lq2*gam*dgam_dB - 2.*dw_dB/w)*c) - Ba2_1 = c0*(dgam_dB*(0.5/gam2 - 0.25*lq2) + dw_dB/(w*gam)) - Ba2_2 = c0*dgam_dB/gam - Ba3 = c0*(-0.25*lq2*gam*dgam_dB/alphad + dw_dB/(w*alphad)) - Ba4_1 = (S2lq*lq)*dgam_dB/w2 - Ba4 = Ba4_1*c + Ba1 = c0 * ( + 0.5 * dgam_dB / gam2 + (0.5 * lq2 * gam * dgam_dB - 2.0 * dw_dB / w) * c + ) + Ba2_1 = c0 * (dgam_dB * (0.5 / gam2 - 0.25 * lq2) + dw_dB / (w * gam)) + Ba2_2 = c0 * dgam_dB / gam + Ba3 = c0 * (-0.25 * lq2 * gam * dgam_dB / alphad + dw_dB / (w * alphad)) + Ba4_1 = (S2lq * lq) * dgam_dB / w2 + Ba4 = Ba4_1 * c - gB[ind3t] = np.real(Ba1[ind]*upm) - np.real(((Ba2_1[ind] + Ba2_2[ind]*t1)*egamt - Ba3[ind]*egamct)*upv)\ - + np.real(Ba4[ind]*upmd) + np.real((Ba4_1[ind]*ec)*upvd) + gB[ind3t] = ( + np.real(Ba1[ind] * upm) + - np.real( + ((Ba2_1[ind] + Ba2_2[ind] * t1) * egamt - Ba3[ind] * egamct) * upv + ) + + np.real(Ba4[ind] * upmd) + + np.real((Ba4_1[ind] * ec) * upvd) + ) # gradient wrt C - dw_dC = - alphad*dw_dB - dgam_dC = 0.5 + 1j*dw_dC + dw_dC = -alphad * dw_dB + dgam_dC = 0.5 + 1j * dw_dC - Ca1 = c0*(-0.25/alpha2 + 0.5*dgam_dC/gam2 + (0.5*lq2*gam*dgam_dC - 2.*dw_dC/w)*c) - Ca2_1 = c0*(dgam_dC*(0.5/gam2 - 0.25*lq2) + dw_dC/(w*gam)) - Ca2_2 = c0*dgam_dC/gam - Ca3_1 = c0*(0.25/alpha2 - 0.25*lq2*gam*dgam_dC/alphad + dw_dC/(w*alphad)) - Ca3_2 = 0.5*c0/alphad - Ca4_1 = (S2lq*lq)*dgam_dC/w2 - Ca4 = Ca4_1*c + Ca1 = c0 * ( + -0.25 / alpha2 + + 0.5 * dgam_dC / gam2 + + (0.5 * lq2 * gam * dgam_dC - 2.0 * dw_dC / w) * c + ) + Ca2_1 = c0 * (dgam_dC * (0.5 / gam2 - 0.25 * lq2) + dw_dC / (w * gam)) + Ca2_2 = c0 * dgam_dC / gam + Ca3_1 = c0 * ( + 0.25 / alpha2 + - 0.25 * lq2 * gam * dgam_dC / alphad + + dw_dC / (w * alphad) + ) + Ca3_2 = 0.5 * c0 / alphad + Ca4_1 = (S2lq * lq) * dgam_dC / w2 + Ca4 = Ca4_1 * c - gC[ind3t] = np.real(Ca1[ind]*upm) - np.real(((Ca2_1[ind] + Ca2_2[ind]*t1)*egamt - (Ca3_1[ind] + Ca3_2[ind]*t1)*egamct)*upv)\ - + np.real(Ca4[ind]*upmd) + np.real((Ca4_1[ind]*ec)*upvd) + gC[ind3t] = ( + np.real(Ca1[ind] * upm) + - np.real( + ( + (Ca2_1[ind] + Ca2_2[ind] * t1) * egamt + - (Ca3_1[ind] + Ca3_2[ind] * t1) * egamct + ) + * upv + ) + + np.real(Ca4[ind] * upmd) + + np.real((Ca4_1[ind] * ec) * upvd) + ) - #Gradient wrt lengthscale - #DxQ terms - la = (1./lq + nu*gam)*c0 - la1 = la*c + # Gradient wrt lengthscale + # DxQ terms + la = (1.0 / lq + nu * gam) * c0 + la1 = la * c - c0l = (S2[d]/w2)*lq - la3 = c0l*c - gam_2 = .5*gam - glq[ind3t] = (la1[ind]*upm).real + ((la[ind]*ec)*upv).real\ - + (la3[ind]*(-gam_2[ind] + etlq2gamt*(-t_lq2 + gam_2[ind]))).real\ - + ((c0l[ind]*ec)*(-et2_lq2*(t_lq2 + gam_2[ind]) + egamt*gam_2[ind])).real + c0l = (S2[d] / w2) * lq + la3 = c0l * c + gam_2 = 0.5 * gam + glq[ind3t] = ( + (la1[ind] * upm).real + + ((la[ind] * ec) * upv).real + + (la3[ind] * (-gam_2[ind] + etlq2gamt * (-t_lq2 + gam_2[ind]))).real + + ( + (c0l[ind] * ec) + * (-et2_lq2 * (t_lq2 + gam_2[ind]) + egamt * gam_2[ind]) + ).real + ) - #(2) When w_d is complex + # (2) When w_d is complex if np.any(wbool): t1 = t[ind2t] ind = index[ind2t] - #Index transformation + # Index transformation d = np.asarray(np.where(wbool)[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - S2lq = S2[d]*(.25*lq) - c0 = S2lq*np.sqrt(np.pi) - w = .5*np.sqrt(C2[d]-4.*B[d]) - w2 = -w*w + # Dx1 terms + S2lq = S2[d] * (0.25 * lq) + c0 = S2lq * np.sqrt(np.pi) + w = 0.5 * np.sqrt(C2[d] - 4.0 * B[d]) + w2 = -w * w alphad = alpha[d] - alpha2 = alphad*alphad + alpha2 = alphad * alphad gam = alphad - w gamc = alphad + w - gam2 = gam*gam - gamc2 = gamc*gamc - c1 = .5/alphad - c21 = .5/gam - c22 = .5/gamc + gam2 = gam * gam + gamc2 = gamc * gamc + c1 = 0.5 / alphad + c21 = 0.5 / gam + c22 = 0.5 / gamc c = c1 - c21 c2 = c1 - c22 - #DxQ terms - c0 = c0/w2 - nu = .5*lq*gam - nuc = .5*lq*gamc + # DxQ terms + c0 = c0 / w2 + nu = 0.5 * lq * gam + nuc = 0.5 * lq * gamc - #Nx1 terms - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 + # Nx1 terms + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 egamt = np.exp(gamt) egamct = np.exp(gamct) - ec = egamt*c21[ind] - egamct*c1[ind] - ec2 = egamct*c22[ind] - egamt*c1[ind] - #NxQ terms - t_lq = t1/lq - t2_lq2 = -t_lq*t_lq + ec = egamt * c21[ind] - egamct * c1[ind] + ec2 = egamct * c22[ind] - egamt * c1[ind] + # NxQ terms + t_lq = t1 / lq + t2_lq2 = -t_lq * t_lq et2_lq2 = np.exp(t2_lq2) etlq2gamct = np.exp(t2_lq2 + gamct) etlq2gamt = np.exp(t2_lq2 + gamt) - #Upsilon Calculations using wofz - t2_lq2 = -t_lq*t_lq #Required when using wofz - wnu = np.real(wofz(1j*nu)) + # Upsilon Calculations using wofz + t2_lq2 = -t_lq * t_lq # Required when using wofz + wnu = np.real(wofz(1j * nu)) lwnu = np.log(wnu) - upm = wnu[ind] - np.exp(t2_lq2 + gamt + np.log(wofz(1j*(t_lq + nu[ind])).real)) - upm[t1[:, 0] == 0., :] = 0. + upm = wnu[ind] - np.exp( + t2_lq2 + gamt + np.log(wofz(1j * (t_lq + nu[ind])).real) + ) + upm[t1[:, 0] == 0.0, :] = 0.0 - nu2 = nu*nu + nu2 = nu * nu z1 = nu[ind] - t_lq - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) upv = -np.exp(lwnu[ind] + gamt) if indv1[0].shape > 0: - upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upv[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real)) if indv2[0].shape > 0: - upv[indv2] += np.exp(nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.)) - np.exp(t2_lq2[indv2]\ - + np.log(wofz(-1j*z1[indv2]).real)) - upv[t1[:, 0] == 0, :] = 0. + upv[indv2] += np.exp( + nu2[ind[indv2[0]], indv2[1]] + gamt[indv2[0], 0] + np.log(2.0) + ) - np.exp(t2_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upv[t1[:, 0] == 0, :] = 0.0 - wnuc = wofz(1j*nuc).real - upmc = wnuc[ind] - np.exp(t2_lq2 + gamct + np.log(wofz(1j*(t_lq + nuc[ind])).real)) - upmc[t1[:, 0] == 0., :] = 0. + wnuc = wofz(1j * nuc).real + upmc = wnuc[ind] - np.exp( + t2_lq2 + gamct + np.log(wofz(1j * (t_lq + nuc[ind])).real) + ) + upmc[t1[:, 0] == 0.0, :] = 0.0 lwnuc = np.log(wnuc) - nuc2 = nuc*nuc + nuc2 = nuc * nuc z1 = nuc[ind] - t_lq - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) upvc = -np.exp(lwnuc[ind] + gamct) if indv1[0].shape > 0: - upvc[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upvc[indv1] += np.exp(t2_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real)) if indv2[0].shape > 0: - upvc[indv2] += np.exp(nuc2[ind[indv2[0]], indv2[1]] + gamct[indv2[0], 0] + np.log(2.)) - np.exp(t2_lq2[indv2]\ - + np.log(wofz(-1j*z1[indv2]).real)) - upvc[t1[:, 0] == 0, :] = 0. + upvc[indv2] += np.exp( + nuc2[ind[indv2[0]], indv2[1]] + gamct[indv2[0], 0] + np.log(2.0) + ) - np.exp(t2_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upvc[t1[:, 0] == 0, :] = 0.0 - #Gradient wrt S - #NxQ terms - c0_S = (S[d]/w2)*(lq*(np.sqrt(np.pi)*.5)) + # Gradient wrt S + # NxQ terms + c0_S = (S[d] / w2) * (lq * (np.sqrt(np.pi) * 0.5)) - K011 = c0_S*c - K012 = c0_S*c2 + K011 = c0_S * c + K012 = c0_S * c2 - gS[ind2t] = K011[ind]*upm + K012[ind]*upmc + (c0_S[ind]*ec)*upv + (c0_S[ind]*ec2)*upvc + gS[ind2t] = ( + K011[ind] * upm + + K012[ind] * upmc + + (c0_S[ind] * ec) * upv + + (c0_S[ind] * ec2) * upvc + ) - #Is required to cache this, C gradient also required them - upmd = -1. + etlq2gamt + # Is required to cache this, C gradient also required them + upmd = -1.0 + etlq2gamt upvd = -et2_lq2 + egamt - upmdc = -1. + etlq2gamct + upmdc = -1.0 + etlq2gamct upvdc = -et2_lq2 + egamct # Gradient wrt B - dgam_dB = 0.5/w + dgam_dB = 0.5 / w dgamc_dB = -dgam_dB - Ba1 = c0*(0.5*dgam_dB/gam2 + (0.5*lq2*gam*dgam_dB - 1./w2)*c) - Ba3 = c0*(-0.25*lq2*gam*dgam_dB/alphad + 0.5/(w2*alphad)) - Ba4_1 = (S2lq*lq)*dgam_dB/w2 - Ba4 = Ba4_1*c - Ba2_1 = c0*(dgam_dB*(0.5/gam2 - 0.25*lq2) + 0.5/(w2*gam)) - Ba2_2 = c0*dgam_dB/gam + Ba1 = c0 * ( + 0.5 * dgam_dB / gam2 + (0.5 * lq2 * gam * dgam_dB - 1.0 / w2) * c + ) + Ba3 = c0 * (-0.25 * lq2 * gam * dgam_dB / alphad + 0.5 / (w2 * alphad)) + Ba4_1 = (S2lq * lq) * dgam_dB / w2 + Ba4 = Ba4_1 * c + Ba2_1 = c0 * (dgam_dB * (0.5 / gam2 - 0.25 * lq2) + 0.5 / (w2 * gam)) + Ba2_2 = c0 * dgam_dB / gam - Ba1c = c0*(0.5*dgamc_dB/gamc2 + (0.5*lq2*gamc*dgamc_dB - 1./w2)*c2) - Ba3c = c0*(-0.25*lq2*gamc*dgamc_dB/alphad + 0.5/(w2*alphad)) - Ba4_1c = (S2lq*lq)*dgamc_dB/w2 - Ba4c = Ba4_1c*c2 - Ba2_1c = c0*(dgamc_dB*(0.5/gamc2 - 0.25*lq2) + 0.5/(w2*gamc)) - Ba2_2c = c0*dgamc_dB/gamc + Ba1c = c0 * ( + 0.5 * dgamc_dB / gamc2 + (0.5 * lq2 * gamc * dgamc_dB - 1.0 / w2) * c2 + ) + Ba3c = c0 * (-0.25 * lq2 * gamc * dgamc_dB / alphad + 0.5 / (w2 * alphad)) + Ba4_1c = (S2lq * lq) * dgamc_dB / w2 + Ba4c = Ba4_1c * c2 + Ba2_1c = c0 * (dgamc_dB * (0.5 / gamc2 - 0.25 * lq2) + 0.5 / (w2 * gamc)) + Ba2_2c = c0 * dgamc_dB / gamc - gB[ind2t] = Ba1[ind]*upm - ((Ba2_1[ind] + Ba2_2[ind]*t1)*egamt - Ba3[ind]*egamct)*upv\ - + Ba4[ind]*upmd + (Ba4_1[ind]*ec)*upvd\ - + Ba1c[ind]*upmc - ((Ba2_1c[ind] + Ba2_2c[ind]*t1)*egamct - Ba3c[ind]*egamt)*upvc\ - + Ba4c[ind]*upmdc + (Ba4_1c[ind]*ec2)*upvdc + gB[ind2t] = ( + Ba1[ind] * upm + - ((Ba2_1[ind] + Ba2_2[ind] * t1) * egamt - Ba3[ind] * egamct) * upv + + Ba4[ind] * upmd + + (Ba4_1[ind] * ec) * upvd + + Ba1c[ind] * upmc + - ((Ba2_1c[ind] + Ba2_2c[ind] * t1) * egamct - Ba3c[ind] * egamt) * upvc + + Ba4c[ind] * upmdc + + (Ba4_1c[ind] * ec2) * upvdc + ) ##Gradient wrt C - dw_dC = 0.5*alphad/w + dw_dC = 0.5 * alphad / w dgam_dC = 0.5 - dw_dC dgamc_dC = 0.5 + dw_dC - S2lq2 = S2lq*lq + S2lq2 = S2lq * lq - Ca1 = c0*(-0.25/alpha2 + 0.5*dgam_dC/gam2 + (0.5*lq2*gam*dgam_dC + alphad/w2)*c) - Ca2_1 = c0*(dgam_dC*(0.5/gam2 - 0.25*lq2) - 0.5*alphad/(w2*gam)) - Ca2_2 = c0*dgam_dC/gam - Ca3_1 = c0*(0.25/alpha2 - 0.25*lq2*gam*dgam_dC/alphad - 0.5/w2) - Ca3_2 = 0.5*c0/alphad - Ca4_1 = S2lq2*(dgam_dC/w2) - Ca4 = Ca4_1*c + Ca1 = c0 * ( + -0.25 / alpha2 + + 0.5 * dgam_dC / gam2 + + (0.5 * lq2 * gam * dgam_dC + alphad / w2) * c + ) + Ca2_1 = c0 * ( + dgam_dC * (0.5 / gam2 - 0.25 * lq2) - 0.5 * alphad / (w2 * gam) + ) + Ca2_2 = c0 * dgam_dC / gam + Ca3_1 = c0 * ( + 0.25 / alpha2 - 0.25 * lq2 * gam * dgam_dC / alphad - 0.5 / w2 + ) + Ca3_2 = 0.5 * c0 / alphad + Ca4_1 = S2lq2 * (dgam_dC / w2) + Ca4 = Ca4_1 * c - Ca1c = c0*(-0.25/alpha2 + 0.5*dgamc_dC/gamc2 + (0.5*lq2*gamc*dgamc_dC + alphad/w2)*c2) - Ca2_1c = c0*(dgamc_dC*(0.5/gamc2 - 0.25*lq2) - 0.5*alphad/(w2*gamc)) - Ca2_2c = c0*dgamc_dC/gamc - Ca3_1c = c0*(0.25/alpha2 - 0.25*lq2*gamc*dgamc_dC/alphad - 0.5/w2) - Ca3_2c = 0.5*c0/alphad - Ca4_1c = S2lq2*(dgamc_dC/w2) - Ca4c = Ca4_1c*c2 + Ca1c = c0 * ( + -0.25 / alpha2 + + 0.5 * dgamc_dC / gamc2 + + (0.5 * lq2 * gamc * dgamc_dC + alphad / w2) * c2 + ) + Ca2_1c = c0 * ( + dgamc_dC * (0.5 / gamc2 - 0.25 * lq2) - 0.5 * alphad / (w2 * gamc) + ) + Ca2_2c = c0 * dgamc_dC / gamc + Ca3_1c = c0 * ( + 0.25 / alpha2 - 0.25 * lq2 * gamc * dgamc_dC / alphad - 0.5 / w2 + ) + Ca3_2c = 0.5 * c0 / alphad + Ca4_1c = S2lq2 * (dgamc_dC / w2) + Ca4c = Ca4_1c * c2 - gC[ind2t] = Ca1[ind]*upm - ((Ca2_1[ind] + Ca2_2[ind]*t1)*egamt - (Ca3_1[ind] + Ca3_2[ind]*t1)*egamct)*upv\ - + Ca4[ind]*upmd + (Ca4_1[ind]*ec)*upvd\ - + Ca1c[ind]*upmc - ((Ca2_1c[ind] + Ca2_2c[ind]*t1)*egamct - (Ca3_1c[ind] + Ca3_2c[ind]*t1)*egamt)*upvc\ - + Ca4c[ind]*upmdc + (Ca4_1c[ind]*ec2)*upvdc + gC[ind2t] = ( + Ca1[ind] * upm + - ( + (Ca2_1[ind] + Ca2_2[ind] * t1) * egamt + - (Ca3_1[ind] + Ca3_2[ind] * t1) * egamct + ) + * upv + + Ca4[ind] * upmd + + (Ca4_1[ind] * ec) * upvd + + Ca1c[ind] * upmc + - ( + (Ca2_1c[ind] + Ca2_2c[ind] * t1) * egamct + - (Ca3_1c[ind] + Ca3_2c[ind] * t1) * egamt + ) + * upvc + + Ca4c[ind] * upmdc + + (Ca4_1c[ind] * ec2) * upvdc + ) - #Gradient wrt lengthscale - #DxQ terms - la = (1./lq + nu*gam)*c0 - lac = (1./lq + nuc*gamc)*c0 - la1 = la*c - la1c = lac*c2 - t_lq2 = t_lq/lq - c0l = (S2[d]/w2)*(.5*lq) - la3 = c0l*c - la3c = c0l*c2 - gam_2 = .5*gam - gamc_2 = .5*gamc - glq[ind2t] = la1c[ind]*upmc + (lac[ind]*ec2)*upvc\ - + la3c[ind]*(-gamc_2[ind] + etlq2gamct*(-t_lq2 + gamc_2[ind]))\ - + (c0l[ind]*ec2)*(-et2_lq2*(t_lq2 + gamc_2[ind]) + egamct*gamc_2[ind])\ - + la1[ind]*upm + (la[ind]*ec)*upv\ - + la3[ind]*(-gam_2[ind] + etlq2gamt*(-t_lq2 + gam_2[ind]))\ - + (c0l[ind]*ec)*(-et2_lq2*(t_lq2 + gam_2[ind]) + egamt*gam_2[ind]) + # Gradient wrt lengthscale + # DxQ terms + la = (1.0 / lq + nu * gam) * c0 + lac = (1.0 / lq + nuc * gamc) * c0 + la1 = la * c + la1c = lac * c2 + t_lq2 = t_lq / lq + c0l = (S2[d] / w2) * (0.5 * lq) + la3 = c0l * c + la3c = c0l * c2 + gam_2 = 0.5 * gam + gamc_2 = 0.5 * gamc + glq[ind2t] = ( + la1c[ind] * upmc + + (lac[ind] * ec2) * upvc + + la3c[ind] * (-gamc_2[ind] + etlq2gamct * (-t_lq2 + gamc_2[ind])) + + (c0l[ind] * ec2) + * (-et2_lq2 * (t_lq2 + gamc_2[ind]) + egamct * gamc_2[ind]) + + la1[ind] * upm + + (la[ind] * ec) * upv + + la3[ind] * (-gam_2[ind] + etlq2gamt * (-t_lq2 + gam_2[ind])) + + (c0l[ind] * ec) + * (-et2_lq2 * (t_lq2 + gam_2[ind]) + egamt * gam_2[ind]) + ) return glq, gS, gB, gC def _gkfu(self, X, index, Z, index2): - index = index.reshape(index.size,) - #TODO: reduce memory usage - #terms that move along t + index = index.reshape( + index.size, + ) + # TODO: reduce memory usage + # terms that move along t d = np.unique(index) B = self.B[d].values C = self.C[d].values S = self.W[d, :].values - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Check where wd becomes complex - wbool = C*C >= 4.*B - #t column + # Check where wd becomes complex + wbool = C * C >= 4.0 * B + # t column t = X[:, 0].reshape(X.shape[0], 1) C = C.reshape(C.size, 1) B = B.reshape(B.size, 1) - C2 = C*C - #z row + C2 = C * C + # z row z = Z[:, 0].reshape(1, Z.shape[0]) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) lq = self.lengthscale.values.reshape((1, self.rank)) - lq2 = lq*lq + lq2 = lq * lq - alpha = .5*C + alpha = 0.5 * C wbool2 = wbool[index] ind2t = np.where(wbool2) ind3t = np.where(np.logical_not(wbool2)) - #kfu = np.empty((t.size, z.size)) + # kfu = np.empty((t.size, z.size)) glq = np.empty((t.size, z.size)) gSdq = np.empty((t.size, z.size)) gB = np.empty((t.size, z.size)) gC = np.empty((t.size, z.size)) indD = np.arange(B.size) - #(1) when wd is real + # (1) when wd is real if np.any(np.logical_not(wbool)): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind3t] ind = index[ind3t] - #Index transformation + # Index transformation d = np.asarray(np.where(np.logical_not(wbool))[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - w = .5*np.sqrt(4.*B[d] - C2[d]) + # Dx1 terms + w = 0.5 * np.sqrt(4.0 * B[d] - C2[d]) alphad = alpha[d] - gam = alphad - 1j*w - gam_2 = .5*gam - S_w = S[d]/w - S_wpi = S_w*(.5*np.sqrt(np.pi)) - #DxQ terms - c0 = S_wpi*lq #lq*Sdq*sqrt(pi)/(2w) - nu = gam*lq - nu2 = 1.+.5*(nu*nu) - nu *= .5 + gam = alphad - 1j * w + gam_2 = 0.5 * gam + S_w = S[d] / w + S_wpi = S_w * (0.5 * np.sqrt(np.pi)) + # DxQ terms + c0 = S_wpi * lq # lq*Sdq*sqrt(pi)/(2w) + nu = gam * lq + nu2 = 1.0 + 0.5 * (nu * nu) + nu *= 0.5 - #1xM terms - z_lq = z/lq[0, index2] - z_lq2 = -z_lq*z_lq - #NxQ terms - t_lq = t1/lq - #DxM terms - gamt = -gam[ind]*t1 - #NxM terms + # 1xM terms + z_lq = z / lq[0, index2] + z_lq2 = -z_lq * z_lq + # NxQ terms + t_lq = t1 / lq + # DxM terms + gamt = -gam[ind] * t1 + # NxM terms zt_lq = z_lq - t_lq[:, index2] - zt_lq2 = -zt_lq*zt_lq + zt_lq2 = -zt_lq * zt_lq ezt_lq2 = -np.exp(zt_lq2) ezgamt = np.exp(z_lq2 + gamt) # Upsilon calculations fullind = np.ix_(ind, index2) - upsi = - np.exp(z_lq2 + gamt + np.log(wofz(1j*(z_lq + nu[fullind])))) - tz = t1-z + upsi = -np.exp(z_lq2 + gamt + np.log(wofz(1j * (z_lq + nu[fullind])))) + tz = t1 - z z1 = zt_lq + nu[fullind] - indv1 = np.where(z1.real >= 0.) - indv2 = np.where(z1.real < 0.) + indv1 = np.where(z1.real >= 0.0) + indv2 = np.where(z1.real < 0.0) if indv1[0].shape > 0: - upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]))) + upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]))) if indv2[0].shape > 0: - nua2 = nu[ind[indv2[0]], index2[indv2[1]]]**2 - upsi[indv2] += np.exp(nua2 - gam[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]))) - upsi[t1[:, 0] == 0., :] = 0. + nua2 = nu[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi[indv2] += np.exp( + nua2 - gam[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]))) + upsi[t1[:, 0] == 0.0, :] = 0.0 - #Gradient wrt S - #DxQ term - Sa1 = lq*(.5*np.sqrt(np.pi))/w + # Gradient wrt S + # DxQ term + Sa1 = lq * (0.5 * np.sqrt(np.pi)) / w - gSdq[ind3t] = Sa1[np.ix_(ind, index2)]*upsi.imag + gSdq[ind3t] = Sa1[np.ix_(ind, index2)] * upsi.imag - #Gradient wrt lq - la1 = S_wpi*nu2 - la2 = S_w*lq - uplq = ezt_lq2*(gam_2[ind]) - uplq += ezgamt*(-z_lq/lq[0, index2] + gam_2[ind]) + # Gradient wrt lq + la1 = S_wpi * nu2 + la2 = S_w * lq + uplq = ezt_lq2 * (gam_2[ind]) + uplq += ezgamt * (-z_lq / lq[0, index2] + gam_2[ind]) - glq[ind3t] = (la1[np.ix_(ind, index2)]*upsi).imag - glq[ind3t] += la2[np.ix_(ind, index2)]*uplq.imag + glq[ind3t] = (la1[np.ix_(ind, index2)] * upsi).imag + glq[ind3t] += la2[np.ix_(ind, index2)] * uplq.imag - #Gradient wrt B - #Dx1 terms - dw_dB = .5/w - dgam_dB = -1j*dw_dB - #DxQ terms - Ba1 = -c0*dw_dB/w #DXQ - Ba2 = c0*dgam_dB #DxQ - Ba3 = lq2*gam_2 #DxQ - Ba4 = (dgam_dB*S_w)*(.5*lq2) #DxQ + # Gradient wrt B + # Dx1 terms + dw_dB = 0.5 / w + dgam_dB = -1j * dw_dB + # DxQ terms + Ba1 = -c0 * dw_dB / w # DXQ + Ba2 = c0 * dgam_dB # DxQ + Ba3 = lq2 * gam_2 # DxQ + Ba4 = (dgam_dB * S_w) * (0.5 * lq2) # DxQ - gB[ind3t] = ((Ba1[np.ix_(ind, index2)] + Ba2[np.ix_(ind, index2)]*(Ba3[np.ix_(ind, index2)] - (t1-z)))*upsi).imag\ - + (Ba4[np.ix_(ind, index2)]*(ezt_lq2 + ezgamt)).imag + gB[ind3t] = ( + ( + Ba1[np.ix_(ind, index2)] + + Ba2[np.ix_(ind, index2)] * (Ba3[np.ix_(ind, index2)] - (t1 - z)) + ) + * upsi + ).imag + (Ba4[np.ix_(ind, index2)] * (ezt_lq2 + ezgamt)).imag - #Gradient wrt C (it uses some calculations performed in B) - #Dx1 terms - dw_dC = -.5*alphad/w - dgam_dC = 0.5 - 1j*dw_dC - #DxQ terms - Ca1 = -c0*dw_dC/w #DXQ - Ca2 = c0*dgam_dC #DxQ - Ca4 = (dgam_dC*S_w)*(.5*lq2) #DxQ + # Gradient wrt C (it uses some calculations performed in B) + # Dx1 terms + dw_dC = -0.5 * alphad / w + dgam_dC = 0.5 - 1j * dw_dC + # DxQ terms + Ca1 = -c0 * dw_dC / w # DXQ + Ca2 = c0 * dgam_dC # DxQ + Ca4 = (dgam_dC * S_w) * (0.5 * lq2) # DxQ - gC[ind3t] = ((Ca1[np.ix_(ind, index2)] + Ca2[np.ix_(ind, index2)]*(Ba3[np.ix_(ind, index2)] - (t1-z)))*upsi).imag\ - + (Ca4[np.ix_(ind, index2)]*(ezt_lq2 + ezgamt)).imag + gC[ind3t] = ( + ( + Ca1[np.ix_(ind, index2)] + + Ca2[np.ix_(ind, index2)] * (Ba3[np.ix_(ind, index2)] - (t1 - z)) + ) + * upsi + ).imag + (Ca4[np.ix_(ind, index2)] * (ezt_lq2 + ezgamt)).imag - #(2) when wd is complex + # (2) when wd is complex if np.any(wbool): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind2t] ind = index[ind2t] - #Index transformation + # Index transformation d = np.asarray(np.where(wbool)[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - w = .5*np.sqrt(C2[d] - 4.*B[d]) - w2 = w*w + # Dx1 terms + w = 0.5 * np.sqrt(C2[d] - 4.0 * B[d]) + w2 = w * w alphad = alpha[d] gam = alphad - w gamc = alphad + w - #DxQ terms - S_w= -S[d]/w #minus is given by j*j - S_wpi = S_w*(.25*np.sqrt(np.pi)) + # DxQ terms + S_w = -S[d] / w # minus is given by j*j + S_wpi = S_w * (0.25 * np.sqrt(np.pi)) - c0 = S_wpi*lq - gam_2 = .5*gam - gamc_2 = .5*gamc - nu = gam*lq - nuc = gamc*lq - nu2 = 1.+.5*(nu*nu) - nuc2 = 1.+.5*(nuc*nuc) - nu *= .5 - nuc *= .5 - #1xM terms - z_lq = z/lq[0, index2] - z_lq2 = -z_lq*z_lq - #Nx1 - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 - #NxQ terms - t_lq = t1/lq[0, index2] - #NxM terms + c0 = S_wpi * lq + gam_2 = 0.5 * gam + gamc_2 = 0.5 * gamc + nu = gam * lq + nuc = gamc * lq + nu2 = 1.0 + 0.5 * (nu * nu) + nuc2 = 1.0 + 0.5 * (nuc * nuc) + nu *= 0.5 + nuc *= 0.5 + # 1xM terms + z_lq = z / lq[0, index2] + z_lq2 = -z_lq * z_lq + # Nx1 + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 + # NxQ terms + t_lq = t1 / lq[0, index2] + # NxM terms zt_lq = z_lq - t_lq - zt_lq2 = -zt_lq*zt_lq + zt_lq2 = -zt_lq * zt_lq ezt_lq2 = -np.exp(zt_lq2) ezgamt = np.exp(z_lq2 + gamt) ezgamct = np.exp(z_lq2 + gamct) # Upsilon calculations fullind = np.ix_(ind, index2) - upsi1 = - np.exp(z_lq2 + gamct + np.log(wofz(1j*(z_lq + nuc[fullind])).real)) - tz = t1-z + upsi1 = -np.exp( + z_lq2 + gamct + np.log(wofz(1j * (z_lq + nuc[fullind])).real) + ) + tz = t1 - z z1 = zt_lq + nuc[fullind] - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) if indv1[0].shape > 0: - upsi1[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upsi1[indv1] += np.exp( + zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real) + ) if indv2[0].shape > 0: - nuac2 = nuc[ind[indv2[0]], index2[indv2[1]]]**2 - upsi1[indv2] += np.exp(nuac2 - gamc[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upsi1[t1[:, 0] == 0., :] = 0. + nuac2 = nuc[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi1[indv2] += np.exp( + nuac2 - gamc[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upsi1[t1[:, 0] == 0.0, :] = 0.0 - upsi2 = - np.exp(z_lq2 + gamt + np.log(wofz(1j*(z_lq + nu[fullind])).real)) + upsi2 = -np.exp(z_lq2 + gamt + np.log(wofz(1j * (z_lq + nu[fullind])).real)) z1 = zt_lq + nu[fullind] - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) if indv1[0].shape > 0: - upsi2[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upsi2[indv1] += np.exp( + zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real) + ) if indv2[0].shape > 0: - nua2 = nu[ind[indv2[0]], index2[indv2[1]]]**2 - upsi2[indv2] += np.exp(nua2 - gam[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upsi2[t1[:, 0] == 0., :] = 0. + nua2 = nu[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi2[indv2] += np.exp( + nua2 - gam[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upsi2[t1[:, 0] == 0.0, :] = 0.0 - #Gradient wrt lq - la1 = S_wpi*nu2 - la1c = S_wpi*nuc2 - la2 = S_w*(.5*lq) - uplq = ezt_lq2*(gamc_2[ind]) + ezgamct*(-z_lq/lq[0, index2] + gamc_2[ind])\ - - ezt_lq2*(gam_2[ind]) - ezgamt*(-z_lq/lq[0, index2] + gam_2[ind]) + # Gradient wrt lq + la1 = S_wpi * nu2 + la1c = S_wpi * nuc2 + la2 = S_w * (0.5 * lq) + uplq = ( + ezt_lq2 * (gamc_2[ind]) + + ezgamct * (-z_lq / lq[0, index2] + gamc_2[ind]) + - ezt_lq2 * (gam_2[ind]) + - ezgamt * (-z_lq / lq[0, index2] + gam_2[ind]) + ) - glq[ind2t] = la1c[np.ix_(ind, index2)]*upsi1 - la1[np.ix_(ind, index2)]*upsi2\ - + la2[np.ix_(ind, index2)]*uplq + glq[ind2t] = ( + la1c[np.ix_(ind, index2)] * upsi1 + - la1[np.ix_(ind, index2)] * upsi2 + + la2[np.ix_(ind, index2)] * uplq + ) + # Gradient wrt S + Sa1 = (lq * (-0.25 * np.sqrt(np.pi))) / w - #Gradient wrt S - Sa1 = (lq*(-.25*np.sqrt(np.pi)))/w + gSdq[ind2t] = Sa1[np.ix_(ind, index2)] * (upsi1 - upsi2) - gSdq[ind2t] = Sa1[np.ix_(ind, index2)]*(upsi1 - upsi2) - - #Gradient wrt B - #Dx1 terms - dgam_dB = .5/w + # Gradient wrt B + # Dx1 terms + dgam_dB = 0.5 / w dgamc_dB = -dgam_dB - #DxQ terms - Ba1 = .5*(c0/w2) - Ba2 = c0*dgam_dB - Ba3 = lq2*gam_2 - Ba4 = (dgam_dB*S_w)*(.25*lq2) + # DxQ terms + Ba1 = 0.5 * (c0 / w2) + Ba2 = c0 * dgam_dB + Ba3 = lq2 * gam_2 + Ba4 = (dgam_dB * S_w) * (0.25 * lq2) - Ba2c = c0*dgamc_dB - Ba3c = lq2*gamc_2 - Ba4c = (dgamc_dB*S_w)*(.25*lq2) + Ba2c = c0 * dgamc_dB + Ba3c = lq2 * gamc_2 + Ba4c = (dgamc_dB * S_w) * (0.25 * lq2) - gB[ind2t] = (Ba1[np.ix_(ind, index2)] + Ba2c[np.ix_(ind, index2)]*(Ba3c[np.ix_(ind, index2)] - (t1-z)))*upsi1\ - + Ba4c[np.ix_(ind, index2)]*(ezt_lq2 + ezgamct)\ - - (Ba1[np.ix_(ind, index2)] + Ba2[np.ix_(ind, index2)]*(Ba3[np.ix_(ind, index2)] - (t1-z)))*upsi2\ - - Ba4[np.ix_(ind, index2)]*(ezt_lq2 + ezgamt) + gB[ind2t] = ( + ( + Ba1[np.ix_(ind, index2)] + + Ba2c[np.ix_(ind, index2)] * (Ba3c[np.ix_(ind, index2)] - (t1 - z)) + ) + * upsi1 + + Ba4c[np.ix_(ind, index2)] * (ezt_lq2 + ezgamct) + - ( + Ba1[np.ix_(ind, index2)] + + Ba2[np.ix_(ind, index2)] * (Ba3[np.ix_(ind, index2)] - (t1 - z)) + ) + * upsi2 + - Ba4[np.ix_(ind, index2)] * (ezt_lq2 + ezgamt) + ) - #Gradient wrt C - #Dx1 terms - dgam_dC = 0.5 - .5*(alphad/w) - dgamc_dC = 0.5 + .5*(alphad/w) - #DxQ terms - Ca1 = -c0*(.5*alphad/w2) - Ca2 = c0*dgam_dC - Ca4 = (dgam_dC*S_w)*(.25*lq2) + # Gradient wrt C + # Dx1 terms + dgam_dC = 0.5 - 0.5 * (alphad / w) + dgamc_dC = 0.5 + 0.5 * (alphad / w) + # DxQ terms + Ca1 = -c0 * (0.5 * alphad / w2) + Ca2 = c0 * dgam_dC + Ca4 = (dgam_dC * S_w) * (0.25 * lq2) - Ca2c = c0*dgamc_dC - Ca4c = (dgamc_dC*S_w)*(.25*lq2) + Ca2c = c0 * dgamc_dC + Ca4c = (dgamc_dC * S_w) * (0.25 * lq2) - gC[ind2t] = (Ca1[np.ix_(ind, index2)] + Ca2c[np.ix_(ind, index2)]*(Ba3c[np.ix_(ind, index2)] - (t1-z)))*upsi1\ - + Ca4c[np.ix_(ind, index2)]*(ezt_lq2 + ezgamct)\ - - (Ca1[np.ix_(ind, index2)] + Ca2[np.ix_(ind, index2)]*(Ba3[np.ix_(ind, index2)] - (t1-z)))*upsi2\ - - Ca4[np.ix_(ind, index2)]*(ezt_lq2 + ezgamt) + gC[ind2t] = ( + ( + Ca1[np.ix_(ind, index2)] + + Ca2c[np.ix_(ind, index2)] * (Ba3c[np.ix_(ind, index2)] - (t1 - z)) + ) + * upsi1 + + Ca4c[np.ix_(ind, index2)] * (ezt_lq2 + ezgamct) + - ( + Ca1[np.ix_(ind, index2)] + + Ca2[np.ix_(ind, index2)] * (Ba3[np.ix_(ind, index2)] - (t1 - z)) + ) + * upsi2 + - Ca4[np.ix_(ind, index2)] * (ezt_lq2 + ezgamt) + ) return glq, gSdq, gB, gC - #TODO: reduce memory usage - def _gkfu_z(self, X, index, Z, index2): #Kfu(t,z) - index = index.reshape(index.size,) - #terms that move along t + # TODO: reduce memory usage + def _gkfu_z(self, X, index, Z, index2): # Kfu(t,z) + index = index.reshape( + index.size, + ) + # terms that move along t d = np.unique(index) B = self.B[d].values C = self.C[d].values S = self.W[d, :].values - #Index transformation + # Index transformation indd = np.arange(self.output_dim) indd[d] = np.arange(d.size) index = indd[index] - #Check where wd becomes complex - wbool = C*C >= 4.*B + # Check where wd becomes complex + wbool = C * C >= 4.0 * B wbool2 = wbool[index] ind2t = np.where(wbool2) ind3t = np.where(np.logical_not(wbool2)) - #t column + # t column t = X[:, 0].reshape(X.shape[0], 1) C = C.reshape(C.size, 1) B = B.reshape(B.size, 1) - C2 = C*C - alpha = .5*C - #z row + C2 = C * C + alpha = 0.5 * C + # z row z = Z[:, 0].reshape(1, Z.shape[0]) - index2 = index2.reshape(index2.size,) + index2 = index2.reshape( + index2.size, + ) lq = self.lengthscale.values.reshape((1, self.rank)) - #kfu = np.empty((t.size, z.size)) + # kfu = np.empty((t.size, z.size)) gz = np.empty((t.size, z.size)) indD = np.arange(B.size) - #(1) when wd is real + # (1) when wd is real if np.any(np.logical_not(wbool)): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind3t] ind = index[ind3t] - #TODO: Find a better way of doing this - #Index transformation + # TODO: Find a better way of doing this + # Index transformation d = np.asarray(np.where(np.logical_not(wbool))[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - w = .5*np.sqrt(4.*B[d] - C2[d]) + # Dx1 terms + w = 0.5 * np.sqrt(4.0 * B[d] - C2[d]) alphad = alpha[d] - gam = alphad - 1j*w - S_w = S[d]/w - S_wpi =S_w*(.5*np.sqrt(np.pi)) - #DxQ terms - c0 = S_wpi*lq #lq*Sdq*sqrt(pi)/(2w) - nu = (.5*gam)*lq + gam = alphad - 1j * w + S_w = S[d] / w + S_wpi = S_w * (0.5 * np.sqrt(np.pi)) + # DxQ terms + c0 = S_wpi * lq # lq*Sdq*sqrt(pi)/(2w) + nu = (0.5 * gam) * lq - #1xM terms - z_lq = z/lq[0, index2] - z_lq2 = -z_lq*z_lq - #NxQ terms - t_lq = t1/lq - #DxM terms - gamt = -gam[ind]*t1 - #NxM terms + # 1xM terms + z_lq = z / lq[0, index2] + z_lq2 = -z_lq * z_lq + # NxQ terms + t_lq = t1 / lq + # DxM terms + gamt = -gam[ind] * t1 + # NxM terms zt_lq = z_lq - t_lq[:, index2] - zt_lq2 = -zt_lq*zt_lq - #ezt_lq2 = -np.exp(zt_lq2) + zt_lq2 = -zt_lq * zt_lq + # ezt_lq2 = -np.exp(zt_lq2) ezgamt = np.exp(z_lq2 + gamt) # Upsilon calculations fullind = np.ix_(ind, index2) - upsi = - np.exp(z_lq2 + gamt + np.log(wofz(1j*(z_lq + nu[fullind])))) - tz = t1-z + upsi = -np.exp(z_lq2 + gamt + np.log(wofz(1j * (z_lq + nu[fullind])))) + tz = t1 - z z1 = zt_lq + nu[fullind] - indv1 = np.where(z1.real >= 0.) - indv2 = np.where(z1.real < 0.) + indv1 = np.where(z1.real >= 0.0) + indv2 = np.where(z1.real < 0.0) if indv1[0].shape > 0: - upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]))) + upsi[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]))) if indv2[0].shape > 0: - nua2 = nu[ind[indv2[0]], index2[indv2[1]]]**2 - upsi[indv2] += np.exp(nua2 - gam[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]))) - upsi[t1[:, 0] == 0., :] = 0. + nua2 = nu[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi[indv2] += np.exp( + nua2 - gam[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]))) + upsi[t1[:, 0] == 0.0, :] = 0.0 - #Gradient wrt z - za1 = c0*gam - #za2 = S_w - gz[ind3t] = (za1[np.ix_(ind, index2)]*upsi).imag + S_w[np.ix_(ind, index2)]*ezgamt.imag + # Gradient wrt z + za1 = c0 * gam + # za2 = S_w + gz[ind3t] = (za1[np.ix_(ind, index2)] * upsi).imag + S_w[ + np.ix_(ind, index2) + ] * ezgamt.imag - #(2) when wd is complex + # (2) when wd is complex if np.any(wbool): - #Indexes of index and t related to (2) + # Indexes of index and t related to (2) t1 = t[ind2t] ind = index[ind2t] - #Index transformation + # Index transformation d = np.asarray(np.where(wbool)[0]) indd = indD.copy() indd[d] = np.arange(d.size) ind = indd[ind] - #Dx1 terms - w = .5*np.sqrt(C2[d] - 4.*B[d]) + # Dx1 terms + w = 0.5 * np.sqrt(C2[d] - 4.0 * B[d]) alphad = alpha[d] gam = alphad - w gamc = alphad + w - #DxQ terms - S_w = -S[d]/w #minus is given by j*j - S_wpi = S_w*(.25*np.sqrt(np.pi)) - c0 = S_wpi*lq - nu = .5*gam*lq - nuc = .5*gamc*lq + # DxQ terms + S_w = -S[d] / w # minus is given by j*j + S_wpi = S_w * (0.25 * np.sqrt(np.pi)) + c0 = S_wpi * lq + nu = 0.5 * gam * lq + nuc = 0.5 * gamc * lq - #1xM terms - z_lq = z/lq[0, index2] - z_lq2 = -z_lq*z_lq - #Nx1 - gamt = -gam[ind]*t1 - gamct = -gamc[ind]*t1 - #NxQ terms - t_lq = t1/lq - #NxM terms + # 1xM terms + z_lq = z / lq[0, index2] + z_lq2 = -z_lq * z_lq + # Nx1 + gamt = -gam[ind] * t1 + gamct = -gamc[ind] * t1 + # NxQ terms + t_lq = t1 / lq + # NxM terms zt_lq = z_lq - t_lq[:, index2] ezgamt = np.exp(z_lq2 + gamt) ezgamct = np.exp(z_lq2 + gamct) # Upsilon calculations - zt_lq2 = -zt_lq*zt_lq + zt_lq2 = -zt_lq * zt_lq fullind = np.ix_(ind, index2) - upsi1 = - np.exp(z_lq2 + gamct + np.log(wofz(1j*(z_lq + nuc[fullind])).real)) - tz = t1-z + upsi1 = -np.exp( + z_lq2 + gamct + np.log(wofz(1j * (z_lq + nuc[fullind])).real) + ) + tz = t1 - z z1 = zt_lq + nuc[fullind] - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) if indv1[0].shape > 0: - upsi1[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upsi1[indv1] += np.exp( + zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real) + ) if indv2[0].shape > 0: - nuac2 = nuc[ind[indv2[0]], index2[indv2[1]]]**2 - upsi1[indv2] += np.exp(nuac2 - gamc[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upsi1[t1[:, 0] == 0., :] = 0. + nuac2 = nuc[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi1[indv2] += np.exp( + nuac2 - gamc[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upsi1[t1[:, 0] == 0.0, :] = 0.0 - upsi2 = - np.exp(z_lq2 + gamt + np.log(wofz(1j*(z_lq + nu[fullind])).real)) + upsi2 = -np.exp(z_lq2 + gamt + np.log(wofz(1j * (z_lq + nu[fullind])).real)) z1 = zt_lq + nu[fullind] - indv1 = np.where(z1 >= 0.) - indv2 = np.where(z1 < 0.) + indv1 = np.where(z1 >= 0.0) + indv2 = np.where(z1 < 0.0) if indv1[0].shape > 0: - upsi2[indv1] += np.exp(zt_lq2[indv1] + np.log(wofz(1j*z1[indv1]).real)) + upsi2[indv1] += np.exp( + zt_lq2[indv1] + np.log(wofz(1j * z1[indv1]).real) + ) if indv2[0].shape > 0: - nua2 = nu[ind[indv2[0]], index2[indv2[1]]]**2 - upsi2[indv2] += np.exp(nua2 - gam[ind[indv2[0]], 0]*tz[indv2] + np.log(2.))\ - - np.exp(zt_lq2[indv2] + np.log(wofz(-1j*z1[indv2]).real)) - upsi2[t1[:, 0] == 0., :] = 0. + nua2 = nu[ind[indv2[0]], index2[indv2[1]]] ** 2 + upsi2[indv2] += np.exp( + nua2 - gam[ind[indv2[0]], 0] * tz[indv2] + np.log(2.0) + ) - np.exp(zt_lq2[indv2] + np.log(wofz(-1j * z1[indv2]).real)) + upsi2[t1[:, 0] == 0.0, :] = 0.0 - #Gradient wrt z - za1 = c0*gam - za1c = c0*gamc - za2 = .5*S_w - gz[ind2t] = za1c[np.ix_(ind, index2)]*upsi1 - za1[np.ix_(ind, index2)]*upsi2\ - + za2[np.ix_(ind, index2)]*(ezgamct - ezgamt) + # Gradient wrt z + za1 = c0 * gam + za1c = c0 * gamc + za2 = 0.5 * S_w + gz[ind2t] = ( + za1c[np.ix_(ind, index2)] * upsi1 + - za1[np.ix_(ind, index2)] * upsi2 + + za2[np.ix_(ind, index2)] * (ezgamct - ezgamt) + ) return gz diff --git a/GPy/kern/src/todo/eq_ode1.py b/GPy/kern/src/todo/eq_ode1.py index bf0ca7e4..7104a8e9 100644 --- a/GPy/kern/src/todo/eq_ode1.py +++ b/GPy/kern/src/todo/eq_ode1.py @@ -121,7 +121,7 @@ class Eq_ode1(Kernpart): target+=self.initial_variance * np.exp(- self.decay * (t1_mat + t2_mat)) def Kdiag(self,index,target): - #target += np.diag(self.B)[np.asarray(index,dtype=np.int).flatten()] + #target += np.diag(self.B)[np.asarray(index,dtype=int).flatten()] pass def _param_grad_helper(self,dL_dK,X,X2,target): @@ -203,7 +203,7 @@ class Eq_ode1(Kernpart): self._t = X[:, 0] if not X.shape[1] == 2: raise ValueError('Input matrix for ode1 covariance should have two columns, one containing times, the other output indices') - self._index = np.asarray(X[:, 1],dtype=np.int) + self._index = np.asarray(X[:, 1],dtype=int) # Sort indices so that outputs are in blocks for computational # convenience. self._order = self._index.argsort() @@ -220,7 +220,7 @@ class Eq_ode1(Kernpart): if not X2.shape[1] == 2: raise ValueError('Input matrix for ode1 covariance should have two columns, one containing times, the other output indices') self._t2 = X2[:, 0] - self._index2 = np.asarray(X2[:, 1],dtype=np.int) + self._index2 = np.asarray(X2[:, 1],dtype=int) self._order2 = self._index2.argsort() self._index2 = self._index2[self._order2] self._t2 = self._t2[self._order2] diff --git a/GPy/models/sparse_gp_coregionalized_regression.py b/GPy/models/sparse_gp_coregionalized_regression.py index 2a19d52c..43e782bf 100644 --- a/GPy/models/sparse_gp_coregionalized_regression.py +++ b/GPy/models/sparse_gp_coregionalized_regression.py @@ -7,6 +7,7 @@ from ..inference.latent_function_inference import VarDTC from .. import kern from .. import util + class SparseGPCoregionalizedRegression(SparseGP): """ Sparse Gaussian Process model for heteroscedastic multioutput regression @@ -34,34 +35,65 @@ class SparseGPCoregionalizedRegression(SparseGP): :type kernel_name: string """ - def __init__(self, X_list, Y_list, Z_list=[], kernel=None, likelihoods_list=None, num_inducing=10, X_variance=None, name='SGPCR',W_rank=1,kernel_name='coreg'): - - #Input and Output - X,Y,self.output_index = util.multioutput.build_XY(X_list,Y_list) + def __init__( + self, + X_list, + Y_list, + Z_list=[], + kernel=None, + likelihoods_list=None, + num_inducing=10, + X_variance=None, + name="SGPCR", + W_rank=1, + kernel_name="coreg", + ): + # Input and Output + X, Y, self.output_index = util.multioutput.build_XY(X_list, Y_list) Ny = len(Y_list) - #Kernel + # Kernel if kernel is None: - kernel = kern.RBF(X.shape[1]-1) - - kernel = util.multioutput.ICM(input_dim=X.shape[1]-1, num_outputs=Ny, kernel=kernel, W_rank=W_rank, name=kernel_name) + kernel = kern.RBF(X.shape[1] - 1) - #Likelihood - likelihood = util.multioutput.build_likelihood(Y_list,self.output_index,likelihoods_list) + kernel = util.multioutput.ICM( + input_dim=X.shape[1] - 1, + num_outputs=Ny, + kernel=kernel, + W_rank=W_rank, + name=kernel_name, + ) - #Inducing inputs list + # Likelihood + likelihood = util.multioutput.build_likelihood( + Y_list, self.output_index, likelihoods_list + ) + + # Inducing inputs list if len(Z_list): - assert len(Z_list) == Ny, 'Number of outputs do not match length of inducing inputs list.' + assert ( + len(Z_list) == Ny + ), "Number of outputs do not match length of inducing inputs list." else: - if isinstance(num_inducing,np.int): + if isinstance(num_inducing, int): num_inducing = [num_inducing] * Ny num_inducing = np.asarray(num_inducing) - assert num_inducing.size == Ny, 'Number of outputs do not match length of inducing inputs list.' - for ni,Xi in zip(num_inducing,X_list): + assert ( + num_inducing.size == Ny + ), "Number of outputs do not match length of inducing inputs list." + for ni, Xi in zip(num_inducing, X_list): i = np.random.permutation(Xi.shape[0])[:ni] Z_list.append(Xi[i].copy()) Z, _, Iz = util.multioutput.build_XY(Z_list) - super(SparseGPCoregionalizedRegression, self).__init__(X, Y, Z, kernel, likelihood, inference_method=VarDTC(), Y_metadata={'output_index':self.output_index}) - self['.*inducing'][:,-1].fix() + super(SparseGPCoregionalizedRegression, self).__init__( + X, + Y, + Z, + kernel, + likelihood, + inference_method=VarDTC(), + Y_metadata={"output_index": self.output_index}, + ) + self[".*inducing"][:, -1].fix() diff --git a/GPy/models/ss_mrd.py b/GPy/models/ss_mrd.py index 0aa472c7..c4dbec78 100644 --- a/GPy/models/ss_mrd.py +++ b/GPy/models/ss_mrd.py @@ -5,52 +5,110 @@ The Maniforld Relevance Determination model with the spike-and-slab prior import numpy as np from ..core import Model from .ss_gplvm import SSGPLVM -from GPy.core.parameterization.variational import SpikeAndSlabPrior,NormalPosterior,VariationalPrior +from GPy.core.parameterization.variational import ( + SpikeAndSlabPrior, + NormalPosterior, + VariationalPrior, +) from ..util.misc import param_to_array from ..kern import RBF from ..core import Param from numpy.linalg.linalg import LinAlgError + class SSMRD(Model): - - def __init__(self, Ylist, input_dim, X=None, X_variance=None, Gammas=None, initx = 'PCA_concat', initz = 'permute', - num_inducing=10, Zs=None, kernels=None, inference_methods=None, likelihoods=None, group_spike=True, - pi=0.5, name='ss_mrd', Ynames=None, mpi_comm=None, IBP=False, alpha=2., taus=None, ): + def __init__( + self, + Ylist, + input_dim, + X=None, + X_variance=None, + Gammas=None, + initx="PCA_concat", + initz="permute", + num_inducing=10, + Zs=None, + kernels=None, + inference_methods=None, + likelihoods=None, + group_spike=True, + pi=0.5, + name="ss_mrd", + Ynames=None, + mpi_comm=None, + IBP=False, + alpha=2.0, + taus=None, + ): super(SSMRD, self).__init__(name) self.mpi_comm = mpi_comm self._PROPAGATE_ = False - + # initialize X for individual models - X, X_variance, Gammas, fracs = self._init_X(Ylist, input_dim, X, X_variance, Gammas, initx) + X, X_variance, Gammas, fracs = self._init_X( + Ylist, input_dim, X, X_variance, Gammas, initx + ) self.X = NormalPosterior(means=X, variances=X_variance) - + if kernels is None: - kernels = [RBF(input_dim, lengthscale=1./fracs, ARD=True) for i in range(len(Ylist))] + kernels = [ + RBF(input_dim, lengthscale=1.0 / fracs, ARD=True) + for i in range(len(Ylist)) + ] if Zs is None: - Zs = [None]* len(Ylist) + Zs = [None] * len(Ylist) if likelihoods is None: - likelihoods = [None]* len(Ylist) + likelihoods = [None] * len(Ylist) if inference_methods is None: - inference_methods = [None]* len(Ylist) - + inference_methods = [None] * len(Ylist) + if IBP: - self.var_priors = [IBPPrior_SSMRD(len(Ylist),input_dim,alpha=alpha) for i in range(len(Ylist))] + self.var_priors = [ + IBPPrior_SSMRD(len(Ylist), input_dim, alpha=alpha) + for i in range(len(Ylist)) + ] else: - self.var_priors = [SpikeAndSlabPrior_SSMRD(nModels=len(Ylist),pi=pi,learnPi=False, group_spike=group_spike) for i in range(len(Ylist))] - self.models = [SSGPLVM(y, input_dim, X=X.copy(), X_variance=X_variance.copy(), Gamma=Gammas[i], num_inducing=num_inducing,Z=Zs[i], learnPi=False, group_spike=group_spike, - kernel=kernels[i],inference_method=inference_methods[i],likelihood=likelihoods[i], variational_prior=self.var_priors[i], IBP=IBP, tau=None if taus is None else taus[i], - name='model_'+str(i), mpi_comm=mpi_comm, sharedX=True) for i,y in enumerate(Ylist)] - self.link_parameters(*(self.models+[self.X])) - + self.var_priors = [ + SpikeAndSlabPrior_SSMRD( + nModels=len(Ylist), pi=pi, learnPi=False, group_spike=group_spike + ) + for i in range(len(Ylist)) + ] + self.models = [ + SSGPLVM( + y, + input_dim, + X=X.copy(), + X_variance=X_variance.copy(), + Gamma=Gammas[i], + num_inducing=num_inducing, + Z=Zs[i], + learnPi=False, + group_spike=group_spike, + kernel=kernels[i], + inference_method=inference_methods[i], + likelihood=likelihoods[i], + variational_prior=self.var_priors[i], + IBP=IBP, + tau=None if taus is None else taus[i], + name="model_" + str(i), + mpi_comm=mpi_comm, + sharedX=True, + ) + for i, y in enumerate(Ylist) + ] + self.link_parameters(*(self.models + [self.X])) + def _propogate_X_val(self): - if self._PROPAGATE_: return + if self._PROPAGATE_: + return for m in self.models: m.X.mean.values[:] = self.X.mean.values m.X.variance.values[:] = self.X.variance.values varp_list = [m.X for m in self.models] [vp._update_inernal(varp_list) for vp in self.var_priors] - self._PROPAGATE_=True - + self._PROPAGATE_ = True + def _collate_X_gradient(self): self._PROPAGATE_ = False self.X.mean.gradient[:] = 0 @@ -58,86 +116,92 @@ class SSMRD(Model): for m in self.models: self.X.mean.gradient += m.X.mean.gradient self.X.variance.gradient += m.X.variance.gradient - + def parameters_changed(self): super(SSMRD, self).parameters_changed() [m.parameters_changed() for m in self.models] - self._log_marginal_likelihood = sum([m._log_marginal_likelihood for m in self.models]) + self._log_marginal_likelihood = sum( + [m._log_marginal_likelihood for m in self.models] + ) self._collate_X_gradient() def log_likelihood(self): return self._log_marginal_likelihood - - def _init_X(self, Ylist, input_dim, X=None, X_variance=None, Gammas=None, initx='PCA_concat'): - + + def _init_X( + self, Ylist, input_dim, X=None, X_variance=None, Gammas=None, initx="PCA_concat" + ): # Divide latent dimensions - idx = np.empty((input_dim,),dtype=np.int) - residue = (input_dim)%(len(Ylist)) + idx = np.empty((input_dim,), dtype=int) + residue = (input_dim) % (len(Ylist)) for i in range(len(Ylist)): if i < residue: - size = input_dim/len(Ylist)+1 - idx[i*size:(i+1)*size] = i + size = input_dim / len(Ylist) + 1 + idx[i * size : (i + 1) * size] = i else: - size = input_dim/len(Ylist) - idx[i*size+residue:(i+1)*size+residue] = i - + size = input_dim / len(Ylist) + idx[i * size + residue : (i + 1) * size + residue] = i + if X is None: - if initx == 'PCA_concat': - X = np.empty((Ylist[0].shape[0],input_dim)) + if initx == "PCA_concat": + X = np.empty((Ylist[0].shape[0], input_dim)) fracs = np.empty((input_dim,)) from ..util.initialization import initialize_latent + for i in range(len(Ylist)): Y = Ylist[i] - dim = (idx==i).sum() - if dim>0: - x, fr = initialize_latent('PCA', dim, Y) - X[:,idx==i] = x - fracs[idx==i] = fr - elif initx=='PCA_joint': + dim = (idx == i).sum() + if dim > 0: + x, fr = initialize_latent("PCA", dim, Y) + X[:, idx == i] = x + fracs[idx == i] = fr + elif initx == "PCA_joint": y = np.hstack(Ylist) from ..util.initialization import initialize_latent - X, fracs = initialize_latent('PCA', input_dim, y) + + X, fracs = initialize_latent("PCA", input_dim, y) else: X = np.random.randn(Ylist[0].shape[0], input_dim) fracs = np.ones(input_dim) else: fracs = np.ones(input_dim) - - - if X_variance is None: # The variance of the variational approximation (S) - X_variance = np.random.uniform(0,.1,X.shape) - + + if X_variance is None: # The variance of the variational approximation (S) + X_variance = np.random.uniform(0, 0.1, X.shape) + if Gammas is None: Gammas = [] for x in X: - gamma = np.empty_like(X) # The posterior probabilities of the binary variable in the variational approximation + gamma = np.empty_like( + X + ) # The posterior probabilities of the binary variable in the variational approximation gamma[:] = 0.5 + 0.1 * np.random.randn(X.shape[0], input_dim) - gamma[gamma>1.-1e-9] = 1.-1e-9 - gamma[gamma<1e-9] = 1e-9 + gamma[gamma > 1.0 - 1e-9] = 1.0 - 1e-9 + gamma[gamma < 1e-9] = 1e-9 Gammas.append(gamma) return X, X_variance, Gammas, fracs @Model.optimizer_array.setter def optimizer_array(self, p): if self.mpi_comm != None: - if self._IN_OPTIMIZATION_ and self.mpi_comm.rank==0: - self.mpi_comm.Bcast(np.int32(1),root=0) - self.mpi_comm.Bcast(p, root=0) - Model.optimizer_array.fset(self,p) - + if self._IN_OPTIMIZATION_ and self.mpi_comm.rank == 0: + self.mpi_comm.Bcast(np.int32(1), root=0) + self.mpi_comm.Bcast(p, root=0) + Model.optimizer_array.fset(self, p) + def optimize(self, optimizer=None, start=None, **kwargs): self._IN_OPTIMIZATION_ = True - if self.mpi_comm==None: - super(SSMRD, self).optimize(optimizer,start,**kwargs) - elif self.mpi_comm.rank==0: - super(SSMRD, self).optimize(optimizer,start,**kwargs) - self.mpi_comm.Bcast(np.int32(-1),root=0) - elif self.mpi_comm.rank>0: + if self.mpi_comm == None: + super(SSMRD, self).optimize(optimizer, start, **kwargs) + elif self.mpi_comm.rank == 0: + super(SSMRD, self).optimize(optimizer, start, **kwargs) + self.mpi_comm.Bcast(np.int32(-1), root=0) + elif self.mpi_comm.rank > 0: x = self.optimizer_array.copy() - flag = np.empty(1,dtype=np.int32) + flag = np.empty(1, dtype=np.int32) while True: - self.mpi_comm.Bcast(flag,root=0) - if flag==1: + self.mpi_comm.Bcast(flag, root=0) + if flag == 1: try: self.optimizer_array = x self._fail_count = 0 @@ -145,29 +209,51 @@ class SSMRD(Model): if self._fail_count >= self._allowed_failures: raise self._fail_count += 1 - elif flag==-1: + elif flag == -1: break else: self._IN_OPTIMIZATION_ = False raise Exception("Unrecognizable flag for synchronization!") self._IN_OPTIMIZATION_ = False - + class SpikeAndSlabPrior_SSMRD(SpikeAndSlabPrior): - def __init__(self, nModels, pi=0.5, learnPi=False, group_spike=True, variance = 1.0, name='SSMRDPrior', **kw): + def __init__( + self, + nModels, + pi=0.5, + learnPi=False, + group_spike=True, + variance=1.0, + name="SSMRDPrior", + **kw + ): self.nModels = nModels self._b_prob_all = 0.5 - super(SpikeAndSlabPrior_SSMRD, self).__init__(pi=pi,learnPi=learnPi,group_spike=group_spike,variance=variance, name=name, **kw) - + super(SpikeAndSlabPrior_SSMRD, self).__init__( + pi=pi, + learnPi=learnPi, + group_spike=group_spike, + variance=variance, + name=name, + **kw + ) + def _update_inernal(self, varp_list): """Make an update of the internal status by gathering the variational posteriors for all the individual models.""" # The probability for the binary variable for the same latent dimension of any of the models is on. if self.group_spike: - self._b_prob_all = 1.-param_to_array(varp_list[0].gamma_group) - [np.multiply(self._b_prob_all, 1.-vp.gamma_group, self._b_prob_all) for vp in varp_list[1:]] + self._b_prob_all = 1.0 - param_to_array(varp_list[0].gamma_group) + [ + np.multiply(self._b_prob_all, 1.0 - vp.gamma_group, self._b_prob_all) + for vp in varp_list[1:] + ] else: - self._b_prob_all = 1.-param_to_array(varp_list[0].binary_prob) - [np.multiply(self._b_prob_all, 1.-vp.binary_prob, self._b_prob_all) for vp in varp_list[1:]] + self._b_prob_all = 1.0 - param_to_array(varp_list[0].binary_prob) + [ + np.multiply(self._b_prob_all, 1.0 - vp.binary_prob, self._b_prob_all) + for vp in varp_list[1:] + ] def KL_divergence(self, variational_posterior): mu = variational_posterior.mean @@ -176,16 +262,20 @@ class SpikeAndSlabPrior_SSMRD(SpikeAndSlabPrior): gamma = variational_posterior.binary_prob[0] else: gamma = variational_posterior.binary_prob - if len(self.pi.shape)==2: - idx = np.unique(gamma._raveled_index()/gamma.shape[-1]) + if len(self.pi.shape) == 2: + idx = np.unique(gamma._raveled_index() / gamma.shape[-1]) pi = self.pi[idx] else: pi = self.pi - var_mean = np.square(mu)/self.variance - var_S = (S/self.variance - np.log(S)) - var_gamma = (gamma*np.log(gamma/pi)).sum()+((1-gamma)*np.log((1-gamma)/(1-pi))).sum() - return var_gamma +((1.-self._b_prob_all)*(np.log(self.variance)-1. +var_mean + var_S)).sum()/(2.*self.nModels) + var_mean = np.square(mu) / self.variance + var_S = S / self.variance - np.log(S) + var_gamma = (gamma * np.log(gamma / pi)).sum() + ( + (1 - gamma) * np.log((1 - gamma) / (1 - pi)) + ).sum() + return var_gamma + ( + (1.0 - self._b_prob_all) * (np.log(self.variance) - 1.0 + var_mean + var_S) + ).sum() / (2.0 * self.nModels) def update_gradients_KL(self, variational_posterior): mu = variational_posterior.mean @@ -195,63 +285,141 @@ class SpikeAndSlabPrior_SSMRD(SpikeAndSlabPrior): gamma = variational_posterior.binary_prob.values[0] else: gamma = variational_posterior.binary_prob.values - if len(self.pi.shape)==2: - idx = np.unique(gamma._raveled_index()/gamma.shape[-1]) + if len(self.pi.shape) == 2: + idx = np.unique(gamma._raveled_index() / gamma.shape[-1]) pi = self.pi[idx] else: pi = self.pi if self.group_spike: - tmp = self._b_prob_all/(1.-gamma) - variational_posterior.binary_prob.gradient -= np.log((1-pi)/pi*gamma/(1.-gamma))/N +tmp*((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2. + tmp = self._b_prob_all / (1.0 - gamma) + variational_posterior.binary_prob.gradient -= ( + np.log((1 - pi) / pi * gamma / (1.0 - gamma)) / N + + tmp + * ( + (np.square(mu) + S) / self.variance + - np.log(S) + + np.log(self.variance) + - 1.0 + ) + / 2.0 + ) else: - variational_posterior.binary_prob.gradient -= np.log((1-pi)/pi*gamma/(1.-gamma))+((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2. - mu.gradient -= (1.-self._b_prob_all)*mu/(self.variance*self.nModels) - S.gradient -= (1./self.variance - 1./S) * (1.-self._b_prob_all) /(2.*self.nModels) + variational_posterior.binary_prob.gradient -= ( + np.log((1 - pi) / pi * gamma / (1.0 - gamma)) + + ( + (np.square(mu) + S) / self.variance + - np.log(S) + + np.log(self.variance) + - 1.0 + ) + / 2.0 + ) + mu.gradient -= (1.0 - self._b_prob_all) * mu / (self.variance * self.nModels) + S.gradient -= ( + (1.0 / self.variance - 1.0 / S) + * (1.0 - self._b_prob_all) + / (2.0 * self.nModels) + ) if self.learnPi: - raise 'Not Supported!' + raise "Not Supported!" + class IBPPrior_SSMRD(VariationalPrior): - def __init__(self, nModels, input_dim, alpha =2., tau=None, name='IBPPrior', **kw): + def __init__(self, nModels, input_dim, alpha=2.0, tau=None, name="IBPPrior", **kw): super(IBPPrior_SSMRD, self).__init__(name=name, **kw) - from paramz.transformations import Logexp, __fixed__ + from paramz.transformations import Logexp, __fixed__ + self.nModels = nModels self._b_prob_all = 0.5 self.input_dim = input_dim - self.variance = 1. - self.alpha = Param('alpha', alpha, __fixed__) + self.variance = 1.0 + self.alpha = Param("alpha", alpha, __fixed__) self.link_parameter(self.alpha) - + def _update_inernal(self, varp_list): """Make an update of the internal status by gathering the variational posteriors for all the individual models.""" # The probability for the binary variable for the same latent dimension of any of the models is on. - self._b_prob_all = 1.-param_to_array(varp_list[0].gamma_group) - [np.multiply(self._b_prob_all, 1.-vp.gamma_group, self._b_prob_all) for vp in varp_list[1:]] + self._b_prob_all = 1.0 - param_to_array(varp_list[0].gamma_group) + [ + np.multiply(self._b_prob_all, 1.0 - vp.gamma_group, self._b_prob_all) + for vp in varp_list[1:] + ] def KL_divergence(self, variational_posterior): - mu, S, gamma, tau = variational_posterior.mean.values, variational_posterior.variance.values, variational_posterior.gamma_group.values, variational_posterior.tau.values - - var_mean = np.square(mu)/self.variance - var_S = (S/self.variance - np.log(S)) - part1 = ((1.-self._b_prob_all)* (np.log(self.variance)-1. +var_mean + var_S)).sum()/(2.*self.nModels) - - ad = self.alpha/self.input_dim - from scipy.special import betaln,digamma - part2 = (gamma*np.log(gamma)).sum() + ((1.-gamma)*np.log(1.-gamma)).sum() + (betaln(ad,1.)*self.input_dim -betaln(tau[:,0], tau[:,1]).sum())/self.nModels \ - + (( (tau[:,0]-ad)/self.nModels -gamma)*digamma(tau[:,0])).sum() + \ - (((tau[:,1]-1.)/self.nModels+gamma-1.)*digamma(tau[:,1])).sum() + (((1.+ad-tau[:,0]-tau[:,1])/self.nModels+1.)*digamma(tau.sum(axis=1))).sum() - return part1+part2 + mu, S, gamma, tau = ( + variational_posterior.mean.values, + variational_posterior.variance.values, + variational_posterior.gamma_group.values, + variational_posterior.tau.values, + ) + + var_mean = np.square(mu) / self.variance + var_S = S / self.variance - np.log(S) + part1 = ( + (1.0 - self._b_prob_all) * (np.log(self.variance) - 1.0 + var_mean + var_S) + ).sum() / (2.0 * self.nModels) + + ad = self.alpha / self.input_dim + from scipy.special import betaln, digamma + + part2 = ( + (gamma * np.log(gamma)).sum() + + ((1.0 - gamma) * np.log(1.0 - gamma)).sum() + + (betaln(ad, 1.0) * self.input_dim - betaln(tau[:, 0], tau[:, 1]).sum()) + / self.nModels + + (((tau[:, 0] - ad) / self.nModels - gamma) * digamma(tau[:, 0])).sum() + + ( + ((tau[:, 1] - 1.0) / self.nModels + gamma - 1.0) * digamma(tau[:, 1]) + ).sum() + + ( + ((1.0 + ad - tau[:, 0] - tau[:, 1]) / self.nModels + 1.0) + * digamma(tau.sum(axis=1)) + ).sum() + ) + return part1 + part2 def update_gradients_KL(self, variational_posterior): - mu, S, gamma, tau = variational_posterior.mean.values, variational_posterior.variance.values, variational_posterior.gamma_group.values, variational_posterior.tau.values + mu, S, gamma, tau = ( + variational_posterior.mean.values, + variational_posterior.variance.values, + variational_posterior.gamma_group.values, + variational_posterior.tau.values, + ) - variational_posterior.mean.gradient -= (1.-self._b_prob_all)*mu/(self.variance*self.nModels) - variational_posterior.variance.gradient -= (1./self.variance - 1./S) * (1.-self._b_prob_all) /(2.*self.nModels) - from scipy.special import digamma,polygamma - tmp = self._b_prob_all/(1.-gamma) - dgamma = (np.log(gamma/(1.-gamma))+ digamma(tau[:,1])-digamma(tau[:,0]))/variational_posterior.num_data - variational_posterior.binary_prob.gradient -= dgamma+tmp*((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2. - ad = self.alpha/self.input_dim - common = ((1.+ad-tau[:,0]-tau[:,1])/self.nModels+1.)*polygamma(1,tau.sum(axis=1)) - variational_posterior.tau.gradient[:,0] = -(((tau[:,0]-ad)/self.nModels -gamma)*polygamma(1,tau[:,0])+common) - variational_posterior.tau.gradient[:,1] = -(((tau[:,1]-1.)/self.nModels+gamma-1.)*polygamma(1,tau[:,1])+common) + variational_posterior.mean.gradient -= ( + (1.0 - self._b_prob_all) * mu / (self.variance * self.nModels) + ) + variational_posterior.variance.gradient -= ( + (1.0 / self.variance - 1.0 / S) + * (1.0 - self._b_prob_all) + / (2.0 * self.nModels) + ) + from scipy.special import digamma, polygamma + + tmp = self._b_prob_all / (1.0 - gamma) + dgamma = ( + np.log(gamma / (1.0 - gamma)) + digamma(tau[:, 1]) - digamma(tau[:, 0]) + ) / variational_posterior.num_data + variational_posterior.binary_prob.gradient -= ( + dgamma + + tmp + * ( + (np.square(mu) + S) / self.variance + - np.log(S) + + np.log(self.variance) + - 1.0 + ) + / 2.0 + ) + ad = self.alpha / self.input_dim + common = ((1.0 + ad - tau[:, 0] - tau[:, 1]) / self.nModels + 1.0) * polygamma( + 1, tau.sum(axis=1) + ) + variational_posterior.tau.gradient[:, 0] = -( + ((tau[:, 0] - ad) / self.nModels - gamma) * polygamma(1, tau[:, 0]) + common + ) + variational_posterior.tau.gradient[:, 1] = -( + ((tau[:, 1] - 1.0) / self.nModels + gamma - 1.0) * polygamma(1, tau[:, 1]) + + common + ) diff --git a/GPy/models/state_space_main.py b/GPy/models/state_space_main.py index 6ed2fbeb..fb6693ec 100644 --- a/GPy/models/state_space_main.py +++ b/GPy/models/state_space_main.py @@ -16,6 +16,7 @@ import warnings try: from . import state_space_setup + setup_available = True except ImportError as e: setup_available = False @@ -25,13 +26,14 @@ print_verbose = False try: import state_space_cython + cython_code_available = True if print_verbose: print("state_space: cython is available") except ImportError as e: cython_code_available = False -#cython_code_available = False +# cython_code_available = False # Use cython by default use_cython = False if setup_available: @@ -49,7 +51,6 @@ tmp_buffer = None class Dynamic_Callables_Python(object): - def f_a(self, k, m, A): """ p_a: function (k, x_{k-1}, A_{k}). Dynamic function. @@ -113,6 +114,7 @@ class Dynamic_Callables_Python(object): raise NotImplemented("reset is not implemented!") + if use_cython: Dynamic_Callables_Class = state_space_cython.Dynamic_Callables_Cython else: @@ -183,9 +185,9 @@ class Measurement_Callables_Python(object): raise NotImplemented("reset is not implemented!") + if use_cython: - Measurement_Callables_Class = state_space_cython.\ - Measurement_Callables_Cython + Measurement_Callables_Class = state_space_cython.Measurement_Callables_Cython else: Measurement_Callables_Class = Measurement_Callables_Python @@ -194,6 +196,7 @@ class R_handling_Python(Measurement_Callables_Class): """ The calss handles noise matrix R. """ + def __init__(self, R, index, R_time_var_index, unique_R_number, dR=None): """ Input: @@ -225,7 +228,7 @@ class R_handling_Python(Measurement_Callables_Class): self.R_time_var_index = int(R_time_var_index) self.dR = dR - if (len(np.unique(index)) > unique_R_number): + if len(np.unique(index)) > unique_R_number: self.svd_each_time = True else: self.svd_each_time = False @@ -248,32 +251,39 @@ class R_handling_Python(Measurement_Callables_Class): ind = int(self.index[self.R_time_var_index, k]) R = self.R[:, :, ind] - if (R.shape[0] == 1): # 1-D case handle simplier. No storage + if R.shape[0] == 1: # 1-D case handle simplier. No storage # of the result, just compute it each time. - inv_square_root = np.sqrt(1.0/R) + inv_square_root = np.sqrt(1.0 / R) else: if self.svd_each_time: + (U, S, Vh) = sp.linalg.svd( + R, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) - (U, S, Vh) = sp.linalg.svd(R, full_matrices=False, - compute_uv=True, overwrite_a=False, - check_finite=True) - - inv_square_root = U * 1.0/np.sqrt(S) + inv_square_root = U * 1.0 / np.sqrt(S) else: if ind in self.R_square_root: inv_square_root = self.R_square_root[ind] else: - (U, S, Vh) = sp.linalg.svd(R, full_matrices=False, - compute_uv=True, - overwrite_a=False, - check_finite=True) + (U, S, Vh) = sp.linalg.svd( + R, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) - inv_square_root = U * 1.0/np.sqrt(S) + inv_square_root = U * 1.0 / np.sqrt(S) self.R_square_root[ind] = inv_square_root return inv_square_root + if use_cython: R_handling_Class = state_space_cython.R_handling_Cython else: @@ -281,11 +291,20 @@ else: class Std_Measurement_Callables_Python(R_handling_Class): - - def __init__(self, H, H_time_var_index, R, index, R_time_var_index, - unique_R_number, dH=None, dR=None): - super(Std_Measurement_Callables_Python, - self).__init__(R, index, R_time_var_index, unique_R_number, dR) + def __init__( + self, + H, + H_time_var_index, + R, + index, + R_time_var_index, + unique_R_number, + dH=None, + dR=None, + ): + super(Std_Measurement_Callables_Python, self).__init__( + R, index, R_time_var_index, unique_R_number, dR + ) self.H = H self.H_time_var_index = int(H_time_var_index) @@ -319,15 +338,16 @@ class Std_Measurement_Callables_Python(R_handling_Class): return self.dH # the same dirivative on each iteration + if use_cython: - Std_Measurement_Callables_Class = state_space_cython.\ - Std_Measurement_Callables_Cython + Std_Measurement_Callables_Class = ( + state_space_cython.Std_Measurement_Callables_Cython + ) else: Std_Measurement_Callables_Class = Std_Measurement_Callables_Python class Q_handling_Python(Dynamic_Callables_Class): - def __init__(self, Q, index, Q_time_var_index, unique_Q_number, dQ=None): """ Input: @@ -360,7 +380,7 @@ class Q_handling_Python(Dynamic_Callables_Class): self.Q_time_var_index = Q_time_var_index self.dQ = dQ - if (len(np.unique(index)) > unique_Q_number): + if len(np.unique(index)) > unique_Q_number: self.svd_each_time = True else: self.svd_each_time = False @@ -391,27 +411,31 @@ class Q_handling_Python(Dynamic_Callables_Class): ind = self.index[self.Q_time_var_index, k] Q = self.Q[:, :, ind] - if (Q.shape[0] == 1): # 1-D case handle simplier. No storage + if Q.shape[0] == 1: # 1-D case handle simplier. No storage # of the result, just compute it each time. square_root = np.sqrt(Q) else: if self.svd_each_time: - - (U, S, Vh) = sp.linalg.svd(Q, full_matrices=False, - compute_uv=True, - overwrite_a=False, - check_finite=True) + (U, S, Vh) = sp.linalg.svd( + Q, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) square_root = U * np.sqrt(S) else: - if ind in self.Q_square_root: square_root = self.Q_square_root[ind] else: - (U, S, Vh) = sp.linalg.svd(Q, full_matrices=False, - compute_uv=True, - overwrite_a=False, - check_finite=True) + (U, S, Vh) = sp.linalg.svd( + Q, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) square_root = U * np.sqrt(S) @@ -419,6 +443,7 @@ class Q_handling_Python(Dynamic_Callables_Class): return square_root + if use_cython: Q_handling_Class = state_space_cython.Q_handling_Cython else: @@ -426,11 +451,20 @@ else: class Std_Dynamic_Callables_Python(Q_handling_Class): - - def __init__(self, A, A_time_var_index, Q, index, Q_time_var_index, - unique_Q_number, dA=None, dQ=None): - super(Std_Dynamic_Callables_Python, - self).__init__(Q, index, Q_time_var_index, unique_Q_number, dQ) + def __init__( + self, + A, + A_time_var_index, + Q, + index, + Q_time_var_index, + unique_Q_number, + dA=None, + dQ=None, + ): + super(Std_Dynamic_Callables_Python, self).__init__( + Q, index, Q_time_var_index, unique_Q_number, dQ + ) self.A = A self.A_time_var_index = np.asarray(A_time_var_index, np.int_) @@ -438,11 +472,11 @@ class Std_Dynamic_Callables_Python(Q_handling_Class): def f_a(self, k, m, A): """ - f_a: function (k, x_{k-1}, A_{k}). Dynamic function. - k (iteration number), starts at 0 - x_{k-1} State from the previous step - A_{k} Jacobian matrices of f_a. In the linear case it is exactly - A_{k}. + f_a: function (k, x_{k-1}, A_{k}). Dynamic function. + k (iteration number), starts at 0 + x_{k-1} State from the previous step + A_{k} Jacobian matrices of f_a. In the linear case it is exactly + A_{k}. """ return np.dot(A, m) @@ -471,16 +505,15 @@ class Std_Dynamic_Callables_Python(Q_handling_Class): return self + if use_cython: - Std_Dynamic_Callables_Class = state_space_cython.\ - Std_Dynamic_Callables_Cython + Std_Dynamic_Callables_Class = state_space_cython.Std_Dynamic_Callables_Cython else: Std_Dynamic_Callables_Class = Std_Dynamic_Callables_Python class AddMethodToClass(object): - - def __init__(self, func=None, tp='staticmethod'): + def __init__(self, func=None, tp="staticmethod"): """ Input: -------------- @@ -495,16 +528,18 @@ class AddMethodToClass(object): self.tp = tp def __get__(self, obj, klass=None, *args, **kwargs): - - if self.tp == 'staticmethod': + if self.tp == "staticmethod": return self.func - elif self.tp == 'normal': + elif self.tp == "normal": + def newfunc(obj, *args, **kwargs): return self.func - elif self.tp == 'classmethod': + elif self.tp == "classmethod": + def newfunc(klass, *args, **kwargs): return self.func + return newfunc @@ -519,23 +554,24 @@ class DescreteStateSpaceMeta(type): """ if use_cython: - if '_kalman_prediction_step_SVD' in attributes: - attributes['_kalman_prediction_step_SVD'] =\ - AddMethodToClass(state_space_cython. - _kalman_prediction_step_SVD_Cython) + if "_kalman_prediction_step_SVD" in attributes: + attributes["_kalman_prediction_step_SVD"] = AddMethodToClass( + state_space_cython._kalman_prediction_step_SVD_Cython + ) - if '_kalman_update_step_SVD' in attributes: - attributes['_kalman_update_step_SVD'] =\ - AddMethodToClass(state_space_cython. - _kalman_update_step_SVD_Cython) + if "_kalman_update_step_SVD" in attributes: + attributes["_kalman_update_step_SVD"] = AddMethodToClass( + state_space_cython._kalman_update_step_SVD_Cython + ) - if '_cont_discr_kalman_filter_raw' in attributes: - attributes['_cont_discr_kalman_filter_raw'] =\ - AddMethodToClass(state_space_cython. - _cont_discr_kalman_filter_raw_Cython) + if "_cont_discr_kalman_filter_raw" in attributes: + attributes["_cont_discr_kalman_filter_raw"] = AddMethodToClass( + state_space_cython._cont_discr_kalman_filter_raw_Cython + ) - return super(DescreteStateSpaceMeta, - typeclass).__new__(typeclass, name, bases, attributes) + return super(DescreteStateSpaceMeta, typeclass).__new__( + typeclass, name, bases, attributes + ) class DescreteStateSpace(object): @@ -560,6 +596,7 @@ class DescreteStateSpace(object): implementations are very similar. """ + __metaclass__ = DescreteStateSpaceMeta @staticmethod @@ -586,37 +623,56 @@ class DescreteStateSpace(object): None. """ - if (len(shape) > 3): - raise ValueError("""Input array is not supposed to be more - than 3 dimensional.""") + if len(shape) > 3: + raise ValueError( + """Input array is not supposed to be more + than 3 dimensional.""" + ) - if (len(shape) > desired_dim): + if len(shape) > desired_dim: raise ValueError("Input array shape is more than desired shape.") elif len(shape) == 1: - if (desired_dim == 3): + if desired_dim == 3: return ((shape[0], 1, 1), shape) # last dimension is the # time serime_series_no - elif (desired_dim == 2): + elif desired_dim == 2: return ((shape[0], 1), shape) elif len(shape) == 2: - if (desired_dim == 3): - return ((shape[1], 1, 1), shape) if (shape[0] == 1) else\ - ((shape[0], shape[1], 1), shape) # convert to column - # vector - elif (desired_dim == 2): - return ((shape[1], 1), shape) if (shape[0] == 1) else\ - ((shape[0], shape[1]), None) # convert to column vector + if desired_dim == 3: + return ( + ((shape[1], 1, 1), shape) + if (shape[0] == 1) + else ((shape[0], shape[1], 1), shape) + ) # convert to column + # vector + elif desired_dim == 2: + return ( + ((shape[1], 1), shape) + if (shape[0] == 1) + else ((shape[0], shape[1]), None) + ) # convert to column vector else: # len(shape) == 3 return (shape, None) # do nothing @classmethod - def kalman_filter(cls, p_A, p_Q, p_H, p_R, Y, index=None, m_init=None, - P_init=None, p_kalman_filter_type='regular', - calc_log_likelihood=False, - calc_grad_log_likelihood=False, grad_params_no=None, - grad_calc_params=None): + def kalman_filter( + cls, + p_A, + p_Q, + p_H, + p_R, + Y, + index=None, + m_init=None, + P_init=None, + p_kalman_filter_type="regular", + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + grad_params_no=None, + grad_calc_params=None, + ): """ This function implements the basic Kalman Filter algorithm These notations for the State-Space model are assumed: @@ -743,7 +799,7 @@ class DescreteStateSpace(object): The dictionary contains the same fields. """ - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() # Parameters checking -> # index @@ -753,14 +809,16 @@ class DescreteStateSpace(object): p_R = np.atleast_1d(p_R) # Reshape and check measurements: - Y.shape, old_Y_shape = cls._reshape_input_data(Y.shape) + Y.shape, old_Y_shape = cls._reshape_input_data(Y.shape) measurement_dim = Y.shape[1] - time_series_no = Y.shape[2] # multiple time series mode + time_series_no = Y.shape[2] # multiple time series mode - if ((len(p_A.shape) == 3) and (len(p_A.shape[2]) != 1)) or\ - ((len(p_Q.shape) == 3) and (len(p_Q.shape[2]) != 1)) or\ - ((len(p_H.shape) == 3) and (len(p_H.shape[2]) != 1)) or\ - ((len(p_R.shape) == 3) and (len(p_R.shape[2]) != 1)): + if ( + ((len(p_A.shape) == 3) and (len(p_A.shape[2]) != 1)) + or ((len(p_Q.shape) == 3) and (len(p_Q.shape[2]) != 1)) + or ((len(p_H.shape) == 3) and (len(p_H.shape[2]) != 1)) + or ((len(p_R.shape) == 3) and (len(p_R.shape[2]) != 1)) + ): model_matrices_chage_with_time = True else: model_matrices_chage_with_time = False @@ -768,35 +826,55 @@ class DescreteStateSpace(object): # Check index old_index_shape = None if index is None: - if (len(p_A.shape) == 3) or (len(p_Q.shape) == 3) or\ - (len(p_H.shape) == 3) or (len(p_R.shape) == 3): - raise ValueError("Parameter index can not be None for time varying matrices (third dimension is present)") - else: # matrices do not change in time, so form dummy zero indices. - index = np.zeros((1,Y.shape[0])) + if ( + (len(p_A.shape) == 3) + or (len(p_Q.shape) == 3) + or (len(p_H.shape) == 3) + or (len(p_R.shape) == 3) + ): + raise ValueError( + "Parameter index can not be None for time varying matrices (third dimension is present)" + ) + else: # matrices do not change in time, so form dummy zero indices. + index = np.zeros((1, Y.shape[0])) else: if len(index.shape) == 1: - index.shape = (1,index.shape[0]) + index.shape = (1, index.shape[0]) old_index_shape = (index.shape[0],) - if (index.shape[1] != Y.shape[0]): - raise ValueError("Number of measurements must be equal the number of A_{k}, Q_{k}, H_{k}, R_{k}") + if index.shape[1] != Y.shape[0]: + raise ValueError( + "Number of measurements must be equal the number of A_{k}, Q_{k}, H_{k}, R_{k}" + ) - if (index.shape[0] == 1): - A_time_var_index = 0; Q_time_var_index = 0 - H_time_var_index = 0; R_time_var_index = 0 - elif (index.shape[0] == 4): - A_time_var_index = 0; Q_time_var_index = 1 - H_time_var_index = 2; R_time_var_index = 3 + if index.shape[0] == 1: + A_time_var_index = 0 + Q_time_var_index = 0 + H_time_var_index = 0 + R_time_var_index = 0 + elif index.shape[0] == 4: + A_time_var_index = 0 + Q_time_var_index = 1 + H_time_var_index = 2 + R_time_var_index = 3 else: raise ValueError("First Dimension of index must be either 1 or 4.") state_dim = p_A.shape[0] # Check and make right shape for model matrices. On exit they all are 3 dimensional. Last dimension # correspond to change in time. - (p_A, old_A_shape) = cls._check_SS_matrix(p_A, state_dim, measurement_dim, which='A') - (p_Q, old_Q_shape) = cls._check_SS_matrix(p_Q, state_dim, measurement_dim, which='Q') - (p_H, old_H_shape) = cls._check_SS_matrix(p_H, state_dim, measurement_dim, which='H') - (p_R, old_R_shape) = cls._check_SS_matrix(p_R, state_dim, measurement_dim, which='R') + (p_A, old_A_shape) = cls._check_SS_matrix( + p_A, state_dim, measurement_dim, which="A" + ) + (p_Q, old_Q_shape) = cls._check_SS_matrix( + p_Q, state_dim, measurement_dim, which="Q" + ) + (p_H, old_H_shape) = cls._check_SS_matrix( + p_H, state_dim, measurement_dim, which="H" + ) + (p_R, old_R_shape) = cls._check_SS_matrix( + p_R, state_dim, measurement_dim, which="R" + ) # m_init if m_init is None: @@ -807,10 +885,10 @@ class DescreteStateSpace(object): # P_init if P_init is None: P_init = np.eye(state_dim) - elif not isinstance(P_init, collections.Iterable): #scalar - P_init = P_init*np.eye(state_dim) + elif not isinstance(P_init, collections.Iterable): # scalar + P_init = P_init * np.eye(state_dim) - if p_kalman_filter_type not in ('regular', 'svd'): + if p_kalman_filter_type not in ("regular", "svd"): raise ValueError("Kalman filer type neither 'regular nor 'svd'.") # Functions to pass to the kalman_filter algorithm: @@ -818,27 +896,51 @@ class DescreteStateSpace(object): # k - number of Kalman filter iteration # m - vector for calculating matrices. Required for EKF. Not used here. - c_p_A = p_A.copy() # create a copy because this object is passed to the smoother - c_p_Q = p_Q.copy() # create a copy because this object is passed to the smoother - c_index = index.copy() # create a copy because this object is passed to the smoother + c_p_A = ( + p_A.copy() + ) # create a copy because this object is passed to the smoother + c_p_Q = ( + p_Q.copy() + ) # create a copy because this object is passed to the smoother + c_index = ( + index.copy() + ) # create a copy because this object is passed to the smoother if calc_grad_log_likelihood: if model_matrices_chage_with_time: - raise ValueError("When computing likelihood gradient A and Q can not change over time.") + raise ValueError( + "When computing likelihood gradient A and Q can not change over time." + ) - dA = cls._check_grad_state_matrices(grad_calc_params.get('dA'), state_dim, grad_params_no, which = 'dA') - dQ = cls._check_grad_state_matrices(grad_calc_params.get('dQ'), state_dim, grad_params_no, which = 'dQ') - dH = cls._check_grad_measurement_matrices(grad_calc_params.get('dH'), state_dim, grad_params_no, measurement_dim, which = 'dH') - dR = cls._check_grad_measurement_matrices(grad_calc_params.get('dR'), state_dim, grad_params_no, measurement_dim, which = 'dR') + dA = cls._check_grad_state_matrices( + grad_calc_params.get("dA"), state_dim, grad_params_no, which="dA" + ) + dQ = cls._check_grad_state_matrices( + grad_calc_params.get("dQ"), state_dim, grad_params_no, which="dQ" + ) + dH = cls._check_grad_measurement_matrices( + grad_calc_params.get("dH"), + state_dim, + grad_params_no, + measurement_dim, + which="dH", + ) + dR = cls._check_grad_measurement_matrices( + grad_calc_params.get("dR"), + state_dim, + grad_params_no, + measurement_dim, + which="dR", + ) - dm_init = grad_calc_params.get('dm_init') + dm_init = grad_calc_params.get("dm_init") if dm_init is None: - # multiple time series mode. Keep grad_params always as a last dimension + # multiple time series mode. Keep grad_params always as a last dimension dm_init = np.zeros((state_dim, time_series_no, grad_params_no)) - dP_init = grad_calc_params.get('dP_init') + dP_init = grad_calc_params.get("dP_init") if dP_init is None: - dP_init = np.zeros((state_dim,state_dim,grad_params_no)) + dP_init = np.zeros((state_dim, state_dim, grad_params_no)) else: dA = None dQ = None @@ -847,17 +949,33 @@ class DescreteStateSpace(object): dm_init = None dP_init = None - dynamic_callables = Std_Dynamic_Callables_Class(c_p_A, A_time_var_index, c_p_Q, c_index, Q_time_var_index, 20, dA, dQ) - measurement_callables = Std_Measurement_Callables_Class(p_H, H_time_var_index, p_R, index, R_time_var_index, 20, dH, dR) + dynamic_callables = Std_Dynamic_Callables_Class( + c_p_A, A_time_var_index, c_p_Q, c_index, Q_time_var_index, 20, dA, dQ + ) + measurement_callables = Std_Measurement_Callables_Class( + p_H, H_time_var_index, p_R, index, R_time_var_index, 20, dH, dR + ) - (M, P,log_likelihood, grad_log_likelihood, dynamic_callables) = \ - cls._kalman_algorithm_raw(state_dim, dynamic_callables, - measurement_callables, Y, m_init, - P_init, p_kalman_filter_type = p_kalman_filter_type, - calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, - grad_params_no=grad_params_no, - dm_init=dm_init, dP_init=dP_init) + ( + M, + P, + log_likelihood, + grad_log_likelihood, + dynamic_callables, + ) = cls._kalman_algorithm_raw( + state_dim, + dynamic_callables, + measurement_callables, + Y, + m_init, + P_init, + p_kalman_filter_type=p_kalman_filter_type, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + grad_params_no=grad_params_no, + dm_init=dm_init, + dP_init=dP_init, + ) # restore shapes so that input parameters are unchenged if old_index_shape is not None: @@ -879,12 +997,23 @@ class DescreteStateSpace(object): p_R.shape = old_R_shape # Return values - return (M, P,log_likelihood, grad_log_likelihood, dynamic_callables) + return (M, P, log_likelihood, grad_log_likelihood, dynamic_callables) @classmethod - def extended_kalman_filter(cls,p_state_dim, p_a, p_f_A, p_f_Q, p_h, p_f_H, p_f_R, Y, m_init=None, - P_init=None,calc_log_likelihood=False): - + def extended_kalman_filter( + cls, + p_state_dim, + p_a, + p_f_A, + p_f_Q, + p_h, + p_f_H, + p_f_R, + Y, + m_init=None, + P_init=None, + calc_log_likelihood=False, + ): """ Extended Kalman Filter @@ -954,83 +1083,95 @@ class DescreteStateSpace(object): """ # Y - Y.shape, old_Y_shape = cls._reshape_input_data(Y.shape) + Y.shape, old_Y_shape = cls._reshape_input_data(Y.shape) - # m_init + # m_init if m_init is None: - m_init = np.zeros((p_state_dim,1)) + m_init = np.zeros((p_state_dim, 1)) else: m_init = np.atleast_2d(m_init).T # P_init if P_init is None: P_init = np.eye(p_state_dim) - elif not isinstance(P_init, collections.Iterable): #scalar - P_init = P_init*np.eye(p_state_dim) + elif not isinstance(P_init, collections.Iterable): # scalar + P_init = P_init * np.eye(p_state_dim) if p_a is None: - p_a = lambda k,m,A: np.dot(A, m) + p_a = lambda k, m, A: np.dot(A, m) old_A_shape = None - if not isinstance(p_f_A, types.FunctionType): # not a function but array + if not isinstance(p_f_A, types.FunctionType): # not a function but array p_f_A = np.atleast_1d(p_f_A) (p_A, old_A_shape) = cls._check_A_matrix(p_f_A) - p_f_A = lambda k, m, P: p_A[:,:, 0] # make function + p_f_A = lambda k, m, P: p_A[:, :, 0] # make function else: if p_f_A(1, m_init, P_init).shape[0] != m_init.shape[0]: raise ValueError("p_f_A function returns matrix of wrong size") old_Q_shape = None - if not isinstance(p_f_Q, types.FunctionType): # not a function but array + if not isinstance(p_f_Q, types.FunctionType): # not a function but array p_f_Q = np.atleast_1d(p_f_Q) (p_Q, old_Q_shape) = cls._check_Q_matrix(p_f_Q) - p_f_Q = lambda k: p_Q[:,:, 0] # make function + p_f_Q = lambda k: p_Q[:, :, 0] # make function else: if p_f_Q(1).shape[0] != m_init.shape[0]: raise ValueError("p_f_Q function returns matrix of wrong size") if p_h is None: - lambda k,m,H: np.dot(H, m) + lambda k, m, H: np.dot(H, m) old_H_shape = None - if not isinstance(p_f_H, types.FunctionType): # not a function but array + if not isinstance(p_f_H, types.FunctionType): # not a function but array p_f_H = np.atleast_1d(p_f_H) (p_H, old_H_shape) = cls._check_H_matrix(p_f_H) - p_f_H = lambda k, m, P: p_H # make function + p_f_H = lambda k, m, P: p_H # make function else: if p_f_H(1, m_init, P_init).shape[0] != Y.shape[1]: raise ValueError("p_f_H function returns matrix of wrong size") old_R_shape = None - if not isinstance(p_f_R, types.FunctionType): # not a function but array + if not isinstance(p_f_R, types.FunctionType): # not a function but array p_f_R = np.atleast_1d(p_f_R) (p_R, old_R_shape) = cls._check_H_matrix(p_f_R) - p_f_R = lambda k: p_R # make function + p_f_R = lambda k: p_R # make function else: if p_f_R(1).shape[0] != m_init.shape[0]: raise ValueError("p_f_R function returns matrix of wrong size") -# class dynamic_callables_class(Dynamic_Model_Callables): -# -# Ak = -# Qk = - + # class dynamic_callables_class(Dynamic_Model_Callables): + # + # Ak = + # Qk = class measurement_callables_class(R_handling_Class): - def __init__(self,R, index, R_time_var_index, unique_R_number): - super(measurement_callables_class,self).__init__(R, index, R_time_var_index, unique_R_number) + def __init__(self, R, index, R_time_var_index, unique_R_number): + super(measurement_callables_class, self).__init__( + R, index, R_time_var_index, unique_R_number + ) Hk = AddMethodToClass(f_H) f_h = AddMethodToClass(f_hl) - - (M, P,log_likelihood, grad_log_likelihood) = cls._kalman_algorithm_raw(p_state_dim, p_a, p_f_A, p_f_Q, p_h, p_f_H, p_f_R, Y, m_init, - P_init, calc_log_likelihood, - calc_grad_log_likelihood=False, grad_calc_params=None) + (M, P, log_likelihood, grad_log_likelihood) = cls._kalman_algorithm_raw( + p_state_dim, + p_a, + p_f_A, + p_f_Q, + p_h, + p_f_H, + p_f_R, + Y, + m_init, + P_init, + calc_log_likelihood, + calc_grad_log_likelihood=False, + grad_calc_params=None, + ) if old_Y_shape is not None: Y.shape = old_Y_shape @@ -1050,11 +1191,21 @@ class DescreteStateSpace(object): return (M, P) @classmethod - def _kalman_algorithm_raw(cls,state_dim, p_dynamic_callables, p_measurement_callables, Y, m_init, - P_init, p_kalman_filter_type='regular', - calc_log_likelihood=False, - calc_grad_log_likelihood=False, grad_params_no=None, - dm_init=None, dP_init=None): + def _kalman_algorithm_raw( + cls, + state_dim, + p_dynamic_callables, + p_measurement_callables, + Y, + m_init, + P_init, + p_kalman_filter_type="regular", + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + grad_params_no=None, + dm_init=None, + dP_init=None, + ): """ General nonlinear filtering algorithm for inference in the state-space model: @@ -1166,94 +1317,142 @@ class DescreteStateSpace(object): """ - steps_no = Y.shape[0] # number of steps in the Kalman Filter - time_series_no = Y.shape[2] # multiple time series mode + steps_no = Y.shape[0] # number of steps in the Kalman Filter + time_series_no = Y.shape[2] # multiple time series mode # Allocate space for results # Mean estimations. Initial values will be included - M = np.empty(((steps_no+1),state_dim,time_series_no)) - M[0,:,:] = m_init # Initialize mean values + M = np.empty(((steps_no + 1), state_dim, time_series_no)) + M[0, :, :] = m_init # Initialize mean values # Variance estimations. Initial values will be included - P = np.empty(((steps_no+1),state_dim,state_dim)) - P_init = 0.5*( P_init + P_init.T) # symmetrize initial covariance. In some ustable cases this is uiseful - P[0,:,:] = P_init # Initialize initial covariance matrix + P = np.empty(((steps_no + 1), state_dim, state_dim)) + P_init = 0.5 * ( + P_init + P_init.T + ) # symmetrize initial covariance. In some ustable cases this is uiseful + P[0, :, :] = P_init # Initialize initial covariance matrix - if p_kalman_filter_type == 'svd': - (U,S,Vh) = sp.linalg.svd( P_init,full_matrices=False, compute_uv=True, - overwrite_a=False,check_finite=True) - S[ (S==0) ] = 1e-17 # allows to run algorithm for singular initial variance - P_upd = (P_init, S,U) + if p_kalman_filter_type == "svd": + (U, S, Vh) = sp.linalg.svd( + P_init, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) + S[(S == 0)] = 1e-17 # allows to run algorithm for singular initial variance + P_upd = (P_init, S, U) log_likelihood = 0 if calc_log_likelihood else None grad_log_likelihood = 0 if calc_grad_log_likelihood else None - #setting initial values for derivatives update + # setting initial values for derivatives update dm_upd = dm_init dP_upd = dP_init # Main loop of the Kalman filter - for k in range(0,steps_no): + for k in range(0, steps_no): # In this loop index for new estimations is (k+1), old - (k) # This happened because initial values are stored at 0-th index. - prev_mean = M[k,:,:] # mean from the previous step + prev_mean = M[k, :, :] # mean from the previous step - if p_kalman_filter_type == 'svd': - m_pred, P_pred, dm_pred, dP_pred = \ - cls._kalman_prediction_step_SVD(k, prev_mean ,P_upd, p_dynamic_callables, + if p_kalman_filter_type == "svd": + m_pred, P_pred, dm_pred, dP_pred = cls._kalman_prediction_step_SVD( + k, + prev_mean, + P_upd, + p_dynamic_callables, calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_upd, p_dP = dP_upd) + p_dm=dm_upd, + p_dP=dP_upd, + ) else: - m_pred, P_pred, dm_pred, dP_pred = \ - cls._kalman_prediction_step(k, prev_mean ,P[k,:,:], p_dynamic_callables, + m_pred, P_pred, dm_pred, dP_pred = cls._kalman_prediction_step( + k, + prev_mean, + P[k, :, :], + p_dynamic_callables, calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_upd, p_dP = dP_upd ) + p_dm=dm_upd, + p_dP=dP_upd, + ) - k_measurment = Y[k,:,:] + k_measurment = Y[k, :, :] - if (np.any(np.isnan(k_measurment)) == False): - if p_kalman_filter_type == 'svd': - m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ - cls._kalman_update_step_SVD(k, m_pred , P_pred, p_measurement_callables, - k_measurment, calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_pred, p_dP = dP_pred ) + if np.any(np.isnan(k_measurment)) == False: + if p_kalman_filter_type == "svd": + ( + m_upd, + P_upd, + log_likelihood_update, + dm_upd, + dP_upd, + d_log_likelihood_update, + ) = cls._kalman_update_step_SVD( + k, + m_pred, + P_pred, + p_measurement_callables, + k_measurment, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + p_dm=dm_pred, + p_dP=dP_pred, + ) - - # m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ - # cls._kalman_update_step(k, m_pred , P_pred[0], f_h, f_H, p_R.f_R, k_measurment, - # calc_log_likelihood=calc_log_likelihood, - # calc_grad_log_likelihood=calc_grad_log_likelihood, - # p_dm = dm_pred, p_dP = dP_pred, grad_calc_params_2 = (dH, dR)) - # - # (U,S,Vh) = sp.linalg.svd( P_upd,full_matrices=False, compute_uv=True, - # overwrite_a=False,check_finite=True) - # P_upd = (P_upd, S,U) + # m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ + # cls._kalman_update_step(k, m_pred , P_pred[0], f_h, f_H, p_R.f_R, k_measurment, + # calc_log_likelihood=calc_log_likelihood, + # calc_grad_log_likelihood=calc_grad_log_likelihood, + # p_dm = dm_pred, p_dP = dP_pred, grad_calc_params_2 = (dH, dR)) + # + # (U,S,Vh) = sp.linalg.svd( P_upd,full_matrices=False, compute_uv=True, + # overwrite_a=False,check_finite=True) + # P_upd = (P_upd, S,U) else: - m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ - cls._kalman_update_step(k, m_pred , P_pred, p_measurement_callables, k_measurment, - calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_pred, p_dP = dP_pred ) + ( + m_upd, + P_upd, + log_likelihood_update, + dm_upd, + dP_upd, + d_log_likelihood_update, + ) = cls._kalman_update_step( + k, + m_pred, + P_pred, + p_measurement_callables, + k_measurment, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + p_dm=dm_pred, + p_dP=dP_pred, + ) else: -# if k_measurment.shape != (1,1): -# raise ValueError("Nan measurements are currently not supported for \ -# multidimensional output and multiple time series.") -# else: -# m_upd = m_pred; P_upd = P_pred; dm_upd = dm_pred; dP_upd = dP_pred -# log_likelihood_update = 0.0; -# d_log_likelihood_update = 0.0; + # if k_measurment.shape != (1,1): + # raise ValueError("Nan measurements are currently not supported for \ + # multidimensional output and multiple time series.") + # else: + # m_upd = m_pred; P_upd = P_pred; dm_upd = dm_pred; dP_upd = dP_pred + # log_likelihood_update = 0.0; + # d_log_likelihood_update = 0.0; if not np.all(np.isnan(k_measurment)): - raise ValueError("""Nan measurements are currently not supported if - they are intermixed with not NaN measurements""") + raise ValueError( + """Nan measurements are currently not supported if + they are intermixed with not NaN measurements""" + ) else: - m_upd = m_pred; P_upd = P_pred; dm_upd = dm_pred; dP_upd = dP_pred + m_upd = m_pred + P_upd = P_pred + dm_upd = dm_pred + dP_upd = dP_pred if calc_log_likelihood: log_likelihood_update = np.zeros((time_series_no,)) if calc_grad_log_likelihood: - d_log_likelihood_update = np.zeros((grad_params_no,time_series_no)) - + d_log_likelihood_update = np.zeros( + (grad_params_no, time_series_no) + ) if calc_log_likelihood: log_likelihood += log_likelihood_update @@ -1261,20 +1460,33 @@ class DescreteStateSpace(object): if calc_grad_log_likelihood: grad_log_likelihood += d_log_likelihood_update - M[k+1,:,:] = m_upd # separate mean value for each time series + M[k + 1, :, :] = m_upd # separate mean value for each time series - if p_kalman_filter_type == 'svd': - P[k+1,:,:] = P_upd[0] + if p_kalman_filter_type == "svd": + P[k + 1, :, :] = P_upd[0] else: - P[k+1,:,:] = P_upd + P[k + 1, :, :] = P_upd # !!!Print statistics! Print sizes of matrices # !!!Print statistics! Print iteration time base on another boolean variable - return (M, P, log_likelihood, grad_log_likelihood, p_dynamic_callables.reset(False)) + return ( + M, + P, + log_likelihood, + grad_log_likelihood, + p_dynamic_callables.reset(False), + ) @staticmethod - def _kalman_prediction_step(k, p_m , p_P, p_dyn_model_callable, calc_grad_log_likelihood=False, - p_dm = None, p_dP = None): + def _kalman_prediction_step( + k, + p_m, + p_P, + p_dyn_model_callable, + calc_grad_log_likelihood=False, + p_dm=None, + p_dP=None, + ): """ Desctrete prediction function @@ -1315,17 +1527,23 @@ class DescreteStateSpace(object): """ # index correspond to values from previous iteration. - A = p_dyn_model_callable.Ak(k,p_m,p_P) # state transition matrix (or Jacobian) - Q = p_dyn_model_callable.Qk(k) # state noise matrix + A = p_dyn_model_callable.Ak( + k, p_m, p_P + ) # state transition matrix (or Jacobian) + Q = p_dyn_model_callable.Qk(k) # state noise matrix # Prediction step -> - m_pred = p_dyn_model_callable.f_a(k, p_m, A) # predicted mean - P_pred = A.dot(p_P).dot(A.T) + Q # predicted variance + m_pred = p_dyn_model_callable.f_a(k, p_m, A) # predicted mean + P_pred = A.dot(p_P).dot(A.T) + Q # predicted variance # Prediction step <- if calc_grad_log_likelihood: - dA_all_params = p_dyn_model_callable.dAk(k) # derivatives of A wrt parameters - dQ_all_params = p_dyn_model_callable.dQk(k) # derivatives of Q wrt parameters + dA_all_params = p_dyn_model_callable.dAk( + k + ) # derivatives of A wrt parameters + dQ_all_params = p_dyn_model_callable.dQk( + k + ) # derivatives of Q wrt parameters param_number = p_dP.shape[2] @@ -1334,19 +1552,21 @@ class DescreteStateSpace(object): dP_pred = np.empty(p_dP.shape) for j in range(param_number): - dA = dA_all_params[:,:,j] - dQ = dQ_all_params[:,:,j] + dA = dA_all_params[:, :, j] + dQ = dQ_all_params[:, :, j] - dP = p_dP[:,:,j] - dm = p_dm[:,:,j] - dm_pred[:,:,j] = np.dot(dA, p_m) + np.dot(A, dm) + dP = p_dP[:, :, j] + dm = p_dm[:, :, j] + dm_pred[:, :, j] = np.dot(dA, p_m) + np.dot(A, dm) # prediction step derivatives for current parameter: - dP_pred[:,:,j] = np.dot( dA ,np.dot(p_P, A.T)) - dP_pred[:,:,j] += dP_pred[:,:,j].T - dP_pred[:,:,j] += np.dot( A ,np.dot(dP, A.T)) + dQ + dP_pred[:, :, j] = np.dot(dA, np.dot(p_P, A.T)) + dP_pred[:, :, j] += dP_pred[:, :, j].T + dP_pred[:, :, j] += np.dot(A, np.dot(dP, A.T)) + dQ - dP_pred[:,:,j] = 0.5*(dP_pred[:,:,j] + dP_pred[:,:,j].T) #symmetrize + dP_pred[:, :, j] = 0.5 * ( + dP_pred[:, :, j] + dP_pred[:, :, j].T + ) # symmetrize else: dm_pred = None dP_pred = None @@ -1354,8 +1574,15 @@ class DescreteStateSpace(object): return m_pred, P_pred, dm_pred, dP_pred @staticmethod - def _kalman_prediction_step_SVD(k, p_m , p_P, p_dyn_model_callable, calc_grad_log_likelihood=False, - p_dm = None, p_dP = None): + def _kalman_prediction_step_SVD( + k, + p_m, + p_P, + p_dyn_model_callable, + calc_grad_log_likelihood=False, + p_dm=None, + p_dP=None, + ): """ Desctrete prediction function @@ -1398,33 +1625,46 @@ class DescreteStateSpace(object): # covariance from the previous step and its SVD decomposition # p_prev_cov = v * S * V.T Prev_cov, S_old, V_old = p_P - #p_prev_cov_tst = np.dot(p_V, (p_S * p_V).T) # reconstructed covariance from the previous step + # p_prev_cov_tst = np.dot(p_V, (p_S * p_V).T) # reconstructed covariance from the previous step # index correspond to values from previous iteration. - A = p_dyn_model_callable.Ak(k,p_m,Prev_cov) # state transition matrix (or Jacobian) - Q = p_dyn_model_callable.Qk(k) # state noise matrx. This is necessary for the square root calculation (next step) + A = p_dyn_model_callable.Ak( + k, p_m, Prev_cov + ) # state transition matrix (or Jacobian) + Q = p_dyn_model_callable.Qk( + k + ) # state noise matrx. This is necessary for the square root calculation (next step) Q_sr = p_dyn_model_callable.Q_srk(k) # Prediction step -> - m_pred = p_dyn_model_callable.f_a(k, p_m, A) # predicted mean + m_pred = p_dyn_model_callable.f_a(k, p_m, A) # predicted mean # coavariance prediction have changed: - svd_1_matr = np.vstack( ( (np.sqrt(S_old)* np.dot(A,V_old)).T , Q_sr.T) ) - (U,S,Vh) = sp.linalg.svd( svd_1_matr,full_matrices=False, compute_uv=True, - overwrite_a=False,check_finite=True) + svd_1_matr = np.vstack(((np.sqrt(S_old) * np.dot(A, V_old)).T, Q_sr.T)) + (U, S, Vh) = sp.linalg.svd( + svd_1_matr, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) # predicted variance computed by the regular method. For testing - #P_pred_tst = A.dot(Prev_cov).dot(A.T) + Q + # P_pred_tst = A.dot(Prev_cov).dot(A.T) + Q V_new = Vh.T S_new = S**2 - P_pred = np.dot(V_new * S_new, V_new.T) # prediction covariance + P_pred = np.dot(V_new * S_new, V_new.T) # prediction covariance P_pred = (P_pred, S_new, Vh.T) # Prediction step <- # derivatives if calc_grad_log_likelihood: - dA_all_params = p_dyn_model_callable.dAk(k) # derivatives of A wrt parameters - dQ_all_params = p_dyn_model_callable.dQk(k) # derivatives of Q wrt parameters + dA_all_params = p_dyn_model_callable.dAk( + k + ) # derivatives of A wrt parameters + dQ_all_params = p_dyn_model_callable.dQk( + k + ) # derivatives of Q wrt parameters param_number = p_dP.shape[2] @@ -1433,20 +1673,21 @@ class DescreteStateSpace(object): dP_pred = np.empty(p_dP.shape) for j in range(param_number): - dA = dA_all_params[:,:,j] - dQ = dQ_all_params[:,:,j] + dA = dA_all_params[:, :, j] + dQ = dQ_all_params[:, :, j] - #dP = p_dP[:,:,j] - #dm = p_dm[:,:,j] - dm_pred[:,:,j] = np.dot(dA, p_m) + np.dot(A, p_dm[:,:,j]) + # dP = p_dP[:,:,j] + # dm = p_dm[:,:,j] + dm_pred[:, :, j] = np.dot(dA, p_m) + np.dot(A, p_dm[:, :, j]) # prediction step derivatives for current parameter: + dP_pred[:, :, j] = np.dot(dA, np.dot(Prev_cov, A.T)) + dP_pred[:, :, j] += dP_pred[:, :, j].T + dP_pred[:, :, j] += np.dot(A, np.dot(p_dP[:, :, j], A.T)) + dQ - dP_pred[:,:,j] = np.dot( dA ,np.dot(Prev_cov, A.T)) - dP_pred[:,:,j] += dP_pred[:,:,j].T - dP_pred[:,:,j] += np.dot( A ,np.dot(p_dP[:,:,j], A.T)) + dQ - - dP_pred[:,:,j] = 0.5*(dP_pred[:,:,j] + dP_pred[:,:,j].T) #symmetrize + dP_pred[:, :, j] = 0.5 * ( + dP_pred[:, :, j] + dP_pred[:, :, j].T + ) # symmetrize else: dm_pred = None dP_pred = None @@ -1454,8 +1695,17 @@ class DescreteStateSpace(object): return m_pred, P_pred, dm_pred, dP_pred @staticmethod - def _kalman_update_step(k, p_m , p_P, p_meas_model_callable, measurement, calc_log_likelihood= False, - calc_grad_log_likelihood=False, p_dm = None, p_dP = None): + def _kalman_update_step( + k, + p_m, + p_P, + p_meas_model_callable, + measurement, + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + p_dm=None, + p_dP=None, + ): """ Input: @@ -1507,45 +1757,54 @@ class DescreteStateSpace(object): adds extra columns to the gradient. """ - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() - m_pred = p_m # from prediction step - P_pred = p_P # from prediction step + m_pred = p_m # from prediction step + P_pred = p_P # from prediction step H = p_meas_model_callable.Hk(k, m_pred, P_pred) R = p_meas_model_callable.Rk(k) - time_series_no = p_m.shape[1] # number of time serieses + time_series_no = p_m.shape[1] # number of time serieses - log_likelihood_update=None; dm_upd=None; dP_upd=None; d_log_likelihood_update=None + log_likelihood_update = None + dm_upd = None + dP_upd = None + d_log_likelihood_update = None # Update step (only if there is data) - #if not np.any(np.isnan(measurement)): # TODO: if some dimensions are missing, do properly computations for other. - v = measurement-p_meas_model_callable.f_h(k, m_pred, H) + # if not np.any(np.isnan(measurement)): # TODO: if some dimensions are missing, do properly computations for other. + v = measurement - p_meas_model_callable.f_h(k, m_pred, H) S = H.dot(P_pred).dot(H.T) + R - if measurement.shape[0]==1: # measurements are one dimensional - if (S < 0): - raise ValueError("Kalman Filter Update: S is negative step %i" % k ) - #import pdb; pdb.set_trace() + if measurement.shape[0] == 1: # measurements are one dimensional + if S < 0: + raise ValueError("Kalman Filter Update: S is negative step %i" % k) + # import pdb; pdb.set_trace() K = P_pred.dot(H.T) / S if calc_log_likelihood: - log_likelihood_update = -0.5 * ( np.log(2*np.pi) + np.log(S) + - v*v / S) - #log_likelihood_update = log_likelihood_update[0,0] # to make int - if np.any(np.isnan(log_likelihood_update)): # some member in P_pred is None. + log_likelihood_update = -0.5 * ( + np.log(2 * np.pi) + np.log(S) + v * v / S + ) + # log_likelihood_update = log_likelihood_update[0,0] # to make int + if np.any( + np.isnan(log_likelihood_update) + ): # some member in P_pred is None. raise ValueError("Nan values in likelihood update!") - LL = None; islower = None + LL = None + islower = None else: - LL,islower = linalg.cho_factor(S) - K = linalg.cho_solve((LL,islower), H.dot(P_pred.T)).T + LL, islower = linalg.cho_factor(S) + K = linalg.cho_solve((LL, islower), H.dot(P_pred.T)).T if calc_log_likelihood: - log_likelihood_update = -0.5 * ( v.shape[0]*np.log(2*np.pi) + - 2*np.sum( np.log(np.diag(LL)) ) +\ - np.sum((linalg.cho_solve((LL,islower),v)) * v, axis = 0) ) # diagonal of v.T*S^{-1}*v + log_likelihood_update = -0.5 * ( + v.shape[0] * np.log(2 * np.pi) + + 2 * np.sum(np.log(np.diag(LL))) + + np.sum((linalg.cho_solve((LL, islower), v)) * v, axis=0) + ) # diagonal of v.T*S^{-1}*v if calc_grad_log_likelihood: - dm_pred_all_params = p_dm # derivativas of the prediction phase + dm_pred_all_params = p_dm # derivativas of the prediction phase dP_pred_all_params = p_dP param_number = p_dP.shape[2] @@ -1556,75 +1815,95 @@ class DescreteStateSpace(object): dm_upd = np.empty(dm_pred_all_params.shape) dP_upd = np.empty(dP_pred_all_params.shape) - # firts dimension parameter_no, second - time series number - d_log_likelihood_update = np.empty((param_number,time_series_no)) + # firts dimension parameter_no, second - time series number + d_log_likelihood_update = np.empty((param_number, time_series_no)) for param in range(param_number): + dH = dH_all_params[:, :, param] + dR = dR_all_params[:, :, param] - dH = dH_all_params[:,:,param] - dR = dR_all_params[:,:,param] - - dm_pred = dm_pred_all_params[:,:,param] - dP_pred = dP_pred_all_params[:,:,param] + dm_pred = dm_pred_all_params[:, :, param] + dP_pred = dP_pred_all_params[:, :, param] # Terms in the likelihood derivatives - dv = - np.dot( dH, m_pred) - np.dot( H, dm_pred) - dS = np.dot(dH, np.dot( P_pred, H.T)) - dS += dS.T - dS += np.dot(H, np.dot( dP_pred, H.T)) + dR + dv = -np.dot(dH, m_pred) - np.dot(H, dm_pred) + dS = np.dot(dH, np.dot(P_pred, H.T)) + dS += dS.T + dS += np.dot(H, np.dot(dP_pred, H.T)) + dR - # TODO: maybe symmetrize dS + # TODO: maybe symmetrize dS - #dm and dP for the next stem - if LL is not None: # the state vector is not a scalar - tmp1 = linalg.cho_solve((LL,islower), H).T - tmp2 = linalg.cho_solve((LL,islower), dH).T - tmp3 = linalg.cho_solve((LL,islower), dS).T - else: # the state vector is a scalar - tmp1 = H.T / S - tmp2 = dH.T / S - tmp3 = dS.T / S + # dm and dP for the next stem + if LL is not None: # the state vector is not a scalar + tmp1 = linalg.cho_solve((LL, islower), H).T + tmp2 = linalg.cho_solve((LL, islower), dH).T + tmp3 = linalg.cho_solve((LL, islower), dS).T + else: # the state vector is a scalar + tmp1 = H.T / S + tmp2 = dH.T / S + tmp3 = dS.T / S - dK = np.dot( dP_pred, tmp1) + np.dot( P_pred, tmp2) - \ - np.dot( P_pred, np.dot( tmp1, tmp3 ) ) + dK = ( + np.dot(dP_pred, tmp1) + + np.dot(P_pred, tmp2) + - np.dot(P_pred, np.dot(tmp1, tmp3)) + ) # terms required for the next step, save this for each parameter - dm_upd[:,:,param] = dm_pred + np.dot(dK, v) + np.dot(K, dv) + dm_upd[:, :, param] = dm_pred + np.dot(dK, v) + np.dot(K, dv) - dP_upd[:,:,param] = -np.dot(dK, np.dot(S, K.T)) - dP_upd[:,:,param] += dP_upd[:,:,param].T - dP_upd[:,:,param] += dP_pred - np.dot(K , np.dot( dS, K.T)) + dP_upd[:, :, param] = -np.dot(dK, np.dot(S, K.T)) + dP_upd[:, :, param] += dP_upd[:, :, param].T + dP_upd[:, :, param] += dP_pred - np.dot(K, np.dot(dS, K.T)) - dP_upd[:,:,param] = 0.5*(dP_upd[:,:,param] + dP_upd[:,:,param].T) #symmetrize + dP_upd[:, :, param] = 0.5 * ( + dP_upd[:, :, param] + dP_upd[:, :, param].T + ) # symmetrize # computing the likelihood change for each parameter: - if LL is not None: # the state vector is not 1D - #tmp4 = linalg.cho_solve((LL,islower), dv) - tmp5 = linalg.cho_solve((LL,islower), v) - else: # the state vector is a scalar - #tmp4 = dv / S - tmp5 = v / S + if LL is not None: # the state vector is not 1D + # tmp4 = linalg.cho_solve((LL,islower), dv) + tmp5 = linalg.cho_solve((LL, islower), v) + else: # the state vector is a scalar + # tmp4 = dv / S + tmp5 = v / S - - d_log_likelihood_update[param,:] = -(0.5*np.sum(np.diag(tmp3)) + \ - np.sum(tmp5*dv, axis=0) - 0.5 * np.sum(tmp5 * np.dot(dS, tmp5), axis=0) ) + d_log_likelihood_update[param, :] = -( + 0.5 * np.sum(np.diag(tmp3)) + + np.sum(tmp5 * dv, axis=0) + - 0.5 * np.sum(tmp5 * np.dot(dS, tmp5), axis=0) + ) # Before - #d_log_likelihood_update[param,0] = -(0.5*np.sum(np.diag(tmp3)) + \ - #np.dot(tmp5.T, dv) - 0.5 * np.dot(tmp5.T ,np.dot(dS, tmp5)) ) - - + # d_log_likelihood_update[param,0] = -(0.5*np.sum(np.diag(tmp3)) + \ + # np.dot(tmp5.T, dv) - 0.5 * np.dot(tmp5.T ,np.dot(dS, tmp5)) ) # Compute the actual updates for mean and variance of the states. - m_upd = m_pred + K.dot( v ) + m_upd = m_pred + K.dot(v) # Covariance update and ensure it is symmetric P_upd = K.dot(S).dot(K.T) - P_upd = 0.5*(P_upd + P_upd.T) - P_upd = P_pred - P_upd# this update matrix is symmetric + P_upd = 0.5 * (P_upd + P_upd.T) + P_upd = P_pred - P_upd # this update matrix is symmetric - return m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update + return ( + m_upd, + P_upd, + log_likelihood_update, + dm_upd, + dP_upd, + d_log_likelihood_update, + ) @staticmethod - def _kalman_update_step_SVD(k, p_m , p_P, p_meas_model_callable, measurement, calc_log_likelihood= False, - calc_grad_log_likelihood=False, p_dm = None, p_dP = None): + def _kalman_update_step_SVD( + k, + p_m, + p_P, + p_meas_model_callable, + measurement, + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + p_dm=None, + p_dP=None, + ): """ Input: @@ -1700,67 +1979,84 @@ class DescreteStateSpace(object): """ - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() - m_pred = p_m # from prediction step - P_pred,S_pred,V_pred = p_P # from prediction step + m_pred = p_m # from prediction step + P_pred, S_pred, V_pred = p_P # from prediction step H = p_meas_model_callable.Hk(k, m_pred, P_pred) R = p_meas_model_callable.Rk(k) - R_isr = p_meas_model_callable.R_isrk(k) # square root of the inverse of R matrix + R_isr = p_meas_model_callable.R_isrk( + k + ) # square root of the inverse of R matrix - time_series_no = p_m.shape[1] # number of time serieses + time_series_no = p_m.shape[1] # number of time serieses - log_likelihood_update=None; dm_upd=None; dP_upd=None; d_log_likelihood_update=None + log_likelihood_update = None + dm_upd = None + dP_upd = None + d_log_likelihood_update = None # Update step (only if there is data) - #if not np.any(np.isnan(measurement)): # TODO: if some dimensions are missing, do properly computations for other. - v = measurement-p_meas_model_callable.f_h(k, m_pred, H) + # if not np.any(np.isnan(measurement)): # TODO: if some dimensions are missing, do properly computations for other. + v = measurement - p_meas_model_callable.f_h(k, m_pred, H) - svd_2_matr = np.vstack( ( np.dot( R_isr.T, np.dot(H, V_pred)) , np.diag( 1.0/np.sqrt(S_pred) ) ) ) + svd_2_matr = np.vstack( + (np.dot(R_isr.T, np.dot(H, V_pred)), np.diag(1.0 / np.sqrt(S_pred))) + ) - (U,S,Vh) = sp.linalg.svd( svd_2_matr,full_matrices=False, compute_uv=True, - overwrite_a=False,check_finite=True) + (U, S, Vh) = sp.linalg.svd( + svd_2_matr, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) - # P_upd = U_upd S_upd**2 U_upd.T + # P_upd = U_upd S_upd**2 U_upd.T U_upd = np.dot(V_pred, Vh.T) - S_upd = (1.0/S)**2 + S_upd = (1.0 / S) ** 2 - P_upd = np.dot(U_upd * S_upd, U_upd.T) # update covariance - P_upd = (P_upd,S_upd,U_upd) # tuple to pass to the next step + P_upd = np.dot(U_upd * S_upd, U_upd.T) # update covariance + P_upd = (P_upd, S_upd, U_upd) # tuple to pass to the next step - # stil need to compute S and K for derivative computation + # stil need to compute S and K for derivative computation S = H.dot(P_pred).dot(H.T) + R - if measurement.shape[0]==1: # measurements are one dimensional - if (S < 0): - raise ValueError("Kalman Filter Update: S is negative step %i" % k ) - #import pdb; pdb.set_trace() + if measurement.shape[0] == 1: # measurements are one dimensional + if S < 0: + raise ValueError("Kalman Filter Update: S is negative step %i" % k) + # import pdb; pdb.set_trace() K = P_pred.dot(H.T) / S if calc_log_likelihood: - log_likelihood_update = -0.5 * ( np.log(2*np.pi) + np.log(S) + - v*v / S) - #log_likelihood_update = log_likelihood_update[0,0] # to make int - if np.any(np.isnan(log_likelihood_update)): # some member in P_pred is None. + log_likelihood_update = -0.5 * ( + np.log(2 * np.pi) + np.log(S) + v * v / S + ) + # log_likelihood_update = log_likelihood_update[0,0] # to make int + if np.any( + np.isnan(log_likelihood_update) + ): # some member in P_pred is None. raise ValueError("Nan values in likelihood update!") - LL = None; islower = None + LL = None + islower = None else: - LL,islower = linalg.cho_factor(S) - K = linalg.cho_solve((LL,islower), H.dot(P_pred.T)).T + LL, islower = linalg.cho_factor(S) + K = linalg.cho_solve((LL, islower), H.dot(P_pred.T)).T if calc_log_likelihood: - log_likelihood_update = -0.5 * ( v.shape[0]*np.log(2*np.pi) + - 2*np.sum( np.log(np.diag(LL)) ) +\ - np.sum((linalg.cho_solve((LL,islower),v)) * v, axis = 0) ) # diagonal of v.T*S^{-1}*v - + log_likelihood_update = -0.5 * ( + v.shape[0] * np.log(2 * np.pi) + + 2 * np.sum(np.log(np.diag(LL))) + + np.sum((linalg.cho_solve((LL, islower), v)) * v, axis=0) + ) # diagonal of v.T*S^{-1}*v # Old method of computing updated covariance (for testing) -> - #P_upd_tst = K.dot(S).dot(K.T) - #P_upd_tst = 0.5*(P_upd_tst + P_upd_tst.T) - #P_upd_tst = P_pred - P_upd_tst# this update matrix is symmetric + # P_upd_tst = K.dot(S).dot(K.T) + # P_upd_tst = 0.5*(P_upd_tst + P_upd_tst.T) + # P_upd_tst = P_pred - P_upd_tst# this update matrix is symmetric # Old method of computing updated covariance (for testing) <- if calc_grad_log_likelihood: - dm_pred_all_params = p_dm # derivativas of the prediction phase + dm_pred_all_params = p_dm # derivativas of the prediction phase dP_pred_all_params = p_dP param_number = p_dP.shape[2] @@ -1771,67 +2067,88 @@ class DescreteStateSpace(object): dm_upd = np.empty(dm_pred_all_params.shape) dP_upd = np.empty(dP_pred_all_params.shape) - # firts dimension parameter_no, second - time series number - d_log_likelihood_update = np.empty((param_number,time_series_no)) + # firts dimension parameter_no, second - time series number + d_log_likelihood_update = np.empty((param_number, time_series_no)) for param in range(param_number): + dH = dH_all_params[:, :, param] + dR = dR_all_params[:, :, param] - dH = dH_all_params[:,:,param] - dR = dR_all_params[:,:,param] - - dm_pred = dm_pred_all_params[:,:,param] - dP_pred = dP_pred_all_params[:,:,param] + dm_pred = dm_pred_all_params[:, :, param] + dP_pred = dP_pred_all_params[:, :, param] # Terms in the likelihood derivatives - dv = - np.dot( dH, m_pred) - np.dot( H, dm_pred) - dS = np.dot(dH, np.dot( P_pred, H.T)) - dS += dS.T - dS += np.dot(H, np.dot( dP_pred, H.T)) + dR + dv = -np.dot(dH, m_pred) - np.dot(H, dm_pred) + dS = np.dot(dH, np.dot(P_pred, H.T)) + dS += dS.T + dS += np.dot(H, np.dot(dP_pred, H.T)) + dR # TODO: maybe symmetrize dS - #dm and dP for the next stem - if LL is not None: # the state vector is not a scalar - tmp1 = linalg.cho_solve((LL,islower), H).T - tmp2 = linalg.cho_solve((LL,islower), dH).T - tmp3 = linalg.cho_solve((LL,islower), dS).T - else: # the state vector is a scalar - tmp1 = H.T / S - tmp2 = dH.T / S - tmp3 = dS.T / S + # dm and dP for the next stem + if LL is not None: # the state vector is not a scalar + tmp1 = linalg.cho_solve((LL, islower), H).T + tmp2 = linalg.cho_solve((LL, islower), dH).T + tmp3 = linalg.cho_solve((LL, islower), dS).T + else: # the state vector is a scalar + tmp1 = H.T / S + tmp2 = dH.T / S + tmp3 = dS.T / S - dK = np.dot( dP_pred, tmp1) + np.dot( P_pred, tmp2) - \ - np.dot( P_pred, np.dot( tmp1, tmp3 ) ) + dK = ( + np.dot(dP_pred, tmp1) + + np.dot(P_pred, tmp2) + - np.dot(P_pred, np.dot(tmp1, tmp3)) + ) - # terms required for the next step, save this for each parameter - dm_upd[:,:,param] = dm_pred + np.dot(dK, v) + np.dot(K, dv) + # terms required for the next step, save this for each parameter + dm_upd[:, :, param] = dm_pred + np.dot(dK, v) + np.dot(K, dv) - dP_upd[:,:,param] = -np.dot(dK, np.dot(S, K.T)) - dP_upd[:,:,param] += dP_upd[:,:,param].T - dP_upd[:,:,param] += dP_pred - np.dot(K , np.dot( dS, K.T)) + dP_upd[:, :, param] = -np.dot(dK, np.dot(S, K.T)) + dP_upd[:, :, param] += dP_upd[:, :, param].T + dP_upd[:, :, param] += dP_pred - np.dot(K, np.dot(dS, K.T)) - dP_upd[:,:,param] = 0.5*(dP_upd[:,:,param] + dP_upd[:,:,param].T) #symmetrize - # computing the likelihood change for each parameter: - if LL is not None: # the state vector is not 1D - tmp5 = linalg.cho_solve((LL,islower), v) - else: # the state vector is a scalar - tmp5 = v / S + dP_upd[:, :, param] = 0.5 * ( + dP_upd[:, :, param] + dP_upd[:, :, param].T + ) # symmetrize + # computing the likelihood change for each parameter: + if LL is not None: # the state vector is not 1D + tmp5 = linalg.cho_solve((LL, islower), v) + else: # the state vector is a scalar + tmp5 = v / S - - d_log_likelihood_update[param,:] = -(0.5*np.sum(np.diag(tmp3)) + \ - np.sum(tmp5*dv, axis=0) - 0.5 * np.sum(tmp5 * np.dot(dS, tmp5), axis=0) ) + d_log_likelihood_update[param, :] = -( + 0.5 * np.sum(np.diag(tmp3)) + + np.sum(tmp5 * dv, axis=0) + - 0.5 * np.sum(tmp5 * np.dot(dS, tmp5), axis=0) + ) # Before - #d_log_likelihood_update[param,0] = -(0.5*np.sum(np.diag(tmp3)) + \ - #np.dot(tmp5.T, dv) - 0.5 * np.dot(tmp5.T ,np.dot(dS, tmp5)) ) + # d_log_likelihood_update[param,0] = -(0.5*np.sum(np.diag(tmp3)) + \ + # np.dot(tmp5.T, dv) - 0.5 * np.dot(tmp5.T ,np.dot(dS, tmp5)) ) # Compute the actual updates for mean of the states. Variance update # is computed earlier. - m_upd = m_pred + K.dot( v ) + m_upd = m_pred + K.dot(v) - return m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update + return ( + m_upd, + P_upd, + log_likelihood_update, + dm_upd, + dP_upd, + d_log_likelihood_update, + ) @staticmethod - def _rts_smoother_update_step(k, p_m , p_P, p_m_pred, p_P_pred, p_m_prev_step, - p_P_prev_step, p_dynamic_callables): + def _rts_smoother_update_step( + k, + p_m, + p_P, + p_m_pred, + p_P_pred, + p_m_prev_step, + p_P_prev_step, + p_dynamic_callables, + ): """ Rauch–Tung–Striebel(RTS) update step @@ -1867,31 +2184,30 @@ class DescreteStateSpace(object): """ - A = p_dynamic_callables.Ak(k,p_m,p_P) # state transition matrix (or Jacobian) + A = p_dynamic_callables.Ak(k, p_m, p_P) # state transition matrix (or Jacobian) - tmp = np.dot( A, p_P.T) - if A.shape[0] == 1: # 1D states - G = tmp.T / p_P_pred # P[:,:,k] is symmetric + tmp = np.dot(A, p_P.T) + if A.shape[0] == 1: # 1D states + G = tmp.T / p_P_pred # P[:,:,k] is symmetric else: try: - LL,islower = linalg.cho_factor(p_P_pred) - G = linalg.cho_solve((LL,islower),tmp).T + LL, islower = linalg.cho_factor(p_P_pred) + G = linalg.cho_solve((LL, islower), tmp).T except: # It happende that p_P_pred has several near zero eigenvalues # hence the Cholesky method does not work. res = sp.linalg.lstsq(p_P_pred, tmp) G = res[0].T - m_upd = p_m + G.dot( p_m_prev_step-p_m_pred ) - P_upd = p_P + G.dot( p_P_prev_step-p_P_pred).dot(G.T) + m_upd = p_m + G.dot(p_m_prev_step - p_m_pred) + P_upd = p_P + G.dot(p_P_prev_step - p_P_pred).dot(G.T) - P_upd = 0.5*(P_upd + P_upd.T) + P_upd = 0.5 * (P_upd + P_upd.T) return m_upd, P_upd, G @classmethod - def rts_smoother(cls,state_dim, p_dynamic_callables, filter_means, - filter_covars): + def rts_smoother(cls, state_dim, p_dynamic_callables, filter_means, filter_covars): """ This function implements Rauch–Tung–Striebel(RTS) smoother algorithm based on the results of kalman_filter_raw. @@ -1934,41 +2250,69 @@ class DescreteStateSpace(object): Smoothed estimates of the state covariances """ - no_steps = filter_covars.shape[0]-1# number of steps (minus initial covariance) + no_steps = ( + filter_covars.shape[0] - 1 + ) # number of steps (minus initial covariance) - M = np.empty(filter_means.shape) # smoothed means - P = np.empty(filter_covars.shape) # smoothed covars - #G = np.empty( (no_steps,state_dim,state_dim) ) # G from the update step of the smoother + M = np.empty(filter_means.shape) # smoothed means + P = np.empty(filter_covars.shape) # smoothed covars + # G = np.empty( (no_steps,state_dim,state_dim) ) # G from the update step of the smoother - M[-1,:] = filter_means[-1,:] - P[-1,:,:] = filter_covars[-1,:,:] - for k in range(no_steps-1,-1,-1): + M[-1, :] = filter_means[-1, :] + P[-1, :, :] = filter_covars[-1, :, :] + for k in range(no_steps - 1, -1, -1): + m_pred, P_pred, tmp1, tmp2 = cls._kalman_prediction_step( + k, + filter_means[k, :], + filter_covars[k, :, :], + p_dynamic_callables, + calc_grad_log_likelihood=False, + ) + p_m = filter_means[k, :] + if len(p_m.shape) < 2: + p_m.shape = (p_m.shape[0], 1) - m_pred, P_pred, tmp1, tmp2 = \ - cls._kalman_prediction_step(k, filter_means[k,:], - filter_covars[k,:,:], p_dynamic_callables, - calc_grad_log_likelihood=False) - p_m = filter_means[k,:] - if len(p_m.shape)<2: - p_m.shape = (p_m.shape[0],1) + p_m_prev_step = M[k + 1, :] + if len(p_m_prev_step.shape) < 2: + p_m_prev_step.shape = (p_m_prev_step.shape[0], 1) - p_m_prev_step = M[k+1,:] - if len(p_m_prev_step.shape)<2: - p_m_prev_step.shape = (p_m_prev_step.shape[0],1) + m_upd, P_upd, G_tmp = cls._rts_smoother_update_step( + k, + p_m, + filter_covars[k, :, :], + m_pred, + P_pred, + p_m_prev_step, + P[k + 1, :, :], + p_dynamic_callables, + ) - m_upd, P_upd, G_tmp = cls._rts_smoother_update_step(k, - p_m ,filter_covars[k,:,:], - m_pred, P_pred, p_m_prev_step ,P[k+1,:,:], p_dynamic_callables) - - M[k,:] = m_upd#np.squeeze(m_upd) - P[k,:,:] = P_upd - #G[k,:,:] = G_upd.T # store transposed G. + M[k, :] = m_upd # np.squeeze(m_upd) + P[k, :, :] = P_upd + # G[k,:,:] = G_upd.T # store transposed G. # Return values - return (M, P) #, G) + return (M, P) # , G) @staticmethod - def _EM_gradient(A,Q,H,R,m_init,P_init,measurements, M, P, G, dA, dQ, dH, dR, dm_init, dP_init): + def _EM_gradient( + A, + Q, + H, + R, + m_init, + P_init, + measurements, + M, + P, + G, + dA, + dQ, + dH, + dR, + dm_init, + dP_init, + ): """ Gradient computation with the EM algorithm. @@ -1979,35 +2323,37 @@ class DescreteStateSpace(object): P: Variances from the smoother G: Gains? from the smoother """ - import pdb; pdb.set_trace(); + import pdb + + pdb.set_trace() param_number = dA.shape[-1] - d_log_likelihood_update = np.empty((param_number,1)) + d_log_likelihood_update = np.empty((param_number, 1)) sample_no = measurements.shape[0] - P_1 = P[1:,:,:] # remove 0-th step - P_2 = P[0:-1,:,:] # remove 0-th step + P_1 = P[1:, :, :] # remove 0-th step + P_2 = P[0:-1, :, :] # remove 0-th step - M_1 = M[1:,:] # remove 0-th step - M_2 = M[0:-1,:] # remove the last step + M_1 = M[1:, :] # remove 0-th step + M_2 = M[0:-1, :] # remove the last step - Sigma = np.mean(P_1,axis=0) + np.dot(M_1.T, M_1) / sample_no # - Phi = np.mean(P_2,axis=0) + np.dot(M_2.T, M_2) / sample_no # + Sigma = np.mean(P_1, axis=0) + np.dot(M_1.T, M_1) / sample_no # + Phi = np.mean(P_2, axis=0) + np.dot(M_2.T, M_2) / sample_no # - B = np.dot( measurements.T, M_1 )/ sample_no - C = (sp.einsum( 'ijk,ikl', P_1, G) + np.dot(M_1.T, M_2)) / sample_no # + B = np.dot(measurements.T, M_1) / sample_no + C = (sp.einsum("ijk,ikl", P_1, G) + np.dot(M_1.T, M_2)) / sample_no # -# C1 = np.zeros( (P_1.shape[1],P_1.shape[1]) ) -# for k in range(P_1.shape[0]): -# C1 += np.dot(P_1[k,:,:],G[k,:,:]) + sp.outer( M_1[k,:], M_2[k,:] ) -# C1 = C1 / sample_no + # C1 = np.zeros( (P_1.shape[1],P_1.shape[1]) ) + # for k in range(P_1.shape[0]): + # C1 += np.dot(P_1[k,:,:],G[k,:,:]) + sp.outer( M_1[k,:], M_2[k,:] ) + # C1 = C1 / sample_no - D = np.dot( measurements.T, measurements ) / sample_no + D = np.dot(measurements.T, measurements) / sample_no try: P_init_inv = sp.linalg.inv(P_init) - if np.max( np.abs(P_init_inv)) > 10e13: + if np.max(np.abs(P_init_inv)) > 10e13: compute_P_init_terms = False else: compute_P_init_terms = True @@ -2017,7 +2363,7 @@ class DescreteStateSpace(object): try: Q_inv = sp.linalg.inv(Q) - if np.max( np.abs(Q_inv)) > 10e13: + if np.max(np.abs(Q_inv)) > 10e13: compute_Q_terms = False else: compute_Q_terms = True @@ -2027,54 +2373,84 @@ class DescreteStateSpace(object): try: R_inv = sp.linalg.inv(R) - if np.max( np.abs(R_inv)) > 10e13: + if np.max(np.abs(R_inv)) > 10e13: compute_R_terms = False else: compute_R_terms = True except np.linalg.LinAlgError: compute_R_terms = False - - d_log_likelihood_update = np.zeros((param_number,1)) + d_log_likelihood_update = np.zeros((param_number, 1)) for j in range(param_number): if compute_P_init_terms: - d_log_likelihood_update[j,:] -= 0.5 * np.sum(P_init_inv* dP_init[:,:,j].T ) #p #m + d_log_likelihood_update[j, :] -= 0.5 * np.sum( + P_init_inv * dP_init[:, :, j].T + ) # p #m - M0_smoothed = M[0]; M0_smoothed.shape = (M0_smoothed.shape[0],1) - tmp1 = np.dot( dP_init[:,:,j], np.dot( P_init_inv, (P[0,:,:] + sp.outer( (M0_smoothed - m_init), (M0_smoothed - m_init) )) ) ) #p #m - d_log_likelihood_update[j,:] += 0.5 * np.sum(P_init_inv* tmp1.T ) + M0_smoothed = M[0] + M0_smoothed.shape = (M0_smoothed.shape[0], 1) + tmp1 = np.dot( + dP_init[:, :, j], + np.dot( + P_init_inv, + ( + P[0, :, :] + + sp.outer((M0_smoothed - m_init), (M0_smoothed - m_init)) + ), + ), + ) # p #m + d_log_likelihood_update[j, :] += 0.5 * np.sum(P_init_inv * tmp1.T) - tmp2 = sp.outer( dm_init[:,j], M0_smoothed ) + tmp2 = sp.outer(dm_init[:, j], M0_smoothed) tmp2 += tmp2.T - d_log_likelihood_update[j,:] += 0.5 * np.sum(P_init_inv* tmp2.T ) + d_log_likelihood_update[j, :] += 0.5 * np.sum(P_init_inv * tmp2.T) if compute_Q_terms: + d_log_likelihood_update[j, :] -= ( + sample_no / 2.0 * np.sum(Q_inv * dQ[:, :, j].T) + ) # m - d_log_likelihood_update[j,:] -= sample_no/2.0 * np.sum(Q_inv* dQ[:,:,j].T ) #m + tmp1 = np.dot(C, A.T) + tmp1 += tmp1.T + tmp1 = Sigma - tmp1 + np.dot(A, np.dot(Phi, A.T)) # m + tmp1 = np.dot(dQ[:, :, j], np.dot(Q_inv, tmp1)) + d_log_likelihood_update[j, :] += ( + sample_no / 2.0 * np.sum(Q_inv * tmp1.T) + ) - tmp1 = np.dot(C,A.T); tmp1 += tmp1.T; tmp1 = Sigma - tmp1 + np.dot(A, np.dot(Phi,A.T)) #m - tmp1 = np.dot( dQ[:,:,j], np.dot( Q_inv, tmp1) ) - d_log_likelihood_update[j,:] += sample_no/2.0 * np.sum(Q_inv * tmp1.T) - - tmp2 = np.dot( dA[:,:,j], C.T); tmp2 += tmp2.T; - tmp3 = np.dot(dA[:,:,j], np.dot(Phi,A.T)); tmp3 += tmp3.T - d_log_likelihood_update[j,:] -= sample_no/2.0 * np.sum(Q_inv.T * (tmp3 - tmp2) ) + tmp2 = np.dot(dA[:, :, j], C.T) + tmp2 += tmp2.T + tmp3 = np.dot(dA[:, :, j], np.dot(Phi, A.T)) + tmp3 += tmp3.T + d_log_likelihood_update[j, :] -= ( + sample_no / 2.0 * np.sum(Q_inv.T * (tmp3 - tmp2)) + ) if compute_R_terms: - d_log_likelihood_update[j,:] -= sample_no/2.0 * np.sum(R_inv* dR[:,:,j].T ) + d_log_likelihood_update[j, :] -= ( + sample_no / 2.0 * np.sum(R_inv * dR[:, :, j].T) + ) - tmp1 = np.dot(B,H.T); tmp1 += tmp1.T; tmp1 = D - tmp1 + np.dot(H, np.dot(Sigma,H.T)) - tmp1 = np.dot( dR[:,:,j], np.dot( R_inv, tmp1) ) - d_log_likelihood_update[j,:] += sample_no/2.0 * np.sum(R_inv * tmp1.T) + tmp1 = np.dot(B, H.T) + tmp1 += tmp1.T + tmp1 = D - tmp1 + np.dot(H, np.dot(Sigma, H.T)) + tmp1 = np.dot(dR[:, :, j], np.dot(R_inv, tmp1)) + d_log_likelihood_update[j, :] += ( + sample_no / 2.0 * np.sum(R_inv * tmp1.T) + ) - tmp2 = np.dot( dH[:,:,j], B.T); tmp2 += tmp2.T; - tmp3 = np.dot(dH[:,:,j], np.dot(Sigma,H.T)); tmp3 += tmp3.T - d_log_likelihood_update[j,:] -= sample_no/2.0 * np.sum(R_inv.T * (tmp3 - tmp2) ) + tmp2 = np.dot(dH[:, :, j], B.T) + tmp2 += tmp2.T + tmp3 = np.dot(dH[:, :, j], np.dot(Sigma, H.T)) + tmp3 += tmp3.T + d_log_likelihood_update[j, :] -= ( + sample_no / 2.0 * np.sum(R_inv.T * (tmp3 - tmp2)) + ) return d_log_likelihood_update @staticmethod - def _check_SS_matrix(p_M, state_dim, measurement_dim, which='A'): + def _check_SS_matrix(p_M, state_dim, measurement_dim, which="A"): """ Veryfy that on exit the matrix has appropriate shape for the KF algorithm. @@ -2096,30 +2472,42 @@ class DescreteStateSpace(object): """ old_M_shape = None - if len(p_M.shape) < 3: # new shape is 3 dimensional - old_M_shape = p_M.shape # save shape to restore it on exit - if len(p_M.shape) == 2: # matrix - p_M.shape = (p_M.shape[0],p_M.shape[1],1) - elif len(p_M.shape) == 1: # scalar but in array already - if (p_M.shape[0] != 1): - raise ValueError("Matrix %s is an 1D array, while it must be a matrix or scalar", which) + if len(p_M.shape) < 3: # new shape is 3 dimensional + old_M_shape = p_M.shape # save shape to restore it on exit + if len(p_M.shape) == 2: # matrix + p_M.shape = (p_M.shape[0], p_M.shape[1], 1) + elif len(p_M.shape) == 1: # scalar but in array already + if p_M.shape[0] != 1: + raise ValueError( + "Matrix %s is an 1D array, while it must be a matrix or scalar", + which, + ) else: - p_M.shape = (1,1,1) + p_M.shape = (1, 1, 1) - if (which == 'A') or (which == 'Q'): + if (which == "A") or (which == "Q"): if (p_M.shape[0] != state_dim) or (p_M.shape[1] != state_dim): - raise ValueError("%s must be a square matrix of size (%i,%i)" % (which, state_dim, state_dim)) - if (which == 'H'): + raise ValueError( + "%s must be a square matrix of size (%i,%i)" + % (which, state_dim, state_dim) + ) + if which == "H": if (p_M.shape[0] != measurement_dim) or (p_M.shape[1] != state_dim): - raise ValueError("H must be of shape (measurement_dim, state_dim) (%i,%i)" % (measurement_dim, state_dim)) - if (which == 'R'): + raise ValueError( + "H must be of shape (measurement_dim, state_dim) (%i,%i)" + % (measurement_dim, state_dim) + ) + if which == "R": if (p_M.shape[0] != measurement_dim) or (p_M.shape[1] != measurement_dim): - raise ValueError("R must be of shape (measurement_dim, measurement_dim) (%i,%i)" % (measurement_dim, measurement_dim)) + raise ValueError( + "R must be of shape (measurement_dim, measurement_dim) (%i,%i)" + % (measurement_dim, measurement_dim) + ) - return (p_M,old_M_shape) + return (p_M, old_M_shape) @staticmethod - def _check_grad_state_matrices(dM, state_dim, grad_params_no, which = 'dA'): + def _check_grad_state_matrices(dM, state_dim, grad_params_no, which="dA"): """ Function checks (mostly check dimensions) matrices for marginal likelihood gradient parameters calculation. It check dA, dQ matrices. @@ -2147,32 +2535,34 @@ class DescreteStateSpace(object): """ - if dM is None: - dM=np.zeros((state_dim,state_dim,grad_params_no)) + dM = np.zeros((state_dim, state_dim, grad_params_no)) elif isinstance(dM, np.ndarray): if state_dim == 1: if len(dM.shape) < 3: - dM.shape = (1,1,1) + dM.shape = (1, 1, 1) else: if len(dM.shape) < 3: - dM.shape = (state_dim,state_dim,1) - elif isinstance(dM, np.int): + dM.shape = (state_dim, state_dim, 1) + elif isinstance(dM, int): if state_dim > 1: - raise ValueError("When computing likelihood gradient wrong %s dimension." % which) + raise ValueError( + "When computing likelihood gradient wrong %s dimension." % which + ) else: - dM = np.ones((1,1,1)) * dM + dM = np.ones((1, 1, 1)) * dM -# if not isinstance(dM, types.FunctionType): -# f_dM = lambda k: dM -# else: -# f_dM = dM + # if not isinstance(dM, types.FunctionType): + # f_dM = lambda k: dM + # else: + # f_dM = dM return dM - @staticmethod - def _check_grad_measurement_matrices(dM, state_dim, grad_params_no, measurement_dim, which = 'dH'): + def _check_grad_measurement_matrices( + dM, state_dim, grad_params_no, measurement_dim, which="dH" + ): """ Function checks (mostly check dimensions) matrices for marginal likelihood gradient parameters calculation. It check dH, dR matrices. @@ -2206,38 +2596,40 @@ class DescreteStateSpace(object): """ if dM is None: - if which == 'dH': - dM=np.zeros((measurement_dim ,state_dim,grad_params_no)) - elif which == 'dR': - dM=np.zeros((measurement_dim,measurement_dim,grad_params_no)) + if which == "dH": + dM = np.zeros((measurement_dim, state_dim, grad_params_no)) + elif which == "dR": + dM = np.zeros((measurement_dim, measurement_dim, grad_params_no)) elif isinstance(dM, np.ndarray): if state_dim == 1: if len(dM.shape) < 3: - dM.shape = (1,1,1) + dM.shape = (1, 1, 1) else: if len(dM.shape) < 3: - if which == 'dH': - dM.shape = (measurement_dim,state_dim,1) - elif which == 'dR': - dM.shape = (measurement_dim,measurement_dim,1) - elif isinstance(dM, np.int): + if which == "dH": + dM.shape = (measurement_dim, state_dim, 1) + elif which == "dR": + dM.shape = (measurement_dim, measurement_dim, 1) + elif isinstance(dM, int): if state_dim > 1: - raise ValueError("When computing likelihood gradient wrong dH dimension.") + raise ValueError( + "When computing likelihood gradient wrong dH dimension." + ) else: - dM = np.ones((1,1,1)) * dM + dM = np.ones((1, 1, 1)) * dM -# if not isinstance(dM, types.FunctionType): -# f_dM = lambda k: dM -# else: -# f_dM = dM + # if not isinstance(dM, types.FunctionType): + # f_dM = lambda k: dM + # else: + # f_dM = dM return dM - class Struct(object): pass + class ContDescrStateSpace(DescreteStateSpace): """ Class for continuous-discrete Kalman filter. State equation is @@ -2261,7 +2653,19 @@ class ContDescrStateSpace(DescreteStateSpace): would take too much memory. """ - def __init__(self, F,L,Qc,dt,compute_derivatives=False, grad_params_no=None, P_inf=None, dP_inf=None, dF = None, dQc=None): + def __init__( + self, + F, + L, + Qc, + dt, + compute_derivatives=False, + grad_params_no=None, + P_inf=None, + dP_inf=None, + dF=None, + dQc=None, + ): """ Constructor. All necessary parameters are passed here and stored in the opject. @@ -2288,7 +2692,7 @@ class ContDescrStateSpace(DescreteStateSpace): self.L = L.copy() self.Qc = Qc.copy() - self.dt = dt # copy is not taken because dt is internal parameter + self.dt = dt # copy is not taken because dt is internal parameter # Parameters are used to calculate derivatives but derivatives # are not used in the smoother. Therefore copies are not taken. @@ -2298,8 +2702,7 @@ class ContDescrStateSpace(DescreteStateSpace): self.dQc = dQc self.compute_derivatives = compute_derivatives - self.grad_params_no = grad_params_no - + self.grad_params_no = grad_params_no self.last_k = 0 self.last_k_computed = False @@ -2313,14 +2716,14 @@ class ContDescrStateSpace(DescreteStateSpace): self.Q_svd_computed = False # !!!Print statistics! Which object is created - def f_a(self, k,m,A): + def f_a(self, k, m, A): """ Dynamic model """ - return np.dot(A, m) # default dynamic model + return np.dot(A, m) # default dynamic model - def _recompute_for_new_k(self,k): + def _recompute_for_new_k(self, k): """ Computes the necessary matrices for an index k and store the results. @@ -2335,9 +2738,18 @@ class ContDescrStateSpace(DescreteStateSpace): A, Q, dA dQ on step k """ if (self.last_k != k) or (self.last_k_computed == False): - v_Ak,v_Qk, tmp, v_dAk, v_dQk = ContDescrStateSpace.lti_sde_to_descrete(self.F, - self.L,self.Qc,self.dt[k],self.compute_derivatives, - grad_params_no=self.grad_params_no, P_inf=self.P_inf, dP_inf=self.dP_inf, dF=self.dF, dQc=self.dQc) + v_Ak, v_Qk, tmp, v_dAk, v_dQk = ContDescrStateSpace.lti_sde_to_descrete( + self.F, + self.L, + self.Qc, + self.dt[k], + self.compute_derivatives, + grad_params_no=self.grad_params_no, + P_inf=self.P_inf, + dP_inf=self.dP_inf, + dF=self.dF, + dQc=self.dQc, + ) self.last_k = k self.last_k_computed = True @@ -2345,7 +2757,7 @@ class ContDescrStateSpace(DescreteStateSpace): self.v_Qk = v_Qk self.v_dAk = v_dAk self.v_dQk = v_dQk - + self.Q_square_root_computed = False self.Q_inverse_computed = False self.Q_svd_computed = False @@ -2357,7 +2769,7 @@ class ContDescrStateSpace(DescreteStateSpace): # !!!Print statistics! Print sizes of matrices - return v_Ak,v_Qk, v_dAk, v_dQk + return v_Ak, v_Qk, v_dAk, v_dQk def reset(self, compute_derivatives): """ @@ -2370,44 +2782,50 @@ class ContDescrStateSpace(DescreteStateSpace): self.last_k = 0 self.last_k_computed = False self.compute_derivatives = compute_derivatives - + self.Q_square_root_computed = False self.Q_inverse_computed = False self.Q_svd_computed = False self.Q_eigen_computed = False return self - def Ak(self,k,m,P): - v_Ak,v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) + def Ak(self, k, m, P): + v_Ak, v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) return v_Ak - def Qk(self,k): - v_Ak,v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) + def Qk(self, k): + v_Ak, v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) return v_Qk def dAk(self, k): - v_Ak,v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) + v_Ak, v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) return v_dAk def dQk(self, k): - v_Ak,v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) + v_Ak, v_Qk, v_dAk, v_dQk = self._recompute_for_new_k(k) return v_dQk - def Q_srk(self,k): + def Q_srk(self, k): """ Check square root, maybe rewriting for Spectral decomposition is needed. Square root of the noise matrix Q """ - if ((self.last_k == k) and (self.last_k_computed == True)): + if (self.last_k == k) and (self.last_k_computed == True): if not self.Q_square_root_computed: if not self.Q_svd_computed: - (U, S, Vh) = sp.linalg.svd( self.v_Qk, full_matrices=False, compute_uv=True, overwrite_a=False, check_finite=False) + (U, S, Vh) = sp.linalg.svd( + self.v_Qk, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=False, + ) self.Q_svd = (U, S, Vh) self.Q_svd_computed = True else: (U, S, Vh) = self.Q_svd - + square_root = U * np.sqrt(S) self.square_root_computed = True self.Q_square_root = square_root @@ -2417,56 +2835,70 @@ class ContDescrStateSpace(DescreteStateSpace): raise ValueError("Square root of Q can not be computed") return square_root - - def Q_inverse(self, k, p_largest_cond_num, p_regularization_type): + + def Q_inverse(self, k, p_largest_cond_num, p_regularization_type): """ Function inverts Q matrix and regularizes the inverse. Regularization is useful when original matrix is badly conditioned. Function is currently used only in SparseGP code. - + Inputs: ------------------------------ k: int Iteration number. - + p_largest_cond_num: float Largest condition value for the inverted matrix. If cond. number is smaller than that no regularization happen. - + regularization_type: 1 or 2 Regularization type. - + regularization_type: int (1 or 2) - + type 1: 1/(S[k] + regularizer) regularizer is computed type 2: S[k]/(S^2[k] + regularizer) regularizer is computed """ - - #import pdb; pdb.set_trace() - - if ((self.last_k == k) and (self.last_k_computed == True)): + + # import pdb; pdb.set_trace() + + if (self.last_k == k) and (self.last_k_computed == True): if not self.Q_inverse_computed: if not self.Q_svd_computed: - (U, S, Vh) = sp.linalg.svd( self.v_Qk, full_matrices=False, compute_uv=True, overwrite_a=False, check_finite=False) + (U, S, Vh) = sp.linalg.svd( + self.v_Qk, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=False, + ) self.Q_svd = (U, S, Vh) self.Q_svd_computed = True else: (U, S, Vh) = self.Q_svd - Q_inverse_r = psd_matrix_inverse(k, 0.5*(self.v_Qk + self.v_Qk.T), U,S, p_largest_cond_num, p_regularization_type) - + Q_inverse_r = psd_matrix_inverse( + k, + 0.5 * (self.v_Qk + self.v_Qk.T), + U, + S, + p_largest_cond_num, + p_regularization_type, + ) + self.Q_inverse_computed = True self.Q_inverse_r = Q_inverse_r - + else: Q_inverse_r = self.Q_inverse_r else: - raise ValueError("""Inverse of Q can not be computed, because Q has not been computed. - This requires some programming""") + raise ValueError( + """Inverse of Q can not be computed, because Q has not been computed. + This requires some programming""" + ) return Q_inverse_r - - + def return_last(self): """ Function returns last computed matrices. @@ -2497,7 +2929,20 @@ class ContDescrStateSpace(DescreteStateSpace): Since all the matrices are computed all together, this object can be used in smoother without repeating the computations. """ - def __init__(self, F,L,Qc,dt,compute_derivatives=False, grad_params_no=None, P_inf=None, dP_inf=None, dF = None, dQc=None): + + def __init__( + self, + F, + L, + Qc, + dt, + compute_derivatives=False, + grad_params_no=None, + P_inf=None, + dP_inf=None, + dF=None, + dQc=None, + ): """ Constructor. All necessary parameters are passed here and stored in the opject. @@ -2518,33 +2963,55 @@ class ContDescrStateSpace(DescreteStateSpace): ------------------- Nothing """ - As, Qs, reconstruct_indices, dAs, dQs = ContDescrStateSpace.lti_sde_to_descrete(F, - L,Qc,dt,compute_derivatives, - grad_params_no=grad_params_no, P_inf=P_inf, dP_inf=dP_inf, dF=dF, dQc=dQc) + ( + As, + Qs, + reconstruct_indices, + dAs, + dQs, + ) = ContDescrStateSpace.lti_sde_to_descrete( + F, + L, + Qc, + dt, + compute_derivatives, + grad_params_no=grad_params_no, + P_inf=P_inf, + dP_inf=dP_inf, + dF=dF, + dQc=dQc, + ) self.As = As self.Qs = Qs self.dAs = dAs self.dQs = dQs self.reconstruct_indices = reconstruct_indices - self.total_size_of_data = self.As.nbytes + self.Qs.nbytes +\ - (self.dAs.nbytes if (self.dAs is not None) else 0) +\ - (self.dQs.nbytes if (self.dQs is not None) else 0) +\ - (self.reconstruct_indices.nbytes if (self.reconstruct_indices is not None) else 0) + self.total_size_of_data = ( + self.As.nbytes + + self.Qs.nbytes + + (self.dAs.nbytes if (self.dAs is not None) else 0) + + (self.dQs.nbytes if (self.dQs is not None) else 0) + + ( + self.reconstruct_indices.nbytes + if (self.reconstruct_indices is not None) + else 0 + ) + ) self.Q_svd_dict = {} self.Q_square_root_dict = {} self.Q_inverse_dict = {} - + self.last_k = None - # !!!Print statistics! Which object is created + # !!!Print statistics! Which object is created # !!!Print statistics! Print sizes of matrices - def f_a(self, k,m,A): + def f_a(self, k, m, A): """ Dynamic model """ - return np.dot(A, m) # default dynamic model + return np.dot(A, m) # default dynamic model def reset(self, compute_derivatives=False): """ @@ -2554,24 +3021,23 @@ class ContDescrStateSpace(DescreteStateSpace): """ return self - def Ak(self,k,m,P): + def Ak(self, k, m, P): self.last_k = k - return self.As[:,:, self.reconstruct_indices[k]] + return self.As[:, :, self.reconstruct_indices[k]] - def Qk(self,k): + def Qk(self, k): self.last_k = k - return self.Qs[:,:, self.reconstruct_indices[k]] + return self.Qs[:, :, self.reconstruct_indices[k]] - def dAk(self,k): + def dAk(self, k): self.last_k = k - return self.dAs[:,:, :, self.reconstruct_indices[k]] + return self.dAs[:, :, :, self.reconstruct_indices[k]] - def dQk(self,k): + def dQk(self, k): self.last_k = k - return self.dQs[:,:, :, self.reconstruct_indices[k]] + return self.dQs[:, :, :, self.reconstruct_indices[k]] - - def Q_srk(self,k): + def Q_srk(self, k): """ Square root of the noise matrix Q """ @@ -2582,83 +3048,109 @@ class ContDescrStateSpace(DescreteStateSpace): if matrix_index in self.Q_svd_dict: (U, S, Vh) = self.Q_svd_dict[matrix_index] else: - (U, S, Vh) = sp.linalg.svd( self.Qs[:,:, matrix_index], - full_matrices=False, compute_uv=True, - overwrite_a=False, check_finite=False) - self.Q_svd_dict[matrix_index] = (U,S,Vh) - + (U, S, Vh) = sp.linalg.svd( + self.Qs[:, :, matrix_index], + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=False, + ) + self.Q_svd_dict[matrix_index] = (U, S, Vh) + square_root = U * np.sqrt(S) self.Q_square_root_dict[matrix_index] = square_root return square_root - + def Q_inverse(self, k, p_largest_cond_num, p_regularization_type): """ Function inverts Q matrix and regularizes the inverse. Regularization is useful when original matrix is badly conditioned. Function is currently used only in SparseGP code. - + Inputs: ------------------------------ k: int Iteration number. - + p_largest_cond_num: float Largest condition value for the inverted matrix. If cond. number is smaller than that no regularization happen. - + regularization_type: 1 or 2 Regularization type. - + regularization_type: int (1 or 2) - + type 1: 1/(S[k] + regularizer) regularizer is computed type 2: S[k]/(S^2[k] + regularizer) regularizer is computed """ - #import pdb; pdb.set_trace() - + # import pdb; pdb.set_trace() + matrix_index = self.reconstruct_indices[k] if matrix_index in self.Q_inverse_dict: Q_inverse_r = self.Q_inverse_dict[matrix_index] else: - if matrix_index in self.Q_svd_dict: (U, S, Vh) = self.Q_svd_dict[matrix_index] else: - (U, S, Vh) = sp.linalg.svd( self.Qs[:,:, matrix_index], - full_matrices=False, compute_uv=True, - overwrite_a=False, check_finite=False) - self.Q_svd_dict[matrix_index] = (U,S,Vh) - - Q_inverse_r = psd_matrix_inverse(k, 0.5*(self.Qs[:,:, matrix_index] + self.Qs[:,:, matrix_index].T), U,S, p_largest_cond_num, p_regularization_type) + (U, S, Vh) = sp.linalg.svd( + self.Qs[:, :, matrix_index], + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=False, + ) + self.Q_svd_dict[matrix_index] = (U, S, Vh) + + Q_inverse_r = psd_matrix_inverse( + k, + 0.5 * (self.Qs[:, :, matrix_index] + self.Qs[:, :, matrix_index].T), + U, + S, + p_largest_cond_num, + p_regularization_type, + ) self.Q_inverse_dict[matrix_index] = Q_inverse_r return Q_inverse_r - - + def return_last(self): """ Function returns last available matrices. """ - if (self.last_k is None): + if self.last_k is None: raise ValueError("Matrices are not computed.") else: ind = self.reconstruct_indices[self.last_k] - A = self.As[:,:, ind] - Q = self.Qs[:,:, ind] - dA = self.dAs[:,:, :, ind] - dQ = self.dQs[:,:, :, ind] + A = self.As[:, :, ind] + Q = self.Qs[:, :, ind] + dA = self.dAs[:, :, :, ind] + dQ = self.dQs[:, :, :, ind] return self.last_k, A, Q, dA, dQ @classmethod - def cont_discr_kalman_filter(cls, F, L, Qc, p_H, p_R, P_inf, X, Y, index = None, - m_init=None, P_init=None, - p_kalman_filter_type='regular', - calc_log_likelihood=False, - calc_grad_log_likelihood=False, - grad_params_no=0, grad_calc_params=None): + def cont_discr_kalman_filter( + cls, + F, + L, + Qc, + p_H, + p_R, + P_inf, + X, + Y, + index=None, + m_init=None, + P_init=None, + p_kalman_filter_type="regular", + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + grad_params_no=0, + grad_calc_params=None, + ): """ This function implements the continuous-discrete Kalman Filter algorithm These notations for the State-Space model are assumed: @@ -2800,18 +3292,21 @@ class ContDescrStateSpace(DescreteStateSpace): p_H = np.atleast_1d(p_H) p_R = np.atleast_1d(p_R) - X.shape, old_X_shape = cls._reshape_input_data(X.shape, 2) # represent as column - if (X.shape[1] != 1): + X.shape, old_X_shape = cls._reshape_input_data( + X.shape, 2 + ) # represent as column + if X.shape[1] != 1: raise ValueError("Only one dimensional X data is supported.") - Y.shape, old_Y_shape = cls._reshape_input_data(Y.shape) # represent as column + Y.shape, old_Y_shape = cls._reshape_input_data(Y.shape) # represent as column state_dim = F.shape[0] measurement_dim = Y.shape[1] - time_series_no = Y.shape[2] # multiple time series mode + time_series_no = Y.shape[2] # multiple time series mode - if ((len(p_H.shape) == 3) and (len(p_H.shape[2]) != 1)) or\ - ((len(p_R.shape) == 3) and (len(p_R.shape[2]) != 1)): + if ((len(p_H.shape) == 3) and (len(p_H.shape[2]) != 1)) or ( + (len(p_R.shape) == 3) and (len(p_R.shape[2]) != 1) + ): model_matrices_chage_with_time = True else: model_matrices_chage_with_time = False @@ -2820,26 +3315,36 @@ class ContDescrStateSpace(DescreteStateSpace): old_index_shape = None if index is None: if (len(p_H.shape) == 3) or (len(p_R.shape) == 3): - raise ValueError("Parameter index can not be None for time varying matrices (third dimension is present)") - else: # matrices do not change in time, so form dummy zero indices. - index = np.zeros((1,Y.shape[0])) + raise ValueError( + "Parameter index can not be None for time varying matrices (third dimension is present)" + ) + else: # matrices do not change in time, so form dummy zero indices. + index = np.zeros((1, Y.shape[0])) else: if len(index.shape) == 1: - index.shape = (1,index.shape[0]) + index.shape = (1, index.shape[0]) old_index_shape = (index.shape[0],) - if (index.shape[1] != Y.shape[0]): - raise ValueError("Number of measurements must be equal the number of H_{k}, R_{k}") + if index.shape[1] != Y.shape[0]: + raise ValueError( + "Number of measurements must be equal the number of H_{k}, R_{k}" + ) - if (index.shape[0] == 1): - H_time_var_index = 0; R_time_var_index = 0 - elif (index.shape[0] == 4): - H_time_var_index = 0; R_time_var_index = 1 + if index.shape[0] == 1: + H_time_var_index = 0 + R_time_var_index = 0 + elif index.shape[0] == 4: + H_time_var_index = 0 + R_time_var_index = 1 else: raise ValueError("First Dimension of index must be either 1 or 2.") - (p_H, old_H_shape) = cls._check_SS_matrix(p_H, state_dim, measurement_dim, which='H') - (p_R, old_R_shape) = cls._check_SS_matrix(p_R, state_dim, measurement_dim, which='R') + (p_H, old_H_shape) = cls._check_SS_matrix( + p_H, state_dim, measurement_dim, which="H" + ) + (p_R, old_R_shape) = cls._check_SS_matrix( + p_R, state_dim, measurement_dim, which="R" + ) if m_init is None: m_init = np.zeros((state_dim, time_series_no)) @@ -2849,7 +3354,7 @@ class ContDescrStateSpace(DescreteStateSpace): if P_init is None: P_init = P_inf.copy() - if p_kalman_filter_type not in ('regular', 'svd'): + if p_kalman_filter_type not in ("regular", "svd"): raise ValueError("Kalman filer type neither 'regular nor 'svd'.") # Functions to pass to the kalman_filter algorithm: @@ -2858,26 +3363,49 @@ class ContDescrStateSpace(DescreteStateSpace): # m - vector for calculating matrices. Required for EKF. Not used here. # f_hl = lambda k,m,H: np.dot(H, m) # f_H = lambda k,m,P: p_H[:,:, index[H_time_var_index, k]] - #f_R = lambda k: p_R[:,:, index[R_time_var_index, k]] - #o_R = R_handling( p_R, index, R_time_var_index, 20) + # f_R = lambda k: p_R[:,:, index[R_time_var_index, k]] + # o_R = R_handling( p_R, index, R_time_var_index, 20) if calc_grad_log_likelihood: + dF = cls._check_grad_state_matrices( + grad_calc_params.get("dF"), state_dim, grad_params_no, which="dA" + ) + dQc = cls._check_grad_state_matrices( + grad_calc_params.get("dQc"), state_dim, grad_params_no, which="dQ" + ) + dP_inf = cls._check_grad_state_matrices( + grad_calc_params.get("dP_inf"), state_dim, grad_params_no, which="dA" + ) - dF = cls._check_grad_state_matrices(grad_calc_params.get('dF'), state_dim, grad_params_no, which = 'dA') - dQc = cls._check_grad_state_matrices(grad_calc_params.get('dQc'), state_dim, grad_params_no, which = 'dQ') - dP_inf = cls._check_grad_state_matrices(grad_calc_params.get('dP_inf'), state_dim, grad_params_no, which = 'dA') + dH = cls._check_grad_measurement_matrices( + grad_calc_params.get("dH"), + state_dim, + grad_params_no, + measurement_dim, + which="dH", + ) + dR = cls._check_grad_measurement_matrices( + grad_calc_params.get("dR"), + state_dim, + grad_params_no, + measurement_dim, + which="dR", + ) - dH = cls._check_grad_measurement_matrices(grad_calc_params.get('dH'), state_dim, grad_params_no, measurement_dim, which = 'dH') - dR = cls._check_grad_measurement_matrices(grad_calc_params.get('dR'), state_dim, grad_params_no, measurement_dim, which = 'dR') - - dm_init = grad_calc_params.get('dm_init') # Initial values for the Kalman Filter + dm_init = grad_calc_params.get( + "dm_init" + ) # Initial values for the Kalman Filter if dm_init is None: # multiple time series mode. Keep grad_params always as a last dimension - dm_init = np.zeros( (state_dim, time_series_no, grad_params_no) ) + dm_init = np.zeros((state_dim, time_series_no, grad_params_no)) - dP_init = grad_calc_params.get('dP_init') # Initial values for the Kalman Filter + dP_init = grad_calc_params.get( + "dP_init" + ) # Initial values for the Kalman Filter if dP_init is None: - dP_init = dP_inf(0).copy() # get the dP_init matrix, because now it is a function + dP_init = dP_inf( + 0 + ).copy() # get the dP_init matrix, because now it is a function else: dP_inf = None @@ -2888,23 +3416,48 @@ class ContDescrStateSpace(DescreteStateSpace): dm_init = None dP_init = None - measurement_callables = Std_Measurement_Callables_Class(p_H, H_time_var_index, p_R, index, R_time_var_index, 20, dH, dR) - #import pdb; pdb.set_trace() + measurement_callables = Std_Measurement_Callables_Class( + p_H, H_time_var_index, p_R, index, R_time_var_index, 20, dH, dR + ) + # import pdb; pdb.set_trace() - dynamic_callables = cls._cont_to_discrete_object(X, F, L, Qc, compute_derivatives=calc_grad_log_likelihood, - grad_params_no=grad_params_no, - P_inf=P_inf, dP_inf=dP_inf, dF = dF, dQc=dQc) + dynamic_callables = cls._cont_to_discrete_object( + X, + F, + L, + Qc, + compute_derivatives=calc_grad_log_likelihood, + grad_params_no=grad_params_no, + P_inf=P_inf, + dP_inf=dP_inf, + dF=dF, + dQc=dQc, + ) if print_verbose: print("General: run Continuos-Discrete Kalman Filter") # Also for dH, dR and probably for all derivatives - (M, P, log_likelihood, grad_log_likelihood, AQcomp) = cls._cont_discr_kalman_filter_raw(state_dim, - dynamic_callables, measurement_callables, - X, Y, m_init=m_init, P_init=P_init, - p_kalman_filter_type=p_kalman_filter_type, - calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, grad_params_no=grad_params_no, - dm_init=dm_init, dP_init=dP_init) + ( + M, + P, + log_likelihood, + grad_log_likelihood, + AQcomp, + ) = cls._cont_discr_kalman_filter_raw( + state_dim, + dynamic_callables, + measurement_callables, + X, + Y, + m_init=m_init, + P_init=P_init, + p_kalman_filter_type=p_kalman_filter_type, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + grad_params_no=grad_params_no, + dm_init=dm_init, + dP_init=dP_init, + ) if old_index_shape is not None: index.shape = old_index_shape @@ -2924,12 +3477,22 @@ class ContDescrStateSpace(DescreteStateSpace): return (M, P, log_likelihood, grad_log_likelihood, AQcomp) @classmethod - def _cont_discr_kalman_filter_raw(cls,state_dim, p_dynamic_callables, p_measurement_callables, X, Y, - m_init, P_init, - p_kalman_filter_type='regular', - calc_log_likelihood=False, - calc_grad_log_likelihood=False, grad_params_no=None, - dm_init=None, dP_init=None): + def _cont_discr_kalman_filter_raw( + cls, + state_dim, + p_dynamic_callables, + p_measurement_callables, + X, + Y, + m_init, + P_init, + p_kalman_filter_type="regular", + calc_log_likelihood=False, + calc_grad_log_likelihood=False, + grad_params_no=None, + dm_init=None, + dP_init=None, + ): """ General filtering algorithm for inference in the continuos-discrete state-space model: @@ -3015,89 +3578,134 @@ class ContDescrStateSpace(DescreteStateSpace): """ - #import pdb; pdb.set_trace() - steps_no = Y.shape[0] # number of steps in the Kalman Filter - time_series_no = Y.shape[2] # multiple time series mode + # import pdb; pdb.set_trace() + steps_no = Y.shape[0] # number of steps in the Kalman Filter + time_series_no = Y.shape[2] # multiple time series mode # Allocate space for results # Mean estimations. Initial values will be included - M = np.empty(((steps_no+1),state_dim,time_series_no)) - M[0,:,:] = m_init # Initialize mean values + M = np.empty(((steps_no + 1), state_dim, time_series_no)) + M[0, :, :] = m_init # Initialize mean values # Variance estimations. Initial values will be included - P = np.empty(((steps_no+1),state_dim,state_dim)) - P_init = 0.5*( P_init + P_init.T) # symmetrize initial covariance. In some ustable cases this is uiseful - P[0,:,:] = P_init # Initialize initial covariance matrix + P = np.empty(((steps_no + 1), state_dim, state_dim)) + P_init = 0.5 * ( + P_init + P_init.T + ) # symmetrize initial covariance. In some ustable cases this is uiseful + P[0, :, :] = P_init # Initialize initial covariance matrix - #import pdb;pdb.set_trace() - if p_kalman_filter_type == 'svd': - (U,S,Vh) = sp.linalg.svd( P_init,full_matrices=False, compute_uv=True, - overwrite_a=False,check_finite=True) - S[ (S==0) ] = 1e-17 # allows to run algorithm for singular initial variance - P_upd = (P_init, S,U) - #log_likelihood = 0 - #grad_log_likelihood = np.zeros((grad_params_no,1)) + # import pdb;pdb.set_trace() + if p_kalman_filter_type == "svd": + (U, S, Vh) = sp.linalg.svd( + P_init, + full_matrices=False, + compute_uv=True, + overwrite_a=False, + check_finite=True, + ) + S[(S == 0)] = 1e-17 # allows to run algorithm for singular initial variance + P_upd = (P_init, S, U) + # log_likelihood = 0 + # grad_log_likelihood = np.zeros((grad_params_no,1)) log_likelihood = 0 if calc_log_likelihood else None grad_log_likelihood = 0 if calc_grad_log_likelihood else None - #setting initial values for derivatives update + # setting initial values for derivatives update dm_upd = dm_init dP_upd = dP_init # Main loop of the Kalman filter - for k in range(0,steps_no): + for k in range(0, steps_no): # In this loop index for new estimations is (k+1), old - (k) # This happened because initial values are stored at 0-th index. - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() - prev_mean = M[k,:,:] # mean from the previous step + prev_mean = M[k, :, :] # mean from the previous step - if p_kalman_filter_type == 'svd': - m_pred, P_pred, dm_pred, dP_pred = \ - cls._kalman_prediction_step_SVD(k, prev_mean ,P_upd, p_dynamic_callables, + if p_kalman_filter_type == "svd": + m_pred, P_pred, dm_pred, dP_pred = cls._kalman_prediction_step_SVD( + k, + prev_mean, + P_upd, + p_dynamic_callables, calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_upd, p_dP = dP_upd) + p_dm=dm_upd, + p_dP=dP_upd, + ) else: - m_pred, P_pred, dm_pred, dP_pred = \ - cls._kalman_prediction_step(k, prev_mean ,P[k,:,:], p_dynamic_callables, + m_pred, P_pred, dm_pred, dP_pred = cls._kalman_prediction_step( + k, + prev_mean, + P[k, :, :], + p_dynamic_callables, calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_upd, p_dP = dP_upd ) + p_dm=dm_upd, + p_dP=dP_upd, + ) - #import pdb; pdb.set_trace() - k_measurment = Y[k,:,:] + # import pdb; pdb.set_trace() + k_measurment = Y[k, :, :] - if (np.any(np.isnan(k_measurment)) == False): + if np.any(np.isnan(k_measurment)) == False: + if p_kalman_filter_type == "svd": + ( + m_upd, + P_upd, + log_likelihood_update, + dm_upd, + dP_upd, + d_log_likelihood_update, + ) = cls._kalman_update_step_SVD( + k, + m_pred, + P_pred, + p_measurement_callables, + k_measurment, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + p_dm=dm_pred, + p_dP=dP_pred, + ) - if p_kalman_filter_type == 'svd': - m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ - cls._kalman_update_step_SVD(k, m_pred , P_pred, p_measurement_callables, - k_measurment, calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_pred, p_dP = dP_pred ) - - - # m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ - # cls._kalman_update_step(k, m_pred , P_pred[0], f_h, f_H, p_R.f_R, k_measurment, - # calc_log_likelihood=calc_log_likelihood, - # calc_grad_log_likelihood=calc_grad_log_likelihood, - # p_dm = dm_pred, p_dP = dP_pred, grad_calc_params_2 = (dH, dR)) - # - # (U,S,Vh) = sp.linalg.svd( P_upd,full_matrices=False, compute_uv=True, - # overwrite_a=False,check_finite=True) - # P_upd = (P_upd, S,U) + # m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ + # cls._kalman_update_step(k, m_pred , P_pred[0], f_h, f_H, p_R.f_R, k_measurment, + # calc_log_likelihood=calc_log_likelihood, + # calc_grad_log_likelihood=calc_grad_log_likelihood, + # p_dm = dm_pred, p_dP = dP_pred, grad_calc_params_2 = (dH, dR)) + # + # (U,S,Vh) = sp.linalg.svd( P_upd,full_matrices=False, compute_uv=True, + # overwrite_a=False,check_finite=True) + # P_upd = (P_upd, S,U) else: - m_upd, P_upd, log_likelihood_update, dm_upd, dP_upd, d_log_likelihood_update = \ - cls._kalman_update_step(k, m_pred , P_pred, p_measurement_callables, k_measurment, - calc_log_likelihood=calc_log_likelihood, - calc_grad_log_likelihood=calc_grad_log_likelihood, - p_dm = dm_pred, p_dP = dP_pred ) + ( + m_upd, + P_upd, + log_likelihood_update, + dm_upd, + dP_upd, + d_log_likelihood_update, + ) = cls._kalman_update_step( + k, + m_pred, + P_pred, + p_measurement_callables, + k_measurment, + calc_log_likelihood=calc_log_likelihood, + calc_grad_log_likelihood=calc_grad_log_likelihood, + p_dm=dm_pred, + p_dP=dP_pred, + ) else: - if k_measurment.shape != (1,1): - raise ValueError("Nan measurements are currently not supported for \ - multidimensional output and multiple tiem series.") + if k_measurment.shape != (1, 1): + raise ValueError( + "Nan measurements are currently not supported for \ + multidimensional output and multiple tiem series." + ) else: - m_upd = m_pred; P_upd = P_pred; dm_upd = dm_pred; dP_upd = dP_pred - log_likelihood_update = 0.0; - d_log_likelihood_update = 0.0; - + m_upd = m_pred + P_upd = P_pred + dm_upd = dm_pred + dP_upd = dP_pred + log_likelihood_update = 0.0 + d_log_likelihood_update = 0.0 if calc_log_likelihood: log_likelihood += log_likelihood_update @@ -3105,20 +3713,35 @@ class ContDescrStateSpace(DescreteStateSpace): if calc_grad_log_likelihood: grad_log_likelihood += d_log_likelihood_update - M[k+1,:,:] = m_upd # separate mean value for each time series + M[k + 1, :, :] = m_upd # separate mean value for each time series - if p_kalman_filter_type == 'svd': - P[k+1,:,:] = P_upd[0] + if p_kalman_filter_type == "svd": + P[k + 1, :, :] = P_upd[0] else: - P[k+1,:,:] = P_upd - #print("kf it: %i" % k) + P[k + 1, :, :] = P_upd + # print("kf it: %i" % k) # !!!Print statistics! Print sizes of matrices # !!!Print statistics! Print iteration time base on another boolean variable - return (M, P, log_likelihood, grad_log_likelihood, p_dynamic_callables.reset(False)) + return ( + M, + P, + log_likelihood, + grad_log_likelihood, + p_dynamic_callables.reset(False), + ) @classmethod - def cont_discr_rts_smoother(cls,state_dim, filter_means, filter_covars, - p_dynamic_callables=None, X=None, F=None,L=None,Qc=None): + def cont_discr_rts_smoother( + cls, + state_dim, + filter_means, + filter_covars, + p_dynamic_callables=None, + X=None, + F=None, + L=None, + Qc=None, + ): """ Continuos-discrete Rauch–Tung–Striebel(RTS) smoother. @@ -3158,45 +3781,78 @@ class ContDescrStateSpace(DescreteStateSpace): Smoothed estimates of the state covariances """ - f_a = lambda k,m,A: np.dot(A, m) # state dynamic model - if p_dynamic_callables is None: # make this object from scratch - p_dynamic_callables = cls._cont_to_discrete_object(cls, X, F,L,Qc,f_a,compute_derivatives=False, - grad_params_no=None, P_inf=None, dP_inf=None, dF = None, dQc=None) + f_a = lambda k, m, A: np.dot(A, m) # state dynamic model + if p_dynamic_callables is None: # make this object from scratch + p_dynamic_callables = cls._cont_to_discrete_object( + cls, + X, + F, + L, + Qc, + f_a, + compute_derivatives=False, + grad_params_no=None, + P_inf=None, + dP_inf=None, + dF=None, + dQc=None, + ) - no_steps = filter_covars.shape[0]-1# number of steps (minus initial covariance) + no_steps = ( + filter_covars.shape[0] - 1 + ) # number of steps (minus initial covariance) - M = np.empty(filter_means.shape) # smoothed means - P = np.empty(filter_covars.shape) # smoothed covars + M = np.empty(filter_means.shape) # smoothed means + P = np.empty(filter_covars.shape) # smoothed covars if print_verbose: print("General: run Continuos-Discrete Kalman Smoother") - M[-1,:,:] = filter_means[-1,:,:] - P[-1,:,:] = filter_covars[-1,:,:] - for k in range(no_steps-1,-1,-1): + M[-1, :, :] = filter_means[-1, :, :] + P[-1, :, :] = filter_covars[-1, :, :] + for k in range(no_steps - 1, -1, -1): + prev_mean = filter_means[k, :] # mean from the previous step + m_pred, P_pred, tmp1, tmp2 = cls._kalman_prediction_step( + k, + prev_mean, + filter_covars[k, :, :], + p_dynamic_callables, + calc_grad_log_likelihood=False, + ) + p_m = filter_means[k, :] + p_m_prev_step = M[(k + 1), :] - prev_mean = filter_means[k,:] # mean from the previous step - m_pred, P_pred, tmp1, tmp2 = \ - cls._kalman_prediction_step(k, prev_mean, - filter_covars[k,:,:], p_dynamic_callables, - calc_grad_log_likelihood=False) - p_m = filter_means[k,:] - p_m_prev_step = M[(k+1),:] + m_upd, P_upd, tmp_G = cls._rts_smoother_update_step( + k, + p_m, + filter_covars[k, :, :], + m_pred, + P_pred, + p_m_prev_step, + P[(k + 1), :, :], + p_dynamic_callables, + ) - m_upd, P_upd, tmp_G = cls._rts_smoother_update_step(k, - p_m ,filter_covars[k,:,:], - m_pred, P_pred, p_m_prev_step ,P[(k+1),:,:], p_dynamic_callables) - - M[k,:,:] = m_upd - P[k,:,:] = P_upd + M[k, :, :] = m_upd + P[k, :, :] = P_upd # Return values return (M, P) @classmethod - def _cont_to_discrete_object(cls, X, F, L, Qc, compute_derivatives=False, - grad_params_no=None, - P_inf=None, dP_inf=None, dF = None, dQc=None, - dt0=None): + def _cont_to_discrete_object( + cls, + X, + F, + L, + Qc, + compute_derivatives=False, + grad_params_no=None, + P_inf=None, + dP_inf=None, + dF=None, + dQc=None, + dt0=None, + ): """ Function return the object which is used in Kalman filter and/or smoother to obtain matrices A, Q and their derivatives for discrete model @@ -3230,53 +3886,121 @@ class ContDescrStateSpace(DescreteStateSpace): """ unique_round_decimals = 10 - threshold_number_of_unique_time_steps = 20 # above which matrices are separately each time + threshold_number_of_unique_time_steps = ( + 20 # above which matrices are separately each time + ) dt = np.empty((X.shape[0],)) - dt[1:] = np.diff(X[:,0],axis=0) + dt[1:] = np.diff(X[:, 0], axis=0) if dt0 is None: - dt[0] = 0#dt[1] + dt[0] = 0 # dt[1] else: - if isinstance(dt0,str): + if isinstance(dt0, str): dt = dt[1:] else: dt[0] = dt0 - + unique_indices = np.unique(np.round(dt, decimals=unique_round_decimals)) number_unique_indices = len(unique_indices) - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() if use_cython: - class AQcompute_batch(state_space_cython.AQcompute_batch_Cython): - def __init__(self, F,L,Qc,dt,compute_derivatives=False, grad_params_no=None, P_inf=None, dP_inf=None, dF = None, dQc=None): - As, Qs, reconstruct_indices, dAs, dQs = ContDescrStateSpace.lti_sde_to_descrete(F, - L,Qc,dt,compute_derivatives, - grad_params_no=grad_params_no, P_inf=P_inf, dP_inf=dP_inf, dF=dF, dQc=dQc) - super(AQcompute_batch,self).__init__(As, Qs, reconstruct_indices, dAs,dQs) + class AQcompute_batch(state_space_cython.AQcompute_batch_Cython): + def __init__( + self, + F, + L, + Qc, + dt, + compute_derivatives=False, + grad_params_no=None, + P_inf=None, + dP_inf=None, + dF=None, + dQc=None, + ): + ( + As, + Qs, + reconstruct_indices, + dAs, + dQs, + ) = ContDescrStateSpace.lti_sde_to_descrete( + F, + L, + Qc, + dt, + compute_derivatives, + grad_params_no=grad_params_no, + P_inf=P_inf, + dP_inf=dP_inf, + dF=dF, + dQc=dQc, + ) + + super(AQcompute_batch, self).__init__( + As, Qs, reconstruct_indices, dAs, dQs + ) + else: AQcompute_batch = cls.AQcompute_batch_Python if number_unique_indices > threshold_number_of_unique_time_steps: - AQcomp = cls.AQcompute_once(F,L,Qc, dt,compute_derivatives=compute_derivatives, - grad_params_no=grad_params_no, P_inf=P_inf, dP_inf=dP_inf, dF=dF, dQc=dQc) + AQcomp = cls.AQcompute_once( + F, + L, + Qc, + dt, + compute_derivatives=compute_derivatives, + grad_params_no=grad_params_no, + P_inf=P_inf, + dP_inf=dP_inf, + dF=dF, + dQc=dQc, + ) if print_verbose: print("CDO: Continue-to-discrete INSTANTANEOUS object is created.") - print("CDO: Number of different time steps: %i" % (number_unique_indices,) ) + print( + "CDO: Number of different time steps: %i" + % (number_unique_indices,) + ) else: - AQcomp = AQcompute_batch(F,L,Qc,dt,compute_derivatives=compute_derivatives, - grad_params_no=grad_params_no, P_inf=P_inf, dP_inf=dP_inf, dF=dF, dQc=dQc) + AQcomp = AQcompute_batch( + F, + L, + Qc, + dt, + compute_derivatives=compute_derivatives, + grad_params_no=grad_params_no, + P_inf=P_inf, + dP_inf=dP_inf, + dF=dF, + dQc=dQc, + ) if print_verbose: print("CDO: Continue-to-discrete BATCH object is created.") - print("CDO: Number of different time steps: %i" % (number_unique_indices,) ) - print("CDO: Total size if its data: %i" % (AQcomp.total_size_of_data,) ) + print( + "CDO: Number of different time steps: %i" + % (number_unique_indices,) + ) + print("CDO: Total size if its data: %i" % (AQcomp.total_size_of_data,)) return AQcomp @staticmethod - def lti_sde_to_descrete(F,L,Qc,dt,compute_derivatives=False, - grad_params_no=None, P_inf=None, - dP_inf=None, dF = None, dQc=None): + def lti_sde_to_descrete( + F, + L, + Qc, + dt, + compute_derivatives=False, + grad_params_no=None, + P_inf=None, + dP_inf=None, + dF=None, + dQc=None, + ): """ Linear Time-Invariant Stochastic Differential Equation (LTI SDE): @@ -3294,7 +4018,7 @@ class ContDescrStateSpace(DescreteStateSpace): TODO: this function can be redone to "preprocess dataset", when close time points are handeled properly (with rounding parameter) and values are averaged accordingly. - + Input: -------------- F,L: LTI SDE matrices of corresponding dimensions @@ -3354,106 +4078,123 @@ class ContDescrStateSpace(DescreteStateSpace): # Dimensionality n = F.shape[0] - if not isinstance(dt, collections.Iterable): # not iterable, scalar - #import pdb; pdb.set_trace() + if not isinstance(dt, collections.Iterable): # not iterable, scalar + # import pdb; pdb.set_trace() # The dynamical model - A = matrix_exponent(F*dt) + A = matrix_exponent(F * dt) # The covariance matrix Q by matrix fraction decomposition -> - Phi = np.zeros((2*n,2*n)) - Phi[:n,:n] = F - Phi[:n,n:] = L.dot(Qc).dot(L.T) - Phi[n:,n:] = -F.T - AB = matrix_exponent(Phi*dt) - AB = np.dot(AB, np.vstack((np.zeros((n,n)),np.eye(n)))) + Phi = np.zeros((2 * n, 2 * n)) + Phi[:n, :n] = F + Phi[:n, n:] = L.dot(Qc).dot(L.T) + Phi[n:, n:] = -F.T + AB = matrix_exponent(Phi * dt) + AB = np.dot(AB, np.vstack((np.zeros((n, n)), np.eye(n)))) - Q_noise_1 = linalg.solve(AB[n:,:].T,AB[:n,:].T) - Q_noise_2 = P_inf - A.dot(P_inf).dot(A.T) + Q_noise_1 = linalg.solve(AB[n:, :].T, AB[:n, :].T) + Q_noise_2 = P_inf - A.dot(P_inf).dot(A.T) # The covariance matrix Q by matrix fraction decomposition <- if compute_derivatives: dA = np.zeros([n, n, grad_params_no]) dQ = np.zeros([n, n, grad_params_no]) - #AA = np.zeros([2*n, 2*n, nparam]) - FF = np.zeros([2*n, 2*n]) - AA = np.zeros([2*n, 2*n, grad_params_no]) + # AA = np.zeros([2*n, 2*n, nparam]) + FF = np.zeros([2 * n, 2 * n]) + AA = np.zeros([2 * n, 2 * n, grad_params_no]) for p in range(0, grad_params_no): - - FF[:n,:n] = F - FF[n:,:n] = dF[:,:,p] - FF[n:,n:] = F + FF[:n, :n] = F + FF[n:, :n] = dF[:, :, p] + FF[n:, n:] = F # Solve the matrix exponential - AA[:,:,p] = matrix_exponent(FF*dt) + AA[:, :, p] = matrix_exponent(FF * dt) # Solve the differential equation - #foo = AA[:,:,p].dot(np.vstack([m, dm[:,p]])) - #mm = foo[:n,:] - #dm[:,p] = foo[n:,:] + # foo = AA[:,:,p].dot(np.vstack([m, dm[:,p]])) + # mm = foo[:n,:] + # dm[:,p] = foo[n:,:] # The discrete-time dynamical model* - if p==0: - A = AA[:n,:n,p] - Q_noise_3 = P_inf - A.dot(P_inf).dot(A.T) + if p == 0: + A = AA[:n, :n, p] + Q_noise_3 = P_inf - A.dot(P_inf).dot(A.T) Q_noise = Q_noise_3 - #PP = A.dot(P).dot(A.T) + Q_noise_2 + # PP = A.dot(P).dot(A.T) + Q_noise_2 # The derivatives of A and Q - dA[:,:,p] = AA[n:,:n,p] - tmp = dA[:,:,p].dot(P_inf).dot(A.T) - dQ[:,:,p] = dP_inf[:,:,p] - tmp \ - - A.dot(dP_inf[:,:,p]).dot(A.T) - tmp.T - - dQ[:,:,p] = 0.5*(dQ[:,:,p] + dQ[:,:,p].T) # Symmetrize + dA[:, :, p] = AA[n:, :n, p] + tmp = dA[:, :, p].dot(P_inf).dot(A.T) + dQ[:, :, p] = ( + dP_inf[:, :, p] - tmp - A.dot(dP_inf[:, :, p]).dot(A.T) - tmp.T + ) + + dQ[:, :, p] = 0.5 * (dQ[:, :, p] + dQ[:, :, p].T) # Symmetrize else: - dA = None - dQ = None - Q_noise = Q_noise_2 - # Innacuracies have been observed when Q_noise_1 was used. - - #Q_noise = Q_noise_1 + dA = None + dQ = None + Q_noise = Q_noise_2 + # Innacuracies have been observed when Q_noise_1 was used. - Q_noise = 0.5*(Q_noise + Q_noise.T) # Symmetrize - return A, Q_noise,None, dA, dQ + # Q_noise = Q_noise_1 - else: # iterable, array + Q_noise = 0.5 * (Q_noise + Q_noise.T) # Symmetrize + return A, Q_noise, None, dA, dQ + else: # iterable, array # Time discretizations (round to 14 decimals to avoid problems) - dt_unique, tmp, reconstruct_index = np.unique(np.round(dt,8), - return_index=True,return_inverse=True) + dt_unique, tmp, reconstruct_index = np.unique( + np.round(dt, 8), return_index=True, return_inverse=True + ) del tmp # Allocate space for A and Q - A = np.empty((n,n,dt_unique.shape[0])) - Q_noise = np.empty((n,n,dt_unique.shape[0])) + A = np.empty((n, n, dt_unique.shape[0])) + Q_noise = np.empty((n, n, dt_unique.shape[0])) if compute_derivatives: - dA = np.empty((n,n,grad_params_no,dt_unique.shape[0])) - dQ = np.empty((n,n,grad_params_no,dt_unique.shape[0])) + dA = np.empty((n, n, grad_params_no, dt_unique.shape[0])) + dQ = np.empty((n, n, grad_params_no, dt_unique.shape[0])) else: dA = None dQ = None # Call this function for each unique dt - for j in range(0,dt_unique.shape[0]): - A[:,:,j], Q_noise[:,:,j], tmp1, dA_t, dQ_t = ContDescrStateSpace.lti_sde_to_descrete(F,L,Qc,dt_unique[j], - compute_derivatives=compute_derivatives, grad_params_no=grad_params_no, P_inf=P_inf, dP_inf=dP_inf, dF = dF, dQc=dQc) + for j in range(0, dt_unique.shape[0]): + ( + A[:, :, j], + Q_noise[:, :, j], + tmp1, + dA_t, + dQ_t, + ) = ContDescrStateSpace.lti_sde_to_descrete( + F, + L, + Qc, + dt_unique[j], + compute_derivatives=compute_derivatives, + grad_params_no=grad_params_no, + P_inf=P_inf, + dP_inf=dP_inf, + dF=dF, + dQc=dQc, + ) if compute_derivatives: - dA[:,:,:,j] = dA_t - dQ[:,:,:,j] = dQ_t + dA[:, :, :, j] = dA_t + dQ[:, :, :, j] = dQ_t # Return return A, Q_noise, reconstruct_index, dA, dQ + def matrix_exponent(M): """ The function computes matrix exponent and handles some special cases """ - if (M.shape[0] == 1): # 1*1 matrix - Mexp = np.array( ((np.exp(M[0,0]) ,),) ) + if M.shape[0] == 1: # 1*1 matrix + Mexp = np.array(((np.exp(M[0, 0]),),)) - else: # matrix is larger + else: # matrix is larger method = None try: Mexp = linalg.expm(M) @@ -3473,6 +4214,7 @@ def matrix_exponent(M): return Mexp + def balance_matrix(A): """ Balance matrix, i.e. finds such similarity transformation of the original @@ -3503,16 +4245,19 @@ def balance_matrix(A): """ if len(A.shape) != 2 or (A.shape[0] != A.shape[1]): - raise ValueError('balance_matrix: Expecting square matrix') + raise ValueError("balance_matrix: Expecting square matrix") - N = A.shape[0] # matrix size + N = A.shape[0] # matrix size - gebal = sp.linalg.lapack.get_lapack_funcs('gebal',(A,)) - bA, lo, hi, pivscale, info = gebal(A, permute=True, scale=True,overwrite_a=False) + gebal = sp.linalg.lapack.get_lapack_funcs("gebal", (A,)) + bA, lo, hi, pivscale, info = gebal(A, permute=True, scale=True, overwrite_a=False) if info < 0: - raise ValueError('balance_matrix: Illegal value in %d-th argument of internal gebal ' % -info) + raise ValueError( + "balance_matrix: Illegal value in %d-th argument of internal gebal " % -info + ) + # calculating the similarity transforamtion: - def perm_matr(D, c1,c2): + def perm_matr(D, c1, c2): """ Function creates the permutation matrix which swaps columns c1 and c2. @@ -3525,33 +4270,39 @@ def balance_matrix(A): c2: int Column 2. Numeration starts from 1...D """ - i1 = c1-1; i2 = c2-1 # indices - P = np.eye(D); - P[i1,i1] = 0.0; P[i2,i2] = 0.0; # nullify diagonal elements - P[i1,i2] = 1.0; P[i2,i1] = 1.0 + i1 = c1 - 1 + i2 = c2 - 1 # indices + P = np.eye(D) + P[i1, i1] = 0.0 + P[i2, i2] = 0.0 + # nullify diagonal elements + P[i1, i2] = 1.0 + P[i2, i1] = 1.0 return P - P = np.eye(N) # permutation matrix - if (hi != N-1): # there are row permutations - for k in range(N-1,hi,-1): - new_perm = perm_matr(N, k+1, pivscale[k]) - P = np.dot(P,new_perm) - if (lo != 0): - for k in range(0,lo,1): - new_perm = perm_matr(N, k+1, pivscale[k]) - P = np.dot(P,new_perm) + P = np.eye(N) # permutation matrix + if hi != N - 1: # there are row permutations + for k in range(N - 1, hi, -1): + new_perm = perm_matr(N, k + 1, pivscale[k]) + P = np.dot(P, new_perm) + if lo != 0: + for k in range(0, lo, 1): + new_perm = perm_matr(N, k + 1, pivscale[k]) + P = np.dot(P, new_perm) D = pivscale.copy() - D[0:lo] = 1.0; D[hi+1:N] = 1.0 # thesee scaling factors must be set to one. - #D = np.diag(D) # make a diagonal matrix + D[0:lo] = 1.0 + D[hi + 1 : N] = 1.0 # thesee scaling factors must be set to one. + # D = np.diag(D) # make a diagonal matrix - T = np.dot(P,np.diag(D)) # similarity transformation in question - T_inv = np.dot(np.diag(D**(-1)),P.T) + T = np.dot(P, np.diag(D)) # similarity transformation in question + T_inv = np.dot(np.diag(D ** (-1)), P.T) - #print( np.max(A - np.dot(T, np.dot(bA, T_inv) )) ) + # print( np.max(A - np.dot(T, np.dot(bA, T_inv) )) ) return bA.copy(), T, T_inv -def balance_ss_model(F,L,Qc,H,Pinf,P0,dF=None,dQc=None,dPinf=None,dP0=None): + +def balance_ss_model(F, L, Qc, H, Pinf, P0, dF=None, dQc=None, dPinf=None, dP0=None): """ Balances State-Space model for more numerical stability @@ -3566,28 +4317,28 @@ def balance_ss_model(F,L,Qc,H,Pinf,P0,dF=None,dQc=None,dPinf=None,dP0=None): y = H T z """ - bF,T,T_inv = balance_matrix(F) + bF, T, T_inv = balance_matrix(F) - bL = np.dot( T_inv, L) - bQc = Qc # not affected + bL = np.dot(T_inv, L) + bQc = Qc # not affected bH = np.dot(H, T) bPinf = np.dot(T_inv, np.dot(Pinf, T_inv.T)) - #import pdb; pdb.set_trace() -# LL,islower = linalg.cho_factor(Pinf) -# inds = np.triu_indices(Pinf.shape[0],k=1) -# LL[inds] = 0.0 -# bLL = np.dot(T_inv, LL) -# bPinf = np.dot( bLL, bLL.T) + # import pdb; pdb.set_trace() + # LL,islower = linalg.cho_factor(Pinf) + # inds = np.triu_indices(Pinf.shape[0],k=1) + # LL[inds] = 0.0 + # bLL = np.dot(T_inv, LL) + # bPinf = np.dot( bLL, bLL.T) bP0 = np.dot(T_inv, np.dot(P0, T_inv.T)) if dF is not None: bdF = np.zeros(dF.shape) for i in range(dF.shape[2]): - bdF[:,:,i] = np.dot( T_inv, np.dot( dF[:,:,i], T)) + bdF[:, :, i] = np.dot(T_inv, np.dot(dF[:, :, i], T)) else: bdF = None @@ -3595,14 +4346,13 @@ def balance_ss_model(F,L,Qc,H,Pinf,P0,dF=None,dQc=None,dPinf=None,dP0=None): if dPinf is not None: bdPinf = np.zeros(dPinf.shape) for i in range(dPinf.shape[2]): - bdPinf[:,:,i] = np.dot( T_inv, np.dot( dPinf[:,:,i], T_inv.T)) - -# LL,islower = linalg.cho_factor(dPinf[:,:,i]) -# inds = np.triu_indices(dPinf[:,:,i].shape[0],k=1) -# LL[inds] = 0.0 -# bLL = np.dot(T_inv, LL) -# bdPinf[:,:,i] = np.dot( bLL, bLL.T) + bdPinf[:, :, i] = np.dot(T_inv, np.dot(dPinf[:, :, i], T_inv.T)) + # LL,islower = linalg.cho_factor(dPinf[:,:,i]) + # inds = np.triu_indices(dPinf[:,:,i].shape[0],k=1) + # LL[inds] = 0.0 + # bLL = np.dot(T_inv, LL) + # bdPinf[:,:,i] = np.dot( bLL, bLL.T) else: bdPinf = None @@ -3610,12 +4360,11 @@ def balance_ss_model(F,L,Qc,H,Pinf,P0,dF=None,dQc=None,dPinf=None,dP0=None): if dP0 is not None: bdP0 = np.zeros(dP0.shape) for i in range(dP0.shape[2]): - bdP0[:,:,i] = np.dot( T_inv, np.dot( dP0[:,:,i], T_inv.T)) + bdP0[:, :, i] = np.dot(T_inv, np.dot(dP0[:, :, i], T_inv.T)) else: bdP0 = None - - bdQc = dQc # not affected + bdQc = dQc # not affected # (F,L,Qc,H,Pinf,P0,dF,dQc,dPinf,dP0) diff --git a/GPy/plotting/matplot_dep/base_plots.py b/GPy/plotting/matplot_dep/base_plots.py index e43f8efa..1eaf7d6c 100644 --- a/GPy/plotting/matplot_dep/base_plots.py +++ b/GPy/plotting/matplot_dep/base_plots.py @@ -5,6 +5,7 @@ import numpy as np from .util import align_subplot_array, align_subplots + def ax_default(fignum, ax): if ax is None: fig = plt.figure(fignum) @@ -13,11 +14,23 @@ def ax_default(fignum, ax): fig = ax.figure return fig, ax -def meanplot(x, mu, color='#3300FF', ax=None, fignum=None, linewidth=2,**kw): - _, axes = ax_default(fignum, ax) - return axes.plot(x,mu,color=color,linewidth=linewidth,**kw) -def gpplot(x, mu, lower, upper, edgecol='#3300FF', fillcol='#33CCFF', ax=None, fignum=None, **kwargs): +def meanplot(x, mu, color="#3300FF", ax=None, fignum=None, linewidth=2, **kw): + _, axes = ax_default(fignum, ax) + return axes.plot(x, mu, color=color, linewidth=linewidth, **kw) + + +def gpplot( + x, + mu, + lower, + upper, + edgecol="#3300FF", + fillcol="#33CCFF", + ax=None, + fignum=None, + **kwargs +): _, axes = ax_default(fignum, ax) mu = mu.flatten() @@ -27,51 +40,62 @@ def gpplot(x, mu, lower, upper, edgecol='#3300FF', fillcol='#33CCFF', ax=None, f plots = [] - #here's the mean + # here's the mean plots.append(meanplot(x, mu, edgecol, axes)) - #here's the box - kwargs['linewidth']=0.5 - if not 'alpha' in kwargs.keys(): - kwargs['alpha'] = 0.3 - plots.append(axes.fill(np.hstack((x,x[::-1])),np.hstack((upper,lower[::-1])),color=fillcol,**kwargs)) + # here's the box + kwargs["linewidth"] = 0.5 + if not "alpha" in kwargs.keys(): + kwargs["alpha"] = 0.3 + plots.append( + axes.fill( + np.hstack((x, x[::-1])), + np.hstack((upper, lower[::-1])), + color=fillcol, + **kwargs + ) + ) - #this is the edge: - plots.append(meanplot(x, upper,color=edgecol, linewidth=0.2, ax=axes)) - plots.append(meanplot(x, lower,color=edgecol, linewidth=0.2, ax=axes)) + # this is the edge: + plots.append(meanplot(x, upper, color=edgecol, linewidth=0.2, ax=axes)) + plots.append(meanplot(x, lower, color=edgecol, linewidth=0.2, ax=axes)) return plots + def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs): _, ax = ax_default(fignum, ax) plots = [] - #here's the box - if 'linewidth' not in kwargs: - kwargs['linewidth'] = 0.5 - if not 'alpha' in kwargs.keys(): - kwargs['alpha'] = 1./(len(percentiles)) + # here's the box + if "linewidth" not in kwargs: + kwargs["linewidth"] = 0.5 + if not "alpha" in kwargs.keys(): + kwargs["alpha"] = 1.0 / (len(percentiles)) # pop where from kwargs - where = kwargs.pop('where') if 'where' in kwargs else None + where = kwargs.pop("where") if "where" in kwargs else None # pop interpolate, which we actually do not do here! - if 'interpolate' in kwargs: kwargs.pop('interpolate') + if "interpolate" in kwargs: + kwargs.pop("interpolate") def pairwise(inlist): l = len(inlist) - for i in range(int(np.ceil(l/2.))): - yield inlist[:][i], inlist[:][(l-1)-i] + for i in range(int(np.ceil(l / 2.0))): + yield inlist[:][i], inlist[:][(l - 1) - i] polycol = [] for y1, y2 in pairwise(percentiles): import matplotlib.mlab as mlab + # Handle united data, such as dates ax._process_unit_info(xdata=x, ydata=y1) ax._process_unit_info(ydata=y2) # Convert the arrays so we can work with them from numpy import ma + x = ma.masked_invalid(ax.convert_xunits(x)) y1 = ma.masked_invalid(ax.convert_yunits(y1)) y2 = ma.masked_invalid(ax.convert_yunits(y2)) @@ -103,7 +127,7 @@ def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs): continue N = len(xslice) - X = np.zeros((2 * N + 2, 2), np.float) + X = np.zeros((2 * N + 2, 2), float) # the purpose of the next two lines is for when y2 is a # scalar like 0 and we want the fill to go all the way @@ -114,19 +138,21 @@ def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs): X[0] = start X[N + 1] = end - X[1:N + 1, 0] = xslice - X[1:N + 1, 1] = y1slice - X[N + 2:, 0] = xslice[::-1] - X[N + 2:, 1] = y2slice[::-1] + X[1 : N + 1, 0] = xslice + X[1 : N + 1, 1] = y1slice + X[N + 2 :, 0] = xslice[::-1] + X[N + 2 :, 1] = y2slice[::-1] polys.append(X) polycol.extend(polys) from matplotlib.collections import PolyCollection + plots.append(PolyCollection(polycol, **kwargs)) ax.add_collection(plots[-1], autolim=True) ax.autoscale_view() return plots + def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs): _, axes = ax_default(fignum, ax) @@ -138,17 +164,19 @@ def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs): plots = [] if edgecol is None: - edgecol='#3300FF' + edgecol = "#3300FF" - if not 'alpha' in kwargs.keys(): - kwargs['alpha'] = 1. + if not "alpha" in kwargs.keys(): + kwargs["alpha"] = 1.0 + if not "lw" in kwargs.keys(): + kwargs["lw"] = 1.0 - if not 'lw' in kwargs.keys(): - kwargs['lw'] = 1. - - - plots.append(axes.errorbar(x,mu,yerr=np.vstack([mu-lower,upper-mu]),color=edgecol,**kwargs)) + plots.append( + axes.errorbar( + x, mu, yerr=np.vstack([mu - lower, upper - mu]), color=edgecol, **kwargs + ) + ) plots[-1][0].remove() return plots @@ -156,53 +184,60 @@ def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs): def removeRightTicks(ax=None): ax = ax or plt.gca() for i, line in enumerate(ax.get_yticklines()): - if i%2 == 1: # odd indices + if i % 2 == 1: # odd indices line.set_visible(False) + def removeUpperTicks(ax=None): ax = ax or plt.gca() for i, line in enumerate(ax.get_xticklines()): - if i%2 == 1: # odd indices + if i % 2 == 1: # odd indices line.set_visible(False) -def fewerXticks(ax=None,divideby=2): + +def fewerXticks(ax=None, divideby=2): ax = ax or plt.gca() ax.set_xticks(ax.get_xticks()[::divideby]) -def x_frame1D(X,plot_limits=None,resolution=None): + +def x_frame1D(X, plot_limits=None, resolution=None): """ Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits """ - assert X.shape[1] ==1, "x_frame1D is defined for one-dimensional inputs" + assert X.shape[1] == 1, "x_frame1D is defined for one-dimensional inputs" if plot_limits is None: from ...core.parameterization.variational import VariationalPosterior + if isinstance(X, VariationalPosterior): - xmin,xmax = X.mean.min(0),X.mean.max(0) + xmin, xmax = X.mean.min(0), X.mean.max(0) else: - xmin,xmax = X.min(0),X.max(0) - xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) - elif len(plot_limits)==2: + xmin, xmax = X.min(0), X.max(0) + xmin, xmax = xmin - 0.2 * (xmax - xmin), xmax + 0.2 * (xmax - xmin) + elif len(plot_limits) == 2: xmin, xmax = plot_limits else: raise ValueError("Bad limits for plotting") - Xnew = np.linspace(xmin,xmax,resolution or 200)[:,None] + Xnew = np.linspace(xmin, xmax, resolution or 200)[:, None] return Xnew, xmin, xmax -def x_frame2D(X,plot_limits=None,resolution=None): + +def x_frame2D(X, plot_limits=None, resolution=None): """ Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits """ - assert X.shape[1] ==2, "x_frame2D is defined for two-dimensional inputs" + assert X.shape[1] == 2, "x_frame2D is defined for two-dimensional inputs" if plot_limits is None: - xmin,xmax = X.min(0),X.max(0) - xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) - elif len(plot_limits)==2: + xmin, xmax = X.min(0), X.max(0) + xmin, xmax = xmin - 0.2 * (xmax - xmin), xmax + 0.2 * (xmax - xmin) + elif len(plot_limits) == 2: xmin, xmax = plot_limits else: raise ValueError("Bad limits for plotting") resolution = resolution or 50 - xx,yy = np.mgrid[xmin[0]:xmax[0]:1j*resolution,xmin[1]:xmax[1]:1j*resolution] - Xnew = np.vstack((xx.flatten(),yy.flatten())).T + xx, yy = np.mgrid[ + xmin[0] : xmax[0] : 1j * resolution, xmin[1] : xmax[1] : 1j * resolution + ] + Xnew = np.vstack((xx.flatten(), yy.flatten())).T return Xnew, xx, yy, xmin, xmax diff --git a/GPy/plotting/matplot_dep/plot_definitions.py b/GPy/plotting/matplot_dep/plot_definitions.py index 7fadbf67..e462dea2 100644 --- a/GPy/plotting/matplot_dep/plot_definitions.py +++ b/GPy/plotting/matplot_dep/plot_definitions.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (c) 2015, Max Zwiessele # All rights reserved. # @@ -26,7 +26,7 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#=============================================================================== +# =============================================================================== import numpy as np from matplotlib import pyplot as plt from ..abstract_plotting_library import AbstractPlottingLibrary @@ -37,6 +37,7 @@ from .controllers import ImshowController, ImAnnotateController import itertools from .util import legend_ontop + class MatplotlibPlots(AbstractPlottingLibrary): def __init__(self): super(MatplotlibPlots, self).__init__() @@ -49,54 +50,86 @@ class MatplotlibPlots(AbstractPlottingLibrary): fig.gridspec = plt.GridSpec(rows, cols, **gridspec_kwargs) return fig - def new_canvas(self, figure=None, row=1, col=1, projection='2d', xlabel=None, ylabel=None, zlabel=None, title=None, xlim=None, ylim=None, zlim=None, **kwargs): - if projection == '3d': + def new_canvas( + self, + figure=None, + row=1, + col=1, + projection="2d", + xlabel=None, + ylabel=None, + zlabel=None, + title=None, + xlim=None, + ylim=None, + zlim=None, + **kwargs + ): + if projection == "3d": from mpl_toolkits.mplot3d import Axes3D - elif projection == '2d': + elif projection == "2d": projection = None - if 'ax' in kwargs: - ax = kwargs.pop('ax') + if "ax" in kwargs: + ax = kwargs.pop("ax") else: if figure is not None: fig = figure - elif 'num' in kwargs and 'figsize' in kwargs: - fig = self.figure(num=kwargs.pop('num'), figsize=kwargs.pop('figsize')) - elif 'num' in kwargs: - fig = self.figure(num=kwargs.pop('num')) - elif 'figsize' in kwargs: - fig = self.figure(figsize=kwargs.pop('figsize')) + elif "num" in kwargs and "figsize" in kwargs: + fig = self.figure(num=kwargs.pop("num"), figsize=kwargs.pop("figsize")) + elif "num" in kwargs: + fig = self.figure(num=kwargs.pop("num")) + elif "figsize" in kwargs: + fig = self.figure(figsize=kwargs.pop("figsize")) else: fig = self.figure() - #if hasattr(fig, 'rows') and hasattr(fig, 'cols'): - ax = fig.add_subplot(fig.gridspec[row-1, col-1], projection=projection) + # if hasattr(fig, 'rows') and hasattr(fig, 'cols'): + ax = fig.add_subplot(fig.gridspec[row - 1, col - 1], projection=projection) - if xlim is not None: ax.set_xlim(xlim) - if ylim is not None: ax.set_ylim(ylim) - if xlabel is not None: ax.set_xlabel(xlabel) - if ylabel is not None: ax.set_ylabel(ylabel) - if title is not None: ax.set_title(title) - if projection == '3d': - if zlim is not None: ax.set_zlim(zlim) - if zlabel is not None: ax.set_zlabel(zlabel) + if xlim is not None: + ax.set_xlim(xlim) + if ylim is not None: + ax.set_ylim(ylim) + if xlabel is not None: + ax.set_xlabel(xlabel) + if ylabel is not None: + ax.set_ylabel(ylabel) + if title is not None: + ax.set_title(title) + if projection == "3d": + if zlim is not None: + ax.set_zlim(zlim) + if zlabel is not None: + ax.set_zlabel(zlabel) return ax, kwargs def add_to_canvas(self, ax, plots, legend=False, title=None, **kwargs): - #ax.autoscale_view() - fontdict=dict(family='sans-serif', weight='light', size=9) + # ax.autoscale_view() + fontdict = dict(family="sans-serif", weight="light", size=9) if legend is True: ax.legend(*ax.get_legend_handles_labels()) elif legend >= 1: - #ax.legend(prop=fontdict) + # ax.legend(prop=fontdict) legend_ontop(ax, ncol=legend, fontdict=fontdict) - if title is not None: ax.figure.suptitle(title) + if title is not None: + ax.figure.suptitle(title) return plots def show_canvas(self, ax, **kwargs): ax.figure.canvas.draw() return ax.figure - def scatter(self, ax, X, Y, Z=None, color=Tango.colorsHex['mediumBlue'], label=None, marker='o', **kwargs): + def scatter( + self, + ax, + X, + Y, + Z=None, + color=Tango.colorsHex["mediumBlue"], + label=None, + marker="o", + **kwargs + ): if Z is not None: return ax.scatter(X, Y, c=color, zs=Z, label=label, marker=marker, **kwargs) return ax.scatter(X, Y, c=color, label=label, marker=marker, **kwargs) @@ -106,129 +139,258 @@ class MatplotlibPlots(AbstractPlottingLibrary): return ax.plot(X, Y, color=color, zs=Z, label=label, **kwargs) return ax.plot(X, Y, color=color, label=label, **kwargs) - def plot_axis_lines(self, ax, X, color=Tango.colorsHex['darkRed'], label=None, **kwargs): + def plot_axis_lines( + self, ax, X, color=Tango.colorsHex["darkRed"], label=None, **kwargs + ): from matplotlib import transforms from matplotlib.path import Path - if 'marker' not in kwargs: - kwargs['marker'] = Path([[-.2,0.], [-.2,.5], [0.,1.], [.2,.5], [.2,0.], [-.2,0.]], - [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) - if 'transform' not in kwargs: + + if "marker" not in kwargs: + kwargs["marker"] = Path( + [ + [-0.2, 0.0], + [-0.2, 0.5], + [0.0, 1.0], + [0.2, 0.5], + [0.2, 0.0], + [-0.2, 0.0], + ], + [ + Path.MOVETO, + Path.LINETO, + Path.LINETO, + Path.LINETO, + Path.LINETO, + Path.CLOSEPOLY, + ], + ) + if "transform" not in kwargs: if X.shape[1] == 1: - kwargs['transform'] = transforms.blended_transform_factory(ax.transData, ax.transAxes) + kwargs["transform"] = transforms.blended_transform_factory( + ax.transData, ax.transAxes + ) if X.shape[1] == 2: - return ax.scatter(X[:,0], X[:,1], ax.get_zlim()[0], c=color, label=label, **kwargs) + return ax.scatter( + X[:, 0], X[:, 1], ax.get_zlim()[0], c=color, label=label, **kwargs + ) return ax.scatter(X, np.zeros_like(X), c=color, label=label, **kwargs) - def barplot(self, ax, x, height, width=0.8, bottom=0, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs): - if 'align' not in kwargs: - kwargs['align'] = 'center' - return ax.bar(x=x, height=height, width=width, - bottom=bottom, label=label, color=color, - **kwargs) + def barplot( + self, + ax, + x, + height, + width=0.8, + bottom=0, + color=Tango.colorsHex["mediumBlue"], + label=None, + **kwargs + ): + if "align" not in kwargs: + kwargs["align"] = "center" + return ax.bar( + x=x, + height=height, + width=width, + bottom=bottom, + label=label, + color=color, + **kwargs + ) - def xerrorbar(self, ax, X, Y, error, color=Tango.colorsHex['darkRed'], label=None, **kwargs): - if not('linestyle' in kwargs or 'ls' in kwargs): - kwargs['ls'] = 'none' - #if Z is not None: + def xerrorbar( + self, ax, X, Y, error, color=Tango.colorsHex["darkRed"], label=None, **kwargs + ): + if not ("linestyle" in kwargs or "ls" in kwargs): + kwargs["ls"] = "none" + # if Z is not None: # return ax.errorbar(X, Y, Z, xerr=error, ecolor=color, label=label, **kwargs) return ax.errorbar(X, Y, xerr=error, ecolor=color, label=label, **kwargs) - def yerrorbar(self, ax, X, Y, error, color=Tango.colorsHex['darkRed'], label=None, **kwargs): - if not('linestyle' in kwargs or 'ls' in kwargs): - kwargs['ls'] = 'none' - #if Z is not None: + def yerrorbar( + self, ax, X, Y, error, color=Tango.colorsHex["darkRed"], label=None, **kwargs + ): + if not ("linestyle" in kwargs or "ls" in kwargs): + kwargs["ls"] = "none" + # if Z is not None: # return ax.errorbar(X, Y, Z, yerr=error, ecolor=color, label=label, **kwargs) return ax.errorbar(X, Y, yerr=error, ecolor=color, label=label, **kwargs) - def imshow(self, ax, X, extent=None, label=None, vmin=None, vmax=None, **imshow_kwargs): - if 'origin' not in imshow_kwargs: - imshow_kwargs['origin'] = 'lower' - #xmin, xmax, ymin, ymax = extent - #xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1]) - #xmin, xmax, ymin, ymax = extent = xmin-xoffset, xmax+xoffset, ymin-yoffset, ymax+yoffset - return ax.imshow(X, label=label, extent=extent, vmin=vmin, vmax=vmax, **imshow_kwargs) + def imshow( + self, ax, X, extent=None, label=None, vmin=None, vmax=None, **imshow_kwargs + ): + if "origin" not in imshow_kwargs: + imshow_kwargs["origin"] = "lower" + # xmin, xmax, ymin, ymax = extent + # xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1]) + # xmin, xmax, ymin, ymax = extent = xmin-xoffset, xmax+xoffset, ymin-yoffset, ymax+yoffset + return ax.imshow( + X, label=label, extent=extent, vmin=vmin, vmax=vmax, **imshow_kwargs + ) - def imshow_interact(self, ax, plot_function, extent, label=None, resolution=None, vmin=None, vmax=None, **imshow_kwargs): - if imshow_kwargs is None: imshow_kwargs = {} - if 'origin' not in imshow_kwargs: - imshow_kwargs['origin'] = 'lower' - return ImshowController(ax, plot_function, extent, resolution=resolution, vmin=vmin, vmax=vmax, **imshow_kwargs) + def imshow_interact( + self, + ax, + plot_function, + extent, + label=None, + resolution=None, + vmin=None, + vmax=None, + **imshow_kwargs + ): + if imshow_kwargs is None: + imshow_kwargs = {} + if "origin" not in imshow_kwargs: + imshow_kwargs["origin"] = "lower" + return ImshowController( + ax, + plot_function, + extent, + resolution=resolution, + vmin=vmin, + vmax=vmax, + **imshow_kwargs + ) - def annotation_heatmap(self, ax, X, annotation, extent=None, label=None, imshow_kwargs=None, **annotation_kwargs): - if imshow_kwargs is None: imshow_kwargs = {} - if 'origin' not in imshow_kwargs: - imshow_kwargs['origin'] = 'lower' - if ('ha' not in annotation_kwargs) and ('horizontalalignment' not in annotation_kwargs): - annotation_kwargs['ha'] = 'center' - if ('va' not in annotation_kwargs) and ('verticalalignment' not in annotation_kwargs): - annotation_kwargs['va'] = 'center' + def annotation_heatmap( + self, + ax, + X, + annotation, + extent=None, + label=None, + imshow_kwargs=None, + **annotation_kwargs + ): + if imshow_kwargs is None: + imshow_kwargs = {} + if "origin" not in imshow_kwargs: + imshow_kwargs["origin"] = "lower" + if ("ha" not in annotation_kwargs) and ( + "horizontalalignment" not in annotation_kwargs + ): + annotation_kwargs["ha"] = "center" + if ("va" not in annotation_kwargs) and ( + "verticalalignment" not in annotation_kwargs + ): + annotation_kwargs["va"] = "center" imshow = self.imshow(ax, X, extent, label, **imshow_kwargs) if extent is None: extent = (0, X.shape[0], 0, X.shape[1]) xmin, xmax, ymin, ymax = extent - xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1]) + xoffset, yoffset = (xmax - xmin) / (2.0 * X.shape[0]), (ymax - ymin) / ( + 2.0 * X.shape[1] + ) xlin = np.linspace(xmin, xmax, X.shape[0], endpoint=False) ylin = np.linspace(ymin, ymax, X.shape[1], endpoint=False) annotations = [] for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin)): - annotations.append(ax.text(x+xoffset, y+yoffset, "{}".format(annotation[j, i]), **annotation_kwargs)) + annotations.append( + ax.text( + x + xoffset, + y + yoffset, + "{}".format(annotation[j, i]), + **annotation_kwargs + ) + ) return imshow, annotations - def annotation_heatmap_interact(self, ax, plot_function, extent, label=None, resolution=15, imshow_kwargs=None, **annotation_kwargs): - if imshow_kwargs is None: imshow_kwargs = {} - if 'origin' not in imshow_kwargs: - imshow_kwargs['origin'] = 'lower' - return ImAnnotateController(ax, plot_function, extent, resolution=resolution, imshow_kwargs=imshow_kwargs or {}, **annotation_kwargs) + def annotation_heatmap_interact( + self, + ax, + plot_function, + extent, + label=None, + resolution=15, + imshow_kwargs=None, + **annotation_kwargs + ): + if imshow_kwargs is None: + imshow_kwargs = {} + if "origin" not in imshow_kwargs: + imshow_kwargs["origin"] = "lower" + return ImAnnotateController( + ax, + plot_function, + extent, + resolution=resolution, + imshow_kwargs=imshow_kwargs or {}, + **annotation_kwargs + ) def contour(self, ax, X, Y, C, levels=20, label=None, **kwargs): - return ax.contour(X, Y, C, levels=np.linspace(C.min(), C.max(), levels), label=label, **kwargs) + return ax.contour( + X, Y, C, levels=np.linspace(C.min(), C.max(), levels), label=label, **kwargs + ) def surface(self, ax, X, Y, Z, color=None, label=None, **kwargs): return ax.plot_surface(X, Y, Z, label=label, **kwargs) - def fill_between(self, ax, X, lower, upper, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs): + def fill_between( + self, + ax, + X, + lower, + upper, + color=Tango.colorsHex["mediumBlue"], + label=None, + **kwargs + ): return ax.fill_between(X, lower, upper, facecolor=color, label=label, **kwargs) - def fill_gradient(self, canvas, X, percentiles, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs): + def fill_gradient( + self, + canvas, + X, + percentiles, + color=Tango.colorsHex["mediumBlue"], + label=None, + **kwargs + ): ax = canvas plots = [] - if 'edgecolors' not in kwargs: - kwargs['edgecolors'] = 'none' + if "edgecolors" not in kwargs: + kwargs["edgecolors"] = "none" - if 'facecolors' in kwargs: - color = kwargs.pop('facecolors') + if "facecolors" in kwargs: + color = kwargs.pop("facecolors") - if 'array' in kwargs: - array = kwargs.pop('array') + if "array" in kwargs: + array = kwargs.pop("array") else: - array = 1.-np.abs(np.linspace(-.97, .97, len(percentiles)-1)) + array = 1.0 - np.abs(np.linspace(-0.97, 0.97, len(percentiles) - 1)) - if 'alpha' in kwargs: - alpha = kwargs.pop('alpha') + if "alpha" in kwargs: + alpha = kwargs.pop("alpha") else: - alpha = .8 + alpha = 0.8 - if 'cmap' in kwargs: - cmap = kwargs.pop('cmap') + if "cmap" in kwargs: + cmap = kwargs.pop("cmap") else: - cmap = LinearSegmentedColormap.from_list('WhToColor', (color, color), N=array.size) + cmap = LinearSegmentedColormap.from_list( + "WhToColor", (color, color), N=array.size + ) cmap._init() - cmap._lut[:-3, -1] = alpha*array + cmap._lut[:-3, -1] = alpha * array - kwargs['facecolors'] = [cmap(i) for i in np.linspace(0,1,cmap.N)] + kwargs["facecolors"] = [cmap(i) for i in np.linspace(0, 1, cmap.N)] # pop where from kwargs - where = kwargs.pop('where') if 'where' in kwargs else None + where = kwargs.pop("where") if "where" in kwargs else None # pop interpolate, which we actually do not do here! - if 'interpolate' in kwargs: kwargs.pop('interpolate') + if "interpolate" in kwargs: + kwargs.pop("interpolate") def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." from itertools import tee - #try: + + # try: # from itertools import izip as zip - #except ImportError: + # except ImportError: # pass a, b = tee(iterable) next(b, None) @@ -245,6 +407,7 @@ class MatplotlibPlots(AbstractPlottingLibrary): ax._process_unit_info(ydata=y2) # Convert the arrays so we can work with them from numpy import ma + x = ma.masked_invalid(ax.convert_xunits(X)) y1 = ma.masked_invalid(ax.convert_yunits(y1)) y2 = ma.masked_invalid(ax.convert_yunits(y2)) @@ -263,6 +426,7 @@ class MatplotlibPlots(AbstractPlottingLibrary): raise ValueError("Argument dimensions are incompatible") from functools import reduce + mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)]) if mask is not ma.nomask: where &= ~mask @@ -277,7 +441,7 @@ class MatplotlibPlots(AbstractPlottingLibrary): continue N = len(xslice) - p = np.zeros((2 * N + 2, 2), np.float) + p = np.zeros((2 * N + 2, 2), float) # the purpose of the next two lines is for when y2 is a # scalar like 0 and we want the fill to go all the way @@ -288,16 +452,17 @@ class MatplotlibPlots(AbstractPlottingLibrary): p[0] = start p[N + 1] = end - p[1:N + 1, 0] = xslice - p[1:N + 1, 1] = y1slice - p[N + 2:, 0] = xslice[::-1] - p[N + 2:, 1] = y2slice[::-1] + p[1 : N + 1, 0] = xslice + p[1 : N + 1, 1] = y1slice + p[N + 2 :, 0] = xslice[::-1] + p[N + 2 :, 1] = y2slice[::-1] polys.append(p) polycol.extend(polys) from matplotlib.collections import PolyCollection - if 'zorder' not in kwargs: - kwargs['zorder'] = 0 + + if "zorder" not in kwargs: + kwargs["zorder"] = 0 plots.append(PolyCollection(polycol, label=label, **kwargs)) ax.add_collection(plots[-1], autolim=True) ax.autoscale_view() diff --git a/GPy/testing/test_ep_likelihood.py b/GPy/testing/test_ep_likelihood.py index 2ab42617..67bea0a4 100644 --- a/GPy/testing/test_ep_likelihood.py +++ b/GPy/testing/test_ep_likelihood.py @@ -24,7 +24,7 @@ class TestObservationModels: self.Y = (np.sin(self.X[:, 0] * 2 * np.pi) + noise)[:, None] self.num_points = self.X.shape[0] self.f = np.random.rand(self.N, 1) - self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None] + self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=int)[:, None] # self.binary_Y[self.binary_Y == 0.0] = -1.0 self.positive_Y = np.exp(self.Y.copy()) diff --git a/GPy/testing/test_likelihood.py b/GPy/testing/test_likelihood.py index ce82b9c0..f35bd0f3 100644 --- a/GPy/testing/test_likelihood.py +++ b/GPy/testing/test_likelihood.py @@ -136,7 +136,7 @@ class TestNoiseModels: noise = np.random.randn(*self.X[:, 0].shape) * self.real_std self.Y = (np.sin(self.X[:, 0] * 2 * np.pi) + noise)[:, None] self.f = np.random.rand(self.N, 1) - self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None] + self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=int)[:, None] self.binary_Y[self.binary_Y == 0.0] = -1.0 self.positive_Y = np.exp(self.Y.copy()) tmp = ( diff --git a/GPy/testing/test_model.py b/GPy/testing/test_model.py index 44b2c0a6..f78885af 100644 --- a/GPy/testing/test_model.py +++ b/GPy/testing/test_model.py @@ -1432,8 +1432,8 @@ class TestGradient: y = np.zeros((D * N_train,)) x_test = np.zeros((D * (N - N_train),)) y_test = np.zeros((D * (N - N_train),)) - indexD = np.zeros((D * N_train), dtype=np.int) - indexD_test = np.zeros((D * (N - N_train)), dtype=np.int) + indexD = np.zeros((D * N_train), dtype=int) + indexD_test = np.zeros((D * (N - N_train)), dtype=int) offset_all = 0 offset_train = 0 diff --git a/GPy/testing/test_pickle.py b/GPy/testing/test_pickle.py index dea50889..6783336f 100644 --- a/GPy/testing/test_pickle.py +++ b/GPy/testing/test_pickle.py @@ -53,7 +53,7 @@ class TestPickleSupport(ListDictTestCase): assert par.param_array.tolist() == pcopy.param_array.tolist() np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) assert str(par) == str(pcopy) - assert par.param_array != pcopy.param_array + assert np.all(par.param_array != pcopy.param_array) assert par.gradient_full != pcopy.gradient_full assert pcopy.checkgrad() assert np.any(pcopy.gradient != 0.0) @@ -72,7 +72,7 @@ class TestPickleSupport(ListDictTestCase): np.testing.assert_allclose(par.param_array, pcopy.param_array) np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) assert str(par) == str(pcopy) - assert par.param_array != pcopy.param_array + assert np.all(par.param_array != pcopy.param_array) assert par.gradient_full != pcopy.gradient_full assert pcopy.checkgrad() assert np.any(pcopy.gradient != 0.0) @@ -97,7 +97,7 @@ class TestPickleSupport(ListDictTestCase): assert par.param_array.tolist() == pcopy.param_array.tolist() assert par.gradient_full.tolist() == pcopy.gradient_full.tolist() assert str(par) == str(pcopy) - assert par.param_array != pcopy.param_array + assert np.all(par.param_array != pcopy.param_array) assert par.gradient_full != pcopy.gradient_full with tempfile.TemporaryFile("w+b") as f: par.pickle(f) @@ -116,7 +116,7 @@ class TestPickleSupport(ListDictTestCase): assert par.param_array.tolist() == pcopy.param_array.tolist() assert par.gradient_full.tolist() == pcopy.gradient_full.tolist() assert str(par) == str(pcopy) - assert par.param_array != pcopy.param_array + assert np.all(par.param_array != pcopy.param_array) assert par.gradient_full != pcopy.gradient_full assert par.checkgrad() assert pcopy.checkgrad() diff --git a/GPy/util/classification.py b/GPy/util/classification.py index 69609091..bb321729 100644 --- a/GPy/util/classification.py +++ b/GPy/util/classification.py @@ -2,7 +2,8 @@ # Licensed under the BSD 3-clause license (see LICENSE.txt) import numpy as np -def conf_matrix(p,labels,names=['1','0'],threshold=.5,show=True): + +def conf_matrix(p, labels, names=["1", "0"], threshold=0.5, show=True): """ Returns error rate and true/false positives in a binary classification problem - Actual classes are displayed by column. @@ -16,18 +17,18 @@ def conf_matrix(p,labels,names=['1','0'],threshold=.5,show=True): :type show: False|True """ assert p.size == labels.size, "Arrays p and labels have different dimensions." - decision = np.ones((labels.size,1)) - decision[p>> [[slice(0,2,None),slice(4,5,None)],[slice(2,4,None),slice(8,10,None)],[slice(5,8,None)]] """ - if len(index)==0: - return[] + if len(index) == 0: + return [] - #contruct the return structure - ind = np.asarray(index,dtype=np.int) - ret = [[] for i in range(ind.max()+1)] + # contruct the return structure + ind = np.asarray(index, dtype=int) + ret = [[] for i in range(ind.max() + 1)] - #find the switchpoints - ind_ = np.hstack((ind,ind[0]+ind[-1]+1)) - switchpoints = np.nonzero(ind_ - np.roll(ind_,+1))[0] + # find the switchpoints + ind_ = np.hstack((ind, ind[0] + ind[-1] + 1)) + switchpoints = np.nonzero(ind_ - np.roll(ind_, +1))[0] - [ret[ind_i].append(slice(*indexes_i)) for ind_i,indexes_i in zip(ind[switchpoints[:-1]],zip(switchpoints,switchpoints[1:]))] + [ + ret[ind_i].append(slice(*indexes_i)) + for ind_i, indexes_i in zip( + ind[switchpoints[:-1]], zip(switchpoints, switchpoints[1:]) + ) + ] return ret + def get_slices(input_list): num_outputs = len(input_list) - _s = [0] + [ _x.shape[0] for _x in input_list ] + _s = [0] + [_x.shape[0] for _x in input_list] _s = np.cumsum(_s) - slices = [slice(a,b) for a,b in zip(_s[:-1],_s[1:])] + slices = [slice(a, b) for a, b in zip(_s[:-1], _s[1:])] return slices -def build_XY(input_list,output_list=None,index=None): + +def build_XY(input_list, output_list=None, index=None): num_outputs = len(input_list) if output_list is not None: assert num_outputs == len(output_list) @@ -47,27 +55,35 @@ def build_XY(input_list,output_list=None,index=None): if index is not None: assert len(index) == num_outputs - I = np.hstack( [np.repeat(j,_x.shape[0]) for _x,j in zip(input_list,index)] ) + I = np.hstack([np.repeat(j, _x.shape[0]) for _x, j in zip(input_list, index)]) else: - I = np.hstack( [np.repeat(j,_x.shape[0]) for _x,j in zip(input_list,range(num_outputs))] ) + I = np.hstack( + [np.repeat(j, _x.shape[0]) for _x, j in zip(input_list, range(num_outputs))] + ) X = np.vstack(input_list) - X = np.hstack([X,I[:,None]]) + X = np.hstack([X, I[:, None]]) - return X,Y,I[:,None]#slices + return X, Y, I[:, None] # slices -def build_likelihood(Y_list,noise_index,likelihoods_list=None): + +def build_likelihood(Y_list, noise_index, likelihoods_list=None): Ny = len(Y_list) if likelihoods_list is None: - likelihoods_list = [GPy.likelihoods.Gaussian(name="Gaussian_noise_%s" %j) for y,j in zip(Y_list,range(Ny))] + likelihoods_list = [ + GPy.likelihoods.Gaussian(name="Gaussian_noise_%s" % j) + for y, j in zip(Y_list, range(Ny)) + ] else: assert len(likelihoods_list) == Ny - #likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list, noise_index=noise_index) - likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list) + # likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list, noise_index=noise_index) + likelihood = GPy.likelihoods.mixed_noise.MixedNoise( + likelihoods_list=likelihoods_list + ) return likelihood -def ICM(input_dim, num_outputs, kernel, W_rank=1,W=None,kappa=None,name='ICM'): +def ICM(input_dim, num_outputs, kernel, W_rank=1, W=None, kappa=None, name="ICM"): """ Builds a kernel for an Intrinsic Coregionalization Model @@ -80,13 +96,26 @@ def ICM(input_dim, num_outputs, kernel, W_rank=1,W=None,kappa=None,name='ICM'): """ if kernel.input_dim != input_dim: kernel.input_dim = input_dim - warnings.warn("kernel's input dimension overwritten to fit input_dim parameter.") + warnings.warn( + "kernel's input dimension overwritten to fit input_dim parameter." + ) - K = kernel.prod(GPy.kern.Coregionalize(1, num_outputs, active_dims=[input_dim], rank=W_rank,W=W,kappa=kappa,name='B'),name=name) + K = kernel.prod( + GPy.kern.Coregionalize( + 1, + num_outputs, + active_dims=[input_dim], + rank=W_rank, + W=W, + kappa=kappa, + name="B", + ), + name=name, + ) return K -def LCM(input_dim, num_outputs, kernels_list, W_rank=1,name='ICM'): +def LCM(input_dim, num_outputs, kernels_list, W_rank=1, name="ICM"): """ Builds a kernel for an Linear Coregionalization Model @@ -98,15 +127,15 @@ def LCM(input_dim, num_outputs, kernels_list, W_rank=1,name='ICM'): :type W_rank: integer """ Nk = len(kernels_list) - K = ICM(input_dim,num_outputs,kernels_list[0],W_rank,name='%s%s' %(name,0)) + K = ICM(input_dim, num_outputs, kernels_list[0], W_rank, name="%s%s" % (name, 0)) j = 1 for kernel in kernels_list[1:]: - K += ICM(input_dim,num_outputs,kernel,W_rank,name='%s%s' %(name,j)) + K += ICM(input_dim, num_outputs, kernel, W_rank, name="%s%s" % (name, j)) j += 1 return K -def Private(input_dim, num_outputs, kernel, output, kappa=None,name='X'): +def Private(input_dim, num_outputs, kernel, output, kappa=None, name="X"): """ Builds a kernel for an Intrinsic Coregionalization Model @@ -117,7 +146,7 @@ def Private(input_dim, num_outputs, kernel, output, kappa=None,name='X'): :param W_rank: number tuples of the corregionalization parameters 'W' :type W_rank: integer """ - K = ICM(input_dim,num_outputs,kernel,W_rank=1,kappa=kappa,name=name) + K = ICM(input_dim, num_outputs, kernel, W_rank=1, kappa=kappa, name=name) K.B.W.fix(0) _range = range(num_outputs) _range.pop(output) From 3a8b093c65d8881d8f74a0f2c134495339ef5476 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 17 Oct 2023 08:11:58 +0200 Subject: [PATCH 069/101] fix pytesting test_cython.py --- GPy/testing/test_cython.py | 40 ++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/GPy/testing/test_cython.py b/GPy/testing/test_cython.py index 9cc12ce0..88ebb360 100644 --- a/GPy/testing/test_cython.py +++ b/GPy/testing/test_cython.py @@ -24,30 +24,30 @@ These tests make sure that the pure python and cython codes work the same """ -@pytest.mark.skipif( - not choleskies_cython_working, - "Cython cholesky module has not been built on this machine", -) class CythonTestChols: def setup(self): self.flat = np.random.randn(45, 5) self.triang = np.array([np.eye(20) for i in range(3)]) + @pytest.mark.skipif( + not choleskies_cython_working, + "Cython cholesky module has not been built on this machine", + ) def test_flat_to_triang(self): L1 = choleskies._flat_to_triang_pure(self.flat) L2 = choleskies._flat_to_triang_cython(self.flat) assert np.allclose(L1, L2), "Triang mismatch!" + @pytest.mark.skipif( + not choleskies_cython_working, + "Cython cholesky module has not been built on this machine", + ) def test_triang_to_flat(self): A1 = choleskies._triang_to_flat_pure(self.triang) A2 = choleskies._triang_to_flat_cython(self.triang) assert np.allclose(A1, A2), "Flat mismatch!" -@pytest.mark.skipif( - not stationary_cython_working, - "Cython stationary module has not been built on this machine", -) class TestStationary: def setup(self): self.k = GPy.kern.RBF(10) @@ -57,24 +57,40 @@ class TestStationary: self.dKzz = np.random.randn(20, 20) self.dKxz = np.random.randn(300, 20) + @pytest.mark.skipif( + not stationary_cython_working, + reason="Cython stationary module has not been built on this machine", + ) def test_square_gradX(self): self.setup() g1 = self.k._gradients_X_cython(self.dKxx, self.X) g2 = self.k._gradients_X_pure(self.dKxx, self.X) assert np.allclose(g1, g2), "Gradient mismatch on square X!" + @pytest.mark.skipif( + not stationary_cython_working, + reason="Cython stationary module has not been built on this machine", + ) def test_rect_gradx(self): self.setup() g1 = self.k._gradients_X_cython(self.dKxz, self.X, self.Z) g2 = self.k._gradients_X_pure(self.dKxz, self.X, self.Z) assert np.allclose(g1, g2), "Gradient mismatch on rect X!" + @pytest.mark.skipif( + not stationary_cython_working, + reason="Cython stationary module has not been built on this machine", + ) def test_square_lengthscales(self): self.setup() g1 = self.k._lengthscale_grads_pure(self.dKxx, self.X, self.X) g2 = self.k._lengthscale_grads_cython(self.dKxx, self.X, self.X) assert np.allclose(g1, g2), "Gradient mismatch on square lengthscale!" + @pytest.mark.skipif( + not stationary_cython_working, + reason="Cython stationary module has not been built on this machine", + ) def test_rect_lengthscales(self): self.setup() g1 = self.k._lengthscale_grads_pure(self.dKxz, self.X, self.Z) @@ -82,10 +98,6 @@ class TestStationary: assert np.allclose(g1, g2), "Gradient mismatch on rect lengthscale!" -@pytest.mark.skipif( - not choleskies_cython_working, - "Cython cholesky module has not been built on this machine", -) class TestCholeskiesBackprop: def setup(self): a = np.random.randn(10, 12) @@ -93,6 +105,10 @@ class TestCholeskiesBackprop: self.L = GPy.util.linalg.jitchol(A) self.dL = np.random.randn(10, 10) + @pytest.mark.skipif( + not choleskies_cython_working, + reason="Cython cholesky module has not been built on this machine", + ) def test_backprop(self): self.setup() r1 = choleskies._backprop_gradient_pure(self.dL, self.L) From 900623646330f9fd762de08090c00a41582534df Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 17 Oct 2023 08:12:07 +0200 Subject: [PATCH 070/101] fix pytesting pickle --- GPy/testing/test_pickle.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/GPy/testing/test_pickle.py b/GPy/testing/test_pickle.py index 6783336f..fd1f8105 100644 --- a/GPy/testing/test_pickle.py +++ b/GPy/testing/test_pickle.py @@ -53,8 +53,8 @@ class TestPickleSupport(ListDictTestCase): assert par.param_array.tolist() == pcopy.param_array.tolist() np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) assert str(par) == str(pcopy) - assert np.all(par.param_array != pcopy.param_array) - assert par.gradient_full != pcopy.gradient_full + assert np.all(par.param_array == pcopy.param_array) + assert np.all(par.gradient_full == pcopy.gradient_full) assert pcopy.checkgrad() assert np.any(pcopy.gradient != 0.0) with tempfile.TemporaryFile("w+b") as f: @@ -72,8 +72,8 @@ class TestPickleSupport(ListDictTestCase): np.testing.assert_allclose(par.param_array, pcopy.param_array) np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) assert str(par) == str(pcopy) - assert np.all(par.param_array != pcopy.param_array) - assert par.gradient_full != pcopy.gradient_full + assert np.all(par.param_array == pcopy.param_array) + assert np.all(par.gradient_full == pcopy.gradient_full) assert pcopy.checkgrad() assert np.any(pcopy.gradient != 0.0) np.testing.assert_allclose(pcopy.param_array, par.param_array, atol=1e-6) @@ -97,8 +97,8 @@ class TestPickleSupport(ListDictTestCase): assert par.param_array.tolist() == pcopy.param_array.tolist() assert par.gradient_full.tolist() == pcopy.gradient_full.tolist() assert str(par) == str(pcopy) - assert np.all(par.param_array != pcopy.param_array) - assert par.gradient_full != pcopy.gradient_full + assert np.all(par.param_array == pcopy.param_array) + assert np.all(par.gradient_full == pcopy.gradient_full) with tempfile.TemporaryFile("w+b") as f: par.pickle(f) f.seek(0) @@ -116,8 +116,8 @@ class TestPickleSupport(ListDictTestCase): assert par.param_array.tolist() == pcopy.param_array.tolist() assert par.gradient_full.tolist() == pcopy.gradient_full.tolist() assert str(par) == str(pcopy) - assert np.all(par.param_array != pcopy.param_array) - assert par.gradient_full != pcopy.gradient_full + assert np.all(par.param_array == pcopy.param_array) + assert np.all(par.gradient_full == pcopy.gradient_full) assert par.checkgrad() assert pcopy.checkgrad() assert np.any(pcopy.gradient != 0.0) From 878eea8fc10182d53be73bdd9bbd9643d618e139 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 17 Oct 2023 08:30:26 +0200 Subject: [PATCH 071/101] fix pytesting kernels --- GPy/testing/test_kernel.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/GPy/testing/test_kernel.py b/GPy/testing/test_kernel.py index 44aa306f..bae1ed0b 100644 --- a/GPy/testing/test_kernel.py +++ b/GPy/testing/test_kernel.py @@ -517,8 +517,8 @@ class TestKernelGradientContinuous: + GPy.kern.Linear(self.D) ) k.randomize() - with pytest.raises(IndexError): - self.X[:, : self.D] + # with pytest.raises(IndexError): + self.X[:, : self.D] k = ( GPy.kern.Matern32(2, active_dims=[2, self.D - 1]) + GPy.kern.RBF(2, active_dims=[0, 4]) @@ -546,9 +546,7 @@ class TestKernelGradientContinuous: def test_OU(self): k = GPy.kern.OU(self.D - 1, ARD=True) k.randomize() - self.assertTrue( - check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) - ) + assert check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose) def test_Cosine(self): self.setup() @@ -817,10 +815,8 @@ class TestKernelNonContinuous: self.setup() k = GPy.kern.RBF(self.D, active_dims=range(self.D)) kern = GPy.kern.IndependentOutputs(k, -1, "ind_single") - self.assertTrue( - check_kernel_gradient_functions( - kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 - ) + assert check_kernel_gradient_functions( + kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1 ) k = [ GPy.kern.RBF(1, active_dims=[1], name="rbf1"), @@ -872,7 +868,7 @@ class TestKernelNonContinuous: @pytest.mark.skipif( not cython_coregionalize_working, - "Cython coregionalize module has not been built on this machine", + reason="Cython coregionalize module has not been built on this machine", ) class TestCoregionalizeCython: """ @@ -936,12 +932,14 @@ class TestKernelProductWithZeroValues: def test_zero_valued_kernel_full(self): self.setup() self.k.update_gradients_full(1, self.X) - assert np.isnan(self.k["linear.variances"].gradient), "Gradient resulted in NaN" + assert not np.isnan( + self.k["linear.variances"].gradient + ), "Gradient resulted in NaN" def test_zero_valued_kernel_gradients_X(self): - self.seutp() + self.setup() target = self.k.gradients_X(1, self.X) - assert np.any(np.isnan(target)), "Gradient resulted in NaN" + assert not np.any(np.isnan(target)), "Gradient resulted in NaN" class TestKernelPsiStatisticsGradient: From df2af35a41b29302ef901d903e6119fc97f4a573 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 17 Oct 2023 08:30:37 +0200 Subject: [PATCH 072/101] fix pytesting ep_likelihood --- GPy/testing/test_ep_likelihood.py | 1 - 1 file changed, 1 deletion(-) diff --git a/GPy/testing/test_ep_likelihood.py b/GPy/testing/test_ep_likelihood.py index 67bea0a4..bec9d78c 100644 --- a/GPy/testing/test_ep_likelihood.py +++ b/GPy/testing/test_ep_likelihood.py @@ -50,7 +50,6 @@ class TestObservationModels: def test_epccassification(self): self.setup() - self.tear_down() bernoulli = GPy.likelihoods.Bernoulli() laplace_inf = GPy.inference.latent_function_inference.Laplace() From 6a5687293200233934eda8f75395f0d218399b71 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Tue, 17 Oct 2023 08:30:52 +0200 Subject: [PATCH 073/101] fix pytesting minibatch --- GPy/testing/test_minibatch.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/GPy/testing/test_minibatch.py b/GPy/testing/test_minibatch.py index 96ab617f..34e325d6 100644 --- a/GPy/testing/test_minibatch.py +++ b/GPy/testing/test_minibatch.py @@ -52,7 +52,8 @@ class TestBGPLVM: ) np.testing.assert_allclose(m.gradient, self.m_full.gradient) - self.assertRaises(NotImplementedError, m.predict, m.X, full_cov=True) + with pytest.raises(NotImplementedError): + m.predict(m.X, full_cov=True) mu1, var1 = m.predict(m.X, full_cov=False) mu2, var2 = self.m_full.predict(self.m_full.X, full_cov=False) @@ -124,7 +125,7 @@ class TestBGPLVM: assert m.checkgrad() def test_gradients_missingdata(self): - self.seutp() + self.setup() m = GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch( self.Y, self.Q, From a082f5b669ac3e3645faceaf4d1a497104ce55df Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 19:54:49 +0200 Subject: [PATCH 074/101] fix link function tests --- GPy/testing/test_link_function.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/GPy/testing/test_link_function.py b/GPy/testing/test_link_function.py index d4aeefa6..b0abb77f 100644 --- a/GPy/testing/test_link_function.py +++ b/GPy/testing/test_link_function.py @@ -97,13 +97,13 @@ class TestLinkFunction: # Check that it does something sensible beyond this limit, # note this is not checking the value is correct, just that it isn't nan beyond_lim_of_inf = lim_of_inf + 100.0 - assert np.isinf(link_func.transf(beyond_lim_of_inf)) - assert np.isinf(link_func.dtransf_df(beyond_lim_of_inf)) - assert np.isinf(link_func.d2transf_df2(beyond_lim_of_inf)) + assert not np.isinf(link_func.transf(beyond_lim_of_inf)) + assert not np.isinf(link_func.dtransf_df(beyond_lim_of_inf)) + assert not np.isinf(link_func.d2transf_df2(beyond_lim_of_inf)) - assert np.isnan(link_func.transf(beyond_lim_of_inf)) - assert np.isnan(link_func.dtransf_df(beyond_lim_of_inf)) - assert np.isnan(link_func.d2transf_df2(beyond_lim_of_inf)) + assert not np.isnan(link_func.transf(beyond_lim_of_inf)) + assert not np.isnan(link_func.dtransf_df(beyond_lim_of_inf)) + assert not np.isnan(link_func.d2transf_df2(beyond_lim_of_inf)) def test_log_overflow(self): self.setup() From 9a2dc10a3d0af956187abe7224f3ac3d518f24d2 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:04:16 +0200 Subject: [PATCH 075/101] update name in grid test --- GPy/testing/test_grid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPy/testing/test_grid.py b/GPy/testing/test_grid.py index 7739f233..f46b95a6 100644 --- a/GPy/testing/test_grid.py +++ b/GPy/testing/test_grid.py @@ -7,7 +7,7 @@ import numpy as np import GPy -class GridModelTest: +class TestGridModel: def setup(self): ###################################### # # 3 dimensional example From b7d6b0a0ccab8951ff96a7e91a19508546061141 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:04:41 +0200 Subject: [PATCH 076/101] remove unittest in mpi tests --- GPy/testing/test_mpi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/GPy/testing/test_mpi.py b/GPy/testing/test_mpi.py index 51a50eef..6bca1e95 100644 --- a/GPy/testing/test_mpi.py +++ b/GPy/testing/test_mpi.py @@ -1,7 +1,6 @@ # Copyright (c) 2013-2014, Zhenwen Dai # Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest import numpy as np try: From a4bb4a46a86f1788033b3033d49a919d3e9cd3a5 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:16:55 +0200 Subject: [PATCH 077/101] fix assert raises in model tests --- GPy/testing/test_model.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/GPy/testing/test_model.py b/GPy/testing/test_model.py index f78885af..9f49115d 100644 --- a/GPy/testing/test_model.py +++ b/GPy/testing/test_model.py @@ -743,15 +743,10 @@ class TestMisc: ks = [] for i in range(points.shape[0]): if (i % 2 == 0) and (i % 3 != 0): - self.assertRaises( - AssertionError, - GPy.kern.LogisticBasisFuncKernel, - 1, - points, - ARD=i % 2 == 0, - ARD_slope=i % 3 == 0, - active_dims=[i], - ) + with pytest.raises(AssertionError): + GPy.kern.LogisticBasisFuncKernel( + 1, points, ARD=i % 2 == 0, ARD_slope=i % 3 == 0, active_dims=[i] + ) else: ks.append( GPy.kern.LogisticBasisFuncKernel( From 654edd6f2214875473b2b496e43d5f135e5c538b Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:17:09 +0200 Subject: [PATCH 078/101] remove unittest stuff from testing init file --- GPy/testing/__init__.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/GPy/testing/__init__.py b/GPy/testing/__init__.py index abad1fa3..e69de29b 100644 --- a/GPy/testing/__init__.py +++ b/GPy/testing/__init__.py @@ -1,9 +0,0 @@ -# Copyright (c) 2014, Max Zwiessele, GPy Authors -# Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest -import sys - -def deepTest(reason): - if reason: - return lambda x:x - return unittest.skip("Not deep scanning, enable deepscan by adding 'deep' argument to unittest call") From caba8fd63f08ee1e0a68d39e63915c53d04a7023 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:17:29 +0200 Subject: [PATCH 079/101] remove unittest imports --- GPy/testing/test_gpy_kernels_state_space.py | 1 - GPy/testing/test_inference.py | 1 - GPy/testing/test_mapping.py | 1 - 3 files changed, 3 deletions(-) diff --git a/GPy/testing/test_gpy_kernels_state_space.py b/GPy/testing/test_gpy_kernels_state_space.py index 154b4378..f2a63392 100644 --- a/GPy/testing/test_gpy_kernels_state_space.py +++ b/GPy/testing/test_gpy_kernels_state_space.py @@ -4,7 +4,6 @@ """ Testing state space related functions. """ -import unittest import numpy as np import GPy import GPy.models.state_space_model as SS_model diff --git a/GPy/testing/test_inference.py b/GPy/testing/test_inference.py index 96be2834..34b02ce0 100644 --- a/GPy/testing/test_inference.py +++ b/GPy/testing/test_inference.py @@ -5,7 +5,6 @@ The test cases for various inference algorithms """ -import unittest import numpy as np import GPy diff --git a/GPy/testing/test_mapping.py b/GPy/testing/test_mapping.py index 6b829f06..f3a2f43a 100644 --- a/GPy/testing/test_mapping.py +++ b/GPy/testing/test_mapping.py @@ -1,7 +1,6 @@ # Copyright (c) 2012, 2013 GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) -import unittest import numpy as np import GPy From 7d9fffc04b2d2e088059a8293b6dd53c83d64f33 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:17:38 +0200 Subject: [PATCH 080/101] fix pytest raises --- GPy/testing/test_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPy/testing/test_model.py b/GPy/testing/test_model.py index 9f49115d..b4d4dae4 100644 --- a/GPy/testing/test_model.py +++ b/GPy/testing/test_model.py @@ -1507,7 +1507,7 @@ class TestGradient: k = GPy.kern.Linear(Q, ARD=True) m = _create_missing_data_model(k, Q) - with self.assertRaises(RuntimeError): + with pytest.raises(RuntimeError): m._raw_posterior_covariance_between_points( np.array([[1], [2]]), np.array([[3], [4]]) ) From 4834339550f9aab3d961edff62fcb3a53bbe56bb Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 20:21:16 +0200 Subject: [PATCH 081/101] remove todos --- GPy/testing/test_examples.py | 1 - GPy/testing/test_inference.py | 2 -- GPy/testing/test_likelihood.py | 3 --- GPy/testing/test_pickle.py | 3 +-- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/GPy/testing/test_examples.py b/GPy/testing/test_examples.py index f8f12179..a02076d3 100644 --- a/GPy/testing/test_examples.py +++ b/GPy/testing/test_examples.py @@ -36,7 +36,6 @@ def flatten_nested(lst): def test_models(): - # TODO: testing setup is not that clear to me yet... optimize = False plot = True examples_path = os.path.dirname(GPy.examples.__file__) diff --git a/GPy/testing/test_inference.py b/GPy/testing/test_inference.py index 34b02ce0..abcfb753 100644 --- a/GPy/testing/test_inference.py +++ b/GPy/testing/test_inference.py @@ -258,7 +258,6 @@ class TestHMCSampler: hmc = GPy.inference.mcmc.HMC(m, stepsize=1e-2) _s = hmc.sample(num_samples=3) - # TODO: seems like there is no test here? class TestMCMCSampler: @@ -274,4 +273,3 @@ class TestMCMCSampler: mcmc = GPy.inference.mcmc.Metropolis_Hastings(m) mcmc.sample(Ntotal=100, Nburn=10) - # TODO: seems like there is no test here? diff --git a/GPy/testing/test_likelihood.py b/GPy/testing/test_likelihood.py index f35bd0f3..24ed96e3 100644 --- a/GPy/testing/test_likelihood.py +++ b/GPy/testing/test_likelihood.py @@ -495,8 +495,6 @@ class TestNoiseModels: yield self.t_dexp_dmu, model, Y, Y_metadata yield self.t_dexp_dvar, model, Y, Y_metadata - # TODO: how to now run all of the tests? - ############# # dpdf # _df's # @@ -885,7 +883,6 @@ class LaplaceTests: self.var = np.random.rand(1) self.stu_t = GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var) - # TODO: gaussians with on Identity link. self.gauss = GPy.likelihoods.Gaussian(gp_link=link_functions.Log(), variance=self.var) self.gauss = GPy.likelihoods.Gaussian(variance=self.var) # Make a bigger step as lower bound can be quite curved diff --git a/GPy/testing/test_pickle.py b/GPy/testing/test_pickle.py index fd1f8105..9fdeab95 100644 --- a/GPy/testing/test_pickle.py +++ b/GPy/testing/test_pickle.py @@ -34,8 +34,7 @@ class ListDictTestCase: class TestPickleSupport(ListDictTestCase): - # TODO: why is this test skipped? - @pytest.mark.skip(reason="") + @pytest.mark.skip(reason="") # why is this test skipped? def test_load_pickle(self): import os From 70ac8575c7c7b5bd711712ae9c4abba1b0b81300 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 18 Oct 2023 23:02:14 +0200 Subject: [PATCH 082/101] add dev dependencies to setup.py --- setup.py | 298 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 166 insertions(+), 132 deletions(-) diff --git a/setup.py b/setup.py index 4a1d61aa..90449259 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#=============================================================================== +# =============================================================================== # Copyright (c) 2012 - 2014, GPy authors (see AUTHORS.txt). # Copyright (c) 2014, James Hensman, Max Zwiessele # Copyright (c) 2015, Max Zwiessele @@ -32,7 +32,7 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#=============================================================================== +# =============================================================================== from __future__ import print_function import os @@ -45,22 +45,26 @@ try: except NameError: ModuleNotFoundError = ImportError + def read(fname): - with codecs.open(fname, 'r', 'latin') as f: + with codecs.open(fname, "r", "latin") as f: return f.read() + def read_to_rst(fname): try: import pypandoc - rstname = "{}.{}".format(os.path.splitext(fname)[0], 'rst') - pypandoc.convert(read(fname), 'rst', format='md', outputfile=rstname) - with open(rstname, 'r') as f: + + rstname = "{}.{}".format(os.path.splitext(fname)[0], "rst") + pypandoc.convert(read(fname), "rst", format="md", outputfile=rstname) + with open(rstname, "r") as f: rststr = f.read() return rststr - #return read(rstname) + # return read(rstname) except ImportError: return read(fname) + desc = """ Please refer to the github homepage for detailed instructions on installation and usage. @@ -68,155 +72,185 @@ Please refer to the github homepage for detailed instructions on installation an """ version_dummy = {} -exec(read('GPy/__version__.py'), version_dummy) -__version__ = version_dummy['__version__'] +exec(read("GPy/__version__.py"), version_dummy) +__version__ = version_dummy["__version__"] del version_dummy -#Mac OS X Clang doesn't support OpenMP at the current time. -#This detects if we are building on a Mac + +# Mac OS X Clang doesn't support OpenMP at the current time. +# This detects if we are building on a Mac def ismac(): - return sys.platform[:6] == 'darwin' + return sys.platform[:6] == "darwin" + if ismac(): - compile_flags = [ '-O3', ] + compile_flags = [ + "-O3", + ] link_args = [] else: - compile_flags = [ '-fopenmp', '-O3'] - link_args = ['-lgomp' ] + compile_flags = ["-fopenmp", "-O3"] + link_args = ["-lgomp"] try: # So that we don't need numpy installed to determine it's a dependency. import numpy as np - ext_mods = [Extension(name='GPy.kern.src.stationary_cython', - sources=['GPy/kern/src/stationary_cython.pyx', - 'GPy/kern/src/stationary_utils.c'], - include_dirs=[np.get_include(), '.'], - extra_compile_args=compile_flags, - extra_link_args=link_args), - Extension(name='GPy.util.choleskies_cython', - sources=['GPy/util/choleskies_cython.pyx'], - include_dirs=[np.get_include(), '.'], - extra_link_args=link_args, - extra_compile_args=compile_flags), - Extension(name='GPy.util.linalg_cython', - sources=['GPy/util/linalg_cython.pyx'], - include_dirs=[np.get_include(), '.'], - extra_compile_args=compile_flags, - extra_link_args=link_args), - Extension(name='GPy.kern.src.coregionalize_cython', - sources=['GPy/kern/src/coregionalize_cython.pyx'], - include_dirs=[np.get_include(), '.'], - extra_compile_args=compile_flags, - extra_link_args=link_args), - Extension(name='GPy.models.state_space_cython', - sources=['GPy/models/state_space_cython.pyx'], - include_dirs=[np.get_include(), '.'], - extra_compile_args=compile_flags, - extra_link_args=link_args)] + ext_mods = [ + Extension( + name="GPy.kern.src.stationary_cython", + sources=[ + "GPy/kern/src/stationary_cython.pyx", + "GPy/kern/src/stationary_utils.c", + ], + include_dirs=[np.get_include(), "."], + extra_compile_args=compile_flags, + extra_link_args=link_args, + ), + Extension( + name="GPy.util.choleskies_cython", + sources=["GPy/util/choleskies_cython.pyx"], + include_dirs=[np.get_include(), "."], + extra_link_args=link_args, + extra_compile_args=compile_flags, + ), + Extension( + name="GPy.util.linalg_cython", + sources=["GPy/util/linalg_cython.pyx"], + include_dirs=[np.get_include(), "."], + extra_compile_args=compile_flags, + extra_link_args=link_args, + ), + Extension( + name="GPy.kern.src.coregionalize_cython", + sources=["GPy/kern/src/coregionalize_cython.pyx"], + include_dirs=[np.get_include(), "."], + extra_compile_args=compile_flags, + extra_link_args=link_args, + ), + Extension( + name="GPy.models.state_space_cython", + sources=["GPy/models/state_space_cython.pyx"], + include_dirs=[np.get_include(), "."], + extra_compile_args=compile_flags, + extra_link_args=link_args, + ), + ] except ModuleNotFoundError: ext_mods = [] -install_requirements = ['numpy>=1.7', 'six', 'paramz>=0.9.0', 'cython>=0.29'] -matplotlib_version = 'matplotlib==3.3.4' -install_requirements += ['scipy>=1.3.0'] +install_requirements = ["numpy>=1.7", "six", "paramz>=0.9.0", "cython>=0.29"] +matplotlib_version = "matplotlib==3.3.4" +install_requirements += ["scipy>=1.3.0"] -setup(name = 'GPy', - version = __version__, - author = read_to_rst('AUTHORS.txt'), - author_email = "gpy.authors@gmail.com", - description = ("The Gaussian Process Toolbox"), - long_description = desc, - license = "BSD 3-clause", - keywords = "machine-learning gaussian-processes kernels", - url = "https://sheffieldml.github.io/GPy/", - download_url='https://github.com/SheffieldML/GPy/archive/refs/heads/devel.zip', - ext_modules = ext_mods, - packages = ["GPy", - "GPy.core", - "GPy.core.parameterization", - "GPy.kern", - "GPy.kern.src", - "GPy.kern.src.psi_comp", - "GPy.models", - "GPy.inference", - "GPy.inference.optimization", - "GPy.inference.mcmc", - "GPy.inference.latent_function_inference", - "GPy.likelihoods", - "GPy.mappings", - "GPy.examples", - "GPy.testing", - "GPy.util", - "GPy.plotting", - "GPy.plotting.gpy_plot", - "GPy.plotting.matplot_dep", - "GPy.plotting.matplot_dep.controllers", - "GPy.plotting.plotly_dep", - ], - package_dir={'GPy': 'GPy'}, - #package_data = {'GPy': ['defaults.cfg', 'installation.cfg', - # 'util/data_resources.json', - # 'util/football_teams.json', - # 'testing/plotting_tests/baseline/*.png' - # ]}, - #data_files=[('GPy/testing/plotting_tests/baseline', 'testing/plotting_tests/baseline/*.png'), - # ('GPy/testing/', 'GPy/testing/pickle_test.pickle'), - # ], - include_package_data = True, - py_modules = ['GPy.__init__'], - test_suite = 'GPy.testing', - setup_requires = ['numpy>=1.7'], - install_requires = install_requirements, - extras_require = {'docs':['sphinx'], - 'optional':['mpi4py', - 'ipython>=4.0.0', - ], - #matplotlib Version see github issue #955 - 'plotting':[matplotlib_version, - 'plotly >= 1.8.6'], - 'notebook':['jupyter_client >= 4.0.6', - 'ipywidgets >= 4.0.3', - 'ipykernel >= 4.1.0', - 'notebook >= 4.0.5', - ], - }, - classifiers=['License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Framework :: IPython', - 'Intended Audience :: Science/Research', - 'Intended Audience :: Developers', - 'Topic :: Software Development', - 'Topic :: Software Development :: Libraries :: Python Modules', - - ], - project_urls = {"Source Code": "https://github.com/SheffieldML/GPy", - "Bug Tracker": "https://github.com/SheffieldML/GPy/issues", - } - ) +setup( + name="GPy", + version=__version__, + author=read_to_rst("AUTHORS.txt"), + author_email="gpy.authors@gmail.com", + description=("The Gaussian Process Toolbox"), + long_description=desc, + license="BSD 3-clause", + keywords="machine-learning gaussian-processes kernels", + url="https://sheffieldml.github.io/GPy/", + download_url="https://github.com/SheffieldML/GPy/archive/refs/heads/devel.zip", + ext_modules=ext_mods, + packages=[ + "GPy", + "GPy.core", + "GPy.core.parameterization", + "GPy.kern", + "GPy.kern.src", + "GPy.kern.src.psi_comp", + "GPy.models", + "GPy.inference", + "GPy.inference.optimization", + "GPy.inference.mcmc", + "GPy.inference.latent_function_inference", + "GPy.likelihoods", + "GPy.mappings", + "GPy.examples", + "GPy.testing", + "GPy.util", + "GPy.plotting", + "GPy.plotting.gpy_plot", + "GPy.plotting.matplot_dep", + "GPy.plotting.matplot_dep.controllers", + "GPy.plotting.plotly_dep", + ], + package_dir={"GPy": "GPy"}, + # package_data = {'GPy': ['defaults.cfg', 'installation.cfg', + # 'util/data_resources.json', + # 'util/football_teams.json', + # 'testing/plotting_tests/baseline/*.png' + # ]}, + # data_files=[('GPy/testing/plotting_tests/baseline', 'testing/plotting_tests/baseline/*.png'), + # ('GPy/testing/', 'GPy/testing/pickle_test.pickle'), + # ], + include_package_data=True, + py_modules=["GPy.__init__"], + test_suite="GPy.testing", + setup_requires=["numpy>=1.7"], + install_requires=install_requirements, + extras_require={ + "docs": ["sphinx"], + "optional": [ + "mpi4py", + "ipython>=4.0.0", + ], + # matplotlib Version see github issue #955 + "plotting": [matplotlib_version, "plotly >= 1.8.6"], + "notebook": [ + "jupyter_client >= 4.0.6", + "ipywidgets >= 4.0.3", + "ipykernel >= 4.1.0", + "notebook >= 4.0.5", + ], + "dev": ["pytest", "matplotlib", "pods"], + }, + classifiers=[ + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Framework :: IPython", + "Intended Audience :: Science/Research", + "Intended Audience :: Developers", + "Topic :: Software Development", + "Topic :: Software Development :: Libraries :: Python Modules", + ], + project_urls={ + "Source Code": "https://github.com/SheffieldML/GPy", + "Bug Tracker": "https://github.com/SheffieldML/GPy/issues", + }, +) # Check config files and settings: -local_file = os.path.abspath(os.path.join(os.path.dirname(__file__), 'GPy', 'installation.cfg')) -home = os.getenv('HOME') or os.getenv('USERPROFILE') -user_file = os.path.join(home,'.config', 'GPy', 'user.cfg') +local_file = os.path.abspath( + os.path.join(os.path.dirname(__file__), "GPy", "installation.cfg") +) +home = os.getenv("HOME") or os.getenv("USERPROFILE") +user_file = os.path.join(home, ".config", "GPy", "user.cfg") print("") try: if not os.path.exists(user_file): # Does an old config exist? - old_user_file = os.path.join(home,'.gpy_user.cfg') + old_user_file = os.path.join(home, ".gpy_user.cfg") if os.path.exists(old_user_file): # Move it to new location: - print("GPy: Found old config file, moving to new location {}".format(user_file)) + print( + "GPy: Found old config file, moving to new location {}".format( + user_file + ) + ) if not os.path.exists(os.path.dirname(user_file)): os.makedirs(os.path.dirname(user_file)) os.rename(old_user_file, user_file) @@ -225,8 +259,8 @@ try: print("GPy: Saving user configuration file to {}".format(user_file)) if not os.path.exists(os.path.dirname(user_file)): os.makedirs(os.path.dirname(user_file)) - with open(user_file, 'w') as f: - with open(local_file, 'r') as l: + with open(user_file, "w") as f: + with open(local_file, "r") as l: tmp = l.read() f.write(tmp) else: From c929ffa9346902c8ec0e53eab63de0cfca891b5a Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 8 Nov 2023 08:19:15 +0100 Subject: [PATCH 083/101] update setup.py to use paramz fork --- setup.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 90449259..2aaa4d4e 100644 --- a/setup.py +++ b/setup.py @@ -139,7 +139,13 @@ try: except ModuleNotFoundError: ext_mods = [] -install_requirements = ["numpy>=1.7", "six", "paramz>=0.9.0", "cython>=0.29"] +install_requirements = [ + "numpy>=1.7", + "six", + "paramz @ git+https://github.com/connorfuhrman/paramz/tree/connorfuhrman/np_type_alias_dep.git", + "cython>=0.29", +] +# 'some-pkg @ git+ssh://git@github.com/someorgname/pkg-repo-name@v1.1#egg=some-pkg', matplotlib_version = "matplotlib==3.3.4" install_requirements += ["scipy>=1.3.0"] From 800f24b130da70e2914a86ce7598b095123b98d3 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 8 Nov 2023 18:51:20 +0100 Subject: [PATCH 084/101] replace pypi paramz by forked paramz --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2aaa4d4e..135764d5 100644 --- a/setup.py +++ b/setup.py @@ -142,7 +142,8 @@ except ModuleNotFoundError: install_requirements = [ "numpy>=1.7", "six", - "paramz @ git+https://github.com/connorfuhrman/paramz/tree/connorfuhrman/np_type_alias_dep.git", + # "paramz @ git+https://github.com/connorfuhrman/paramz/tree/connorfuhrman/np_type_alias_dep.git", + "paramz @ git+https://github.com/MartinBubel/paramz.git@fix-numpy-types", "cython>=0.29", ] # 'some-pkg @ git+ssh://git@github.com/someorgname/pkg-repo-name@v1.1#egg=some-pkg', From 722fe6da35b38178d3c63e5c05bf8133b7cb2064 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 8 Nov 2023 18:51:48 +0100 Subject: [PATCH 085/101] fix test_model --- GPy/testing/test_model.py | 71 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/GPy/testing/test_model.py b/GPy/testing/test_model.py index b4d4dae4..af0e94d3 100644 --- a/GPy/testing/test_model.py +++ b/GPy/testing/test_model.py @@ -571,47 +571,42 @@ class TestMisc: warping_ind_1 = [0, 1, 2] warping_ind_2 = [-1, 1, 2] warping_ind_3 = [0, 1.5, 2] - self.failUnlessRaises( - ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_1 - ) - self.failUnlessRaises( - ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_2 - ) - self.failUnlessRaises( - ValueError, GPy.util.input_warping_functions.KumarWarping, X, warping_ind_3 - ) + with pytest.raises(ValueError): + GPy.util.input_warping_functions.KumarWarping(X, warping_ind_1) + + with pytest.raises(ValueError): + GPy.util.input_warping_functions.KumarWarping(X, warping_ind_2) + + with pytest.raises(ValueError): + GPy.util.input_warping_functions.KumarWarping(X, warping_ind_3) # testing Xmin and Xmax Xmin_1, Xmax_1 = None, [1, 1] Xmin_2, Xmax_2 = [0, 0], None Xmin_3, Xmax_3 = [0, 0, 0], [1, 1] - self.failUnlessRaises( - ValueError, - GPy.util.input_warping_functions.KumarWarping, - X, - [0, 1], - epsilon, - Xmin_1, - Xmax_1, - ) - self.failUnlessRaises( - ValueError, - GPy.util.input_warping_functions.KumarWarping, - X, - [0, 1], - epsilon, - Xmin_2, - Xmax_2, - ) - self.failUnlessRaises( - ValueError, - GPy.util.input_warping_functions.KumarWarping, - X, - [0, 1], - epsilon, - Xmin_3, - Xmax_3, - ) + + with pytest.raises(ValueError): + GPy.util.input_warping_functions.KumarWarping( + X, [0, 1], epsilon, Xmin_1, Xmax_1 + ) + + with pytest.raises(ValueError): + GPy.util.input_warping_functions.KumarWarping( + X, + [0, 1], + epsilon, + Xmin_2, + Xmax_2 + ) + + with pytest.raises(ValueError): + GPy.util.input_warping_functions.KumarWarping( + X, + [0, 1], + epsilon, + Xmin_3, + Xmax_3 + ) def test_warped_gp_identity(self): """ @@ -1804,3 +1799,7 @@ def _create_missing_data_model(kernel, Q): ) return m + + +if __name__ == "__main__": + pytest.main([__file__]) From 684508c96511feec9608f037a3937e9f1a37693e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 8 Nov 2023 18:53:52 +0100 Subject: [PATCH 086/101] re-add mpi_test__.py --- GPy/testing/mpi_test__.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 GPy/testing/mpi_test__.py diff --git a/GPy/testing/mpi_test__.py b/GPy/testing/mpi_test__.py new file mode 100644 index 00000000..a05f5cb8 --- /dev/null +++ b/GPy/testing/mpi_test__.py @@ -0,0 +1,21 @@ + +import numpy as np +import GPy +from mpi4py import MPI +np.random.seed(123456) +comm = MPI.COMM_WORLD +N = 100 +x = np.linspace(-6., 6., N) +y = np.sin(x) + np.random.randn(N) * 0.05 +comm.Bcast(y) +data = np.vstack([x,y]) +#infr = GPy.inference.latent_function_inference.VarDTC_minibatch(mpi_comm=comm) +m = GPy.models.SparseGPRegression(data[:1].T,data[1:2].T,mpi_comm=comm) +m.optimize(max_iters=10) +if comm.rank==0: + print float(m.objective_function()) + m.inference_method.mpi_comm=None + m.mpi_comm=None + m._trigger_params_changed() + print float(m.objective_function()) + \ No newline at end of file From bd14886c2d9bddcb62833e2f2f7d59b8470259ae Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Wed, 8 Nov 2023 18:54:08 +0100 Subject: [PATCH 087/101] re-add mpi_test__.py --- mpi_test__.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 mpi_test__.py diff --git a/mpi_test__.py b/mpi_test__.py new file mode 100644 index 00000000..a05f5cb8 --- /dev/null +++ b/mpi_test__.py @@ -0,0 +1,21 @@ + +import numpy as np +import GPy +from mpi4py import MPI +np.random.seed(123456) +comm = MPI.COMM_WORLD +N = 100 +x = np.linspace(-6., 6., N) +y = np.sin(x) + np.random.randn(N) * 0.05 +comm.Bcast(y) +data = np.vstack([x,y]) +#infr = GPy.inference.latent_function_inference.VarDTC_minibatch(mpi_comm=comm) +m = GPy.models.SparseGPRegression(data[:1].T,data[1:2].T,mpi_comm=comm) +m.optimize(max_iters=10) +if comm.rank==0: + print float(m.objective_function()) + m.inference_method.mpi_comm=None + m.mpi_comm=None + m._trigger_params_changed() + print float(m.objective_function()) + \ No newline at end of file From 238775116f9ac2230738c643e7199310556e6a58 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 20:49:31 +0100 Subject: [PATCH 088/101] deactivate test_examples.py --- GPy/testing/{ => deactivated}/test_examples.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename GPy/testing/{ => deactivated}/test_examples.py (100%) diff --git a/GPy/testing/test_examples.py b/GPy/testing/deactivated/test_examples.py similarity index 100% rename from GPy/testing/test_examples.py rename to GPy/testing/deactivated/test_examples.py From 7902cfb609e8c87c92d16044ee6cf78a74a3f83e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 20:50:21 +0100 Subject: [PATCH 089/101] deactivate test_mpi.py --- GPy/testing/deactivated/test_mpi.py | 83 +++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 GPy/testing/deactivated/test_mpi.py diff --git a/GPy/testing/deactivated/test_mpi.py b/GPy/testing/deactivated/test_mpi.py new file mode 100644 index 00000000..6bca1e95 --- /dev/null +++ b/GPy/testing/deactivated/test_mpi.py @@ -0,0 +1,83 @@ +# Copyright (c) 2013-2014, Zhenwen Dai +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import numpy as np + +try: + import subprocess + + class TestMPI: + def test_BayesianGPLVM_MPI(self): + code = """ +import numpy as np +import GPy +from mpi4py import MPI +np.random.seed(123456) +comm = MPI.COMM_WORLD +N = 100 +x = np.linspace(-6., 6., N) +y = np.sin(x) + np.random.randn(N) * 0.05 +comm.Bcast(y) +data = np.vstack([x,y]) +infr = GPy.inference.latent_function_inference.VarDTC_minibatch(mpi_comm=comm) +m = GPy.models.BayesianGPLVM(data.T,1,mpi_comm=comm) +m.optimize(max_iters=10) +if comm.rank==0: + print float(m.objective_function()) + m.inference_method.mpi_comm=None + m.mpi_comm=None + m._trigger_params_changed() + print float(m.objective_function()) + """ + with open("mpi_test__.py", "w") as f: + f.write(code) + f.close() + p = subprocess.Popen( + "mpirun -n 4 python mpi_test__.py", stdout=subprocess.PIPE, shell=True + ) + (stdout, _stderr) = p.communicate() + L1 = float(stdout.splitlines()[-2]) + L2 = float(stdout.splitlines()[-1]) + self.assertTrue(np.allclose(L1, L2)) + import os + + os.remove("mpi_test__.py") + + def test_SparseGPRegression_MPI(self): + code = """ +import numpy as np +import GPy +from mpi4py import MPI +np.random.seed(123456) +comm = MPI.COMM_WORLD +N = 100 +x = np.linspace(-6., 6., N) +y = np.sin(x) + np.random.randn(N) * 0.05 +comm.Bcast(y) +data = np.vstack([x,y]) +#infr = GPy.inference.latent_function_inference.VarDTC_minibatch(mpi_comm=comm) +m = GPy.models.SparseGPRegression(data[:1].T,data[1:2].T,mpi_comm=comm) +m.optimize(max_iters=10) +if comm.rank==0: + print float(m.objective_function()) + m.inference_method.mpi_comm=None + m.mpi_comm=None + m._trigger_params_changed() + print float(m.objective_function()) + """ + with open("mpi_test__.py", "w") as f: + f.write(code) + f.close() + p = subprocess.Popen( + "mpirun -n 4 python mpi_test__.py", stdout=subprocess.PIPE, shell=True + ) + (stdout, stderr) = p.communicate() + L1 = float(stdout.splitlines()[-2]) + L2 = float(stdout.splitlines()[-1]) + assert np.allclose(L1, L2) + import os + + os.remove("mpi_test__.py") + +except: + pass From 6d5258e6597c70557785a79fe90063d39528d68c Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 20:52:24 +0100 Subject: [PATCH 090/101] update run coverage --- GPy/testing/run_coverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPy/testing/run_coverage.sh b/GPy/testing/run_coverage.sh index f2e52230..a32e1ad1 100755 --- a/GPy/testing/run_coverage.sh +++ b/GPy/testing/run_coverage.sh @@ -1 +1 @@ -nosetests . --with-coverage --logging-level=INFO --cover-html --cover-html-dir=coverage --cover-package=GPy --cover-erase +pytest . \ No newline at end of file From 7983d87a854a6ef2ef896ee434fc47003e1b2c9a Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 20:58:18 +0100 Subject: [PATCH 091/101] update changelog.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f5cf0bc..bebfe2eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## Unreleased + +* Change from `nosetest` to `pytest` ## v1.9.8 (2019-05-17) From f4e28d6d7deff396943af8b410fee8b7acd043cc Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 20:59:32 +0100 Subject: [PATCH 092/101] remove additional mp_test__.py --- mpi_test__.py | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 mpi_test__.py diff --git a/mpi_test__.py b/mpi_test__.py deleted file mode 100644 index a05f5cb8..00000000 --- a/mpi_test__.py +++ /dev/null @@ -1,21 +0,0 @@ - -import numpy as np -import GPy -from mpi4py import MPI -np.random.seed(123456) -comm = MPI.COMM_WORLD -N = 100 -x = np.linspace(-6., 6., N) -y = np.sin(x) + np.random.randn(N) * 0.05 -comm.Bcast(y) -data = np.vstack([x,y]) -#infr = GPy.inference.latent_function_inference.VarDTC_minibatch(mpi_comm=comm) -m = GPy.models.SparseGPRegression(data[:1].T,data[1:2].T,mpi_comm=comm) -m.optimize(max_iters=10) -if comm.rank==0: - print float(m.objective_function()) - m.inference_method.mpi_comm=None - m.mpi_comm=None - m._trigger_params_changed() - print float(m.objective_function()) - \ No newline at end of file From faae055ebce43bfa6f6fa50c7dbc4e2a161302de Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 20:59:43 +0100 Subject: [PATCH 093/101] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e609cb6..8cdf6ac1 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ If you're having trouble installing GPy via `pip install GPy` here is a probable cd GPy git checkout devel python setup.py build_ext --inplace - nosetests GPy/testing + pytest . ### Direct downloads From 6ea51bd0b0bfbb46e1e676335e5a01e128406637 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:00:19 +0100 Subject: [PATCH 094/101] add more python versions to .travis.yml --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7fa2e442..edf47fa8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,12 +20,17 @@ env: - PYTHON_VERSION=3.7 - PYTHON_VERSION=3.8 - PYTHON_VERSION=3.9 + - PYTHON_VERSION=3.10 + - PYTHON_VERSION=3.11 + - PYTHON_VERSION=3.12 + # TODO: add more recent python versions? will later address this in the issue claiming we follow numpy before_install: - wget https://github.com/mzwiessele/travis_scripts/raw/master/download_miniconda.sh - wget https://github.com/mzwiessele/travis_scripts/raw/master/install_retry.sh - source download_miniconda.sh - echo $PATH +# why not cloning a miniconda container?! install: - echo $PATH From 2268ea8652b4c4b8c3d7e65e6b12e648da4dde3e Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:00:56 +0100 Subject: [PATCH 095/101] remove nosetest install from .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index edf47fa8..2de5e89a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,6 @@ install: - pip install pypandoc - pip install git+git://github.com/BRML/climin.git - pip install autograd -- pip install nose-show-skipped - python setup.py develop script: From 9913763529dc11dc7e5dc536f128a33788037fa2 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:02:20 +0100 Subject: [PATCH 096/101] update travis_tests --- travis_tests.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/travis_tests.py b/travis_tests.py index 16713962..c1700744 100644 --- a/travis_tests.py +++ b/travis_tests.py @@ -1,4 +1,4 @@ -#=============================================================================== +# =============================================================================== # Copyright (c) 2015, Max Zwiessele # # All rights reserved. @@ -27,14 +27,13 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#=============================================================================== +# =============================================================================== #!/usr/bin/env python import matplotlib -matplotlib.use('agg') -import nose, warnings -with warnings.catch_warnings(): - warnings.simplefilter("ignore") - nose.main('GPy', defaultTest='GPy/testing', argv=['', '--show-skipped']) +matplotlib.use("agg") +import pytest + +pytest.main(["GPy/testing/"]) From 1df19252d3eff9559450378bf917ecac3d558cf3 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:02:29 +0100 Subject: [PATCH 097/101] update travis_tests.py --- travis_tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/travis_tests.py b/travis_tests.py index c1700744..f736d322 100644 --- a/travis_tests.py +++ b/travis_tests.py @@ -30,10 +30,9 @@ # =============================================================================== #!/usr/bin/env python +import pytest import matplotlib matplotlib.use("agg") -import pytest - pytest.main(["GPy/testing/"]) From 6cf318323df43fdff2b46fc2e086f0887e622a8d Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:03:21 +0100 Subject: [PATCH 098/101] replace nose by pytest in requrements.txt --- doc/source/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/requirements.txt b/doc/source/requirements.txt index 5ae1e857..ab1cfca7 100644 --- a/doc/source/requirements.txt +++ b/doc/source/requirements.txt @@ -7,4 +7,4 @@ paramz cython mock sympy -nose \ No newline at end of file +pytest \ No newline at end of file From 07f2c50f3b3dd50b0e8359287ee6ba781488784a Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:03:51 +0100 Subject: [PATCH 099/101] remove nose install from appreyor.yml --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 7db6a95a..b2ff1bd2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -34,7 +34,6 @@ install: - python -m pip install wheel # GPy needs paramz - python -m pip install paramz - - python -m pip install nose-show-skipped - python -m pip install coverage - python -m pip install coveralls - python -m pip install codecov From e8cafdbe06d52d727bc541904e04e5d9177127f7 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Mon, 13 Nov 2023 21:04:38 +0100 Subject: [PATCH 100/101] update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8cdf6ac1..5df04327 100644 --- a/README.md +++ b/README.md @@ -171,13 +171,13 @@ print(m_load) New way of running tests is using coverage: -Ensure nose and coverage is installed: +Ensure pytest and coverage is installed: - pip install nose coverage + pip install pytest Run nosetests from root directory of repository: - coverage run travis_tests.py + python travis_tests.py Create coverage report in htmlcov/ From caafcbf1d733c9453b2f0b6d2072076cd64d8bc3 Mon Sep 17 00:00:00 2001 From: Martin Bubel Date: Thu, 16 Nov 2023 08:06:05 +0100 Subject: [PATCH 101/101] add pytest to appveyor.yml --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b2ff1bd2..207b0b12 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,12 +33,12 @@ install: # We need wheel installed to build wheels - python -m pip install wheel # GPy needs paramz - - python -m pip install paramz - python -m pip install coverage - python -m pip install coveralls - python -m pip install codecov - python -m pip install twine - - "python setup.py develop" + - python -m pip install pytest + - python setup.py develop build: off