diff --git a/lib/node_modules/@stdlib/stats/incr/wmean/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/wmean/docs/types/index.d.ts index b91edc36cd26..11bb03f73fef 100644 --- a/lib/node_modules/@stdlib/stats/incr/wmean/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/stats/incr/wmean/docs/types/index.d.ts @@ -28,7 +28,8 @@ * - If provided `NaN` or a value which, when used in computations, results in `NaN`, the accumulated value is `NaN` for all future invocations. * * @param x - value -* @param w - weight +* @param {NonNegativeNumber} [w] - weight +* @throws {TypeError} second argument must be a nonnegative number * @returns weighted arithmetic mean */ type accumulator = ( x?: number, w?: number ) => number | null; diff --git a/lib/node_modules/@stdlib/stats/incr/wmean/lib/main.js b/lib/node_modules/@stdlib/stats/incr/wmean/lib/main.js index 59e1253bdd55..936ae6af39e3 100644 --- a/lib/node_modules/@stdlib/stats/incr/wmean/lib/main.js +++ b/lib/node_modules/@stdlib/stats/incr/wmean/lib/main.js @@ -18,6 +18,14 @@ 'use strict'; +// MODULES // + +var isNonNegativeNumber = require( '@stdlib/assert/is-nonnegative-number' ).isPrimitive; +var format = require( '@stdlib/string/format' ); + + +// MAIN // + /** * Returns an accumulator function which incrementally computes a weighted arithmetic mean. * @@ -97,7 +105,8 @@ function incrwmean() { * * @private * @param {number} [x] - value - * @param {number} [w] - weight + * @param {NonNegativeNumber} [w] - weight + * @throws {TypeError} second argument must be a nonnegative number * @returns {(number|null)} weighted mean or null */ function accumulator( x, w ) { @@ -107,6 +116,12 @@ function incrwmean() { } return mu; } + if ( !isNonNegativeNumber( w ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be a nonnegative number. Value: `%s`.', w ) ); + } + if ( w === 0.0 ) { + return ( FLG === void 0 ) ? null : mu; + } FLG = true; wsum += w; mu += ( w/wsum ) * ( x-mu ); diff --git a/lib/node_modules/@stdlib/stats/incr/wmean/test/test.js b/lib/node_modules/@stdlib/stats/incr/wmean/test/test.js index a238dac9005f..cbf5ebcbd779 100644 --- a/lib/node_modules/@stdlib/stats/incr/wmean/test/test.js +++ b/lib/node_modules/@stdlib/stats/incr/wmean/test/test.js @@ -46,6 +46,47 @@ tape( 'the initial accumulated value is `null`', function test( t ) { t.end(); }); +tape( 'the accumulator function ignores zero weights and only updates the mean after encountering a non-zero weight', function test( t ) { + var acc = incrwmean(); + t.equal( acc(), null, 'returns expected value' ); + t.equal( acc( 2.0, 0.0 ), null, 'returns expected value' ); + t.equal( acc( 2.0, 2.0 ), 2.0, 'returns expected value' ); + t.equal( acc( 5.0, 0.0 ), 2.0, 'returns expected value' ); + t.end(); +}); + +tape( 'the accumulator function throws an error if provided a second argument which is not a nonnegative number', function test( t ) { + var values; + var acc; + var i; + + values = [ + '5', + -5.0, + NaN, + undefined, + 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() { + acc = incrwmean(); + acc( 2.0, value ); + }; + } +}); + tape( 'the accumulator function incrementally computes a weighted arithmetic mean', function test( t ) { var expected; var actual; @@ -99,24 +140,9 @@ tape( 'if not provided arguments, the accumulator function returns the current w t.end(); }); -tape( 'if not provided a weight, the accumulator function returns `NaN`', function test( t ) { +tape( 'if provided `NaN` for a value, the accumulator function returns `NaN`', function test( t ) { var acc = incrwmean(); - t.equal( isnan( acc( 2.0 ) ), true, 'returns NaN' ); - t.equal( isnan( acc( 3.14 ) ), true, 'returns NaN' ); - t.end(); -}); - -tape( 'if provided `NaN` for either a value or a weight, the accumulator function returns `NaN`', function test( t ) { - var acc = incrwmean(); - t.equal( isnan( acc( 2.0, NaN ) ), true, 'returns NaN' ); - t.equal( isnan( acc( 3.14, NaN ) ), true, 'returns NaN' ); - - acc = incrwmean(); t.equal( isnan( acc( NaN, 1.0 ) ), true, 'returns NaN' ); t.equal( isnan( acc( NaN, 1.0 ) ), true, 'returns NaN' ); - - acc = incrwmean(); - t.equal( isnan( acc( NaN, NaN ) ), true, 'returns NaN' ); - t.equal( isnan( acc( NaN, NaN ) ), true, 'returns NaN' ); t.end(); });