Skip to content

Conversation

@aryan7071
Copy link
Contributor


type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes. report:

  • task: lint_filenames status: passed
  • task: lint_editorconfig status: passed
  • task: lint_markdown status: passed
  • task: lint_package_json status: passed
  • task: lint_repl_help status: passed
  • task: lint_javascript_src status: passed
  • task: lint_javascript_cli status: na
  • task: lint_javascript_examples status: passed
  • task: lint_javascript_tests status: passed
  • task: lint_javascript_benchmarks status: passed
  • task: lint_python status: na
  • task: lint_r status: na
  • task: lint_c_src status: na
  • task: lint_c_examples status: na
  • task: lint_c_benchmarks status: na
  • task: lint_c_tests_fixtures status: na
  • task: lint_shell status: na
  • task: lint_typescript_declarations status: passed
  • task: lint_typescript_tests status: passed
  • task: lint_license_headers status: passed ---

Description

What is the purpose of this pull request?

This pull request:

  • add stats/base/ndarray/snanstdev

Related Issues

Does this pull request have any related issues?

This pull request has the following related issues:

  • #{{TODO: add related issue number}}

Questions

Any questions for reviewers of this pull request?

No.

Other

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

No.

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

@stdlib-js/reviewers

---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: passed
  - task: lint_package_json
    status: passed
  - task: lint_repl_help
    status: passed
  - task: lint_javascript_src
    status: passed
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: passed
  - task: lint_javascript_tests
    status: passed
  - task: lint_javascript_benchmarks
    status: passed
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: passed
  - task: lint_license_headers
    status: passed
---
@stdlib-bot stdlib-bot added Statistics Issue or pull request related to statistical functionality. Needs Review A pull request which needs code review. labels Jan 9, 2026
@aryan7071
Copy link
Contributor Author

/stdlib update-copyright-years

@stdlib-bot stdlib-bot added the bot: In Progress Pull request is currently awaiting automation. label Jan 9, 2026
@stdlib-bot stdlib-bot removed the bot: In Progress Pull request is currently awaiting automation. label Jan 9, 2026
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: na
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: passed
  - task: lint_javascript_benchmarks
    status: passed
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: na
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: passed
  - task: lint_javascript_benchmarks
    status: na
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: na
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: passed
  - task: lint_javascript_benchmarks
    status: na
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
@stdlib-bot
Copy link
Contributor

stdlib-bot commented Jan 9, 2026

Coverage Report

Package Statements Branches Functions Lines
stats/base/ndarray/snanstdev $\color{green}110/110$
$\color{green}+0.00%$
$\color{green}3/3$
$\color{green}+0.00%$
$\color{green}1/1$
$\color{green}+0.00%$
$\color{green}110/110$
$\color{green}+0.00%$

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

@Planeshifter Planeshifter changed the title feat: add stats/base/ndarray/snanstdev feat: add stats/base/ndarray/snanstdev Jan 10, 2026
Copy link
Member

@Planeshifter Planeshifter left a comment

Choose a reason for hiding this comment

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

This PR currently has a critical bug.

