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..73761f0ff957 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/README.md @@ -0,0 +1,182 @@ + + +# 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 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' ); + +// 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 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: + +- **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 add4 = require( '@stdlib/number/float64/base/add4' ); +var dispatch = require( '@stdlib/ndarray/base/kernels/generic/quaternary/dispatch' ); + +// 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..9741077d9999 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/docs/repl.txt @@ -0,0 +1,104 @@ + +{{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..ec57ceac136a --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/examples/index.js @@ -0,0 +1,67 @@ +/** +* @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 add4 = require( '@stdlib/number/float64/base/add4' ); +var dispatch = require( './../lib' ); + +// 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..73abc918b96e --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/index.js @@ -0,0 +1,76 @@ +/** +* @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 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' ); +* +* // 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 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 // + +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..0ae40ad7ca8e --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/kernels/generic/quaternary/dispatch/lib/main.js @@ -0,0 +1,324 @@ +/** +* @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 */ + +'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 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' ); +* +* // 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 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; + 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 ) ); + } + 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, ord === 1, 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, ord === 1, fcn ); + } + // 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, ord === 1, 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... + 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, ord === 1, 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..ce4bb8bb329e --- /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 sign strides)', 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, mixed sign strides)', 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(); +});