Skip to content

Commit dd80dd0

Browse files
committed
feat: add support for normalize index mode
1 parent 08d72b4 commit dd80dd0

File tree

7 files changed

+140
-14
lines changed

7 files changed

+140
-14
lines changed

lib/node_modules/@stdlib/ndarray/sub2ind/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,16 @@ var idx = sub2ind( shape, 1, 0 );
5353

5454
The function supports the following `options`:
5555

56-
- `mode`: specifies how to handle subscripts which exceed array dimensions. The following modes are supported:
56+
- **mode**: specifies how to handle subscripts which exceed array dimensions. The following modes are supported:
5757

5858
- `throw`: specifies that the function should throw an error when a subscript exceeds array dimensions.
59+
- `normalize`: specifies that the function should normalize negative subscripts and throw an error when a subscript exceeds array dimensions.
5960
- `wrap`: specifies that the function should wrap around subscripts exceeding array dimensions using modulo arithmetic.
6061
- `clamp`: specifies that the function should set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension.
6162

6263
If provided a `mode` array, each array element corresponds to a dimension. If provided fewer modes than dimensions, the function reuses modes using modulo arithmetic. Default: `[ 'throw' ]`.
6364

64-
- `order`: specifies whether an array is `row-major` (C-style) or `column-major` (Fortran-style). Default: `'row-major'`.
65+
- **order**: specifies whether an array is `row-major` (C-style) or `column-major` (Fortran-style). Default: `'row-major'`.
6566

6667
By default, the function assumes a row-major array. To return a linear index for a column-major array, set the `order` option.
6768

lib/node_modules/@stdlib/ndarray/sub2ind/benchmark/benchmark.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,76 @@ bench( pkg+':mode=[clamp]', function benchmark( b ) {
271271
b.end();
272272
});
273273

