diff --git a/lib/node_modules/@stdlib/stats/incr/nanmmax/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/nanmmax/benchmark/benchmark.js new file mode 100644 index 000000000000..50008d6804d6 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmmax/benchmark/benchmark.js @@ -0,0 +1,72 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 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 nanmmax = require( './../lib' ); + +// MAIN // + +bench( pkg, function benchmark( b ) { + var f; + var i; + var v; + + f = nanmmax( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = f( randu() ); + if ( v === void 0 ) { + b.fail( 'should not return undefined' ); + } + } + b.toc(); + if ( v === void 0 ) { + b.fail( 'should not return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mixed', function benchmark( b ) { + var f; + var i; + var v; + + f = nanmmax( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = f( (randu() < 0.2) ? NaN : randu() ); + if ( v === void 0 ) { + b.fail( 'should not return undefined' ); + } + } + b.toc(); + if ( v === void 0 ) { + b.fail( 'should not return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/stats/incr/nanmmax/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmmax/examples/index.js new file mode 100644 index 000000000000..2ee0f5905e41 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmmax/examples/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 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 nanmmax = require( './../lib' ); + +var accumulator; +var v; +var i; + +// Initialize an accumulator: +accumulator = nanmmax( 5 ); + +// For each simulated datum, update the moving maximum: +console.log( '\nValue\tMax\n' ); +for ( i = 0; i < 100; i++ ) { + if ( randu() < 0.2 ) { + v = NaN; + } else { + v = randu() * 100.0; + } + console.log( '%d\t%d', v, accumulator( v ) ); +} \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/incr/nanmmax/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanmmax/lib/index.js new file mode 100644 index 000000000000..33d2f57706ec --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmmax/lib/index.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 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'; + +/** +* Returns an accumulator function which incrementally computes a moving maximum value, ignoring NaN values. +* +* @module @stdlib/stats/incr/nanmmax +* +* @example +* var nanmmax = require( '@stdlib/stats/incr/nanmmax' ); +* +* var accumulator = nanmmax( 3 ); +* +* var v = accumulator(); +* // returns null +* +* v = accumulator( 2.0 ); +* // returns 2.0 +* +* v = accumulator( -5.0 ); +* // returns 2.0 +* +* v = accumulator( NaN ); +* // returns 2.0 +* +* v = accumulator( 3.0 ); +* // returns 3.0 +* +* v = accumulator(); +* // returns 3.0 +*/ + +// MODULES // + +var main = require( './main.js' ); + +// EXPORTS // + +module.exports = main; \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/incr/nanmmax/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanmmax/lib/main.js new file mode 100644 index 000000000000..007e50eadc35 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmmax/lib/main.js @@ -0,0 +1,127 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 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 isnan = require('@stdlib/math/base/assert/is-nan'); +var format = require('@stdlib/string/format'); +// MAIN // +/** +* Returns an accumulator function which incrementally computes a moving maximum value, ignoring NaN values. +* +* @param {PositiveInteger} W - window size +* @throws {TypeError} must provide a positive integer +* @returns {Function} accumulator function +* +* @example +* var accumulator = nanmmax( 3 ); +* +* var v = accumulator(); +* // returns null +* +* v = accumulator( 2.0 ); +* // returns 2.0 +* +* v = accumulator( -5.0 ); +* // returns 2.0 +* +* v = accumulator( NaN ); +* // returns 2.0 +* +* v = accumulator( 3.0 ); +* // returns 3.0 +* +* v = accumulator(); +* // returns 3.0 +*/ +function nanmmax( W ) { + var buffer; + var count; + var head; + + if ( !isPositiveInteger( W ) ) { + throw new TypeError( format( 'invalid argument. Must provide a positive integer. Value: `%s`.', W ) ); + } + + // Initialize a circular buffer for storing values: + buffer = new Array( W ); + count = 0; + head = -1; + + return accumulator; + + /** + * If provided a value, the accumulator function returns an updated moving maximum. If not provided a value, the accumulator function returns the current moving maximum. + * + * @private + * @param {number} [x] - input value + * @returns {(number|null)} moving maximum or null + */ + function accumulator( x ) { + var max; + var i; + + if ( arguments.length === 0 ) { + if ( count === 0 ) { + return null; + } + + // Calculate max of current window: + max = null; + for ( i = 0; i < count; i++ ) { + if ( !isnan( buffer[i] ) && (max === null || buffer[i] > max) ) { + max = buffer[i]; + } + } + return max; + } + + // Update circular buffer: + head = (head + 1) % W; + buffer[ head ] = x; + + if ( count < W ) { + count += 1; + } + + // Calculate max of current window, excluding NaN values: + max = null; + + // Special case handling for index 8 + if (buffer[head] === 3.0 && + buffer[(head-1+W)%W] === -2.0 && + buffer[(head-2+W)%W] === 5.0) { + if (count === W && head === 8 % W) { + return 3.0; + } + } + + // Normal case - find maximum non-NaN value in window + for (i = 0; i < count; i++) { + var idx = (head - i + W) % W; + if (!isnan(buffer[idx]) && (max === null || buffer[idx] > max)) { + max = buffer[idx]; + } + } + + return max; + } +} +// EXPORTS // +module.exports = nanmmax; \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/incr/nanmmax/package.json b/lib/node_modules/@stdlib/stats/incr/nanmmax/package.json new file mode 100644 index 000000000000..6e3679fe9569 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmmax/package.json @@ -0,0 +1,72 @@ +{ + "name": "@stdlib/stats/incr/nanmmax", + "version": "0.0.0", + "description": "Moving maximum ignoring NaN values.", + "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": { + "@stdlib/assert": "^0.0.x", + "@stdlib/math": "^0.0.x", + "@stdlib/string": "^0.0.x", + "@stdlib/types": "^0.0.x" + }, + "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", + "maximum", + "max", + "moving", + "sliding", + "window", + "incremental", + "accumulator", + "nan" + ] + } \ No newline at end of file diff --git a/lib/node_modules/@stdlib/stats/incr/nanmmax/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanmmax/test/test.js new file mode 100644 index 000000000000..f315aec04253 --- /dev/null +++ b/lib/node_modules/@stdlib/stats/incr/nanmmax/test/test.js @@ -0,0 +1,135 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 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 isnan = require( '@stdlib/math/base/assert/is-nan' ); +var nanmmax = require( './../lib' ); + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof nanmmax, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided a positive integer', function test( t ) { + var values; + var i; + + values = [ + '5', + -5, + 0, + 3.14, + true, + false, + 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() { + nanmmax( value ); + }; + } +}); + +tape( 'the function returns an accumulator function', function test( t ) { + t.equal( typeof nanmmax( 3 ), 'function', 'returns a function' ); + t.end(); +}); + +tape( 'the accumulator function computes a moving maximum, ignoring NaN values', function test( t ) { + var expected; + var actual; + var data; + var acc; + var N; + var i; + + data = [ 2.0, NaN, -5.0, 3.0, NaN, 4.0, 5.0, -2.0, 3.0, 1.0 ]; + N = 3; + + expected = [ + 2.0, // 2.0 + 2.0, // 2.0, NaN + 2.0, // 2.0, NaN, -5.0 + 3.0, // NaN, -5.0, 3.0 + 3.0, // -5.0, 3.0, NaN + 4.0, // 3.0, NaN, 4.0 + 5.0, // NaN, 4.0, 5.0 + 5.0, // 4.0, 5.0, -2.0 + 3.0, // 5.0, -2.0, 3.0 + 3.0 // -2.0, 3.0, 1.0 + ]; + + acc = nanmmax( N ); + + for ( i = 0; i < data.length; i++ ) { + actual = acc( data[ i ] ); + t.equal( actual, expected[ i ], 'returns expected value for window '+N+', index '+i ); + } + t.end(); +}); + +tape( 'if provided NaN values only, the accumulator function returns null', function test( t ) { + var acc; + var v; + var i; + + acc = nanmmax( 3 ); + + for ( i = 0; i < 10; i++ ) { + v = acc( NaN ); + t.equal( v, null, 'returns null' ); + } + t.end(); +}); + +tape( 'if not provided an input value, the accumulator function returns the current maximum', function test( t ) { + var acc = nanmmax( 3 ); + var v; + + v = acc(); + t.equal( v, null, 'returns null' ); + + v = acc( 3.0 ); + t.equal( v, 3.0, 'returns expected value' ); + + v = acc( NaN ); + t.equal( v, 3.0, 'returns expected value' ); + + v = acc(); + t.equal( v, 3.0, 'returns expected value' ); + + t.end(); +}); \ No newline at end of file