diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/README.md b/lib/node_modules/@stdlib/stats/incr/nanmme/README.md new file mode 100644 index 000000000000..e516ac848ece --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/README.md @@ -0,0 +1,152 @@ + + +# incrnanmme + +> Compute a moving [mean error][mean-absolute-error] (ME) incrementally, ignoring `NaN` values. + +
+ +For a window of size `W`, the [mean error][mean-absolute-error] is defined **ignoring any `(x, y)` pairs containing NaN**. + +```math +\mathop{\mathrm{ME}} = \frac{1}{W} \sum_{i=0}^{W-1} (y_i - x_i) +``` + + + + + +
+ + + +
+ +## Usage + +```javascript +var incrnanmme = require( '@stdlib/stats/incr/nanmme' ); +``` + +#### incrnanmme( window ) + +Returns an accumulator `function` which incrementally computes a moving [mean error][mean-absolute-error], ignoring any `(x, y)` pairs containing `NaN`. The `window` parameter defines the number of values over which to compute the moving [mean error][mean-absolute-error]. + +```javascript +var accumulator = incrnanmme( 3 ); +``` + +#### accumulator( \[x, y] ) + +If provided input values `x` and `y`, the accumulator function returns an updated [mean error][mean-absolute-error]. If not provided input values `x` and `y`, the accumulator function returns the current [mean error][mean-absolute-error]. + +```javascript +var accumulator = incrnanmme( 3 ); + +var m = accumulator(); +// returns null + +// Fill the window... +m = accumulator( 2.0, 3.0 ); // [(2.0,3.0)] +// returns 1.0 + +m = accumulator( -1.0, 4.0 ); // [(2.0,3.0), (-1.0,4.0)] +// returns 3.0 + +m = accumulator( 3.0, NaN ); // ignored +// returns 3.0 + +// Window begins sliding... +m = accumulator( -7.0, 3.0 ); +// returns ~5.33 + +m = accumulator( -5.0, -3.0 ); +// returns ~5.67 + +m = accumulator(); +// returns ~5.67 +``` + +
+ + + +
+ +## Notes + +- Input values are **not** type checked. Any `(x, y)` pair containing `NaN` is ignored and does **not** update the window. +- As `W` (x,y) pairs 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. +- Be careful when interpreting the [mean error][mean-absolute-error] as errors can cancel. This stated, that errors can cancel makes the [mean error][mean-absolute-error] suitable for measuring the bias in forecasts. +- **Warning**: the [mean error][mean-absolute-error] is scale-dependent and, thus, the measure should **not** be used to make comparisons between datasets having different scales. + +
+ + + +
+ +## Examples + + + +```javascript +var randu = require( '@stdlib/random/base/randu' ); +var incrnanmme = require( '@stdlib/stats/incr/nanmme' ); + +var accumulator; +var v1; +var v2; +var i; + +// Initialize an accumulator: +accumulator = incrnanmme( 5 ); + +// For each simulated datum, update the moving mean error... +for ( i = 0; i < 100; i++ ) { + v1 = ( randu()*100.0 ) - 50.0; + v2 = ( randu()*100.0 ) - 50.0; + accumulator( v1, v2 ); +} +console.log( accumulator() ); +``` + +
+ + + + + + + + + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/nanmme/benchmark/benchmark.js new file mode 100644 index 000000000000..8ba1d40828e5 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/benchmark/benchmark.js @@ -0,0 +1,74 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 format = require( '@stdlib/string/format' ); +var pkg = require( './../package.json' ).name; +var incrnanmme = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var f; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + f = incrnanmme( (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( format( '%s::accumulator-nan', pkg ), function benchmark( b ) { + var acc; + var v; + var i; + + acc = incrnanmme( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + if ( i%10 === 0 ) { + v = acc( NaN, randu()-0.5 ); + } else { + v = acc( randu()-0.5, randu()-0.5 ); + } + 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/nanmme/docs/img/equation_mean_error.svg b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/img/equation_mean_error.svg new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/repl.txt new file mode 100644 index 000000000000..408d164f88c2 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/repl.txt @@ -0,0 +1,45 @@ +{{alias}}( W ) + Returns an accumulator function which incrementally computes a moving + mean error (ME), ignoring `NaN` values. + + The `W` parameter defines the number of values over which to compute the + moving mean error. + + If provided a value, the accumulator function returns an updated moving + mean error. If not provided a value, the accumulator function returns the + current moving mean error. + + 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 which are not `NaN`. + + Parameters + ---------- + W: integer + Window size. + + Returns + ------- + acc: Function + Accumulator function. + + Examples + -------- + > var accumulator = {{alias}}( 3 ); + > var m = accumulator() + null + > m = accumulator( 2.0, 3.0 ) + 1.0 + > m = accumulator( -5.0, NaN ) + 1.0 + > m = accumulator( 3.0, 2.0 ) + 0.0 + > m = accumulator( 5.0, -2.0 ) + ~-2.33 + > m = accumulator() + ~-2.33 + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/types/index.d.ts new file mode 100644 index 000000000000..e7128912ec4f --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/types/index.d.ts @@ -0,0 +1,75 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2026 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 input values, the accumulator function returns an updated mean error. If not provided input values, the accumulator function returns the current mean error. +* +* ## Notes +* +* - If either `x` or `y` is `NaN`, the accumulator ignores the input values and returns the previously accumulated value. +* +* @param x - input value +* @param y - input value +* @returns mean error or null +*/ +type accumulator = ( x?: number, y?: number ) => number | null; + +/** +* Returns an accumulator function which incrementally computes a moving mean error, ignoring 'NaN' values. +* +* ## Notes +* +* - The `W` parameter defines the number of values over which to compute the moving mean error. +* - 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. +* +* @param W - window size +* @throws must provide a positive integer +* @returns accumulator function +* +* @example +* var accumulator = incrnanmme( 3 ); +* +* var m = accumulator(); +* // returns null +* +* m = accumulator( 2.0, 3.0 ); +* // returns 1.0 +* +* m = accumulator( -5.0, 2.0 ); +* // returns 4.0 +* +* m = accumulator( 3.0, 2.0 ); +* // returns ~2.33 +* +* m = accumulator( 5.0, -2.0 ); +* // returns ~-0.33 +* +* m = accumulator(); +* // returns ~-0.33 +*/ +declare function incrnanmme( W: number ): accumulator; + + +// EXPORTS // + +export = incrnanmme; + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/docs/types/test.ts b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/types/test.ts new file mode 100644 index 000000000000..0e545472064b --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/docs/types/test.ts @@ -0,0 +1,75 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2026 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 incrnanmme = require( './index' ); + + +// TESTS // + +// The function returns an accumulator function... +{ + incrnanmme( 3 ); // $ExpectType accumulator +} + +// The compiler throws an error if the function is provided an argument that is not a number... +{ + incrnanmme( '5' ); // $ExpectError + incrnanmme( true ); // $ExpectError + incrnanmme( false ); // $ExpectError + incrnanmme( null ); // $ExpectError + incrnanmme( undefined ); // $ExpectError + incrnanmme( [] ); // $ExpectError + incrnanmme( {} ); // $ExpectError + incrnanmme( ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an invalid number of arguments... +{ + incrnanmme(); // $ExpectError + incrnanmme( 5, 3 ); // $ExpectError +} + +// The function returns an accumulator function which returns an accumulated result... +{ + const acc = incrnanmme( 3 ); + + acc(); // $ExpectType number | null + acc( 3.14, 2.0 ); // $ExpectType number | null +} + +// The compiler throws an error if the returned accumulator function is provided invalid arguments... +{ + const acc = incrnanmme( 3 ); + + acc( '5', 2.0 ); // $ExpectError + acc( true, 2.0 ); // $ExpectError + acc( false, 2.0 ); // $ExpectError + acc( null, 2.0 ); // $ExpectError + acc( [], 2.0 ); // $ExpectError + acc( {}, 2.0 ); // $ExpectError + acc( ( x: number ): number => x, 2.0 ); // $ExpectError + + acc( 3.14, '5' ); // $ExpectError + acc( 3.14, true ); // $ExpectError + acc( 3.14, false ); // $ExpectError + acc( 3.14, null ); // $ExpectError + acc( 3.14, [] ); // $ExpectError + acc( 3.14, {} ); // $ExpectError + acc( 3.14, ( x: number ): number => x ); // $ExpectError +} + diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmme/examples/index.js new file mode 100644 index 000000000000..f56ee89a72ea --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 incrnanmme = require( './../lib' ); + +var accumulator; +var err; +var v1; +var v2; +var i; + +// Initialize an accumulator: +accumulator = incrnanmme( 5 ); + +// For each simulated datum, update the moving mean error... +console.log( '\nValue\tValue\tMean\n' ); +for ( i = 0; i < 100; i++ ) { + v1 = ( randu()*100.0 ) - 50.0; + v2 = ( i%10 === 0 ) ? NaN : ( ( randu()*100.0 ) - 50.0 ); + err = accumulator( v1, v2 ); + console.log('%s\t%s\t%s', v1.toFixed( 3 ), ( isNaN( v2 ) ) ? 'NaN' : v2.toFixed( 3 ), ( err === null || isNaN( err ) ) ? 'NaN' : err.toFixed( 3 )); +} diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanmme/lib/index.js new file mode 100644 index 000000000000..ab133ad88f7d --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/lib/index.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 mean error incrementally, ignoring `NaN` values. +* +* @module @stdlib/stats/incr/nanmme +* +* @example +* var incrnanmme = require( '@stdlib/stats/incr/nanmme' ); +* +* var accumulator = incrnanmme( 3 ); +* +* var m = accumulator(); +* // returns null +* +* m = accumulator( 2.0, 3.0 ); +* // returns 1.0 +* +* m = accumulator( -5.0, 2.0 ); +* // returns 4.0 +* +* m = accumulator( 3.0, 2.0 ); +* // returns ~2.33 +* +* m = accumulator( 5.0, -2.0 ); +* // returns ~-0.33 +* +* m = accumulator(); +* // returns ~-0.33 +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanmme/lib/main.js new file mode 100644 index 000000000000..48c454b613b6 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/lib/main.js @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive; +var incrmmean = require( '@stdlib/stats/incr/mmean' ); +var format = require( '@stdlib/string/format' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); + + +// MAIN // + +/** +* Returns an accumulator function which incrementally computes a moving mean error, ignoring `NaN` values. +* +* @param {PositiveInteger} W - window size +* @throws {TypeError} must provide a positive integer +* @returns {Function} accumulator function +* +* @example +* var incrnanmme = require( '@stdlib/stats/incr/nanmme' ); +* +* var accumulator = incrnanmme( 3 ); +* +* var m = accumulator(); +* // returns null +* +* m = accumulator( 2.0, 3.0 ); +* // returns 1.0 +* +* m = accumulator( -5.0, 2.0 ); +* // returns 4.0 +* +* m = accumulator( 3.0, 2.0 ); +* // returns ~2.33 +* +* m = accumulator( 5.0, -2.0 ); +* // returns ~-0.33 +* +* m = accumulator(); +* // returns ~-0.33 +*/ +function incrnanmme( W ) { + var mean; + if ( !isPositiveInteger( W ) ) { + throw new TypeError( format( 'invalid argument. Must provide a positive integer. Value: `%s`.', W ) ); + } + mean = incrmmean( W ); + return accumulator; + + /** + * If provided input values, the accumulator function returns an updated mean error. If not provided input values, the accumulator function returns the current mean error. + * + * @private + * @param {number} [x] - input value + * @param {number} [y] - input value + * @returns {(number|null)} mean error or null + */ + function accumulator( x, y ) { + if ( arguments.length === 0 ) { + return mean(); + } + if ( isnan( x ) || isnan( y ) ) { + return mean(); + } + return mean( y-x ); + } +} + + +// EXPORTS // + +module.exports = incrnanmme; diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/package.json b/lib/node_modules/@stdlib/stats/incr/nanmme/package.json new file mode 100644 index 000000000000..7a8550cadc92 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/package.json @@ -0,0 +1,83 @@ +{ + "name": "@stdlib/stats/incr/nanmme", + "version": "0.0.0", + "description": "Compute a moving mean error (ME) 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", + "average", + "avg", + "mean", + "error", + "err", + "me", + "incremental", + "accumulator", + "moving mean", + "moving average", + "sliding window", + "sliding", + "window", + "moving", + "time series", + "timeseries", + "forecasting", + "forecast", + "difference", + "diff", + "delta", + "bias", + "nan", + "ignorenan" + ] +} diff --git a/lib/node_modules/@stdlib/stats/incr/nanmme/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanmme/test/test.js new file mode 100644 index 000000000000..5b99adc3be67 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmme/test/test.js @@ -0,0 +1,114 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 ulpdiff = require( '@stdlib/number/float64/base/ulp-difference' ); +var incrnanmme = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function testMainExport( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof incrnanmme, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'throws if not given a positive integer', function testInvalidInput( t ) { + var values = [ '5', -5, 0, 3.14, true, null, undefined, NaN, [], {}, function noop() {} ]; + var i; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws error for ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValueTest() { + incrnanmme( value ); + }; + } +}); + +tape( 'returns an accumulator function', function testReturnsFunction( t ) { + var acc = incrnanmme( 3 ); + t.strictEqual( typeof acc, 'function', 'returns a function' ); + t.end(); +}); + +tape( 'accumulator computes moving mean error incrementally', function testIncrementalBehavior( t ) { + var expected = [ 1, -1.5, 0, -3, -8/3, -2/3 ]; + var actual; + var data = [ + [ 2, 3 ], + [ 3, -1 ], + [ 2, 5 ], + [ 4, -4 ], + [ 3, 0 ], + [ -4, 5 ] + ]; + var acc = incrnanmme( 3 ); + var i; + + for ( i = 0; i < data.length; i++ ) { + actual = acc( data[ i ][ 0 ], data[ i ][ 1 ] ); + t.strictEqual( ulpdiff( actual, expected[i] ) <= 1, true, 'returns expected value' ); + } + t.end(); +}); + +tape( 'returns current mean error when no input', function testNoInput( t ) { + var acc = incrnanmme( 2 ); + + acc( 2, 3 ); + acc( 3, -5 ); + acc( 1, 10 ); + + t.strictEqual( acc(), 0.5 ); + t.end(); +}); + +tape( 'returns null if no data', function testNoData( t ) { + var acc = incrnanmme( 3 ); + t.strictEqual( acc(), null ); + t.end(); +}); + +tape( 'ignores NaN inputs', function testNanHandling( t ) { + var expected = [ null, null, null, 0, 0 ]; + var data = [ + [ NaN, 1 ], + [ 1, NaN ], + [ NaN, NaN ], + [ 2, 2 ], + [ NaN, 3 ] + ]; + var acc = incrnanmme( 3 ); + var v; + var i; + + for ( i = 0; i < data.length; i++ ) { + v = acc( data[ i ][ 0 ], data[ i ][ 1 ] ); + t.strictEqual( v, expected[ i ], 'window ' + i ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/README.md b/lib/node_modules/@stdlib/stats/incr/nanrss/README.md new file mode 100644 index 000000000000..e2ea6f8ab99a --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/README.md @@ -0,0 +1,153 @@ + + +# incrnanrss + +> Compute the [residual sum of squares][residual-sum-of-squares] (RSS) incrementally, ignoring `NaN` values. + +
+ +The [**residual sum of squares**][residual-sum-of-squares] (also referred to as the **sum of squared residuals** (SSR) and the **sum of squared errors** (SSE)) is defined as + + + +```math +\mathop{\mathrm{RSS}} = \sum_{i=0}^{n-1} (y_i - x_i)^2 +``` + + + + + +
+ + + +
+ +## Usage + +```javascript +var incrnanrss = require( '@stdlib/stats/incr/nanrss' ); +``` + +#### incrnanrss() + +Returns an accumulator `function` which incrementally computes the [residual sum of squares][residual-sum-of-squares], ignoring NaN values. + +```javascript +var accumulator = incrnanrss(); +``` + +#### accumulator( \[x, y] ) + +If provided input values x and y, the accumulator function updates the RSS. If NaN is provided, it is ignored, and the previous RSS is returned. If no arguments are provided, the accumulator function returns the current RSS. + +```javascript +var accumulator = incrnanrss(); + +var r = accumulator( 2.0, 3.0 ); +// returns 1.0 + +r = accumulator( -1.0, -4.0 ); +// returns 10.0 + +r = accumulator( -3.0, 5.0 ); +// returns 74.0 + +r = accumulator( NaN, 3.0 ); +// returns 74.0 + +r = accumulator(); +// returns 74.0 +``` + +
+ + + +
+ +## Notes + +- Input values are **not** type checked. If provided `NaN` or a value which, when used in computations, results in `NaN`, the accumulated value is `NaN` for **all** future invocations. If non-numeric inputs are possible, you are advised to type check and handle accordingly **before** passing the value to the accumulator function. + +
+ + + +
+ +## Examples + + + +```javascript +var randu = require( '@stdlib/random/base/randu' ); +var incrnanrss = require( '@stdlib/stats/incr/nanrss' ); + +var accumulator; +var v1; +var v2; +var i; + +// Initialize an accumulator: +accumulator = incrnanrss(); + +// For each simulated datum, update the residual sum of squares... +for ( i = 0; i < 100; i++ ) { + v1 = ( randu()*100.0 ) - 50.0; + v2 = ( randu()*100.0 ) - 50.0; + accumulator( v1, v2 ); + + // NaN values are ignored + accumulator( NaN, v2 ); +} +console.log( accumulator() ); +``` + +
+ + + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/nanrss/benchmark/benchmark.js new file mode 100644 index 000000000000..64a46bfdea4e --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/benchmark/benchmark.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 incrnanrss = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var f; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + f = incrnanrss(); + 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 = incrnanrss(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + if ( i%10 === 0 ) { + v = acc( NaN, randu()-0.5 ); + } else { + v = acc( randu()-0.5, randu()-0.5 ); + } + 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/nanrss/docs/img/equation_residual_sum_of_squares.svg b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/img/equation_residual_sum_of_squares.svg new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/repl.txt new file mode 100644 index 000000000000..61b3c5fb9076 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/repl.txt @@ -0,0 +1,34 @@ + +{{alias}}() + Returns an accumulator function which incrementally computes the residual + sum of squares (RSS), ignoring `NaN` values. + + If provided input values, the accumulator function returns an updated + residual sum of squares. If not provided input values, the accumulator + function returns the current residual sum of squares. + + NaN input values are ignored. + + Returns + ------- + acc: Function + Accumulator function. + + Examples + -------- + > var accumulator = {{alias}}(); + > var r = accumulator() + null + > r = accumulator( 2.0, 3.0 ) + 1.0 + > r = accumulator( NaN, 3.0 ) + 1.0 + > r = accumulator( -5.0, 2.0 ) + 50.0 + > r = accumulator() + 50.0 + + See Also + -------- + + diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/types/index.d.ts new file mode 100644 index 000000000000..8bcb2558d749 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/types/index.d.ts @@ -0,0 +1,63 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2026 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 arguments, returns an updated residual sum of squares; otherwise, returns the current residual sum of squares. +* +* ## Notes +* +* NaN input values are ignored. +* @returns residual sum of squares +*/ +type accumulator = ( x?: number, y?: number ) => number | null; + +/** +* Returns an accumulator function which incrementally computes the residual sum of squares, ignoring `NaN` values. +* +* @returns accumulator function +* +* @example +* var accumulator = incrnanrss(); +* +* var r = accumulator(); +* // returns null +* +* r = accumulator( 2.0, 3.0 ); +* // returns 1.0 +* +* r = accumulator( -5.0, 2.0 ); +* // returns 50.0 +* +* r = accumulator(); +* // returns 50.0 +* r = accumulator( NaN, 3.0 ); +* // 50.0 +* r = accumulator( 5.0, NaN ); +* // 50.0 +*/ +declare function incrnanrss(): accumulator; + + +// EXPORTS // + +export = incrnanrss; + diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/docs/types/test.ts b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/types/test.ts new file mode 100644 index 000000000000..fd0a136de7d2 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/docs/types/test.ts @@ -0,0 +1,73 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2026 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 incrnanrss = require( './index' ); + + +// TESTS // + +// The function returns an accumulator function... +{ + incrnanrss(); // $ExpectType accumulator +} + +// The compiler throws an error if the function is provided arguments... +{ + incrnanrss( '5' ); // $ExpectError + incrnanrss( 5 ); // $ExpectError + incrnanrss( true ); // $ExpectError + incrnanrss( false ); // $ExpectError + incrnanrss( null ); // $ExpectError + incrnanrss( undefined ); // $ExpectError + incrnanrss( [] ); // $ExpectError + incrnanrss( {} ); // $ExpectError + incrnanrss( ( x: number ): number => x ); // $ExpectError +} + +// The function returns an accumulator function which returns an accumulated result... +{ + const acc = incrnanrss(); + + acc( 2.0, 3.0 ); // $ExpectType number | null + acc( NaN, 3.0 ); // ok + acc( 5.0, NaN ); // ok + + acc(); // $ExpectType number | null + acc( 3.14, 2.0 ); // $ExpectType number | null +} + +// The compiler throws an error if the returned accumulator function is provided invalid arguments... +{ + const acc = incrnanrss(); + + acc( '5', 1.0 ); // $ExpectError + acc( true, 1.0 ); // $ExpectError + acc( false, 1.0 ); // $ExpectError + acc( null, 1.0 ); // $ExpectError + acc( [], 1.0 ); // $ExpectError + acc( {}, 1.0 ); // $ExpectError + acc( ( x: number ): number => x, 1.0 ); // $ExpectError + + acc( 3.14, '5' ); // $ExpectError + acc( 3.14, true ); // $ExpectError + acc( 3.14, false ); // $ExpectError + acc( 3.14, null ); // $ExpectError + acc( 3.14, [] ); // $ExpectError + acc( 3.14, {} ); // $ExpectError + acc( 3.14, ( x: number ): number => x ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanrss/examples/index.js new file mode 100644 index 000000000000..c10aa662a5e6 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/examples/index.js @@ -0,0 +1,42 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 incrnanrss = require( './../lib' ); + +var accumulator; +var nanrss; +var v1; +var v2; +var i; + +// Initialize an accumulator: +accumulator = incrnanrss(); + +// For each simulated datum, update the residual sum of squares... +console.log( '\nValue\tValue\tRSS\n' ); +for ( i = 0; i < 100; i++ ) { + v1 = ( randu()*100.0 ) - 50.0; + v2 = ( randu()*100.0 ) - 50.0; + nanrss = accumulator( v1, v2 ); + nanrss = accumulator( NaN, v2 );// NaN input values should be ignored + console.log( '%d\t%d\t%d', v1.toFixed( 3 ), v2.toFixed( 3 ), nanrss.toFixed( 3 ) ); +} +console.log( '\nFinal RSS: %d\n', accumulator() ); diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanrss/lib/index.js new file mode 100644 index 000000000000..b90363b2ad02 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/lib/index.js @@ -0,0 +1,51 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 the residual sum of squares incrementally, ignoring `NaN` values. +* +* @module @stdlib/stats/incr/nanrss +* +* @example +* var incrnanrss = require( '@stdlib/stats/incr/nanrss' ); +* +* var accumulator = incrnanrss(); +* +* var r = accumulator(); +* // returns null +* +* r = accumulator( 2.0, 3.0 ); +* // returns 1.0 +* +* r = accumulator( -5.0, 2.0 ); +* // returns 50.0 +* +* r = accumulator(); +* // returns 50.0 +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanrss/lib/main.js new file mode 100644 index 000000000000..9ddeb3d92e22 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/lib/main.js @@ -0,0 +1,79 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 incrnansum = require( '@stdlib/stats/incr/nansum' ); + + +// MAIN // + +/** +* Returns an accumulator function which incrementally computes the residual sum of squares, ignoring `NaN` values. +* +* @returns {Function} accumulator function +* +* @example +* var accumulator = incrnanrss(); +* +* var r = accumulator(); +* // returns null +* +* r = accumulator( 2.0, 3.0 ); +* // returns 1.0 +* +* r = accumulator( -5.0, 2.0 ); +* // returns 50.0 +* +* r = accumulator(); +* // returns 50.0 +* +* r = accumulator( NaN, 3.0 ); +* // returns 50.0 +*/ +function incrnanrss() { + var nansum = incrnansum(); + return accumulator; + + /** + * If provided input values, the accumulator function returns an updated residual sum of squares. If not provided input values, the accumulator function returns the current residual sum of squares. + * + * @private + * @param {number} [x] - input value + * @param {number} [y] - input value + * @returns {(number|null)} residual sum of squares or null + */ + function accumulator( x, y ) { + var r; + if ( arguments.length === 0 ) { + return nansum(); + } + if ( x !== x || y !== y ) { + return nansum(); // ignore NaN values + } + r = y - x; + return nansum( r*r ); + } +} + + +// EXPORTS // + +module.exports = incrnanrss; diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/package.json b/lib/node_modules/@stdlib/stats/incr/nanrss/package.json new file mode 100644 index 000000000000..9f62e1a76a6d --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/package.json @@ -0,0 +1,87 @@ +{ + "name": "@stdlib/stats/incr/rss", + "version": "0.0.0", + "description": "Compute the residual sum of squares (RSS) 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", + "error", + "err", + "rss", + "ssr", + "sse", + "residuals", + "deviation", + "difference", + "diff", + "delta", + "incremental", + "accumulator", + "time series", + "timeseries", + "forecasting", + "forecast", + "model", + "selection", + "evaluation", + "prediction", + "manhattan", + "cityblock", + "city-block", + "distance", + "dist", + "nanrss", + "ignorenan" + ] +} + diff --git a/lib/node_modules/@stdlib/stats/incr/nanrss/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanrss/test/test.js new file mode 100644 index 000000000000..df81b9779aee --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanrss/test/test.js @@ -0,0 +1,139 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 EPS = require( '@stdlib/constants/float64/eps' ); +var incrnanrss = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof incrnanrss, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an accumulator function', function test( t ) { + t.strictEqual( typeof incrnanrss(), 'function', 'returns expected value' ); + t.end(); +}); + +tape( 'the initial accumulated value is `null`', function test( t ) { + var acc = incrnanrss(); + t.strictEqual( acc(), null, 'returns expected value' ); + t.end(); +}); + +tape( 'the accumulator function incrementally computes the residual sum of squares', function test( t ) { + var expected; + var actual; + var delta; + var data; + var acc; + var sum; + var tol; + var N; + var r; + var x; + var y; + var i; + + data = [ + [ 2.0, 3.0 ], + [ 3.0, -1.0 ], + [ 2.0, 5.0 ], + [ 4.0, -4.0 ], + [ 3.0, 0.0 ], + [ -4.0, 5.0 ] + ]; + N = data.length; + + acc = incrnanrss(); + + sum = 0; + for ( i = 0; i < N; i++ ) { + x = data[ i ][ 0 ]; + y = data[ i ][ 1 ]; + r = y - x; + sum += r * r; + expected = sum; + actual = acc( x, y ); + if ( actual === expected ) { + t.strictEqual( actual, expected, 'returns expected value' ); + } else { + delta = abs( expected - actual ); + tol = 1.0 * EPS * abs( expected ); + t.strictEqual( delta <= tol, true, 'within tolerance. Actual: '+actual+'. Expected: '+expected+'. Delta: '+delta+'. Tol: '+tol+'.' ); + } + } + t.end(); +}); + +tape( 'if not provided an input value, the accumulator function returns the current residual sum of squares', function test( t ) { + var expected; + var actual; + var delta; + var data; + var acc; + var tol; + var i; + + data = [ + [ 2.0, 3.0 ], + [ 3.0, -5.0 ], + [ 1.0, 10.0 ] + ]; + acc = incrnanrss(); + for ( i = 0; i < data.length; i++ ) { + acc( data[ i ][ 0 ], data[ i ][ 1 ] ); + } + actual = acc(); + expected = 1.0 + 64.0 + 81.0; + delta = abs( expected - actual ); + tol = 1.0 * EPS * abs( expected ); + t.strictEqual( delta <= tol, true, 'within tolerance. Actual: '+actual+'. Expected: '+expected+'. Delta: '+delta+'. Tol: '+tol+'.' ); + t.end(); +}); + +tape( 'NaN inputs are ignored', function test( t ) { + var acc = incrnanrss(); + + acc( 2.0, 3.0 ); + acc( NaN, 3.0 ); + acc( 3.0, NaN ); + + t.strictEqual( acc(), 1.0, 'returns expected value' ); + t.end(); +}); + +tape( 'handles NaN values', function test( t ) { + var acc = incrnanrss(); + + acc( 1.0, 2.0 ); // 1 + acc( NaN, NaN ); // ignored + acc( 2.0, 4.0 ); // +4 + + t.strictEqual( acc(), 5.0, 'returns expected value' ); + t.end(); +});