Repository: stdlib-js/stdlib (2025-07-06T11:18:57Z)

Issue:
[RFC]: refactor and add protocol support to `stats/base/cuminabs`
## Description

This RFC proposes refactoring and adding accessor protocol support to [`@stdlib/stats/base/cuminabs`](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/cuminabs).

For background on the accessor protocol, see https://blog.stdlib.io/introducing-the-accessor-protocol-for-array-like-objects/.

Examples of what we are looking for:

- `stats/base/min`: https://github.com/stdlib-js/stdlib/commit/fbb31fbaafbbbf233740a41a88a57f4db1cb427b ([package](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/min))
- `stats/base/cumax`: https://github.com/stdlib-js/stdlib/commit/11f1341134c5d6c7c0ecd82c99dff766e08e731a ([package](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/cumax))
- `stats/base/cumin`: https://github.com/stdlib-js/stdlib/commit/528efd8000eb7b910f64e63796a8a7c2fdfa03cd ([package](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/cumin))
- `stats/base/mediansorted`: https://github.com/stdlib-js/stdlib/commit/065f86535e3f1915160f91820f1fa0af79633b72 ([package](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/mediansorted))
- `stats/base/mskmax`: https://github.com/stdlib-js/stdlib/commit/417e65361234ec46382f58cc303a544f5bbcbf9e ([package](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/mskmax))

While the changes proposed in this RFC will **not** match the implementations found in the above packages, the packages should provide a conceptual idea of what is desired. Do **not** simply copy-paste the code found in those packages without reasoning about expected behavior and API design.

### Key Points

#### Refactoring

When refactoring and cleaning up existing implementations, pay special attention to the changes made in the commits referred to above. You'll need to go line-by-line in [`@stdlib/stats/base/cuminabs`](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/cuminabs) and compare with the changes made in the above commits.

In particular, we're interested in

1. standardizing language in descriptions so that all packages in `stats/base` use similar language for describing input parameters and behavior.
2. updating examples to align with current conventions in stdlib.
3. simplifying examples and benchmarks to use utilities for generating random arrays.
4. reducing code duplication by having the main package entry point delegate to the `ndarray` API.

#### Accessor protocol

Prior to adding accessor protocol support, check whether the implementation has any strided array dependencies. For example, for certain algorithms for computing the mean, implementations will depend on algorithms for computing the sum. Ensure that the upstream implementations have support for accessor arrays. If not, you'll need to open a separate PR adding support in the upstream dependencies before working on this package.

When adding support for the accessor protocol, you'll need to do the following:

##### Create an accessors file

Create a new `lib/accessors.js` file. This file will contain an implementation which can handle accessor arrays.

##### Modify the ndarray file

Modify the `lib/ndarray.js` file to delegate to the accessors implementation when one (or more) of the input arrays is an accessor array.

##### Update tests

Modify the tests to include explicit tests for accessor arrays.

#### Run tests and other commands

For each of the following commands, please run them from the root stdlib repository directory (not the package folder!).

To run unit tests,

```bash
make test TESTS_FILTER=".*/stats/base/cuminabs/.*"
```

To run examples,

```bash
make examples EXAMPLES_FILTER=".*/stats/base/cuminabs/.*"
```

To run benchmarks,

```bash
make benchmark BENCHMARKS_FILTER=".*/stats/base/cuminabs/.*"
```

### Create pull request

Provided all tests, examples, and benchmarks successfully execute and pass and that you've updated the package's documentation, you are now ready to open a pull request!

* * *

## Notes

