Skip to content

refactor: replace isProbability with inline range check in stats/base/dists/bernoulli/mgf#12292

Merged
kgryte merged 1 commit into
developfrom
philipp/drift-stats-base-dists-bernoulli-2026-05-26
May 27, 2026
Merged

refactor: replace isProbability with inline range check in stats/base/dists/bernoulli/mgf#12292
kgryte merged 1 commit into
developfrom
philipp/drift-stats-base-dists-bernoulli-2026-05-26

Conversation

@Planeshifter
Copy link
Copy Markdown
Member

Description

Normalizes the probability-range validation in @stdlib/stats/base/dists/bernoulli/mgf (both lib/main.js and lib/factory.js) from !isProbability( p ) to the inline form isnan( p ) || p < 0.0 || p > 1.0 used by every other JS member of the stats/base/dists/bernoulli namespace, and removes the now-unused @stdlib/math/base/assert/is-probability require from both files.

Namespace summary

  • Target: @stdlib/stats/base/dists/bernoulli
  • Members analyzed: 13 (cdf, ctor, entropy, kurtosis, mean, median, mgf, mode, pmf, quantile, skewness, stdev, variance)
  • Autogenerated members: 0
  • Features analyzed: file tree; package.json top-level / scripts / stdlib key sets; manifest.json key set; README ##/### section sequence; test/ / benchmark/ / examples/ filenames; per-package lib/main.js and lib/factory.js public signature, validation prologue, return kind, error-construction style, JSDoc shape, and require dependency set.
  • Features with a clear majority (≥75% conformance): full package.json top-level 18-key set (13/13 = 100%); manifest.json presence + 3-key set (12/13 = 92%); the native-bindings file group binding.gyp / include.gypi / src/{Makefile,addon.c,main.c} / lib/native.js / include/.../<name>.h / examples/c/** / benchmark/c/** / benchmark/benchmark.native.js / test/test.native.js (12/13 = 92%); README 5-section sequence ## Usage## Examples## C APIs### Usage### Examples (11/13 = 85%); test/fixtures/julia/REQUIRE + runner.jl (11/13 = 85%); validation prologue isnan( p ) || p < 0.0 || p > 1.0 in JS sources where p is checked (12/13 = 92%); value return kind (13/13 = 100%); JSDoc hasExample (13/13 = 100%).
  • Features without a clear majority (excluded from drift detection): public signature shape (single-arg name(p) 8/13 vs 2-arg distribution-function packages 4/13 vs ctor 1/13 — no shape ≥75%); error-construction style (only ctor throws; the remaining 12 return NaN, so this is degenerate).

stats/base/dists/bernoulli/mgf

Replaces !isProbability( p ) with the inline isnan( p ) || p < 0.0 || p > 1.0 check in both lib/main.js and lib/factory.js, and drops the unused @stdlib/math/base/assert/is-probability import from each file. The inline form is what the other 12 bernoulli siblings use (92.3% conformance) and what 20 of the 22 stats/base/dists/*/mgf packages across the wider namespace use (90.9%). isProbability( x ) is defined as x >= 0.0 && x <= 1.0, so the two forms agree on NaN, ±Infinity, and all finite inputs; observable behavior is preserved.

Validation

