Skip to content

[BUG] fix scipy scale mapping for HalfNormal/HalfLogistic with regression tests (towards #22)#957

Open
kunal14901 wants to merge 2 commits intosktime:mainfrom
kunal14901:bug/half-distributions-scipy-scale
Open

[BUG] fix scipy scale mapping for HalfNormal/HalfLogistic with regression tests (towards #22)#957
kunal14901 wants to merge 2 commits intosktime:mainfrom
kunal14901:bug/half-distributions-scipy-scale

Conversation

@kunal14901
Copy link

Reference Issues/PRs

See #22

What does this implement/fix? Explain your changes.

This PR fixes scipy parameter mapping semantics for two half-distributions and adds dedicated regression tests.

Changes:

  • HalfNormal._get_scipy_param
    • before: return [sigma], {}
    • after: return [], {"scale": sigma}
  • HalfLogistic._get_scipy_param
    • before: return [beta], {}
    • after: return [], {"scale": beta}

These changes align parameter passing with scipy keyword semantics and avoid incorrect positional binding behavior.

Additionally, this PR adds:

  • skpro/distributions/tests/test_half_distributions.py

The new tests validate:

  • scalar parity vs scipy (pdf, cdf, ppf) for HalfNormal and HalfLogistic
  • broadcast/shape/index/columns behavior for both distributions

Does your contribution introduce a new dependency? If yes, which one?

No new dependency is introduced.

What should a reviewer concentrate their feedback on?

  • Correctness of scipy parameter mapping updates in both distributions
  • Whether test coverage is sufficient for scalar and broadcasted behavior
  • Preferred conventions for grouping multiple distribution regression tests in one file

Did you add any tests for the change?

Yes.

Added:

  • skpro/distributions/tests/test_half_distributions.py

Validation performed locally:

  • targeted tests in test_half_distributions.py passed
  • filtered broader checks in test_all_distrs.py for HalfNormal/HalfLogistic passed

Any other comments?

Submitted as part of my ESoC 2026 contributions towards #22.
Happy to iterate quickly on review feedback.

PR checklist

For all contributions
  • I've added myself to the list of contributors with any new badges I've earned
  • The PR title starts with either [ENH], [MNT], [DOC], or [BUG].
For new estimators
  • Not applicable (this PR fixes existing distributions and adds regression tests)
  • Not applicable
  • Not applicable

Copilot AI review requested due to automatic review settings March 16, 2026 21:23
@kunal14901
Copy link
Author

Hi @fkiraly, I opened a second PR towards #22:
#957

This fixes scipy scale mapping for HalfNormal and HalfLogistic and adds dedicated regression tests.
Happy to iterate quickly on feedback.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes SciPy parameter mapping for half-distributions by passing scale as a keyword argument (avoiding incorrect positional binding), and adds regression tests to ensure parity with SciPy for scalar and broadcasted cases.

Changes:

  • Update _get_scipy_param for HalfNormal, HalfLogistic, and HalfCauchy to return {"scale": ...} as kwargs instead of positional args.
  • Add regression tests comparing pdf/cdf/ppf against SciPy for scalar inputs.
  • Add broadcast/shape/index/columns regression checks for DataFrame-backed evaluations.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
skpro/distributions/halfnormal.py Fix SciPy parameter mapping to use scale= keyword for halfnorm.
skpro/distributions/halflogistic.py Fix SciPy parameter mapping to use scale= keyword for halflogistic.
skpro/distributions/halfcauchy.py Fix SciPy parameter mapping to use scale= keyword for halfcauchy.
skpro/distributions/tests/test_half_distributions.py Add regression tests for HalfNormal/HalfLogistic scalar parity and broadcast behavior.
skpro/distributions/tests/test_halfcauchy.py Add regression tests for HalfCauchy scalar parity and broadcast behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 68 to +70
def _get_scipy_param(self):
beta = self._bc_params["beta"]
return [beta], {}
return [], {"scale": beta}
Comment on lines +19 to +48
def test_halfnormal_scalar_matches_scipy_scale():
"""HalfNormal scalar pdf/cdf/ppf should match scipy with scale=sigma."""
sigma = 2.5
dist = HalfNormal(sigma=sigma)

x = 1.7
p = 0.8

assert_allclose(dist.pdf(x), halfnorm.pdf(x, scale=sigma), rtol=1e-12)
assert_allclose(dist.cdf(x), halfnorm.cdf(x, scale=sigma), rtol=1e-12)
assert_allclose(dist.ppf(p), halfnorm.ppf(p, scale=sigma), rtol=1e-12)


@pytest.mark.skipif(
not run_test_module_changed("skpro.distributions"),
reason="run only if skpro.distributions has been changed",
)
def test_halflogistic_scalar_matches_scipy_scale():
"""HalfLogistic scalar pdf/cdf/ppf should match scipy with scale=beta."""
beta = 1.8
dist = HalfLogistic(beta=beta)

x = 1.3
p = 0.7

assert_allclose(dist.pdf(x), halflogistic.pdf(x, scale=beta), rtol=1e-12)
assert_allclose(dist.cdf(x), halflogistic.cdf(x, scale=beta), rtol=1e-12)
assert_allclose(dist.ppf(p), halflogistic.ppf(p, scale=beta), rtol=1e-12)


Comment on lines +19 to +49
def test_halfnormal_scalar_matches_scipy_scale():
"""HalfNormal scalar pdf/cdf/ppf should match scipy with scale=sigma."""
sigma = 2.5
dist = HalfNormal(sigma=sigma)

x = 1.7
p = 0.8

assert_allclose(dist.pdf(x), halfnorm.pdf(x, scale=sigma), rtol=1e-12)
assert_allclose(dist.cdf(x), halfnorm.cdf(x, scale=sigma), rtol=1e-12)
assert_allclose(dist.ppf(p), halfnorm.ppf(p, scale=sigma), rtol=1e-12)


@pytest.mark.skipif(
not run_test_module_changed("skpro.distributions"),
reason="run only if skpro.distributions has been changed",
)
def test_halflogistic_scalar_matches_scipy_scale():
"""HalfLogistic scalar pdf/cdf/ppf should match scipy with scale=beta."""
beta = 1.8
dist = HalfLogistic(beta=beta)

x = 1.3
p = 0.7

assert_allclose(dist.pdf(x), halflogistic.pdf(x, scale=beta), rtol=1e-12)
assert_allclose(dist.cdf(x), halflogistic.cdf(x, scale=beta), rtol=1e-12)
assert_allclose(dist.ppf(p), halflogistic.ppf(p, scale=beta), rtol=1e-12)


@pytest.mark.skipif(
x = 1.7
p = 0.8

assert_allclose(dist.pdf(x), halfnorm.pdf(x, scale=sigma), rtol=1e-12)
pdf = dist.pdf(x)
cdf = dist.cdf(x)
ppf = dist.ppf(p)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants