Skip to content

Commit 5324e96

Browse files
headlessNodekgryte
andauthored
feat: add ndarray/base/maybe-broadcast-array-except-dimensions
PR-URL: #10413 Closes: stdlib-js/metr-issue-tracker#167 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com>
1 parent f10a6aa commit 5324e96

File tree

10 files changed

+1437
-0
lines changed

10 files changed

+1437
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2026 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+
# maybeBroadcastArrayExceptDimensions
22+
23+
> Broadcast an [ndarray][@stdlib/ndarray/base/ctor] to a specified shape while keeping a list of specified dimensions unchanged if and only if the specified shape differs from the provided [ndarray][@stdlib/ndarray/base/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+
<!-- eslint-disable id-length -->
40+
41+
```javascript
42+
var maybeBroadcastArrayExceptDimensions = require( '@stdlib/ndarray/base/maybe-broadcast-array-except-dimensions' );
43+
```
44+
45+
#### maybeBroadcastArrayExceptDimensions( arr, shape, dims )
46+
47+
Broadcasts an [ndarray][@stdlib/ndarray/base/ctor] to a specified shape while keeping a list of specified dimensions unchanged if and only if the specified shape differs from the provided [ndarray][@stdlib/ndarray/base/ctor]'s shape.
48+
49+
<!-- eslint-disable id-length -->
50+
51+
```javascript
52+
var array = require( '@stdlib/ndarray/array' );
53+
54+
// Create a 2x2 ndarray:
55+
var x = array( [ [ 1, 2 ], [ 3, 4 ] ] );
56+
// returns <ndarray>[ [ 1, 2 ], [ 3, 4 ] ]
57+
58+
// Perform broadcasting:
59+
var y = maybeBroadcastArrayExceptDimensions( x, [ 3, 2, 2 ], [ -1 ] );
60+
// returns <ndarray>[ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 1, 2 ], [ 3, 4 ] ], [ [ 1, 2 ], [ 3, 4 ] ] ]
61+
```
62+
63+
The function accepts the following arguments:
64+
65+
- **arr**: input [ndarray][@stdlib/ndarray/base/ctor].
66+
- **shape**: target shape.
67+
- **dims**: list of dimensions to exclude from broadcasting. Should be a list of negative integers.
68+
69+
</section>
70+
71+
<!-- /.usage -->
72+
73+
<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
74+
75+
<section class="notes">
76+
77+
## Notes
78+
79+
- The function throws an error if a provided [ndarray][@stdlib/ndarray/base/ctor] is [incompatible][@stdlib/ndarray/base/broadcast-shapes] with a provided shape.
80+
- If a provided [ndarray][@stdlib/ndarray/base/ctor] has the same shape as the specified shape (excluding the list of specified dimensions), the function returns the provided [ndarray][@stdlib/ndarray/base/ctor].
81+
- If a provided [ndarray][@stdlib/ndarray/base/ctor] has a different (broadcast compatible) shape than the specified shape, the function returns a new (base) [ndarray][@stdlib/ndarray/base/ctor] view of the provided [ndarray][@stdlib/ndarray/base/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 view may affect multiple elements. If you need to write to the returned [ndarray][@stdlib/ndarray/base/ctor], copy the [ndarray][@stdlib/ndarray/base/ctor] **before** performing operations which may mutate elements.
82+
- If a provided [ndarray][@stdlib/ndarray/base/ctor] does not have the same shape as the specified shape (excluding the list of specified dimensions), the returned [ndarray][@stdlib/ndarray/base/ctor] is a "base" [ndarray][@stdlib/ndarray/base/ctor], and, thus, the returned [ndarray][@stdlib/ndarray/base/ctor] does not perform bounds checking or afford any of the guarantees of the non-base [ndarray][@stdlib/ndarray/ctor] constructor. The primary intent of this function is to broadcast an ndarray-like object within internal implementations and to do so with minimal overhead.
83+
84+
</section>
85+
86+
<!-- /.notes -->
87+
88+
<!-- Package usage examples. -->
89+
90+
<section class="examples">
91+
92+
## Examples
93+
94+
<!-- eslint-disable id-length -->
95+
96+
<!-- eslint no-undef: "error" -->
97+
98+
```javascript
99+
var array = require( '@stdlib/ndarray/array' );
100+
var numel = require( '@stdlib/ndarray/base/numel' );
101+
var ind2sub = require( '@stdlib/ndarray/ind2sub' );
102+
var getShape = require( '@stdlib/ndarray/shape' );
103+
var maybeBroadcastArrayExceptDimensions = require( '@stdlib/ndarray/base/maybe-broadcast-array-except-dimensions' );
104+
105+
// Create a 1x3 array:
106+
var x = array( [ [ 1, 2, 3 ] ] );
107+
// returns <ndarray>[ [ 1, 2, 3 ] ]
108+
109+
// Broadcast the array to 2x1x3:
110+
var y = maybeBroadcastArrayExceptDimensions( x, [ 2, 2, 3 ], [ -2 ] );
111+
// returns <ndarray>[ [ [ 1, 2, 3 ] ], [ [ 1, 2, 3 ] ] ]
112+
113+
// Retrieve the shape:
114+
var sh = getShape( y );
115+
// returns [ 2, 1, 3 ]
116+
117+
// Retrieve the number of elements:
118+
var N = numel( sh );
119+
120+
// Loop through the array elements...
121+
var sub;
122+
var v;
123+
var i;
124+
for ( i = 0; i < N; i++ ) {
125+
v = y.iget( i );
126+
sub = ind2sub( sh, i );
127+
console.log( 'Y[%s] = %d', sub.join( ', ' ), v );
128+
}
129+
```
130+
131+
</section>
132+
133+
<!-- /.examples -->
134+
135+
<!-- 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. -->
136+
137+
<section class="references">
138+
139+
</section>
140+
141+
<!-- /.references -->
142+
143+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
144+
145+
<section class="related">
146+
147+
</section>
148+
149+
<!-- /.related -->
150+
151+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
152+
153+
<section class="links">
154+
155+
[@stdlib/ndarray/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/ctor
156+
157+
[@stdlib/ndarray/base/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/base/ctor
158+
159+
[@stdlib/ndarray/base/broadcast-shapes]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/base/broadcast-shapes
160+
161+
</section>
162+
163+
<!-- /.links -->

0 commit comments

Comments
 (0)