Skip to content

test: migrate stats/incr/mpcorr to ULP-based assertions - #16064

Draft
kgryte wants to merge 1 commit into
developfrom
kgryte/ulp-stats-incr-mpcorr
Draft

kgryte wants to merge 1 commit into
developfrom
kgryte/ulp-stats-incr-mpcorr

Conversation

@kgryte

@kgryte kgryte commented Oct 11, 2026

Copy link
Copy Markdown
Member

Resolves a part of #11352.

Description

What is the purpose of this pull request?

This pull request:

Specifically, this pull request:

  • adds the @stdlib/assert/is-almost-same-value import and removes the now-unused @stdlib/math/base/special/abs and @stdlib/constants/float64/eps imports.
  • removes the delta/tol computations (and the corresponding var delta;/var tol; declarations) from the six fixture loops which used them.
  • replaces the if ( actual === expected ) { ... } else { ... delta/tol ... } branches with a single t.strictEqual( isAlmostSameValue( actual, expected, N ), true, 'returns expected value' ); assertion.
  • pins the PRNG seed used to generate the sample datasets (see "Other" below).

Only test/test.js is modified; the package has no test/test.native.js. No other test cases were touched, and existing exact comparisons (t.strictEqual/t.notEqual/isnan checks) were left as-is.

The conversion mirrors, line for line, the already-merged stats/incr/mpcorr2 migration. That package's test file is structurally identical to this one apart from squaring the correlation coefficient, so it serves as direct prior art for every change here.

ULP bounds

Each fixture loop was tightened independently to the measured minimum:

Test case Measured ULP difference Final ULP bound
moving sample correlation coefficient, unknown means 6716 6716
moving sample correlation coefficient, known means 1623 1623
acc() returns current coefficient, unknown means 1 1
acc() returns current coefficient, known means 0 0
NaN handling, unknown means (both data orderings) 1 1

The bounds were tightened agentically, starting high and lowering. Each one is confirmed minimal: lowering 6716 to 6715, 1623 to 1622, or any of the 1s to 0 causes the suite to fail on exactly the affected assertions. The 0 bound is already the floor (isAlmostSameValue with maxULP === 0 reduces to isSameValue, and all values in that loop compare exactly equal).

The large bounds in the first two cases reflect the catastrophic cancellation inherent to incrementally accumulating a moving correlation coefficient over datasets spanning ten orders of magnitude; they are of the same order as the 10425/3415 bounds accepted for the corresponding loops in stats/incr/mpcorr2, and are substantially tighter than the relative tolerance they replace (5.0e5 * EPS, i.e. roughly 2.3e6 ULP).

Related Issues

Does this pull request have any related issues?

This pull request has the following related issues:

Questions

Any questions for reviewers of this pull request?

Flagging one change for explicit review: pinning the PRNG seed (see "Other" below). It is strictly necessary for the ULP bounds to be meaningful, and it follows the precedent set by stats/incr/mpcorr2 and stats/incr/nanmpcorr2, but it is the one change in this PR which is not a pure assertion rewrite. Happy to revisit if a different seed or a different approach is preferred.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

  • PRNG seed pinning. The two large fixture loops previously called datasets( N, M, randu.seed ). randu.seed is seeded non-deterministically per process, so the sample datasets — and therefore the observed ULP differences — varied from run to run, which makes a minimum ULP bound impossible to establish or to keep stable in CI. Both calls are now datasets( N, M, 123456 ), matching the already-merged stats/incr/mpcorr2 and stats/incr/nanmpcorr2 test files, which pin the same seed value for the same reason. All remaining uses of randu in the file (the window-size-1 test cases) are untouched.
  • make test TESTS_FILTER=".*/stats/incr/mpcorr/.*" passes 2422/2422. The suite was run twice at the final bounds with identical results, and the per-loop maximum ULP differences were separately measured across three additional runs, all identical — confirming determinism (no FMA/arch-dependent variation in this environment).
  • make eslint-tests TESTS_FILTER=".*/stats/incr/mpcorr/.*" passes cleanly.
  • The lint-editorconfig-files target could not be run in this environment because it downloads the editorconfig-checker binary from a GitHub repository that was not reachable from the sandbox (HTTP 403). The file was instead verified programmatically against .editorconfig: LF line endings, valid UTF-8, tab indentation (no space-indented lines), no trailing whitespace, and a single final newline.

Checklist

Please ensure the following tasks are completed before submitting this pull request.

AI Assistance

When authoring the changes proposed in this PR, did you use any kind of 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

If you answered "yes" to using AI assistance, please provide a short disclosure indicating how you used AI assistance. This helps reviewers determine how much scrutiny to apply when reviewing your contribution. Example disclosures: "This PR was written primarily by Claude Code." or "I consulted ChatGPT to understand the codebase, but the proposed changes were fully authored manually by myself.".

This PR was authored by Claude Code running as an unattended scheduled task. It selected the package at random from the remaining unconverted candidates, studied the already-merged stats/incr/mpcorr2 migration as prior art, performed the test conversion, and determined the minimum ULP bounds empirically by instrumenting the suite to record the maximum ULP difference observed in each fixture loop and then confirming that each bound minus one fails.


@stdlib-js/reviewers


Generated by Claude Code

Migrates the `stats/incr/mpcorr` test suite from relative tolerance
testing to ULP difference testing.

-   Adds the `@stdlib/assert/is-almost-same-value` import and removes
    the now-unused `@stdlib/math/base/special/abs` and
    `@stdlib/constants/float64/eps` imports.
-   Replaces the `delta`/`tol` computations and their
    `t.strictEqual( delta < tol, ... )` assertions with
    `t.strictEqual( isAlmostSameValue( actual, expected, N ), true,
    'returns expected value' )`, using the measured minimum `N`.
-   Pins the PRNG seed used to generate the sample datasets, as
    previously done in `stats/incr/mpcorr2` and
    `stats/incr/nanmpcorr2`, so that the ULP bounds are deterministic.

Ref: #11352

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GzPhMP8iKCvtg52SimALy
@stdlib-bot stdlib-bot added Statistics Issue or pull request related to statistical functionality. Good First PR A pull request resolving a Good First Issue. labels Oct 11, 2026
@stdlib-bot

Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
stats/incr/mpcorr $\\color{green}590/590$
$\\color{green}+100.00\\%$
$\\color{green}61/61$
$\\color{green}+100.00\\%$
$\\color{green}3/3$
$\\color{green}+100.00\\%$
$\\color{green}590/590$
$\\color{green}+100.00\\%$

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

This branch has not been deployed

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

Labels

Good First PR A pull request resolving a Good First Issue. Statistics Issue or pull request related to statistical functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants