refactor: add explicit isnan guards#13343
Merged
kgryte merged 2 commits intoJul 7, 2026
Merged
Conversation
…1/mean` Adds explicit `isnan( alpha ) || isnan( beta )` short-circuits to the validation prologue in `lib/main.js`, matching the pattern used by 10/12 comparable siblings in `stats/base/dists/pareto-type1` (`cdf`, `entropy`, `kurtosis`, `logcdf`, `logpdf`, `mode`, `pdf`, `quantile`, `skewness`, `variance` — 83.3% conformance) and the package's own C counterpart in `src/main.c`, which uses `stdlib_base_is_nan( alpha ) || stdlib_base_is_nan( beta )`. NaN inputs previously returned NaN via arithmetic propagation through the `(alpha*beta) / (alpha-1)` expression; observable behavior is unchanged.
…1/median` Adds explicit `isnan( alpha ) || isnan( beta )` short-circuits to the validation prologue in `lib/main.js`, matching the pattern used by 10/12 comparable siblings in `stats/base/dists/pareto-type1` (`cdf`, `entropy`, `kurtosis`, `logcdf`, `logpdf`, `mode`, `pdf`, `quantile`, `skewness`, `variance` — 83.3% conformance). NaN inputs previously returned NaN via arithmetic propagation through `beta * pow( 2, 1/alpha )`; observable behavior is unchanged.
Contributor
Coverage Report
The above coverage report was generated for the changes in this PR. |
kgryte
approved these changes
Jul 7, 2026
isnan guards in stats/base/dists/pareto-type1/{mean,median}isnan guards
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This pull request:
stats/base/dists/pareto-type1/meanandstats/base/dists/pareto-type1/medianwith the interleavedisnan()guard shape already used by 10 of 12 comparable sibling packages (cdf,entropy,kurtosis,logcdf,logpdf,mode,pdf,quantile,skewness,variance— 83.3% conformance) and with themeanpackage's own C source atsrc/main.c. Observable behavior is unchanged in both packages;NaNinputs previously returnedNaNthrough arithmetic propagation and now short-circuit via the explicit guard.Namespace summary
@stdlib/stats/base/dists/pareto-type1cdf,ctor,entropy,kurtosis,logcdf,logpdf,mean,median,mode,pdf,quantile,skewness,stdev,variance)package.jsontop-level /scripts/stdlib/directories/keywordskeys, README section sequence,manifest.jsonshape, test/benchmark/examples filenames, public signature, return kind, validation prologue, error construction, JSDoc shape (param tags / returns / throws /@exampleblocks),lib/main.jsrequiredependencies, and the corresponding C sources.package.jsontop-level key set (100%);directorieskeysbenchmark/doc/example/lib/test(100%);## Usageand## ExamplesREADME sections (100%); interleavedisnan( arg ) || arg <= 0.0 || …validation prologue at 10/14 = 71% overall, 10/12 = 83.3% among the numeric-property packages that carry a prologue at all (ctorandstdevlegitimately excluded —ctorthrows viaformat,stdevdelegates viasqrt( variance( α, β ) )); Cstdlib_base_is_nanguard insrc/main.cat 11/12 native-backed C sources = 91.7% (stdevexcluded).manifest.json,binding.gyp,include.gypi,src/**,lib/native.js,benchmark/c/**,benchmark/benchmark.native.js,examples/c/**,test/test.native.js) at 12/14 = 85.7% (the 2 outliers arectorandmedian, which are inapplicable — see PR feat: add C implementation forstats/base/dists/pareto-type1/median#10079 formedian's native binding);## C APIsREADME section at 12/14 = 85.7% (same rationale);gypfilepackage.jsonkey at 12/14 = 85.7%;lib/factory.jsat 5/14 = 36%; public signature shape (split between(α, β)summary stats and(x|p, α, β)distribution functions — no shape ≥ 75%); error construction (onlyctorthrows; rest returnNaN); README## Notessection (onlylogcdfandlogpdf); dependency sets (varies legitimately by mathematical implementation).stats/base/dists/pareto-type1/meanAdd explicit
isnan( alpha ) || isnan( beta )guards to the validation prologue inlib/main.js, matching the interleaved shape used by 10 of 12 sibling numeric-property packages (83.3% conformance) and realigning the JS with the C source atsrc/main.c, which already checksstdlib_base_is_nan( alpha ) || stdlib_base_is_nan( beta ). Observable behavior is unchanged:NaNinputs previously propagated through(alpha*beta)/(alpha-1)and now short-circuit via the explicit guard.stats/base/dists/pareto-type1/medianPrepend explicit
isnan( alpha )andisnan( beta )checks to the parameter validation prologue inlib/main.js, matching the interleaved guard shape used by 10 of 12 comparable numeric-property packages instats/base/dists/pareto-type1(83.3% conformance;ctorandstdevare excluded as they validate viaformatandsqrt( variance( α, β ) )respectively). Observable behavior is unchanged:median( NaN, 2.0 )previously returnedNaNthrough arithmetic propagation inbeta * pow( 2.0, 1.0/alpha ), and now returnsNaNvia the explicit guard. Orthogonal to #10079, which adds the native binding and applies the equivalentstdlib_base_is_nanguard in the C source.Validation
Checked:
package.jsonshape, README section list,manifest.jsonshape, test/benchmark/example filenames) across all 14 members.lib/main.jsand the correspondingsrc/main.cdirectly.confirmed-driftfor bothmeanandmedian, citing thatmean/src/main.calready includes thestdlib_base_is_nanguard (the JS drifted from its own C mirror) and that no comment, test, or JSDoc claim justifies omission.safe-to-applyfor both, confirmingtest/test.jsin both packages already assertsNaNreturn forNaNinputs,docs/repl.txtanddocs/types/index.d.tsalready document the same,examples/index.jsuses non-NaNuniform-random inputs, andctorconsumers gate throughisPositivebefore ever invokingmean/median(soctorbehavior is unaffected).confirmed-driftfor both, confirming the family pattern is the exact interleaved shapeif ( isnan( α ) || α <= 0.0 || isnan( β ) || β <= 0.0 )(as used bymode,entropy,kurtosis,skewness,variance), and that placement of the guard beforemean'sif ( alpha <= 1.0 ) return PINF;branch is correct (sinceNaN <= 1.0isfalse, without the guardNaNwould fall through the PINF branch).Deliberately excluded:
ctorerrorConstruction = "format"(throwsTypeErrorvia@stdlib/string/format) vs. the majorityreturn NaN. Intentional deviation: a class constructor legitimately throws on bad arguments; distribution-property scalars returnNaN.stdev/lib/main.jslacks a validation prologue, delegatingreturn sqrt( variance( alpha, beta ) );. Intentional deviation:variancealready performs identical validation;sqrt( NaN ) === NaNpreserves observable behavior; sibling distributionsbinomial/stdev,lognormal/stdev,poisson/stdevfollow the same delegating idiom (independently established by the earlierbinomialandlognormalruns of this routine, PRs style: align outliers instats/base/dists/binomialwith namespace majority patterns #11902 and docs: add negative-scale@exampletostats/base/dists/lognormal/cdf#12093).ctor(constructor — inapplicable) andmedian(currently JS-only ondevelop; feat: add C implementation forstats/base/dists/pareto-type1/median#10079 adds it). Adding a full C stack is a substantive new feature, not a mechanical drift fix.logcdfandlogpdfREADMEs carry an extra## Notessection not present in siblings. Intentional: the note explains thex < betabranch that returns-Infinity, which is specific to the logarithmic transform.## See AlsoREADME section drift — auto-populated by the package generator; gate 7a excludes.equation_pareto_type1_expectation.svgformeanvs._median.svg,_mode.svg,_kurtosis.svg, etc.). Intentional:expectationmatches the equation label\mathbb{E}[X]in the same file.Related Issues
No.
Questions
No.
Other
Random namespace pick from the
lib/node_modules/@stdlib/walk of directories with ≥ 8 direct child packages. Does not conflict with the open native-binding PR #10079 targetingpareto-type1/median, which touches only new native files (binding.gyp,manifest.json,include/**,src/**,benchmark/benchmark.native.js,benchmark/c/**,examples/c/**,lib/native.js,test/test.native.js) and appends a## C APIssection toREADME.md— orthogonal to thelib/main.jsfiles modified here.Checklist
AI Assistance
If you answered "yes" above, how did you use AI assistance?
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/pareto-type1, majority patterns were computed at a 75% conformance threshold, and three independent validation agents (opus semantic-review, opus cross-reference, sonnet structural-review) confirmed each correction was high-signal mechanical drift before any file was edited. The two edits are pure additive guards to existingif (…) return NaN;prologues inlib/main.js; no source, test, or observable-behavior changes.@stdlib-js/reviewers
Generated by Claude Code