From 74395b9196c019f23a158aeb97774fc50d7b0cf6 Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 20:54:57 +0800 Subject: [PATCH 01/10] Convert input to the right size --- pints/toy/_gaussian.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pints/toy/_gaussian.py b/pints/toy/_gaussian.py index 082935b6b..9b628a545 100644 --- a/pints/toy/_gaussian.py +++ b/pints/toy/_gaussian.py @@ -58,6 +58,7 @@ def __init__(self, mean=[0, 0], sigma=[1, 1]): self._sigma_inv = np.linalg.inv(self._sigma) def __call__(self, x): + x = pints.vector(x).reshape(self._n_parameters) return self._phi.logpdf(x) def distance(self, samples): From 42693c0f5358dbd83db675ade025e121c408ee4d Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:05:56 +0800 Subject: [PATCH 02/10] Do not change the input vector --- pints/toy/_gaussian.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pints/toy/_gaussian.py b/pints/toy/_gaussian.py index 9b628a545..a1e72b1f2 100644 --- a/pints/toy/_gaussian.py +++ b/pints/toy/_gaussian.py @@ -58,8 +58,8 @@ def __init__(self, mean=[0, 0], sigma=[1, 1]): self._sigma_inv = np.linalg.inv(self._sigma) def __call__(self, x): - x = pints.vector(x).reshape(self._n_parameters) - return self._phi.logpdf(x) + y = pints.vector(x).reshape(self._n_parameters) + return self._phi.logpdf(y) def distance(self, samples): """ From c576517fd70379d46902184dd9081623f8a22a96 Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:32:12 +0800 Subject: [PATCH 03/10] Fix import bug --- pints/toy/_gaussian.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pints/toy/_gaussian.py b/pints/toy/_gaussian.py index a1e72b1f2..3f72bba52 100644 --- a/pints/toy/_gaussian.py +++ b/pints/toy/_gaussian.py @@ -9,6 +9,7 @@ import scipy.stats from . import ToyLogPDF +from .. import vector class GaussianLogPDF(ToyLogPDF): @@ -58,7 +59,7 @@ def __init__(self, mean=[0, 0], sigma=[1, 1]): self._sigma_inv = np.linalg.inv(self._sigma) def __call__(self, x): - y = pints.vector(x).reshape(self._n_parameters) + y = vector(x).reshape(self._n_parameters) return self._phi.logpdf(y) def distance(self, samples): From 770079ac6939c5709c4093bc1e498499e891bd00 Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:32:56 +0800 Subject: [PATCH 04/10] Add test for incorrect input error --- pints/tests/test_toy_gaussian_logpdf.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pints/tests/test_toy_gaussian_logpdf.py b/pints/tests/test_toy_gaussian_logpdf.py index c9208af6e..96406ff60 100755 --- a/pints/tests/test_toy_gaussian_logpdf.py +++ b/pints/tests/test_toy_gaussian_logpdf.py @@ -46,6 +46,11 @@ def test_gaussian_logpdf(self): self.assertRaises( ValueError, pints.toy.GaussianLogPDF, [1, 2, 3], [1, 2, 3, 4]) + # Bad calls to function + f = pints.toy.GaussianLogPDF([1, 2, 3], [1, 1, 1]) + self.assertRaises(ValueError, f.__call__, [1, 2]) + self.assertRaises(ValueError, f.__call__, [1, 2, 3, 4, 5]) + def test_sampling_and_kl_divergence(self): # Test GaussianLogPDF.kl_divergence() and .sample(). From 870aa03541037d74330c22c9f37db45390cbaff3 Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:33:22 +0800 Subject: [PATCH 05/10] Change mode to executable --- pints/tests/test_abc_rejection.py | 0 pints/tests/test_abc_smc.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 pints/tests/test_abc_rejection.py mode change 100644 => 100755 pints/tests/test_abc_smc.py diff --git a/pints/tests/test_abc_rejection.py b/pints/tests/test_abc_rejection.py old mode 100644 new mode 100755 diff --git a/pints/tests/test_abc_smc.py b/pints/tests/test_abc_smc.py old mode 100644 new mode 100755 From 36adc72695d59ed6022d7e5ad9cc2c504618ed4a Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:33:47 +0800 Subject: [PATCH 06/10] Fix input dimension error issue --- pints/toy/_high_dimensional_gaussian.py | 4 +++- pints/toy/_multimodal_gaussian.py | 3 ++- pints/toy/_parabola.py | 3 ++- pints/toy/_twisted_gaussian_banana.py | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pints/toy/_high_dimensional_gaussian.py b/pints/toy/_high_dimensional_gaussian.py index 580bd67a8..85d604b1e 100644 --- a/pints/toy/_high_dimensional_gaussian.py +++ b/pints/toy/_high_dimensional_gaussian.py @@ -9,6 +9,7 @@ import scipy.stats from . import ToyLogPDF +from .. import vector class HighDimensionalGaussianLogPDF(ToyLogPDF): @@ -61,7 +62,8 @@ def __init__(self, dimension=20, rho=0.5): self._var = scipy.stats.multivariate_normal(self._mean, self._cov) def __call__(self, x): - return self._var.logpdf(x) + y = vector(x).reshape(self._n_parameters) + return self._var.logpdf(y) def distance(self, samples): """ diff --git a/pints/toy/_multimodal_gaussian.py b/pints/toy/_multimodal_gaussian.py index 9b9a90139..1c350852c 100644 --- a/pints/toy/_multimodal_gaussian.py +++ b/pints/toy/_multimodal_gaussian.py @@ -98,7 +98,8 @@ def __init__(self, modes=None, covariances=None): np.linalg.inv(self._covs[i]) for i, mode in enumerate(self._modes)] def __call__(self, x): - f = np.sum([var.pdf(x) for var in self._vars]) + y = pints.vector(x).reshape(self._n_parameters) + f = np.sum([var.pdf(y) for var in self._vars]) return -np.inf if f == 0 else np.log(f) def distance(self, samples): diff --git a/pints/toy/_parabola.py b/pints/toy/_parabola.py index f9fe93e13..084806e71 100644 --- a/pints/toy/_parabola.py +++ b/pints/toy/_parabola.py @@ -29,7 +29,8 @@ def __init__(self, c=[0, 0]): self._n = len(self._c) def __call__(self, x): - return np.sum((self._c - x)**2) + y = pints.vector(x).reshape(self._n_parameters) + return np.sum((self._c - y)**2) def evaluateS1(self, x): """ See :meth:`pints.ErrorMeasure.evaluateS1()`. """ diff --git a/pints/toy/_twisted_gaussian_banana.py b/pints/toy/_twisted_gaussian_banana.py index 6c9082f66..72544ecb7 100644 --- a/pints/toy/_twisted_gaussian_banana.py +++ b/pints/toy/_twisted_gaussian_banana.py @@ -66,6 +66,7 @@ def __call__(self, x): y = np.array(x, copy=True, dtype='float') y[0] = float(y[0]) / np.sqrt(self._V) y[1] += self._b * ((x[0] ** 2) - self._V) + y = y.reshape(self._n_parameters) return self._phi.logpdf(y) def distance(self, samples): From fd895060b96f4825d6cf04912e7bfbb374d2e6ac Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:34:05 +0800 Subject: [PATCH 07/10] Add test for incorrect input error --- pints/tests/test_toy_high_dimensional_gaussian_logpdf.py | 5 +++++ pints/tests/test_toy_multimodal_gaussian_logpdf.py | 5 +++++ pints/tests/test_toy_parabolic_error.py | 5 +++++ pints/tests/test_toy_twisted_gaussian_logpdf.py | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/pints/tests/test_toy_high_dimensional_gaussian_logpdf.py b/pints/tests/test_toy_high_dimensional_gaussian_logpdf.py index 70a97e095..ec4039870 100755 --- a/pints/tests/test_toy_high_dimensional_gaussian_logpdf.py +++ b/pints/tests/test_toy_high_dimensional_gaussian_logpdf.py @@ -106,6 +106,11 @@ def test_high_dimensional_log_pdf(self): self.assertRaises( ValueError, pints.toy.HighDimensionalGaussianLogPDF, 11, -0.11) + # Bad calls to function + f = pints.toy.HighDimensionalGaussianLogPDF(3) + self.assertRaises(ValueError, f.__call__, [1, 2]) + self.assertRaises(ValueError, f.__call__, [1, 2, 3, 4, 5]) + def test_sensitivities(self): # tests that sensitivities are correct diff --git a/pints/tests/test_toy_multimodal_gaussian_logpdf.py b/pints/tests/test_toy_multimodal_gaussian_logpdf.py index 0abd8ff8e..0754cf34f 100755 --- a/pints/tests/test_toy_multimodal_gaussian_logpdf.py +++ b/pints/tests/test_toy_multimodal_gaussian_logpdf.py @@ -65,6 +65,11 @@ def test_basic(self): [1, 1], [1.5, 1.5], [3, 0], [0, 3.5] ]) + # Bad calls to function + f = pints.toy.MultimodalGaussianLogPDF([[1, 1, 1]]) + self.assertRaises(ValueError, f.__call__, [1, 2]) + self.assertRaises(ValueError, f.__call__, [1, 2, 3, 4, 5]) + def test_bad_constructors(self): # Tests bad Constructors. diff --git a/pints/tests/test_toy_parabolic_error.py b/pints/tests/test_toy_parabolic_error.py index 7e08ff5fd..f5e6df1f8 100755 --- a/pints/tests/test_toy_parabolic_error.py +++ b/pints/tests/test_toy_parabolic_error.py @@ -49,6 +49,11 @@ def test_parabolic_error(self): self.assertAlmostEqual(dfx[1], 0) self.assertAlmostEqual(dfx[2], -0.4) + # Bad calls to function + f = pints.toy.ParabolicError([1, 1, 1]) + self.assertRaises(ValueError, f.__call__, [1, 2]) + self.assertRaises(ValueError, f.__call__, [1, 2, 3, 4, 5]) + if __name__ == '__main__': unittest.main() diff --git a/pints/tests/test_toy_twisted_gaussian_logpdf.py b/pints/tests/test_toy_twisted_gaussian_logpdf.py index 2b4685f50..484110fdd 100755 --- a/pints/tests/test_toy_twisted_gaussian_logpdf.py +++ b/pints/tests/test_toy_twisted_gaussian_logpdf.py @@ -28,6 +28,11 @@ def test_twisted_gaussian_logpdf(self): self.assertRaises(ValueError, pints.toy.TwistedGaussianLogPDF, 1) self.assertRaises(ValueError, pints.toy.TwistedGaussianLogPDF, b=-1) + # Bad calls to function + f = pints.toy.TwistedGaussianLogPDF(3) + self.assertRaises(ValueError, f.__call__, [1, 2]) + self.assertRaises(ValueError, f.__call__, [1, 2, 3, 4, 5]) + def test_sampling_and_kl_divergence(self): # Test TwistedGaussianLogPDF.kl_divergence() and .sample(). From 84377fa23a5f14638dc17a0260b7b576f3039ba1 Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 21:57:48 +0800 Subject: [PATCH 08/10] Fix typo --- pints/toy/_parabola.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pints/toy/_parabola.py b/pints/toy/_parabola.py index 084806e71..98901d693 100644 --- a/pints/toy/_parabola.py +++ b/pints/toy/_parabola.py @@ -29,7 +29,7 @@ def __init__(self, c=[0, 0]): self._n = len(self._c) def __call__(self, x): - y = pints.vector(x).reshape(self._n_parameters) + y = pints.vector(x).reshape(self._n) return np.sum((self._c - y)**2) def evaluateS1(self, x): From e9aebbaee91442e548a968f3abaa805a0fc3f820 Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 23:22:12 +0800 Subject: [PATCH 09/10] Update _twisted_gaussian_banana.py --- pints/toy/_twisted_gaussian_banana.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pints/toy/_twisted_gaussian_banana.py b/pints/toy/_twisted_gaussian_banana.py index 72544ecb7..456530c7a 100644 --- a/pints/toy/_twisted_gaussian_banana.py +++ b/pints/toy/_twisted_gaussian_banana.py @@ -63,10 +63,9 @@ def __init__(self, dimension=10, b=0.1, V=100): np.zeros(self._n_parameters), self._sigma) def __call__(self, x): - y = np.array(x, copy=True, dtype='float') + y = np.array(x, copy=True, dtype='float').reshape(self._n_parameters) y[0] = float(y[0]) / np.sqrt(self._V) y[1] += self._b * ((x[0] ** 2) - self._V) - y = y.reshape(self._n_parameters) return self._phi.logpdf(y) def distance(self, samples): From bf12ae19401e7c4128dfcca3e3ca5fc4c1ed032d Mon Sep 17 00:00:00 2001 From: Chon Lok Lei Date: Tue, 7 Nov 2023 23:27:31 +0800 Subject: [PATCH 10/10] Update CHANGELOG.md for #1505 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7258a691..379473a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. ### Deprecated ### Removed ### Fixed +- [#1505](https://github.com/pints-team/pints/pull/1505) Fixed issues with toy problems that accept invalid inputs. ## [0.5.0] - 2023-07-27