From 4c663c7f72b865c971479c91f6fd571551f5968c Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:53:03 +0200 Subject: [PATCH 1/2] Stabilize piecewise-constant weight normalization --- .../circle/piecewise_constant_distribution.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pyrecest/distributions/circle/piecewise_constant_distribution.py b/src/pyrecest/distributions/circle/piecewise_constant_distribution.py index 4712348d3b..c201e40ea9 100644 --- a/src/pyrecest/distributions/circle/piecewise_constant_distribution.py +++ b/src/pyrecest/distributions/circle/piecewise_constant_distribution.py @@ -4,6 +4,7 @@ import numpy as np import pyrecest.backend from pyrecest.backend import ( + amax, arange, array, exp, @@ -144,11 +145,12 @@ def __init__(self, w): if any(bool(weight < 0.0) for weight in w): raise ValueError("Weights must be nonnegative") - mean_weight = mean(w) - if not bool(mean_weight > 0.0): + weight_scale = amax(w) + if not bool(weight_scale > 0.0): raise ValueError("Weights must have positive total mass") + scaled_weights = w / weight_scale - self.w = w / (mean_weight * 2.0 * pi) + self.w = scaled_weights / (mean(scaled_weights) * 2.0 * pi) def pdf(self, xs): """Evaluate the pdf at each point in xs. From 261a4c575b4726b3a1600fc78929e8b94919839a Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:53:13 +0200 Subject: [PATCH 2/2] Add large-weight normalization regression --- ...test_piecewise_constant_weight_overflow.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/distributions/test_piecewise_constant_weight_overflow.py diff --git a/tests/distributions/test_piecewise_constant_weight_overflow.py b/tests/distributions/test_piecewise_constant_weight_overflow.py new file mode 100644 index 0000000000..970e6119b0 --- /dev/null +++ b/tests/distributions/test_piecewise_constant_weight_overflow.py @@ -0,0 +1,23 @@ +import numpy as np +import numpy.testing as npt + +from pyrecest.backend import array, to_numpy +from pyrecest.distributions.circle.piecewise_constant_distribution import ( + PiecewiseConstantDistribution, +) + + +def test_maximum_finite_weights_normalize_without_overflow(): + backend_dtype = np.asarray(to_numpy(array([1.0], dtype=float))).dtype + maximum_finite_weight = np.finfo(backend_dtype).max + + distribution = PiecewiseConstantDistribution( + array([maximum_finite_weight, maximum_finite_weight / 2.0], dtype=float) + ) + + npt.assert_allclose( + np.asarray(to_numpy(distribution.w)), + np.array([2.0 / (3.0 * np.pi), 1.0 / (3.0 * np.pi)]), + rtol=1.0e-6, + atol=0.0, + )