From 12967cbe9d7049cf58ac18b19f6bf24ea0812c18 Mon Sep 17 00:00:00 2001 From: Hemang Chodhary Date: Sat, 22 Mar 2025 22:38:20 +0530 Subject: [PATCH 1/6] Added nanmstdev --- .../@stdlib/stats/incr/nanmstdev/README.md | 187 ++++++++ .../incr/nanmstdev/benchmark/benchmark.js | 91 ++++ ...on_corrected_sample_standard_deviation.svg | 73 +++ .../stats/incr/nanmstdev/docs/repl.txt | 56 +++ .../incr/nanmstdev/docs/types/index.d.ts | 84 ++++ .../stats/incr/nanmstdev/docs/types/test.ts | 77 ++++ .../stats/incr/nanmstdev/examples/index.js | 38 ++ .../@stdlib/stats/incr/nanmstdev/lib/index.js | 63 +++ .../@stdlib/stats/incr/nanmstdev/lib/main.js | 158 +++++++ .../@stdlib/stats/incr/nanmstdev/package.json | 74 ++++ .../@stdlib/stats/incr/nanmstdev/test/test.js | 416 ++++++++++++++++++ 11 files changed, 1317 insertions(+) create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/img/equation_corrected_sample_standard_deviation.svg create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json create mode 100644 lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md new file mode 100644 index 000000000000..fa4637f29f0a --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md @@ -0,0 +1,187 @@ + + +# incrnanmstdev + +> Compute a moving [corrected sample standard deviation][standard-deviation] incrementally, ignoring NaN values. + +
+ +For a window of size `W`, the [corrected sample standard deviation][standard-deviation] is defined as + + + +```math +s = \sqrt{\frac{1}{W-1} \sum_{i=0}^{W-1} ( x_i - \bar{x} )^2} +``` + + + + + +
+ + + +
+ +## Usage + +```javascript +var incrnanmstdev = require( '@stdlib/stats/incr/nanmstdev' ); +``` + +#### incrnanmstdev( window\[, mean] ) + +Returns an accumulator `function` which incrementally computes a moving [corrected sample standard deviation][standard-deviation], ignoring `NaN` values. The `window` parameter defines the number of values over which to compute the moving [corrected sample standard deviation][standard-deviation]. + +```javascript +var accumulator = incrnanmstdev( 3 ); +``` + +If the mean is already known, provide a `mean` argument. + +```javascript +var accumulator = incrnanmstdev( 3, 5.0 ); +``` + +#### accumulator( \[x] ) + +If provided an input value `x`, the accumulator function returns an updated [corrected sample standard deviation][standard-deviation]. If not provided an input value `x`, the accumulator function returns the current [corrected sample standard deviation][standard-deviation]. If provided `NaN`, the accumulator function ignores the value and returns the current [corrected sample standard deviation][standard-deviation]. + +```javascript +var accumulator = incrnanmstdev( 3 ); + +var s = accumulator(); +// returns null + +// Fill the window... +s = accumulator( 2.0 ); // [2.0] +// returns 0.0 + +s = accumulator( NaN ); // [2.0, NaN] +// returns 0.0 + +s = accumulator( 3.0 ); // [2.0, NaN, 3.0] +// returns ~0.7071 + +// Window begins sliding... +s = accumulator( -7.0 ); // [NaN, 3.0, -7.0] +// returns ~7.07 + +s = accumulator( -5.0 ); // [3.0, -7.0, -5.0] +// returns ~5.29 + +s = accumulator(); +// returns ~5.29 +``` + +
+ + + +
+ +## Notes + +- Input values are **not** type checked. If provided `NaN`, the value is ignored and the accumulator function returns the current [corrected sample standard deviation][standard-deviation]. If non-numeric inputs are possible, you are advised to type check and handle accordingly **before** passing the value to the accumulator function. +- As `W` values are needed to fill the window buffer, the first `W-1` returned values are calculated from smaller sample sizes. Until the window is full, each returned value is calculated from all provided values (excluding NaN values). + +
+ + + +
+ +## Examples + + + +```javascript +var randu = require( '@stdlib/random/base/randu' ); +var incrnanmstdev = require( '@stdlib/stats/incr/nanmstdev' ); + +var accumulator; +var v; +var i; + +// Initialize an accumulator: +accumulator = incrnanmstdev( 5 ); + +// For each simulated datum, update the moving corrected sample standard deviation... +for ( i = 0; i < 100; i++ ) { + if ( randu() < 0.2 ) { + v = NaN; + } else { + v = randu() * 100.0; + } + accumulator( v ); +} +console.log( accumulator() ); +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js new file mode 100644 index 000000000000..625440c09a8f --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var pkg = require( './../package.json' ).name; +var incrnanmstdev = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var f; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + f = incrnanmstdev( (i%5)+1 ); + if ( typeof f !== 'function' ) { + b.fail( 'should return a function' ); + } + } + b.toc(); + if ( typeof f !== 'function' ) { + b.fail( 'should return a function' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::accumulator', function benchmark( b ) { + var acc; + var v; + var i; + + acc = incrnanmstdev( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = acc( randu() ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::accumulator,known_mean', function benchmark( b ) { + var acc; + var v; + var i; + + acc = incrnanmstdev( 5, 3.0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = acc( randu() ); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/img/equation_corrected_sample_standard_deviation.svg b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/img/equation_corrected_sample_standard_deviation.svg new file mode 100644 index 000000000000..dfe5a3d60cbb --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/img/equation_corrected_sample_standard_deviation.svg @@ -0,0 +1,73 @@ + +s equals StartRoot StartFraction 1 Over upper W minus 1 EndFraction sigma-summation Underscript i equals 0 Overscript upper W minus 1 Endscripts left-parenthesis x Subscript i Baseline minus x overbar right-parenthesis squared EndRoot + + + \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt new file mode 100644 index 000000000000..47ec7d85f697 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt @@ -0,0 +1,56 @@ +{{alias}}( W[, mean] ) + Returns an accumulator function which incrementally computes a moving + corrected sample standard deviation, ignoring NaN values. + + The `W` parameter defines the number of values over which to compute the + moving corrected sample standard deviation. + + If provided a value, the accumulator function returns an updated moving + corrected sample standard deviation. If not provided a value, the + accumulator function returns the current moving corrected sample standard + deviation. + + As `W` values are needed to fill the window buffer, the first `W-1` returned + values are calculated from smaller sample sizes. Until the window is full, + each returned value is calculated from all provided values. + + NaN values are ignored during computation. If provided NaN, the + accumulator returns the current corrected sample standard deviation. + + Parameters + ---------- + W: integer + Window size. + + mean: number (optional) + Known mean. + + Returns + ------- + acc: Function + Accumulator function. + + Examples + -------- + > var accumulator = {{alias}}( 3 ); + > var s = accumulator() + null + > s = accumulator( 2.0 ) + 0.0 + > s = accumulator( NaN ) + 0.0 + > s = accumulator( -5.0 ) + ~4.95 + > s = accumulator( 3.0 ) + ~4.36 + > s = accumulator( NaN ) + ~4.36 + > s = accumulator( 5.0 ) + ~5.29 + > s = accumulator() + ~5.29 + + See Also + -------- + @stdlib/stats/incr/mstdev, @stdlib/stats/incr/nanstdev, @stdlib/stats/incr/nanvariance + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts new file mode 100644 index 000000000000..056f3e14ca39 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts @@ -0,0 +1,84 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2019 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TypeScript Version: 4.1 + +/// + +/** +* If provided a value, returns an updated corrected sample standard deviation; otherwise, returns the current corrected sample standard deviation. +* +* ## Notes +* +* - If provided `NaN` or a value which, when used in computations, results in `NaN`, the accumulated value is not updated (i.e., NaN values are ignored). +* +* @param x - value +* @returns corrected sample standard deviation +*/ +type accumulator = ( x?: number ) => number | null; + +/** +* Returns an accumulator function which incrementally computes a moving corrected sample standard deviation, ignoring NaN values. +* +* ## Notes +* +* - The `W` parameter defines the number of values over which to compute the moving sum. +* - As `W` values are needed to fill the window buffer, the first `W-1` returned values are calculated from smaller sample sizes. Until the window is full, each returned value is calculated from all provided values. +* - NaN values are ignored. +* +* @param W - window size +* @param mean - mean value +* @throws first argument must be a positive integer +* @returns accumulator function +* +* @example +* var accumulator = incrnanmstdev( 3 ); +* +* var s = accumulator(); +* // returns null +* +* s = accumulator( 2.0 ); +* // returns 0.0 +* +* s = accumulator( NaN ); +* // returns 0.0 +* +* s = accumulator( -5.0 ); +* // returns ~4.95 +* +* s = accumulator( 3.0 ); +* // returns ~4.36 +* +* s = accumulator( NaN ); +* // returns ~4.36 +* +* s = accumulator( 5.0 ); +* // returns ~5.29 +* +* s = accumulator(); +* // returns ~5.29 +* +* @example +* var accumulator = incrnanmstdev( 3, 5.0 ); +*/ +declare function incrnanmstdev( W: number, mean?: number ): accumulator; + + +// EXPORTS // + +export = incrnanmstdev; diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts new file mode 100644 index 000000000000..1d7b9fae82f9 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts @@ -0,0 +1,77 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2019 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import incrnanmstdev = require( './index' ); + + +// TESTS // + +// The function returns an accumulator function... +{ + incrnanmstdev( 3 ); // $ExpectType accumulator + incrnanmstdev( 3, 0.0 ); // $ExpectType accumulator +} + +// The compiler throws an error if the function is provided a first argument which is not a number... +{ + incrnanmstdev( '5' ); // $ExpectError + incrnanmstdev( true ); // $ExpectError + incrnanmstdev( false ); // $ExpectError + incrnanmstdev( null ); // $ExpectError + incrnanmstdev( [] ); // $ExpectError + incrnanmstdev( {} ); // $ExpectError + incrnanmstdev( ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument which is not a number... +{ + incrnanmstdev( 3, '5' ); // $ExpectError + incrnanmstdev( 3, true ); // $ExpectError + incrnanmstdev( 3, false ); // $ExpectError + incrnanmstdev( 3, null ); // $ExpectError + incrnanmstdev( 3, [] ); // $ExpectError + incrnanmstdev( 3, {} ); // $ExpectError + incrnanmstdev( 3, ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an invalid number of arguments... +{ + incrnanmstdev(); // $ExpectError + incrnanmstdev( 3, 2.5, 3 ); // $ExpectError +} + +// The function returns an accumulator function which returns an accumulated result... +{ + const acc = incrnanmstdev( 3 ); + + acc(); // $ExpectType number | null + acc( 3.14 ); // $ExpectType number | null +} + +// The compiler throws an error if the returned accumulator function is provided invalid arguments... +{ + const acc = incrnanmstdev( 3 ); + + acc( '5' ); // $ExpectError + acc( true ); // $ExpectError + acc( false ); // $ExpectError + acc( null ); // $ExpectError + acc( [] ); // $ExpectError + acc( {} ); // $ExpectError + acc( ( x: number ): number => x ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js new file mode 100644 index 000000000000..81dafb0a9965 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js @@ -0,0 +1,38 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var randu = require( '@stdlib/random/base/randu' ); +var incrnanmstdev = require( './../lib' ); + +var accumulator; +var s; +var v; +var i; + +// Initialize an accumulator: +accumulator = incrnanmstdev( 5 ); + +// For each simulated datum, update the moving t-student standard deviation... +console.log( '\nValue\tT-Student Stdev\n' ); +for ( i = 0; i < 100; i++ ) { + v = randu() > 0.2 ? NaN : randu() * 100.0; + s = accumulator( v ); + console.log( '%d\t%d', v.toFixed( 4 ),(s == null) ? NaN : s.toFixed( 4 ) ); +} diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js new file mode 100644 index 000000000000..27c9ed5d7efd --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js @@ -0,0 +1,63 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Compute a moving corrected sample standard deviation incrementally, ignoring NaN values. +* +* @module @stdlib/stats/incr/nanmstdev +* +* @example +* var incrnanmstdev = require( '@stdlib/stats/incr/nanmstdev' ); +* +* var accumulator = incrnanmstdev( 3 ); +* +* var s = accumulator(); +* // returns null +* +* s = accumulator( 2.0 ); +* // returns 0.0 +* +* s = accumulator( NaN ); +* // returns 0.0 +* +* s = accumulator( -5.0 ); +* // returns ~4.95 +* +* s = accumulator( 3.0 ); +* // returns ~4.36 +* +* s = accumulator( NaN ); +* // returns ~4.36 +* +* s = accumulator( 5.0 ); +* // returns ~5.29 +* +* s = accumulator(); +* // returns ~5.29 +*/ + +// MODULES // + +var main = require( '@stdlib/stats/incr/nanmstdev/lib/main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js new file mode 100644 index 000000000000..20369013132f --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js @@ -0,0 +1,158 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var incrmstdev = require( '@stdlib/stats/incr/mstdev' ); + + +// MAIN // + +/** +* Returns an accumulator function which incrementally computes a moving corrected sample standard deviation, ignoring NaN values. +* +* ## Method +* +* - Let \\(W\\) be a window of \\(N\\) elements over which we want to compute an corrected sample standard deviation. +* +* - We first recognize that the corrected sample standard deviation is defined as the square root of the unbiased sample variance. Accordingly, in order to derive an update equation for the corrected sample standard deviation, deriving an update equation for the unbiased sample variance is sufficient. +* +* - The difference between the unbiased sample variance in a window \\(W_i\\) and the unbiased sample variance in a window \\(W_{i+1})\\) is given by +* +* ```tex +* \Delta s^2 = s_{i+1}^2 - s_{i}^2 +* ``` +* +* - If we multiply both sides by \\(N-1\\), +* +* ```tex +* (N-1)(\Delta s^2) = (N-1)s_{i+1}^2 - (N-1)s_{i}^2 +* ``` +* +* - If we substitute the definition of the unbiased sample variance having the form +* +* ```tex +* \begin{align*} +* s^2 &= \frac{1}{N-1} \biggl( \sum_{i=1}^{N} (x_i - \bar{x})^2 \biggr) \\ +* &= \frac{1}{N-1} \biggl( \sum_{i=1}^{N} (x_i^2 - 2\bar{x}x_i + \bar{x}^2) \biggr) \\ +* &= \frac{1}{N-1} \biggl( \sum_{i=1}^{N} x_i^2 - 2\bar{x} \sum_{i=1}^{N} x_i + \sum_{i=1}^{N} \bar{x}^2) \biggr) \\ +* &= \frac{1}{N-1} \biggl( \sum_{i=1}^{N} x_i^2 - \frac{2N\bar{x}\sum_{i=1}^{N} x_i}{N} + N\bar{x}^2 \biggr) \\ +* &= \frac{1}{N-1} \biggl( \sum_{i=1}^{N} x_i^2 - 2N\bar{x}^2 + N\bar{x}^2 \biggr) \\ +* &= \frac{1}{N-1} \biggl( \sum_{i=1}^{N} x_i^2 - N\bar{x}^2 \biggr) +* \end{align*} +* ``` +* +* we return +* +* ```tex +* (N-1)(\Delta s^2) = \biggl(\sum_{k=1}^N x_k^2 - N\bar{x}_{i+1}^2 \biggr) - \biggl(\sum_{k=0}^{N-1} x_k^2 - N\bar{x}_{i}^2 \biggr) +* ``` +* +* - This can be further simplified by recognizing that subtracting the sums reduces to \\(x_N^2 - x_0^2\\); in which case, +* +* ```tex +* \begin{align*} +* (N-1)(\Delta s^2) &= x_N^2 - x_0^2 - N\bar{x}_{i+1}^2 + N\bar{x}_{i}^2 \\ +* &= x_N^2 - x_0^2 - N(\bar{x}_{i+1}^2 - \bar{x}_{i}^2) \\ +* &= x_N^2 - x_0^2 - N(\bar{x}_{i+1} - \bar{x}_{i})(\bar{x}_{i+1} + \bar{x}_{i}) +* \end{align*} +* ``` +* +* - Recognizing that the difference of means can be expressed +* +* ```tex +* \bar{x}_{i+1} - \bar{x}_i = \frac{1}{N} \biggl( \sum_{k=1}^N x_k - \sum_{k=0}^{N-1} x_k \biggr) = \frac{x_N - x_0}{N} +* ``` +* +* and substituting into the equation above +* +* ```tex +* (N-1)(\Delta s^2) = x_N^2 - x_0^2 - (x_N - x_0)(\bar{x}_{i+1} + \bar{x}_{i}) +* ``` +* +* - Rearranging terms gives us the update equation +* +* ```tex +* \begin{align*} +* (N-1)(\Delta s^2) &= (x_N - x_0)(x_N + x_0) - (x_N - x_0)(\bar{x}_{i+1} + \bar{x}_{i}) +* &= (x_N - x_0)(x_N + x_0 - \bar{x}_{i+1} - \bar{x}_{i}) \\ +* &= (x_N - x_0)(x_N - \bar{x}_{i+1} + x_0 - \bar{x}_{i}) +* \end{align*} +* ``` +* +* @param {PositiveInteger} W - window size +* @param {number} [mean] - mean value +* @throws {TypeError} first argument must be a positive integer +* @throws {TypeError} second argument must be a number +* @returns {Function} accumulator function +* +* @example +* var accumulator = incrnanmstdev( 3 ); +* +* var s = accumulator(); +* // returns null +* +* s = accumulator( 2.0 ); +* // returns 0.0 +* +* s = accumulator( NaN ); +* // returns 0.0 +* +* s = accumulator( -5.0 ); +* // returns ~4.95 +* +* s = accumulator( 3.0 ); +* // returns ~4.36 +* +* s = accumulator( NaN ); +* // returns ~4.36 +* +* s = accumulator( 5.0 ); +* // returns ~5.29 +* +* s = accumulator(); +* // returns ~5.29 +* +* @example +* var accumulator = incrnanmstdev( 3, 5.0 ); +*/ +function incrnanmstdev( W, mean ) { + var acc; + if ( arguments.length > 1 ) { + acc = incrmstdev( W, mean ); + } else { + acc = incrmstdev( W ); + } + return function accumulator( x ) { + if ( arguments.length === 0 ) { + return acc(); + } + if ( isnan( x ) ) { + return acc(); + } + return acc( x ); + }; +} + + +// EXPORTS // + +module.exports = incrnanmstdev; diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json b/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json new file mode 100644 index 000000000000..63c815672c13 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json @@ -0,0 +1,74 @@ +{ + "name": "@stdlib/stats/incr/nanmstdev", + "version": "0.0.0", + "description": "Compute a moving corrected sample standard deviation incrementally.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdmath", + "statistics", + "stats", + "mathematics", + "math", + "variance", + "sample", + "sample variance", + "stdev", + "standard", + "deviation", + "corrected", + "dispersion", + "incremental", + "accumulator", + "moving variance", + "sliding window", + "sliding", + "window", + "moving" + ] +} diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js new file mode 100644 index 000000000000..c6785afdc642 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js @@ -0,0 +1,416 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var abs = require( '@stdlib/math/base/special/abs' ); +var sqrt = require( '@stdlib/math/base/special/sqrt' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var randu = require( '@stdlib/random/base/randu' ); +var EPS = require( '@stdlib/constants/float64/eps' ); +var incrnanmstdev = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof incrnanmstdev, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided a positive integer for the window size', function test( t ) { + var values; + var i; + + values = [ + '5', + -5.0, + 0.0, + 3.14, + true, + null, + void 0, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + incrnanmstdev( value ); + }; + } +}); + +tape( 'the function throws an error if not provided a positive integer for the window size (known mean)', function test( t ) { + var values; + var i; + + values = [ + '5', + -5.0, + 0.0, + 3.14, + true, + null, + void 0, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + incrnanmstdev( value, 5.0 ); + }; + } +}); + +tape( 'the function throws an error if not provided a number as the mean value', function test( t ) { + var values; + var i; + + values = [ + '5', + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + incrnanmstdev( 3, value ); + }; + } +}); + +tape( 'the function returns an accumulator function', function test( t ) { + t.equal( typeof incrnanmstdev( 3 ), 'function', 'returns a function' ); + t.end(); +}); + +tape( 'the function returns an accumulator function (known mean)', function test( t ) { + t.equal( typeof incrnanmstdev( 3, 3.0 ), 'function', 'returns a function' ); + t.end(); +}); + +tape( 'the accumulator function computes a moving corrected sample standard deviation incrementally', function test( t ) { + var expected; + var actual; + var data; + var acc; + var N; + var i; + + data = [ 2.0, 3.0, 4.0, -1.0, 3.0, 1.0 ]; + N = data.length; + + acc = incrnanmstdev( 3 ); + + actual = []; + for ( i = 0; i < N; i++ ) { + actual.push( acc( data[ i ] ) ); + } + expected = [ + 0.0, + sqrt( 0.5 ), + 1.0, + sqrt( 7.0 ), + sqrt( 7.0 ), + 2.0 + ]; + + t.deepEqual( actual, expected, 'returns expected incremental results' ); + t.end(); +}); + +tape( 'the accumulator function computes a moving corrected sample standard deviation incrementally (known mean)', function test( t ) { + var expected; + var actual; + var data; + var acc; + var N; + var i; + + data = [ 2.0, 3.0, 4.0, -1.0, 3.0, 1.0 ]; + N = data.length; + + acc = incrnanmstdev( 3, 2.0 ); + + actual = []; + for ( i = 0; i < N; i++ ) { + actual.push( acc( data[ i ] ) ); + } + expected = [ + 0.0, + sqrt( 0.5 ), + sqrt( 1.6666666666666666 ), + sqrt( 4.6666666666666666 ), + sqrt( 4.6666666666666666 ), + sqrt( 3.6666666666666666 ) + ]; + + t.deepEqual( actual, expected, 'returns expected incremental results' ); + t.end(); +}); + +tape( 'if not provided an input value, the accumulator function returns the current corrected sample standard deviation', function test( t ) { + var expected; + var actual; + var delta; + var data; + var tol; + var acc; + var i; + + data = [ 2.0, 3.0, 10.0 ]; + acc = incrnanmstdev( 3 ); + for ( i = 0; i < data.length-1; i++ ) { + acc( data[ i ] ); + } + t.equal( acc(), sqrt( 0.5 ), 'returns current corrected sample standard deviation' ); + + acc( data[ data.length-1 ] ); + + expected = sqrt( 19.0 ); + actual = acc(); + delta = abs( actual - expected ); + tol = EPS * expected; + + t.equal( delta < tol, true, 'expected: '+expected+'. actual: '+actual+'. tol: '+tol+'. delta: '+delta+'.' ); + t.end(); +}); + +tape( 'if not provided an input value, the accumulator function returns the current corrected sample standard deviation (known mean)', function test( t ) { + var expected; + var actual; + var delta; + var data; + var tol; + var acc; + var i; + + data = [ 2.0, 3.0, 10.0 ]; + acc = incrnanmstdev( 3, 5.0 ); + for ( i = 0; i < data.length-1; i++ ) { + acc( data[ i ] ); + } + t.equal( acc(), sqrt( 6.5 ), 'returns current unbiased sample variance' ); + + acc( data[ data.length-1 ] ); + + expected = sqrt( 12.666666666666666 ); + actual = acc(); + delta = abs( actual - expected ); + tol = EPS * expected; + + t.equal( delta < tol, true, 'expected: '+expected+'. actual: '+actual+'. tol: '+tol+'. delta: '+delta+'.' ); + t.end(); +}); + +tape( 'if data has yet to be provided, the accumulator function returns `null`', function test( t ) { + var acc = incrnanmstdev( 3 ); + t.equal( acc(), null, 'returns null' ); + t.end(); +}); + +tape( 'if data has yet to be provided, the accumulator function returns `null` (known mean)', function test( t ) { + var acc = incrnanmstdev( 3, 3.0 ); + t.equal( acc(), null, 'returns null' ); + t.end(); +}); + +tape( 'if only one datum has been provided and the mean is unknown, the accumulator function returns `0`', function test( t ) { + var acc = incrnanmstdev( 3 ); + acc( 2.0 ); + t.equal( acc(), 0.0, 'returns 0' ); + t.end(); +}); + +tape( 'if only one datum has been provided and the mean is known, the accumulator function may not return `0`', function test( t ) { + var acc = incrnanmstdev( 3, 3.0 ); + acc( 2.0 ); + t.notEqual( acc(), 0.0, 'does not return 0' ); + t.end(); +}); + +tape( 'if the window size is `1` and the mean is unknown, the accumulator functions always returns `0`', function test( t ) { + var acc; + var s; + var i; + + acc = incrnanmstdev( 1 ); + for ( i = 0; i < 100; i++ ) { + s = acc( randu() * 100.0 ); + t.equal( s, 0.0, 'returns 0' ); + } + t.end(); +}); + +tape( 'if the window size is `1` and the mean is known, the accumulator functions does not always returns `0`', function test( t ) { + var acc; + var s; + var i; + + acc = incrnanmstdev( 1, 500.0 ); // mean is larger than simulated value range, so stdev should never be zero + for ( i = 0; i < 100; i++ ) { + s = acc( randu() * 100.0 ); + t.notEqual( s, 0.0, 'does not return 0' ); + } + t.end(); +}); + + +tape( 'if provided a NaN, the accumulator function ignores it (unknown mean, W=1)', function test( t ) { + var expected; + var data; + var acc; + var v; + var i; + + acc = incrnanmstdev( 1 ); + + data = [ + NaN, // NaN (ignored) -> null + 3.14, // 3.14 -> 0 + NaN, // NaN (ignored) -> 0 + 4.2, // 4.2 -> 0 + NaN, // NaN (ignored) -> 0 + 5.6 // 5.6 -> 0 + ]; + + expected = [ + null, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ]; + + for ( i = 0; i < data.length; i++ ) { + v = acc( data[ i ] ); + if ( expected[i] === null ) { + t.equal( v, null, 'returns null for window '+i ); + } else { + t.equal( v, expected[ i ], 'returns expected value for window '+i ); + } + + // Test accumulator without arguments + if (expected[i] === null) { + t.equal( acc(), null, 'returns correct value for window '+i ); + } else { + t.equal( acc(), expected[ i ], 'returns expected value for window '+i ); + } + } + t.end(); +}); + +tape( 'if provided a NaN, the accumulator function ignores it (known mean, W=1)', function test( t ) { + var expected; + var data; + var acc; + var v; + var i; + + acc = incrnanmstdev( 1, 5.0 ); + + data = [ + NaN, // NaN (ignored) -> null + 3.0, // 3.0 -> 2.0 + NaN, // NaN (ignored) -> 2.0 + 4.0, // 4.0 -> 1.0 + NaN, // NaN (ignored) -> 1.0 + 5.0 // 5.0 -> 0.0 + ]; + + expected = [ + null, + 2.0, + 2.0, + 1.0, + 1.0, + 0.0 + ]; + + for ( i = 0; i < data.length; i++ ) { + v = acc( data[ i ] ); + if ( expected[i] === null ) { + t.equal( v, null, 'returns null for window '+i ); + } else { + t.equal( v, expected[ i ], 'returns expected value for window '+i ); + } + + // Test accumulator without arguments + if (expected[i] === null) { + t.equal( acc(), null, 'returns correct value for window '+i ); + } else { + t.equal( acc(), expected[ i ], 'returns expected value for window '+i ); + } + } + t.end(); +}); + +tape( 'if provided a sequence of NaN values, the accumulator function should continue to ignore them', function test( t ) { + var acc; + var v; + + acc = incrnanmstdev( 3 ); + + v = acc( 2.0 ); + t.equal( v, 0.0, 'returns expected value' ); + + v = acc( NaN ); + t.equal( v, 0.0, 'returns expected value' ); + + v = acc( NaN ); + t.equal( v, 0.0, 'returns expected value' ); + + v = acc( NaN ); + t.equal( v, 0.0, 'returns expected value' ); + + v = acc( 3.0 ); + t.equal( v.toFixed(4), sqrt(0.5).toFixed(4), 'returns expected value' ); + + t.end(); +}); \ No newline at end of file From c34d01506369e9e6c1a5f27271cd8ab70f715cb8 Mon Sep 17 00:00:00 2001 From: stdlib-bot <82920195+stdlib-bot@users.noreply.github.com> Date: Wed, 16 Apr 2025 00:14:10 +0000 Subject: [PATCH 2/6] chore: update copyright years --- lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md | 2 +- .../@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js | 2 +- .../@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts | 2 +- .../@stdlib/stats/incr/nanmstdev/docs/types/test.ts | 2 +- lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js | 2 +- lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js | 2 +- lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js | 2 +- lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md index fa4637f29f0a..4fe9b77941c8 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md @@ -2,7 +2,7 @@ @license Apache-2.0 -Copyright (c) 2018 The Stdlib Authors. +Copyright (c) 2025 The Stdlib Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js index 625440c09a8f..219f6c3bcf9d 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/benchmark/benchmark.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2018 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts index 056f3e14ca39..8ddd02385643 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts @@ -1,7 +1,7 @@ /* * @license Apache-2.0 * -* Copyright (c) 2019 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts index 1d7b9fae82f9..da67fda500e6 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/test.ts @@ -1,7 +1,7 @@ /* * @license Apache-2.0 * -* Copyright (c) 2019 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js index 81dafb0a9965..e39e79f85939 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2018 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js index 27c9ed5d7efd..e28e6e5a76a4 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2018 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js index 20369013132f..e5b7dbfbfe04 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2018 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js index c6785afdc642..c339513e6021 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2018 The Stdlib Authors. +* Copyright (c) 2025 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 4c8ca68c87a2ab4d6f4d09452999e876350f85cd Mon Sep 17 00:00:00 2001 From: Hemang Chodhary Date: Tue, 22 Apr 2025 12:09:54 +0530 Subject: [PATCH 3/6] Update index.js --- lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js index e28e6e5a76a4..77da373559f8 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/index.js @@ -55,7 +55,7 @@ // MODULES // -var main = require( '@stdlib/stats/incr/nanmstdev/lib/main.js' ); +var main = require( './main.js' ); // EXPORTS // From 46aa802ca6742db20c551b62e77480c0efb69b77 Mon Sep 17 00:00:00 2001 From: Hemang Chodhary Date: Fri, 25 Apr 2025 10:21:21 +0530 Subject: [PATCH 4/6] [Fixed lint issues] --- .../@stdlib/stats/incr/nanmstdev/README.md | 28 +++++++++++-------- .../stats/incr/nanmstdev/docs/repl.txt | 10 +++---- .../incr/nanmstdev/docs/types/index.d.ts | 2 +- .../stats/incr/nanmstdev/examples/index.js | 4 +-- .../@stdlib/stats/incr/nanmstdev/lib/main.js | 15 ++++++++-- .../@stdlib/stats/incr/nanmstdev/test/test.js | 26 ++++++++--------- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md index 4fe9b77941c8..f892623eae11 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md @@ -67,7 +67,7 @@ var accumulator = incrnanmstdev( 3, 5.0 ); #### accumulator( \[x] ) -If provided an input value `x`, the accumulator function returns an updated [corrected sample standard deviation][standard-deviation]. If not provided an input value `x`, the accumulator function returns the current [corrected sample standard deviation][standard-deviation]. If provided `NaN`, the accumulator function ignores the value and returns the current [corrected sample standard deviation][standard-deviation]. +If provided an input value `x`, the accumulator function returns an updated [corrected sample standard deviation][standard-deviation]. If not provided an input value `x`, the accumulator function returns the current [corrected sample standard deviation][standard-deviation]. If provided `NaN`, the accumulator function ignores the value and returns the current [corrected sample standard deviation][standard-deviation] without updating the window. ```javascript var accumulator = incrnanmstdev( 3 ); @@ -75,25 +75,31 @@ var accumulator = incrnanmstdev( 3 ); var s = accumulator(); // returns null -// Fill the window... +// Fill the window with non-NaN values... s = accumulator( 2.0 ); // [2.0] // returns 0.0 -s = accumulator( NaN ); // [2.0, NaN] +s = accumulator( NaN ); // [2.0] // returns 0.0 -s = accumulator( 3.0 ); // [2.0, NaN, 3.0] +s = accumulator( 3.0 ); // [2.0, 3.0] // returns ~0.7071 +s = accumulator( 5.0 ); // [2.0, 3.0, 5.0] +// returns ~1.53 + // Window begins sliding... -s = accumulator( -7.0 ); // [NaN, 3.0, -7.0] -// returns ~7.07 +s = accumulator( -7.0 ); // [3.0, 5.0, -7.0] +// returns ~6.43 + +s = accumulator( NaN ); // [3.0, 5.0, -7.0] +// returns ~6.43 -s = accumulator( -5.0 ); // [3.0, -7.0, -5.0] -// returns ~5.29 +s = accumulator( -5.0 ); // [5.0, -7.0, -5.0] +// returns ~6.43 s = accumulator(); -// returns ~5.29 +// returns ~6.43 ``` @@ -104,7 +110,7 @@ s = accumulator(); ## Notes -- Input values are **not** type checked. If provided `NaN`, the value is ignored and the accumulator function returns the current [corrected sample standard deviation][standard-deviation]. If non-numeric inputs are possible, you are advised to type check and handle accordingly **before** passing the value to the accumulator function. +- Input values are **not** type checked. If provided `NaN`, the value is ignored and the accumulator function returns the current [corrected sample standard deviation][standard-deviation] without updating the window. If non-numeric inputs are possible, you are advised to type check and handle accordingly **before** passing the value to the accumulator function. - As `W` values are needed to fill the window buffer, the first `W-1` returned values are calculated from smaller sample sizes. Until the window is full, each returned value is calculated from all provided values (excluding NaN values). @@ -153,7 +159,7 @@ console.log( accumulator() ); ## See Also - [`@stdlib/stats/incr/mstdev`][@stdlib/stats/incr/mstdev]: compute a moving corrected sample standard deviation incrementally. -- [`@stdlib/stats/incr/nanmmean`][@stdlib/stats/incr/nanmmean]: compute a moving arietic mean incrementally, iging NaN values. +- [`@stdlib/stats/incr/mmean`][@stdlib/stats/incr/mmean]: compute a moving arietic mean incrementally, iging NaN values. - [`@stdlib/stats/incr/msummary`][@stdlib/stats/incr/msummary]: compute a moving statistical summary incrementally, ignoring NaN values. - [`@stdlib/stats/incr/mvariance`][@stdlib/stats/incr/mvariance]: compute a moving unbiased sample variance incrementally, ignoring NaN values. - [`@stdlib/stats/incr/stdev`][@stdlib/stats/incr/stdev]: compute a corrected sample standard deviation incrementally, ignoring NaN values. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt index 47ec7d85f697..633785455ffb 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt @@ -1,4 +1,5 @@ {{alias}}( W[, mean] ) + Returns an accumulator function which incrementally computes a moving corrected sample standard deviation, ignoring NaN values. @@ -10,9 +11,9 @@ accumulator function returns the current moving corrected sample standard deviation. - As `W` values are needed to fill the window buffer, the first `W-1` returned - values are calculated from smaller sample sizes. Until the window is full, - each returned value is calculated from all provided values. + As `W` values are needed to fill the window buffer, the first `W-1` + returned values are calculated from smaller sample sizes. Until the window + is full, each returned value is calculated from all provided values. NaN values are ignored during computation. If provided NaN, the accumulator returns the current corrected sample standard deviation. @@ -52,5 +53,4 @@ See Also -------- - @stdlib/stats/incr/mstdev, @stdlib/stats/incr/nanstdev, @stdlib/stats/incr/nanvariance - + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts index 8ddd02385643..7661335a91e1 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/types/index.d.ts @@ -37,7 +37,7 @@ type accumulator = ( x?: number ) => number | null; * * ## Notes * -* - The `W` parameter defines the number of values over which to compute the moving sum. +* - The `W` parameter defines the number of values over which to compute the moving corrected sample standard deviation. * - As `W` values are needed to fill the window buffer, the first `W-1` returned values are calculated from smaller sample sizes. Until the window is full, each returned value is calculated from all provided values. * - NaN values are ignored. * diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js index e39e79f85939..4ad171c4985e 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js @@ -32,7 +32,7 @@ accumulator = incrnanmstdev( 5 ); // For each simulated datum, update the moving t-student standard deviation... console.log( '\nValue\tT-Student Stdev\n' ); for ( i = 0; i < 100; i++ ) { - v = randu() > 0.2 ? NaN : randu() * 100.0; + v = ( randu() > 0.2 ) ? NaN : randu() * 100.0; s = accumulator( v ); - console.log( '%d\t%d', v.toFixed( 4 ),(s == null) ? NaN : s.toFixed( 4 ) ); + console.log( '%d\t%d', v.toFixed( 4 ), (s === null) ? NaN : s.toFixed( 4 ) ); } diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js index e5b7dbfbfe04..c6019c85afb5 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/lib/main.js @@ -92,7 +92,7 @@ var incrmstdev = require( '@stdlib/stats/incr/mstdev' ); * * ```tex * \begin{align*} -* (N-1)(\Delta s^2) &= (x_N - x_0)(x_N + x_0) - (x_N - x_0)(\bar{x}_{i+1} + \bar{x}_{i}) +* (N-1)(\Delta s^2) &= (x_N - x_0)(x_N + x_0) - (x_N - x_0)(\bar{x}_{i+1} + \bar{x}_{i}) \\ * &= (x_N - x_0)(x_N + x_0 - \bar{x}_{i+1} - \bar{x}_{i}) \\ * &= (x_N - x_0)(x_N - \bar{x}_{i+1} + x_0 - \bar{x}_{i}) * \end{align*} @@ -141,7 +141,16 @@ function incrnanmstdev( W, mean ) { } else { acc = incrmstdev( W ); } - return function accumulator( x ) { + return accumulator; + + /** + * If provided a value, the accumulator function returns an updated standard deviation. If not provided a value, the accumulator function returns the current standard deviation. + * + * @private + * @param {number} [x] - new value + * @returns {(number|null)} standard deviation or null + */ + function accumulator( x ) { if ( arguments.length === 0 ) { return acc(); } @@ -149,7 +158,7 @@ function incrnanmstdev( W, mean ) { return acc(); } return acc( x ); - }; + } } diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js index c339513e6021..c693f7684b13 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/test/test.js @@ -23,7 +23,6 @@ var tape = require( 'tape' ); var abs = require( '@stdlib/math/base/special/abs' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); -var isnan = require( '@stdlib/math/base/assert/is-nan' ); var randu = require( '@stdlib/random/base/randu' ); var EPS = require( '@stdlib/constants/float64/eps' ); var incrnanmstdev = require( './../lib' ); @@ -300,7 +299,6 @@ tape( 'if the window size is `1` and the mean is known, the accumulator function t.end(); }); - tape( 'if provided a NaN, the accumulator function ignores it (unknown mean, W=1)', function test( t ) { var expected; var data; @@ -318,7 +316,7 @@ tape( 'if provided a NaN, the accumulator function ignores it (unknown mean, W=1 NaN, // NaN (ignored) -> 0 5.6 // 5.6 -> 0 ]; - + expected = [ null, 0.0, @@ -335,7 +333,7 @@ tape( 'if provided a NaN, the accumulator function ignores it (unknown mean, W=1 } else { t.equal( v, expected[ i ], 'returns expected value for window '+i ); } - + // Test accumulator without arguments if (expected[i] === null) { t.equal( acc(), null, 'returns correct value for window '+i ); @@ -363,7 +361,7 @@ tape( 'if provided a NaN, the accumulator function ignores it (known mean, W=1)' NaN, // NaN (ignored) -> 1.0 5.0 // 5.0 -> 0.0 ]; - + expected = [ null, 2.0, @@ -380,7 +378,7 @@ tape( 'if provided a NaN, the accumulator function ignores it (known mean, W=1)' } else { t.equal( v, expected[ i ], 'returns expected value for window '+i ); } - + // Test accumulator without arguments if (expected[i] === null) { t.equal( acc(), null, 'returns correct value for window '+i ); @@ -394,23 +392,23 @@ tape( 'if provided a NaN, the accumulator function ignores it (known mean, W=1)' tape( 'if provided a sequence of NaN values, the accumulator function should continue to ignore them', function test( t ) { var acc; var v; - + acc = incrnanmstdev( 3 ); - + v = acc( 2.0 ); t.equal( v, 0.0, 'returns expected value' ); - + v = acc( NaN ); t.equal( v, 0.0, 'returns expected value' ); - + v = acc( NaN ); t.equal( v, 0.0, 'returns expected value' ); - + v = acc( NaN ); t.equal( v, 0.0, 'returns expected value' ); - + v = acc( 3.0 ); t.equal( v.toFixed(4), sqrt(0.5).toFixed(4), 'returns expected value' ); - + t.end(); -}); \ No newline at end of file +}); From 864a47ee0ce44f3ba38f654df4d0140fe6b21a5e Mon Sep 17 00:00:00 2001 From: Hemang Chodhary Date: Tue, 29 Apr 2025 18:11:55 +0530 Subject: [PATCH 5/6] [Fixed Issues] --- lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json b/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json index 63c815672c13..38a9bb398e03 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/package.json @@ -1,7 +1,7 @@ { "name": "@stdlib/stats/incr/nanmstdev", "version": "0.0.0", - "description": "Compute a moving corrected sample standard deviation incrementally.", + "description": "Compute a moving corrected sample standard deviation incrementally, ignoring NaN values.", "license": "Apache-2.0", "author": { "name": "The Stdlib Authors", From 890d9a35002be6b50551d997fbbc65e1d66178ee Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Sat, 3 May 2025 10:50:45 -0400 Subject: [PATCH 6/6] chore: apply suggestions from code review Signed-off-by: Philipp Burckhardt --- .../@stdlib/stats/incr/nanmstdev/README.md | 10 ---------- .../@stdlib/stats/incr/nanmstdev/docs/repl.txt | 2 +- .../@stdlib/stats/incr/nanmstdev/examples/index.js | 6 +++++- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md index f892623eae11..3d652c8b71df 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/README.md @@ -154,16 +154,6 @@ console.log( accumulator() ); diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt index 633785455ffb..4589f9e9d77b 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/docs/repl.txt @@ -1,5 +1,5 @@ -{{alias}}( W[, mean] ) +{{alias}}( W[, mean] ) Returns an accumulator function which incrementally computes a moving corrected sample standard deviation, ignoring NaN values. diff --git a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js index 4ad171c4985e..1c6661472c92 100644 --- a/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js +++ b/lib/node_modules/@stdlib/stats/incr/nanmstdev/examples/index.js @@ -32,7 +32,11 @@ accumulator = incrnanmstdev( 5 ); // For each simulated datum, update the moving t-student standard deviation... console.log( '\nValue\tT-Student Stdev\n' ); for ( i = 0; i < 100; i++ ) { - v = ( randu() > 0.2 ) ? NaN : randu() * 100.0; + if ( randu() < 0.2 ) { + v = NaN; + } else { + v = randu() * 100.0; + } s = accumulator( v ); console.log( '%d\t%d', v.toFixed( 4 ), (s === null) ? NaN : s.toFixed( 4 ) ); }