Skip to content

Commit b825b00

Browse files
committed
Refactor to support a separate method for providing an output array
1 parent 1f04874 commit b825b00

File tree

10 files changed

+1618
-947
lines changed

10 files changed

+1618
-947
lines changed

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ limitations under the License.
4040
var ind2sub = require( '@stdlib/ndarray/ind2sub' );
4141
```
4242

43-
#### ind2sub( \[out,] shape, idx\[, options] )
43+
#### ind2sub( shape, idx\[, options] )
4444

4545
Converts a linear index to an array of subscripts.
4646

@@ -87,19 +87,23 @@ s = ind2sub( shape, 7, opts );
8787
// returns [ 1, 1 ]
8888
```
8989

90-
By default, the function returns subscripts in a new `array`. To avoid unnecessary memory allocation, the function supports providing an output (destination) object.
90+
#### ind2sub.assign( shape, idx\[, options], out )
91+
92+
Converts a linear index to an array of subscripts and assigns results to a provided output array.
9193

9294
```javascript
9395
var shape = [ 2, 2 ];
94-
var out = new Array( shape.length );
96+
var out = [ 0, 0 ];
9597

96-
var subscripts = ind2sub( out, shape, 1 );
98+
var subscripts = ind2sub.assign( shape, 1, out );
9799
// returns [ 0, 1 ]
98100

99101
var bool = ( subscripts === out );
100102
// returns true
101103
```
102104

105+
The function accepts the same `options` as above.
106+
103107
</section>
104108

105109
<!-- /.usage -->
@@ -127,10 +131,10 @@ var ind2sub = require( '@stdlib/ndarray/ind2sub' );
127131
var shape = [ 3, 3, 3 ];
128132
var len = numel( shape );
129133

130-
var arr = new Array( len );
134+
var arr = [];
131135
var i;
132136
for ( i = 0; i < len; i++ ) {
133-
arr[ i ] = i;
137+
arr.push( i );
134138
}
135139

