From b12ff6aa9dfbef246df6812c0fef1edbb4080df2 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 20 May 2023 00:03:05 +0200 Subject: [PATCH] Added custom and uniform distributions for hyperrectangles --- .../custom_hyperrectangular_distribution.py | 7 +++++ .../hyperrectangular_uniform_distribution.py | 14 +++++++++ .../abstract_hyperrectangular_distribution.py | 29 +++++++++++++++++++ ...st_custom_hyperrectangular_distribution.py | 13 +++++++++ 4 files changed, 63 insertions(+) create mode 100644 pyrecest/distributions/custom_hyperrectangular_distribution.py create mode 100644 pyrecest/distributions/hyperrectangular_uniform_distribution.py create mode 100644 pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py create mode 100644 pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py diff --git a/pyrecest/distributions/custom_hyperrectangular_distribution.py b/pyrecest/distributions/custom_hyperrectangular_distribution.py new file mode 100644 index 00000000..47aba512 --- /dev/null +++ b/pyrecest/distributions/custom_hyperrectangular_distribution.py @@ -0,0 +1,7 @@ +from .nonperiodic.abstract_hyperrectangular_distribution import AbstractHyperrectangularDistribution +from .custom_distribution import CustomDistribution + +class CustomHyperrectangularDistribution(AbstractHyperrectangularDistribution, CustomDistribution): + def __init__(self, f, bounds): + AbstractHyperrectangularDistribution.__init__(self, bounds) + CustomDistribution.__init__(self, f, self.dim) diff --git a/pyrecest/distributions/hyperrectangular_uniform_distribution.py b/pyrecest/distributions/hyperrectangular_uniform_distribution.py new file mode 100644 index 00000000..63c87a88 --- /dev/null +++ b/pyrecest/distributions/hyperrectangular_uniform_distribution.py @@ -0,0 +1,14 @@ + +from .abstract_uniform_distribution import AbstractUniformDistribution +from .nonperiodic.abstract_hyperrectangular_distribution import AbstractHyperrectangularDistribution + +class HyperrectangularUniformDistribution(AbstractUniformDistribution, AbstractHyperrectangularDistribution): + def __init__(self, bounds): + AbstractUniformDistribution.__init__(self, bounds.shape[-1]) + AbstractHyperrectangularDistribution.__init__(self, bounds) + + def get_manifold_size(self): + return AbstractHyperrectangularDistribution.get_manifold_size(self) + + + \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py new file mode 100644 index 00000000..47444c1a --- /dev/null +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -0,0 +1,29 @@ +import numpy as np +from ..abstract_bounded_nonperiodic_distribution import AbstractBoundedNonPeriodicDistribution +import scipy + +class AbstractHyperrectangularDistribution(AbstractBoundedNonPeriodicDistribution): + def __init__(self, bounds): + AbstractBoundedNonPeriodicDistribution.__init__(self, np.size(bounds[0])) + self.bounds = bounds + + def get_manifold_size(self): + s = np.prod(np.diff(self.bounds, axis=1)) + return s + + @property + def input_dim(self): + return self.dim + + def integrate(self, integration_boundaries=None): + if integration_boundaries is None: + integration_boundaries = self.bounds + + left = np.atleast_1d(integration_boundaries[0]) + right = np.atleast_1d(integration_boundaries[1]) + + def pdf_fun(*args): + return self.pdf(np.array(args)) + + integration_boundaries = [(left[i], right[i]) for i in range(self.dim)] + return scipy.integrate.nquad(pdf_fun, integration_boundaries)[0] \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py new file mode 100644 index 00000000..e693d895 --- /dev/null +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -0,0 +1,13 @@ +import numpy as np +import unittest +from pyrecest.distributions.hyperrectangular_uniform_distribution import HyperrectangularUniformDistribution +from pyrecest.distributions.custom_hyperrectangular_distribution import CustomHyperrectangularDistribution + +class TestCustomHyperrectangularDistribution(unittest.TestCase): + def test_basic(self): + hud = HyperrectangularUniformDistribution(np.array([[1, 3], [2, 5]])) + cd = CustomHyperrectangularDistribution(hud.pdf, hud.bounds) + x_mesh, y_mesh = np.meshgrid(np.linspace(1, 3, 50), np.linspace(2, 5, 50)) + self.assertTrue(np.allclose(cd.pdf(np.column_stack((x_mesh.ravel(), y_mesh.ravel()))), 1/6 * np.ones(50**2))) + + \ No newline at end of file