274+
bench( pkg+':mode=normalize', function benchmark( b ) {
275+
var shape;
276+
var opts;
277+
var out;
278+
var s0;
279+
var s1;
280+
var s2;
281+
var i;
282+
283+
shape = [ 10, 10, 10 ];
284+
285+
s0 = discreteUniform( 0, shape[ 0 ]-1 );
286+
s1 = discreteUniform( 0, shape[ 1 ]-1 );
287+
s2 = discreteUniform( 0, shape[ 2 ]-1 );
288+
289+
opts = {
290+
'mode': 'normalize'
291+
};
292+
293+
b.tic();
294+
for ( i = 0; i < b.iterations; i++ ) {
295+
s2 = floor( randu()*2000.0 ) - 1000.0;
296+
out = sub2ind( shape, s0, s1, s2, opts );
297+
if ( out !== out ) {
298+
b.fail( 'should not return NaN' );
299+
}
300+
}
301+
b.toc();
302+
if ( !isInteger( out ) ) {
303+
b.fail( 'should return an integer' );
304+
}
305+
b.pass( 'benchmark finished' );
306+
b.end();
307+
});
308+
309+
bench( pkg+':mode=[normalize]', function benchmark( b ) {
310+
var shape;
311+
var opts;
312+
var out;
313+
var s0;
314+
var s1;
315+
var s2;
316+
var i;
317+
318+
shape = [ 10, 10, 10 ];
319+
320+
s0 = discreteUniform( 0, shape[ 0 ]-1 );
321+
s1 = discreteUniform( 0, shape[ 1 ]-1 );
322+
s2 = discreteUniform( 0, shape[ 2 ]-1 );
323+
324+
opts = {
325+
'mode': [ 'normalize' ]
326+
};
327+
328+
b.tic();
329+
for ( i = 0; i < b.iterations; i++ ) {
330+
s2 = floor( randu()*2000.0 ) - 1000.0;
331+
out = sub2ind( shape, s0, s1, s2, opts );
332+
if ( out !== out ) {
333+
b.fail( 'should not return NaN' );
334+
}
335+
}
336+
b.toc();
337+
if ( !isInteger( out ) ) {
338+
b.fail( 'should return an integer' );
339+
}
340+
b.pass( 'benchmark finished' );
341+
b.end();
342+
});
343+
274344
bench( pkg+':order=row-major', function benchmark( b ) {
275345
var shape;
276346
var opts;

lib/node_modules/@stdlib/ndarray/sub2ind/docs/repl.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
options.mode: string|Array<string> (optional)
2121
Specifies how to handle subscripts which exceed array dimensions. If
2222
equal to 'throw', the function throws an error when a subscript exceeds
23-
array dimensions. If equal to 'wrap', the function wraps around
24-
subscripts exceeding array dimensions using modulo arithmetic. If equal
25-
to 'clamp', the function sets subscripts exceeding array dimensions to
23+
array dimensions. If equal to 'normalize', the function normalizes
24+
negative subscripts and throws an error when a subscript exceeds array
25+
dimensions. If equal to 'wrap', the function wraps around subscripts
26+
exceeding array dimensions using modulo arithmetic. If equal to
27+
'clamp', the function sets subscripts exceeding array dimensions to
2628
either `0` (minimum index) or the maximum index along a particular
2729
dimension. If provided a mode array, each array element specifies the
2830
mode for a corresponding array dimension. If provided fewer modes than

lib/node_modules/@stdlib/ndarray/sub2ind/docs/types/index.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ interface Options {
4646
*
4747
* - The function accepts the following "modes":
4848
*
49-
* - `throw`: throws an error when a subscript exceeds array dimensions.
50-
* - `wrap`: wrap around subscripts exceeding array dimensions using modulo arithmetic.
51-
* - `clamp`: set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension.
49+
* - **throw**: throw an error when a subscript exceeds array dimensions.
50+
* - **normalize**: normalize negative subscripts and throw an error when a subscript exceeds array dimensions.
51+
* - **wrap**: wrap around subscripts exceeding array dimensions using modulo arithmetic.
52+
* - **clamp**: set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension.
5253
*
5354
* - If provided fewer modes than dimensions, the function recycles modes using modulo arithmetic.
5455
*
55-
*
5656
* @param shape - array shape
5757
* @param args - subscripts followed by an optional options object
5858
* @throws first argument must be an array-like object containing nonnegative integers

lib/node_modules/@stdlib/ndarray/sub2ind/lib/main.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ var validate = require( './validate.js' );
3838
*
3939
* - The function accepts the following "modes":
4040
*
41-
* - `throw`: throws an error when a subscript exceeds array dimensions.
42-
* - `wrap`: wrap around subscripts exceeding array dimensions using modulo arithmetic.
43-
* - `clamp`: set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension.
41+
* - **throw**: throw an error when a subscript exceeds array dimensions.
42+
* - **normalize**: normalize negative subscripts and throw an error when a subscript exceeds array dimensions.
43+
* - **wrap**: wrap around subscripts exceeding array dimensions using modulo arithmetic.
44+
* - **clamp**: set subscripts exceeding array dimensions to either `0` (minimum index) or the maximum index along a particular dimension.
4445
*
4546
* - If provided fewer modes than dimensions, the function recycles modes using modulo arithmetic.
4647
*

lib/node_modules/@stdlib/ndarray/sub2ind/test/test.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ tape( 'the function throws an error if provided an invalid option', function tes
281281
'throws',
282282
'wraps',
283283
'clamps',
284+
'normalizes',
284285
'clip',
285286
5,
286287
NaN,
@@ -289,7 +290,7 @@ tape( 'the function throws an error if provided an invalid option', function tes
289290
null,
290291
void 0,
291292
[],
292-
[ 'wrap', 'clamp', 'throw', 'foo' ],
293+
[ 'wrap', 'clamp', 'throw', 'normalize', 'foo' ],
293294
{},
294295
function noop() {}
295296
];
@@ -454,6 +455,29 @@ tape( 'if the `mode` is `throw`, the function throws if provided a subscript whi
454455
}
455456
});
456457

458+
tape( 'if the `mode` is `normalize`, the function throws if provided a subscript which exceeds array dimensions', function test( t ) {
459+
var shape;
460+
var opts;
461+
462+
shape = [ 2, 2 ];
463+
opts = {
464+
'mode': 'normalize'
465+
};
466+
467+
t.throws( foo, RangeError, 'throws a range error' );
468+
t.throws( bar, RangeError, 'throws a range error' );
469+
470+
t.end();
471+
472+
function foo() {
473+
sub2ind( shape, 999999, 1, opts );
474+
}
475+
476+
function bar() {
477+
sub2ind( shape, 1, -999999, opts );
478+
}
479+
});
480+
457481
tape( 'if the `mode` is `wrap`, the function wraps subscripts which exceed array dimensions', function test( t ) {
458482
var shape;
459483
var opts;
@@ -519,6 +543,34 @@ tape( 'if the `mode` is `clamp`, the function clamps subscripts which exceed arr
519543
t.end();
520544
});
521545

546+
tape( 'if the `mode` is `normalize`, the function normalizes negative subscripts', function test( t ) {
547+
var shape;
548+
var opts;
549+
var idx;
550+
551+
shape = [ 2, 2 ];
552+
opts = {
553+
'mode': 'normalize'
554+
};
555+
556+
idx = sub2ind( shape, 1, 0, opts );
557+
t.strictEqual( idx, 2, 'returns expected value' );
558+
559+
idx = sub2ind( shape, -1, 0, opts );
560+
t.strictEqual( idx, 2, 'returns expected value' );
561+
562+
idx = sub2ind( shape, 0, -1, opts );
563+
t.strictEqual( idx, 1, 'returns expected value' );
564+
565+
idx = sub2ind( shape, -2, -2, opts );
566+
t.strictEqual( idx, 0, 'returns expected value' );
567+
568+
idx = sub2ind( shape, -1, -1, opts );
569+
t.strictEqual( idx, 3, 'returns expected value' );
570+
571+
t.end();
572+
});
573+
522574
tape( 'the function supports providing mixed modes', function test( t ) {
523575
var shape;
524576
var opts;

lib/node_modules/@stdlib/ndarray/sub2ind/test/test.validate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ tape( 'the function returns `null` if all options are valid (mode array)', funct
156156

157157
opts = {};
158158
options = {
159-
'mode': [ 'wrap', 'clamp', 'throw' ],
159+
'mode': [ 'wrap', 'clamp', 'throw', 'normalize' ],
160160
'order': 'column-major'
161161
};
162162

0 commit comments

Comments
 (0)