Skip to content

Commit f475c84

Browse files
headlessNodekgryte
andauthored
feat!: add writable parameter to ndarray/base/expand-dimensions
This commit adds a writable parameter to `expandDimensions` to explicitly support indicating whether a returned ndarray should be read-only. Previously, we only returned a read-only ndarray is an input ndarray was read-only. This now pushes responsibility for determining whether an output ndarray is read-only to the user. BREAKING CHANGE: add `writable` parameter To migrate, users should explicitly provide a third argument indicating whether to return a read-only ndarray. To preserve prior behavior, users should provide a boolean based on whether an input ndarray is read-only. PR-URL: #9476 Closes: stdlib-js/metr-issue-tracker#138 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com>
1 parent 5cddadf commit f475c84

10 files changed

Lines changed: 145 additions & 183 deletions

File tree

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/README.md

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

43-
#### expandDimensions( x, axis )
43+
#### expandDimensions( x, axis, writable )
4444

4545
Expands the shape of an array `x` by inserting a new dimension of size one at a specified `axis`.
4646

@@ -53,27 +53,33 @@ var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
5353
// returns <ndarray>[ [ 1, 2 ], [ 3, 4 ] ]
5454

5555
// Prepend a singleton dimension:
56-
var y = expandDimensions( x, 0 );
56+
var y = expandDimensions( x, 0, false );
5757
// returns <ndarray>[ [ [ 1, 2 ], [ 3, 4 ] ] ]
5858

5959
var sh = getShape( y );
6060
// returns [ 1, 2, 2 ]
6161

6262
// Append a singleton dimension:
63-
y = expandDimensions( x, 2 );
63+
y = expandDimensions( x, 2, false );
6464
// returns <ndarray>[ [ [ 1 ], [ 2 ] ], [ [ 3 ], [ 4 ] ] ]
6565

6666
sh = getShape( y );
6767
// returns [ 2, 2, 1 ]
6868

6969
// Insert a singleton dimension:
70-
y = expandDimensions( x, 1 );
70+
y = expandDimensions( x, 1, false );
7171
// returns <ndarray>[ [ [ 1, 2 ] ], [ [ 3, 4 ] ] ]
7272

7373
sh = getShape( y );
7474
// returns [ 2, 1, 2 ]
7575
```
7676

77+
The function accepts the following arguments:
78+
79+
- **x**: input ndarray.
80+
- **axis**: axis at which to insert a singleton dimension
81+
- **writable**: boolean indicating whether a returned ndarray should be writable.
82+
7783
</section>
7884

7985
<!-- /.usage -->
@@ -85,6 +91,7 @@ sh = getShape( y );
8591
## Notes
8692

8793
- A provided axis must reside on the interval `[-N-1, N]`, where `N` is the rank (i.e., number of dimensions) of the provided input array. If provided a negative `axis`, the axis position at which to insert a singleton dimension is computed as `N + axis + 1`. Hence, if provided `-1`, the resolved axis position is `N` (i.e., a singleton dimension is appended to the input array).
94+
- The `writable` parameter **only** applies to ndarray constructors supporting **read-only** instances.
8895

8996
</section>
9097

@@ -99,32 +106,15 @@ sh = getShape( y );
99106
<!-- eslint no-undef: "error" -->
100107

101108
```javascript
102-
var array = require( '@stdlib/ndarray/array' );
103-
var numel = require( '@stdlib/ndarray/base/numel' );
104-
var ind2sub = require( '@stdlib/ndarray/ind2sub' );
105-
var getShape = require( '@stdlib/ndarray/shape' );
109+
var uniform = require( '@stdlib/random/uniform' );
110+
var ndarray2array = require( '@stdlib/ndarray/to-array' );
106111
var expandDimensions = require( '@stdlib/ndarray/base/expand-dimensions' );
107112

108-
// Create a 2-dimensional array:
109-
var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
110-
// returns <ndarray>
111-
112-
// Insert a singleton dimension:
113-
var y = expandDimensions( x, 1 );
114-
// returns <ndarray>
115-
116-
// Retrieve the shape:
117-
var sh = getShape( y );
118-
// returns [ 2, 1, 2 ]
119-
120-
// Retrieve the number of elements:
121-
var N = numel( sh );
113+
var x = uniform( [ 3, 3, 3 ], -10.0, 10.0 );
114+
console.log( ndarray2array( x ) );
122115

123-
// Loop through the array elements...
124-
var i;
125-
for ( i = 0; i < N; i++ ) {
126-
console.log( 'Y[%s] = %d', ind2sub( sh, i ).join( ', ' ), y.iget( i ) );
127-
}
116+
var y = expandDimensions( x, 1, false );
117+
console.log( ndarray2array( y ) );
128118
```
129119

130120
</section>

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/benchmark/benchmark.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bench( pkg+'::base_ndarray,2d', function benchmark( b ) {
5959

6060
b.tic();
6161
for ( i = 0; i < b.iterations; i++ ) {
62-
out = expandDimensions( values[ i%values.length ], 1 );
62+
out = expandDimensions( values[ i%values.length ], 1, false );
6363
if ( typeof out !== 'object' ) {
6464
b.fail( 'should return an object' );
6565
}
@@ -100,7 +100,7 @@ bench( pkg+'::ndarray,2d', function benchmark( b ) {
100100

101101
b.tic();
102102
for ( i = 0; i < b.iterations; i++ ) {
103-
out = expandDimensions( values[ i%values.length ], 1 );
103+
out = expandDimensions( values[ i%values.length ], 1, false );
104104
if ( typeof out !== 'object' ) {
105105
b.fail( 'should return an object' );
106106
}

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/benchmark/benchmark.ndims.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function createBenchmark( ndims ) {
5454

5555
b.tic();
5656
for ( i = 0; i < b.iterations; i++ ) {
57-
out = expandDimensions( x, i%(ndims-1) );
57+
out = expandDimensions( x, i%(ndims-1), false );
5858
if ( typeof out !== 'object' ) {
5959
b.fail( 'should return an object' );
6060
}

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/docs/repl.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
{{alias}}( x, axis )
2+
{{alias}}( x, axis, writable )
33
Expands the shape of an array by inserting a new dimension of size one at a
44
specified axis.
55

@@ -11,6 +11,9 @@
1111
the resolved axis position is `N` (i.e., a singleton dimension is appended
1212
to the input array).
1313

14+
The `writable` parameter only applies to ndarray constructors supporting
15+
read-only instances.
16+
1417
Parameters
1518
----------
1619
x: ndarray
@@ -19,6 +22,9 @@
1922
axis: integer
2023
Axis at which to insert a singleton dimension.
2124

25+
writable: boolean
26+
Boolean indicating whether the returned ndarray should be writable.
27+
2228
Returns
2329
-------
2430
out: ndarray
@@ -28,12 +34,8 @@
2834
--------
2935
> var x = {{alias:@stdlib/ndarray/array}}( [ [ 1, 2 ], [ 3, 4 ] ] )
3036
<ndarray>[ [ 1, 2 ], [ 3, 4 ] ]
31-
> var sh = {{alias:@stdlib/ndarray/shape}}( x )
32-
[ 2, 2 ]
33-
> var y = {{alias}}( x, 1 )
37+
> var y = {{alias}}( x, 1, false )
3438
<ndarray>[ [ [ 1, 2 ] ], [ [ 3, 4 ] ] ]
35-
> sh = {{alias:@stdlib/ndarray/shape}}( y )
36-
[ 2, 1, 2 ]
3739

3840
See Also
3941
--------

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/docs/types/index.d.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,19 @@ import { typedndarray } from '@stdlib/types/ndarray';
3131
*
3232
* @param x - input array
3333
* @param axis - axis at which to insert a singleton dimension
34+
* @param writable - boolean indicating whether the returned ndarray should be writable
3435
* @returns output array
3536
*
3637
* @example
37-
* var getShape = require( '@stdlib/ndarray/shape' );
3838
* var array = require( '@stdlib/ndarray/array' );
3939
*
4040
* var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
4141
* // returns <ndarray>[ [ 1, 2 ], [ 3, 4 ] ]
4242
*
43-
* var shx = getShape( x );
44-
* // returns [ 2, 2 ]
45-
*
46-
* var y = expandDimensions( x, 1 );
43+
* var y = expandDimensions( x, 1, false );
4744
* // returns <ndarray>[ [ [ 1, 2 ] ], [ [ 3, 4 ] ] ]
48-
*
49-
* var shy = getShape( y );
50-
* // returns [ 2, 1, 2 ]
5145
*/
52-
declare function expandDimensions<T = unknown>( x: typedndarray<T>, axis: number ): typedndarray<T>;
46+
declare function expandDimensions<T = unknown>( x: typedndarray<T>, axis: number, writable: boolean ): typedndarray<T>;
5347

5448

5549
// EXPORTS //

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/docs/types/test.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,47 @@ import expandDimensions = require( './index' );
2626
{
2727
const x = zeros( [ 2, 2 ] );
2828

29-
expandDimensions( x, 1 ); // $ExpectType typedndarray<number>
29+
expandDimensions( x, 1, false ); // $ExpectType typedndarray<number>
3030
}
3131

3232
// The compiler throws an error if the function is not provided a first argument which is an ndarray...
3333
{
34-
expandDimensions( '5', 1 ); // $ExpectError
35-
expandDimensions( 5, 1 ); // $ExpectError
36-
expandDimensions( true, 1 ); // $ExpectError
37-
expandDimensions( false, 1 ); // $ExpectError
38-
expandDimensions( null, 1 ); // $ExpectError
39-
expandDimensions( {}, 1 ); // $ExpectError
40-
expandDimensions( [ '5' ], 1 ); // $ExpectError
41-
expandDimensions( ( x: number ): number => x, 1 ); // $ExpectError
34+
expandDimensions( '5', 1, false ); // $ExpectError
35+
expandDimensions( 5, 1, false ); // $ExpectError
36+
expandDimensions( true, 1, false ); // $ExpectError
37+
expandDimensions( false, 1, false ); // $ExpectError
38+
expandDimensions( void 0, 1, false ); // $ExpectError
39+
expandDimensions( null, 1, false ); // $ExpectError
40+
expandDimensions( {}, 1, false ); // $ExpectError
41+
expandDimensions( [ '5' ], 1, false ); // $ExpectError
42+
expandDimensions( ( x: number ): number => x, 1, false ); // $ExpectError
4243
}
4344

4445
// The compiler throws an error if the function is not provided a second argument which is a number...
4546
{
4647
const x = zeros( [ 2, 2 ] );
4748

48-
expandDimensions( x, '5' ); // $ExpectError
49-
expandDimensions( x, true ); // $ExpectError
50-
expandDimensions( x, false ); // $ExpectError
51-
expandDimensions( x, null ); // $ExpectError
52-
expandDimensions( x, {} ); // $ExpectError
53-
expandDimensions( x, [ '5' ] ); // $ExpectError
54-
expandDimensions( x, ( x: number ): number => x ); // $ExpectError
49+
expandDimensions( x, '5', false ); // $ExpectError
50+
expandDimensions( x, true, false ); // $ExpectError
51+
expandDimensions( x, false, false ); // $ExpectError
52+
expandDimensions( x, void 0, false ); // $ExpectError
53+
expandDimensions( x, null, false ); // $ExpectError
54+
expandDimensions( x, {}, false ); // $ExpectError
55+
expandDimensions( x, [ '5' ], false ); // $ExpectError
56+
expandDimensions( x, ( x: number ): number => x, false ); // $ExpectError
57+
}
58+
59+
// The compiler throws an error if the function is not provided a third argument which is a boolean...
60+
{
61+
const x = zeros( [ 2, 2 ] );
62+
63+
expandDimensions( x, 1, '5' ); // $ExpectError
64+
expandDimensions( x, 1, 5 ); // $ExpectError
65+
expandDimensions( x, 1, void 0 ); // $ExpectError
66+
expandDimensions( x, 1, null ); // $ExpectError
67+
expandDimensions( x, 1, {} ); // $ExpectError
68+
expandDimensions( x, 1, [ '5' ] ); // $ExpectError
69+
expandDimensions( x, 1, ( x: number ): number => x ); // $ExpectError
5570
}
5671

5772
// The compiler throws an error if the function is provided an unsupported number of arguments...
@@ -60,5 +75,6 @@ import expandDimensions = require( './index' );
6075

6176
expandDimensions(); // $ExpectError
6277
expandDimensions( x ); // $ExpectError
63-
expandDimensions( x, 1, [ 1, 2, 3 ], [ 2, 3 ] ); // $ExpectError
78+
expandDimensions( x, 1 ); // $ExpectError
79+
expandDimensions( x, 1, false, [ 1, 2, 3 ] ); // $ExpectError
6480
}

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/examples/index.js

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,12 @@
1818

1919
'use strict';
2020

21-
var array = require( '@stdlib/ndarray/array' );
22-
var numel = require( '@stdlib/ndarray/base/numel' );
23-
var ind2sub = require( '@stdlib/ndarray/ind2sub' );
24-
var getShape = require( '@stdlib/ndarray/shape' );
21+
var uniform = require( '@stdlib/random/uniform' );
22+
var ndarray2array = require( '@stdlib/ndarray/to-array' );
2523
var expandDimensions = require( './../lib' );
2624

27-
// Create a 2-dimensional array:
28-
var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
29-
// returns <ndarray>
25+
var x = uniform( [ 3, 3, 3 ], -10.0, 10.0 );
26+
console.log( ndarray2array( x ) );
3027

31-
// Insert a singleton dimension:
32-
var y = expandDimensions( x, 1 );
33-
// returns <ndarray>
34-
35-
// Retrieve the shape:
36-
var sh = getShape( y );
37-
// returns [ 2, 1, 2 ]
38-
39-
// Retrieve the number of elements:
40-
var N = numel( sh );
41-
42-
// Loop through the array elements...
43-
var i;
44-
for ( i = 0; i < N; i++ ) {
45-
console.log( 'Y[%s] = %d', ind2sub( sh, i ).join( ', ' ), y.iget( i ) );
46-
}
28+
var y = expandDimensions( x, 1, false );
29+
console.log( ndarray2array( y ) );

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/lib/index.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,14 @@
2424
* @module @stdlib/ndarray/base/expand-dimensions
2525
*
2626
* @example
27-
* var getShape = require( '@stdlib/ndarray/shape' );
2827
* var array = require( '@stdlib/ndarray/array' );
2928
* var expandDimensions = require( '@stdlib/ndarray/base/expand-dimensions' );
3029
*
3130
* var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
3231
* // returns <ndarray>[ [ 1, 2 ], [ 3, 4 ] ]
3332
*
34-
* var shx = getShape( x );
35-
* // returns [ 2, 2 ]
36-
*
37-
* var y = expandDimensions( x, 1 );
33+
* var y = expandDimensions( x, 1, false );
3834
* // returns <ndarray>[ [ [ 1, 2 ] ], [ [ 3, 4 ] ] ]
39-
*
40-
* var shy = getShape( y );
41-
* // returns [ 2, 1, 2 ]
4235
*/
4336

4437
// MODULES //

lib/node_modules/@stdlib/ndarray/base/expand-dimensions/lib/main.js

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

2323
var isRowMajor = require( '@stdlib/ndarray/base/assert/is-row-major-string' );
24-
var isReadOnly = require( '@stdlib/ndarray/base/assert/is-read-only' );
2524
var normalizeIndex = require( '@stdlib/ndarray/base/normalize-index' );
2625
var getDType = require( '@stdlib/ndarray/base/dtype' );
2726
var getShape = require( '@stdlib/ndarray/base/shape' );
@@ -43,26 +42,20 @@ var format = require( '@stdlib/string/format' );
4342
*
4443
* @param {ndarray} x - input array
4544
* @param {integer} axis - axis at which to insert a singleton dimension
45+
* @param {boolean} writable - boolean indicating whether the returned ndarray should be writable
4646
* @throws {RangeError} must provide a valid axis
4747
* @returns {ndarray} output array
4848
*
4949
* @example
50-
* var getShape = require( '@stdlib/ndarray/shape' );
5150
* var array = require( '@stdlib/ndarray/array' );
5251
*
5352
* var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
5453
* // returns <ndarray>[ [ 1, 2 ], [ 3, 4 ] ]
5554
*
56-
* var shx = getShape( x );
57-
* // returns [ 2, 2 ]
58-
*
59-
* var y = expandDimensions( x, 1 );
55+
* var y = expandDimensions( x, 1, false );
6056
* // returns <ndarray>[ [ [ 1, 2 ] ], [ [ 3, 4 ] ] ]
61-
*
62-
* var shy = getShape( y );
63-
* // returns [ 2, 1, 2 ]
6457
*/
65-
function expandDimensions( x, axis ) {
58+
function expandDimensions( x, axis, writable ) {
6659
var strides;
6760
var shape;
6861
var isrm;
@@ -132,13 +125,9 @@ function expandDimensions( x, axis ) {
132125
}
133126
}
134127
}
135-
if ( isReadOnly( x ) ) {
136-
// If provided a read-only view, the returned array should also be read-only...
137-
return new x.constructor( getDType( x ), getData( x ), shape, strides, getOffset( x ), ord, { // eslint-disable-line max-len
138-
'readonly': true
139-
});
140-
}
141-
return new x.constructor( getDType( x ), getData( x ), shape, strides, getOffset( x ), ord ); // eslint-disable-line max-len
128+
return new x.constructor( getDType( x ), getData( x ), shape, strides, getOffset( x ), ord, { // eslint-disable-line max-len
129+
'readonly': !writable
130+
});
142131
}
143132

144133

0 commit comments

Comments
 (0)