From 1b82b7ea3313f6e41b20050a14ec90b715ddb867 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Thu, 1 Oct 2026 15:27:56 +0500 Subject: [PATCH 1/3] feat: add ndarray/base/kernels/generic/quaternary/dispatch --- .../generic/quaternary/dispatch/README.md | 179 ++++++++++ .../generic/quaternary/dispatch/docs/repl.txt | 105 ++++++ .../quaternary/dispatch/examples/index.js | 70 ++++ .../generic/quaternary/dispatch/lib/index.js | 74 ++++ .../generic/quaternary/dispatch/lib/main.js | 322 ++++++++++++++++++ .../generic/quaternary/dispatch/package.json | 63 ++++ .../generic/quaternary/dispatch/test/test.js | 316 +++++++++++++++++ 7 files changed, 1129 insertions(+) create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/package.json create mode 100644 lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md new file mode 100644 index 000000000000..f3e721f59352 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md @@ -0,0 +1,179 @@ + + +# dispatch + +> Apply a quaternary callback to elements in four input ndarrays and assign results to elements in an output ndarray. + +
+ +
+ + + +
+ +## Usage + +```javascript +var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatch' ); +``` + +#### dispatch( arrays, fcn ) + +Applies a quaternary callback to elements in four input ndarrays and assigns results to elements in an output ndarray. + +```javascript +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var getData = require( '@stdlib/ndarray/data-buffer' ); + +function add4( a, b, c, d ) { + return a + b + c + d; +} + +// Create data buffers: +var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +var zbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +var wbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +var ubuf = new Float64Array( 6 ); + +// Define the shape of the input and output arrays: +var shape = [ 3, 1, 2 ]; + +// Define the array strides: +var sx = [ 2, 2, 1 ]; +var sy = [ 2, 2, 1 ]; +var sz = [ 2, 2, 1 ]; +var sw = [ 2, 2, 1 ]; +var su = [ 2, 2, 1 ]; + +// Create the input and output ndarrays: +var x = ndarray( 'float64', xbuf, shape, sx, 0, 'row-major' ); +var y = ndarray( 'float64', ybuf, shape, sy, 0, 'row-major' ); +var z = ndarray( 'float64', zbuf, shape, sz, 0, 'row-major' ); +var w = ndarray( 'float64', wbuf, shape, sw, 0, 'row-major' ); +var u = ndarray( 'float64', ubuf, shape, su, 0, 'row-major' ); + +// Apply the quaternary callback: +dispatch( [ x, y, z, w, u ], add4 ); + +var v = getData( u ); +// returns [ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0 ] +``` + +The function accepts the following arguments: + +- **arrays**: array-like object containing four input ndarrays and one output ndarray. +- **fcn**: quaternary callback accepting four scalar values and returning one scalar value. + +
+ + + +
+ +## Notes + +- Each provided ndarray should be an object with the following properties: + + - **dtype**: data type. + - **data**: data buffer. + - **shape**: dimensions. + - **strides**: stride lengths. + - **offset**: index offset. + - **order**: specifies whether an ndarray is row-major (C-style) or column-major (Fortran-style). + +- The function dispatches to the most efficient kernel based on array contiguity, memory layout, and dimensionality. + +
+ + + +
+ +## Examples + + + +```javascript +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +var getData = require( '@stdlib/ndarray/data-buffer' ); +var getShape = require( '@stdlib/ndarray/shape' ); +var getStrides = require( '@stdlib/ndarray/strides' ); +var getOffset = require( '@stdlib/ndarray/offset' ); +var getOrder = require( '@stdlib/ndarray/order' ); +var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatch' ); + +function add4( a, b, c, d ) { + return a + b + c + d; +} + +// Create data buffers: +var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +var zbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +var wbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +var ubuf = new Float64Array( 6 ); + +// Define the shape of the input and output arrays: +var shape = [ 3, 1, 2 ]; + +// Define the array strides: +var sx = [ 2, 2, 1 ]; +var sy = [ 2, 2, 1 ]; +var sz = [ 2, 2, 1 ]; +var sw = [ 2, 2, 1 ]; +var su = [ 2, 2, 1 ]; + +// Create the input and output ndarrays: +var x = ndarray( 'float64', xbuf, shape, sx, 0, 'row-major' ); +var y = ndarray( 'float64', ybuf, shape, sy, 0, 'row-major' ); +var z = ndarray( 'float64', zbuf, shape, sz, 0, 'row-major' ); +var w = ndarray( 'float64', wbuf, shape, sw, 0, 'row-major' ); +var u = ndarray( 'float64', ubuf, shape, su, 0, 'row-major' ); + +// Apply the quaternary callback: +dispatch( [ x, y, z, w, u ], add4 ); + +console.log( ndarray2array( getData( u ), getShape( u ), getStrides( u ), getOffset( u ), getOrder( u ) ) ); +// => [ [ [ 4.0, 6.0 ] ], [ [ 8.0, 10.0 ] ], [ [ 12.0, 14.0 ] ] ] +``` + +
+ + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt new file mode 100644 index 000000000000..0e3e95d40172 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt @@ -0,0 +1,105 @@ + +{{alias}}( arrays, fcn ) + Applies a quaternary callback to elements in four input ndarrays and + assigns results to elements in an output ndarray. + + Each provided ndarray should be an object with the following properties: + + - dtype: data type. + - data: data buffer. + - shape: dimensions. + - strides: stride lengths. + - offset: index offset. + - order: specifies whether an ndarray is row-major (C-style) or column- + major (Fortran-style). + + Parameters + ---------- + arrays: ArrayLikeObject + Array-like object containing four input ndarray-like objects and one + output ndarray-like object. + + fcn: Function + Quaternary callback accepting four scalar values and returning one + scalar value. + + Examples + -------- + // Define ndarray data and meta data... + > var xbuf = new {{alias:@stdlib/array/float64}}( [ 1.0, 2.0, 3.0, 4.0 ] ); + > var ybuf = new {{alias:@stdlib/array/float64}}( [ 5.0, 6.0, 7.0, 8.0 ] ); + > var zbuf = new {{alias:@stdlib/array/float64}}( [ 1.0, 1.0, 1.0, 1.0 ] ); + > var wbuf = new {{alias:@stdlib/array/float64}}( [ 1.0, 1.0, 1.0, 1.0 ] ); + > var ubuf = new {{alias:@stdlib/array/float64}}( 4 ); + > var dtype = 'float64'; + > var shape = [ 2, 2 ]; + > var sx = [ 2, 1 ]; + > var sy = [ 2, 1 ]; + > var sz = [ 2, 1 ]; + > var sw = [ 2, 1 ]; + > var su = [ 2, 1 ]; + > var ox = 0; + > var oy = 0; + > var oz = 0; + > var ow = 0; + > var ou = 0; + > var order = 'row-major'; + + // Using ndarrays... + > var x = {{alias:@stdlib/ndarray/ctor}}( dtype, xbuf, shape, sx, ox, order ); + > var y = {{alias:@stdlib/ndarray/ctor}}( dtype, ybuf, shape, sy, oy, order ); + > var z = {{alias:@stdlib/ndarray/ctor}}( dtype, zbuf, shape, sz, oz, order ); + > var w = {{alias:@stdlib/ndarray/ctor}}( dtype, wbuf, shape, sw, ow, order ); + > var u = {{alias:@stdlib/ndarray/ctor}}( dtype, ubuf, shape, su, ou, order ); + > {{alias}}( [ x, y, z, w, u ], {{alias:@stdlib/number/float64/base/add4}} ); + > {{alias:@stdlib/ndarray/data-buffer}}( u ) + [ 8.0, 10.0, 12.0, 14.0 ] + + // Using minimal ndarray-like objects... + > x = { + ... 'dtype': dtype, + ... 'data': xbuf, + ... 'shape': shape, + ... 'strides': sx, + ... 'offset': ox, + ... 'order': order + ... }; + > y = { + ... 'dtype': dtype, + ... 'data': ybuf, + ... 'shape': shape, + ... 'strides': sy, + ... 'offset': oy, + ... 'order': order + ... }; + > z = { + ... 'dtype': dtype, + ... 'data': zbuf, + ... 'shape': shape, + ... 'strides': sz, + ... 'offset': oz, + ... 'order': order + ... }; + > w = { + ... 'dtype': dtype, + ... 'data': wbuf, + ... 'shape': shape, + ... 'strides': sw, + ... 'offset': ow, + ... 'order': order + ... }; + > u = { + ... 'dtype': dtype, + ... 'data': ubuf, + ... 'shape': shape, + ... 'strides': su, + ... 'offset': ou, + ... 'order': order + ... }; + > {{alias}}( [ x, y, z, w, u ], {{alias:@stdlib/number/float64/base/add4}} ); + > {{alias:@stdlib/ndarray/data-buffer}}( u ) + [ 8.0, 10.0, 12.0, 14.0 ] + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js new file mode 100644 index 000000000000..e10a7e3417ff --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js @@ -0,0 +1,70 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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 Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +var getData = require( '@stdlib/ndarray/data-buffer' ); +var getShape = require( '@stdlib/ndarray/shape' ); +var getStrides = require( '@stdlib/ndarray/strides' ); +var getOffset = require( '@stdlib/ndarray/offset' ); +var getOrder = require( '@stdlib/ndarray/order' ); +var dispatch = require( './../lib' ); + +function add4( a, b, c, d ) { + return a + b + c + d; +} + +// Create data buffers: +var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +var zbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +var wbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +var ubuf = new Float64Array( 6 ); + +// Define the shape of the input and output arrays: +var shape = [ 3, 1, 2 ]; + +// Define the array strides: +var sx = [ 2, 2, 1 ]; +var sy = [ 2, 2, 1 ]; +var sz = [ 2, 2, 1 ]; +var sw = [ 2, 2, 1 ]; +var su = [ 2, 2, 1 ]; + +// Define the index offsets: +var ox = 0; +var oy = 0; +var oz = 0; +var ow = 0; +var ou = 0; + +// Create the input and output ndarrays: +var x = ndarray( 'float64', xbuf, shape, sx, ox, 'row-major' ); +var y = ndarray( 'float64', ybuf, shape, sy, oy, 'row-major' ); +var z = ndarray( 'float64', zbuf, shape, sz, oz, 'row-major' ); +var w = ndarray( 'float64', wbuf, shape, sw, ow, 'row-major' ); +var u = ndarray( 'float64', ubuf, shape, su, ou, 'row-major' ); + +// Apply the quaternary callback: +dispatch( [ x, y, z, w, u ], add4 ); + +console.log( ndarray2array( getData( u ), getShape( u ), getStrides( u ), getOffset( u ), getOrder( u ) ) ); +// => [ [ [ 4.0, 6.0 ] ], [ [ 8.0, 10.0 ] ], [ [ 12.0, 14.0 ] ] ] diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js new file mode 100644 index 000000000000..459dffe83723 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js @@ -0,0 +1,74 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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'; + +/** +* Apply a quaternary callback to elements in four input ndarrays and assign results to elements in an output ndarray. +* +* @module @stdlib/ndarray/base/kernels/generic/quaternary/dispatch +* +* @example +* var Float64Array = require( '@stdlib/array/float64' ); +* var ndarray = require( '@stdlib/ndarray/ctor' ); +* var getData = require( '@stdlib/ndarray/data-buffer' ); +* var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatch' ); +* +* function add4( a, b, c, d ) { +* return a + b + c + d; +* } +* +* // Create data buffers: +* var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +* var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +* var zbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +* var wbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +* var ubuf = new Float64Array( 6 ); +* +* // Define the shape of the input and output arrays: +* var shape = [ 3, 1, 2 ]; +* +* // Define the array strides: +* var sx = [ 2, 2, 1 ]; +* var sy = [ 2, 2, 1 ]; +* var sz = [ 2, 2, 1 ]; +* var sw = [ 2, 2, 1 ]; +* var su = [ 2, 2, 1 ]; +* +* // Create the input and output ndarrays: +* var x = ndarray( 'float64', xbuf, shape, sx, 0, 'row-major' ); +* var y = ndarray( 'float64', ybuf, shape, sy, 0, 'row-major' ); +* var z = ndarray( 'float64', zbuf, shape, sz, 0, 'row-major' ); +* var w = ndarray( 'float64', wbuf, shape, sw, 0, 'row-major' ); +* var u = ndarray( 'float64', ubuf, shape, su, 0, 'row-major' ); +* +* // Apply the quaternary callback: +* dispatch( [ x, y, z, w, u ], add4 ); +* +* console.log( getData( u ) ); +* // => [ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0 ] +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js new file mode 100644 index 000000000000..2668a9478b7f --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js @@ -0,0 +1,322 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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. +*/ + +/* eslint-disable max-statements, max-lines-per-function */ + +'use strict'; + +// MODULES // + +var iterationOrder = require( '@stdlib/ndarray/base/iteration-order' ); +var minmaxViewBufferIndex = require( '@stdlib/ndarray/base/minmax-view-buffer-index' ); +var ndarray2object = require( '@stdlib/ndarray/base/ndarraylike2object' ); +var strides2order = require( '@stdlib/ndarray/base/strides2order' ); +var format = require( '@stdlib/string/format' ); +var unblocked = require( '@stdlib/ndarray/base/kernels/generic/quaternary/unblocked' ); +var blocked = require( '@stdlib/ndarray/base/kernels/generic/quaternary/blocked' ); +var linear = require( '@stdlib/ndarray/base/kernels/generic/quaternary/linear' ); + + +// VARIABLES // + +var MAX_DIMS = 10; + + +// MAIN // + +/** +* Applies a quaternary callback to elements in four input ndarrays and assigns results to elements in an output ndarray. +* +* ## Notes +* +* - Each provided ndarray should be an object with the following properties: +* +* - **dtype**: data type. +* - **data**: data buffer. +* - **shape**: dimensions. +* - **strides**: stride lengths. +* - **offset**: index offset. +* - **order**: specifies whether an ndarray is row-major (C-style) or column major (Fortran-style). +* +* @param {ArrayLikeObject} arrays - array-like object containing four input arrays and one output array +* @param {Callback} fcn - quaternary callback +* @throws {Error} arrays must have the same number of dimensions +* @throws {Error} arrays must have the same shape +* @returns {void} +* +* @example +* var Float64Array = require( '@stdlib/array/float64' ); +* var ndarray = require( '@stdlib/ndarray/ctor' ); +* var getData = require( '@stdlib/ndarray/data-buffer' ); +* +* function add4( a, b, c, d ) { +* return a + b + c + d; +* } +* +* // Create data buffers: +* var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +* var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); +* var zbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +* var wbuf = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ); +* var ubuf = new Float64Array( 6 ); +* +* // Define the shape of the input and output arrays: +* var shape = [ 3, 1, 2 ]; +* +* // Define the array strides: +* var sx = [ 2, 2, 1 ]; +* var sy = [ 2, 2, 1 ]; +* var sz = [ 2, 2, 1 ]; +* var sw = [ 2, 2, 1 ]; +* var su = [ 2, 2, 1 ]; +* +* // Create the input and output ndarrays: +* var x = ndarray( 'float64', xbuf, shape, sx, 0, 'row-major' ); +* var y = ndarray( 'float64', ybuf, shape, sy, 0, 'row-major' ); +* var z = ndarray( 'float64', zbuf, shape, sz, 0, 'row-major' ); +* var w = ndarray( 'float64', wbuf, shape, sw, 0, 'row-major' ); +* var u = ndarray( 'float64', ubuf, shape, su, 0, 'row-major' ); +* +* // Apply the quaternary callback: +* dispatch( [ x, y, z, w, u ], add4 ); +* +* var v = getData( u ); +* // returns [ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0 ] +*/ +function dispatch( arrays, fcn ) { + var ndims; + var xmmv; + var ymmv; + var zmmv; + var wmmv; + var ummv; + var shx; + var shy; + var shz; + var shw; + var shu; + var iox; + var ioy; + var ioz; + var iow; + var iou; + var len; + var ord; + var sx; + var sy; + var sz; + var sw; + var su; + var ox; + var oy; + var oz; + var ow; + var ou; + var ns; + var x; + var y; + var z; + var w; + var u; + var d; + var f; + var i; + + // Unpack the ndarrays and standardize ndarray meta data: + x = ndarray2object( arrays[ 0 ] ); + y = ndarray2object( arrays[ 1 ] ); + z = ndarray2object( arrays[ 2 ] ); + w = ndarray2object( arrays[ 3 ] ); + u = ndarray2object( arrays[ 4 ] ); + + // Verify that the input and output arrays have the same number of dimensions... + shx = x.shape; + shy = y.shape; + shz = z.shape; + shw = w.shape; + shu = u.shape; + ndims = shx.length; + if ( + ndims !== shy.length || + ndims !== shz.length || + ndims !== shw.length || + ndims !== shu.length + ) { + throw new Error( format( 'invalid arguments. Arrays must have the same number of dimensions (i.e., same rank). ndims(x) == %d. ndims(y) == %d. ndims(z) == %d. ndims(w) == %d. ndims(u) == %d.', ndims, shy.length, shz.length, shw.length, shu.length ) ); + } + // Determine whether we can avoid iteration altogether... + if ( ndims === 0 ) { + f = unblocked( ndims ); + return f( x, y, z, w, u, fcn ); + } + // Verify that the input and output arrays have the same dimensions... + len = 1; // number of elements + ns = 0; // number of singleton dimensions + for ( i = 0; i < ndims; i++ ) { + d = shx[ i ]; + if ( d !== shy[ i ] || d !== shz[ i ] || d !== shw[ i ] || d !== shu[ i ] ) { // eslint-disable-line max-len + throw new Error( 'invalid arguments. Arrays must have the same shape.' ); + } + // Note that, if one of the dimensions is `0`, the length will be `0`... + len *= d; + + // Check whether the current dimension is a singleton dimension... + if ( d === 1 ) { + ns += 1; + } + } + // Check whether we were provided empty ndarrays... + if ( len === 0 ) { + return; + } + // Determine whether the ndarrays are one-dimensional and thus readily translate to one-dimensional strided arrays... + if ( ndims === 1 ) { + f = unblocked( 1 ); + return f( x, y, z, w, u, fcn ); + } + sx = x.strides; + sy = y.strides; + sz = z.strides; + sw = w.strides; + su = u.strides; + + // Determine whether the ndarrays have only **one** non-singleton dimension (e.g., ndims=4, shape=[10,1,1,1]) so that we can treat the ndarrays as being equivalent to one-dimensional strided arrays... + if ( ns === ndims-1 ) { + // Get the index of the non-singleton dimension... + for ( i = 0; i < ndims; i++ ) { + if ( shx[ i ] !== 1 ) { + break; + } + } + x.shape = [ shx[i] ]; + y.shape = x.shape; + z.shape = x.shape; + w.shape = x.shape; + u.shape = x.shape; + x.strides = [ sx[i] ]; + y.strides = [ sy[i] ]; + z.strides = [ sz[i] ]; + w.strides = [ sw[i] ]; + u.strides = [ su[i] ]; + f = unblocked( 1 ); + return f( x, y, z, w, u, fcn ); + } + iox = iterationOrder( sx ); // +/-1 + ioy = iterationOrder( sy ); // +/-1 + ioz = iterationOrder( sz ); // +/-1 + iow = iterationOrder( sw ); // +/-1 + iou = iterationOrder( su ); // +/-1 + + // Determine whether we can avoid blocked iteration... + ord = strides2order( sx ); + if ( + iox !== 0 && + ioy !== 0 && + ioz !== 0 && + iow !== 0 && + iou !== 0 && + ord === strides2order( sy ) && + ord === strides2order( sz ) && + ord === strides2order( sw ) && + ord === strides2order( su ) + ) { + // Determine the minimum and maximum linear indices which are accessible by the array views: + xmmv = minmaxViewBufferIndex( shx, sx, x.offset ); + ymmv = minmaxViewBufferIndex( shy, sy, y.offset ); + zmmv = minmaxViewBufferIndex( shz, sz, z.offset ); + wmmv = minmaxViewBufferIndex( shw, sw, w.offset ); + ummv = minmaxViewBufferIndex( shu, su, u.offset ); + + // Determine whether we can ignore shape (and strides) and treat the ndarrays as linear one-dimensional strided arrays... + if ( + len === ( xmmv[1]-xmmv[0]+1 ) && + len === ( ymmv[1]-ymmv[0]+1 ) && + len === ( zmmv[1]-zmmv[0]+1 ) && + len === ( wmmv[1]-wmmv[0]+1 ) && + len === ( ummv[1]-ummv[0]+1 ) + ) { + // Note: the above is equivalent to @stdlib/ndarray/base/assert/is-contiguous, but in-lined so we can retain computed values... + if ( iox === 1 ) { + ox = xmmv[ 0 ]; + } else { + ox = xmmv[ 1 ]; + } + if ( ioy === 1 ) { + oy = ymmv[ 0 ]; + } else { + oy = ymmv[ 1 ]; + } + if ( ioz === 1 ) { + oz = zmmv[ 0 ]; + } else { + oz = zmmv[ 1 ]; + } + if ( iow === 1 ) { + ow = wmmv[ 0 ]; + } else { + ow = wmmv[ 1 ]; + } + if ( iou === 1 ) { + ou = ummv[ 0 ]; + } else { + ou = ummv[ 1 ]; + } + x.shape = [ len ]; + y.shape = x.shape; + z.shape = x.shape; + w.shape = x.shape; + u.shape = x.shape; + x.strides = [ iox ]; + y.strides = [ ioy ]; + z.strides = [ ioz ]; + w.strides = [ iow ]; + u.strides = [ iou ]; + x.offset = ox; + y.offset = oy; + z.offset = oz; + w.offset = ow; + u.offset = ou; + f = unblocked( 1 ); + return f( x, y, z, w, u, fcn ); + } + // At least one ndarray is non-contiguous, so we cannot directly use one-dimensional array functionality... + + // Determine whether we can use simple nested loops... + if ( ndims <= MAX_DIMS ) { + // So long as iteration for each respective array always moves in the same direction (i.e., no mixed sign strides), we can leverage cache-optimal (i.e., normal) nested loops without resorting to blocked iteration... + f = unblocked( ndims ); + return f( x, y, z, w, u, ord === 1, fcn ); + } + // Fall-through to blocked iteration... + } + // At this point, we're either dealing with non-contiguous n-dimensional arrays, high dimensional n-dimensional arrays, and/or arrays having differing memory layouts, so our only hope is that we can still perform blocked iteration... + + // Determine whether we can perform blocked iteration... + if ( ndims <= MAX_DIMS ) { + f = blocked( ndims ); + return f( x, y, z, w, u, fcn ); + } + // Fall-through to linear view iteration without regard for how data is stored in memory (i.e., take the slow path)... + f = linear(); + return f( x, y, z, w, u, fcn ); +} + + +// EXPORTS // + +module.exports = dispatch; diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/package.json b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/package.json new file mode 100644 index 000000000000..6c7786ad62c7 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/package.json @@ -0,0 +1,63 @@ +{ + "name": "@stdlib/ndarray/base/kernels/generic/quaternary/dispatch", + "version": "0.0.0", + "description": "Apply a quaternary callback to elements in four input ndarrays and assign results to elements in an output ndarray.", + "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": { + "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", + "base", + "ndarray", + "quaternary", + "dispatch", + "apply", + "element-wise", + "elementwise", + "callback", + "kernel" + ], + "__stdlib__": {} +} diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js new file mode 100644 index 000000000000..dbe8867c5969 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js @@ -0,0 +1,316 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 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. +*/ + +/* eslint-disable max-len */ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isSameFloat64Array = require( '@stdlib/assert/is-same-float64array' ); +var Float64Array = require( '@stdlib/array/float64' ); +var ndarray = require( '@stdlib/ndarray/ctor' ); +var scalar2ndarray = require( '@stdlib/ndarray/from-scalar' ); +var zeros = require( '@stdlib/array/zeros' ); +var ones = require( '@stdlib/array/ones' ); +var oneTo = require( '@stdlib/array/one-to' ); +var shape2strides = require( '@stdlib/ndarray/base/shape2strides' ); +var strides2offset = require( '@stdlib/ndarray/base/strides2offset' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var getData = require( '@stdlib/ndarray/data-buffer' ); +var add4 = require( '@stdlib/number/float64/base/add4' ); +var dispatch = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof dispatch, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if provided input and output ndarrays which do not have the same number of dimensions', function test( t ) { + var shapes; + var i; + + shapes = [ + [ [ 4, 2, 1 ], [ 4, 2, 1 ], [ 4, 2, 1 ], [ 4, 2, 1 ], [ 4, 2 ] ], + [ [ 2, 2 ], [ 2, 2, 2 ], [ 2, 2, 2 ], [ 2, 2, 2 ], [ 2, 2, 2 ] ], + [ [ 1, 1, 1, 1 ], [ 1, 1, 1 ], [ 1, 1, 1 ], [ 1, 1 ], [ 1, 1 ] ], + [ [ 2, 2, 1, 2 ], [ 2, 2, 1 ], [ 2, 2, 1 ], [ 2, 1, 2 ], [ 2, 1, 2 ] ], + [ [ 1, 1, 4, 2, 2, 2 ], [ 0 ], [ 10, 2 ], [ 10, 2 ], [ 10, 2 ] ], + [ [ 1, 1, 1, 1 ], [ 1, 1, 1 ], [ 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ] ] + ]; + + for ( i = 0; i < shapes.length; i++ ) { + t.throws( badValue( shapes[i][0], shapes[i][1], shapes[i][2], shapes[i][3], shapes[i][4] ), Error, 'throws an error for index ' + i ); + } + t.end(); + + function badValue( sh1, sh2, sh3, sh4, sh5 ) { + return function badValue() { + var dtype; + var ord; + var st1; + var st2; + var st3; + var st4; + var st5; + var o1; + var o2; + var o3; + var o4; + var o5; + var x; + var y; + var z; + var w; + var u; + + ord = 'row-major'; + dtype = 'float64'; + + st1 = shape2strides( sh1, ord ); + st2 = shape2strides( sh2, ord ); + st3 = shape2strides( sh3, ord ); + st4 = shape2strides( sh4, ord ); + st5 = shape2strides( sh5, ord ); + o1 = strides2offset( sh1, st1 ); + o2 = strides2offset( sh2, st2 ); + o3 = strides2offset( sh3, st3 ); + o4 = strides2offset( sh4, st4 ); + o5 = strides2offset( sh5, st5 ); + + x = ndarray( dtype, ones( numel( sh1 ), dtype ), sh1, st1, o1, ord ); + y = ndarray( dtype, ones( numel( sh2 ), dtype ), sh2, st2, o2, ord ); + z = ndarray( dtype, ones( numel( sh3 ), dtype ), sh3, st3, o3, ord ); + w = ndarray( dtype, zeros( numel( sh4 ), dtype ), sh4, st4, o4, ord ); + u = ndarray( dtype, zeros( numel( sh5 ), dtype ), sh5, st5, o5, ord ); + + dispatch( [ x, y, z, w, u ], add4 ); + }; + } +}); + +tape( 'the function throws an error if provided input and output ndarrays which do not have the same shape', function test( t ) { + var shapes; + var i; + + shapes = [ + [ [ 4, 2, 1 ], [ 4, 2, 2 ], [ 4, 2, 1 ], [ 4, 2, 1 ], [ 4, 2, 1 ] ], + [ [ 3, 3 ], [ 2, 2 ], [ 3, 3 ], [ 3, 3 ], [ 3, 3 ] ], + [ [ 5, 5, 5 ], [ 5, 5, 4 ], [ 5, 5, 4 ], [ 5, 5, 4 ], [ 5, 5, 4 ] ], + [ [ 1, 1, 1 ], [ 2, 2, 2 ], [ 1, 1, 2 ], [ 1, 1, 2 ], [ 1, 1, 2 ] ], + [ [ 1, 4 ], [ 3, 8 ], [ 4, 4 ], [ 4, 4 ], [ 4, 4 ] ], + [ [ 10, 2, 1 ], [ 1, 2, 10 ], [ 2, 1, 10 ], [ 2, 1, 10 ], [ 2, 1, 10 ] ] + ]; + + for ( i = 0; i < shapes.length; i++ ) { + t.throws( badValue( shapes[i][0], shapes[i][1], shapes[i][2], shapes[i][3], shapes[i][4] ), Error, 'throws an error for index ' + i ); + } + t.end(); + + function badValue( sh1, sh2, sh3, sh4, sh5 ) { + return function badValue() { + var dtype; + var ord; + var st1; + var st2; + var st3; + var st4; + var st5; + var o1; + var o2; + var o3; + var o4; + var o5; + var x; + var y; + var z; + var w; + var u; + + ord = 'row-major'; + dtype = 'float64'; + + st1 = shape2strides( sh1, ord ); + st2 = shape2strides( sh2, ord ); + st3 = shape2strides( sh3, ord ); + st4 = shape2strides( sh4, ord ); + st5 = shape2strides( sh5, ord ); + o1 = strides2offset( sh1, st1 ); + o2 = strides2offset( sh2, st2 ); + o3 = strides2offset( sh3, st3 ); + o4 = strides2offset( sh4, st4 ); + o5 = strides2offset( sh5, st5 ); + + x = ndarray( dtype, ones( numel( sh1 ), dtype ), sh1, st1, o1, ord ); + y = ndarray( dtype, ones( numel( sh2 ), dtype ), sh2, st2, o2, ord ); + z = ndarray( dtype, ones( numel( sh3 ), dtype ), sh3, st3, o3, ord ); + w = ndarray( dtype, zeros( numel( sh4 ), dtype ), sh4, st4, o4, ord ); + u = ndarray( dtype, zeros( numel( sh5 ), dtype ), sh5, st5, o5, ord ); + + dispatch( [ x, y, z, w, u ], add4 ); + }; + } +}); + +tape( 'the function applies a quaternary callback (0-dimensional)', function test( t ) { + var expected; + var x; + var y; + var z; + var w; + var u; + + x = scalar2ndarray( 5.0, { + 'dtype': 'float64' + }); + y = scalar2ndarray( 3.0, { + 'dtype': 'float64' + }); + z = scalar2ndarray( 2.0, { + 'dtype': 'float64' + }); + w = scalar2ndarray( 1.0, { + 'dtype': 'float64' + }); + u = scalar2ndarray( 0.0, { + 'dtype': 'float64' + }); + + dispatch( [ x, y, z, w, u ], add4 ); + + expected = new Float64Array( [ 11.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function applies a quaternary callback (1-dimensional)', function test( t ) { + var expected; + var x; + var u; + + x = ndarray( 'float64', oneTo( 4, 'float64' ), [ 4 ], [ 1 ], 0, 'row-major' ); + u = ndarray( 'float64', zeros( 4, 'float64' ), [ 4 ], [ 1 ], 0, 'row-major' ); + + dispatch( [ x, x, x, x, u ], add4 ); + + expected = new Float64Array( [ 4.0, 8.0, 12.0, 16.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function applies a quaternary callback (n-dimensional)', function test( t ) { + var expected; + var ord; + var sh; + var st; + var dt; + var o; + var x; + var u; + + dt = 'float64'; + ord = 'row-major'; + sh = [ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 ]; + st = [ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 ]; + o = strides2offset( sh, st ); + + x = ndarray( dt, oneTo( 8, dt ), sh, st, o, ord ); + u = ndarray( dt, zeros( 8, dt ), sh, st, o, ord ); + + dispatch( [ x, x, x, x, u ], add4 ); + + expected = new Float64Array( [ 4.0, 8.0, 0.0, 0.0, 20.0, 24.0, 0.0, 0.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function applies a quaternary callback (contiguous)', function test( t ) { + var expected; + var ord; + var sh; + var st; + var dt; + var o; + var x; + var u; + + dt = 'float64'; + ord = 'row-major'; + sh = [ 2, 2 ]; + st = shape2strides( sh, ord ); + o = strides2offset( sh, st ); + + x = ndarray( dt, oneTo( numel( sh ), dt ), sh, st, o, ord ); + u = ndarray( dt, zeros( numel( sh ), dt ), sh, st, o, ord ); + + dispatch( [ x, x, x, x, u ], add4 ); + + expected = new Float64Array( [ 4.0, 8.0, 12.0, 16.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function applies a quaternary callback (contiguous, singleton dimensions)', function test( t ) { + var expected; + var x; + var u; + + x = ndarray( 'float64', oneTo( 4, 'float64' ), [ 4, 1, 1 ], [ 1, 1, 1 ], 0, 'row-major' ); + u = ndarray( 'float64', zeros( 4, 'float64' ), [ 4, 1, 1 ], [ 1, 1, 1 ], 0, 'row-major' ); + + dispatch( [ x, x, x, x, u ], add4 ); + + expected = new Float64Array( [ 4.0, 8.0, 12.0, 16.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function applies a quaternary callback (non-contiguous, same order)', function test( t ) { + var expected; + var x; + var u; + + x = ndarray( 'float64', oneTo( 8, 'float64' ), [ 2, 2 ], [ 4, 1 ], 0, 'row-major' ); + u = ndarray( 'float64', zeros( 8, 'float64' ), [ 2, 2 ], [ 4, 1 ], 0, 'row-major' ); + + dispatch( [ x, x, x, x, u ], add4 ); + + expected = new Float64Array( [ 4.0, 8.0, 0.0, 0.0, 20.0, 24.0, 0.0, 0.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function applies a quaternary callback (non-contiguous)', function test( t ) { + var expected; + var x; + var u; + + x = ndarray( 'float64', oneTo( 8, 'float64' ), [ 2, 2 ], [ 4, -1 ], strides2offset( [ 2, 2 ], [ 4, -1 ] ), 'row-major' ); + u = ndarray( 'float64', zeros( 8, 'float64' ), [ 2, 2 ], [ 4, -1 ], strides2offset( [ 2, 2 ], [ 4, -1 ] ), 'row-major' ); + + dispatch( [ x, x, x, x, u ], add4 ); + + expected = new Float64Array( [ 4.0, 8.0, 0.0, 0.0, 20.0, 24.0, 0.0, 0.0 ] ); + t.strictEqual( isSameFloat64Array( getData( u ), expected ), true, 'returns expected value' ); + t.end(); +}); From b98076a39f1a15d73c28da6ea6bedc8fb9715cf0 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Thu, 1 Oct 2026 15:46:30 +0500 Subject: [PATCH 2/3] fix: lint errs --- .../ndarray/base/kernels/generic/quaternary/dispatch/README.md | 2 ++ .../base/kernels/generic/quaternary/dispatch/lib/main.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md index f3e721f59352..04c9d70a5c3a 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md @@ -114,6 +114,8 @@ The function accepts the following arguments: + + ```javascript var Float64Array = require( '@stdlib/array/float64' ); var ndarray = require( '@stdlib/ndarray/ctor' ); diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js index 2668a9478b7f..672e4b066bb6 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js @@ -16,7 +16,7 @@ * limitations under the License. */ -/* eslint-disable max-statements, max-lines-per-function */ +/* eslint-disable max-statements */ 'use strict'; From 8f141edc9f436feef3359fb40d2fb1b4e644fc42 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Fri, 2 Oct 2026 22:43:04 +0500 Subject: [PATCH 3/3] fix: apply suggestions from code review --- .../generic/quaternary/dispatch/README.md | 21 +++++------ .../generic/quaternary/dispatch/docs/repl.txt | 9 +++-- .../quaternary/dispatch/examples/index.js | 5 +-- .../generic/quaternary/dispatch/lib/index.js | 14 ++++---- .../generic/quaternary/dispatch/lib/main.js | 36 ++++++++++--------- .../generic/quaternary/dispatch/test/test.js | 4 +-- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md index 04c9d70a5c3a..73761f0ff957 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md @@ -40,14 +40,18 @@ var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatc Applies a quaternary callback to elements in four input ndarrays and assigns results to elements in an output ndarray. + + ```javascript var Float64Array = require( '@stdlib/array/float64' ); var ndarray = require( '@stdlib/ndarray/ctor' ); +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); var getData = require( '@stdlib/ndarray/data-buffer' ); - -function add4( a, b, c, d ) { - return a + b + c + d; -} +var getShape = require( '@stdlib/ndarray/shape' ); +var getStrides = require( '@stdlib/ndarray/strides' ); +var getOffset = require( '@stdlib/ndarray/offset' ); +var getOrder = require( '@stdlib/ndarray/order' ); +var add4 = require( '@stdlib/number/float64/base/add4' ); // Create data buffers: var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); @@ -76,8 +80,8 @@ var u = ndarray( 'float64', ubuf, shape, su, 0, 'row-major' ); // Apply the quaternary callback: dispatch( [ x, y, z, w, u ], add4 ); -var v = getData( u ); -// returns [ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0 ] +var arr = ndarray2array( getData( u ), getShape( u ), getStrides( u ), getOffset( u ), getOrder( u ) ); +// returns [ [ [ 4.0, 6.0 ] ], [ [ 8.0, 10.0 ] ], [ [ 12.0, 14.0 ] ] ] ``` The function accepts the following arguments: @@ -125,12 +129,9 @@ var getShape = require( '@stdlib/ndarray/shape' ); var getStrides = require( '@stdlib/ndarray/strides' ); var getOffset = require( '@stdlib/ndarray/offset' ); var getOrder = require( '@stdlib/ndarray/order' ); +var add4 = require( '@stdlib/number/float64/base/add4' ); var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatch' ); -function add4( a, b, c, d ) { - return a + b + c + d; -} - // Create data buffers: var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt index 0e3e95d40172..9741077d9999 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt @@ -1,7 +1,7 @@ {{alias}}( arrays, fcn ) - Applies a quaternary callback to elements in four input ndarrays and - assigns results to elements in an output ndarray. + Applies a quaternary callback to elements in four input ndarrays and assigns + results to elements in an output ndarray. Each provided ndarray should be an object with the following properties: @@ -10,8 +10,8 @@ - shape: dimensions. - strides: stride lengths. - offset: index offset. - - order: specifies whether an ndarray is row-major (C-style) or column- - major (Fortran-style). + - order: specifies whether an ndarray is row-major (C-style) or column-major + (Fortran-style). Parameters ---------- @@ -102,4 +102,3 @@ See Also -------- - diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js index e10a7e3417ff..ec57ceac136a 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js @@ -26,12 +26,9 @@ var getShape = require( '@stdlib/ndarray/shape' ); var getStrides = require( '@stdlib/ndarray/strides' ); var getOffset = require( '@stdlib/ndarray/offset' ); var getOrder = require( '@stdlib/ndarray/order' ); +var add4 = require( '@stdlib/number/float64/base/add4' ); var dispatch = require( './../lib' ); -function add4( a, b, c, d ) { - return a + b + c + d; -} - // Create data buffers: var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js index 459dffe83723..73abc918b96e 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js @@ -26,13 +26,15 @@ * @example * var Float64Array = require( '@stdlib/array/float64' ); * var ndarray = require( '@stdlib/ndarray/ctor' ); +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); * var getData = require( '@stdlib/ndarray/data-buffer' ); +* var getShape = require( '@stdlib/ndarray/shape' ); +* var getStrides = require( '@stdlib/ndarray/strides' ); +* var getOffset = require( '@stdlib/ndarray/offset' ); +* var getOrder = require( '@stdlib/ndarray/order' ); +* var add4 = require( '@stdlib/number/float64/base/add4' ); * var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatch' ); * -* function add4( a, b, c, d ) { -* return a + b + c + d; -* } -* * // Create data buffers: * var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); * var ybuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); @@ -60,8 +62,8 @@ * // Apply the quaternary callback: * dispatch( [ x, y, z, w, u ], add4 ); * -* console.log( getData( u ) ); -* // => [ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0 ] +* var arr = ndarray2array( getData( u ), getShape( u ), getStrides( u ), getOffset( u ), getOrder( u ) ); +* // returns [ [ [ 4.0, 6.0 ] ], [ [ 8.0, 10.0 ] ], [ [ 12.0, 14.0 ] ] ] */ // MODULES // diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js index 672e4b066bb6..0ae40ad7ca8e 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js @@ -62,11 +62,13 @@ var MAX_DIMS = 10; * @example * var Float64Array = require( '@stdlib/array/float64' ); * var ndarray = require( '@stdlib/ndarray/ctor' ); +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); * var getData = require( '@stdlib/ndarray/data-buffer' ); -* -* function add4( a, b, c, d ) { -* return a + b + c + d; -* } +* var getShape = require( '@stdlib/ndarray/shape' ); +* var getStrides = require( '@stdlib/ndarray/strides' ); +* var getOffset = require( '@stdlib/ndarray/offset' ); +* var getOrder = require( '@stdlib/ndarray/order' ); +* var add4 = require( '@stdlib/number/float64/base/add4' ); * * // Create data buffers: * var xbuf = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 ] ); @@ -95,8 +97,8 @@ var MAX_DIMS = 10; * // Apply the quaternary callback: * dispatch( [ x, y, z, w, u ], add4 ); * -* var v = getData( u ); -* // returns [ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0 ] +* var arr = ndarray2array( getData( u ), getShape( u ), getStrides( u ), getOffset( u ), getOrder( u ) ); +* // returns [ [ [ 4.0, 6.0 ] ], [ [ 8.0, 10.0 ] ], [ [ 12.0, 14.0 ] ] ] */ function dispatch( arrays, fcn ) { var ndims; @@ -159,10 +161,17 @@ function dispatch( arrays, fcn ) { ) { throw new Error( format( 'invalid arguments. Arrays must have the same number of dimensions (i.e., same rank). ndims(x) == %d. ndims(y) == %d. ndims(z) == %d. ndims(w) == %d. ndims(u) == %d.', ndims, shy.length, shz.length, shw.length, shu.length ) ); } + sx = x.strides; + sy = y.strides; + sz = z.strides; + sw = w.strides; + su = u.strides; + ord = strides2order( sx ); + // Determine whether we can avoid iteration altogether... if ( ndims === 0 ) { f = unblocked( ndims ); - return f( x, y, z, w, u, fcn ); + return f( x, y, z, w, u, ord === 1, fcn ); } // Verify that the input and output arrays have the same dimensions... len = 1; // number of elements @@ -187,14 +196,8 @@ function dispatch( arrays, fcn ) { // Determine whether the ndarrays are one-dimensional and thus readily translate to one-dimensional strided arrays... if ( ndims === 1 ) { f = unblocked( 1 ); - return f( x, y, z, w, u, fcn ); + return f( x, y, z, w, u, ord === 1, fcn ); } - sx = x.strides; - sy = y.strides; - sz = z.strides; - sw = w.strides; - su = u.strides; - // Determine whether the ndarrays have only **one** non-singleton dimension (e.g., ndims=4, shape=[10,1,1,1]) so that we can treat the ndarrays as being equivalent to one-dimensional strided arrays... if ( ns === ndims-1 ) { // Get the index of the non-singleton dimension... @@ -214,7 +217,7 @@ function dispatch( arrays, fcn ) { w.strides = [ sw[i] ]; u.strides = [ su[i] ]; f = unblocked( 1 ); - return f( x, y, z, w, u, fcn ); + return f( x, y, z, w, u, ord === 1, fcn ); } iox = iterationOrder( sx ); // +/-1 ioy = iterationOrder( sy ); // +/-1 @@ -223,7 +226,6 @@ function dispatch( arrays, fcn ) { iou = iterationOrder( su ); // +/-1 // Determine whether we can avoid blocked iteration... - ord = strides2order( sx ); if ( iox !== 0 && ioy !== 0 && @@ -292,7 +294,7 @@ function dispatch( arrays, fcn ) { w.offset = ow; u.offset = ou; f = unblocked( 1 ); - return f( x, y, z, w, u, fcn ); + return f( x, y, z, w, u, ord === 1, fcn ); } // At least one ndarray is non-contiguous, so we cannot directly use one-dimensional array functionality... diff --git a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js index dbe8867c5969..ce4bb8bb329e 100644 --- a/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/test/test.js @@ -285,7 +285,7 @@ tape( 'the function applies a quaternary callback (contiguous, singleton dimensi t.end(); }); -tape( 'the function applies a quaternary callback (non-contiguous, same order)', function test( t ) { +tape( 'the function applies a quaternary callback (non-contiguous, same sign strides)', function test( t ) { var expected; var x; var u; @@ -300,7 +300,7 @@ tape( 'the function applies a quaternary callback (non-contiguous, same order)', t.end(); }); -tape( 'the function applies a quaternary callback (non-contiguous)', function test( t ) { +tape( 'the function applies a quaternary callback (non-contiguous, mixed sign strides)', function test( t ) { var expected; var x; var u;