Skip to content

Commit 34f1b73

Browse files
committed
fix: refactor implementation to only support a single reduction dimension
--- 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: na - 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 ---
1 parent dc2c9b6 commit 34f1b73

File tree

2 files changed

+116
-68
lines changed

2 files changed

+116
-68
lines changed

lib/node_modules/@stdlib/blas/ext/index-of/lib/assign.js

Lines changed: 105 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
// MODULES //
2222

2323
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
24-
var objectAssign = require( '@stdlib/object/assign' );
25-
var isObject = require( '@stdlib/assert/is-object' );
24+
var isPlainObject = require( '@stdlib/assert/is-plain-object' );
2625
var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive;
2726
var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' );
2827
var broadcastScalar = require( '@stdlib/ndarray/base/broadcast-scalar' );
@@ -44,39 +43,38 @@ var DEFAULT_DTYPE = defaults.get( 'dtypes.integer_index' );
4443
// MAIN //
4544

4645
/**
47-
* Returns the first index of a specified search element along one or more ndarray dimensions and assigns the results to a provided output ndarray.
46+
* Returns the first index of a specified search element along an ndarray dimension and assigns the results to a provided output ndarray.
4847
*
49-
* @name assign
50-
* @type {Function}
5148
* @param {ndarrayLike} x - input ndarray
5249
* @param {(ndarrayLike|*)} searchElement - search element
5350
* @param {(ndarrayLike|integer)} [fromIndex] - index from which to begin searching
5451
* @param {ndarrayLike} out - output ndarray
5552
* @param {Options} [options] - function options
56-
* @param {IntegerArray} [options.dims] - list of dimensions over which to perform operation
53+
* @param {IntegerArray} [options.dim=-1] - dimension over which to perform operation
5754
* @throws {TypeError} function must be provided at least three arguments
5855
* @throws {TypeError} first argument must be an ndarray-like object
5956
* @throws {TypeError} third argument must be either an ndarray-like object or an integer
60-
* @throws {TypeError} fourth argument must be an ndarray-like object
57+
* @throws {TypeError} output argument must be an ndarray-like object
6158
* @throws {TypeError} options argument must be an object
62-
* @throws {RangeError} dimension indices must not exceed input ndarray bounds
63-
* @throws {RangeError} number of dimension indices must not exceed the number of input ndarray dimensions
59+
* @throws {RangeError} dimension dimension index must not exceed input ndarray bounds
60+
* @throws {RangeError} first argument must have at least one dimension
6461
* @throws {Error} must provide valid options
6562
* @returns {ndarray} output ndarray
6663
*
6764
* @example
6865
* var Float64Array = require( '@stdlib/array/float64' );
6966
* var zeros = require( '@stdlib/ndarray/zeros' );
67+
* var ndarray2array = require( '@stdlib/ndarray/to-array' );
7068
* var ndarray = require( '@stdlib/ndarray/ctor' );
7169
*
7270
* // Create data buffers:
7371
* var xbuf = new Float64Array( [ 1.0, 2.0, -3.0, 4.0, -5.0, 6.0 ] );
7472
*
7573
* // Define the shape of the input array:
76-
* var shape = [ 3, 1, 2 ];
74+
* var shape = [ 2, 3 ];
7775
*
7876
* // Define the array strides:
79-
* var strides = [ 2, 2, 1 ];
77+
* var strides = [ 3, 1 ];
8078
*
8179
* // Define the index offset:
8280
* var offset = 0;
@@ -85,91 +83,138 @@ var DEFAULT_DTYPE = defaults.get( 'dtypes.integer_index' );
8583
* var x = new ndarray( 'float64', xbuf, shape, strides, offset, 'row-major' );
8684
*
8785
* // Create an output ndarray:
88-
* var y = zeros( [], {
86+
* var y = zeros( [ 2 ], {
8987
* 'dtype': 'int32'
9088
* });
9189
*
9290
* // Perform operation:
93-
* var out = assign( x, 4.0, y );
91+
* var out = assign( x, -5.0, y );
9492
* // returns <ndarray>
9593
*
9694
* var bool = ( out === y );
9795
* // returns true
9896
*
99-
* var idx = out.get();
100-
* // returns 3
97+
* var arr = ndarray2array( out );
98+
* // returns [ -1, 1 ]
10199
*/
102-
function assign( x, searchElement, fromIndex, out, options ) {
100+
function assign( x, searchElement, fromIndex, out ) {
101+
var hasOptions;
102+
var options;
103103
var nargs;
104104
var opts;
105+
var fidx;
106+
var iflg;
105107
var ord;
106108
var dt;
107109
var sh;
110+
var v;
111+
var o;
108112

109113
nargs = arguments.length;
110-
if ( nargs < 3 ) {
111-
throw new TypeError( format( 'invalid argument. The function must be provided at least three arguments. Value: `%s`.', nargs ) );
112-
}
113-
114114
if ( !isndarrayLike( x ) ) {
115-
throw new TypeError( format( 'invalid argument. The first argument must be an ndarray-like object. Value: `%s`.', x ) );
115+
throw new TypeError( format( 'invalid argument. The first argument must be an ndarray. Value: `%s`.', x ) );
116+
}
117+
if ( nargs < 2 ) {
118+
throw new TypeError( format( 'invalid argument. Second argument must be either an ndarray or a scalar value. Value: `%s`.', searchElement ) );
119+
}
120+
if ( nargs < 3 ) {
121+
throw new TypeError( format( 'invalid argument. Third argument must be an ndarray. Value: `%s`.', fromIndex ) );
116122
}
117-
118123
// Resolve input ndarray meta data:
119124
dt = getDType( x );
120125
ord = getOrder( x );
121126

122-
// Initialize options object:
123-
opts = {};
127+
// Initialize an options object:
128+
opts = {
129+
'dims': [ -1 ] // default behavior is to perform a reduction over the last dimension
130+
};
131+
132+
// Initialize the `fromIndex` to the first element along a dimension:
133+
fidx = 0;
134+
135+
// Initialize a flag indicating whether the `fromIndex` argument is a scalar:
136+
iflg = true;
137+
138+
// Initialize a flag indicating whether an `options` argument was provided:
139+
hasOptions = false;
124140

125-
// Case: assign( x, searchElement, out )
141+
// Case: assign( x, search_element, out )
126142
if ( nargs === 3 ) {
127-
out = fromIndex;
128-
fromIndex = 0;
143+
o = fromIndex;
129144
}
130-
// Case: assign( x, searchElement, out, options )
131-
else if (
132-
nargs === 4 &&
133-
isndarrayLike( fromIndex ) &&
134-
!isndarrayLike( out ) &&
135-
isObject( out )
136-
) {
137-
opts = objectAssign( opts, out );
138-
out = fromIndex;
139-
fromIndex = 0;
145+
// Case: assign( x, search_element, ???, ??? )
146+
else if ( nargs === 4 ) {
147+
// Case: assign( x, search_element, from_index, out )
148+
if ( isndarrayLike( out ) ) {
149+
o = out;
150+
151+
// Case: assign( x, search_element, from_index_scalar, out )
152+
if ( isInteger( fromIndex ) ) {
153+
fidx = fromIndex;
154+
}
155+
// Case: assign( x, search_element, from_index_ndarray, out )
156+
else if ( isndarrayLike( fromIndex ) ) {
157+
fidx = fromIndex;
158+
iflg = false;
159+
}
160+
// Case: assign( x, search_element, ???, out )
161+
else {
162+
throw new TypeError( format( 'invalid argument. Third argument must be either an ndarray or an integer. Value: `%s`.', fromIndex ) );
163+
}
164+
}
165+
// Case: assign( x, search_element, out, options )
166+
else {
167+
o = fromIndex;
168+
options = out;
169+
hasOptions = true;
170+
}
140171
}
141-
// Case: assign( x, searchElement, fromIndex, out, options )
142-
else if ( nargs === 5 ) {
143-
if ( !isObject( options ) ) {
144-
throw new TypeError( format( 'invalid argument. The fifth argument must be an object. Value: `%s`.', options ) );
172+
// Case: assign( x, search_element, from_index, out, options )
173+
else { // nargs > 4
174+
// Case: assign( x, search_element, from_index_scalar, out, options )
175+
if ( isInteger( fromIndex ) ) {
176+
fidx = fromIndex;
177+
}
178+
// Case: assign( x, search_element, from_index_ndarray, out, options )
179+
else if ( isndarrayLike( fromIndex ) ) {
180+
fidx = fromIndex;
181+
iflg = false;
145182
}
146-
opts = objectAssign( opts, options );
183+
// Case: assign( x, search_element, ???, out, options )
184+
else {
185+
throw new TypeError( format( 'invalid argument. Third argument must be either an ndarray or an integer. Value: `%s`.', fromIndex ) );
186+
}
187+
o = out;
188+
options = arguments[ 4 ];
189+
hasOptions = true;
147190
}
148-
149-
// Resolve shape for broadcasting
150-
if ( hasOwnProp( opts, 'dims' ) ) {
151-
sh = nonCoreShape( getShape( x ), opts.dims );
152-
} else {
153-
sh = [];
191+
if ( hasOptions && !isPlainObject( options ) ) {
192+
throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) );
193+
}
194+
// Resolve provided options...
195+
if ( hasOwnProp( options, 'dim' ) ) {
196+
opts.dims[ 0 ] = options.dim;
197+
}
198+
// Resolve the list of non-reduced dimensions:
199+
sh = getShape( x );
200+
if ( sh.length < 1 ) {
201+
throw new RangeError( 'invalid argument. First argument must have at least one dimension.' );
154202
}
203+
sh = nonCoreShape( sh, opts.dims );
155204

156-
// Normalize search element:
205+
// Broadcast the search element to match the shape of the non-reduced dimensions...
157206
if ( isndarrayLike( searchElement ) ) {
158-
searchElement = maybeBroadcastArray( searchElement, sh );
207+
v = maybeBroadcastArray( searchElement, sh );
159208
} else {
160-
searchElement = broadcastScalar( searchElement, dt, sh, ord );
209+
v = broadcastScalar( searchElement, dt, sh, ord ); // WARNING: potential for undesired value casting (e.g., if `searchElement` is `null` and cast to `float64`, the broadcasted scalar will be `0`, not `null`!)
161210
}
162-
163-
// Normalize from index:
164-
if ( isndarrayLike( fromIndex ) ) {
165-
fromIndex = maybeBroadcastArray( fromIndex, sh );
166-
} else if ( isInteger( fromIndex ) ) {
167-
fromIndex = broadcastScalar( fromIndex, DEFAULT_DTYPE, sh, ord );
211+
// Broadcast the `fromIndex` to match the shape of the non-reduced dimensions...
212+
if ( iflg ) {
213+
fidx = broadcastScalar( fidx, DEFAULT_DTYPE, sh, ord );
168214
} else {
169-
throw new TypeError( format( 'invalid argument. Third argument must be either an ndarray or an integer. Value: `%s`.', fromIndex ) );
215+
fidx = maybeBroadcastArray( fidx, sh );
170216
}
171-
172-
return base( x, searchElement, fromIndex, out, opts );
217+
return base( x, v, fidx, o, opts );
173218
}
174219

175220

lib/node_modules/@stdlib/blas/ext/index-of/lib/main.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ var DEFAULT_DTYPE = defaults.get( 'dtypes.integer_index' );
4545
/**
4646
* Returns the first index of a specified search element along an ndarray dimension.
4747
*
48-
* @name indexOf
49-
* @type {Function}
5048
* @param {ndarrayLike} x - input ndarray
5149
* @param {(ndarrayLike|*)} searchElement - search element
5250
* @param {(ndarrayLike|integer)} [fromIndex] - index from which to begin searching
@@ -59,6 +57,7 @@ var DEFAULT_DTYPE = defaults.get( 'dtypes.integer_index' );
5957
* @throws {TypeError} third argument must be either an ndarray-like object or an integer
6058
* @throws {TypeError} options argument must be an object
6159
* @throws {RangeError} dimension index must not exceed input ndarray bounds
60+
* @throws {RangeError} first argument must have at least one dimension
6261
* @throws {Error} must provide valid options
6362
* @returns {ndarray} output ndarray
6463
*
@@ -102,17 +101,16 @@ function indexOf( x, searchElement, fromIndex ) {
102101
var v;
103102

104103
nargs = arguments.length;
105-
106104
if ( !isndarrayLike( x ) ) {
107105
throw new TypeError( format( 'invalid argument. First argument must be an ndarray. Value: `%s`.', x ) );
108106
}
107+
if ( nargs < 2 ) {
108+
throw new TypeError( format( 'invalid argument. Second argument must be either an ndarray or a scalar value. Value: `%s`.', searchElement ) );
109+
}
109110
// Resolve input ndarray meta data:
110111
dt = getDType( x );
111112
ord = getOrder( x );
112113

113-
if ( nargs < 2 ) {
114-
throw new TypeError( format( 'invalid argument. Second argument must be either an ndarray or a scalar value. Value: `%s`.', searchElement ) );
115-
}
116114
// Initialize an options object:
117115
opts = {
118116
'dims': [ -1 ], // default behavior is to perform a reduction over the last dimension
@@ -154,6 +152,7 @@ function indexOf( x, searchElement, fromIndex ) {
154152
// Case: indexOf( x, search_element, from_index_ndarray, options )
155153
else if ( isndarrayLike( fromIndex ) ) {
156154
fidx = fromIndex;
155+
iflg = false;
157156
}
158157
// Case: indexOf( x, search_element, ???, options )
159158
else {
@@ -173,13 +172,17 @@ function indexOf( x, searchElement, fromIndex ) {
173172
opts.keepdims = options.keepdims;
174173
}
175174
// Resolve the list of non-reduced dimensions:
176-
sh = nonCoreShape( getShape( x ), opts.dims );
175+
sh = getShape( x );
176+
if ( sh.length < 1 ) {
177+
throw new RangeError( 'invalid argument. First argument must have at least one dimension.' );
178+
}
179+
sh = nonCoreShape( sh, opts.dims );
177180

178181
// Broadcast the search element to match the shape of the non-reduced dimensions...
179182
if ( isndarrayLike( searchElement ) ) {
180183
v = maybeBroadcastArray( searchElement, sh );
181184
} else {
182-
v = broadcastScalar( searchElement, dt, sh, ord );
185+
v = broadcastScalar( searchElement, dt, sh, ord ); // WARNING: potential for undesired value casting (e.g., if `searchElement` is `null` and cast to `float64`, the broadcasted scalar will be `0`, not `null`!)
183186
}
184187
// Broadcast the `fromIndex` to match the shape of the non-reduced dimensions...
185188
if ( iflg ) {

0 commit comments

Comments
 (0)