Checked:

  • Structural feature extraction (file tree; package.json shape; manifest.json shape; README ##/### section list; test/ / benchmark/ / examples/ filenames) across all 13 members.
  • Semantic feature extraction (public signature; validation prologue; return kind; error-construction style; JSDoc shape; require dependency set) across all 13 members by reading each lib/main.js (and lib/factory.js where present) directly.
  • Three-agent drift validation on the single surviving correction (bernoulli/mgf validation prologue):
    • Semantic-review confirmed !isProbability( p ) and isnan( p ) || p < 0.0 || p > 1.0 are mathematically equivalent for double-precision input (NaN, ±Infinity, and out-of-range values all map to the false branch of isProbability, which becomes the true branch of !isProbability, matching the disjunction).
    • Cross-reference confirmed test/test.mgf.js boundary cases (NaN, ±Infinity, 2.0, -0.5 for p) all return NaN under both forms, README.md and docs/repl.txt make no reference to isProbability, and no sibling package imports bernoulli/mgf directly.
    • Structural-review is not applicable (semantic-only feature).
  • Open-PR check via the GitHub MCP — no open PR targets stats/base/dists/bernoulli or proposes this fix.
  • Manual smoke test from a Node REPL against the same boundary inputs the existing test/test.mgf.js exercises; all return NaN as before.

Deliberately excluded:

  • ctor — absence of the native-bindings file group, gypfile, manifest.json, and the canonical ## Usage## Examples README structure. Intentional: pure-JS class constructor with no native numerical hot path; the constructor's documentation legitimately requires intermediate property/method subsections.
  • mode — extra ## Notes section between ## Usage and ## Examples. Intentional: the Bernoulli mode is undefined at p === 0.5; the note documents stdlib's 0 convention. Stripping the section would lose content.
  • stdev — uses test/fixtures/python/ instead of test/fixtures/julia/, and delegates stdev( p ) = sqrt( variance( p ) ) rather than carrying the canonical validation prologue. Cascading / intentional: regenerating fixtures and updating the tape test loader is out of scope for a mechanical drift PR; the delegation idiom was the subject of merged PR refactor: reuse variance in stats/base/dists/bernoulli/stdev #11366 and is correct.
  • C-side src/main.c for bernoulli/mgf only checks isnan( t ) || isnan( p ), missing the p < 0.0 || p > 1.0 range that cdf/src/main.c and pmf/src/main.c apply, and lib/native.js JSDoc actually documents the missing-check behaviour as expected. Not fixed here: changing observable native-path output and the documented examples is out of scope; surfacing as a separate behavioural follow-up.
  • Public signature drift between single-arg property packages and 2-arg distribution-function packages — no signature shape reaches 75%.

Related Issues

This pull request has no related issues.

Questions

No.

Other

stats/base/dists/geometric/mgf carries the identical isProbability drift (the only other distribution-namespace mgf package using the predicate form) and is a clear follow-up candidate. Internal run metadata (random seed, full per-feature distributions, dropped corrections with reasons) lives in the local drift report at ~/drift-reports/drift-stats-base-dists-bernoulli-2026-05-26.md.

Checklist

AI Assistance

  • Yes
  • No

If you answered "yes" above, how did you use AI assistance?

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

Disclosure

This PR was authored by Claude Code via the cross-package drift-detection routine: structural and semantic features were extracted from every member of stats/base/dists/bernoulli, the majority pattern was computed at a 75% conformance threshold, and three independent validation agents (semantic-review, cross-reference, structural-review) confirmed the single surviving correction was high-signal mechanical drift before any file was edited. The edit replaces a predicate-based probability check with the namespace-standard inline check and removes the now-unused require; no test, fixture, or behavioural change.


@stdlib-js/reviewers


Generated by Claude Code

…ase/dists/bernoulli/mgf`

Normalize the probability-range validation in `lib/main.js` and `lib/factory.js`
to the inline form `isnan( p ) || p < 0.0 || p > 1.0` used by every other member
of the `stats/base/dists/bernoulli` namespace (12/13 siblings; 92.3% conformance).
Cross-namespace, the same inline form is used by 20/22 `stats/base/dists/*/mgf`
packages (90.9%), so the previous `!isProbability(p)` form is also a minority
across the wider `stats/base/dists` family.

Behavior preserved: `isProbability(x)` returns `x >= 0.0 && x <= 1.0`, so
`!isProbability(p)` and `isnan(p) || p < 0.0 || p > 1.0` agree on NaN, ±Infinity,
and all finite inputs. The `@stdlib/math/base/assert/is-probability` import is
removed from both files since it is no longer used.

Manual smoke-tested against the existing `test/test.mgf.js` boundary cases
(`NaN`, ±Infinity, `2.0`, `-0.5` for `p`); all return `NaN` as before.
@stdlib-bot stdlib-bot added the Statistics Issue or pull request related to statistical functionality. label May 26, 2026
@stdlib-bot
Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
stats/base/dists/bernoulli/mgf $\color{green}269/269$
$\color{green}+100.00%$
$\color{green}19/19$
$\color{green}+100.00%$
$\color{green}4/4$
$\color{green}+100.00%$
$\color{green}269/269$
$\color{green}+100.00%$

The above coverage report was generated for the changes in this PR.

@Planeshifter Planeshifter marked this pull request as ready for review May 26, 2026 17:10
@Planeshifter Planeshifter requested a review from a team May 26, 2026 17:10
@stdlib-bot stdlib-bot added the Needs Review A pull request which needs code review. label May 26, 2026
@Planeshifter Planeshifter requested a review from kgryte May 26, 2026 17:10
@kgryte kgryte removed the Needs Review A pull request which needs code review. label May 27, 2026
@kgryte kgryte merged commit 3c1e93d into develop May 27, 2026
54 checks passed
@kgryte kgryte deleted the philipp/drift-stats-base-dists-bernoulli-2026-05-26 branch May 27, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Statistics Issue or pull request related to statistical functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants