time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

README.md (10317B)


      1 <!--
      2 
      3 @license Apache-2.0
      4 
      5 Copyright (c) 2021 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 # broadcastShapes
     22 
     23 > Broadcast array shapes to a single 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 broadcastShapes = require( '@stdlib/ndarray/base/broadcast-shapes' );
     41 ```
     42 
     43 #### broadcastShapes( shapes )
     44 
     45 Broadcasts array shapes to a single shape.
     46 
     47 ```javascript
     48 var sh1 = [ 8, 1, 6, 1 ];
     49 var sh2 = [ 7, 1, 5 ];
     50 
     51 var sh = broadcastShapes( [ sh1, sh2 ] );
     52 // returns [ 8, 7, 6, 5 ]
     53 ```
     54 
     55 </section>
     56 
     57 <!-- /.usage -->
     58 
     59 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
     60 
     61 <section class="notes">
     62 
     63 ## Notes
     64 
     65 -   When operating on two arrays, the function compares their shapes element-wise, beginning with the trailing (i.e., rightmost) dimension. The following are examples of compatible shapes and their corresponding broadcasted shape:
     66 
     67     ```text
     68     A      (4d array):  8 x 1 x 6 x 1
     69     B      (3d array):      7 x 1 x 5
     70     ---------------------------------
     71     Result (4d array):  8 x 7 x 6 x 5
     72 
     73     A      (2d array):  5 x 4
     74     B      (1d array):      1
     75     -------------------------
     76     Result (2d array):  5 x 4
     77 
     78     A      (2d array):  5 x 4
     79     B      (1d array):      4
     80     -------------------------
     81     Result (2d array):  5 x 4
     82 
     83     A      (3d array):  15 x 3 x 5
     84     B      (3d array):  15 x 1 x 5
     85     ------------------------------
     86     Result (3d array):  15 x 3 x 5
     87 
     88     A      (3d array):  15 x 3 x 5
     89     B      (2d array):       3 x 5
     90     ------------------------------
     91     Result (3d array):  15 x 3 x 5
     92 
     93     A      (3d array):  15 x 3 x 5
     94     B      (2d array):       3 x 1
     95     ------------------------------
     96     Result (3d array):  15 x 3 x 5
     97 
     98     A      (5d array):  8 x 1 x 1 x 6 x 1
     99     B      (4d array):      1 x 7 x 1 x 5
    100     C      (5d array):  8 x 4 x 1 x 6 x 5
    101     -------------------------------------
    102     Result (5d array):  8 x 4 x 7 x 6 x 5
    103 
    104     A      (5d array):  8 x 1 x 1 x 6 x 1
    105     B      (1d array):                  0
    106     -------------------------------------
    107     Result (5d array):  8 x 1 x 1 x 6 x 0
    108 
    109     A      (5d array):  8 x 0 x 1 x 6 x 1
    110     B      (2d array):              6 x 5
    111     -------------------------------------
    112     Result (5d array):  8 x 0 x 1 x 6 x 5
    113 
    114     A      (5d array):  8 x 1 x 1 x 6 x 1
    115     B      (5d array):  8 x 0 x 1 x 6 x 1
    116     -------------------------------------
    117     Result (5d array):  8 x 0 x 1 x 6 x 1
    118 
    119     A      (3d array):  3 x 2 x 1
    120     B      (0d array):
    121     -----------------------------
    122     Result (3d array):  3 x 2 x 1
    123 
    124     A      (0d array):
    125     B      (3d array):  3 x 2 x 1
    126     -----------------------------
    127     Result (3d array):  3 x 2 x 1
    128     ```
    129 
    130     As demonstrated above, arrays are not required to have the same number of dimensions in order to be broadcast compatible. Array shapes with fewer dimensions are implicitly prepended with singleton dimensions (i.e., dimensions equal to `1`). Accordingly, the following example
    131 
    132     ```text
    133     A      (2d array):  5 x 4
    134     B      (1d array):      4
    135     -------------------------
    136     Result (2d array):  5 x 4
    137     ```
    138 
    139     is equivalent to
    140 
    141     ```text
    142     A      (2d array):  5 x 4
    143     B      (2d array):  1 x 4
    144     -------------------------
    145     Result (2d array):  5 x 4
    146     ```
    147 
    148     Similarly, a zero-dimensional array is expanded (by prepending singleton dimensions) from
    149 
    150     ```text
    151     A      (3d array):  3 x 2 x 1
    152     B      (0d array):
    153     -----------------------------
    154     Result (3d array):  3 x 2 x 1
    155     ```
    156 
    157     to
    158 
    159     ```text
    160     A      (3d array):  3 x 2 x 1
    161     B      (3d array):  1 x 1 x 1
    162     -----------------------------
    163     Result (3d array):  3 x 2 x 1
    164     ```
    165 
    166     Stated otherwise, every array has implicit leading dimensions of size `1`. During broadcasting, a `3 x 4` matrix is the same as a `3 x 4 x 1 x 1 x 1` multidimensional array.
    167 
    168 -   Two respective dimensions in two shape arrays are compatible if
    169 
    170     1.  the dimensions are equal.
    171     2.  one dimension is `1`.
    172 
    173     The two aforementioned rules apply to empty arrays or arrays that have a dimension of size `0`. For unequal dimensions, the size of the dimension which is not `1` determines the size of the output shape dimension.
    174 
    175     Accordingly, dimensions of size `0` must be paired with a dimension of size `0` or `1`. In such cases, by the rules above, the size of the corresponding output shape dimension is `0`.
    176 
    177 -   The function returns `null` if provided incompatible shapes (i.e., shapes which cannot be broadcast with one another).
    178 
    179     ```javascript
    180     var sh1 = [ 3, 2 ];
    181     var sh2 = [ 2, 3 ];
    182 
    183     var sh = broadcastShapes( [ sh1, sh2 ] );
    184     // returns null
    185     ```
    186 
    187     The following are examples of array shapes which are **not** compatible and do **not** broadcast:
    188 
    189     ```text
    190     A      (1d array):  3
    191     B      (1d array):  4                   # dimension does not match
    192 
    193     A      (2d array):      2 x 1
    194     B      (3d array):  8 x 4 x 3           # second dimension does not match
    195 
    196     A      (3d array):  15 x 3 x 5
    197     B      (2d array):  15 x 3              # singleton dimensions can only be prepended, not appended
    198 
    199     A      (5d array):  8 x 8 x 1 x 6 x 1
    200     B      (5d array):  8 x 0 x 1 x 6 x 1   # second dimension does not match
    201     ```
    202 
    203 </section>
    204 
    205 <!-- /.notes -->
    206 
    207 <!-- Package usage examples. -->
    208 
    209 <section class="examples">
    210 
    211 ## Examples
    212 
    213 <!-- eslint no-undef: "error" -->
    214 
    215 ```javascript
    216 var lpad = require( '@stdlib/string/left-pad' );
    217 var broadcastShapes = require( '@stdlib/ndarray/base/broadcast-shapes' );
    218 
    219 var shapes;
    220 var out;
    221 var sh;
    222 var i;
    223 var j;
    224 
    225 function shape2string( shape ) {
    226     return lpad( shape.join( ' x ' ), 20, ' ' );
    227 }
    228 
    229 shapes = [
    230     [ [ 1, 2 ], [ 2 ] ],
    231     [ [ 1, 1 ], [ 3, 4 ] ],
    232     [ [ 6, 7 ], [ 5, 6, 1 ], [ 7 ], [ 5, 1, 7 ] ],
    233     [ [ 1, 3 ], [ 3, 1 ] ],
    234     [ [ 1 ], [ 3 ] ],
    235     [ [ 2 ], [ 3, 2 ] ],
    236     [ [ 2, 3 ], [ 2, 3 ], [ 2, 3 ], [ 2, 3 ] ],
    237     [ [ 1, 2 ], [ 1, 2 ] ]
    238 ];
    239 
    240 for ( i = 0; i < shapes.length; i++ ) {
    241     sh = shapes[ i ];
    242     for ( j = 0; j < sh.length; j++ ) {
    243         console.log( shape2string( sh[ j ] ) );
    244     }
    245     console.log( lpad( '', 20, '-' ) );
    246 
    247     out = broadcastShapes( sh );
    248     console.log( shape2string( out )+'\n' );
    249 }
    250 ```
    251 
    252 </section>
    253 
    254 <!-- /.examples -->
    255 
    256 <!-- C interface documentation. -->
    257 
    258 * * *
    259 
    260 <section class="c">
    261 
    262 ## C APIs
    263 
    264 <!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
    265 
    266 <section class="intro">
    267 
    268 </section>
    269 
    270 <!-- /.intro -->
    271 
    272 <!-- C usage documentation. -->
    273 
    274 <section class="usage">
    275 
    276 ### Usage
    277 
    278 ```c
    279 #include "stdlib/ndarray/base/broadcast_shapes.h"
    280 ```
    281 
    282 #### stdlib_ndarray_broadcast_shapes( M, \*\*shapes, \*ndims, \*out )
    283 
    284 Broadcasts array shapes to a single shape.
    285 
    286 ```c
    287 #include "stdlib/ndarray/base/broadcast_shapes.h"
    288 #include <stdint.h>
    289 
    290 int64_t N1 = 4;
    291 int64_t sh1[] = { 8, 1, 6, 1 };
    292 
    293 int64_t N2 = 3;
    294 int64_t sh2[] = { 7, 1, 5 };
    295 
    296 int64_t ndims[] = { N1, N2 };
    297 int64_t *shapes[] = { sh1, sh2 };
    298 
    299 int64_t out[] = { 0, 0, 0, 0 };
    300 int8_t status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out );
    301 if ( status != 0 ) {
    302     // Handle error...
    303 }
    304 ```
    305 
    306 The function accepts the following arguments:
    307 
    308 -   **M**: `[in] int64_t` number of shape arrays.
    309 -   **shapes**: `[in] int64_t**` array of shape arrays (dimensions).
    310 -   **ndims**: `[in] int64_t*` number of dimensions for each respective shape array.
    311 -   **out**: `[out] int64_t*` output shape array.
    312 
    313 ```c
    314 int8_t stdlib_ndarray_broadcast_shapes( int64_t M, int64_t *shapes[], int64_t ndims[], int64_t *out );
    315 ```
    316 
    317 If successful, the function returns `0`; otherwise, the function returns `-1` (e.g., due to incompatible shapes).
    318 
    319 </section>
    320 
    321 <!-- /.usage -->
    322 
    323 <!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    324 
    325 <section class="notes">
    326 
    327 ### Notes
    328 
    329 -   Even if the function is unsuccessful, the function may still overwrite elements in the output array before returning. In other words, do not assume that providing incompatible shapes is a no-op with regard to the output array.
    330 
    331 </section>
    332 
    333 <!-- /.notes -->
    334 
    335 <!-- C API usage examples. -->
    336 
    337 <section class="examples">
    338 
    339 ### Examples
    340 
    341 ```c
    342 #include "stdlib/ndarray/base/broadcast_shapes.h"
    343 #include <stdint.h>
    344 #include <stdio.h>
    345 #include <inttypes.h>
    346 
    347 int main() {
    348     int64_t N1 = 4;
    349     int64_t sh1[] = { 8, 1, 6, 1 };
    350 
    351     int64_t N2 = 3;
    352     int64_t sh2[] = { 7, 1, 5 };
    353 
    354     int64_t ndims[] = { N1, N2 };
    355     int64_t *shapes[] = { sh1, sh2 };
    356 
    357     int64_t out[] = { 0, 0, 0, 0 };
    358     int8_t status = stdlib_ndarray_broadcast_shapes( 2, shapes, ndims, out );
    359     if ( status != 0 ) {
    360         printf( "incompatible shapes\n" );
    361         return 1;
    362     }
    363     int64_t i;
    364     printf( "shape = ( " );
    365     for ( i = 0; i < N1; i++ ) {
    366         printf( "%"PRId64"", out[ i ] );
    367         if ( i < N1-1 ) {
    368             printf( ", " );
    369         }
    370     }
    371     printf( " )\n" );
    372     return 0;
    373 }
    374 ```
    375 
    376 </section>
    377 
    378 <!-- /.examples -->
    379 
    380 </section>
    381 
    382 <!-- /.c -->
    383 
    384 <!-- 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. -->
    385 
    386 <section class="references">
    387 
    388 </section>
    389 
    390 <!-- /.references -->
    391 
    392 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    393 
    394 <section class="links">
    395 
    396 </section>
    397 
    398 <!-- /.links -->