- If you are interested in contributing a PR which addresses this RFC and still getting familiar with our project conventions, please do **not** submit LLM-generated code. Please consult our [contributing guidelines](https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md) and the associated [development guide](https://github.com/stdlib-js/stdlib/blob/develop/docs/development.md). Failure to respect project conventions will result in your PR being rejected without review. Thank you for understanding!

### Checklist

- [X] I have read and understood the [Code of Conduct](https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md).
- [X] Searched for existing issues and pull requests.
- [X] The issue name begins with `[RFC]:`.



Discussion:
# :wave: Important: PLEASE READ :wave:

This issue has been labeled as a **good first issue** and is available for anyone to work on.

If this is your first time contributing to an open source project, some aspects of the development process may seem unusual, arcane, or some combination of both.

1.  **You cannot "claim" issues.** People new to open source often want to "claim" or be assigned an issue before beginning work. The typical rationale is that people want to avoid wasted work in the event that someone else ends up working the issue. However, this practice is not effective in open source, as it often leads to "issue squatting", in which an individual asks to be assigned, is granted their request, and then never ends up working on the issue. Accordingly, you are encouraged to communicate your intent to address this issue, ideally by providing a rough outline as to how you plan to address the issue or asking clarifying questions, but, at the end of the day, we will take running code and rough consensus in order to move forward quickly.
2.  **We have a very high bar for contributions.** We have very high standards for contributions and expect all contributions—whether new features, tests, or documentation—to be rigorous, thorough, and complete. Once a pull request is merged into stdlib, that contribution immediately becomes the collective responsibility of all maintainers of stdlib. When we merge code into stdlib, we are saying that we, the maintainers, commit to reviewing subsequent changes and making bugfixes to the code. Hence, in order to ensure future maintainability, this naturally leads to a higher standard of contribution.

Before working on this issue and opening a pull request, please read the project's [contributing guidelines](https://github.com/stdlib-js/stdlib/blob/develop/CONTRIBUTING.md). These guidelines and the associated [development guide](https://github.com/stdlib-js/stdlib/blob/develop/docs/contributing/development.md) provide important information, including links to stdlib's [Code of Conduct](https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md), license policy, and steps for setting up your local development environment.

To reiterate, we **strongly** encourage you to refer to our contributing guides **before** beginning work on this issue. Failure to follow our guidelines significantly decreases the likelihood that you'll successfully contribute to stdlib and may result in automatic closure of a pull request without review.

Setting up your local development environment is a critical first step, as doing so ensures that automated development processes for linting, license verification, and unit testing can run prior to authoring commits and pushing changes. If you would prefer to avoid manual setup, we provide pre-configured [development containers](https://github.com/stdlib-js/stdlib/tree/develop/.devcontainer) for use locally or in GitHub Codespaces.

We place a high value on consistency throughout the stdlib codebase. We encourage you to closely examine other packages in stdlib and attempt to emulate the practices and conventions found therein.

-   If you are attempting to contribute a new package, sometimes the best approach is to simply copy the contents of an existing package and then modify the minimum amount necessary to implement the feature (e.g., changing descriptions, parameter names, and implementation).
-   If you are contributing tests, find a package implementing a similar feature and emulate the tests of that package.
-   If you are updating documentation, examine several similar packages and emulate the content, style, and prose of those packages.

In short, the more effort you put in to ensure that your contribution looks and feels like stdlib—including variables names, bracket spacing, line breaks, etc—the more likely that your contribution will be reviewed and ultimately accepted. We encourage you to closely study the codebase **before** beginning work on this issue.

:sparkles: Thank you again for your interest in stdlib, and we look forward to reviewing your future contributions. :sparkles:




Patch:
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/README.md b/lib/node_modules/@stdlib/stats/base/cuminabs/README.md
index 209988aec339..09ea14e71ebb 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/README.md
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/README.md
@@ -52,11 +52,11 @@ The function has the following parameters:
 
 -   **N**: number of indexed elements.
 -   **x**: input [`Array`][mdn-array] or [`typed array`][mdn-typed-array].
--   **strideX**: index increment for `x`.
+-   **strideX**: stride length for `x`.
 -   **y**: output [`Array`][mdn-array] or [`typed array`][mdn-typed-array].
--   **strideY**: index increment for `y`.
+-   **strideY**: stride length for `y`.
 
-The `N` and `stride` parameters determine which elements in `x` and `y` are accessed at runtime. For example, to compute the cumulative minimum absolute value of every other element in `x`,
+The `N` and stride parameters determine which elements in the strided arrays are accessed at runtime. For example, to compute the cumulative minimum absolute value of every other element in `x`,
 
 ```javascript
 var x = [ 1.0, 2.0, 2.0, -7.0, -2.0, 3.0, 4.0, 2.0 ];
@@ -102,7 +102,7 @@ The function has the following additional parameters:
 -   **offsetX**: starting index for `x`.
 -   **offsetY**: starting index for `y`.
 
-While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, `offsetX` and `offsetY` parameters support indexing semantics based on a starting indices. For example, to calculate the cumulative minimum absolute value of every other value in `x` starting from the second value and to store in the last `N` elements of `y` starting from the last element
+While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, offset parameters support indexing semantics based on starting indices. For example, to calculate the cumulative minimum absolute value of every other element in `x` starting from the second element and to store in the last `N` elements of `y` starting from the last element
 
 ```javascript
 var x = [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ];
@@ -122,6 +122,7 @@ cuminabs.ndarray( 4, x, 2, 1, y, -1, y.length-1 );
 
 -   If `N <= 0`, both functions return `y` unchanged.
 -   Depending on the environment, the typed versions ([`dcuminabs`][@stdlib/stats/strided/dcuminabs], [`scuminabs`][@stdlib/stats/strided/scuminabs], etc.) are likely to be significantly more performant.
+-   Both functions support array-like objects having getter and setter accessors for array element access (e.g., [`@stdlib/array/base/accessor`][@stdlib/array/base/accessor]).
 
 </section>
 
@@ -134,20 +135,14 @@ cuminabs.ndarray( 4, x, 2, 1, y, -1, y.length-1 );
 <!-- eslint no-undef: "error" -->
 
 ```javascript
-var randu = require( '@stdlib/random/base/randu' );
-var round = require( '@stdlib/math/base/special/round' );
+var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
 var Float64Array = require( '@stdlib/array/float64' );
 var cuminabs = require( '@stdlib/stats/base/cuminabs' );
 
-var y;
-var x;
-var i;
-
-x = new Float64Array( 10 );
-y = new Float64Array( x.length );
-for ( i = 0; i < x.length; i++ ) {
-    x[ i ] = round( randu()*100.0 );
-}
+var x = discreteUniform( 10, 0, 100, {
+    'dtype': 'float64'
+});
+var y = new Float64Array( x.length );
 console.log( x );
 console.log( y );
 
@@ -188,6 +183,8 @@ console.log( y );
 
 [mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
 
+[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
+
 [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
 
 <!-- <related-links> -->
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.js b/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.js
index ef5edfecb9b2..722f2756d807 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.js
@@ -21,13 +21,22 @@
 // MODULES //
 
 var bench = require( '@stdlib/bench' );
-var randu = require( '@stdlib/random/base/randu' );
 var isnan = require( '@stdlib/math/base/assert/is-nan' );
 var pow = require( '@stdlib/math/base/special/pow' );
+var uniform = require( '@stdlib/random/array/uniform' );
+var zeros = require( '@stdlib/array/zeros' );
+var gfill = require( '@stdlib/blas/ext/base/gfill' );
 var pkg = require( './../package.json' ).name;
 var cuminabs = require( './../lib' );
 
 
+// VARIABLES //
+
+var options = {
+	'dtype': 'generic'
+};
+
+
 // FUNCTIONS //
 
 /**
@@ -38,35 +47,26 @@ var cuminabs = require( './../lib' );
 * @returns {Function} benchmark function
 */
 function createBenchmark( len ) {
-	var y;
-	var x;
-	var i;
-
-	x = [];
-	y = [];
-	for ( i = 0; i < len; i++ ) {
-		x.push( ( randu()*20.0 ) - 10.0 );
-		y.push( 0.0 );
-	}
+	var x = uniform( len, -10, 10, options );
+	var y = zeros( len, options.dtype );
 	return benchmark;
 
 	function benchmark( b ) {
 		var v;
 		var i;
 
-		for ( i = 0; i < len; i++ ) {
-			y[ i ] = 0.0;
-		}
+		gfill( len, 0.0, y, 1 );
+
 		b.tic();
 		for ( i = 0; i < b.iterations; i++ ) {
 			x[ 0 ] += 1.0;
 			v = cuminabs( x.length, x, 1, y, 1 );
-			if ( isnan( v[ i%len ] ) ) {
+			if ( isnan( v[ i % len ] ) ) {
 				b.fail( 'should not return NaN' );
 			}
 		}
 		b.toc();
-		if ( isnan( v[ i%len ] ) ) {
+		if ( isnan( v[ i % len ] ) ) {
 			b.fail( 'should not return NaN' );
 		}
 		b.pass( 'benchmark finished' );
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.ndarray.js b/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.ndarray.js
index af00fc89932e..a4844b9e2b9a 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.ndarray.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/benchmark/benchmark.ndarray.js
@@ -21,13 +21,22 @@
 // MODULES //
 
 var bench = require( '@stdlib/bench' );
-var randu = require( '@stdlib/random/base/randu' );
 var isnan = require( '@stdlib/math/base/assert/is-nan' );
 var pow = require( '@stdlib/math/base/special/pow' );
+var uniform = require( '@stdlib/random/array/uniform' );
+var zeros = require( '@stdlib/array/zeros' );
+var gfill = require( '@stdlib/blas/ext/base/gfill' );
 var pkg = require( './../package.json' ).name;
 var cuminabs = require( './../lib/ndarray.js' );
 
 
+// VARIABLES //
+
+var options = {
+	'dtype': 'generic'
+};
+
+
 // FUNCTIONS //
 
 /**
@@ -38,35 +47,26 @@ var cuminabs = require( './../lib/ndarray.js' );
 * @returns {Function} benchmark function
 */
 function createBenchmark( len ) {
-	var x;
-	var y;
-	var i;
-
-	x = [];
-	y = [];
-	for ( i = 0; i < len; i++ ) {
-		x.push( ( randu()*20.0 ) - 10.0 );
-		y.push( 0.0 );
-	}
+	var x = uniform( len, -10, 10, options );
+	var y = zeros( len, options.dtype );
 	return benchmark;
 
 	function benchmark( b ) {
 		var v;
 		var i;
 
-		for ( i = 0; i < len; i++ ) {
-			y[ i ] = 0.0;
-		}
+		gfill( len, 0.0, y, 1 );
+
 		b.tic();
 		for ( i = 0; i < b.iterations; i++ ) {
 			x[ 0 ] += 1.0;
 			v = cuminabs( x.length, x, 1, 0, y, 1, 0 );
-			if ( isnan( v[ i%len ] ) ) {
+			if ( isnan( v[ i % len ] ) ) {
 				b.fail( 'should not return NaN' );
 			}
 		}
 		b.toc();
-		if ( isnan( v[ i%len ] ) ) {
+		if ( isnan( v[ i % len ] ) ) {
 			b.fail( 'should not return NaN' );
 		}
 		b.pass( 'benchmark finished' );
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/docs/repl.txt b/lib/node_modules/@stdlib/stats/base/cuminabs/docs/repl.txt
index 8881fca3325e..a2f38a7811c3 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/docs/repl.txt
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/docs/repl.txt
@@ -2,8 +2,8 @@
 {{alias}}( N, x, strideX, y, strideY )
     Computes the cumulative minimum absolute value of a strided array.
 
-    The `N` and `stride` parameters determine which elements in `x` and `y` are
-    accessed at runtime.
+    The `N` and stride parameters determine which elements in the strided arrays
+    are accessed at runtime.
 
     Indexing is relative to the first index. To introduce an offset, use a typed
     array view.
@@ -19,13 +19,13 @@
         Input array.
 
     strideX: integer
-        Index increment for `x`.
+        Stride length for `x`.
 
     y: Array<number>|TypedArray
         Output array.
 
     strideY: integer
-        Index increment for `y`.
+        Stride length for `y`.
 
     Returns
     -------
@@ -40,11 +40,10 @@
     > {{alias}}( x.length, x, 1, y, 1 )
     [ 1.0, 1.0, 1.0 ]
 
-    // Using `N` and `stride` parameters:
+    // Using `N` and stride parameters:
     > x = [ -2.0, 1.0, 1.0, -5.0, 2.0, -1.0 ];
     > y = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ];
-    > var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
-    > {{alias}}( N, x, 2, y, 2 )
+    > {{alias}}( 3, x, 2, y, 2 )
     [ 2.0, 0.0, 1.0, 0.0, 1.0, 0.0 ]
 
     // Using view offsets:
@@ -52,12 +51,12 @@
     > var y0 = new {{alias:@stdlib/array/float64}}( x0.length );
     > var x1 = new {{alias:@stdlib/array/float64}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 );
     > var y1 = new {{alias:@stdlib/array/float64}}( y0.buffer, y0.BYTES_PER_ELEMENT*3 );
-    > N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 );
-    > {{alias}}( N, x1, 2, y1, 1 )
+    > {{alias}}( 3, x1, 2, y1, 1 )
     <Float64Array>[ 2.0, 2.0, 1.0 ]
     > y0
     <Float64Array>[ 0.0, 0.0, 0.0, 2.0, 2.0, 1.0 ]
 
+
 {{alias}}.ndarray( N, x, strideX, offsetX, y, strideY, offsetY )
     Computes the cumulative minimum absolute value of a strided array using
     alternative indexing semantics.
@@ -75,7 +74,7 @@
         Input array.
 
     strideX: integer
-        Index increment for `x`.
+        Stride length for `x`.
 
     offsetX: integer
         Starting index for `x`.
@@ -84,7 +83,7 @@
         Output array.
 
     strideY: integer
-        Index increment for `y`.
+        Stride length for `y`.
 
     offsetY: integer
         Starting index for `y`.
@@ -105,8 +104,7 @@
     // Advanced indexing:
     > x = [ 1.0, -2.0, 3.0, 2.0, 5.0, -1.0 ];
     > y = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ];
-    > var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
-    > {{alias}}.ndarray( N, x, 2, 1, y, -1, y.length-1 )
+    > {{alias}}.ndarray( 3, x, 2, 1, y, -1, y.length-1 )
     [ 0.0, 0.0, 0.0, 1.0, 2.0, 2.0 ]
 
     See Also
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/index.d.ts
index efef24911f98..becc70e98334 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/index.d.ts
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/index.d.ts
@@ -20,7 +20,17 @@
 
 /// <reference types="@stdlib/types"/>
 
-import { NumericArray } from '@stdlib/types/array';
+import { NumericArray, Collection, AccessorArrayLike } from '@stdlib/types/array';
+
+/**
+* Input array.
+*/
+type InputArray = NumericArray | Collection<number> | AccessorArrayLike<number>;
+
+/**
+* Output array.
+*/
+type OutputArray = NumericArray | Collection<number> | AccessorArrayLike<number>;
 
 /**
 * Interface describing `cuminabs`.
@@ -31,9 +41,9 @@ interface Routine {
 	*
 	* @param N - number of indexed elements
 	* @param x - input array
-	* @param strideX - `x` stride length
+	* @param strideX - stride length for `x`
 	* @param y - output array
-	* @param strideY - `y` stride length
+	* @param strideY - stride length for `y`
 	* @returns output array
 	*
 	* @example
@@ -43,17 +53,17 @@ interface Routine {
 	* cuminabs( x.length, x, 1, y, 1 );
 	* // y => [ 1.0, 1.0, 1.0 ]
 	*/
-	( N: number, x: NumericArray, strideX: number, y: NumericArray, strideY: number ): NumericArray;
+	<T extends OutputArray>( N: number, x: InputArray, strideX: number, y: T, strideY: number ): T;
 
 	/**
 	* Computes the cumulative minimum absolute value of a strided array using alternative indexing semantics.
 	*
 	* @param N - number of indexed elements
 	* @param x - input array
-	* @param strideX - `x` stride length
+	* @param strideX - stride length for `x`
 	* @param offsetX - starting index for `x`
 	* @param y - output array
-	* @param strideY - `y` stride length
+	* @param strideY - stride length for `y`
 	* @param offsetY - starting index for `y`
 	* @returns output array
 	*
@@ -64,7 +74,7 @@ interface Routine {
 	* cuminabs.ndarray( x.length, x, 1, 0, y, 1, 0 );
 	* // y => [ 1.0, 1.0, 1.0 ]
 	*/
-	ndarray( N: number, x: NumericArray, strideX: number, offsetX: number, y: NumericArray, strideY: number, offsetY: number ): NumericArray;
+	ndarray<T extends OutputArray>( N: number, x: InputArray, strideX: number, offsetX: number, y: T, strideY: number, offsetY: number ): T;
 }
 
 /**
@@ -72,9 +82,9 @@ interface Routine {
 *
 * @param N - number of indexed elements
 * @param x - input array
-* @param strideX - `x` stride length
+* @param strideX - stride length for `x`
 * @param y - output array
-* @param strideY - `y` stride length
+* @param strideY - stride length for `y`
 * @returns output array
 *
 * @example
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/examples/index.js b/lib/node_modules/@stdlib/stats/base/cuminabs/examples/index.js
index 90ddc21deb45..86de6dd0e4c4 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/examples/index.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/examples/index.js
@@ -18,20 +18,14 @@
 
 'use strict';
 
-var randu = require( '@stdlib/random/base/randu' );
-var round = require( '@stdlib/math/base/special/round' );
 var Float64Array = require( '@stdlib/array/float64' );
+var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
 var cuminabs = require( './../lib' );
 
-var y;
-var x;
-var i;
-
-x = new Float64Array( 10 );
-y = new Float64Array( x.length );
-for ( i = 0; i < x.length; i++ ) {
-	x[ i ] = round( (randu()*100.0) - 50.0 );
-}
+var x = discreteUniform( 10, -50, 50, {
+	'dtype': 'float64'
+});
+var y = new Float64Array( x.length );
 console.log( x );
 console.log( y );
 
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/lib/accessors.js b/lib/node_modules/@stdlib/stats/base/cuminabs/lib/accessors.js
new file mode 100644
index 000000000000..c944a20f5a9c
--- /dev/null
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/lib/accessors.js
@@ -0,0 +1,110 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2025 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 abs = require( '@stdlib/math/base/special/abs' );
+
+
+// MAIN //
+
+/**
+* Computes the cumulative minimum absolute value of a strided array.
+*
+* @private
+* @param {PositiveInteger} N - number of indexed elements
+* @param {Object} x - input array object
+* @param {Collection} x.data - input array data
+* @param {Array<Function>} x.accessors - array element accessors
+* @param {integer} strideX - stride length for `x`
+* @param {NonNegativeInteger} offsetX - starting index for `x`
+* @param {Object} y - output array object
+* @param {Collection} y.data - output array data
+* @param {Array<Function>} y.accessors - array element accessors
+* @param {integer} strideY - stride length for `y`
+* @param {NonNegativeInteger} offsetY - starting index for `y`
+* @returns {Object} output array object
+*
+* @example
+* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
+* var arraylike2object = require( '@stdlib/array/base/arraylike2object' );
+*
+* var x = [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ];
+* var y = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ];
+*
+* cuminabs( 4, arraylike2object( toAccessorArray( x ) ), 2, 1, arraylike2object( toAccessorArray( y ) ), 1, 0 );
+* // y => [ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 ];
+*/
+function cuminabs( N, x, strideX, offsetX, y, strideY, offsetY ) {
+	var xbuf;
+	var ybuf;
+	var xget;
+	var yset;
+	var min;
+	var ix;
+	var iy;
+	var v;
+	var i;
+
+	// Cache references to array data:
+	xbuf = x.data;
+	ybuf = y.data;
+
+	// Cache references to element accessors:
+	xget = x.accessors[ 0 ];
+	yset = y.accessors[ 1 ];
+
+	ix = offsetX;
+	iy = offsetY;
+
+	min = abs( xget( xbuf, ix ) );
+	yset( ybuf, iy, min );
+
+	iy += strideY;
+	i = 1;
+	if ( isnan( min ) === false ) {
+		for ( i; i < N; i++ ) {
+			ix += strideX;
+			v = abs( xget( xbuf, ix ) );
+			if ( isnan( v ) ) {
+				min = v;
+				break;
+			}
+			if ( v < min ) {
+				min = v;
+			}
+			yset( ybuf, iy, min );
+			iy += strideY;
+		}
+	}
+	if ( isnan( min ) ) {
+		for ( i; i < N; i++ ) {
+			yset( ybuf, iy, min );
+			iy += strideY;
+		}
+	}
+	return y;
+}
+
+
+// EXPORTS //
+
+module.exports = cuminabs;
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/lib/main.js b/lib/node_modules/@stdlib/stats/base/cuminabs/lib/main.js
index 9b6dffe2ddf3..6503d1d5acc6 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/lib/main.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/lib/main.js
@@ -20,8 +20,8 @@
 
 // MODULES //
 
-var isnan = require( '@stdlib/math/base/assert/is-nan' );
-var abs = require( '@stdlib/math/base/special/abs' );
+var stride2offset = require( '@stdlib/strided/base/stride2offset' );
+var ndarray = require( './ndarray.js' );
 
 
 // MAIN //
@@ -31,9 +31,9 @@ var abs = require( '@stdlib/math/base/special/abs' );
 *
 * @param {PositiveInteger} N - number of indexed elements
 * @param {NumericArray} x - input array
-* @param {integer} strideX - `x` stride length
+* @param {integer} strideX - stride length for `x`
 * @param {NumericArray} y - output array
-* @param {integer} strideY - `y` stride length
+* @param {integer} strideY - stride length for `y`
 * @returns {NumericArray} output array
 *
 * @example
@@ -45,52 +45,9 @@ var abs = require( '@stdlib/math/base/special/abs' );
 * // returns [ 1.0, 1.0, 1.0 ]
 */
 function cuminabs( N, x, strideX, y, strideY ) {
-	var min;
-	var ix;
-	var iy;
-	var v;
-	var i;
-
-	if ( N <= 0 ) {
-		return y;
-	}
-	if ( strideX < 0 ) {
-		ix = (1-N) * strideX;
-	} else {
-		ix = 0;
-	}
-	if ( strideY < 0 ) {
-		iy = (1-N) * strideY;
-	} else {
-		iy = 0;
-	}
-	min = abs( x[ ix ] );
-	y[ iy ] = min;
-
-	iy += strideY;
-	i = 1;
-	if ( isnan( min ) === false ) {
-		for ( i; i < N; i++ ) {
-			ix += strideX;
-			v = abs( x[ ix ] );
-			if ( isnan( v ) ) {
-				min = v;
-				break;
-			}
-			if ( v < min ) {
-				min = v;
-			}
-			y[ iy ] = min;
-			iy += strideY;
-		}
-	}
-	if ( isnan( min ) ) {
-		for ( i; i < N; i++ ) {
-			y[ iy ] = min;
-			iy += strideY;
-		}
-	}
-	return y;
+	var ix = stride2offset( N, strideX );
+	var iy = stride2offset( N, strideY );
+	return ndarray( N, x, strideX, ix, y, strideY, iy );
 }
 
 
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/lib/ndarray.js b/lib/node_modules/@stdlib/stats/base/cuminabs/lib/ndarray.js
index 73ed1d9c851a..7970d017c29b 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/lib/ndarray.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/lib/ndarray.js
@@ -22,6 +22,8 @@
 
 var isnan = require( '@stdlib/math/base/assert/is-nan' );
 var abs = require( '@stdlib/math/base/special/abs' );
+var arraylike2object = require( '@stdlib/array/base/arraylike2object' );
+var accessors = require( './accessors.js' );
 
 
 // MAIN //
@@ -31,33 +33,38 @@ var abs = require( '@stdlib/math/base/special/abs' );
 *
 * @param {PositiveInteger} N - number of indexed elements
 * @param {NumericArray} x - input array
-* @param {integer} strideX - `x` stride length
+* @param {integer} strideX - stride length for `x`
 * @param {NonNegativeInteger} offsetX - starting index for `x`
 * @param {NumericArray} y - output array
-* @param {integer} strideY - `y` stride length
+* @param {integer} strideY - stride length for `y`
 * @param {NonNegativeInteger} offsetY - starting index for `y`
 * @returns {NumericArray} output array
 *
 * @example
-* var floor = require( '@stdlib/math/base/special/floor' );
-*
 * var x = [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ];
 * var y = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ];
-* var N = floor( x.length / 2 );
 *
-* var v = cuminabs( N, x, 2, 1, y, 1, 0 );
+* var v = cuminabs( 4, x, 2, 1, y, 1, 0 );
 * // returns [ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 ]
 */
 function cuminabs( N, x, strideX, offsetX, y, strideY, offsetY ) {
 	var min;
 	var ix;
 	var iy;
+	var ox;
+	var oy;
 	var v;
 	var i;
 
 	if ( N <= 0 ) {
 		return y;
 	}
+	ox = arraylike2object( x );
+	oy = arraylike2object( y );
+	if ( ox.accessorProtocol || oy.accessorProtocol ) {
+		accessors( N, ox, strideX, offsetX, oy, strideY, offsetY );
+		return y;
+	}
 	ix = offsetX;
 	iy = offsetY;
 


Test patch:
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/test.ts b/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/test.ts
index 6b6d7af70bf7..5ef54b1a9efb 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/test.ts
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/docs/types/test.ts
@@ -16,6 +16,7 @@
 * limitations under the License.
 */
 
+import AccessorArray = require( '@stdlib/array/base/accessor' );
 import cuminabs = require( './index' );
 
 
@@ -26,7 +27,8 @@ import cuminabs = require( './index' );
 	const x = new Float64Array( 10 );
 	const y = new Float64Array( 10 );
 
-	cuminabs( x.length, x, 1, y, 1 ); // $ExpectType NumericArray
+	cuminabs( x.length, x, 1, y, 1 ); // $ExpectType Float64Array
+	cuminabs( x.length, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType AccessorArray<number>
 }
 
 // The compiler throws an error if the function is provided a first argument which is not a number...
@@ -123,7 +125,8 @@ import cuminabs = require( './index' );
 	const x = new Float64Array( 10 );
 	const y = new Float64Array( 10 );
 
-	cuminabs.ndarray( x.length, x, 1, 0, y, 1, 0 ); // $ExpectType NumericArray
+	cuminabs.ndarray( x.length, x, 1, 0, y, 1, 0 ); // $ExpectType Float64Array
+	cuminabs.ndarray( x.length, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType AccessorArray<number>
 }
 
 // The compiler throws an error if the `ndarray` method is provided a first argument which is not a number...
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.main.js b/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.main.js
index 1924c34fe64a..b6453e2b2f0f 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.main.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.main.js
@@ -21,9 +21,9 @@
 // MODULES //
 
 var tape = require( 'tape' );
-var floor = require( '@stdlib/math/base/special/floor' );
 var isnan = require( '@stdlib/math/base/assert/is-nan' );
 var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
+var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
 var Float64Array = require( '@stdlib/array/float64' );
 var cuminabs = require( './../lib/main.js' );
 
@@ -109,6 +109,74 @@ tape( 'the function computes the cumulative minimum absolute value', function te
 	t.end();
 });
 
+tape( 'the function computes the cumulative minimum absolute value (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var i;
+
+	x = [ 1.0, -2.0, 3.0, -4.0, 5.0 ];
+	y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+
+	expected = [
+		1.0,
+		1.0,
+		1.0,
+		1.0,
+		1.0
+	];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	x = [ -0.0, 0.0, -0.0 ];
+	y = [ -0.0, -0.0, -0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+
+	expected = [
+		0.0,
+		0.0,
+		0.0
+	];
+	for ( i = 0; i < y.length; i++ ) {
+		t.strictEqual( isPositiveZero( y[ i ] ), true, 'returns expected value. i: ' + i );
+	}
+
+	x = [ NaN ];
+	y = [ 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+
+	for ( i = 0; i < y.length; i++ ) {
+		t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
+	}
+
+	x = [ NaN, NaN ];
+	y = [ 0.0, 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+
+	for ( i = 0; i < y.length; i++ ) {
+		t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
+	}
+
+	x = [ 1.0, NaN, 3.0, NaN ];
+	y = [ 0.0, 0.0, 0.0, 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+
+	expected = [
+		1.0,
+		NaN,
+		NaN,
+		NaN
+	];
+	for ( i = 0; i < y.length; i++ ) {
+		if ( isnan( expected[ i ] ) ) {
+			t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
+		} else {
+			t.strictEqual( y[ i ], expected[ i ], true, 'returns expected value. i: ' + i );
+		}
+	}
+	t.end();
+});
+
 tape( 'the function returns a reference to the output array', function test( t ) {
 	var out;
 	var x;
@@ -123,6 +191,20 @@ tape( 'the function returns a reference to the output array', function test( t )
 	t.end();
 });
 
+tape( 'the function returns a reference to the output array (accessors)', function test( t ) {
+	var out;
+	var x;
+	var y;
+
+	x = toAccessorArray( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
+	y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] );
+
+	out = cuminabs( x.length, x, 1, y, 1 );
+	t.strictEqual( out, y, 'same reference' );
+
+	t.end();
+});
+
 tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) {
 	var expected;
 	var x;
@@ -142,6 +224,25 @@ tape( 'if provided an `N` parameter less than or equal to `0`, the function retu
 	t.end();
 });
 
+tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+
+	x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ];
+	y = [ 6.0, 7.0, 8.0, 9.0, 10.0 ];
+
+	expected = [ 6.0, 7.0, 8.0, 9.0, 10.0 ];
+
+	cuminabs( -1, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+	t.deepEqual( y, expected, 'returns `y` unchanged' );
+
+	cuminabs( 0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
+	t.deepEqual( y, expected, 'returns `y` unchanged' );
+
+	t.end();
+});
+
 tape( 'the function supports an `x` stride', function test( t ) {
 	var expected;
 	var x;
@@ -172,6 +273,36 @@ tape( 'the function supports an `x` stride', function test( t ) {
 	t.end();
 });
 
+tape( 'the function supports an `x` stride (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var N;
+
+	x = [
+		1.0,  // 0
+		-2.0,
+		3.0,  // 1
+		4.0,
+		-5.0  // 2
+	];
+	y = [
+		0.0, // 0
+		0.0, // 1
+		0.0, // 2
+		0.0,
+		0.0
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), 2, toAccessorArray( y ), 1 );
+
+	expected = [ 1.0, 1.0, 1.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
 tape( 'the function supports a `y` stride', function test( t ) {
 	var expected;
 	var x;
@@ -202,6 +333,36 @@ tape( 'the function supports a `y` stride', function test( t ) {
 	t.end();
 });
 
+tape( 'the function supports a `y` stride (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var N;
+
+	x = [
+		1.0,  // 0
+		-2.0, // 1
+		3.0,  // 2
+		4.0,
+		5.0
+	];
+	y = [
+		0.0, // 0
+		0.0,
+		0.0, // 1
+		0.0,
+		0.0  // 2
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), 1, toAccessorArray( y ), 2 );
+
+	expected = [ 1.0, 0.0, 1.0, 0.0, 1.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
 tape( 'the function supports negative strides', function test( t ) {
 	var expected;
 	var x;
@@ -232,6 +393,36 @@ tape( 'the function supports negative strides', function test( t ) {
 	t.end();
 });
 
+tape( 'the function supports negative strides (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var N;
+
+	x = [
+		1.0,  // 2
+		-2.0,
+		3.0,  // 1
+		4.0,
+		-5.0  // 0
+	];
+	y = [
+		0.0, // 2
+		0.0, // 1
+		0.0, // 0
+		0.0,
+		0.0
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), -2, toAccessorArray( y ), -1 );
+
+	expected = [ 1.0, 3.0, 5.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
 tape( 'the function supports complex access patterns', function test( t ) {
 	var expected;
 	var x;
@@ -264,13 +455,44 @@ tape( 'the function supports complex access patterns', function test( t ) {
 	t.end();
 });
 
+tape( 'the function supports complex access patterns (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var N;
+
+	x = [
+		1.0,  // 0
+		2.0,
+		-3.0, // 1
+		4.0,
+		5.0,  // 2
+		6.0
+	];
+	y = [
+		0.0,  // 2
+		0.0,  // 1
+		0.0,  // 0
+		0.0,
+		0.0,
+		0.0
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), 2, toAccessorArray( y ), -1 );
+
+	expected = [ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
 tape( 'the function supports view offsets', function test( t ) {
 	var expected;
 	var x0;
 	var y0;
 	var x1;
 	var y1;
-	var N;
 
 	// Initial arrays...
 	x0 = new Float64Array([
@@ -294,9 +516,43 @@ tape( 'the function supports view offsets', function test( t ) {
 	x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // begin at 2nd element
 	y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // begin at the 4th element
 
-	N = floor( x0.length / 2 );
+	cuminabs( 3, x1, -2, y1, 1 );
+	expected = new Float64Array( [ 0.0, 0.0, 0.0, 6.0, 4.0, 2.0 ] );
+
+	t.deepEqual( y0, expected, 'returns expected value' );
+	t.end();
+});
+
+tape( 'the function supports view offsets (accessors)', function test( t ) {
+	var expected;
+	var x0;
+	var y0;
+	var x1;
+	var y1;
+
+	// Initial arrays...
+	x0 = new Float64Array([
+		1.0,
+		2.0, // 2
+		3.0,
+		4.0, // 1
+		5.0,
+		6.0  // 0
+	]);
+	y0 = new Float64Array([
+		0.0,
+		0.0,
+		0.0,
+		0.0, // 0
+		0.0, // 1
+		0.0  // 2
+	]);
+
+	// Create offset views...
+	x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // begin at 2nd element
+	y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // begin at the 4th element
 
-	cuminabs( N, x1, -2, y1, 1 );
+	cuminabs( 3, toAccessorArray( x1 ), -2, toAccessorArray( y1 ), 1 );
 	expected = new Float64Array( [ 0.0, 0.0, 0.0, 6.0, 4.0, 2.0 ] );
 
 	t.deepEqual( y0, expected, 'returns expected value' );
diff --git a/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.ndarray.js b/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.ndarray.js
index 188e85d243a7..ac8367cadabe 100644
--- a/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.ndarray.js
+++ b/lib/node_modules/@stdlib/stats/base/cuminabs/test/test.ndarray.js
@@ -21,8 +21,8 @@
 // MODULES //
 
 var tape = require( 'tape' );
-var floor = require( '@stdlib/math/base/special/floor' );
 var isnan = require( '@stdlib/math/base/assert/is-nan' );
+var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
 var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
 var cuminabs = require( './../lib/ndarray.js' );
 
@@ -108,6 +108,74 @@ tape( 'the function calculates the cumulative minimum absolute value', function
 	t.end();
 });
 
+tape( 'the function computes the cumulative minimum absolute value (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var i;
+
+	x = [ 1.0, -2.0, 3.0, -4.0, 5.0 ];
+	y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); // eslint-disable-line max-len
+
+	expected = [
+		1.0,
+		1.0,
+		1.0,
+		1.0,
+		1.0
+	];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	x = [ -0.0, 0.0, -0.0 ];
+	y = [ -0.0, -0.0, -0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); // eslint-disable-line max-len
+
+	expected = [
+		0.0,
+		0.0,
+		0.0
+	];
+	for ( i = 0; i < y.length; i++ ) {
+		t.strictEqual( isPositiveZero( y[ i ] ), true, 'returns expected value. i: ' + i );
+	}
+
+	x = [ NaN ];
+	y = [ 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); // eslint-disable-line max-len
+
+	for ( i = 0; i < y.length; i++ ) {
+		t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
+	}
+
+	x = [ NaN, NaN ];
+	y = [ 0.0, 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); // eslint-disable-line max-len
+
+	for ( i = 0; i < y.length; i++ ) {
+		t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
+	}
+
+	x = [ 1.0, NaN, 3.0, NaN ];
+	y = [ 0.0, 0.0, 0.0, 0.0 ];
+	cuminabs( x.length, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); // eslint-disable-line max-len
+
+	expected = [
+		1.0,
+		NaN,
+		NaN,
+		NaN
+	];
+	for ( i = 0; i < y.length; i++ ) {
+		if ( isnan( expected[ i ] ) ) {
+			t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
+		} else {
+			t.strictEqual( y[ i ], expected[ i ], true, 'returns expected value. i: ' + i );
+		}
+	}
+	t.end();
+});
+
 tape( 'the function returns a reference to the output array', function test( t ) {
 	var out;
 	var x;
@@ -122,6 +190,20 @@ tape( 'the function returns a reference to the output array', function test( t )
 	t.end();
 });
 
+tape( 'the function returns a reference to the output array (accessors)', function test( t ) {
+	var out;
+	var x;
+	var y;
+
+	x = toAccessorArray( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
+	y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] );
+
+	out = cuminabs( x.length, x, 1, 0, y, 1, 0 );
+	t.strictEqual( out, y, 'same reference' );
+
+	t.end();
+});
+
 tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) {
 	var expected;
 	var x;
@@ -141,6 +223,25 @@ tape( 'if provided an `N` parameter less than or equal to `0`, the function retu
 	t.end();
 });
 
+tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+
+	x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ];
+	y = [ 6.0, 7.0, 8.0, 9.0, 10.0 ];
+
+	expected = [ 6.0, 7.0, 8.0, 9.0, 10.0 ];
+
+	cuminabs( -1, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 );
+	t.deepEqual( y, expected, 'returns `y` unchanged' );
+
+	cuminabs( 0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 );
+	t.deepEqual( y, expected, 'returns `y` unchanged' );
+
+	t.end();
+});
+
 tape( 'the function supports an `x` stride', function test( t ) {
 	var expected;
 	var x;
@@ -171,6 +272,36 @@ tape( 'the function supports an `x` stride', function test( t ) {
 	t.end();
 });
 
+tape( 'the function supports an `x` stride (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var N;
+
+	x = [
+		1.0,  // 0
+		-2.0,
+		3.0,  // 1
+		4.0,
+		-5.0  // 2
+	];
+	y = [
+		0.0, // 0
+		0.0, // 1
+		0.0, // 2
+		0.0,
+		0.0
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), 2, 0, toAccessorArray( y ), 1, 0 );
+
+	expected = [ 1.0, 1.0, 1.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
 tape( 'the function supports a `y` stride', function test( t ) {
 	var expected;
 	var x;
@@ -201,6 +332,36 @@ tape( 'the function supports a `y` stride', function test( t ) {
 	t.end();
 });
 
+tape( 'the function supports a `y` stride (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+	var N;
+
+	x = [
+		1.0,  // 0
+		-2.0, // 1
+		3.0,  // 2
+		4.0,
+		5.0
+	];
+	y = [
+		0.0, // 0
+		0.0,
+		0.0, // 1
+		0.0,
+		0.0  // 2
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 2, 0 );
+
+	expected = [ 1.0, 0.0, 1.0, 0.0, 1.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
 tape( 'the function supports negative strides', function test( t ) {
 	var expected;
 	var x;
@@ -231,9 +392,72 @@ tape( 'the function supports negative strides', function test( t ) {
 	t.end();
 });
 
-tape( 'the function supports an `x` offset', function test( t ) {
+tape( 'the function supports negative strides (accessors)', function test( t ) {
 	var expected;
+	var x;
+	var y;
 	var N;
+
+	x = [
+		1.0,  // 2
+		-2.0,
+		3.0,  // 1
+		4.0,
+		-5.0  // 0
+	];
+	y = [
+		0.0, // 2
+		0.0, // 1
+		0.0, // 0
+		0.0,
+		0.0
+	];
+	N = 3;
+
+	cuminabs( N, toAccessorArray( x ), -2, x.length-1, toAccessorArray( y ), -1, 2 ); // eslint-disable-line max-len
+
+	expected = [ 1.0, 3.0, 5.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
+tape( 'the function supports an `x` offset', function test( t ) {
+	var expected;
+	var x;
+	var y;
+
+	x = [
+		2.0,
+		1.0,  // 0
+		2.0,
+		-2.0, // 1
+		-2.0,
+		2.0,  // 2
+		3.0,
+		4.0   // 3
+	];
+	y = [
+		0.0, // 0
+		0.0, // 1
+		0.0, // 2
+		0.0, // 3
+		0.0,
+		0.0,
+		0.0,
+		0.0
+	];
+
+	cuminabs( 4, x, 2, 1, y, 1, 0 );
+
+	expected = [ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
+tape( 'the function supports an `x` offset (accessors)', function test( t ) {
+	var expected;
 	var x;
 	var y;
 
@@ -257,9 +481,8 @@ tape( 'the function supports an `x` offset', function test( t ) {
 		0.0,
 		0.0
 	];
-	N = floor( x.length / 2 );
 
-	cuminabs( N, x, 2, 1, y, 1, 0 );
+	cuminabs( 4, toAccessorArray( x ), 2, 1, toAccessorArray( y ), 1, 0 );
 
 	expected = [ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 ];
 	t.deepEqual( y, expected, 'returns expected value' );
@@ -269,7 +492,6 @@ tape( 'the function supports an `x` offset', function test( t ) {
 
 tape( 'the function supports a `y` offset', function test( t ) {
 	var expected;
-	var N;
 	var x;
 	var y;
 
@@ -293,9 +515,42 @@ tape( 'the function supports a `y` offset', function test( t ) {
 		0.0,
 		0.0  // 3
 	];
-	N = floor( x.length / 2 );
 
-	cuminabs( N, x, 1, 0, y, 2, 1 );
+	cuminabs( 4, x, 1, 0, y, 2, 1 );
+
+	expected = [ 0.0, 2.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
+tape( 'the function supports a `y` offset (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+
+	x = [
+		2.0,  // 0
+		1.0,  // 1
+		2.0,  // 2
+		-2.0, // 3
+		-2.0,
+		2.0,
+		3.0,
+		4.0
+	];
+	y = [
+		0.0,
+		0.0, // 0
+		0.0,
+		0.0, // 1
+		0.0,
+		0.0, // 2
+		0.0,
+		0.0  // 3
+	];
+
+	cuminabs( 4, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 2, 1 );
 
 	expected = [ 0.0, 2.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 ];
 	t.deepEqual( y, expected, 'returns expected value' );
@@ -307,7 +562,6 @@ tape( 'the function supports complex access patterns', function test( t ) {
 	var expected;
 	var x;
 	var y;
-	var N;
 
 	x = [
 		1.0,  // 0
@@ -325,9 +579,38 @@ tape( 'the function supports complex access patterns', function test( t ) {
 		0.0,
 		0.0
 	];
-	N = 3;
 
-	cuminabs( N, x, 2, 0, y, -1, 2 );
+	cuminabs( 3, x, 2, 0, y, -1, 2 );
+
+	expected = [ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 ];
+	t.deepEqual( y, expected, 'returns expected value' );
+
+	t.end();
+});
+
+tape( 'the function supports complex access patterns (accessors)', function test( t ) {
+	var expected;
+	var x;
+	var y;
+
+	x = [
+		1.0,  // 0
+		2.0,
+		-3.0, // 1
+		4.0,
+		5.0,  // 2
+		6.0
+	];
+	y = [
+		0.0,  // 2
+		0.0,  // 1
+		0.0,  // 0
+		0.0,
+		0.0,
+		0.0
+	];
+
+	cuminabs( 3, toAccessorArray( x ), 2, 0, toAccessorArray( y ), -1, 2 );
 
 	expected = [ 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 ];
 	t.deepEqual( y, expected, 'returns expected value' );