From 4bc9fed4a2475053151c11b6987f0d16292bfed0 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Tue, 29 Jul 2025 08:25:43 +0000 Subject: [PATCH 1/4] feat: add ndarray/base/nullary-strided1d --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: passed - task: lint_repl_help status: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../ndarray/base/nullary-strided1d/README.md | 212 ++++++++++ .../base/nullary-strided1d/docs/repl.txt | 92 +++++ .../base/nullary-strided1d/examples/index.js | 61 +++ .../ndarray/base/nullary-strided1d/lib/0d.js | 110 ++++++ .../ndarray/base/nullary-strided1d/lib/1d.js | 169 ++++++++ .../ndarray/base/nullary-strided1d/lib/2d.js | 201 ++++++++++ .../base/nullary-strided1d/lib/2d_blocked.js | 231 +++++++++++ .../ndarray/base/nullary-strided1d/lib/3d.js | 217 ++++++++++ .../base/nullary-strided1d/lib/3d_blocked.js | 256 ++++++++++++ .../base/nullary-strided1d/lib/defaults.js | 43 ++ .../base/nullary-strided1d/lib/factory.js | 172 ++++++++ .../lib/increment_offsets.js | 46 +++ .../base/nullary-strided1d/lib/index.js | 153 ++++++++ .../lib/initialize_array_views.js | 57 +++ .../base/nullary-strided1d/lib/main.js | 157 ++++++++ .../nullary-strided1d/lib/main_factory.js | 371 ++++++++++++++++++ .../ndarray/base/nullary-strided1d/lib/nd.js | 177 +++++++++ .../base/nullary-strided1d/lib/offsets.js | 42 ++ .../nullary-strided1d/lib/set_view_offsets.js | 46 +++ .../base/nullary-strided1d/lib/strategy.js | 300 ++++++++++++++ .../base/nullary-strided1d/lib/validate.js | 66 ++++ .../base/nullary-strided1d/package.json | 61 +++ .../base/nullary-strided1d/test/test.js | 35 ++ 23 files changed, 3275 insertions(+) create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/defaults.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/increment_offsets.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/index.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/initialize_array_views.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main_factory.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/offsets.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/set_view_offsets.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/validate.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/package.json create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/test/test.js diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md new file mode 100644 index 000000000000..367bd544f1b7 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md @@ -0,0 +1,212 @@ + + +# nullaryStrided1d + +> Apply a one-dimensional strided array function to a list of specified dimensions in an input ndarray. + +
+ +
+ + + +
+ +## Usage + +```javascript +var nullaryStrided1d = require( '@stdlib/ndarray/base/nullary-strided1d' ); +``` + +#### nullaryStrided1d( fcn, arrays, dims\[, options] ) + +Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. + + + +```javascript +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +var getStride = require( '@stdlib/ndarray/base/stride' ); +var getOffset = require( '@stdlib/ndarray/base/offset' ); +var getData = require( '@stdlib/ndarray/base/data-buffer' ); +var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; + +function wrapper( arrays ) { + var x = arrays[ 0 ]; + var o = arrays[ 1 ]; + return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +} + +// Create data buffers: +var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; + +// Define the array shapes: +var xsh = [ 1, 3, 2, 2 ]; + +// Define the array strides: +var sx = [ 12, 4, 2, 1 ]; + +// Define the index offsets: +var ox = 0; + +// Create an input ndarray-like object: +var x = { + 'dtype': 'generic', + 'data': xbuf, + 'shape': xsh, + 'strides': sx, + 'offset': ox, + 'order': 'row-major' +}; + +// Create an ndarray-like object for the sort order: +var sortOrder = { + 'dtype': 'generic', + 'data': [ 1.0 ], + 'shape': [ 1, 3 ], + 'strides': [ 0, 0 ], + 'offset': 0, + 'order': 'row-major' +}; + +// Apply strided function: +nullaryStrided1d( wrapper, [ x, sortOrder ], [ 2, 3 ] ); + +var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +// returns [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] +``` + +The function accepts the following arguments: + +- **fcn**: function which will be applied to a one-dimensional input subarray. +- **arrays**: array-like object containing one input ndarray followed by any additional ndarray arguments. +- **dims**: list of dimensions to which to apply a strided array function. +- **options**: function options which are passed through to `fcn` (_optional_). + +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). + +#### TODO: document factory method + +
+ + + +
+ +## Notes + +- Any additional ndarray arguments are expected to have the same dimensions as the loop dimensions of the input ndarray. When calling the strided array function, any additional ndarray arguments are provided as zero-dimensional ndarray-like objects. + +- The strided array function is expected to have the following signature: + + ```text + fcn( arrays[, options] ) + ``` + + where + + - **arrays**: array containing a one-dimensional subarray of the input ndarray and any additional ndarray arguments as zero-dimensional ndarrays. + - **options**: function options (_optional_). + +- The function iterates over ndarray elements according to the memory layout of the input ndarray. + +- For very high-dimensional ndarrays which are non-contiguous, one should consider copying the underlying data to contiguous memory before performing an operation in order to achieve better performance. + +
+ + + +
+ +## Examples + + + + + +```javascript +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +var getData = require( '@stdlib/ndarray/base/data-buffer' ); +var getStride = require( '@stdlib/ndarray/base/stride' ); +var getOffset = require( '@stdlib/ndarray/base/offset' ); +var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +var nullaryStrided1d = require( '@stdlib/ndarray/base/nullary-strided1d' ); + +function wrapper( arrays ) { + var x = arrays[ 0 ]; + var o = arrays[ 1 ]; + return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +} + +var N = 10; +var x = { + 'dtype': 'generic', + 'data': discreteUniform( N, -5, 5, { + 'dtype': 'generic' + }), + 'shape': [ 1, 5, 2 ], + 'strides': [ 10, 2, 1 ], + 'offset': 0, + 'order': 'row-major' +}; +var sortOrder = { + 'dtype': 'generic', + 'data': [ 0.0 ], + 'shape': [ 1, 2 ], + 'strides': [ 0, 0 ], + 'offset': 0, + 'order': 'row-major' +}; + +nullaryStrided1d( wrapper, [ x, sortOrder ], [ 1 ] ); + +console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); +``` + +
+ + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/docs/repl.txt b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/docs/repl.txt new file mode 100644 index 000000000000..4b64d5cbf6ec --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/docs/repl.txt @@ -0,0 +1,92 @@ + +{{alias}}( fcn, arrays, dims[, options] ) + Applies a one-dimensional strided array function to a list of specified + dimensions in an input 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). + + Any additional ndarray arguments are expected to have the same dimensions as + the loop dimensions of the input ndarray. When calling the strided array + function, any additional ndarray arguments are provided as zero-dimensional + ndarray-like objects. + + Parameters + ---------- + fcn: Function + Function which will be applied to a one-dimensional input subarray. The + function should have the following signature: + + fcn( arrays[, options] ) + + where + + - arrays: array containing a one-dimensional subarray of the input + ndarray and any additional ndarray arguments as zero-dimensional + ndarrays. + - options: function options. + + arrays: ArrayLikeObject + Array-like object containing an input ndarray followed by any additional + ndarray arguments. + + dims: Array + List of dimensions to which to apply a strided array function. + + options: Object (optional) + Function options. + + Examples + -------- + // Define ndarray data and meta data... + > var xbuf = [ 4.0, 3.0, 2.0, 1.0 ]; + > var dtype = 'generic'; + > var shx = [ 2, 2 ]; + > var sx = [ 2, 1 ]; + > var ox = 0; + > var order = 'row-major'; + + // Define a wrapper for an extended BLAS function... + > var f = {{alias:@stdlib/blas/ext/base/gsorthp}}.ndarray; + > function fcn( arrays ) { + ... var x = arrays[ 0 ]; + ... var o = arrays[ 1 ]; + ... var N = x.shape[ 0 ]; + ... var dx = x.data; + ... var sx = x.strides[ 0 ]; + ... var ox = x.offset; + ... var init = o.data[ o.offset ]; + ... return f( N, init, dx, sx, ox ); + ... }; + + // Using minimal ndarray-like objects... + > var x = { + ... 'dtype': dtype, + ... 'data': xbuf, + ... 'shape': shx, + ... 'strides': sx, + ... 'offset': ox, + ... 'order': order + ... }; + > var sortOrder = { + ... 'dtype': dtype, + ... 'data': [ 1.0 ], + ... 'shape': [], + ... 'strides': [ 0 ], + ... 'offset': 0, + ... 'order': order + ... }; + > {{alias}}( fcn, [ x, sortOrder ], [ 0, 1 ] ); + > x.data + [ 1.0, 2.0, 3.0, 4.0 ] + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js new file mode 100644 index 000000000000..097849105d07 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js @@ -0,0 +1,61 @@ +/** +* @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. +*/ + +/* eslint-disable max-len */ + +'use strict'; + +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); +var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +var getData = require( '@stdlib/ndarray/base/data-buffer' ); +var getStride = require( '@stdlib/ndarray/base/stride' ); +var getOffset = require( '@stdlib/ndarray/base/offset' ); +var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +var nullaryStrided1d = require( './../lib' ); + +function wrapper( arrays ) { + var x = arrays[ 0 ]; + var o = arrays[ 1 ]; + return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +} + +var N = 10; +var x = { + 'dtype': 'generic', + 'data': discreteUniform( N, -5, 5, { + 'dtype': 'generic' + }), + 'shape': [ 1, 5, 2 ], + 'strides': [ 10, 2, 1 ], + 'offset': 0, + 'order': 'row-major' +}; +var sortOrder = { + 'dtype': 'generic', + 'data': [ 0.0 ], + 'shape': [ 1, 2 ], + 'strides': [ 0, 0 ], + 'offset': 0, + 'order': 'row-major' +}; + +nullaryStrided1d( wrapper, [ x, sortOrder ], [ 0 ] ); + +console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js new file mode 100644 index 000000000000..61a503f3056c --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.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'; + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array function +* @param {Array} arrays - ndarrays +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 3 ], +* 'strides': [ 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* nullary0d( wrapper, [ x, sortOrder ], strategy, {} ); +* +* var v = x.data; +* // returns [ 1.0, 2.0, 3.0, 4.0 ] +*/ +function nullary0d( fcn, arrays, strategyX, opts ) { + arrays[ 0 ] = strategyX.input( arrays[ 0 ] ); + fcn( arrays, opts ); +} + + +// EXPORTS // + +module.exports = nullary0d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js new file mode 100644 index 000000000000..2ea440f61077 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js @@ -0,0 +1,169 @@ +/** +* @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 copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 3 ], +* 'strides': [ 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* nullary1d( wrapper, [ x, sortOrder ], views, [ 3 ], [ 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] +*/ +function nullary1d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { + var dv0; + var S0; + var iv; + var i0; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + S0 = shape[ 0 ]; + dv0 = [ + stridesX[0] + ]; + for ( i = 1; i < arrays.length; i++ ) { + dv0.push( arrays[i].strides[0] ); + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX.input( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } +} + + +// EXPORTS // + +module.exports = nullary1d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js new file mode 100644 index 000000000000..0e907d207039 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js @@ -0,0 +1,201 @@ +/** +* @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 copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 3 ], +* 'strides': [ 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* nullary2d( wrapper, [ x, sortOrder ], views, [ 1, 3 ], [ 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] +*/ +function nullary2d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len + var dv0; + var dv1; + var S0; + var S1; + var sv; + var iv; + var i0; + var i1; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 1 ]; + S1 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[1] + ]; + dv1 = [ // offset increment for outermost loop + stridesX[0] - ( S0*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[1] ); + dv1.push( sv[0] - ( S0*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ // offset increment for outermost loop + stridesX[1] - ( S0*stridesX[0] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX.input( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } +} + + +// EXPORTS // + +module.exports = nullary2d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js new file mode 100644 index 000000000000..c2744ae25155 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js @@ -0,0 +1,231 @@ +/** +* @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 loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop-blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 3 ], +* 'strides': [ 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* blockednullary2d( wrapper, [ x, sortOrder ], views, [ 1, 3 ], [ 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] +*/ +function blockednullary2d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-len + var bsize; + var dv0; + var dv1; + var ov1; + var sh; + var s0; + var s1; + var sv; + var ov; + var iv; + var i0; + var i1; + var j0; + var j1; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + dv1 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov1[ k ] = ov[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX.input( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary2d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js new file mode 100644 index 000000000000..7e5f47acb34f --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js @@ -0,0 +1,217 @@ +/** +* @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 copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 3 ], +* 'strides': [ 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* nullary3d( wrapper, [ x, sortOrder ], views, [ 1, 1, 3 ], [ 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] ] +*/ +function nullary3d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len + var dv0; + var dv1; + var dv2; + var S0; + var S1; + var S2; + var sv; + var iv; + var i0; + var i1; + var i2; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 2 ]; + S1 = shape[ 1 ]; + S2 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[2] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[2] ) + ]; + dv2 = [ // offset increment for outermost loop + stridesX[0] - ( S1*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[2] ); + dv1.push( sv[1] - ( S0*sv[2] ) ); + dv2.push( sv[0] - ( S1*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ // offset increment for outermost loop + stridesX[2] - ( S1*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX.input( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } +} + + +// EXPORTS // + +module.exports = nullary3d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js new file mode 100644 index 000000000000..c2112673950e --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js @@ -0,0 +1,256 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 3 ], +* 'strides': [ 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* blockednullary3d( wrapper, [ x, sortOrder ], views, [ 1, 1, 3 ], [ 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] ] +*/ +function blockednullary3d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-len + var bsize; + var dv0; + var dv1; + var dv2; + var ov1; + var ov2; + var sh; + var s0; + var s1; + var s2; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var j0; + var j1; + var j2; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov2[ k ] = ov[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX.input( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary3d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/defaults.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/defaults.js new file mode 100644 index 000000000000..e1cec7ed37ba --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/defaults.js @@ -0,0 +1,43 @@ +/** +* @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'; + +// MAIN // + +/** +* Returns default options. +* +* @private +* @returns {Object} default options +* +* @example +* var o = defaults(); +* // returns {...} +*/ +function defaults() { + return { + // Require that the order of element traversal match the memory layout of an input ndarray: + 'strictTraversalOrder': false + }; +} + + +// EXPORTS // + +module.exports = defaults; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js new file mode 100644 index 000000000000..3127192c27fd --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js @@ -0,0 +1,172 @@ +/** +* @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 isFunction = require( '@stdlib/assert/is-function' ); +var mainFactory = require( './main_factory.js' ); +var main = require( './main.js' ); + + +// MAIN // + +/** +* Return a function for applying a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @param {Function} [fcn] - wrapper for a one-dimensional strided array function +* @param {Options} [options] - function options +* @param {boolean} [options.strictTraversalOrder=false] - boolean specifying whether to require that element traversal match the memory layout of an input ndarray +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options +* @returns {Function} function for applying a strided array function +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 3 ], +* 'strides': [ 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Create a function for applying a strided function: +* var sorthp = factory( wrapper ); +* // returns +* +* // Apply strided function: +* sorthp( [ x, sortOrder ], [ 2, 3 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] +*/ +function factory() { + var nullary; + var nargs; + var fcn; + var f; + + nargs = arguments.length; + + // Case: factory() + if ( nargs === 0 ) { + nullary = main; + f = wrap; + } + // Case: factory( fcn, opts ) + else if ( nargs > 1 ) { + nullary = mainFactory( arguments[ 1 ] ); + fcn = arguments[ 0 ]; + f = apply; + } + // Case: factory( fcn ) + else if ( isFunction( arguments[ 0 ] ) ) { + nullary = main; + fcn = arguments[ 0 ]; + f = apply; + } + // Case: factory( opts ) + else { + nullary = mainFactory( arguments[ 0 ] ); + f = wrap; + } + return f; + + /** + * Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. + * + * @private + * @param {ArrayLikeObject} arrays - array-like object containing ndarrays + * @param {IntegerArray} dims - list of dimensions to which to apply a strided array function + * @param {Options} [options] - function options + * @returns {void} + */ + function apply( arrays, dims, options ) { + var opts; + if ( arguments.length > 2 ) { + opts = options; + } else { + opts = {}; + } + return nullary( fcn, arrays, dims, opts ); + } + + /** + * Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. + * + * @private + * @param {Function} fcn - wrapper for a one-dimensional strided array function + * @param {ArrayLikeObject} arrays - array-like object containing ndarrays + * @param {IntegerArray} dims - list of dimensions to which to apply a strided array function + * @param {Options} [options] - function options + * @returns {void} + */ + function wrap( fcn, arrays, dims, options ) { + var opts; + if ( arguments.length > 3 ) { + opts = options; + } else { + opts = {}; + } + return nullary( fcn, arrays, dims, opts ); + } +} + + +// EXPORTS // + +module.exports = factory; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/increment_offsets.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/increment_offsets.js new file mode 100644 index 000000000000..7d525521b721 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/increment_offsets.js @@ -0,0 +1,46 @@ +/** +* @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'; + +// MAIN // + +/** +* Increments index offsets according to a list of increments. +* +* ## Notes +* +* - This function mutates the list of index offsets. +* +* @private +* @param {NonNegativeIntegerArray} offsets - list of index offsets +* @param {NonNegativeIntegerArray} inc - list of increments +* @returns {NonNegativeIntegerArray} updated offsets +*/ +function incrementOffsets( offsets, inc ) { + var i; + for ( i = 0; i < offsets.length; i++ ) { + offsets[ i ] += inc[ i ]; + } + return offsets; +} + + +// EXPORTS // + +module.exports = incrementOffsets; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/index.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/index.js new file mode 100644 index 000000000000..833269fb00ec --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/index.js @@ -0,0 +1,153 @@ +/** +* @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'; + +/** +* Apply a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @module @stdlib/ndarray/base/nullary-strided1d +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* var nullaryStrided1d = require( '@stdlib/ndarray/base/nullary-strided1d' ); +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 3 ], +* 'strides': [ 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Apply strided function: +* nullaryStrided1d( wrapper, [ x, sortOrder ], [ 2, 3 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 1.0, 3.0 ], [ 6.0, 10.0 ] ], [ [ 5.0, 11.0 ], [ 18.0, 26.0 ] ], [ [ 9.0, 19.0 ], [ 30.0, 42.0 ] ] ] ] +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* var nullaryStrided1d = require( '@stdlib/ndarray/base/nullary-strided1d' ); +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [], +* 'strides': [ 1 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Create a function for applying a strided function: +* var gsorthp = nullaryStrided1d.factory( wrapper ); +* // returns +* +* // Apply strided function: +* gsorthp( [ x, sortOrder ], [ 2, 3 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 1.0, 3.0 ], [ 6.0, 10.0 ] ], [ [ 5.0, 11.0 ], [ 18.0, 26.0 ] ], [ [ 9.0, 19.0 ], [ 30.0, 42.0 ] ] ] ] +*/ + +// MODULES // + +var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var factory = require( './factory.js' ); +var main = require( './main.js' ); + + +// MAIN // + +setReadOnly( main, 'factory', factory ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/initialize_array_views.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/initialize_array_views.js new file mode 100644 index 000000000000..df86de5bafc0 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/initialize_array_views.js @@ -0,0 +1,57 @@ +/** +* @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'; + +// MAIN // + +/** +* Initialize ndarray-like objects for representing zero-dimensional sub-array views of ancillary ndarray arguments. +* +* ## Notes +* +* - This function ignores the first ndarray-like object, which is assumed to be the input ndarray. +* - This function mutates the provided output array. +* +* @private +* @param {ArrayLikeObject} arrays - list of ndarray-like objects +* @param {Array} out - output array +* @returns {Array} output array +*/ +function initializeViews( arrays, out ) { + var v; + var i; + + for ( i = 1; i < arrays.length; i++ ) { + v = arrays[ i ]; + out.push({ + 'dtype': v.dtype, + 'data': v.data, + 'shape': [], + 'strides': [ 0 ], + 'offset': v.offset, + 'order': v.order + }); + } + return out; +} + + +// EXPORTS // + +module.exports = initializeViews; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main.js new file mode 100644 index 000000000000..c3e782a65b71 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main.js @@ -0,0 +1,157 @@ +/** +* @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 factory = require( './main_factory.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @name nullaryStrided1d +* @type {Function} +* @param {Function} fcn - wrapper for a one-dimensional strided array function +* @param {ArrayLikeObject} arrays - array-like object containing ndarrays +* @param {IntegerArray} dims - list of dimensions to which to apply a strided array function +* @param {Options} [options] - function options +* @throws {Error} arrays must have the expected number of dimensions +* @throws {RangeError} dimension indices must not exceed input ndarray bounds +* @throws {RangeError} number of dimension indices must not exceed the number of input ndarray dimensions +* @throws {Error} must provide unique dimension indices +* @throws {Error} arrays must have the same loop dimension sizes +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 3 ], +* 'strides': [ 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Apply strided function: +* var f = factory(); +* f( wrapper, [ x, sortOrder ], [ 2, 3 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Apply strided function: +* var f = factory(); +* f( wrapper, [ x, sortOrder ], [ 0, 1, 2 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ] ] +*/ +var nullaryStrided1d = factory(); + + +// EXPORTS // + +module.exports = nullaryStrided1d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main_factory.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main_factory.js new file mode 100644 index 000000000000..1236a87d0539 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/main_factory.js @@ -0,0 +1,371 @@ +/** +* @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 ndarray2object = require( '@stdlib/ndarray/base/ndarraylike2object' ); +var normalizeIndices = require( '@stdlib/ndarray/base/to-unique-normalized-indices' ); +var indicesComplement = require( '@stdlib/array/base/indices-complement' ); +var takeIndexed2 = require( '@stdlib/array/base/take-indexed2' ); +var iterationOrder = require( '@stdlib/ndarray/base/iteration-order' ); +var strides2order = require( '@stdlib/ndarray/base/strides2order' ); +var numel = require( '@stdlib/ndarray/base/numel' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var initializeViews = require( './initialize_array_views.js' ); +var strategy = require( './strategy.js' ); +var defaults = require( './defaults.js' ); +var validate = require( './validate.js' ); +var blockednullary2d = require( './2d_blocked.js' ); +var blockednullary3d = require( './3d_blocked.js' ); +var nullary0d = require( './0d.js' ); +var nullary1d = require( './1d.js' ); +var nullary2d = require( './2d.js' ); +var nullary3d = require( './3d.js' ); +var nullarynd = require( './nd.js' ); + + +// VARIABLES // + +var NULLARY = [ + nullary0d, + nullary1d, + nullary2d, + nullary3d +]; +var BLOCKED_NULLARY = [ + blockednullary2d, // 0 + blockednullary3d +]; +var MAX_DIMS = NULLARY.length - 1; + + +// MAIN // + +/** +* Returns a function for applying a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Options} [options] - function options +* @param {boolean} [options.strictTraversalOrder=false] - boolean specifying whether to require that element traversal match the memory layout of an input ndarray +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options +* @returns {Function} function for applying a strided array function +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 3 ], +* 'strides': [ 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Apply strided function: +* var f = factory(); +* f( wrapper, [ x, sortOrder ], [ 2, 3 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Apply strided function: +* var f = factory(); +* f( wrapper, [ x, sortOrder ], [ 0, 1, 2, 3 ] ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ] ] ] +*/ +function factory( options ) { + var OPTS; + var err; + + OPTS = defaults(); + if ( arguments.length ) { + err = validate( OPTS, options ); + if ( err ) { + throw err; + } + } + return nullaryStrided1d; + + /** + * Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. + * + * @private + * @param {Function} fcn - wrapper for a one-dimensional strided array function + * @param {ArrayLikeObject} arrays - array-like object containing ndarrays + * @param {IntegerArray} dims - list of dimensions to which to apply a strided array function + * @param {Options} [options] - function options + * @throws {Error} arrays must have the expected number of dimensions + * @throws {RangeError} dimension indices must not exceed input ndarray bounds + * @throws {RangeError} number of dimension indices must not exceed the number of input ndarray dimensions + * @throws {Error} must provide unique dimension indices + * @throws {Error} arrays must have the same loop dimension sizes + * @returns {void} + */ + function nullaryStrided1d( fcn, arrays, dims, options ) { + var strategyX; + var views; + var ndims; + var ldims; + var opts; + var arr; + var tmp; + var len; + var shl; + var shc; + var shx; + var iox; + var scx; + var slx; + var ord; + var ns; + var d; + var s; + var N; + var M; + var K; + var x; + var i; + var j; + + if ( arguments.length > 3 ) { + opts = options; + } else { + opts = {}; + } + // Standardize ndarray meta data... + N = arrays.length; + arr = []; + for ( i = 0; i < N; i++ ) { + arr.push( ndarray2object( arrays[ i ] ) ); + } + // Cache references to the input array: + x = arr[ 0 ]; + + // Resolve the number of input array dimensions: + shx = x.shape; + ndims = shx.length; + + // Verify that we've been provided a list of unique dimension indices... + M = dims.length; + d = normalizeIndices( dims, ndims-1 ); + if ( d === null ) { + throw new RangeError( format( 'invalid argument. Third argument contains an out-of-bounds dimension index. Value: [%s].', join( dims, ',' ) ) ); + } + d.sort(); + if ( d.length !== M ) { + throw new Error( format( 'invalid argument. Third argument must contain a list of unique dimension indices. Value: [%s].', join( dims, ',' ) ) ); + } + // Check whether we've been provided a valid number of dimensions... + if ( M > ndims ) { + throw new RangeError( format( 'invalid argument. Number of specified dimensions cannot exceed the number of dimensions in the input array. Number of dimensions: %d. Value: [%s].', ndims, join( dims, ',' ) ) ); + } + // Verify that provided ancillary ndarrays have the expected number of dimensions... + K = ndims - M; + for ( i = 1; i < N; i++ ) { + if ( arr[ i ].shape.length !== K ) { + throw new Error( format( 'invalid argument. Array arguments after the first array must have the same number of loop dimensions. Input array shape: [%s]. Number of loop dimensions: %d. Array shape: [%s] (index: %d).', join( shx, ',' ), K, join( arr[ i ].shape, ',' ), i ) ); + } + } + // Resolve the loop dimensions and associated strides: + ldims = indicesComplement( shx.length, d ); + tmp = takeIndexed2( shx, x.strides, ldims ); + shl = tmp[ 0 ]; + slx = tmp[ 1 ]; + + // Resolve the core dimensions and associated strides: + tmp = takeIndexed2( shx, x.strides, d ); + shc = tmp[ 0 ]; + scx = tmp[ 1 ]; + + // Verify that provided ancillary arrays have the same loop dimensions... + len = 1; // number of elements + ns = 0; // number of singleton dimensions + for ( i = 0; i < K; i++ ) { + s = shl[ i ]; + for ( j = 2; j < N; j++ ) { + if ( s !== arr[ j ].shape[ i ] ) { + throw new Error( format( 'invalid argument. Loop dimensions must be consistent across all provided arrays. Input array shape: [%s]. Loop dimension indices: [%s]. Loop dimensions: [%s]. Array shape: [%s] (index: %d).', join( shx, ',' ), join( ldims, ',' ), join( shl, ',' ), join( arr[ j ].shape, ',' ), j ) ); + } + } + // Note that, if one of the dimensions is `0`, the length will be `0`... + len *= s; + + // Check whether the current dimension is a singleton dimension... + if ( s === 1 ) { + ns += 1; + } + } + // Check whether we were provided empty ndarrays... + if ( len === 0 || ( shc.length && numel( shc ) === 0 ) ) { + return; + } + // Initialize ndarray-like objects for representing sub-array views... + views = [ + { + 'dtype': x.dtype, + 'data': x.data, + 'shape': shc, + 'strides': scx, + 'offset': x.offset, + 'order': x.order + } + ]; + initializeViews( arr, views ); + + // Determine the strategy for marshaling data to and from sub-array views of the input array before and after performing an operation: + strategyX = strategy( views[ 0 ] ); + + // Determine whether we can avoid iteration altogether... + if ( K === 0 ) { + return NULLARY[ K ]( fcn, arr, strategyX, opts ); + } + // Determine whether we only have one loop dimension and can thus readily perform one-dimensional iteration... + if ( K === 1 ) { + return NULLARY[ K ]( fcn, arr, views, shl, slx, strategyX, opts ); + } + // Determine whether the loop dimensions have only **one** non-singleton dimension (e.g., shape=[10,1,1,1]) so that we can treat loop iteration as being equivalent to one-dimensional iteration... + if ( ns === K-1 ) { + // Get the index of the non-singleton dimension... + for ( i = 0; i < K; i++ ) { + if ( shl[ i ] !== 1 ) { + break; + } + } + for ( j = 0; j < N; j++ ) { + arr[ j ].strides = [ arr[j].strides[i] ]; + } + slx = [ slx[i] ]; + return NULLARY[ 1 ]( fcn, arr, views, [ shl[i] ], slx, strategyX, opts ); // eslint-disable-line max-len + } + iox = iterationOrder( slx ); // +/-1 + + // Determine whether we can avoid blocked iteration... + ord = strides2order( slx ); + if ( iox !== 0 && K <= MAX_DIMS ) { + // So long as iteration for each respective array always moves in the same direction (i.e., no mixed sign strides) and the memory layouts are the same, we can leverage cache-optimal (i.e., normal) nested loops without resorting to blocked iteration... + return NULLARY[ K ]( fcn, arr, views, shl, slx, ord === 1, strategyX, opts ); // eslint-disable-line max-len + } + // Check whether blocked iteration is prohibited due to a requirement that the order of element traversal match the memory layout of a provided input ndarray... + if ( OPTS.strictTraversalOrder && K <= MAX_DIMS ) { + // We have two choices here: (1) we could copy to contiguous memory or (2) we can perform normal nested loop iteration, even though this is not cache-optimal based on the assumption that, while this may hurt performance, for many cases (i.e., smaller ndarrays), this should be fine and likely better than performing a complete copy... + return NULLARY[ K ]( fcn, arr, views, shl, slx, ord === 1, strategyX, opts ); // eslint-disable-line max-len + } + // 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 ( K <= MAX_DIMS ) { + return BLOCKED_NULLARY[ K-2 ]( fcn, arr, views, shl, slx, strategyX, opts ); // eslint-disable-line max-len + } + // Perform linear view iteration without regard for how data is stored in memory (i.e., take the slow path)... + nullarynd( fcn, arr, views, shl, slx, strategyX, opts ); + } +} + + +// EXPORTS // + +module.exports = factory; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js new file mode 100644 index 000000000000..43d6f37415d7 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js @@ -0,0 +1,177 @@ +/** +* @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 numel = require( '@stdlib/ndarray/base/numel' ); +var vind2bind = require( '@stdlib/ndarray/base/vind2bind' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// VARIABLES // + +var MODE = 'throw'; + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1 ], +* 'strides': [ 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function inputStrategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* var strategy = { +* 'input': inputStrategy +* }; +* +* // Apply strided function: +* nullarynd( wrapper, [ x, sortOrder ], views, [ 3 ], [ 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] +*/ +function nullarynd( fcn, arrays, views, shape, stridesX, strategyX, opts ) { + var len; + var arr; + var iv; + var io; + var N; + var v; + var i; + var j; + + N = arrays.length; + + // Compute the total number of elements over which to iterate: + len = numel( shape ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate based on the linear **view** index, regardless as to how the data is stored in memory... + io = zeros( N ); + for ( i = 0; i < len; i++ ) { + for ( j = 0; j < N; j++ ) { + arr = arrays[ j ]; + io[ j ] = vind2bind( shape, arr.strides, iv[ j ], arr.order, i, MODE ); // eslint-disable-line max-len + } + setViewOffsets( views, io ); + v[ 0 ] = strategyX.input( views[ 0 ] ); + fcn( v, opts ); + } +} + + +// EXPORTS // + +module.exports = nullarynd; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/offsets.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/offsets.js new file mode 100644 index 000000000000..a606628f5f3d --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/offsets.js @@ -0,0 +1,42 @@ +/** +* @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'; + +// MAIN // + +/** +* Resolves index offsets from a list of ndarray-like objects. +* +* @private +* @param {ArrayLikeObject} arrays - list of ndarray-like objects +* @returns {NonNegativeIntegerArray} list of offsets +*/ +function offsets( arrays ) { + var out = []; + var i; + for ( i = 0; i < arrays.length; i++ ) { + out.push( arrays[ i ].offset ); + } + return out; +} + + +// EXPORTS // + +module.exports = offsets; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/set_view_offsets.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/set_view_offsets.js new file mode 100644 index 000000000000..923da7aedb58 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/set_view_offsets.js @@ -0,0 +1,46 @@ +/** +* @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'; + +// MAIN // + +/** +* Sets view offsets according to a list of index offsets. +* +* ## Notes +* +* - This function mutates the provides view objects. +* +* @private +* @param {Array} views - list of ndarray-like objects representing ndarray views +* @param {NonNegativeIntegerArray} offsets - list of index offsets +* @returns {Array} updated views +*/ +function setViewOffsets( views, offsets ) { + var i; + for ( i = 0; i < offsets.length; i++ ) { + views[ i ].offset = offsets[ i ]; + } + return views; +} + + +// EXPORTS // + +module.exports = setViewOffsets; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js new file mode 100644 index 000000000000..083992f8f1c4 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js @@ -0,0 +1,300 @@ +/** +* @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 iterationOrder = require( '@stdlib/ndarray/base/iteration-order' ); +var minmaxViewBufferIndex = require( '@stdlib/ndarray/base/minmax-view-buffer-index' ).assign; +var ndarraylike2object = require( '@stdlib/ndarray/base/ndarraylike2object' ); +var assign = require( '@stdlib/ndarray/base/assign' ); +var ndarraylike2ndarray = require( '@stdlib/ndarray/base/ndarraylike2ndarray' ); +var emptyLike = require( '@stdlib/ndarray/base/empty-like' ); + + +// FUNCTIONS // + +/** +* Returns an input ndarray. +* +* @private +* @param {ndarrayLike} x - input ndarray +* @returns {ndarrayLike} input ndarray +*/ +function identity( x ) { + return x; +} + +/** +* Broadcasts a zero-dimensional ndarray to a one-dimensional ndarray view containing a single element. +* +* @private +* @param {ndarrayLike} x - input ndarray +* @returns {ndarrayLike} broadcasted ndarray view +*/ +function broadcast( x ) { + // NOTE: the following properties must be set in the exact same order as in `x` in order to ensure that the returned object has the same hidden shape as the input ndarray-like object... + return { + 'dtype': x.dtype, + 'data': x.data, + 'shape': [ 1 ], + 'strides': [ 0 ], + 'offset': x.offset, + 'order': x.order + }; +} + +/** +* Returns a function which returns an ndarray view in which the singleton dimensions are removed from an input ndarray having only a single non-singleton dimension. +* +* @private +* @param {ndarrayLike} arr - original ndarray +* @param {NonNegativeInteger} index - index of the non-singleton dimension +* @returns {Function} function for returning an ndarray view +*/ +function squeeze( arr, index ) { + var sh = [ arr.shape[ index ] ]; + var sx = [ arr.strides[ index ] ]; + return reshape; + + /** + * Returns an ndarray view in which the singleton dimensions are removed from an input ndarray having only a single non-singleton dimension. + * + * @private + * @param {ndarrayLike} x - input ndarray + * @returns {ndarrayLike} a squeezed ndarray view + */ + function reshape( x ) { + // NOTE: the following properties must be set in the exact same order as in `arr` in order to ensure that the returned object has the same hidden shape as the input ndarray-like object... + return { + 'dtype': x.dtype, + 'data': x.data, + 'shape': sh, + 'strides': sx, + 'offset': x.offset, + 'order': x.order + }; + } +} + +/** +* Returns a function which returns a one-dimensional ndarray view of a contiguous input ndarray having more than one dimension. +* +* @private +* @param {NonNegativeInteger} len - number of elements in an ndarray +* @param {integer} iox - iteration order +* @returns {Function} function for returning a one-dimensional ndarray view +*/ +function contiguous( len, iox ) { + var xmmv; + var ind; + var sh; + var sx; + + // Resolve the index of the min/max view buffer element which is the first indexed element... + if ( iox === 1 ) { + ind = 0; + } else { + ind = 1; + } + // Initialize an array for storing the min/max view buffer elements: + xmmv = [ 0, 0 ]; // [ min, max ] + + // Initialize the output one-dimensional view's shape and strides: + sh = [ len ]; + sx = [ iox ]; + + return reshape; + + /** + * Returns a one-dimensional ndarray view of a contiguous input ndarray having more than one dimension. + * + * @private + * @param {ndarrayLike} x - input ndarray + * @returns {ndarrayLike} a one-dimensional ndarray view + */ + function reshape( x ) { + // Resolve the minimum and maximum linear indices in the underlying data buffer which are accessible to the input ndarray view: + minmaxViewBufferIndex( x.shape, x.strides, x.offset, xmmv ); + + // NOTE: the following properties must be set in the exact same order as in `x` in order to ensure that the returned object has the same hidden shape as the input ndarray-like object... + return { + 'dtype': x.dtype, + 'data': x.data, + 'shape': sh, + 'strides': sx, + 'offset': xmmv[ ind ], // the index of the first indexed element + 'order': x.order + }; + } +} + +/** +* Returns a function which copies an input ndarray to a contiguous ndarray workspace. +* +* @private +* @param {NonNegativeInteger} len - number of elements in an ndarray +* @param {ndarrayLike} workspace - ndarray workspace +* @returns {Function} function which copies an input ndarray to a contiguous ndarray workspace +*/ +function copyToWorkspace( len, workspace ) { + // NOTE: the following properties must be set in the exact same order as in the input ndarray-like object in order to ensure that the returned object has the same hidden shape... + var view = { + 'dtype': workspace.dtype, + 'data': workspace.data, + 'shape': [ len ], + 'strides': [ 1 ], + 'offset': workspace.offset, + 'order': workspace.order + }; + return reshape; + + /** + * Copies an input ndarray to a contiguous ndarray workspace and returns a one-dimensional workspace view. + * + * @private + * @param {ndarrayLike} x - input ndarray + * @returns {ndarrayLike} one-dimensional workspace view + */ + function reshape( x ) { + assign( [ x, workspace ] ); + return view; + } +} + +/** +* Returns a function which copies from a contiguous ndarray workspace to an input ndarray. +* +* @private +* @param {ndarrayLike} workspace - ndarray workspace +* @returns {Function} function which copies from a contiguous ndarray workspace to an input ndarray +*/ +function copyFromWorkspace( workspace ) { + return copy; + + /** + * Copies from a contiguous ndarray workspace to an input ndarray. + * + * @private + * @param {ndarrayLike} x - input ndarray + * @returns {ndarrayLike} input ndarray + */ + function copy( x ) { + assign( [ workspace, x ] ); + return x; + } +} + + +// MAIN // + +/** +* Returns an object for reshaping input ndarrays which have the same data type, shape, and strides as a provided ndarray. +* +* @private +* @param {ndarrayLike} x - input ndarray +* @param {string} x.dtype - input ndarray data type +* @param {Collection} x.data - input ndarray data buffer +* @param {NonNegativeIntegerArray} x.shape - input ndarray shape +* @param {IntegerArray} x.strides - input ndarray strides +* @param {NonNegativeInteger} x.offset - input ndarray index offset +* @param {string} x.order - input ndarray memory layout +* @returns {Object} object containing methods implementing a reshape strategy +*/ +function strategy( x ) { + var workspace; + var ndims; + var xmmv; + var len; + var iox; + var sh; + var ns; + var i; + + // Resolve the number of array dimensions: + sh = x.shape; + ndims = sh.length; + + // Check whether the ndarray is zero-dimensional... + if ( ndims === 0 ) { + return { + 'input': broadcast, + 'output': identity + }; + } + // Check whether the ndarray is already one-dimensional... + if ( ndims === 1 ) { + return { + 'input': identity, + 'output': identity + }; + } + // Determine the number of singleton dimensions... + len = 1; // number of elements + ns = 0; // number of singleton dimensions + for ( i = 0; i < ndims; i++ ) { + // Check whether the current dimension is a singleton dimension... + if ( sh[ i ] === 1 ) { + ns += 1; + } + len *= sh[ i ]; + } + // Determine whether the ndarray has only **one** non-singleton dimension (e.g., ndims=4, shape=[10,1,1,1]) so that we can simply create an ndarray view without the singleton dimensions... + if ( ns === ndims-1 ) { + // Get the index of the non-singleton dimension... + for ( i = 0; i < ndims; i++ ) { + if ( sh[ i ] !== 1 ) { + break; + } + } + return { + 'input': squeeze( x, i ), + 'output': identity + }; + } + iox = iterationOrder( x.strides ); // +/-1 + + // Determine whether we can avoid copying data... + if ( iox !== 0 ) { + // Determine the minimum and maximum linear indices which are accessible by the ndarray view: + xmmv = minmaxViewBufferIndex( sh, x.strides, x.offset, [ 0, 0 ] ); + + // Determine whether we can ignore shape (and strides) and create a new one-dimensional ndarray view... + if ( len === ( xmmv[1]-xmmv[0]+1 ) ) { + return { + 'input': contiguous( len, iox ), + 'output': identity + }; + } + // The ndarray is non-contiguous, so we cannot directly interpret as a one-dimensional ndarray... + + // Fall-through to copying to a workspace ndarray... + } + // At this point, we're dealing with a non-contiguous multi-dimensional ndarray, so we need to copy to a contiguous workspace: + workspace = ndarraylike2object( emptyLike( ndarraylike2ndarray( x ) ) ); + return { + 'input': copyToWorkspace( len, workspace ), + 'output': copyFromWorkspace( workspace ) + }; +} + + +// EXPORTS // + +module.exports = strategy; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/validate.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/validate.js new file mode 100644 index 000000000000..95f0cd5a23cd --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/validate.js @@ -0,0 +1,66 @@ +/** +* @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 isObject = require( '@stdlib/assert/is-plain-object' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var format = require( '@stdlib/string/format' ); + + +// MAIN // + +/** +* Validates function options. +* +* @private +* @param {Object} opts - destination object +* @param {Options} options - function options +* @param {boolean} [options.strictTraversalOrder] - boolean indicating whether the order of element traversal must match the memory layout order of an input ndarray +* @returns {(Error|null)} null or an error object +* +* @example +* var opts = {}; +* var options = { +* 'strictTraversalOrder': true +* }; +* var err = validate( opts, options ); +* if ( err ) { +* throw err; +* } +*/ +function validate( opts, options ) { + if ( !isObject( options ) ) { + return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) ); + } + if ( hasOwnProp( options, 'strictTraversalOrder' ) ) { + opts.strictTraversalOrder = options.strictTraversalOrder; + if ( !isBoolean( opts.strictTraversalOrder ) ) { + return new TypeError( format( 'invalid option. `%s` option must be a boolean. Option: `%s`.', 'strictTraversalOrder', opts.strictTraversalOrder ) ); + } + } + return null; +} + + +// EXPORTS // + +module.exports = validate; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/package.json b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/package.json new file mode 100644 index 000000000000..a41dd127b15d --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/package.json @@ -0,0 +1,61 @@ +{ + "name": "@stdlib/ndarray/base/nullary-strided1d", + "version": "0.0.0", + "description": "Apply a one-dimensional strided array function to a list of specified dimensions in an input 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", + "strided", + "array", + "ndarray", + "nullary", + "apply", + "vector" + ], + "__stdlib__": {} +} diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/test/test.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/test/test.js new file mode 100644 index 000000000000..6308a869cb7f --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/test/test.js @@ -0,0 +1,35 @@ +/** +* @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 tape = require( 'tape' ); +var nullaryStrided1d = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof nullaryStrided1d, 'function', 'main export is a function' ); + t.end(); +}); + +// FIXME: add tests From 070159e396cc50d20f69f9581c633852d9ff6def Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Tue, 29 Jul 2025 13:41:26 +0500 Subject: [PATCH 2/4] docs: apply suggestions from code review Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- .../@stdlib/ndarray/base/nullary-strided1d/lib/1d.js | 2 +- .../@stdlib/ndarray/base/nullary-strided1d/lib/2d.js | 2 +- .../@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js | 2 +- .../@stdlib/ndarray/base/nullary-strided1d/lib/3d.js | 2 +- .../@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js | 2 +- .../@stdlib/ndarray/base/nullary-strided1d/lib/factory.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js index 2ea440f61077..23479103eca8 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js @@ -128,7 +128,7 @@ var offsets = require( './offsets.js' ); * nullary1d( wrapper, [ x, sortOrder ], views, [ 3 ], [ 4 ], strategy, {} ); * * var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); -* // returns [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] +* // returns [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] */ function nullary1d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { var dv0; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js index 0e907d207039..02e7ebcb9220 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js @@ -129,7 +129,7 @@ var offsets = require( './offsets.js' ); * nullary2d( wrapper, [ x, sortOrder ], views, [ 1, 3 ], [ 12, 4 ], true, strategy, {} ); * * var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); -* // returns [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] +* // returns [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] */ function nullary2d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len var dv0; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js index c2744ae25155..391d2c136a43 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js @@ -132,7 +132,7 @@ var offsets = require( './offsets.js' ); * blockednullary2d( wrapper, [ x, sortOrder ], views, [ 1, 3 ], [ 12, 4 ], strategy, {} ); * * var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); -* // returns [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] +* // returns [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] */ function blockednullary2d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-len var bsize; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js index 7e5f47acb34f..ef6c6d6f9c7e 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js @@ -129,7 +129,7 @@ var offsets = require( './offsets.js' ); * nullary3d( wrapper, [ x, sortOrder ], views, [ 1, 1, 3 ], [ 12, 12, 4 ], true, strategy, {} ); * * var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); -* // returns [ [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] ] +* // returns [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] */ function nullary3d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len var dv0; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js index c2112673950e..8414ad9218c0 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js @@ -134,7 +134,7 @@ var offsets = require( './offsets.js' ); * blockednullary3d( wrapper, [ x, sortOrder ], views, [ 1, 1, 3 ], [ 12, 12, 4 ], strategy, {} ); * * var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); -* // returns [ [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] ] +* // returns [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] */ function blockednullary3d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-len var bsize; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js index 3127192c27fd..c7d0a7da0cf7 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/factory.js @@ -92,7 +92,7 @@ var main = require( './main.js' ); * sorthp( [ x, sortOrder ], [ 2, 3 ] ); * * var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); -* // returns [ [ [ [ 9, 10 ], [ 11, 12 ] ], [ [ 5, 6 ], [ 7, 8 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ] ] +* // returns [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] */ function factory() { var nullary; From 1fcc2fd6773464b78495ab6e08d5d1a6ec6909e1 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Wed, 30 Jul 2025 07:37:02 +0000 Subject: [PATCH 3/4] refactor: refactor reshape strategy for nullary --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../ndarray/base/nullary-strided1d/README.md | 2 + .../base/nullary-strided1d/examples/index.js | 10 ++-- .../ndarray/base/nullary-strided1d/lib/0d.js | 8 +-- .../ndarray/base/nullary-strided1d/lib/1d.js | 8 +-- .../ndarray/base/nullary-strided1d/lib/2d.js | 8 +-- .../base/nullary-strided1d/lib/2d_blocked.js | 8 +-- .../ndarray/base/nullary-strided1d/lib/3d.js | 8 +-- .../base/nullary-strided1d/lib/3d_blocked.js | 8 +-- .../ndarray/base/nullary-strided1d/lib/nd.js | 8 +-- .../base/nullary-strided1d/lib/strategy.js | 52 +++---------------- 10 files changed, 29 insertions(+), 91 deletions(-) diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md index 367bd544f1b7..136e9dad386d 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md @@ -179,6 +179,8 @@ var x = { 'offset': 0, 'order': 'row-major' }; +console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); + var sortOrder = { 'dtype': 'generic', 'data': [ 0.0 ], diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js index 097849105d07..3a1755f25b0d 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/examples/index.js @@ -47,15 +47,17 @@ var x = { 'offset': 0, 'order': 'row-major' }; +console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); + var sortOrder = { 'dtype': 'generic', - 'data': [ 0.0 ], - 'shape': [ 1, 2 ], - 'strides': [ 0, 0 ], + 'data': [ 1.0 ], + 'shape': [ 2 ], + 'strides': [ 0 ], 'offset': 0, 'order': 'row-major' }; -nullaryStrided1d( wrapper, [ x, sortOrder ], [ 0 ] ); +nullaryStrided1d( wrapper, [ x, sortOrder ], [ 0, 1 ] ); console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js index 61a503f3056c..1972ce0855e8 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/0d.js @@ -78,7 +78,7 @@ * }; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -89,10 +89,6 @@ * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * nullary0d( wrapper, [ x, sortOrder ], strategy, {} ); * @@ -100,7 +96,7 @@ * // returns [ 1.0, 2.0, 3.0, 4.0 ] */ function nullary0d( fcn, arrays, strategyX, opts ) { - arrays[ 0 ] = strategyX.input( arrays[ 0 ] ); + arrays[ 0 ] = strategyX( arrays[ 0 ] ); fcn( arrays, opts ); } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js index 2ea440f61077..d9f1fe4f09c9 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/1d.js @@ -109,7 +109,7 @@ var offsets = require( './offsets.js' ); * ]; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -120,10 +120,6 @@ var offsets = require( './offsets.js' ); * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * nullary1d( wrapper, [ x, sortOrder ], views, [ 3 ], [ 4 ], strategy, {} ); * @@ -157,7 +153,7 @@ function nullary1d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // Iterate over the loop dimensions... for ( i0 = 0; i0 < S0; i0++ ) { setViewOffsets( views, iv ); - v[ 0 ] = strategyX.input( views[ 0 ] ); + v[ 0 ] = strategyX( views[ 0 ] ); fcn( v, opts ); incrementOffsets( iv, dv0 ); } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js index 0e907d207039..fcd2cd18ac61 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d.js @@ -110,7 +110,7 @@ var offsets = require( './offsets.js' ); * ]; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -121,10 +121,6 @@ var offsets = require( './offsets.js' ); * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * nullary2d( wrapper, [ x, sortOrder ], views, [ 1, 3 ], [ 12, 4 ], true, strategy, {} ); * @@ -187,7 +183,7 @@ function nullary2d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, for ( i1 = 0; i1 < S1; i1++ ) { for ( i0 = 0; i0 < S0; i0++ ) { setViewOffsets( views, iv ); - v[ 0 ] = strategyX.input( views[ 0 ] ); + v[ 0 ] = strategyX( views[ 0 ] ); fcn( v, opts ); incrementOffsets( iv, dv0 ); } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js index c2744ae25155..e006d5dc07ed 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/2d_blocked.js @@ -113,7 +113,7 @@ var offsets = require( './offsets.js' ); * ]; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -124,10 +124,6 @@ var offsets = require( './offsets.js' ); * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * blockednullary2d( wrapper, [ x, sortOrder ], views, [ 1, 3 ], [ 12, 4 ], strategy, {} ); * @@ -215,7 +211,7 @@ function blockednullary2d( fcn, arrays, views, shape, stridesX, strategyX, opts for ( i1 = 0; i1 < s1; i1++ ) { for ( i0 = 0; i0 < s0; i0++ ) { setViewOffsets( views, iv ); - v[ 0 ] = strategyX.input( views[ 0 ] ); + v[ 0 ] = strategyX( views[ 0 ] ); fcn( v, opts ); incrementOffsets( iv, dv0 ); } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js index 7e5f47acb34f..c6328df8651b 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d.js @@ -110,7 +110,7 @@ var offsets = require( './offsets.js' ); * ]; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -121,10 +121,6 @@ var offsets = require( './offsets.js' ); * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * nullary3d( wrapper, [ x, sortOrder ], views, [ 1, 1, 3 ], [ 12, 12, 4 ], true, strategy, {} ); * @@ -201,7 +197,7 @@ function nullary3d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, for ( i1 = 0; i1 < S1; i1++ ) { for ( i0 = 0; i0 < S0; i0++ ) { setViewOffsets( views, iv ); - v[ 0 ] = strategyX.input( views[ 0 ] ); + v[ 0 ] = strategyX( views[ 0 ] ); fcn( v, opts ); incrementOffsets( iv, dv0 ); } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js index c2112673950e..0d7e53d2f185 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/3d_blocked.js @@ -115,7 +115,7 @@ var offsets = require( './offsets.js' ); * ]; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -126,10 +126,6 @@ var offsets = require( './offsets.js' ); * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * blockednullary3d( wrapper, [ x, sortOrder ], views, [ 1, 1, 3 ], [ 12, 12, 4 ], strategy, {} ); * @@ -237,7 +233,7 @@ function blockednullary3d( fcn, arrays, views, shape, stridesX, strategyX, opts for ( i1 = 0; i1 < s1; i1++ ) { for ( i0 = 0; i0 < s0; i0++ ) { setViewOffsets( views, iv ); - v[ 0 ] = strategyX.input( views[ 0 ] ); + v[ 0 ] = strategyX( views[ 0 ] ); fcn( v, opts ); incrementOffsets( iv, dv0 ); } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js index 43d6f37415d7..ad6fd4eaf4e4 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/nd.js @@ -116,7 +116,7 @@ var MODE = 'throw'; * ]; * * // Define an input strategy: -* function inputStrategy( x ) { +* function strategy( x ) { * return { * 'dtype': x.dtype, * 'data': x.data, @@ -127,10 +127,6 @@ var MODE = 'throw'; * }; * } * -* var strategy = { -* 'input': inputStrategy -* }; -* * // Apply strided function: * nullarynd( wrapper, [ x, sortOrder ], views, [ 3 ], [ 4 ], strategy, {} ); * @@ -166,7 +162,7 @@ function nullarynd( fcn, arrays, views, shape, stridesX, strategyX, opts ) { io[ j ] = vind2bind( shape, arr.strides, iv[ j ], arr.order, i, MODE ); // eslint-disable-line max-len } setViewOffsets( views, io ); - v[ 0 ] = strategyX.input( views[ 0 ] ); + v[ 0 ] = strategyX( views[ 0 ] ); fcn( v, opts ); } } diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js index 083992f8f1c4..c964a967e0c8 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/strategy.js @@ -178,34 +178,11 @@ function copyToWorkspace( len, workspace ) { } } -/** -* Returns a function which copies from a contiguous ndarray workspace to an input ndarray. -* -* @private -* @param {ndarrayLike} workspace - ndarray workspace -* @returns {Function} function which copies from a contiguous ndarray workspace to an input ndarray -*/ -function copyFromWorkspace( workspace ) { - return copy; - - /** - * Copies from a contiguous ndarray workspace to an input ndarray. - * - * @private - * @param {ndarrayLike} x - input ndarray - * @returns {ndarrayLike} input ndarray - */ - function copy( x ) { - assign( [ workspace, x ] ); - return x; - } -} - // MAIN // /** -* Returns an object for reshaping input ndarrays which have the same data type, shape, and strides as a provided ndarray. +* Returns a function for reshaping input ndarrays which have the same data type, shape, and strides as a provided ndarray. * * @private * @param {ndarrayLike} x - input ndarray @@ -215,7 +192,7 @@ function copyFromWorkspace( workspace ) { * @param {IntegerArray} x.strides - input ndarray strides * @param {NonNegativeInteger} x.offset - input ndarray index offset * @param {string} x.order - input ndarray memory layout -* @returns {Object} object containing methods implementing a reshape strategy +* @returns {Function} function implementing a reshape strategy */ function strategy( x ) { var workspace; @@ -233,17 +210,11 @@ function strategy( x ) { // Check whether the ndarray is zero-dimensional... if ( ndims === 0 ) { - return { - 'input': broadcast, - 'output': identity - }; + return broadcast; } // Check whether the ndarray is already one-dimensional... if ( ndims === 1 ) { - return { - 'input': identity, - 'output': identity - }; + return identity; } // Determine the number of singleton dimensions... len = 1; // number of elements @@ -263,10 +234,7 @@ function strategy( x ) { break; } } - return { - 'input': squeeze( x, i ), - 'output': identity - }; + return squeeze( x, i ); } iox = iterationOrder( x.strides ); // +/-1 @@ -277,10 +245,7 @@ function strategy( x ) { // Determine whether we can ignore shape (and strides) and create a new one-dimensional ndarray view... if ( len === ( xmmv[1]-xmmv[0]+1 ) ) { - return { - 'input': contiguous( len, iox ), - 'output': identity - }; + return contiguous( len, iox ); } // The ndarray is non-contiguous, so we cannot directly interpret as a one-dimensional ndarray... @@ -288,10 +253,7 @@ function strategy( x ) { } // At this point, we're dealing with a non-contiguous multi-dimensional ndarray, so we need to copy to a contiguous workspace: workspace = ndarraylike2object( emptyLike( ndarraylike2ndarray( x ) ) ); - return { - 'input': copyToWorkspace( len, workspace ), - 'output': copyFromWorkspace( workspace ) - }; + return copyToWorkspace( len, workspace ); } From 4c5c84a6e148ee27b27400be1ba9520bd07b634e Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Wed, 30 Jul 2025 10:04:46 +0000 Subject: [PATCH 4/4] feat: add remaining kernels --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../ndarray/base/nullary-strided1d/README.md | 6 +- .../ndarray/base/nullary-strided1d/lib/10d.js | 327 ++++++++++++++ .../base/nullary-strided1d/lib/10d_blocked.js | 413 ++++++++++++++++++ .../ndarray/base/nullary-strided1d/lib/4d.js | 229 ++++++++++ .../base/nullary-strided1d/lib/4d_blocked.js | 275 ++++++++++++ .../ndarray/base/nullary-strided1d/lib/5d.js | 245 +++++++++++ .../base/nullary-strided1d/lib/5d_blocked.js | 298 +++++++++++++ .../ndarray/base/nullary-strided1d/lib/6d.js | 263 +++++++++++ .../base/nullary-strided1d/lib/6d_blocked.js | 321 ++++++++++++++ .../ndarray/base/nullary-strided1d/lib/7d.js | 279 ++++++++++++ .../base/nullary-strided1d/lib/7d_blocked.js | 344 +++++++++++++++ .../ndarray/base/nullary-strided1d/lib/8d.js | 295 +++++++++++++ .../base/nullary-strided1d/lib/8d_blocked.js | 367 ++++++++++++++++ .../ndarray/base/nullary-strided1d/lib/9d.js | 311 +++++++++++++ .../base/nullary-strided1d/lib/9d_blocked.js | 391 +++++++++++++++++ 15 files changed, 4361 insertions(+), 3 deletions(-) create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d_blocked.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d.js create mode 100644 lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d_blocked.js diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md index 136e9dad386d..ff205daa9f17 100644 --- a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/README.md @@ -183,14 +183,14 @@ console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); var sortOrder = { 'dtype': 'generic', - 'data': [ 0.0 ], - 'shape': [ 1, 2 ], + 'data': [ 1.0 ], + 'shape': [ 2 ], 'strides': [ 0, 0 ], 'offset': 0, 'order': 'row-major' }; -nullaryStrided1d( wrapper, [ x, sortOrder ], [ 1 ] ); +nullaryStrided1d( wrapper, [ x, sortOrder ], [ 0, 1 ] ); console.log( ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ) ); ``` diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d.js new file mode 100644 index 000000000000..0ab6b8a17719 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d.js @@ -0,0 +1,327 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary10d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] ] ] ] +*/ +function nullary10d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-statements + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var dv7; + var dv8; + var dv9; + var S0; + var S1; + var S2; + var S3; + var S4; + var S5; + var S6; + var S7; + var S8; + var S9; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var i7; + var i8; + var i9; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 9 ]; + S1 = shape[ 8 ]; + S2 = shape[ 7 ]; + S3 = shape[ 6 ]; + S4 = shape[ 5 ]; + S5 = shape[ 4 ]; + S6 = shape[ 3 ]; + S7 = shape[ 2 ]; + S8 = shape[ 1 ]; + S9 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[9] + ]; + dv1 = [ + stridesX[8] - ( S0*stridesX[9] ) + ]; + dv2 = [ + stridesX[7] - ( S1*stridesX[8] ) + ]; + dv3 = [ + stridesX[6] - ( S2*stridesX[7] ) + ]; + dv4 = [ + stridesX[5] - ( S3*stridesX[6] ) + ]; + dv5 = [ + stridesX[4] - ( S4*stridesX[5] ) + ]; + dv6 = [ + stridesX[3] - ( S5*stridesX[4] ) + ]; + dv7 = [ + stridesX[2] - ( S6*stridesX[3] ) + ]; + dv8 = [ + stridesX[1] - ( S7*stridesX[2] ) + ]; + dv9 = [ // offset increment for outermost loop + stridesX[0] - ( S8*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[9] ); + dv1.push( sv[8] - ( S0*sv[9] ) ); + dv2.push( sv[7] - ( S1*sv[8] ) ); + dv3.push( sv[6] - ( S2*sv[7] ) ); + dv4.push( sv[5] - ( S3*sv[6] ) ); + dv5.push( sv[4] - ( S4*sv[5] ) ); + dv6.push( sv[3] - ( S5*sv[4] ) ); + dv7.push( sv[2] - ( S6*sv[3] ) ); + dv8.push( sv[1] - ( S7*sv[2] ) ); + dv9.push( sv[0] - ( S8*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + S4 = shape[ 4 ]; + S5 = shape[ 5 ]; + S6 = shape[ 6 ]; + S7 = shape[ 7 ]; + S8 = shape[ 8 ]; + S9 = shape[ 9 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[2] ) + ]; + dv4 = [ + stridesX[4] - ( S3*stridesX[3] ) + ]; + dv5 = [ + stridesX[5] - ( S4*stridesX[4] ) + ]; + dv6 = [ + stridesX[6] - ( S5*stridesX[5] ) + ]; + dv7 = [ + stridesX[7] - ( S6*stridesX[6] ) + ]; + dv8 = [ + stridesX[8] - ( S7*stridesX[7] ) + ]; + dv9 = [ // offset increment for outermost loop + stridesX[9] - ( S8*stridesX[8] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + dv4.push( sv[4] - ( S3*sv[3] ) ); + dv5.push( sv[5] - ( S4*sv[4] ) ); + dv6.push( sv[6] - ( S5*sv[5] ) ); + dv7.push( sv[7] - ( S6*sv[6] ) ); + dv8.push( sv[8] - ( S7*sv[7] ) ); + dv9.push( sv[9] - ( S8*sv[8] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i9 = 0; i9 < S9; i9++ ) { + for ( i8 = 0; i8 < S8; i8++ ) { + for ( i7 = 0; i7 < S7; i7++ ) { + for ( i6 = 0; i6 < S6; i6++ ) { + for ( i5 = 0; i5 < S5; i5++ ) { + for ( i4 = 0; i4 < S4; i4++ ) { + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + incrementOffsets( iv, dv7 ); + } + incrementOffsets( iv, dv8 ); + } + incrementOffsets( iv, dv9 ); + } +} + + +// EXPORTS // + +module.exports = nullary10d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d_blocked.js new file mode 100644 index 000000000000..b5d8e12f75eb --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/10d_blocked.js @@ -0,0 +1,413 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary10d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] ] ] ] +*/ +function blockednullary10d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-statements, max-lines-per-function + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var dv7; + var dv8; + var dv9; + var ov1; + var ov2; + var ov3; + var ov4; + var ov5; + var ov6; + var ov7; + var ov8; + var ov9; + var sh; + var s0; + var s1; + var s2; + var s3; + var s4; + var s5; + var s6; + var s7; + var s8; + var s9; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var i7; + var i8; + var i9; + var j0; + var j1; + var j2; + var j3; + var j4; + var j5; + var j6; + var j7; + var j8; + var j9; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + ov4 = zeros( N ); + ov5 = zeros( N ); + ov6 = zeros( N ); + ov7 = zeros( N ); + ov8 = zeros( N ); + ov9 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + dv4 = zeros( N ); + dv5 = zeros( N ); + dv6 = zeros( N ); + dv7 = zeros( N ); + dv8 = zeros( N ); + dv9 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j9 = sh[9]; j9 > 0; ) { + if ( j9 < bsize ) { + s9 = j9; + j9 = 0; + } else { + s9 = bsize; + j9 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov9[ k ] = ov[k] + ( j9*sv[k][9] ); + } + for ( j8 = sh[8]; j8 > 0; ) { + if ( j8 < bsize ) { + s8 = j8; + j8 = 0; + } else { + s8 = bsize; + j8 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv9 = sv[k][9] - ( s8*sv[k][8] ); + ov8[ k ] = ov9[k] + ( j8*sv[k][8] ); + } + for ( j7 = sh[7]; j7 > 0; ) { + if ( j7 < bsize ) { + s7 = j7; + j7 = 0; + } else { + s7 = bsize; + j7 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv8 = sv[k][8] - ( s7*sv[k][7] ); + ov7[ k ] = ov8[k] + ( j7*sv[k][7] ); + } + for ( j6 = sh[6]; j6 > 0; ) { + if ( j6 < bsize ) { + s6 = j6; + j6 = 0; + } else { + s6 = bsize; + j6 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv7 = sv[k][7] - ( s6*sv[k][6] ); + ov6[ k ] = ov7[k] + ( j6*sv[k][6] ); + } + for ( j5 = sh[5]; j5 > 0; ) { + if ( j5 < bsize ) { + s5 = j5; + j5 = 0; + } else { + s5 = bsize; + j5 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv6 = sv[k][6] - ( s5*sv[k][5] ); + ov5[ k ] = ov6[k] + ( j5*sv[k][5] ); + } + for ( j4 = sh[4]; j4 > 0; ) { + if ( j4 < bsize ) { + s4 = j4; + j4 = 0; + } else { + s4 = bsize; + j4 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv5 = sv[k][5] - ( s4*sv[k][4] ); + ov4[ k ] = ov5[k] + ( j4*sv[k][4] ); + } + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv4[ k ] = sv[k][4] - ( s3*sv[k][3] ); + ov3[ k ] = ov4[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i9 = 0; i9 < s9; i9++ ) { + for ( i8 = 0; i8 < s8; i8++ ) { + for ( i7 = 0; i7 < s7; i7++ ) { + for ( i6 = 0; i6 < s6; i6++ ) { + for ( i5 = 0; i5 < s5; i5++ ) { + for ( i4 = 0; i4 < s4; i4++ ) { + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + incrementOffsets( iv, dv7 ); + } + incrementOffsets( iv, dv8 ); + } + incrementOffsets( iv, dv9 ); + } + } + } + } + } + } + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary10d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d.js new file mode 100644 index 000000000000..7328968a3d7c --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d.js @@ -0,0 +1,229 @@ +/** +* @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 copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary4d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 3 ], [ 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] +*/ +function nullary4d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len + var dv0; + var dv1; + var dv2; + var dv3; + var S0; + var S1; + var S2; + var S3; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 3 ]; + S1 = shape[ 2 ]; + S2 = shape[ 1 ]; + S3 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[3] + ]; + dv1 = [ + stridesX[2] - ( S0*stridesX[3] ) + ]; + dv2 = [ + stridesX[1] - ( S1*stridesX[2] ) + ]; + dv3 = [ // offset increment for outermost loop + stridesX[0] - ( S2*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[3] ); + dv1.push( sv[2] - ( S0*sv[3] ) ); + dv2.push( sv[1] - ( S1*sv[2] ) ); + dv3.push( sv[0] - ( S2*sv[1]) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ // offset increment for outermost loop + stridesX[3] - ( S2*stridesX[2] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } +} + + +// EXPORTS // + +module.exports = nullary4d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d_blocked.js new file mode 100644 index 000000000000..f0a360e7354b --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/4d_blocked.js @@ -0,0 +1,275 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary4d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 3 ], [ 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] +*/ +function blockednullary4d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-len + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var ov1; + var ov2; + var ov3; + var sh; + var s0; + var s1; + var s2; + var s3; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var j0; + var j1; + var j2; + var j3; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov3[ k ] = ov[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary4d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d.js new file mode 100644 index 000000000000..4aa5337223d0 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d.js @@ -0,0 +1,245 @@ +/** +* @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 copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary5d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] +*/ +function nullary5d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var S0; + var S1; + var S2; + var S3; + var S4; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 4 ]; + S1 = shape[ 3 ]; + S2 = shape[ 2 ]; + S3 = shape[ 1 ]; + S4 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[4] + ]; + dv1 = [ + stridesX[3] - ( S0*stridesX[4] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[3] ) + ]; + dv3 = [ + stridesX[1] - ( S2*stridesX[2] ) + ]; + dv4 = [ // offset increment for outermost loop + stridesX[0] - ( S3*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[4] ); + dv1.push( sv[3] - ( S0*sv[4] ) ); + dv2.push( sv[2] - ( S1*sv[3] ) ); + dv3.push( sv[1] - ( S2*sv[2] ) ); + dv4.push( sv[0] - ( S3*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + S4 = shape[ 4 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[2] ) + ]; + dv4 = [ // offset increment for outermost loop + stridesX[4] - ( S3*stridesX[3] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + dv4.push( sv[4] - ( S3*sv[3] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i4 = 0; i4 < S4; i4++ ) { + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } +} + + +// EXPORTS // + +module.exports = nullary5d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d_blocked.js new file mode 100644 index 000000000000..365119dd3e46 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/5d_blocked.js @@ -0,0 +1,298 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary5d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] +*/ +function blockednullary5d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-statements + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var ov1; + var ov2; + var ov3; + var ov4; + var sh; + var s0; + var s1; + var s2; + var s3; + var s4; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var j0; + var j1; + var j2; + var j3; + var j4; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + ov4 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + dv4 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j4 = sh[4]; j4 > 0; ) { + if ( j4 < bsize ) { + s4 = j4; + j4 = 0; + } else { + s4 = bsize; + j4 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov4[ k ] = ov[k] + ( j4*sv[k][4] ); + } + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv4[ k ] = sv[k][4] - ( s3*sv[k][3] ); + ov3[ k ] = ov4[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i4 = 0; i4 < s4; i4++ ) { + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary5d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d.js new file mode 100644 index 000000000000..9ac02b73a907 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d.js @@ -0,0 +1,263 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth */ + +'use strict'; + +// MODULES // + +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary6d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] +*/ +function nullary6d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var S0; + var S1; + var S2; + var S3; + var S4; + var S5; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 5 ]; + S1 = shape[ 4 ]; + S2 = shape[ 3 ]; + S3 = shape[ 2 ]; + S4 = shape[ 1 ]; + S5 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[5] + ]; + dv1 = [ + stridesX[4] - ( S0*stridesX[5] ) + ]; + dv2 = [ + stridesX[3] - ( S1*stridesX[4] ) + ]; + dv3 = [ + stridesX[2] - ( S2*stridesX[3] ) + ]; + dv4 = [ + stridesX[1] - ( S3*stridesX[2] ) + ]; + dv5 = [ // offset increment for outermost loop + stridesX[0] - ( S4*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[5] ); + dv1.push( sv[4] - ( S0*sv[5] ) ); + dv2.push( sv[3] - ( S1*sv[4] ) ); + dv3.push( sv[2] - ( S2*sv[3] ) ); + dv4.push( sv[1] - ( S3*sv[2] ) ); + dv5.push( sv[0] - ( S4*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + S4 = shape[ 4 ]; + S5 = shape[ 5 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[2] ) + ]; + dv4 = [ + stridesX[4] - ( S3*stridesX[3] ) + ]; + dv5 = [ // offset increment for outermost loop + stridesX[5] - ( S4*stridesX[4] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + dv4.push( sv[4] - ( S3*sv[3] ) ); + dv5.push( sv[5] - ( S4*sv[4] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i5 = 0; i5 < S5; i5++ ) { + for ( i4 = 0; i4 < S4; i4++ ) { + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } +} + + +// EXPORTS // + +module.exports = nullary6d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d_blocked.js new file mode 100644 index 000000000000..f81a1f226ecb --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/6d_blocked.js @@ -0,0 +1,321 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary6d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] +*/ +function blockednullary6d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-statements + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var ov1; + var ov2; + var ov3; + var ov4; + var ov5; + var sh; + var s0; + var s1; + var s2; + var s3; + var s4; + var s5; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var j0; + var j1; + var j2; + var j3; + var j4; + var j5; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + ov4 = zeros( N ); + ov5 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + dv4 = zeros( N ); + dv5 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j5 = sh[5]; j5 > 0; ) { + if ( j5 < bsize ) { + s5 = j5; + j5 = 0; + } else { + s5 = bsize; + j5 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov5[ k ] = ov[k] + ( j5*sv[k][5] ); + } + for ( j4 = sh[4]; j4 > 0; ) { + if ( j4 < bsize ) { + s4 = j4; + j4 = 0; + } else { + s4 = bsize; + j4 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv5 = sv[k][5] - ( s4*sv[k][4] ); + ov4[ k ] = ov5[k] + ( j4*sv[k][4] ); + } + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv4[ k ] = sv[k][4] - ( s3*sv[k][3] ); + ov3[ k ] = ov4[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i5 = 0; i5 < s5; i5++ ) { + for ( i4 = 0; i4 < s4; i4++ ) { + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + } + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary6d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d.js new file mode 100644 index 000000000000..002d5d8c163f --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d.js @@ -0,0 +1,279 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth */ + +'use strict'; + +// MODULES // + +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary7d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] +*/ +function nullary7d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var S0; + var S1; + var S2; + var S3; + var S4; + var S5; + var S6; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 6 ]; + S1 = shape[ 5 ]; + S2 = shape[ 4 ]; + S3 = shape[ 3 ]; + S4 = shape[ 2 ]; + S5 = shape[ 1 ]; + S6 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[6] + ]; + dv1 = [ + stridesX[5] - ( S0*stridesX[6] ) + ]; + dv2 = [ + stridesX[4] - ( S1*stridesX[5] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[4] ) + ]; + dv4 = [ + stridesX[2] - ( S3*stridesX[3] ) + ]; + dv5 = [ + stridesX[1] - ( S4*stridesX[2] ) + ]; + dv6 = [ // offset increment for outermost loop + stridesX[0] - ( S5*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[6] ); + dv1.push( sv[5] - ( S0*sv[6] ) ); + dv2.push( sv[4] - ( S1*sv[5] ) ); + dv3.push( sv[3] - ( S2*sv[4] ) ); + dv4.push( sv[2] - ( S3*sv[3] ) ); + dv5.push( sv[1] - ( S4*sv[2] ) ); + dv6.push( sv[0] - ( S5*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + S4 = shape[ 4 ]; + S5 = shape[ 5 ]; + S6 = shape[ 6 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[2] ) + ]; + dv4 = [ + stridesX[4] - ( S3*stridesX[3] ) + ]; + dv5 = [ + stridesX[5] - ( S4*stridesX[4] ) + ]; + dv6 = [ // offset increment for outermost loop + stridesX[6] - ( S5*stridesX[5] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + dv4.push( sv[4] - ( S3*sv[3] ) ); + dv5.push( sv[5] - ( S4*sv[4] ) ); + dv6.push( sv[6] - ( S5*sv[5] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i6 = 0; i6 < S6; i6++ ) { + for ( i5 = 0; i5 < S5; i5++ ) { + for ( i4 = 0; i4 < S4; i4++ ) { + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } +} + + +// EXPORTS // + +module.exports = nullary7d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d_blocked.js new file mode 100644 index 000000000000..17bb1c5723a8 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/7d_blocked.js @@ -0,0 +1,344 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary7d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] +*/ +function blockednullary7d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-statements + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var ov1; + var ov2; + var ov3; + var ov4; + var ov5; + var ov6; + var sh; + var s0; + var s1; + var s2; + var s3; + var s4; + var s5; + var s6; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var j0; + var j1; + var j2; + var j3; + var j4; + var j5; + var j6; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + ov4 = zeros( N ); + ov5 = zeros( N ); + ov6 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + dv4 = zeros( N ); + dv5 = zeros( N ); + dv6 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j6 = sh[6]; j6 > 0; ) { + if ( j6 < bsize ) { + s6 = j6; + j6 = 0; + } else { + s6 = bsize; + j6 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov6[ k ] = ov[k] + ( j6*sv[k][6] ); + } + for ( j5 = sh[5]; j5 > 0; ) { + if ( j5 < bsize ) { + s5 = j5; + j5 = 0; + } else { + s5 = bsize; + j5 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv6 = sv[k][6] - ( s5*sv[k][5] ); + ov5[ k ] = ov6[k] + ( j5*sv[k][5] ); + } + for ( j4 = sh[4]; j4 > 0; ) { + if ( j4 < bsize ) { + s4 = j4; + j4 = 0; + } else { + s4 = bsize; + j4 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv5 = sv[k][5] - ( s4*sv[k][4] ); + ov4[ k ] = ov5[k] + ( j4*sv[k][4] ); + } + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv4[ k ] = sv[k][4] - ( s3*sv[k][3] ); + ov3[ k ] = ov4[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i6 = 0; i6 < s6; i6++ ) { + for ( i5 = 0; i5 < s5; i5++ ) { + for ( i4 = 0; i4 < s4; i4++ ) { + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + } + } + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary7d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d.js new file mode 100644 index 000000000000..f556ed7a40f7 --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d.js @@ -0,0 +1,295 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth */ + +'use strict'; + +// MODULES // + +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary8d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] ] +*/ +function nullary8d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-len, max-statements + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var dv7; + var S0; + var S1; + var S2; + var S3; + var S4; + var S5; + var S6; + var S7; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var i7; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 7 ]; + S1 = shape[ 6 ]; + S2 = shape[ 5 ]; + S3 = shape[ 4 ]; + S4 = shape[ 3 ]; + S5 = shape[ 2 ]; + S6 = shape[ 1 ]; + S7 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[7] + ]; + dv1 = [ + stridesX[6] - ( S0*stridesX[7] ) + ]; + dv2 = [ + stridesX[5] - ( S1*stridesX[6] ) + ]; + dv3 = [ + stridesX[4] - ( S2*stridesX[5] ) + ]; + dv4 = [ + stridesX[3] - ( S3*stridesX[4] ) + ]; + dv5 = [ + stridesX[2] - ( S4*stridesX[3] ) + ]; + dv6 = [ + stridesX[1] - ( S5*stridesX[2] ) + ]; + dv7 = [ // offset increment for outermost loop + stridesX[0] - ( S6*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[7] ); + dv1.push( sv[6] - ( S0*sv[7] ) ); + dv2.push( sv[5] - ( S1*sv[6] ) ); + dv3.push( sv[4] - ( S2*sv[5] ) ); + dv4.push( sv[3] - ( S3*sv[4] ) ); + dv5.push( sv[2] - ( S4*sv[3] ) ); + dv6.push( sv[1] - ( S5*sv[2] ) ); + dv7.push( sv[0] - ( S6*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + S4 = shape[ 4 ]; + S5 = shape[ 5 ]; + S6 = shape[ 6 ]; + S7 = shape[ 7 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[2] ) + ]; + dv4 = [ + stridesX[4] - ( S3*stridesX[3] ) + ]; + dv5 = [ + stridesX[5] - ( S4*stridesX[4] ) + ]; + dv6 = [ + stridesX[6] - ( S5*stridesX[5] ) + ]; + dv7 = [ // offset increment for outermost loop + stridesX[7] - ( S6*stridesX[6] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + dv4.push( sv[4] - ( S3*sv[3] ) ); + dv5.push( sv[5] - ( S4*sv[4] ) ); + dv6.push( sv[6] - ( S5*sv[5] ) ); + dv7.push( sv[7] - ( S6*sv[6] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i7 = 0; i7 < S7; i7++ ) { + for ( i6 = 0; i6 < S6; i6++ ) { + for ( i5 = 0; i5 < S5; i5++ ) { + for ( i4 = 0; i4 < S4; i4++ ) { + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + incrementOffsets( iv, dv7 ); + } +} + + +// EXPORTS // + +module.exports = nullary8d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d_blocked.js new file mode 100644 index 000000000000..4d8dab40b51f --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/8d_blocked.js @@ -0,0 +1,367 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary8d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] ] +*/ +function blockednullary8d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-statements, max-lines-per-function + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var dv7; + var ov1; + var ov2; + var ov3; + var ov4; + var ov5; + var ov6; + var ov7; + var sh; + var s0; + var s1; + var s2; + var s3; + var s4; + var s5; + var s6; + var s7; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var i7; + var j0; + var j1; + var j2; + var j3; + var j4; + var j5; + var j6; + var j7; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + ov4 = zeros( N ); + ov5 = zeros( N ); + ov6 = zeros( N ); + ov7 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + dv4 = zeros( N ); + dv5 = zeros( N ); + dv6 = zeros( N ); + dv7 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j7 = sh[7]; j7 > 0; ) { + if ( j7 < bsize ) { + s7 = j7; + j7 = 0; + } else { + s7 = bsize; + j7 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov7[ k ] = ov[k] + ( j7*sv[k][7] ); + } + for ( j6 = sh[6]; j6 > 0; ) { + if ( j6 < bsize ) { + s6 = j6; + j6 = 0; + } else { + s6 = bsize; + j6 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv7 = sv[k][7] - ( s6*sv[k][6] ); + ov6[ k ] = ov7[k] + ( j6*sv[k][6] ); + } + for ( j5 = sh[5]; j5 > 0; ) { + if ( j5 < bsize ) { + s5 = j5; + j5 = 0; + } else { + s5 = bsize; + j5 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv6 = sv[k][6] - ( s5*sv[k][5] ); + ov5[ k ] = ov6[k] + ( j5*sv[k][5] ); + } + for ( j4 = sh[4]; j4 > 0; ) { + if ( j4 < bsize ) { + s4 = j4; + j4 = 0; + } else { + s4 = bsize; + j4 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv5 = sv[k][5] - ( s4*sv[k][4] ); + ov4[ k ] = ov5[k] + ( j4*sv[k][4] ); + } + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv4[ k ] = sv[k][4] - ( s3*sv[k][3] ); + ov3[ k ] = ov4[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i7 = 0; i7 < s7; i7++ ) { + for ( i6 = 0; i6 < s6; i6++ ) { + for ( i5 = 0; i5 < s5; i5++ ) { + for ( i4 = 0; i4 < s4; i4++ ) { + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + incrementOffsets( iv, dv7 ); + } + } + } + } + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary8d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d.js new file mode 100644 index 000000000000..98ca9c4929ec --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d.js @@ -0,0 +1,311 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {boolean} isRowMajor - boolean indicating if provided arrays are in row-major order +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* nullary9d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 12, 12, 4 ], true, strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] ] ] +*/ +function nullary9d( fcn, arrays, views, shape, stridesX, isRowMajor, strategyX, opts ) { // eslint-disable-line max-statements + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var dv7; + var dv8; + var S0; + var S1; + var S2; + var S3; + var S4; + var S5; + var S6; + var S7; + var S8; + var sv; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var i7; + var i8; + var v; + var i; + + // Note on variable naming convention: S#, dv#, i# where # corresponds to the loop number, with `0` being the innermost loop... + + // Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... + if ( isRowMajor ) { + // For row-major ndarrays, the last dimensions have the fastest changing indices... + S0 = shape[ 8 ]; + S1 = shape[ 7 ]; + S2 = shape[ 6 ]; + S3 = shape[ 5 ]; + S4 = shape[ 4 ]; + S5 = shape[ 3 ]; + S6 = shape[ 2 ]; + S7 = shape[ 1 ]; + S8 = shape[ 0 ]; + dv0 = [ // offset increment for innermost loop + stridesX[8] + ]; + dv1 = [ + stridesX[7] - ( S0*stridesX[8] ) + ]; + dv2 = [ + stridesX[6] - ( S1*stridesX[7] ) + ]; + dv3 = [ + stridesX[5] - ( S2*stridesX[6] ) + ]; + dv4 = [ + stridesX[4] - ( S3*stridesX[5] ) + ]; + dv5 = [ + stridesX[3] - ( S4*stridesX[4] ) + ]; + dv6 = [ + stridesX[2] - ( S5*stridesX[3] ) + ]; + dv7 = [ + stridesX[1] - ( S6*stridesX[2] ) + ]; + dv8 = [ // offset increment for outermost loop + stridesX[0] - ( S7*stridesX[1] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[8] ); + dv1.push( sv[7] - ( S0*sv[8] ) ); + dv2.push( sv[6] - ( S1*sv[7] ) ); + dv3.push( sv[5] - ( S2*sv[6] ) ); + dv4.push( sv[4] - ( S3*sv[5] ) ); + dv5.push( sv[3] - ( S4*sv[4] ) ); + dv6.push( sv[2] - ( S5*sv[3] ) ); + dv7.push( sv[1] - ( S6*sv[2] ) ); + dv8.push( sv[0] - ( S7*sv[1] ) ); + } + } else { // order === 'column-major' + // For column-major ndarrays, the first dimensions have the fastest changing indices... + S0 = shape[ 0 ]; + S1 = shape[ 1 ]; + S2 = shape[ 2 ]; + S3 = shape[ 3 ]; + S4 = shape[ 4 ]; + S5 = shape[ 5 ]; + S6 = shape[ 6 ]; + S7 = shape[ 7 ]; + S8 = shape[ 8 ]; + dv0 = [ // offset increment for innermost loop + stridesX[0] + ]; + dv1 = [ + stridesX[1] - ( S0*stridesX[0] ) + ]; + dv2 = [ + stridesX[2] - ( S1*stridesX[1] ) + ]; + dv3 = [ + stridesX[3] - ( S2*stridesX[2] ) + ]; + dv4 = [ + stridesX[4] - ( S3*stridesX[3] ) + ]; + dv5 = [ + stridesX[5] - ( S4*stridesX[4] ) + ]; + dv6 = [ + stridesX[6] - ( S5*stridesX[5] ) + ]; + dv7 = [ + stridesX[7] - ( S6*stridesX[6] ) + ]; + dv8 = [ // offset increment for outermost loop + stridesX[8] - ( S7*stridesX[7] ) + ]; + for ( i = 1; i < arrays.length; i++ ) { + sv = arrays[ i ].strides; + dv0.push( sv[0] ); + dv1.push( sv[1] - ( S0*sv[0] ) ); + dv2.push( sv[2] - ( S1*sv[1] ) ); + dv3.push( sv[3] - ( S2*sv[2] ) ); + dv4.push( sv[4] - ( S3*sv[3] ) ); + dv5.push( sv[5] - ( S4*sv[4] ) ); + dv6.push( sv[6] - ( S5*sv[5] ) ); + dv7.push( sv[7] - ( S6*sv[6] ) ); + dv8.push( sv[8] - ( S7*sv[7] ) ); + } + } + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + iv = offsets( arrays ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over the loop dimensions... + for ( i8 = 0; i8 < S8; i8++ ) { + for ( i7 = 0; i7 < S7; i7++ ) { + for ( i6 = 0; i6 < S6; i6++ ) { + for ( i5 = 0; i5 < S5; i5++ ) { + for ( i4 = 0; i4 < S4; i4++ ) { + for ( i3 = 0; i3 < S3; i3++ ) { + for ( i2 = 0; i2 < S2; i2++ ) { + for ( i1 = 0; i1 < S1; i1++ ) { + for ( i0 = 0; i0 < S0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + incrementOffsets( iv, dv7 ); + } + incrementOffsets( iv, dv8 ); + } +} + + +// EXPORTS // + +module.exports = nullary9d; diff --git a/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d_blocked.js b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d_blocked.js new file mode 100644 index 000000000000..9eaf23cc158d --- /dev/null +++ b/lib/node_modules/@stdlib/ndarray/base/nullary-strided1d/lib/9d_blocked.js @@ -0,0 +1,391 @@ +/** +* @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. +*/ + +/* eslint-disable max-depth, max-len */ + +'use strict'; + +// MODULES // + +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +var blockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +var takeIndexed = require( '@stdlib/array/base/take-indexed' ); +var copyIndexed = require( '@stdlib/array/base/copy-indexed' ); +var zeros = require( '@stdlib/array/base/zeros' ); +var incrementOffsets = require( './increment_offsets.js' ); +var setViewOffsets = require( './set_view_offsets.js' ); +var offsets = require( './offsets.js' ); + + +// MAIN // + +/** +* Applies a one-dimensional strided array function to a list of specified dimensions in an input ndarray via loop blocking. +* +* @private +* @param {Function} fcn - wrapper for a one-dimensional strided array reduction function +* @param {Array} arrays - ndarrays +* @param {Array} views - initialized ndarray-like objects representing sub-array views +* @param {NonNegativeIntegerArray} shape - loop dimensions +* @param {IntegerArray} stridesX - loop dimension strides for the input ndarray +* @param {Object} strategyX - strategy for marshaling data to and from an input ndarray view +* @param {Options} opts - function options +* @returns {void} +* +* @example +* var ndarray2array = require( '@stdlib/ndarray/base/to-array' ); +* var getStride = require( '@stdlib/ndarray/base/stride' ); +* var getOffset = require( '@stdlib/ndarray/base/offset' ); +* var getData = require( '@stdlib/ndarray/base/data-buffer' ); +* var numelDimension = require( '@stdlib/ndarray/base/numel-dimension' ); +* var ndarraylike2scalar = require( '@stdlib/ndarray/base/ndarraylike2scalar' ); +* var gsorthp = require( '@stdlib/blas/ext/base/gsorthp' ).ndarray; +* +* function wrapper( arrays ) { +* var x = arrays[ 0 ]; +* var o = arrays[ 1 ]; +* return gsorthp( numelDimension( x, 0 ), ndarraylike2scalar( o ), getData( x ), getStride( x, 0 ), getOffset( x ) ); +* } +* +* // Create data buffers: +* var xbuf = [ 12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ]; +* +* // Define the array shapes: +* var xsh = [ 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2 ]; +* +* // Define the array strides: +* var sx = [ 12, 12, 12, 12, 12, 12, 12, 12, 4, 2, 1 ]; +* +* // Define the index offsets: +* var ox = 0; +* var oy = 0; +* +* // Create an input ndarray-like object: +* var x = { +* 'dtype': 'generic', +* 'data': xbuf, +* 'shape': xsh, +* 'strides': sx, +* 'offset': ox, +* 'order': 'row-major' +* }; +* +* // Create an ndarray-like object for the sort order: +* var sortOrder = { +* 'dtype': 'generic', +* 'data': [ 1.0 ], +* 'shape': [ 1, 1, 1, 1, 1, 1, 1, 1, 3 ], +* 'strides': [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], +* 'offset': 0, +* 'order': 'row-major' +* }; +* +* // Initialize ndarray-like objects representing sub-array views: +* var views = [ +* { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 2, 2 ], +* 'strides': [ 2, 1 ], +* 'offset': x.offset, +* 'order': x.order +* }, +* { +* 'dtype': sortOrder.dtype, +* 'data': sortOrder.data, +* 'shape': [], +* 'strides': [ 0 ], +* 'offset': sortOrder.offset, +* 'order': sortOrder.order +* } +* ]; +* +* // Define an input strategy: +* function strategy( x ) { +* return { +* 'dtype': x.dtype, +* 'data': x.data, +* 'shape': [ 4 ], +* 'strides': [ 1 ], +* 'offset': x.offset, +* 'order': x.order +* }; +* } +* +* // Apply strided function: +* blockednullary9d( wrapper, [ x, sortOrder ], views, [ 1, 1, 1, 1, 1, 1, 1, 1, 3 ], [ 12, 12, 12, 12, 12, 12, 12, 12, 4 ], strategy, {} ); +* +* var arr = ndarray2array( x.data, x.shape, x.strides, x.offset, x.order ); +* // returns [ [ [ [ [ [ [ [ [ [ [ 9.0, 10.0 ], [ 11.0, 12.0 ] ], [ [ 5.0, 6.0 ], [ 7.0, 8.0 ] ], [ [ 1.0, 2.0 ], [ 3.0, 4.0 ] ] ] ] ] ] ] ] ] ] ] +*/ +function blockednullary9d( fcn, arrays, views, shape, stridesX, strategyX, opts ) { // eslint-disable-line max-statements, max-lines-per-function + var bsize; + var dv0; + var dv1; + var dv2; + var dv3; + var dv4; + var dv5; + var dv6; + var dv7; + var dv8; + var ov1; + var ov2; + var ov3; + var ov4; + var ov5; + var ov6; + var ov7; + var ov8; + var sh; + var s0; + var s1; + var s2; + var s3; + var s4; + var s5; + var s6; + var s7; + var s8; + var sv; + var ov; + var iv; + var i0; + var i1; + var i2; + var i3; + var i4; + var i5; + var i6; + var i7; + var i8; + var j0; + var j1; + var j2; + var j3; + var j4; + var j5; + var j6; + var j7; + var j8; + var N; + var x; + var v; + var o; + var k; + + // Note on variable naming convention: S#, dv#, i#, j# where # corresponds to the loop number, with `0` being the innermost loop... + + N = arrays.length; + x = arrays[ 0 ]; + + // Resolve the loop interchange order: + o = loopOrder( shape, stridesX ); + sh = o.sh; + sv = [ o.sx ]; + for ( k = 1; k < N; k++ ) { + sv.push( takeIndexed( arrays[k].strides, o.idx ) ); + } + // Determine the block size: + bsize = blockSize( x.dtype ); + + // Resolve a list of pointers to the first indexed elements in the respective ndarrays: + ov = offsets( arrays ); + + // Cache offset increments for the innermost loop... + dv0 = []; + for ( k = 0; k < N; k++ ) { + dv0.push( sv[k][0] ); + } + // Initialize loop variables... + ov1 = zeros( N ); + ov2 = zeros( N ); + ov3 = zeros( N ); + ov4 = zeros( N ); + ov5 = zeros( N ); + ov6 = zeros( N ); + ov7 = zeros( N ); + ov8 = zeros( N ); + dv1 = zeros( N ); + dv2 = zeros( N ); + dv3 = zeros( N ); + dv4 = zeros( N ); + dv5 = zeros( N ); + dv6 = zeros( N ); + dv7 = zeros( N ); + dv8 = zeros( N ); + iv = zeros( N ); + + // Shallow copy the list of views to an internal array so that we can update with reshaped views without impacting the original list of views: + v = copyIndexed( views ); + + // Iterate over blocks... + for ( j8 = sh[8]; j8 > 0; ) { + if ( j8 < bsize ) { + s8 = j8; + j8 = 0; + } else { + s8 = bsize; + j8 -= bsize; + } + for ( k = 0; k < N; k++ ) { + ov8[ k ] = ov[k] + ( j8*sv[k][8] ); + } + for ( j7 = sh[7]; j7 > 0; ) { + if ( j7 < bsize ) { + s7 = j7; + j7 = 0; + } else { + s7 = bsize; + j7 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv8 = sv[k][8] - ( s7*sv[k][7] ); + ov7[ k ] = ov8[k] + ( j7*sv[k][7] ); + } + for ( j6 = sh[6]; j6 > 0; ) { + if ( j6 < bsize ) { + s6 = j6; + j6 = 0; + } else { + s6 = bsize; + j6 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv7 = sv[k][7] - ( s6*sv[k][6] ); + ov6[ k ] = ov7[k] + ( j6*sv[k][6] ); + } + for ( j5 = sh[5]; j5 > 0; ) { + if ( j5 < bsize ) { + s5 = j5; + j5 = 0; + } else { + s5 = bsize; + j5 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv6 = sv[k][6] - ( s5*sv[k][5] ); + ov5[ k ] = ov6[k] + ( j5*sv[k][5] ); + } + for ( j4 = sh[4]; j4 > 0; ) { + if ( j4 < bsize ) { + s4 = j4; + j4 = 0; + } else { + s4 = bsize; + j4 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv5 = sv[k][5] - ( s4*sv[k][4] ); + ov4[ k ] = ov5[k] + ( j4*sv[k][4] ); + } + for ( j3 = sh[3]; j3 > 0; ) { + if ( j3 < bsize ) { + s3 = j3; + j3 = 0; + } else { + s3 = bsize; + j3 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv4[ k ] = sv[k][4] - ( s3*sv[k][3] ); + ov3[ k ] = ov4[k] + ( j3*sv[k][3] ); + } + for ( j2 = sh[2]; j2 > 0; ) { + if ( j2 < bsize ) { + s2 = j2; + j2 = 0; + } else { + s2 = bsize; + j2 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv3[ k ] = sv[k][3] - ( s2*sv[k][2] ); + ov2[ k ] = ov3[k] + ( j2*sv[k][2] ); + } + for ( j1 = sh[1]; j1 > 0; ) { + if ( j1 < bsize ) { + s1 = j1; + j1 = 0; + } else { + s1 = bsize; + j1 -= bsize; + } + for ( k = 0; k < N; k++ ) { + dv2[ k ] = sv[k][2] - ( s1*sv[k][1] ); + ov1[ k ] = ov2[k] + ( j1*sv[k][1] ); + } + for ( j0 = sh[0]; j0 > 0; ) { + if ( j0 < bsize ) { + s0 = j0; + j0 = 0; + } else { + s0 = bsize; + j0 -= bsize; + } + // Compute index offsets and loop offset increments for the first ndarray elements in the current block... + for ( k = 0; k < N; k++ ) { + iv[ k ] = ov1[k] + ( j0*sv[k][0] ); + dv1[ k ] = sv[k][1] - ( s0*sv[k][0] ); + } + // Iterate over the loop dimensions... + for ( i8 = 0; i8 < s8; i8++ ) { + for ( i7 = 0; i7 < s7; i7++ ) { + for ( i6 = 0; i6 < s6; i6++ ) { + for ( i5 = 0; i5 < s5; i5++ ) { + for ( i4 = 0; i4 < s4; i4++ ) { + for ( i3 = 0; i3 < s3; i3++ ) { + for ( i2 = 0; i2 < s2; i2++ ) { + for ( i1 = 0; i1 < s1; i1++ ) { + for ( i0 = 0; i0 < s0; i0++ ) { + setViewOffsets( views, iv ); + v[ 0 ] = strategyX( views[ 0 ] ); + fcn( v, opts ); + incrementOffsets( iv, dv0 ); + } + incrementOffsets( iv, dv1 ); + } + incrementOffsets( iv, dv2 ); + } + incrementOffsets( iv, dv3 ); + } + incrementOffsets( iv, dv4 ); + } + incrementOffsets( iv, dv5 ); + } + incrementOffsets( iv, dv6 ); + } + incrementOffsets( iv, dv7 ); + } + incrementOffsets( iv, dv8 ); + } + } + } + } + } + } + } + } + } + } +} + + +// EXPORTS // + +module.exports = blockednullary9d;