*/
function snanstdev( arrays ) {
var x = arrays[ 0 ];
return strided(numelDimension( x, 0 ), getData( x ), getStride( x, 0 ), getOffset( x )); // eslint-disable-line max-len
Copy link
Member

Choose a reason for hiding this comment

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

The call to strided() (which is snanstdevpn.ndarray) is missing the required correction parameter. Looking at the underlying function signature:

snanstdevpn( N, correction, x, stride, offset )

The current call passes:

  • N = numelDimension(x, 0)
  • correction = getData(x) ✗ (the data buffer is being passed as correction!)
  • x = getStride(x, 0) ✗ (stride is being passed as the array)
  • stride = getOffset(x) ✗ (offset is being passed as stride)
  • offset = missing ✗

This completely breaks the function. Looking at similar packages like sstdevpn and sstdev, the function should:

  1. Accept a second ndarray in arrays for the correction value
  2. Extract it using ndarraylike2scalar
  3. Pass all 5 arguments to strided()

See @stdlib/stats/base/ndarray/sstdevpn/lib/main.js for the correct pattern.

Comment on lines 35 to 46
* @param {ArrayLikeObject<Object>} arrays - array-like object containing an input ndarray
* @returns {number} standard deviation
*
* @example
* var Float32Array = require( '@stdlib/array/float32' );
* var ndarray = require( '@stdlib/ndarray/base/ctor' );
*
* var xbuf = new Float32Array( [ 1.0, 3.0, NaN, 2.0 ] );
* var x = new ndarray( 'float32', xbuf, [ 4 ], [ 1 ], 0, 'row-major' );
*
* var v = snanstdev( [ x ] );
* // returns NaN
Copy link
Member

Choose a reason for hiding this comment

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

The JSDoc says this accepts only one ndarray, but standard deviation packages in stdlib require a second zero-dimensional ndarray for the degrees of freedom adjustment (correction). The function signature should match packages like sstdev and sstdevpn:

* @param {ArrayLikeObject<Object>} arrays - array-like object containing a one-dimensional input ndarray and a zero-dimensional ndarray specifying a degrees of freedom adjustment

Also, the // returns NaN comment is incorrect - for input [1.0, 3.0, 2.0] (ignoring the NaN), the standard deviation should be approximately 1.0, not NaN.

> var ord = 'row-major';
> var x = new {{alias:@stdlib/ndarray/ctor}}( dt, xbuf, sh, sx, ox, ord );
> {{alias}}( [ x ] )
NaN
Copy link
Member

Choose a reason for hiding this comment

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

The example output NaN is incorrect. For input [ 1.0, -2.0, 2.0 ] (none of which are NaN), the standard deviation should be a positive number, not NaN.

Once the correction parameter is added to the API, this example should also include the correction ndarray and show the correct numeric output.

Comment on lines 74 to 78
tape( 'the function supports ndarrays with multiple non-NaN values', function test( t ) {
var x = new Float32Array( [ 1.0, 2.0, NaN, 3.0 ] );
var v = snanstdev( [ vector( x, 4, 1, 0 ) ] );

t.ok( isnanf( v ) || v >= 0.0, 'returns NaN or non-negative number' );
Copy link
Member

Choose a reason for hiding this comment

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

These assertions are too weak - they pass even when the function returns NaN for all inputs (which is what's happening due to the missing correction parameter bug).

Tests should verify the actual computed standard deviation value. For example, for input [1.0, 2.0, 3.0] (ignoring NaN), with correction=1, the expected standard deviation is 1.0.

Consider adding tests like:

tape( 'the function computes the standard deviation', function test( t ) {
    var expected = 1.0;  // stdev of [1, 2, 3] with correction=1
    var x = new Float32Array( [ 1.0, 2.0, NaN, 3.0 ] );
    var v = snanstdev( [ vector( x, 4, 1, 0 ), correction ] );
    t.strictEqual( v, expected, 'returns expected value' );
    t.end();
});

Comment on lines 65 to 76
function benchmark( b ) {
var v;
var i;

b.tic();
for ( i = 0; i < b.iterations; i++ ) {
v = variancech( [ x, correction ] );
if ( isnan( v ) ) {
b.fail( 'should not return NaN' );
}
snanstdev( [ x ] );
}
b.toc();
if ( isnan( v ) ) {
b.fail( 'should not return NaN' );
}

b.pass( 'benchmark finished' );
b.end();
}
Copy link
Member

Choose a reason for hiding this comment

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

The benchmark doesn't capture or verify the return value. Looking at reference packages like snanmean, the benchmark should:

  1. Capture the return value: v = snanstdev( [ x ] );
  2. Import isnanf and add sanity checks inside and after the loop
Suggested change
function benchmark( b ) {
var v;
var i;
b.tic();
for ( i = 0; i < b.iterations; i++ ) {
v = variancech( [ x, correction ] );
if ( isnan( v ) ) {
b.fail( 'should not return NaN' );
}
snanstdev( [ x ] );
}
b.toc();
if ( isnan( v ) ) {
b.fail( 'should not return NaN' );
}
b.pass( 'benchmark finished' );
b.end();
}
function benchmark( b ) {
var v;
var i;
b.tic();
for ( i = 0; i < b.iterations; i++ ) {
v = snanstdev( [ x ] );
if ( isnanf( v ) ) {
b.fail( 'should not return NaN' );
}
}
b.toc();
if ( isnanf( v ) ) {
b.fail( 'should not return NaN' );
}
b.pass( 'benchmark finished' );
b.end();
}

Note: You'll also need to add var isnanf = require( '@stdlib/math/base/assert/is-nanf' ); to the imports.

Comment on lines +32 to +34
function vector( buffer, length, stride, offset ) {
return new ndarray( 'float32', buffer, [ length ], [ stride ], offset, 'row-major' );
}
Copy link
Member

Choose a reason for hiding this comment

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

This helper function needs JSDoc documentation to match stdlib conventions. See reference packages like snanmean/test/test.js:

Suggested change
function vector( buffer, length, stride, offset ) {
return new ndarray( 'float32', buffer, [ length ], [ stride ], offset, 'row-major' );
}
/**
* Returns a one-dimensional ndarray.
*
* @private
* @param {Collection} buffer - underlying data buffer
* @param {NonNegativeInteger} length - number of indexed elements
* @param {integer} stride - stride length
* @param {NonNegativeInteger} offset - index offset
* @returns {ndarray} one-dimensional ndarray
*/
function vector( buffer, length, stride, offset ) {
return new ndarray( 'float32', buffer, [ length ], [ stride ], offset, 'row-major' );
}

* // returns <number>
*/
declare function prependSingletonDimensions<T = unknown, U extends typedndarray<T> = typedndarray<T>>( x: U, n: number ): U;
declare function snanstdev( arrays: [ float32ndarray ] ): number;
Copy link
Member

Choose a reason for hiding this comment

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

The type signature needs to accept two ndarrays to match the expected API pattern for stdev functions. Looking at sstdev and sstdevpn, the signature should be:

declare function snanstdev( arrays: [ float32ndarray, ndarray ] ): number;

The second element is a zero-dimensional ndarray containing the degrees of freedom adjustment (correction value).

@Planeshifter Planeshifter added Needs Changes Pull request which needs changes before being merged. and removed Needs Review A pull request which needs code review. labels Jan 10, 2026
@aryan7071
Copy link
Contributor Author

Understood. Updated snanstdev to accept a second zero-dimensional ndarray specifying the degrees of freedom adjustment (correction), and now pass it correctly to snanstdevpn.ndarray.

Updated JSDoc, TypeScript definitions, REPL docs, tests, and benchmarks to reflect the corrected API and verify the actual computed standard deviation values.

---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: passed
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: passed
  - task: lint_javascript_src
    status: passed
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: passed
  - task: lint_javascript_benchmarks
    status: passed
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: passed
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: passed
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: na
  - task: lint_javascript_benchmarks
    status: na
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: na
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: na
  - task: lint_javascript_benchmarks
    status: passed
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: passed
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: na
  - task: lint_javascript_benchmarks
    status: passed
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: na
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: na
  - task: lint_javascript_tests
    status: passed
  - task: lint_javascript_benchmarks
    status: na
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
---
type: pre_commit_static_analysis_report
description: Results of running static analysis checks when committing changes.
report:
  - task: lint_filenames
    status: passed
  - task: lint_editorconfig
    status: passed
  - task: lint_markdown
    status: na
  - task: lint_package_json
    status: na
  - task: lint_repl_help
    status: na
  - task: lint_javascript_src
    status: na
  - task: lint_javascript_cli
    status: na
  - task: lint_javascript_examples
    status: passed
  - task: lint_javascript_tests
    status: na
  - task: lint_javascript_benchmarks
    status: na
  - task: lint_python
    status: na
  - task: lint_r
    status: na
  - task: lint_c_src
    status: na
  - task: lint_c_examples
    status: na
  - task: lint_c_benchmarks
    status: na
  - task: lint_c_tests_fixtures
    status: na
  - task: lint_shell
    status: na
  - task: lint_typescript_declarations
    status: passed
  - task: lint_typescript_tests
    status: na
  - task: lint_license_headers
    status: passed
---
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs Changes Pull request which needs changes before being merged. Statistics Issue or pull request related to statistical functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants