diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/README.md b/lib/node_modules/@stdlib/stats/incr/wstdev/README.md
new file mode 100644
index 000000000000..2b37c1aa247e
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/README.md
@@ -0,0 +1,145 @@
+
+
+# incrwstdev
+
+> Compute an incremental [weighted standard deviation][weighted-standard-deviation].
+
+## Introduction
+
+The [weighted standard deviation][weighted-standard-deviation] is defined as:
+
+```math
+\sqrt{ \frac{\displaystyle\sum_{i=0}^{n-1} w_{i} \left( x_i - \bar{x} \right)^2 }{ \displaystyle\sum_{i=0}^{n-1} w_{i} } }
+```
+
+This function provides an incremental approach to calculating the weighted standard deviation. It computes the value iteratively, updating the result with each new data point and weight, which is useful for scenarios where data is streamed or updated over time.
+
+
+
+
+
+
+
+
+
+## Examples
+
+
+
+```javascript
+var randu = require( '@stdlib/random/base/randu' );
+var incrwstdev = require( '@stdlib/stats/incr/wstdev' );
+
+var accumulator;
+var s;
+var i;
+
+// Initialize an accumulator:
+accumulator = incrwstdev();
+
+// For each simulated datum, update the weighted standard deviation...
+for ( i = 0; i < 100; i++ ) {
+ var value = randu() * 100.0;
+ var weight = randu();
+ accumulator( value, weight );
+}
+console.log( accumulator() );
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[weighted-standard-deviation]:https://www.itl.nist.gov/div898/software/dataplot/refman2/ch2/weightsd.pdf
+
+
+
+[@stdlib/stats/incr/mstdev]:https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/mstdev
+
+[@stdlib/stats/incr/ewstdev]:https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/ewstdev
+
+[@stdlib/stats/incr/mmeanstdev]:https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/mmeanstdev
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/wstdev/benchmark/benchmark.js
new file mode 100644
index 000000000000..70938a7736b3
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/benchmark/benchmark.js
@@ -0,0 +1,92 @@
+/**
+* @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 incrwstdev = require( './../lib' );
+
+
+// MAIN //
+
+bench( pkg, function benchmark( b ) {
+ var f;
+ var i;
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ f = incrwstdev();
+ 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 = incrwstdev();
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ v = acc( randu(), randu() ); // passing random value and weight
+ 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 = incrwstdev( 3.14 ); // using a known mean
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ v = acc( randu(), randu() ); // passing random value and weight
+ 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();
+});
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/wstdev/docs/repl.txt
new file mode 100644
index 000000000000..690aa9aa8f9d
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/docs/repl.txt
@@ -0,0 +1,31 @@
+{{alias}}( [mean] )
+ Returns an accumulator function which incrementally computes a weighted standard deviation.
+
+ If provided a value and its associated weight, the accumulator function updates and returns the current weighted standard deviation. If not provided with arguments, the accumulator function returns the current weighted standard deviation.
+
+ If provided `NaN` or if a calculation results in `NaN`, the accumulated value will be `NaN` for all future invocations.
+
+ Parameters
+ ----------
+ mean: number (optional)
+ Known mean, if already computed.
+
+ Returns
+ -------
+ acc: Function
+ Accumulator function.
+
+ Examples
+ --------
+ > var accumulator = {{alias}}();
+ > var s = accumulator()
+ null
+ > s = accumulator( 2.0, 1.5 )
+ 0.0
+ > s = accumulator( -5.0, 2.0 )
+ updated weighted standard deviation
+ > s = accumulator()
+ current weighted standard deviation
+
+ See Also
+ --------
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/wstdev/docs/types/index.d.ts
new file mode 100644
index 000000000000..8cf1824d5ab7
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/docs/types/index.d.ts
@@ -0,0 +1,62 @@
+/*
+* @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 and a weight, returns an updated weighted standard deviation; otherwise, returns the current weighted standard deviation.
+*
+* ## Notes
+*
+* - 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 weight - weight associated with the value
+* @returns weighted standard deviation
+*/
+type accumulator = ( x?: number, weight?: number ) => number | null;
+
+/**
+* Returns an accumulator function which incrementally computes a weighted standard deviation.
+*
+* @param mu - known mean
+* @returns accumulator function
+*
+* @example
+* var accumulator = incrwstdev();
+*
+* var s = accumulator();
+* // returns null
+*
+* s = accumulator( 2.0, 1.5 );
+* // returns 0.0
+*
+* s = accumulator( -5.0, 2.0 );
+* // returns updated weighted standard deviation
+*
+* s = accumulator();
+* // returns current weighted standard deviation
+*/
+declare function incrwstdev( mu?: number ): accumulator;
+
+
+// EXPORTS //
+
+export = incrwstdev;
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/docs/types/test.ts b/lib/node_modules/@stdlib/stats/incr/wstdev/docs/types/test.ts
new file mode 100644
index 000000000000..a29b86beccd1
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/docs/types/test.ts
@@ -0,0 +1,62 @@
+/*
+* @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 incrwstdev = require( './index' );
+
+
+// TESTS //
+
+// The function returns an accumulator function...
+{
+ incrwstdev(); // $ExpectType accumulator
+ incrwstdev( 0.0 ); // $ExpectType accumulator
+}
+
+// The compiler throws an error if the function is provided invalid arguments...
+{
+ incrwstdev( '5' ); // $ExpectError
+ incrwstdev( true ); // $ExpectError
+ incrwstdev( false ); // $ExpectError
+ incrwstdev( null ); // $ExpectError
+ incrwstdev( [] ); // $ExpectError
+ incrwstdev( {} ); // $ExpectError
+ incrwstdev( ( x: number ): number => x ); // $ExpectError
+}
+
+// The function returns an accumulator function which returns an accumulated result...
+{
+ const acc = incrwstdev();
+
+ acc(); // $ExpectType number | null
+ acc( 3.14, 1.5 ); // $ExpectType number | null
+}
+
+// The compiler throws an error if the returned accumulator function is provided invalid arguments...
+{
+ const acc = incrwstdev();
+
+ acc( '5', 1.5 ); // $ExpectError
+ acc( 3.14, '1.5' ); // $ExpectError
+ acc( true, 1.5 ); // $ExpectError
+ acc( 3.14, false ); // $ExpectError
+ acc( null, 1.5 ); // $ExpectError
+ acc( 3.14, null ); // $ExpectError
+ acc( [], 1.5 ); // $ExpectError
+ acc( 3.14, {} ); // $ExpectError
+ acc( ( x: number ): number => x, 1.5 ); // $ExpectError
+}
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/examples/index.js b/lib/node_modules/@stdlib/stats/incr/wstdev/examples/index.js
new file mode 100644
index 000000000000..4d22d49e506a
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/examples/index.js
@@ -0,0 +1,41 @@
+/**
+* @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 incrwstdev = require( './../lib' );
+
+var accumulator;
+var s;
+var v;
+var w;
+var i;
+
+// Initialize an accumulator:
+accumulator = incrwstdev();
+
+// For each simulated datum, update the weighted standard deviation...
+console.log( '\nValue\tWeight\tWeighted Std Dev\n' );
+for ( i = 0; i < 100; i++ ) {
+ v = randu() * 100.0; // Simulated value
+ w = randu() * 10.0 + 1.0; // Simulated weight between 1 and 10
+ s = accumulator( v, w );
+ console.log( '%d\t%d\t%d', v.toFixed( 4 ), w.toFixed( 4 ), s.toFixed( 4 ) );
+}
+console.log( '\nFinal weighted standard deviation: %d\n', accumulator() );
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/lib/index.js b/lib/node_modules/@stdlib/stats/incr/wstdev/lib/index.js
new file mode 100644
index 000000000000..a03eabf394c0
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/lib/index.js
@@ -0,0 +1,51 @@
+/**
+* @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 an incremental weighted standard deviation.
+*
+* @module @stdlib/stats/incr/wstdev
+*
+* @example
+* var incrwstdev = require( '@stdlib/stats/incr/wstdev' );
+*
+* var accumulator = incrwstdev();
+*
+* var s = accumulator();
+* // returns null
+*
+* s = accumulator( 2.0, 1.5 );
+* // returns 0.0
+*
+* s = accumulator( -5.0, 2.0 );
+* // returns updated weighted standard deviation
+*
+* s = accumulator();
+* // returns current weighted standard deviation
+*/
+
+// MODULES //
+
+var main = require( './main.js' );
+
+
+// EXPORTS //
+
+module.exports = main;
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/lib/main.js b/lib/node_modules/@stdlib/stats/incr/wstdev/lib/main.js
new file mode 100644
index 000000000000..0f7469b8951c
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/lib/main.js
@@ -0,0 +1,131 @@
+/**
+* @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 isNumber = require( '@stdlib/assert/is-number' ).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 weighted standard deviation.
+*
+* @param {number} [mean] - known mean value
+* @throws {TypeError} must provide a number primitive for mean
+* @returns {Function} accumulator function
+*
+* @example
+* var accumulator = incrwstdev();
+*
+* var s = accumulator();
+* // returns null
+*
+* s = accumulator( 2.0, 1.5 );
+* // returns 0.0
+*
+* s = accumulator( -5.0, 2.0 );
+* // returns updated weighted standard deviation
+*
+* s = accumulator();
+* // returns current weighted standard deviation
+*
+* @example
+* var accumulator = incrwstdev( 3.14 );
+*/
+function incrwstdev( mean ) {
+ var delta;
+ var mu;
+ var M2;
+ var W;
+ var N;
+
+ M2 = 0.0;
+ W = 0.0;
+ N = 0;
+ if ( arguments.length ) {
+ if ( !isNumber( mean ) ) {
+ throw new TypeError( format( 'invalid argument. Must provide a number. Value: `%s`.', mean ) );
+ }
+ mu = mean;
+ return accumulatorWithMean;
+ }
+ mu = 0.0;
+ return accumulatorWithoutMean;
+
+ /**
+ * If provided a value and weight, the accumulator function returns an updated weighted standard deviation.
+ * If not provided a value, the accumulator function returns the current weighted standard deviation.
+ *
+ * @private
+ * @param {number} [x] - new value
+ * @param {number} [w] - weight for the new value
+ * @returns {(number|null)} weighted standard deviation or null
+ */
+ function accumulatorWithoutMean( x, w ) {
+ if ( arguments.length < 2 ) {
+ if ( W === 0 ) {
+ return null;
+ }
+ return Math.sqrt( M2 / W );
+ }
+ if ( !isNumber( x ) || !isNumber( w ) || w < 0 ) {
+ throw new TypeError( 'Both value and non-negative weight are required' );
+ }
+ W += w;
+ N += 1;
+ delta = x - mu;
+ mu += ( w * delta ) / W;
+ M2 += w * delta * ( x - mu );
+ return Math.sqrt( M2 / W );
+ }
+
+ /**
+ * If provided a value and weight, the accumulator function returns an updated weighted standard deviation.
+ * If not provided a value, the accumulator function returns the current weighted standard deviation.
+ *
+ * @private
+ * @param {number} [x] - new value
+ * @param {number} [w] - weight for the new value
+ * @returns {(number|null)} weighted standard deviation or null
+ */
+ function accumulatorWithMean( x, w ) {
+ if ( arguments.length < 2 ) {
+ if ( W === 0 ) {
+ return null;
+ }
+ return Math.sqrt( M2 / W );
+ }
+ if ( !isNumber( x ) || !isNumber( w ) || w < 0 ) {
+ throw new TypeError( 'Both value and non-negative weight are required' );
+ }
+ W += w;
+ delta = x - mu;
+ M2 += w * delta * delta;
+ return Math.sqrt( M2 / W );
+ }
+}
+
+
+// EXPORTS //
+
+module.exports = incrwstdev;
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/package.json b/lib/node_modules/@stdlib/stats/incr/wstdev/package.json
new file mode 100644
index 000000000000..db3eadb812af
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/package.json
@@ -0,0 +1,78 @@
+{
+ "name": "@stdlib/stats/incr/wstdev",
+ "version": "0.0.1",
+ "description": "Compute an incremental weighted sample standard deviation.",
+ "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": {
+ "test": "node test/test.js",
+ "build-docs": "node ./scripts/generate-docs.js",
+ "start": "node lib/index.js"
+ },
+ "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/math/base/assert/is-nan": "^0.0.1",
+ "@stdlib/math/base/assert/is-finite": "^0.0.1"
+ },
+ "devDependencies": {
+ "tape": "^5.2.2"
+ },
+ "engines": {
+ "node": ">=14.0.0",
+ "npm": ">=6.0.0"
+ },
+ "os": [
+ "aix",
+ "darwin",
+ "freebsd",
+ "linux",
+ "macos",
+ "openbsd",
+ "sunos",
+ "win32",
+ "windows"
+ ],
+ "keywords": [
+ "stdlib",
+ "stdmath",
+ "statistics",
+ "stats",
+ "mathematics",
+ "math",
+ "weighted standard deviation",
+ "weighted stdev",
+ "sample standard deviation",
+ "unbiased",
+ "variance",
+ "dispersion",
+ "central tendency",
+ "incremental",
+ "accumulator"
+ ]
+ }
+
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/stats/incr/wstdev/test/test.js b/lib/node_modules/@stdlib/stats/incr/wstdev/test/test.js
new file mode 100644
index 000000000000..9f56e66c4849
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/wstdev/test/test.js
@@ -0,0 +1,210 @@
+/**
+* @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 isnan = require('@stdlib/math/base/assert/is-nan');
+var incrwstdev = require('./../lib'); // Replace with actual path
+
+
+// TESTS //
+
+tape('main export is a function', function test(t) {
+ t.ok(true, __filename);
+ t.strictEqual(typeof incrwstdev, 'function', 'main export is a function');
+ t.end();
+});
+
+tape('the function returns an accumulator function', function test(t) {
+ t.equal(typeof incrwstdev(), 'function', 'returns a function');
+ t.end();
+});
+
+tape('the accumulator function computes an incremental weighted standard deviation', function test(t) {
+ var data = [2.0, 3.0, 2.0, 4.0, 3.0, 4.0];
+ var weights = [1.0, 0.5, 1.5, 1.0, 0.75, 1.25];
+ var expected = [
+ 0.0,
+ 0.5,
+ 0.7071067811865476,
+ 1.0,
+ 0.7745966692414834,
+ 0.9128709291752769
+ ];
+
+ var acc = incrwstdev();
+ var actual = new Array(data.length);
+
+ for (var i = 0; i < data.length; i++) {
+ actual[i] = acc(data[i], weights[i]);
+ }
+ t.deepEqual(actual, expected, 'returns expected incremental results');
+ t.end();
+});
+
+tape('if no inputs are provided, the result is `null`', function test(t) {
+ var acc = incrwstdev();
+ t.equal(acc(), null, 'returns null without inputs');
+ t.end();
+});
+
+tape('returns `null` if all weights are zero', function test(t) {
+ var data = [1.0, 2.0, 3.0];
+ var weights = [0, 0, 0];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ acc(data[i], weights[i]);
+ }
+ t.equal(acc(), null, 'returns null when all weights are zero');
+ t.end();
+});
+
+tape('returns 0 when all data points are identical with non-zero weights', function test(t) {
+ var data = [3.0, 3.0, 3.0];
+ var weights = [1.0, 0.5, 1.5];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ t.equal(acc(data[i], weights[i]), 0.0, 'returns 0 for identical data points');
+ }
+ t.equal(acc(), 0.0, 'final accumulated value is 0');
+ t.end();
+});
+
+tape('NaN propagation: if any data or weight is NaN, all future results are NaN', function test(t) {
+ var data = [2.0, NaN, 3.0];
+ var weights = [1.0, 1.0, 0.5];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ t.equal(isnan(acc(data[i], weights[i])), true, 'returns NaN if any input is NaN');
+ }
+ t.equal(isnan(acc()), true, 'final accumulated value is NaN');
+ t.end();
+});
+
+tape('zero or negative weights return null and do not affect the result', function test(t) {
+ var data = [2.0, 3.0, 4.0];
+ var weights = [1.0, 0.0, -1.0];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ acc(data[i], weights[i]);
+ }
+ t.equal(acc(), null, 'returns null if all weights are zero or negative');
+ t.end();
+});
+
+tape('handles very small weights without underflow', function test(t) {
+ var data = [2.0, 3.0, 2.0];
+ var weights = [1e-10, 2e-10, 1e-10];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ acc(data[i], weights[i]);
+ }
+ t.ok(acc() >= 0, 'returns a non-negative standard deviation with very small weights');
+ t.end();
+});
+
+tape('handles large weights without overflow', function test(t) {
+ var data = [2.0, 3.0, 4.0];
+ var weights = [1e10, 1e10, 1e10];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ acc(data[i], weights[i]);
+ }
+ t.ok(acc() >= 0, 'returns a non-negative standard deviation with very large weights');
+ t.end();
+});
+
+tape('non-numeric inputs for data or weights throw errors', function test(t) {
+ var acc = incrwstdev();
+ var badData = [true, 'text', [], {}, null, undefined];
+ var weight = 1.0;
+
+ badData.forEach(function(badValue) {
+ t.throws(function() {
+ acc(badValue, weight);
+ }, TypeError, 'throws error for non-numeric data: ' + badValue);
+ });
+
+ var data = 2.0;
+ var badWeights = [true, 'text', [], {}, null, undefined];
+
+ badWeights.forEach(function(badValue) {
+ t.throws(function() {
+ acc(data, badValue);
+ }, TypeError, 'throws error for non-numeric weight: ' + badValue);
+ });
+
+ t.end();
+});
+
+tape('when no value is provided, the function returns the current weighted standard deviation', function test(t) {
+ var data = [2.0, 4.0, 6.0];
+ var weights = [1.0, 2.0, 3.0];
+ var acc = incrwstdev();
+
+ data.forEach(function(value, i) {
+ acc(value, weights[i]);
+ });
+ t.equal(acc(), 1.632993161855452, 'returns the correct current weighted standard deviation');
+ t.end();
+});
+
+tape('returns null when only one valid data-weight pair has been provided', function test(t) {
+ var acc = incrwstdev();
+ acc(3.0, 1.0);
+ t.equal(acc(), null, 'returns null when only one pair is provided');
+ t.end();
+});
+
+tape('handles large variance in data points', function test(t) {
+ var data = [1e-10, 1e10];
+ var weights = [1.0, 1.0];
+ var acc = incrwstdev();
+
+ for (var i = 0; i < data.length; i++) {
+ acc(data[i], weights[i]);
+ }
+ t.ok(acc() > 0, 'handles high variance without underflow or overflow');
+ t.end();
+});
+
+tape('handles large datasets and remains performant', function test(t) {
+ var acc = incrwstdev();
+ var data = [];
+ var weights = [];
+ var n = 100000;
+
+ for (var i = 0; i < n; i++) {
+ data.push(Math.random() * 100);
+ weights.push(Math.random());
+ acc(data[i], weights[i]);
+ }
+
+ t.ok(!isnan(acc()), 'returns a valid standard deviation for large dataset');
+ t.end();
+});
+