diff --git a/README.md b/README.md index d1ca0e50..19d15c56 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,6 @@ In addition, the namespace contains the following multidimensional array utility - [`ndarrayCastingModes()`][@stdlib/ndarray/casting-modes]: list of ndarray casting modes. - [`defaults()`][@stdlib/ndarray/defaults]: default ndarray settings. - [`dispatch( fcns, types, data, nargs, nin, nout )`][@stdlib/ndarray/dispatch]: create an ndarray function interface which performs multiple dispatch. -- [`dispatch( fcns, types, data, nargs, nin, nout )`][@stdlib/ndarray/dispatch]: create an ndarray function interface which performs multiple dispatch. - [`ndarrayDataTypes( [kind] )`][@stdlib/ndarray/dtypes]: list of ndarray data types. - [`ndemptyLike( x[, options] )`][@stdlib/ndarray/empty-like]: create an uninitialized ndarray having the same shape and data type as a provided ndarray. - [`ndempty( shape[, options] )`][@stdlib/ndarray/empty]: create an uninitialized ndarray having a specified shape and data type. diff --git a/dispatch-by/README.md b/dispatch-by/README.md index 421100d6..f64080e7 100644 --- a/dispatch-by/README.md +++ b/dispatch-by/README.md @@ -18,7 +18,7 @@ limitations under the License. --> -# Dispatch +# dispatchBy > Create an [ndarray][@stdlib/ndarray/ctor] function interface which performs multiple dispatch. @@ -33,78 +33,17 @@ limitations under the License. ## Usage ```javascript -var dispatch = require( '@stdlib/ndarray/dispatch' ); +var dispatchBy = require( '@stdlib/ndarray/dispatch-by' ); ``` -#### dispatch( fcns, types, data, nargs, nin, nout ) +#### dispatchBy( fcns, types, data, nargs, nin, nout ) Returns an [ndarray][@stdlib/ndarray/ctor] function interface which performs multiple dispatch. ```javascript -var unary = require( '@stdlib/ndarray/base/unary' ); -var Float64Array = require( '@stdlib/array/float64' ); -var Float32Array = require( '@stdlib/array/float32' ); -var ndarray = require( '@stdlib/ndarray/ctor' ); - -function foo( x ) { - return x * 10.0; -} - -function bar( x ) { - return x * 5.0; -} - -// Define a list of ndarray functions for applying a unary callback: -var fcns = [ - unary, - unary -]; - -// Define a one-dimensional list of input and output array types: -var types = [ - 'float64', 'float64', // input, output - 'float32', 'float32' // input, output -]; - -// Define a list of callbacks which should be applied based on the provided array types: -var data = [ - foo, - bar -]; - -// Define the total number of input arguments: -var nargs = 2; // input_array + output_array - -// Define the number of input ndarrays: -var nin = 1; - -// Define the number of output ndarrays: -var nout = 1; - -// Create an ndarray function interface: -var fcn = dispatch( fcns, types, data, nargs, nin, nout ); - -// ... - -var xbuf = new Float64Array( [ 1.0, 2.0, 3.0 ] ); -var ybuf = new Float64Array( xbuf.length ); - -var x = ndarray( 'float64', xbuf, [ 3 ], [ 1 ], 0, 'row-major' ); -var y = ndarray( 'float64', ybuf, [ 3 ], [ 1 ], 0, 'row-major' ); - -fcn( x, y ); -// ybuf => [ 10.0, 20.0, 30.0 ] - -xbuf = new Float32Array( [ 1.0, 2.0, 3.0 ] ); -ybuf = new Float32Array( xbuf.length ); - -x = ndarray( 'float32', xbuf, [ 3 ], [ 1 ], 0, 'row-major' ); -y = ndarray( 'float32', ybuf, [ 3 ], [ 1 ], 0, 'row-major' ); - -fcn( x, y ); -// ybuf => [ 5.0, 10.0, 15.0 ] +console.log( 'TODO' ); ``` The function accepts the following arguments: @@ -154,7 +93,7 @@ The function accepts the following arguments: ```javascript - var unary = require( '@stdlib/ndarray/base/unary' ); + var unary = require( '@stdlib/ndarray/base/unary-by' ); function foo( x ) { return x * 10.0; @@ -177,7 +116,7 @@ The function accepts the following arguments: bar ]; - var fcn = dispatch( fcns, types, data, 2, 1, 1 ); + var fcn = dispatchBy( fcns, types, data, 2, 1, 1 ); ``` is equivalent to @@ -185,7 +124,7 @@ The function accepts the following arguments: ```javascript - var unary = require( '@stdlib/ndarray/base/unary' ); + var unary = require( '@stdlib/ndarray/base/unary-by' ); function foo( x ) { return x * 10.0; @@ -204,7 +143,7 @@ The function accepts the following arguments: bar ]; - var fcn = dispatch( unary, types, data, 2, 1, 1 ); + var fcn = dispatchBy( unary, types, data, 2, 1, 1 ); ``` @@ -218,29 +157,7 @@ The function accepts the following arguments: ```javascript -var unary = require( '@stdlib/ndarray/base/unary' ); -var ndarray = require( '@stdlib/ndarray/ctor' ); -var abs = require( '@stdlib/math/base/special/abs' ); -var Float64Array = require( '@stdlib/array/float64' ); -var dispatch = require( '@stdlib/ndarray/dispatch' ); - -var types = [ 'float64', 'float64' ]; - -var data = [ - abs -]; - -var absolute = dispatch( unary, types, data, 2, 1, 1 ); - -var xbuf = new Float64Array( [ -1.0, -2.0, -3.0, -4.0, -5.0 ] ); -var ybuf = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] ); - -var x = ndarray( 'float64', xbuf, [ 5 ], [ 1 ], 0, 'row-major' ); -var y = ndarray( 'float64', ybuf, [ 5 ], [ 1 ], 0, 'row-major' ); - -absolute( x, y ); -console.log( ybuf ); -// => [ 1.0, 2.0, 3.0, 4.0, 5.0 ] +console.log( 'TODO' ); ``` diff --git a/fancy/examples/3d.js b/fancy/examples/3d.js index ecd9c407..c8fa1e6e 100644 --- a/fancy/examples/3d.js +++ b/fancy/examples/3d.js @@ -72,24 +72,24 @@ var s = E( 1, S(0,_,2), _ ); // Use the slice to create a view on the original ndarray: var y1 = x[ s ]; console.log( toArray( y1 ) ); -// => [ [ [ 9, 10 ], [ 13, 100 ] ] ] +// => [ [ 9, 10 ], [ 13, 100 ] ] // Use alternative syntax: var y2 = x[ [ 1, S(0,_,2), _ ] ]; console.log( toArray( y2 ) ); -// => [ [ [ 9, 10 ], [ 13, 100 ] ] ] +// => [ [ 9, 10 ], [ 13, 100 ] ] // Use alternative syntax: var y3 = x[ '1,0::2,:' ]; console.log( toArray( y3 ) ); -// => [ [ [ 9, 10 ], [ 13, 100 ] ] ] +// => [ [ 9, 10 ], [ 13, 100 ] ] // Flip dimensions: var y4 = x[ [ 1, S(_,_,-2), S(_,_,-1) ] ]; console.log( toArray( y4 ) ); -// => [ [ [ 100, 13 ], [ 10, 9 ] ] ] +// => [ [ 100, 13 ], [ 10, 9 ] ] // Only the second rows: var y5 = x[ [ _, 1, _ ] ]; console.log( toArray( y5 ) ); -// => [ [ [ 5, 6 ] ], [ [ 11, 12 ] ] ] +// throws [ [ 5, 6 ], [ 11, 12 ] ] diff --git a/fancy/lib/get.nd.js b/fancy/lib/get.nd.js index c14fb23f..8b324a89 100644 --- a/fancy/lib/get.nd.js +++ b/fancy/lib/get.nd.js @@ -24,10 +24,10 @@ var isFunction = require( '@stdlib/assert/is-function' ); var trim = require( '@stdlib/string/base/trim' ); var str2multislice = require( '@stdlib/slice/base/str2multislice' ); var seq2multislice = require( '@stdlib/slice/base/seq2multislice' ); +var sargs2multislice = require( '@stdlib/slice/base/sargs2multislice' ); var format = require( '@stdlib/string/format' ); var hasProperty = require( './has_property.js' ); var RE_SUBSEQ = require( './re_subseq.js' ); -var multisliceWrap = require( './wrap_multislice_arguments.js' ); var sliceView = require( './view.nd.js' ); var empty = require( './empty.js' ); @@ -104,9 +104,9 @@ function get( target, property, receiver ) { } // Case: array syntax (e.g., [ Slice(0,10,1), null, Slice(4,null,-1) ]) - // TODO: => @stdlib/ndarray/base/slice: return slice( receiver, str2multislice( multisliceWrap( prop ) ).data ); // TODO: handle `null` + // TODO: => @stdlib/ndarray/base/slice: return slice( receiver, sargs2multislice( prop ).data ); // TODO: handle `null` - return sliceView( target, '['+property+']', receiver, str2multislice( multisliceWrap( prop ) ) ); + return sliceView( target, '['+property+']', receiver, sargs2multislice( prop ) ); /** * Method wrapper. diff --git a/fancy/lib/nonreduced_dimensions.js b/fancy/lib/nonreduced_dimensions.js deleted file mode 100644 index 076ca78d..00000000 --- a/fancy/lib/nonreduced_dimensions.js +++ /dev/null @@ -1,48 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2023 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 a list of non-reduced dimensions in an un-normalized multi-slice. -* -* @private -* @param {MultiSlice} slice - input slice -* @returns {NonNegativeIntegerArray} list of non-reduced dimensions -*/ -function nonreducedDimensions( slice ) { - var data; - var out; - var i; - - data = slice.data; - out = []; - for ( i = 0; i < data.length; i++ ) { - if ( typeof data[ i ] !== 'number' ) { - out.push( i ); - } - } - return out; -} - - -// EXPORTS // - -module.exports = nonreducedDimensions; diff --git a/fancy/lib/slice_start.js b/fancy/lib/slice_start.js index 919c5691..149f8ca6 100644 --- a/fancy/lib/slice_start.js +++ b/fancy/lib/slice_start.js @@ -26,14 +26,14 @@ var sub2ind = require( './../../base/sub2ind' ); // MAIN // /** -* Resolves the linear index of the first element indexed by a multi-slice. +* Resolves the linear index of the first element indexed by a normalized multi-slice. * * ## Notes * * - If `strides` contains negative strides, if an `offset` is greater than `0`, the function returns a linear index with respect to the underlying data buffer. If an `offset` is equal to `0`, the function returns a linear index with respect to the array view. For more information, see `@stdlib/ndarray/base/sub2ind`. * * @private -* @param {MultiSlice} slice - multi-slice object +* @param {MultiSlice} slice - normalized multi-slice object * @param {NonNegativeIntegerArray} shape - array shape * @param {IntegerArray} strides - array strides * @param {NonNegativeInteger} offset - index offset diff --git a/fancy/lib/slice_strides.js b/fancy/lib/slice_strides.js index b8deb28c..d53e4b09 100644 --- a/fancy/lib/slice_strides.js +++ b/fancy/lib/slice_strides.js @@ -21,10 +21,10 @@ // MAIN // /** -* Resolves slice strides. +* Resolves slice strides for a provided normalized multi-slice object. * * @private -* @param {MultiSlice} slice - multi-slice object +* @param {MultiSlice} slice - normalized multi-slice object * @param {IntegerArray} strides - array strides * @param {NonNegativeIntegerArray} sdims - indices of non-reduced dimensions * @returns {IntegerArray} slice strides diff --git a/fancy/lib/view.nd.js b/fancy/lib/view.nd.js index afb0456b..b8090967 100644 --- a/fancy/lib/view.nd.js +++ b/fancy/lib/view.nd.js @@ -21,12 +21,12 @@ // MODULES // var normalizeMultiSlice = require( '@stdlib/slice/base/normalize-multi-slice' ); +var nonreducedDimensions = require( '@stdlib/slice/base/nonreduced-dimensions' ); var sliceShape = require( '@stdlib/slice/base/shape' ); var take = require( '@stdlib/array/base/take' ); var vind2bind = require( './../../base/vind2bind' ); var numel = require( './../../base/numel' ); var format = require( '@stdlib/string/format' ); -var nonreducedDimensions = require( './nonreduced_dimensions.js' ); var sliceStart = require( './slice_start.js' ); var sliceStrides = require( './slice_strides.js' ); var options = require( './array_options.js' ); @@ -58,6 +58,7 @@ function sliceView( target, property, receiver, slice ) { var sdims; var ctor; var sh; + var ns; // Verify that we were successfully able to create a multi-slice: if ( slice === null ) { @@ -76,17 +77,17 @@ function sliceView( target, property, receiver, slice ) { throw new RangeError( format( 'invalid operation. Number of array dimensions does not match the number of slice dimensions. Array shape: (%s). Slice dimensions: %u.', shape.join( ',' ), slice.ndims ) ); } // Normalize the slice object based on the array shape: - slice = normalizeMultiSlice( slice, shape, true ); + ns = normalizeMultiSlice( slice, shape, true ); // In strict mode, if the slice exceeds array bounds, raise an exception... - if ( slice.code && strict ) { + if ( ns.code && strict ) { throw new RangeError( format( 'invalid operation. Slice exceeds array bounds. Array shape: (%s).', shape.join( ',' ) ) ); } // Resolve the output array constructor: ctor = receiver.constructor; // Compute the slice shape: - sh = sliceShape( slice ); + sh = sliceShape( ns ); // Resolve the indices of the non-reduced dimensions: sdims = nonreducedDimensions( slice ); @@ -96,7 +97,7 @@ function sliceView( target, property, receiver, slice ) { return empty( ctor, dtype, take( sh, sdims ), order ); } // Resolve the index offset of the first element: - offset = vind2bind( shape, strides, offset, order, sliceStart( slice, shape, strides, 0 ), 'throw' ); + offset = vind2bind( shape, strides, offset, order, sliceStart( ns, shape, strides, 0 ), 'throw' ); // TODO: @stdlib/ndarray/base/sind2bind // Remove reduced dimensions from the slice shape: sh = take( sh, sdims ); @@ -106,7 +107,7 @@ function sliceView( target, property, receiver, slice ) { return new ctor( dtype, target.data, [], [ 0 ], offset, order, options() ); // eslint-disable-line max-len } // Update strides according to slice steps: - strides = sliceStrides( slice, strides, sdims ); + strides = sliceStrides( ns, strides, sdims ); // Return a slice view: return new ctor( dtype, target.data, sh, strides, offset, order, options() ); // eslint-disable-line max-len diff --git a/fancy/lib/wrap_multislice_arguments.js b/fancy/lib/wrap_multislice_arguments.js deleted file mode 100644 index 9f2f3703..00000000 --- a/fancy/lib/wrap_multislice_arguments.js +++ /dev/null @@ -1,62 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2023 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 replace = require( '@stdlib/string/base/replace' ); - - -// MAIN // - -/** -* Returns string-serialized array elements as arguments to the MultiSlice constructor. -* -* @private -* @param {string} str - array elements serialized as a string -* @returns {string} wrapped arguments -* -* @example -* var args = wrap( ',Slice(0,10,1)' ); -* // returns 'MultiSlice(null,Slice(0,10,1))' -* -* @example -* var args = wrap( 'Slice(0,10,1),' ); -* // returns 'MultiSlice(Slice(0,10,1),null)' -* -* @example -* var args = wrap( 'Slice(0,10,1),,,Slice(0,10,1)' ); -* // returns 'MultiSlice(Slice(0,10,1),null,null,Slice(0,10,1))' -* -* @example -* var args = wrap( ',Slice(0,10,1),null,,Slice(2,9,2),null,' ); -* // returns 'MultiSlice(null,Slice(0,10,1),null,null,Slice(2,9,2),null,null)' -*/ -function wrap( str ) { - // In order to support `x[ [...] ]` syntax, we need to touch up the serialized string due to how `undefined` is serialized... - str = replace( str, /^,/, 'null,' ); // leading comma (e.g., [ void 0, Slice(0,10,1) ] => ',Slice(0,10,1)') - str = replace( str, /,$/, ',null' ); // trailing comma (e.g., [ Slice(0,10,1), void 0 ] => 'Slice(0,10,1),') - str = replace( str, /,(?=,)/g, ',null' ); // between commas (e.g., [ Slice(0,10,1), void 0, void 0, Slice(0,10,1) ] => 'Slice(0,10,1),,,Slice(0,10,1)') - return 'MultiSlice(' + str + ')'; -} - - -// EXPORTS // - -module.exports = wrap;