Skip to content

Commit 12102f1

Browse files
committed
feat: add support for normalize index mode
1 parent 274da55 commit 12102f1

8 files changed

Lines changed: 268 additions & 35 deletions

File tree

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ var s = ind2sub( shape, 2 );
5353

5454
The function supports the following `options`:
5555

56-
- `mode`: specifies how to handle a linear index which exceeds array dimensions. The following modes are supported:
56+
- **mode**: specifies how to handle a linear index which exceeds array dimensions. The following modes are supported:
5757

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

62-
- `order`: specifies whether an array is `row-major` (C-style) or `column-major` (Fortran-style). Default: `'row-major'`.
63+
- **order**: specifies whether an array is `row-major` (C-style) or `column-major` (Fortran-style). Default: `'row-major'`.
6364

6465
By default, the function assumes a row-major array. To return subscripts for a column-major array, set the `order` option.
6566

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,36 @@ bench( pkg+':mode=clamp', function benchmark( b ) {
145145
b.end();
146146
});
147147

148+
bench( pkg+':mode=normalize', function benchmark( b ) {
149+
var shape;
150+
var opts;
151+
var len;
152+
var out;
153+
var idx;
154+
var i;
155+
156+
shape = [ 10, 10, 10 ];
157+
len = numel( shape );
158+
opts = {
159+
'mode': 'normalize'
160+
};
161+
162+
b.tic();
163+
for ( i = 0; i < b.iterations; i++ ) {
164+
idx = floor( randu()*len*2.0 ) - len;
165+
out = ind2sub( shape, idx, opts );
166+
if ( out.length !== shape.length ) {
167+
b.fail( 'should return an array with expected length' );
168+
}
169+
}
170+
b.toc();
171+
if ( !isNonNegativeIntegerArray( out ) ) {
172+
b.fail( 'should return an array containing nonnegative integers' );
173+
}
174+
b.pass( 'benchmark finished' );
175+
b.end();
176+
});
177+
148178
bench( pkg+':mode=throw', function benchmark( b ) {
149179
var shape;
150180
var opts;

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
options.mode: string (optional)
2121
Specifies how to handle a linear index which exceeds array dimensions.
2222
If equal to 'throw', the function throws an error when a linear index
23-
exceeds array dimensions. If equal to 'wrap', the function wraps around
24-
a linear index exceeding array dimensions using modulo arithmetic. If
25-
equal to 'clamp', the function sets a linear index exceeding array
26-
dimensions to either `0` (minimum linear index) or the maximum linear
27-
index. Default: 'throw'.
23+
exceeds array dimensions. If equal to 'normalize', the function
24+
normalizes negative linear indices and throws an error when a linear
25+
index exceeds array dimensions. If equal to 'wrap', the function wraps
26+
around a linear index exceeding array dimensions using modulo
27+
arithmetic. If equal to 'clamp', the function sets a linear index
28+
exceeding array dimensions to either `0` (minimum linear index) or the
29+
maximum linear index. Default: 'throw'.
2830

2931
Returns
3032
-------
@@ -60,11 +62,13 @@
6062
options.mode: string (optional)
6163
Specifies how to handle a linear index which exceeds array dimensions.
6264
If equal to 'throw', the function throws an error when a linear index
63-
exceeds array dimensions. If equal to 'wrap', the function wraps around
64-
a linear index exceeding array dimensions using modulo arithmetic. If
65-
equal to 'clamp', the function sets a linear index exceeding array
66-
dimensions to either `0` (minimum linear index) or the maximum linear
67-
index. Default: 'throw'.
65+
exceeds array dimensions. If equal to 'normalize', the function
66+
normalizes negative linear indices and throws an error when a linear
67+
index exceeds array dimensions. If equal to 'wrap', the function wraps
68+
around a linear index exceeding array dimensions using modulo
69+
arithmetic. If equal to 'clamp', the function sets a linear index
70+
exceeding array dimensions to either `0` (minimum linear index) or the
71+
maximum linear index. Default: 'throw'.
6872

6973
out: Array|TypedArray|Object
7074
Output array.

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ interface Ind2Sub {
4747
*
4848
* - The function accepts the following "modes":
4949
*
50-
* - `throw`: throws an error when a linear index exceeds array dimensions.
51-
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
52-
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
53-
*
50+
* - **throw**: throw an error when a linear index exceeds array dimensions.
51+
* - **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
52+
* - **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
53+
* - **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
5454
*
5555
* @param shape - array shape
5656
* @param idx - linear index
@@ -73,12 +73,12 @@ interface Ind2Sub {
7373
*
7474
* ## Notes
7575
*
76-
* - The function accepts the following "modes":
77-
*
78-
* - `throw`: throws an error when a linear index exceeds array dimensions.
79-
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
80-
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
76+
* - The function accepts the following "modes":
8177
*
78+
* - **throw**: throw an error when a linear index exceeds array dimensions.
79+
* - **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
80+
* - **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
81+
* - **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
8282
*
8383
* @param shape - array shape
8484
* @param idx - linear index
@@ -111,10 +111,10 @@ interface Ind2Sub {
111111
*
112112
* - The function accepts the following "modes":
113113
*
114-
* - `throw`: throws an error when a linear index exceeds array dimensions.
115-
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
116-
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
117-
*
114+
* - **throw**: throw an error when a linear index exceeds array dimensions.
115+
* - **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
116+
* - **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
117+
* - **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
118118
*
119119
* @param shape - array shape
120120
* @param idx - linear index
@@ -144,10 +144,10 @@ interface Ind2Sub {
144144
*
145145
* - The function accepts the following "modes":
146146
*
147-
* - `throw`: throws an error when a linear index exceeds array dimensions.
148-
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
149-
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
150-
*
147+
* - **throw**: throw an error when a linear index exceeds array dimensions.
148+
* - **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
149+
* - **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
150+
* - **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
151151
*
152152
* @param shape - array shape
153153
* @param idx - linear index

lib/node_modules/@stdlib/ndarray/ind2sub/lib/assign.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 linear index exceeds array dimensions.
42-
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
43-
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
41+
* - **throw**: throw an error when a linear index exceeds array dimensions.
42+
* - **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
43+
* - **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
44+
* - **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
4445
*
4546
* @param {NonNegativeIntegerArray} shape - array shape
4647
* @param {integer} idx - linear index

lib/node_modules/@stdlib/ndarray/ind2sub/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 linear index exceeds array dimensions.
42-
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
43-
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
41+
* - **throw**: throw an error when a linear index exceeds array dimensions.
42+
* - **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
43+
* - **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
44+
* - **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
4445
*
4546
* @param {NonNegativeIntegerArray} shape - array shape
4647
* @param {integer} idx - linear index

lib/node_modules/@stdlib/ndarray/ind2sub/test/test.assign.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,3 +776,104 @@ tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceed
776776

777777
t.end();
778778
});
779+
780+
tape( 'if the `mode` is `normalize`, the function normalize negative linear indices', function test( t ) {
781+
var shape;
782+
var opts;
783+
var out;
784+
var s;
785+
786+
shape = [ 2, 2 ];
787+
opts = {
788+
'mode': 'normalize'
789+
};
790+
out = [ 0, 0 ];
791+
792+
s = ind2sub( shape, 2, opts, out );
793+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
794+
795+
s = ind2sub( shape, 3, opts, out );
796+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
797+
798+
s = ind2sub( shape, -1, opts, out );
799+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
800+
801+
s = ind2sub( shape, -4, opts, out );
802+
t.deepEqual( s, [ 0, 0 ], 'returns expected value' );
803+
804+
s = ind2sub( shape, -3, opts, out );
805+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
806+
807+
s = ind2sub( shape, -2, opts, out );
808+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
809+
810+
t.end();
811+
});
812+
813+
tape( 'if the `mode` is `normalize`, the function normalize negative linear indices (order=row-major)', function test( t ) {
814+
var shape;
815+
var opts;
816+
var out;
817+
var s;
818+
819+
shape = [ 2, 2 ];
820+
opts = {
821+
'mode': 'normalize',
822+
'order': 'row-major'
823+
};
824+
out = [ 0, 0 ];
825+
826+
s = ind2sub( shape, 2, opts, out );
827+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
828+
829+
s = ind2sub( shape, 3, opts, out );
830+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
831+
832+
s = ind2sub( shape, -1, opts, out );
833+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
834+
835+
s = ind2sub( shape, -4, opts, out );
836+
t.deepEqual( s, [ 0, 0 ], 'returns expected value' );
837+
838+
s = ind2sub( shape, -3, opts, out );
839+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
840+
841+
s = ind2sub( shape, -2, opts, out );
842+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
843+
844+
t.end();
845+
});
846+
847+
tape( 'if the `mode` is `normalize`, the function normalize negative linear indices (order=column-major)', function test( t ) {
848+
var shape;
849+
var opts;
850+
var out;
851+
var s;
852+
853+
shape = [ 2, 2 ];
854+
opts = {
855+
'mode': 'normalize',
856+
'order': 'column-major'
857+
};
858+
out = [ 0, 0 ];
859+
860+
s = ind2sub( shape, 2, opts, out );
861+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
862+
863+
s = ind2sub( shape, 3, opts, out );
864+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
865+
866+
s = ind2sub( shape, -1, opts, out );
867+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
868+
869+
s = ind2sub( shape, -4, opts, out );
870+
t.deepEqual( s, [ 0, 0 ], 'returns expected value' );
871+
872+
s = ind2sub( shape, -3, opts, out );
873+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
874+
875+
s = ind2sub( shape, -2, opts, out );
876+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
877+
878+
t.end();
879+
});

lib/node_modules/@stdlib/ndarray/ind2sub/test/test.main.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,98 @@ tape( 'if the `mode` is `clamp`, the function clamps a linear index which exceed
655655

656656
t.end();
657657
});
658+
659+
tape( 'if the `mode` is `normalize`, the function normalize negative linear indices', function test( t ) {
660+
var shape;
661+
var opts;
662+
var s;
663+
664+
shape = [ 2, 2 ];
665+
opts = {
666+
'mode': 'normalize'
667+
};
668+
669+
s = ind2sub( shape, 2, opts );
670+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
671+
672+
s = ind2sub( shape, 3, opts );
673+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
674+
675+
s = ind2sub( shape, -1, opts );
676+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
677+
678+
s = ind2sub( shape, -4, opts );
679+
t.deepEqual( s, [ 0, 0 ], 'returns expected value' );
680+
681+
s = ind2sub( shape, -3, opts );
682+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
683+
684+
s = ind2sub( shape, -2, opts );
685+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
686+
687+
t.end();
688+
});
689+
690+
tape( 'if the `mode` is `normalize`, the function normalize negative linear indices (order=row-major)', function test( t ) {
691+
var shape;
692+
var opts;
693+
var s;
694+
695+
shape = [ 2, 2 ];
696+
opts = {
697+
'mode': 'normalize',
698+
'order': 'row-major'
699+
};
700+
701+
s = ind2sub( shape, 2, opts );
702+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
703+
704+
s = ind2sub( shape, 3, opts );
705+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
706+
707+
s = ind2sub( shape, -1, opts );
708+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
709+
710+
s = ind2sub( shape, -4, opts );
711+
t.deepEqual( s, [ 0, 0 ], 'returns expected value' );
712+
713+
s = ind2sub( shape, -3, opts );
714+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
715+
716+
s = ind2sub( shape, -2, opts );
717+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
718+
719+
t.end();
720+
});
721+
722+
tape( 'if the `mode` is `normalize`, the function normalize negative linear indices (order=column-major)', function test( t ) {
723+
var shape;
724+
var opts;
725+
var s;
726+
727+
shape = [ 2, 2 ];
728+
opts = {
729+
'mode': 'normalize',
730+
'order': 'column-major'
731+
};
732+
733+
s = ind2sub( shape, 2, opts );
734+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
735+
736+
s = ind2sub( shape, 3, opts );
737+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
738+
739+
s = ind2sub( shape, -1, opts );
740+
t.deepEqual( s, [ 1, 1 ], 'returns expected value' );
741+
742+
s = ind2sub( shape, -4, opts );
743+
t.deepEqual( s, [ 0, 0 ], 'returns expected value' );
744+
745+
s = ind2sub( shape, -3, opts );
746+
t.deepEqual( s, [ 1, 0 ], 'returns expected value' );
747+
748+
s = ind2sub( shape, -2, opts );
749+
t.deepEqual( s, [ 0, 1 ], 'returns expected value' );
750+
751+
t.end();
752+
});

0 commit comments

Comments
 (0)