136140
var opts = {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ bench( pkg, function benchmark( b ) {
5757
b.end();
5858
});
5959

60-
bench( pkg+'::memory_reuse', function benchmark( b ) {
60+
bench( pkg+'::memory_reuse:assign', function benchmark( b ) {
6161
var shape;
6262
var len;
6363
var out;
@@ -67,12 +67,12 @@ bench( pkg+'::memory_reuse', function benchmark( b ) {
6767

6868
shape = [ 10, 10, 10 ];
6969
len = numel( shape );
70-
out = new Array( shape.length );
70+
out = [ 0, 0, 0 ];
7171

7272
b.tic();
7373
for ( i = 0; i < b.iterations; i++ ) {
7474
idx = floor( randu()*len );
75-
s = ind2sub( out, shape, idx );
75+
s = ind2sub.assign( shape, idx, out );
7676
if ( s !== out ) {
7777
b.fail( 'should return output array' );
7878
}

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

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11

2-
{{alias}}( [out,] shape, idx[, options] )
2+
{{alias}}( shape, idx[, options] )
33
Converts a linear index to an array of subscripts.
44

55
Parameters
66
----------
7-
out: Array|TypedArray|Object (optional)
8-
Output array.
9-
107
shape: ArrayLike
118
Array shape.
129

@@ -40,9 +37,48 @@
4037
> var s = {{alias}}( d, 17 )
4138
[ 1, 2, 2 ]
4239

43-
// Provide an output array:
44-
> var out = new Array( d.length );
45-
> s = {{alias}}( out, d, 17 )
40+
41+
{{alias}}.assign( shape, idx[, options], out )
42+
Converts a linear index to an array of subscripts and assigns results to a
43+
provided output array.
44+
45+
Parameters
46+
----------
47+
shape: ArrayLike
48+
Array shape.
49+
50+
idx: integer
51+
Linear index.
52+
53+
options: Object (optional)
54+
Options.
55+
56+
options.order: string (optional)
57+
Specifies whether an array is row-major (C-style) or column-major
58+
(Fortran style). Default: 'row-major'.
59+
60+
options.mode: string (optional)
61+
Specifies how to handle a linear index which exceeds array dimensions.
62+
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'.
68+
69+
out: Array|TypedArray|Object
70+
Output array.
71+
72+
Returns
73+
-------
74+
out: Array|TypedArray|Object
75+
Subscripts.
76+
77+
Examples
78+
--------
79+
> var d = [ 3, 3, 3 ];
80+
> var out = [ 0, 0, 0 ];
81+
> var s = {{alias}}.assign( d, 17, out )
4682
[ 1, 2, 2 ]
4783
> var bool = ( s === out )
4884
true

lib/node_modules/@stdlib/ndarray/ind2sub/examples/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ var ind2sub = require( './../lib' );
2424
var shape = [ 3, 3, 3 ];
2525
var len = numel( shape );
2626

27-
var arr = new Array( len );
27+
var arr = [];
2828
var i;
2929
for ( i = 0; i < len; i++ ) {
30-
arr[ i ] = i;
30+
arr.push( i );
3131
}
3232

3333
var opts = {
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2018 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var isNonNegativeIntegerArray = require( '@stdlib/assert/is-nonnegative-integer-array' ).primitives;
24+
var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive;
25+
var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
26+
var getSubscripts = require( '@stdlib/ndarray/base/ind2sub' ).assign;
27+
var defaults = require( './defaults.json' );
28+
var validate = require( './validate.js' );
29+
30+
31+
// MAIN //
32+
33+
/**
34+
* Converts a linear index to an array of subscripts and assigns results to a provided output array.
35+
*
36+
* ## Notes
37+
*
38+
* - The function accepts the following "modes":
39+
*
40+
* - `throw`: throws an error when a linear index exceeds array dimensions.
41+
* - `wrap`: wrap around a linear index exceeding array dimensions using modulo arithmetic.
42+
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
43+
*
44+
*
45+
* @param {NonNegativeIntegerArray} shape - array shape
46+
* @param {integer} idx - linear index
47+
* @param {Options} [options] - function options
48+
* @param {string} [options.mode="throw"] - specifies how to handle a linear index which exceeds array dimensions
49+
* @param {string} [options.order="row-major"] - specifies whether an array is row-major (C-style) or column-major (Fortran-style)
50+
* @param {(Array|TypedArray|Object)} out - output array
51+
* @throws {TypeError} output argument must be either an array, typed array, or an object
52+
* @throws {TypeError} shape argument must be an array-like object containing nonnegative integers
53+
* @throws {TypeError} linear index argument must be integer valued
54+
* @throws {TypeError} options argument must be an object
55+
* @throws {TypeError} must provide valid options
56+
* @throws {RangeError} must provide a linear index which does not exceed array dimensions
57+
* @returns {NonNegativeIntegerArray} subscripts
58+
*
59+
* @example
60+
* var shape = [ 3, 3, 3 ];
61+
* var out = [ 0, 0, 0 ];
62+
*
63+
* var s = ind2sub( shape, 17, out );
64+
* // returns [ 1, 2, 2 ]
65+
*
66+
* var bool = ( s === out );
67+
* // returns true
68+
*/
69+
function ind2sub( shape, idx, options, out ) {
70+
var opts;
71+
var dest;
72+
var err;
73+
74+
opts = {};
75+
opts.mode = defaults.mode;
76+
opts.order = defaults.order;
77+
if ( arguments.length === 4 ) {
78+
err = validate( opts, arguments[ 2 ] );
79+
if ( err ) {
80+
throw err;
81+
}
82+
if ( typeof out !== 'object' || out === null ) {
83+
throw new TypeError( 'invalid argument. Output argument must be either an array, typed array, or object. Value: `' + out + '`.' );
84+
}
85+
dest = out;
86+
} else {
87+
dest = options;
88+
if ( typeof dest !== 'object' || dest === null ) {
89+
throw new TypeError( 'invalid argument. Output argument must be either an array, typed array, or object. Value: `' + dest + '`.' );
90+
}
91+
}
92+
if ( !isNonNegativeIntegerArray( shape ) ) {
93+
throw new TypeError( 'invalid argument. Shape argument must be an array-like object containing nonnegative integers. Value: `' + shape + '`.' );
94+
}
95+
if ( !isInteger( idx ) ) {
96+
throw new TypeError( 'invalid argument. Linear index argument must be integer valued. Value: `' + idx + '`.' );
97+
}
98+
// Note: strides are positive, so offset is always zero
99+
return getSubscripts( shape, shape2strides( shape, opts.order ), 0, opts.order, idx, opts.mode, dest ); // eslint-disable-line max-len
100+
}
101+
102+
103+
// EXPORTS //
104+
105+
module.exports = ind2sub;

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
* var ind2sub = require( '@stdlib/ndarray/ind2sub' );
3434
*
3535
* var shape = [ 3, 3, 3 ];
36-
* var out = new Array( shape.length );
36+
* var out = [ 0, 0, 0 ];
3737
*
38-
* var s = ind2sub( out, shape, 17 );
38+
* var s = ind2sub.assign( shape, 17, out );
3939
* // returns [ 1, 2, 2 ]
4040
*
4141
* var bool = ( s === out );
@@ -44,9 +44,16 @@
4444

4545
// MODULES //
4646

47-
var ind2sub = require( './main.js' );
47+
var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' );
48+
var main = require( './main.js' );
49+
var assign = require( './assign.js' );
50+
51+
52+
// MAIN //
53+
54+
setReadOnly( main, 'assign', assign );
4855

4956

5057
// EXPORTS //
5158

52-
module.exports = ind2sub;
59+
module.exports = main;

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

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,11 @@ var validate = require( './validate.js' );
4242
* - `clamp`: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
4343
*
4444
*
45-
* @param {(Array|TypedArray|Object)} [out] - output array
4645
* @param {NonNegativeIntegerArray} shape - array shape
4746
* @param {integer} idx - linear index
4847
* @param {Options} [options] - function options
4948
* @param {string} [options.mode="throw"] - specifies how to handle a linear index which exceeds array dimensions
5049
* @param {string} [options.order="row-major"] - specifies whether an array is row-major (C-style) or column-major (Fortran-style)
51-
* @throws {TypeError} output argument must be either an array, typed array, or an object
5250
* @throws {TypeError} shape argument must be an array-like object containing nonnegative integers
5351
* @throws {TypeError} linear index argument must be integer valued
5452
* @throws {TypeError} options argument must be an object
@@ -59,58 +57,15 @@ var validate = require( './validate.js' );
5957
* @example
6058
* var s = ind2sub( [ 3, 3, 3 ], 17 );
6159
* // returns [ 1, 2, 2 ]
62-
*
63-
* @example
64-
* var shape = [ 3, 3, 3 ];
65-
* var out = new Array( shape.length );
66-
*
67-
* var s = ind2sub( out, shape, 17 );
68-
* // returns [ 1, 2, 2 ]
69-
*
70-
* var bool = ( s === out );
71-
* // returns true
7260
*/
73-
function ind2sub() {
74-
var options;
75-
var strides;
76-
var offset;
77-
var shape;
61+
function ind2sub( shape, idx, options ) {
7862
var opts;
79-
var idx;
80-
var out;
8163
var err;
8264

8365
opts = {};
8466
opts.mode = defaults.mode;
8567
opts.order = defaults.order;
86-
if ( arguments.length === 2 ) {
87-
shape = arguments[ 0 ];
88-
idx = arguments[ 1 ];
89-
} else if ( arguments.length === 3 ) {
90-
if ( isInteger( arguments[ 1 ] ) ) {
91-
shape = arguments[ 0 ];
92-
idx = arguments[ 1 ];
93-
options = arguments[ 2 ];
94-
err = validate( opts, options );
95-
if ( err ) {
96-
throw err;
97-
}
98-
} else {
99-
out = arguments[ 0 ];
100-
if ( typeof out !== 'object' || out === null ) {
101-
throw new TypeError( 'invalid argument. Output argument must be either an array, typed array, or object. Value: `' + out + '`.' );
102-
}
103-
shape = arguments[ 1 ];
104-
idx = arguments[ 2 ];
105-
}
106-
} else {
107-
out = arguments[ 0 ];
108-
if ( typeof out !== 'object' || out === null ) {
109-
throw new TypeError( 'invalid argument. Output argument must be either an array, typed array, or object. Value: `' + out + '`.' );
110-
}
111-
shape = arguments[ 1 ];
112-
idx = arguments[ 2 ];
113-
options = arguments[ 3 ];
68+
if ( arguments.length > 2 ) {
11469
err = validate( opts, options );
11570
if ( err ) {
11671
throw err;
@@ -122,12 +77,8 @@ function ind2sub() {
12277
if ( !isInteger( idx ) ) {
12378
throw new TypeError( 'invalid argument. Linear index argument must be integer valued. Value: `' + idx + '`.' );
12479
}
125-
if ( out === void 0 ) {
126-
out = new Array( shape.length );
127-
}
128-
strides = shape2strides( shape, opts.order );
129-
offset = 0; // strides are positive, so offset is always zero
130-
return getSubscripts( out, shape, strides, offset, opts.order, idx, opts.mode ); // eslint-disable-line max-len
80+
// Note: strides are positive, so offset is always zero
81+
return getSubscripts( shape, shape2strides( shape, opts.order ), 0, opts.order, idx, opts.mode ); // eslint-disable-line max-len
13182
}
13283

13384

0 commit comments

Comments
 (0)