Skip to content

Commit c9a6ad4

Browse files
committed
refactor: update wmean implementation and tests to handle nonnegative weights
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- type: pre_push_report description: Results of running various checks prior to pushing changes. report: - task: run_javascript_examples status: na - task: run_c_examples status: na - task: run_cpp_examples status: na - task: run_javascript_readme_examples status: na - task: run_c_benchmarks status: na - task: run_cpp_benchmarks status: na - task: run_fortran_benchmarks status: na - task: run_javascript_benchmarks status: na - task: run_julia_benchmarks status: na - task: run_python_benchmarks status: na - task: run_r_benchmarks status: na - task: run_javascript_tests status: na ---
1 parent 31224e1 commit c9a6ad4

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed

lib/node_modules/@stdlib/stats/incr/wmean/lib/main.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818

1919
'use strict';
2020

21+
// MODULES //
22+
23+
var isNonNegativeNumber = require( '@stdlib/assert/is-nonnegative-number' ).isPrimitive;
24+
var format = require( '@stdlib/string/format' );
25+
26+
27+
// MAIN //
28+
2129
/**
2230
* Returns an accumulator function which incrementally computes a weighted arithmetic mean.
2331
*
@@ -97,7 +105,8 @@ function incrwmean() {
97105
*
98106
* @private
99107
* @param {number} [x] - value
100-
* @param {number} [w] - weight
108+
* @param {NonNegativeNumber} [w] - weight
109+
* @throws {TypeError} must provide a nonnegative number as the weight
101110
* @returns {(number|null)} weighted mean or null
102111
*/
103112
function accumulator( x, w ) {
@@ -107,6 +116,12 @@ function incrwmean() {
107116
}
108117
return mu;
109118
}
119+
if ( !isNonNegativeNumber( w ) ) {
120+
throw new TypeError( format( 'invalid argument. Must provide a nonnegative number. Value: `%s`.', w ) );
121+
}
122+
if (w === 0.0) {
123+
return ( FLG === void 0 ) ? null : mu;
124+
}
110125
FLG = true;
111126
wsum += w;
112127
mu += ( w/wsum ) * ( x-mu );

lib/node_modules/@stdlib/stats/incr/wmean/test/test.js

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,47 @@ tape( 'the initial accumulated value is `null`', function test( t ) {
4646
t.end();
4747
});
4848

49+
tape( 'the accumulator function ignores zero weights and only updates the mean after encountering a non-zero weight', function test( t ) {
50+
var acc = incrwmean();
51+
t.equal( acc(), null, 'returns expected value' );
52+
t.equal( acc( 2.0, 0.0 ), null, 'returns the previous accumulated mean' );
53+
t.equal( acc( 2.0, 2.0 ), 2.0, 'returns the current accumulated mean' );
54+
t.equal( acc( 5.0, 0.0 ), 2.0, 'returns the previous accumulated mean' );
55+
t.end();
56+
});
57+
58+
tape( 'the function throws an error if not provided a nonnegative number', function test( t ) {
59+
var values;
60+
var acc;
61+
var i;
62+
63+
values = [
64+
'5',
65+
-5.0,
66+
NaN,
67+
undefined,
68+
true,
69+
false,
70+
null,
71+
void 0,
72+
[],
73+
{},
74+
function noop() {}
75+
];
76+
77+
for ( i = 0; i < values.length; i++ ) {
78+
t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] );
79+
}
80+
t.end();
81+
82+
function badValue( value ) {
83+
return function badValue() {
84+
acc = incrwmean();
85+
acc( 2.0, value );
86+
};
87+
}
88+
});
89+
4990
tape( 'the accumulator function incrementally computes a weighted arithmetic mean', function test( t ) {
5091
var expected;
5192
var actual;
@@ -99,24 +140,9 @@ tape( 'if not provided arguments, the accumulator function returns the current w
99140
t.end();
100141
});
101142

102-
tape( 'if not provided a weight, the accumulator function returns `NaN`', function test( t ) {
143+
tape( 'if provided `NaN` for a value, the accumulator function returns `NaN`', function test( t ) {
103144
var acc = incrwmean();
104-
t.equal( isnan( acc( 2.0 ) ), true, 'returns NaN' );
105-
t.equal( isnan( acc( 3.14 ) ), true, 'returns NaN' );
106-
t.end();
107-
});
108-
109-
tape( 'if provided `NaN` for either a value or a weight, the accumulator function returns `NaN`', function test( t ) {
110-
var acc = incrwmean();
111-
t.equal( isnan( acc( 2.0, NaN ) ), true, 'returns NaN' );
112-
t.equal( isnan( acc( 3.14, NaN ) ), true, 'returns NaN' );
113-
114-
acc = incrwmean();
115145
t.equal( isnan( acc( NaN, 1.0 ) ), true, 'returns NaN' );
116146
t.equal( isnan( acc( NaN, 1.0 ) ), true, 'returns NaN' );
117-
118-
acc = incrwmean();
119-
t.equal( isnan( acc( NaN, NaN ) ), true, 'returns NaN' );
120-
t.equal( isnan( acc( NaN, NaN ) ), true, 'returns NaN' );
121147
t.end();
122148
});

0 commit comments

Comments
 (0)