time-to-botec

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

README.md (10630B)


      1 <!--
      2 
      3 @license Apache-2.0
      4 
      5 Copyright (c) 2018 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 # ind2sub
     22 
     23 > Convert a linear index to an array of subscripts.
     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 ind2sub = require( '@stdlib/ndarray/base/ind2sub' );
     41 ```
     42 
     43 #### ind2sub( shape, strides, offset, order, idx, mode )
     44 
     45 Converts a linear index to an array of subscripts.
     46 
     47 ```javascript
     48 var shape = [ 2, 2 ];
     49 var order = 'row-major';
     50 var strides = [ 2, 1 ];
     51 var offset = 0;
     52 
     53 var subscripts = ind2sub( shape, strides, offset, order, 1, 'throw' );
     54 // returns [ 0, 1 ]
     55 ```
     56 
     57 The function supports the following `modes`:
     58 
     59 -   `throw`: specifies that the function should throw an error when a linear index exceeds array dimensions.
     60 -   `wrap`: specifies that the function should wrap around a linear index exceeding array dimensions using modulo arithmetic.
     61 -   `clamp`: specifies that the function should set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
     62 
     63 ```javascript
     64 var shape = [ 2, 2 ];
     65 var order = 'row-major';
     66 var strides = [ 2, 1 ];
     67 var offset = 0;
     68 
     69 var idx = ind2sub( shape, strides, offset, order, -2, 'wrap' );
     70 // returns [ 1, 0 ]
     71 
     72 idx = ind2sub( shape, strides, offset, order, 10, 'clamp' );
     73 // returns [ 1, 1 ]
     74 ```
     75 
     76 The `order` parameter specifies whether an array is `row-major` (C-style) or `column-major` (Fortran-style).
     77 
     78 ```javascript
     79 var shape = [ 2, 2 ];
     80 var order = 'column-major';
     81 var strides = [ 1, 2 ];
     82 var offset = 0;
     83 
     84 var idx = ind2sub( shape, strides, offset, order, 2, 'throw' );
     85 // returns [ 0, 1 ]
     86 ```
     87 
     88 #### ind2sub.assign( shape, strides, offset, order, idx, mode, out )
     89 
     90 Converts a linear index to an array of subscripts and assigns results to a provided output array.
     91 
     92 ```javascript
     93 var shape = [ 2, 2 ];
     94 var order = 'row-major';
     95 var strides = [ 2, 1 ];
     96 var offset = 0;
     97 
     98 var out = [ 0, 0 ];
     99 var subscripts = ind2sub.assign( shape, strides, offset, order, 1, 'throw', out );
    100 // returns [ 0, 1 ]
    101 
    102 var bool = ( subscripts === out );
    103 // returns true
    104 ```
    105 
    106 </section>
    107 
    108 <!-- /.usage -->
    109 
    110 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    111 
    112 <section class="notes">
    113 
    114 ## Notes
    115 
    116 -   When provided a stride array containing negative strides, if an `offset` is greater than `0`, the function interprets the linear index as an index into the underlying data buffer for the array, thus returning subscripts from the perspective of that buffer. If an `offset` is equal to `0`, the function treats the linear index as an index into an array view, thus returning subscripts from the perspective of that view.
    117 
    118     ```text
    119     Dims: 2x2
    120     Buffer: [ 1, 2, 3, 4 ]
    121 
    122     View = [ a00, a01,
    123              a10, a11 ]
    124 
    125     Strides: 2,1
    126     Offset: 0
    127 
    128     View = [ 1, 2,
    129              3, 4 ]
    130 
    131     Strides: 2,-1
    132     Offset: 1
    133 
    134     View = [ 2, 1,
    135              4, 3 ]
    136 
    137     Strides: -2,1
    138     Offset: 2
    139 
    140     View = [ 3, 4,
    141              1, 2 ]
    142 
    143     Strides: -2,-1
    144     Offset: 3
    145 
    146     View = [ 4, 3,
    147              2, 1 ]
    148     ```
    149 
    150     ```javascript
    151     var shape = [ 2, 2 ];
    152     var order = 'row-major';
    153     var strides = [ -2, 1 ];
    154     var offset = 2;
    155     var mode = 'throw';
    156 
    157     // From the perspective of a view...
    158     var s = ind2sub( shape, strides, 0, order, 0, mode );
    159     // returns [ 0, 0 ]
    160 
    161     s = ind2sub( shape, strides, 0, order, 1, mode );
    162     // returns [ 0, 1 ]
    163 
    164     s = ind2sub( shape, strides, 0, order, 2, mode );
    165     // returns [ 1, 0 ]
    166 
    167     s = ind2sub( shape, strides, 0, order, 3, mode );
    168     // returns [ 1, 1 ]
    169 
    170     // From the perspective of an underlying buffer...
    171     s = ind2sub( shape, strides, offset, order, 0, mode );
    172     // returns [ 1, 0 ]
    173 
    174     s = ind2sub( shape, strides, offset, order, 1, mode );
    175     // returns [ 1, 1 ]
    176 
    177     s = ind2sub( shape, strides, offset, order, 2, mode );
    178     // returns [ 0, 0 ]
    179 
    180     s = ind2sub( shape, strides, offset, order, 3, mode );
    181     // returns [ 0, 1 ]
    182     ```
    183 
    184     In short, from the perspective of a view, view data is always ordered.
    185 
    186 </section>
    187 
    188 <!-- /.notes -->
    189 
    190 <!-- Package usage examples. -->
    191 
    192 <section class="examples">
    193 
    194 ## Examples
    195 
    196 <!-- eslint no-undef: "error" -->
    197 
    198 ```javascript
    199 var discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
    200 var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
    201 var strides2offset = require( '@stdlib/ndarray/base/strides2offset' );
    202 var numel = require( '@stdlib/ndarray/base/numel' );
    203 var randu = require( '@stdlib/random/base/randu' );
    204 var abs = require( '@stdlib/math/base/special/abs' );
    205 var ind2sub = require( '@stdlib/ndarray/base/ind2sub' );
    206 
    207 // Specify array characteristics:
    208 var shape = [ 3, 3, 3 ];
    209 var order = 'row-major';
    210 
    211 // Compute array meta data:
    212 var ndims = shape.length;
    213 var strides = shape2strides( shape, order );
    214 var len = numel( shape );
    215 
    216 // Determine stride indices to be used for formatting how views are displayed...
    217 var s0;
    218 var s1;
    219 if ( order === 'column-major' ) {
    220     s0 = ndims - 1;
    221     s1 = s0 - 1;
    222 } else { // row-major
    223     s0 = 0;
    224     s1 = s0 + 1;
    225 }
    226 
    227 // Initialize a linear array...
    228 var arr = [];
    229 var i;
    230 for ( i = 0; i < len; i++ ) {
    231     arr.push( 0 );
    232 }
    233 
    234 // Generate random views and display the mapping of elements in the linear array to view subscripts...
    235 var offset;
    236 var row;
    237 var j;
    238 var s;
    239 for ( i = 0; i < 20; i++ ) {
    240     // Randomly flip the sign of one of the strides...
    241     j = discreteUniform( 0, ndims-1 );
    242     strides[ j ] *= ( randu() < 0.5 ) ? -1 : 1;
    243     offset = strides2offset( shape, strides );
    244 
    245     // Print view meta data...
    246     console.log( '' );
    247     console.log( 'Dimensions: %s.', shape.join( 'x' ) );
    248     console.log( 'Strides: %s.', strides.join( ',' ) );
    249     console.log( 'View (subscripts):' );
    250 
    251     // Print the mapping of elements in the linear array to view subscripts...
    252     row = '  ';
    253     for ( j = 0; j < len; j++ ) {
    254         s = ind2sub( shape, strides, offset, order, j, 'throw' );
    255         row += '(' + s.join( ',' ) + ')';
    256         if ( ndims === 1 && j === len-1 ) {
    257             console.log( row );
    258         } else if ( ndims === 2 && (j+1)%abs( strides[ s0 ] ) === 0 ) {
    259             console.log( row );
    260             row = '  ';
    261         } else if ( ndims > 2 && (j+1)%abs( strides[ s1 ] ) === 0 ) {
    262             console.log( row );
    263             if ( (j+1)%abs( strides[ s0 ] ) === 0 ) {
    264                 console.log( '' );
    265             }
    266             row = '  ';
    267         } else {
    268             row += ', ';
    269         }
    270     }
    271 }
    272 ```
    273 
    274 </section>
    275 
    276 <!-- /.examples -->
    277 
    278 <!-- C interface documentation. -->
    279 
    280 * * *
    281 
    282 <section class="c">
    283 
    284 ## C APIs
    285 
    286 <!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
    287 
    288 <section class="intro">
    289 
    290 </section>
    291 
    292 <!-- /.intro -->
    293 
    294 <!-- C usage documentation. -->
    295 
    296 <section class="usage">
    297 
    298 ### Usage
    299 
    300 ```c
    301 #include "stdlib/ndarray/base/ind2sub.h"
    302 ```
    303 
    304 <!-- lint disable maximum-heading-length -->
    305 
    306 #### stdlib_ndarray_ind2sub( ndims, \*shape, \*strides, offset, order, idx, mode, \*out )
    307 
    308 Computes the minimum and maximum linear indices in an underlying data buffer accessible to an array view.
    309 
    310 ```c
    311 #include "stdlib/ndarray/index_modes.h"
    312 #include "stdlib/ndarray/orders.h"
    313 #include <stdint.h>
    314 
    315 int64_t ndims = 2;
    316 int64_t shape[] = { 3, 3 };
    317 int64_t strides[] = { -3, 1 };
    318 int64_t offset = 6;
    319 
    320 int64_t out[ 2 ];
    321 
    322 int8_t status = stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, 7, STDLIB_NDARRAY_INDEX_ERROR, out );
    323 if ( status == -1 ) {
    324     // Handle error...
    325 }
    326 ```
    327 
    328 The function accepts the following arguments:
    329 
    330 -   **ndims**: `[in] int64_t` number of dimensions.
    331 -   **shape**: `[in] int64_t*` array shape (dimensions).
    332 -   **strides**: `[in] int64_t*` array strides.
    333 -   **offset**: `[in] int64_t` index offset.
    334 -   **order**: `[in] enum STDLIB_NDARRAY_ORDER` specifies whether an array is row-major (C-style) or column-major (Fortran-style).
    335 -   **idx**: `[in] int64_t` linear index in an array view.
    336 -   **mode**: `[in] enum STDLIB_NDARRAY_INDEX_MODE` specifies how to handle a linear index which exceeds array dimensions.
    337 -   **out**: `[out] int64_t*` output array.
    338 
    339 ```c
    340 int8_t stdlib_ndarray_ind2sub( int64_t ndims, int64_t *shape, int64_t *strides, int64_t offset, enum STDLIB_NDARRAY_ORDER order, int64_t idx, enum STDLIB_NDARRAY_INDEX_MODE mode, int64_t *out );
    341 ```
    342 
    343 </section>
    344 
    345 <!-- /.usage -->
    346 
    347 <!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    348 
    349 <section class="notes">
    350 
    351 </section>
    352 
    353 <!-- /.notes -->
    354 
    355 <!-- C API usage examples. -->
    356 
    357 <section class="examples">
    358 
    359 ### Examples
    360 
    361 ```c
    362 #include "stdlib/ndarray/base/ind2sub.h"
    363 #include "stdlib/ndarray/index_modes.h"
    364 #include "stdlib/ndarray/orders.h"
    365 #include <stdint.h>
    366 #include <stdio.h>
    367 #include <inttypes.h>
    368 
    369 int main() {
    370     int64_t ndims = 2;
    371     int64_t shape[] = { 3, 3 };
    372     int64_t strides[] = { -3, 1 };
    373     int64_t offset = 6;
    374 
    375     int64_t out[ 2 ];
    376 
    377     stdlib_ndarray_ind2sub( ndims, shape, strides, offset, STDLIB_NDARRAY_ROW_MAJOR, 7, STDLIB_NDARRAY_INDEX_ERROR, out );
    378 
    379     int i;
    380     printf( "subscripts = { " );
    381     for ( i = 0; i < ndims; i++ ) {
    382         printf( "%"PRId64"", out[ i ] );
    383         if ( i < ndims-1 ) {
    384             printf( ", " );
    385         }
    386     }
    387     printf( " }\n" );
    388 }
    389 ```
    390 
    391 </section>
    392 
    393 <!-- /.examples -->
    394 
    395 </section>
    396 
    397 <!-- /.c -->
    398 
    399 <!-- 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. -->
    400 
    401 <section class="references">
    402 
    403 </section>
    404 
    405 <!-- /.references -->
    406 
    407 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    408 
    409 <section class="links">
    410 
    411 </section>
    412 
    413 <!-- /.links -->