From 5a0cc9be63547a4e4fb7a5cbf613c51205d18dd5 Mon Sep 17 00:00:00 2001 From: Sonu Sharma Date: Thu, 10 Sep 2026 23:21:54 +0530 Subject: [PATCH 1/4] fix(gp): raise ValueError in set_boundary when boundary size L <= 0 (#8427) --- pymc/gp/hsgp_approx.py | 5 +++++ tests/gp/test_hsgp_approx.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/pymc/gp/hsgp_approx.py b/pymc/gp/hsgp_approx.py index 1b147eb9e2..24d55355fe 100644 --- a/pymc/gp/hsgp_approx.py +++ b/pymc/gp/hsgp_approx.py @@ -41,6 +41,11 @@ def set_boundary(X: TensorLike, c: numbers.Real | TensorLike) -> np.ndarray: S = (pt.max(X, axis=0) - pt.min(X, axis=0)) / 2.0 L = (c * S).eval() # eval() makes sure L is not changed with out-of-sample preds + if np.any(L <= 0): + raise ValueError( + "Boundary size L must be strictly positive for all dimensions. " + "Check that input data X has non-zero range (max - min > 0) for each feature column." + ) return L diff --git a/tests/gp/test_hsgp_approx.py b/tests/gp/test_hsgp_approx.py index d131f82e98..9144d181e3 100644 --- a/tests/gp/test_hsgp_approx.py +++ b/tests/gp/test_hsgp_approx.py @@ -121,6 +121,11 @@ def test_set_boundaries_3d(self, X2): L = pm.gp.hsgp_approx.set_boundary(X2s, c=2) assert np.all(L == 10) + def test_set_boundary_zero_range_raises(self): + X = np.ones((10, 2)) + with pytest.raises(ValueError, match="Boundary size L must be strictly positive"): + pm.gp.hsgp_approx.set_boundary(X, c=1.5) + def test_mean_invariance(self): X = np.linspace(0, 10, 100)[:, None] original_center = (np.max(X, axis=0) - np.min(X, axis=0)) / 2 From c9d642b3da385184445bb0224ddd697e57dcd8c0 Mon Sep 17 00:00:00 2001 From: Sonu Sharma Date: Tue, 15 Sep 2026 01:52:21 +0530 Subject: [PATCH 2/4] fix(distributions): improve lower tail numerical stability in Moyal logcdf (#8437) --- pymc/distributions/continuous.py | 7 ++++++- tests/distributions/test_continuous.py | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pymc/distributions/continuous.py b/pymc/distributions/continuous.py index b0fdcc2ba3..451bd4b0fe 100644 --- a/pymc/distributions/continuous.py +++ b/pymc/distributions/continuous.py @@ -4055,7 +4055,12 @@ def logp(value, mu, sigma): def logcdf(value, mu, sigma): scaled = (value - mu) / sigma - res = pt.log(pt.erfc(pt.exp(-scaled / 2) * (2**-0.5))) + u = pt.exp(-scaled / 2) * (2**-0.5) + res = pt.switch( + pt.gt(u, 1.0), + pt.log(pt.erfcx(u)) - pt.sqr(u), + pt.log(pt.erfc(u)), + ) return check_parameters( res, sigma > 0, diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index ac112a4228..e267d6dd37 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -956,6 +956,14 @@ def test_moyal_logcdf(self): if pytensor.config.floatX == "float32": raise Exception("Flaky test: It passed this time, but XPASS is not allowed.") + def test_moyal_logcdf_lower_tail(self): + rv = pm.Moyal.dist(mu=0.0, sigma=1.0) + xs = np.array([-10.0, -20.0, -50.0]) + res = pm.logcdf(rv, xs).eval() + expected = st.moyal.logcdf(xs, loc=0.0, scale=1.0) + np.testing.assert_allclose(res, expected, rtol=1e-5) + + def test_moyal_icdf(self): check_icdf( pm.Moyal, From a9e414d19b86f27a79cb78318b4060d5ed8c39c0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 20:45:45 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/distributions/test_continuous.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index e267d6dd37..b8f8b1ee19 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -963,7 +963,6 @@ def test_moyal_logcdf_lower_tail(self): expected = st.moyal.logcdf(xs, loc=0.0, scale=1.0) np.testing.assert_allclose(res, expected, rtol=1e-5) - def test_moyal_icdf(self): check_icdf( pm.Moyal, From 2af30620813687ea228f9426b64a60c833adba79 Mon Sep 17 00:00:00 2001 From: Sonu Sharma Date: Wed, 7 Oct 2026 11:17:05 +0530 Subject: [PATCH 4/4] Fix Moyal lower-tail regression test reference --- tests/distributions/test_continuous.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index b8f8b1ee19..505e092b1b 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -960,7 +960,10 @@ def test_moyal_logcdf_lower_tail(self): rv = pm.Moyal.dist(mu=0.0, sigma=1.0) xs = np.array([-10.0, -20.0, -50.0]) res = pm.logcdf(rv, xs).eval() - expected = st.moyal.logcdf(xs, loc=0.0, scale=1.0) + # F(x) = 2 * Phi(-exp(-x / 2)); avoid taking log of an underflowed CDF. + expected = np.log(2.0) + sp.log_ndtr(-np.exp(-xs / 2.0)) + assert np.isfinite(expected).all() + assert np.isfinite(res).all() np.testing.assert_allclose(res, expected, rtol=1e-5) def test_moyal_icdf(self):