Skip to content

[DOC] add explicit formulae to _formula_docs for Logistic and Weibull distributions - #1124

Merged
fkiraly merged 5 commits into
sktime:mainfrom
itsnevu:patch-1
Aug 22, 2026
Merged

[DOC] add explicit formulae to _formula_docs for Logistic and Weibull distributions#1124
fkiraly merged 5 commits into
sktime:mainfrom
itsnevu:patch-1

Conversation

@itsnevu

@itsnevu itsnevu commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Reference Issues/PRs

Towards #1120.

Does not overlap with #1123 (Uniform, @Vidit-lab) or #968 (Pareto). Claimed on the issue before starting.

What does this implement/fix? Explain your changes.

Populates _formula_docs for two distributions that previously had none:

  • Logistic (skpro/distributions/logistic.py)
  • Weibull (skpro/distributions/weibull.py)

Each dict covers all seven applicable keys: pdf, log_pdf, cdf, ppf, mean, var, energy, following the Normal example and the extension template.

I picked these two because they are native BaseDistribution implementations with elementary closed-form ppf and exact mean/var, so every key is fillable without guessing. I looked at Poisson, Binomial and Beta first and skipped them: they are _ScipyAdapter wrappers whose ppf has no closed form.

This PR also has to touch skpro/distributions/tests/test_docstring_injection.py. That test used Weibull as the UNHOOKED_CLASSES control group, so adding formulae to Weibull made test_unhooked_clean_fallback fail on its ".. math::" not in doc assertion. Weibull moves into HOOKED_CLASSES alongside Logistic, and Gamma becomes the new control - it has no _formula_docs and is unclaimed on #1120 at the time of writing. Happy to use a different control if you would prefer one less likely to be claimed.

References for the formulae

No AI-generated formulae.

Core pdf/log_pdf/cdf/ppf/mean/var are standard results from Johnson, Kotz & Balakrishnan, Continuous Univariate Distributions, 2nd ed. - Vol. 2 Ch. 23 (Logistic) and Vol. 1 Ch. 21 (Weibull); cross-checked against the NIST/SEMATECH e-Handbook 1.3.6.6.

The two energy formulae, stated explicitly since they need more than a citation:

  • Logistic, E|X-Y| = 2s - already stated and derived in this repo, in the existing Logistic._energy_self docstring (logistic.py L223-233).
  • Weibull, E|X-Y| = 2*lambda*Gamma(1 + 1/k)*(1 - 2**(-1/k)) - derived from the fact that for iid X, Y ~ Weibull(lambda, k), min(X, Y) ~ Weibull(lambda * 2**(-1/k), k), so E|X-Y| = 2*(E[X] - E[min]).

Both reproduce the Analytic column already tabulated in this repo's own skpro/distributions/energy_formulae.md - Logistic(0,1) = 2.000000 and Weibull(1,2) = 0.519140 - which I treat as independent confirmation rather than my own arithmetic checking itself.

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

No.

What should a reviewer concentrate their feedback on?

  • The choice of Gamma as the replacement control group in test_docstring_injection.py.
  • Whether the energy key should be included at all, or left out until there is a dedicated review of energy formulae. Removing it is a clean deletion of one key per distribution; the other six are independent.
  • Parameterisation, which I matched to the code rather than to any single textbook convention: Logistic.scale is the true scale s (so the sd is s*pi/sqrt(3)), and Weibull.scale is the multiplicative scale lambda, matching scipy.stats.weibull_min(c=k, scale=lambda). Neither is a rate. Weibull's documented support is x >= 0 because _pdf and _cdf both multiply by (x >= 0).

Did you add any tests for the change?

No new tests. The existing test_docstring_injection.py already covers exactly this change: test_hooked_math_injection now asserts that Logistic and Weibull render .. math::, and test_placeholder_removal_universal asserts no {formula_doc} leak. 95 tests pass locally.

Separately from the test suite, I verified every formula numerically against each class's own _pdf/_log_pdf/_cdf/_ppf/_mean/_var over several parameter settings (max deviation ~1e-15), and the energy closed forms against quadrature of 2 * integral F(t)(1-F(t)) dt.

Any other comments?

Two docstring errors in logistic.py that I did not touch here, since they are bugs rather than missing formulae, and I would rather not smuggle behaviour-adjacent corrections into a docs PR:

  1. The class docstring at L17 gives the cdf as F(x) = 1/(1 + exp((x - mu)/s)) - the minus sign is missing, so that is the survival function, not the cdf. The code is correct.
  2. _var at L79 writes \pi^3 where the code correctly computes pi**2.

Happy to fold both into this PR if you would prefer, or I will open a separate [BUG] issue.

On LogNormal, which I also claimed on the issue: lognormal.py is the only one of the three files with CRLF line endings, and editing it through the GitHub web editor normalises them to LF, turning a ~60 line addition into a 265-line whitespace diff. Rather than mix a line-ending change into a docs PR, I am leaving it for a follow-up done as a local commit. Worth noting that the CRLF endings in that one file may be unintentional in an otherwise LF repo.

All seven keys: pdf, log_pdf, cdf, ppf, mean, var, energy.

Core formulae from Johnson, Kotz & Balakrishnan, Continuous Univariate
Distributions, 2nd ed., Vol. 2 Ch. 23. Energy 2s is already stated and
derived in this file’s own _energy_self docstring, and matches the
Analytic column for Logistic(0,1) in energy_formulae.md.

Note scale is the true scale s, not a rate: sd is s*pi/sqrt(3).
All seven keys: pdf, log_pdf, cdf, ppf, mean, var, energy.

Core formulae from Johnson, Kotz & Balakrishnan, Continuous Univariate
Distributions, 2nd ed., Vol. 1 Ch. 21. Energy derived from the fact that
min(X, Y) of two iid Weibull(lambda, k) is Weibull(lambda * 2**(-1/k), k),
so E|X-Y| = 2*(E[X] - E[min]); this reproduces the Analytic value 0.519140
for Weibull(1,2) already tabulated in energy_formulae.md.

Note scale is the multiplicative scale lambda, not a rate, matching
scipy.stats.weibull_min(c=k, scale=lambda). Support is x >= 0, as the
_pdf and _cdf both multiply by (x >= 0).
Weibull was the UNHOOKED_CLASSES control group, so adding _formula_docs
to it makes test_unhooked_clean_fallback fail on the ".. math::" assertion.

Moves Weibull into HOOKED_CLASSES together with Logistic and LogNormal,
and promotes Gamma to be the new control. Gamma has no _formula_docs and
is not claimed on sktime#1120 at the time of writing.
lognormal.py is the only file of the three with CRLF line endings, and
editing it through the GitHub web editor normalises them to LF, which
turns a +60 line change into a 265-line whitespace diff. Rather than mix
a line-ending change into a docs PR, LogNormal is left for a follow-up
done as a local commit.

This PR is therefore Logistic and Weibull only, and the test file is
adjusted to match.
@fkiraly fkiraly added module:distributions&simulation probability distributions and simulators documentation Documentation & tutorials labels Aug 22, 2026
@fkiraly
fkiraly merged commit c560308 into sktime:main Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Documentation & tutorials module:distributions&simulation probability distributions and simulators

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants