Skip to content

Commit e96df4a

Browse files
committed
feat: add ndarray/maybe-broadcast-array
1 parent bc1768e commit e96df4a

File tree

11 files changed

+1539
-0
lines changed

11 files changed

+1539
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2023 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# maybeBroadcastArray
22+
23+
> Broadcast an [ndarray][@stdlib/ndarray/ctor] to a specified shape if and only if the specified shape differs from the provided [ndarray][@stdlib/ndarray/ctor]'s shape.
24+
25+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
26+
27+
<section class="intro">
28+
29+
</section>
30+
31+
<!-- /.intro -->
32+
33+
<!-- Package usage documentation. -->
34+
35+
<section class="usage">
36+
37+
## Usage
38+
39+
```javascript
40+
var maybeBroadcastArray = require( '@stdlib/ndarray/maybe-broadcast-array' );
41+
```
42+
43+
#### maybeBroadcastArray( arr, shape )
44+
45+
Broadcasts an [ndarray][@stdlib/ndarray/ctor] to a specified `shape` if and only if the specified `shape` differs from the provided [ndarray][@stdlib/ndarray/ctor]'s shape.
46+
47+
```javascript
48+
var array = require( '@stdlib/ndarray/array' );
49+
50+
// Create a 2x2 ndarray:
51+
var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
52+
// returns <ndarray>
53+
54+
// Broadcast to a 2x2x2 ndarray:
55+
var y = maybeBroadcastArray( x, [ 2, 2, 2 ] );
56+
// returns <ndarray>
57+
```
58+
59+
</section>
60+
61+
<!-- /.usage -->
62+
63+
<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
64+
65+
<section class="notes">
66+
67+
## Notes
68+
69+
- The function throws an error if a provided [ndarray][@stdlib/ndarray/ctor] is [incompatible][@stdlib/ndarray/base/broadcast-shapes] with a provided shape.
70+
- If a provided [ndarray][@stdlib/ndarray/ctor] has the same shape as the specified shape, the function returns the provided [ndarray][@stdlib/ndarray/ctor].
71+
- If a provided [ndarray][@stdlib/ndarray/ctor] has a different (broadcast compatible) shape than the specified shape, the function returns a new **read-only** [ndarray][@stdlib/ndarray/ctor] view of the provided [ndarray][@stdlib/ndarray/ctor]'s data. The view is typically **not** contiguous. As more than one element of a returned view may refer to the same memory location, writing to the input [ndarray][@stdlib/ndarray/ctor] may affect multiple elements. If you need to write to the input [ndarray][@stdlib/ndarray/ctor], copy the [ndarray][@stdlib/ndarray/ctor] **before** broadcasting.
72+
73+
</section>
74+
75+
<!-- /.notes -->
76+
77+
<!-- Package usage examples. -->
78+
79+
<section class="examples">
80+
81+
## Examples
82+
83+
<!-- eslint no-undef: "error" -->
84+
85+
```javascript
86+
var array = require( '@stdlib/ndarray/array' );
87+
var numel = require( '@stdlib/ndarray/base/numel' );
88+
var ind2sub = require( '@stdlib/ndarray/ind2sub' );
89+
var maybeBroadcastArray = require( '@stdlib/ndarray/maybe-broadcast-array' );
90+
91+
// Create a 2x2 array:
92+
var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
93+
// returns <ndarray>
94+
95+
// Broadcast the array to 3x2x2:
96+
var y = maybeBroadcastArray( x, [ 3, 2, 2 ] );
97+
// returns <ndarray>
98+
99+
// Retrieve the shape:
100+
var sh = y.shape;
101+
// returns [ 3, 2, 2 ]
102+
103+
// Retrieve the number of elements:
104+
var N = numel( sh );
105+
106+
// Loop through the array elements...
107+
var i;
108+
for ( i = 0; i < N; i++ ) {
109+
console.log( 'Y[%s] = %d', ind2sub( sh, i ).join( ', ' ), y.iget( i ) );
110+
}
111+
```
112+
113+
</section>
114+
115+
<!-- /.examples -->
116+
117+
<!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
118+
119+
<section class="references">
120+
121+
</section>
122+
123+
<!-- /.references -->
124+
125+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
126+
127+
<section class="related">
128+
129+
</section>
130+
131+
<!-- /.related -->
132+
133+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
134+
135+
<section class="links">
136+
137+
[@stdlib/ndarray/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/ctor
138+
139+
[@stdlib/ndarray/base/broadcast-shapes]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/base/broadcast-shapes
140+
141+
</section>
142+
143+
<!-- /.links -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 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 bench = require( '@stdlib/bench' );
24+
var Float64Array = require( '@stdlib/array/float64' );
25+
var ndarrayBase = require( '@stdlib/ndarray/base/ctor' );
26+
var ndarray = require( '@stdlib/ndarray/ctor' );
27+
var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' );
28+
var pkg = require( './../package.json' ).name;
29+
var maybeBroadcastArray = require( './../lib' );
30+
31+
32+
// MAIN //
33+
34+
bench( pkg+'::base_ndarray,2d', function benchmark( b ) {
35+
var strides;
36+
var values;
37+
var buffer;
38+
var offset;
39+
var dtype;
40+
var shape;
41+
var order;
42+
var out;
43+
var i;
44+
45+
dtype = 'float64';
46+
buffer = new Float64Array( 4 );
47+
shape = [ 2, 2 ];
48+
strides = [ 2, 1 ];
49+
offset = 0;
50+
order = 'row-major';
51+
52+
values = [
53+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
54+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
55+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
56+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
57+
ndarrayBase( dtype, buffer, shape, strides, offset, order )
58+
];
59+
60+
b.tic();
61+
for ( i = 0; i < b.iterations; i++ ) {
62+
out = maybeBroadcastArray( values[ i%values.length ], [ 2, 2, 2 ] );
63+
if ( typeof out !== 'object' ) {
64+
b.fail( 'should return an object' );
65+
}
66+
}
67+
b.toc();
68+
if ( !isndarrayLike( out ) ) {
69+
b.fail( 'should return an ndarray' );
70+
}
71+
b.pass( 'benchmark finished' );
72+
b.end();
73+
});
74+
75+
bench( pkg+'::base_ndarray,2d,same_shape', function benchmark( b ) {
76+
var strides;
77+
var values;
78+
var buffer;
79+
var offset;
80+
var dtype;
81+
var shape;
82+
var order;
83+
var out;
84+
var i;
85+
86+
dtype = 'float64';
87+
buffer = new Float64Array( 4 );
88+
shape = [ 2, 2 ];
89+
strides = [ 2, 1 ];
90+
offset = 0;
91+
order = 'row-major';
92+
93+
values = [
94+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
95+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
96+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
97+
ndarrayBase( dtype, buffer, shape, strides, offset, order ),
98+
ndarrayBase( dtype, buffer, shape, strides, offset, order )
99+
];
100+
101+
b.tic();
102+
for ( i = 0; i < b.iterations; i++ ) {
103+
out = maybeBroadcastArray( values[ i%values.length ], shape );
104+
if ( typeof out !== 'object' ) {
105+
b.fail( 'should return an object' );
106+
}
107+
}
108+
b.toc();
109+
if ( !isndarrayLike( out ) ) {
110+
b.fail( 'should return an ndarray' );
111+
}
112+
b.pass( 'benchmark finished' );
113+
b.end();
114+
});
115+
116+
bench( pkg+'::ndarray,2d', function benchmark( b ) {
117+
var strides;
118+
var values;
119+
var buffer;
120+
var offset;
121+
var dtype;
122+
var shape;
123+
var order;
124+
var out;
125+
var i;
126+
127+
dtype = 'float64';
128+
buffer = new Float64Array( 4 );
129+
shape = [ 2, 2 ];
130+
strides = [ 2, 1 ];
131+
offset = 0;
132+
order = 'row-major';
133+
134+
values = [
135+
ndarray( dtype, buffer, shape, strides, offset, order ),
136+
ndarray( dtype, buffer, shape, strides, offset, order ),
137+
ndarray( dtype, buffer, shape, strides, offset, order ),
138+
ndarray( dtype, buffer, shape, strides, offset, order ),
139+
ndarray( dtype, buffer, shape, strides, offset, order )
140+
];
141+
142+
b.tic();
143+
for ( i = 0; i < b.iterations; i++ ) {
144+
out = maybeBroadcastArray( values[ i%values.length ], [ 2, 2, 2 ] );
145+
if ( typeof out !== 'object' ) {
146+
b.fail( 'should return an object' );
147+
}
148+
}
149+
b.toc();
150+
if ( !isndarrayLike( out ) ) {
151+
b.fail( 'should return an ndarray' );
152+
}
153+
b.pass( 'benchmark finished' );
154+
b.end();
155+
});
156+
157+
bench( pkg+'::ndarray,2d,same_shape', function benchmark( b ) {
158+
var strides;
159+
var values;
160+
var buffer;
161+
var offset;
162+
var dtype;
163+
var shape;
164+
var order;
165+
var out;
166+
var i;
167+
168+
dtype = 'float64';
169+
buffer = new Float64Array( 4 );
170+
shape = [ 2, 2 ];
171+
strides = [ 2, 1 ];
172+
offset = 0;
173+
order = 'row-major';
174+
175+
values = [
176+
ndarray( dtype, buffer, shape, strides, offset, order ),
177+
ndarray( dtype, buffer, shape, strides, offset, order ),
178+
ndarray( dtype, buffer, shape, strides, offset, order ),
179+
ndarray( dtype, buffer, shape, strides, offset, order ),
180+
ndarray( dtype, buffer, shape, strides, offset, order )
181+
];
182+
183+
b.tic();
184+
for ( i = 0; i < b.iterations; i++ ) {
185+
out = maybeBroadcastArray( values[ i%values.length ], shape );
186+
if ( typeof out !== 'object' ) {
187+
b.fail( 'should return an object' );
188+
}
189+
}
190+
b.toc();
191+
if ( !isndarrayLike( out ) ) {
192+
b.fail( 'should return an ndarray' );
193+
}
194+
b.pass( 'benchmark finished' );
195+
b.end();
196+
});

0 commit comments

Comments
 (0)