diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/README.md b/lib/node_modules/@stdlib/stats/incr/nanmae/README.md
new file mode 100644
index 000000000000..0a8dbc6afa1e
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/README.md
@@ -0,0 +1,175 @@
+
+
+# incrnanmae
+
+> Compute the [mean absolute error][mean-absolute-error] (MAE) incrementally, ignoring `NaN` values.
+
+
+
+The [mean absolute error][mean-absolute-error] is defined as
+
+
+
+```math
+\mathop{\mathrm{MAE}} = \frac{\displaystyle\sum_{i=0}^{n-1} |y_i - x_i|}{n}
+```
+
+
+
+
+
+
+
+
+
+
+
+## Usage
+
+```javascript
+var incrnanmae = require( '@stdlib/stats/incr/nanmae' );
+```
+
+#### incrnanmae()
+
+Returns an accumulator `function` which incrementally computes the [mean absolute error][mean-absolute-error] ignoring NaN values.
+
+```javascript
+var accumulator = incrnanmae();
+```
+
+#### accumulator( \[x, y] )
+
+If provided input values `x` and `y`, the accumulator function returns an updated [mean absolute error][mean-absolute-error]. If not provided input values `x` and `y`, the accumulator function returns the current [mean absolute error][mean-absolute-error].
+
+```javascript
+var accumulator = incrnanmae();
+
+var m = accumulator();
+// returns null
+
+m = accumulator( 2.0, 3.0 );
+// returns 1.0
+
+m = accumulator( NaN, 2.0 );
+// returns 1.0
+
+m = accumulator( -5.0, NaN );
+// returns 1.0
+
+m = accumulator( NaN, NaN );
+// returns 1.0
+
+m = accumulator( -5.0, 2.0 );
+// returns 4.0
+
+m = accumulator();
+// returns 4.0
+```
+
+
+
+
+
+
+
+## Notes
+
+- Input values are not type checked beyond checking for NaN. If provided values which are not numbers or NaN (e.g., strings, booleans), the behavior of the accumulator is undefined. If non-numeric inputs are possible, you are advised to type check and handle accordingly before passing the value to the accumulator function.
+- If both provided values are NaN, the accumulated value is unchanged. The accumulator only updates when both inputs are valid numbers.
+- **Warning**: the [mean absolute 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 incrnanmae = require( '@stdlib/stats/incr/nanmae' );
+
+var accumulator;
+var v1;
+var v2;
+var i;
+
+// Initialize an accumulator:
+accumulator = incrnanmae();
+
+// For each simulated datum, update the mean absolute error...
+for ( i = 0; i < 100; i++ ) {
+ v1 = ( randu() < 0.2 ) ? NaN : ( randu()*100.0 ) - 50.0;
+ v2 = ( randu() < 0.2 ) ? NaN : ( randu()*100.0 ) - 50.0;
+ accumulator( v1, v2 );
+}
+console.log( accumulator() );
+```
+
+
+
+
+
+
+
+
+
+* * *
+
+## See Also
+
+- [`@stdlib/stats/incr/mape`][@stdlib/stats/incr/mape]: compute the mean absolute percentage error (MAPE) incrementally.
+- [`@stdlib/stats/incr/me`][@stdlib/stats/incr/me]: compute the mean error (ME) incrementally.
+- [`@stdlib/stats/incr/mean`][@stdlib/stats/incr/mean]: compute an arithmetic mean incrementally.
+- [`@stdlib/stats/incr/mmae`][@stdlib/stats/incr/mmae]: compute a moving mean absolute error (MAE) incrementally.
+
+
+
+
+
+
+
+
+
+[mean-absolute-error]: https://en.wikipedia.org/wiki/Mean_absolute_error
+
+
+
+[@stdlib/stats/incr/mape]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/mape
+
+[@stdlib/stats/incr/me]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/me
+
+[@stdlib/stats/incr/mean]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/mean
+
+[@stdlib/stats/incr/mmae]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/incr/mmae
+
+
+
+
+
+
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/incr/nanmae/benchmark/benchmark.js
new file mode 100644
index 000000000000..287889ceafa2
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/benchmark/benchmark.js
@@ -0,0 +1,105 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 isnan = require( '@stdlib/math/base/assert/is-nan' );
+var pkg = require( './../package.json' ).name;
+var incrnanmae = require( './../lib' ); // Corrected from incrmae
+
+
+// MAIN //
+
+bench( pkg, function benchmark( b ) {
+ var f;
+ var i;
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ f = incrnanmae();
+ 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;
+ var x;
+ var y;
+
+ acc = incrnanmae();
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ x = ( randu() < 0.2 ) ? NaN : randu()-0.5;
+ y = ( randu() < 0.2 ) ? NaN : randu()-0.5;
+ v = acc( x, y );
+ if ( v !== v && !isnan( x ) && !isnan( y ) ) {
+ b.fail( 'should not return NaN when inputs are not NaN' );
+ }
+ }
+ b.toc();
+ if ( v !== v && !isnan( x ) && !isnan( y ) ) {
+ b.fail( 'should not return NaN when inputs are not NaN' );
+ }
+ b.pass( 'benchmark finished' );
+ b.end();
+});
+
+bench( pkg+'::accumulator,nan_handling', function benchmark( b ) {
+ var acc;
+ var v;
+ var i;
+
+ b.tic();
+ for ( i = 0; i < b.iterations; i++ ) {
+ acc = incrnanmae(); // Reset accumulator for each iteration
+ v = acc(); // Initial state
+ if ( v !== null ) {
+ b.fail( 'initial value should be null' );
+ }
+ acc( 2.0, 3.0 ); // Set a baseline MAE
+ v = acc( NaN, randu()-0.5 );
+ if ( typeof v !== 'number' || isnan( v ) ) {
+ b.fail( 'should return a number when one input is NaN' );
+ }
+ v = acc( randu()-0.5, NaN );
+ if ( typeof v !== 'number' || isnan( v ) ) {
+ b.fail( 'should return a number when one input is NaN' );
+ }
+ v = acc( NaN, NaN );
+ if ( typeof v !== 'number' || isnan( v ) ) {
+ b.fail( 'should return a number when both inputs are NaN' );
+ }
+ }
+ b.toc();
+ b.pass( 'benchmark finished' );
+ b.end();
+});
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/docs/img/equation_mean_absolute_error.svg b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/img/equation_mean_absolute_error.svg
new file mode 100644
index 000000000000..8ca0b90df05f
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/img/equation_mean_absolute_error.svg
@@ -0,0 +1,54 @@
+
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/docs/repl.txt b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/repl.txt
new file mode 100644
index 000000000000..7c907d14fe40
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/repl.txt
@@ -0,0 +1,36 @@
+
+{{alias}}()
+ Returns an accumulator function which incrementally computes the mean
+ absolute error, ignoring `NaN` values.
+
+ If provided two values, the accumulator function returns an updated mean
+ absolute error. If not provided values, the accumulator function returns
+ the current mean absolute error.
+
+ Returns
+ -------
+ acc: Function
+ Accumulator function.
+
+ Examples
+ --------
+ > var incrnanmae = require( '@stdlib/stats/incr/nanmae' );
+ > var accumulator = incrnanmae();
+ > var m = accumulator()
+ null
+ > m = accumulator( 2.0, 3.0 )
+ 1.0
+ > m = accumulator( NaN, 2.0 )
+ 1.0
+ > m = accumulator( -5.0, NaN )
+ 1.0
+ > m = accumulator( NaN, NaN )
+ 1.0
+ > m = accumulator( -5.0, 2.0 )
+ 4.0
+ > m = accumulator()
+ 4.0
+
+ See Also
+ --------
+
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/types/index.d.ts
new file mode 100644
index 000000000000..3752fc459795
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/types/index.d.ts
@@ -0,0 +1,70 @@
+/*
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 absolute error. If not provided input values, the accumulator function returns the current mean absolute error.
+*
+* ## Notes
+*
+* - If either provided value is `NaN`, the accumulated value is unchanged and remains the current mean absolute error (or `null` if no valid values have been provided).
+*
+* @param x - input value
+* @param y - input value
+* @returns mean absolute error or null
+*/
+type accumulator = ( x?: number, y?: number ) => number | null;
+
+/**
+* Returns an accumulator function which incrementally computes the mean absolute error, ignoring `NaN` values.
+*
+* @returns accumulator function
+*
+* @example
+* var accumulator = incrnanmae();
+*
+* var m = accumulator();
+* // returns null
+*
+* m = accumulator( 2.0, 3.0 );
+* // returns 1.0
+*
+* m = accumulator( NaN, 2.0 );
+* // returns 1.0
+*
+* m = accumulator( -5.0, NaN );
+* // returns 1.0
+*
+* m = accumulator( NaN, NaN );
+* // returns 1.0
+*
+* m = accumulator( -5.0, 2.0 );
+* // returns 4.0
+*
+* m = accumulator();
+* // returns 4.0
+*/
+declare function incrnanmae(): accumulator;
+
+
+// EXPORTS //
+
+export = incrnanmae;
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/docs/types/test.ts b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/types/test.ts
new file mode 100644
index 000000000000..8002fcff4beb
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/docs/types/test.ts
@@ -0,0 +1,72 @@
+/*
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 incrnanmae = require( './index' );
+
+
+// TESTS //
+
+// The function returns an accumulator function...
+{
+ incrnanmae(); // $ExpectType accumulator
+}
+
+// The compiler throws an error if the function is provided arguments...
+{
+ incrnanmae( '5' ); // $ExpectError
+ incrnanmae( 5 ); // $ExpectError
+ incrnanmae( true ); // $ExpectError
+ incrnanmae( false ); // $ExpectError
+ incrnanmae( null ); // $ExpectError
+ incrnanmae( undefined ); // $ExpectError
+ incrnanmae( [] ); // $ExpectError
+ incrnanmae( {} ); // $ExpectError
+ incrnanmae( ( x: number ): number => x ); // $ExpectError
+}
+
+// The function returns an accumulator function which returns an accumulated result...
+{
+ const acc = incrnanmae();
+
+ acc(); // $ExpectType number | null
+ acc( 3.14, 2.0 ); // $ExpectType number | null
+ acc( NaN, 2.0 ); // $ExpectType number | null
+ acc( -5.0, NaN ); // $ExpectType number | null
+ acc( NaN, NaN ); // $ExpectType number | null
+}
+
+// The compiler throws an error if the returned accumulator function is provided invalid arguments...
+{
+ const acc = incrnanmae();
+
+ 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/nanmae/examples/index.js b/lib/node_modules/@stdlib/stats/incr/nanmae/examples/index.js
new file mode 100644
index 000000000000..407d45eda10a
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/examples/index.js
@@ -0,0 +1,41 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 incrnanmae = require( './../lib' );
+
+var accumulator;
+var err;
+var v1;
+var v2;
+var i;
+
+// Initialize an accumulator:
+accumulator = incrnanmae();
+
+// For each simulated datum, update the mean absolute error...
+console.log( '\nValue\tValue\tMean\n' );
+for ( i = 0; i < 100; i++ ) {
+ v1 = ( randu() < 0.2 ) ? NaN : ( randu()*100.0 ) - 50.0;
+ v2 = ( randu() < 0.2 ) ? NaN : ( randu()*100.0 ) - 50.0;
+ err = accumulator( v1, v2 );
+ console.log( '%d\t%d\t%d', v1.toFixed( 3 ), v2.toFixed( 3 ), err.toFixed( 3 ) );
+}
+console.log( '\nFinal MAE: %d\n', accumulator() );
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/lib/index.js b/lib/node_modules/@stdlib/stats/incr/nanmae/lib/index.js
new file mode 100644
index 000000000000..4c736e68e65b
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/lib/index.js
@@ -0,0 +1,60 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 mean absolute error incrementally, ignoring NaN values.
+*
+* @module @stdlib/stats/incr/nanmae
+*
+* @example
+* var incrnanmae = require( '@stdlib/stats/incr/nanmae' );
+*
+* var accumulator = incrnanmae();
+*
+* var m = accumulator();
+* // returns null
+*
+* m = accumulator( 2.0, 3.0 );
+* // returns 1.0
+*
+* m = accumulator( NaN, 2.0 );
+* // returns 1.0
+*
+* m = accumulator( -5.0, NaN );
+* // returns 1.0
+*
+* m = accumulator( NaN, NaN );
+* // returns 1.0
+*
+* m = accumulator( -5.0, 2.0 );
+* // returns 4.0
+*
+* m = accumulator();
+* // returns 4.0
+*/
+
+// MODULES //
+
+var main = require( './main.js' );
+
+
+// EXPORTS //
+
+module.exports = main;
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/lib/main.js b/lib/node_modules/@stdlib/stats/incr/nanmae/lib/main.js
new file mode 100644
index 000000000000..a77f39707440
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/lib/main.js
@@ -0,0 +1,84 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 isnan = require( '@stdlib/math/base/assert/is-nan' );
+var incrmae = require( '@stdlib/stats/incr/mae' );
+
+
+// MAIN //
+
+/**
+* Returns an accumulator function which incrementally computes the mean absolute error, ignoring NaN values.
+*
+* @returns {Function} accumulator function
+*
+* @example
+* var accumulator = incrnanmae();
+*
+* var m = accumulator();
+* // returns null
+*
+* m = accumulator( 2.0, 3.0 );
+* // returns 1.0
+*
+* m = accumulator( NaN, 2.0 );
+* // returns 1.0
+*
+* m = accumulator( -5.0, NaN );
+* // returns 1.0
+*
+* m = accumulator( NaN, NaN );
+* // returns 1.0
+*
+* m = accumulator( -5.0, 2.0 );
+* // returns 4.0
+*
+* m = accumulator();
+* // returns 4.0
+*/
+function incrnanmae() {
+ var mae = incrmae();
+ return accumulator;
+
+ /**
+ * If provided input values, the accumulator function returns an updated mean absolute error. If not provided input values, the accumulator function returns the current mean absolute error.
+ *
+ * @private
+ * @param {number} [x] - input value
+ * @param {number} [y] - input value
+ * @returns {(number|null)} mean absolute error or null
+ */
+ function accumulator( x, y ) {
+ if ( arguments.length === 0 ) {
+ return mae();
+ }
+ if ( isnan( x ) || isnan( y ) ) {
+ return mae();
+ }
+ return mae( x, y );
+ }
+}
+
+
+// EXPORTS //
+
+module.exports = incrnanmae;
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/package.json b/lib/node_modules/@stdlib/stats/incr/nanmae/package.json
new file mode 100644
index 000000000000..3268526505e7
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/package.json
@@ -0,0 +1,67 @@
+{
+ "name": "@stdlib/stats/incr/nanmae",
+ "version": "0.0.0",
+ "description": "Compute the mean absolute error incrementally, 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": {},
+ "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",
+ "absolute",
+ "avg",
+ "mean",
+ "arithmetic mean",
+ "central tendency",
+ "error",
+ "incremental",
+ "accumulator"
+ ]
+}
diff --git a/lib/node_modules/@stdlib/stats/incr/nanmae/test/test.js b/lib/node_modules/@stdlib/stats/incr/nanmae/test/test.js
new file mode 100644
index 000000000000..bc9d044ec11b
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/incr/nanmae/test/test.js
@@ -0,0 +1,115 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2020 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 incrnanmae = require( './../lib' );
+
+
+// TESTS //
+
+tape( 'main export is a function', function test( t ) {
+ t.ok( true, __filename );
+ t.strictEqual( typeof incrnanmae, 'function', 'main export is a function' );
+ t.end();
+});
+
+tape( 'the function returns an accumulator function', function test( t ) {
+ t.equal( typeof incrnanmae(), 'function', 'returns a function' );
+ t.end();
+});
+
+tape( 'the initial accumulated value is `null`', function test( t ) {
+ var acc = incrnanmae();
+ t.equal( acc(), null, 'returns expected value' );
+ t.end();
+});
+
+tape( 'the accumulator function incrementally computes the mean absolute error, ignoring NaN values', function test( t ) {
+ var expected;
+ var actual;
+ var delta;
+ var data;
+ var acc;
+ var sum;
+ var tol;
+ var N;
+ var n;
+ var x;
+ var y;
+ var i;
+
+ data = [
+ [ 2.0, 3.0 ], // MAE = |2-3| / 1 = 1.0
+ [ 3.0, NaN ], // Ignored, MAE = 1.0
+ [ NaN, 5.0 ], // Ignored, MAE = 1.0
+ [ 4.0, -4.0 ], // MAE = (1 + |4-(-4)|) / 2 = 4.5
+ [ NaN, NaN ], // Ignored, MAE = 4.5
+ [ -4.0, 5.0 ] // MAE = (1 + 8 + |-4-5|) / 3 = 6.0
+ ];
+ N = data.length;
+
+ acc = incrnanmae();
+
+ sum = 0;
+ n = 0; // Count of valid pairs
+ for ( i = 0; i < N; i++ ) {
+ x = data[ i ][ 0 ];
+ y = data[ i ][ 1 ];
+ if ( !isNaN( x ) && !isNaN( y ) ) {
+ sum += abs( y-x );
+ n += 1;
+ expected = sum / n;
+ } else {
+ expected = ( n === 0 ) ? null : sum / n;
+ }
+ actual = acc( x, y );
+ if ( actual === expected ) {
+ t.equal( actual, expected, 'returns expected value' );
+ } else {
+ delta = abs( expected - actual );
+ tol = 1.0 * EPS * abs( expected );
+ t.equal( 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 mean absolute error', function test( t ) {
+ var data;
+ var acc;
+ var i;
+
+ data = [
+ [ 2.0, 3.0 ], // MAE = 1.0
+ [ NaN, -5.0 ], // Ignored, MAE = 1.0
+ [ 1.0, NaN ], // Ignored, MAE = 1.0
+ [ 1.0, 10.0 ] // MAE = (1 + |1-10|) / 2 = 5.0
+ ];
+ acc = incrnanmae();
+ for ( i = 0; i < data.length; i++ ) {
+ acc( data[ i ][ 0 ], data[ i ][ 1 ] );
+ }
+ t.equal( acc(), 5.0, 'returns expected value' );
+ t.end();
+});