From df85740fb00a695bb47b310e43da5e40ff8e2411 Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Mon, 18 May 2026 11:50:07 +0200 Subject: [PATCH 1/3] Guard undefined hyperspherical mean directions --- .../abstract_hypersphere_subset_distribution.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/src/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 52228908a..de627a5f3 100644 --- a/src/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/src/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,4 +1,3 @@ -import warnings from abc import abstractmethod from collections.abc import Callable from typing import Union @@ -117,13 +116,13 @@ def fangles_array(*args): else: raise ValueError("Unsupported") - if linalg.norm(mu) < 1e-9: - warnings.warn( - "Warning: Density may not actually have a mean direction because integral yields a point very close to the origin." + norm_mu = linalg.norm(mu) + if norm_mu < 1e-9: + raise ValueError( + "Mean direction is undefined because the first moment is too close to the origin." ) - mu = mu / linalg.norm(mu) - return mu + return mu / norm_mu def gen_pdf_hyperspherical_coords(self): """ From b480757771cfc958783aec5c4a86e1c769aa4f32 Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Mon, 18 May 2026 12:39:48 +0200 Subject: [PATCH 2/3] Guard undefined hyperhemispherical mean directions --- .../abstract_hyperhemispherical_distribution.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/src/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index c5b4cb046..0fa01a93b 100644 --- a/src/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/src/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -125,13 +125,13 @@ def mean_direction_numerical(self, integration_boundaries=None): p = self.pdf(r) mu = r @ p / n * Sd - if linalg.norm(mu) < 1e-9: - warnings.warn( - "Density may not have actually have a mean direction because integral yields a point very close to the origin." + norm_mu = linalg.norm(mu) + if norm_mu < 1e-9: + raise ValueError( + "Mean direction is undefined because the first moment is too close to the origin." ) - mu = mu / linalg.norm(mu) - return mu + return mu / norm_mu @staticmethod def get_full_integration_boundaries(dim: Union[int, int32, int64]): From df4d83043860792a0ad6a1b734fc3cc49f93a4f7 Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Mon, 18 May 2026 12:52:41 +0200 Subject: [PATCH 3/3] Add undefined mean-direction regression test --- .../test_abstract_hyperspherical_distribution.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/distributions/test_abstract_hyperspherical_distribution.py b/tests/distributions/test_abstract_hyperspherical_distribution.py index bd242b770..7e9b9766b 100644 --- a/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -7,6 +7,7 @@ from pyrecest.backend import array, linalg, log, pi, sqrt from pyrecest.distributions import ( AbstractHypersphericalDistribution, + HypersphericalUniformDistribution, VonMisesFisherDistribution, ) @@ -68,6 +69,16 @@ def test_mean_direction_numerical(self): vmf = VonMisesFisherDistribution(mu, kappa) self.assertLess(linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) + @unittest.skipIf( + pyrecest.backend.__backend_name__ == "jax", + reason="Not supported on this backend", + ) + def test_mean_direction_numerical_undefined_for_uniform_circle(self): + """Tests that undefined mean directions are reported explicitly.""" + uniform_circle = HypersphericalUniformDistribution(1) + with self.assertRaisesRegex(ValueError, "Mean direction is undefined"): + uniform_circle.mean_direction_numerical() + def test_plotting_error_free_1d(self): """Tests the plotting function for circular distributions."""