All files / ndarray/ind2sub/lib main.js

100% Statements 88/88
100% Branches 9/9
100% Functions 1/1
100% Lines 88/88

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 892x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 167x 167x 167x 167x 167x 167x 167x 167x 135x 135x 24x 24x 135x 167x 30x 30x 167x 22x 22x 91x 91x 167x 2x 2x 2x 2x 2x  
/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
'use strict';
 
// MODULES //
 
var isNonNegativeIntegerArray = require( '@stdlib/assert/is-nonnegative-integer-array' ).primitives;
var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive;
var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
var getSubscripts = require( '@stdlib/ndarray/base/ind2sub' );
var format = require( '@stdlib/string/format' );
var defaults = require( './defaults.json' );
var validate = require( './validate.js' );
 
 
// MAIN //
 
/**
* Converts a linear index to an array of subscripts.
*
* ## Notes
*
* -   The function accepts the following "modes":
*
*     -   **throw**: throw an error when a linear index exceeds array dimensions.
*     -   **normalize**: normalize negative linear indices and throw an error when a linear index exceeds array dimensions.
*     -   **wrap**: wrap around a linear index exceeding array dimensions using modulo arithmetic.
*     -   **clamp**: set a linear index exceeding array dimensions to either `0` (minimum linear index) or the maximum linear index.
*
* @param {NonNegativeIntegerArray} shape - array shape
* @param {integer} idx - linear index
* @param {Options} [options] - function options
* @param {string} [options.mode="throw"] - specifies how to handle a linear index which exceeds array dimensions
* @param {string} [options.order="row-major"] - specifies whether an array is row-major (C-style) or column-major (Fortran-style)
* @throws {TypeError} shape argument must be an array-like object containing nonnegative integers
* @throws {TypeError} linear index argument must be integer valued
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @throws {RangeError} must provide a linear index which does not exceed array dimensions
* @returns {NonNegativeIntegerArray} subscripts
*
* @example
* var s = ind2sub( [ 3, 3, 3 ], 17 );
* // returns [ 1, 2, 2 ]
*/
function ind2sub( shape, idx, options ) {
	var opts;
	var err;
 
	opts = {};
	opts.mode = defaults.mode;
	opts.order = defaults.order;
	if ( arguments.length > 2 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	if ( !isNonNegativeIntegerArray( shape ) ) {
		throw new TypeError( format( 'invalid argument. Shape argument must be an array-like object containing nonnegative integers. Value: `%s`.', shape ) );
	}
	if ( !isInteger( idx ) ) {
		throw new TypeError( format( 'invalid argument. Linear index must be integer valued. Value: `%s`.', idx ) );
	}
	// Note: strides are positive, so offset is always zero
	return getSubscripts( shape, shape2strides( shape, opts.order ), 0, opts.order, idx, opts.mode ); // eslint-disable-line max-len
}
 
 
// EXPORTS //
 
module.exports = ind2sub;