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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 30x 30x 69x 99x 13x 13x 13x 12x 7x 7x 5x 5x 13x 99x 49x 49x 1x 1x 99x 13x 6x 6x 1x 1x 13x 7x 7x 10x 10x 7x 12x 12x 13x 4x 4x 8x 8x 8x 4x 4x 8x 4x 13x 56x 56x 99x 7x 7x 49x 49x 49x 99x 3x 3x 3x 46x 46x 99x 4x 4x 42x 42x 42x 99x 77x 3x 3x 77x 6x 6x 6x 77x 33x 99x 65x 65x 65x 65x 65x 65x 17x 17x 17x 65x 65x 18x 18x 18x 65x 33x 33x 33x 99x 1x 1x 1x 1x 1x | /**
* @license Apache-2.0
*
* Copyright (c) 2026 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 isArrayLikeObject = require( '@stdlib/assert/is-array-like-object' );
var isPlainObject = require( '@stdlib/assert/is-plain-object' );
var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' );
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
var isMultiSlice = require( '@stdlib/assert/is-multi-slice' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var MultiSlice = require( '@stdlib/slice/multi' );
var args2multislice = require( '@stdlib/slice/base/args2multislice' );
var normalizeMultiSlice = require( '@stdlib/slice/base/normalize-multi-slice' );
var getShape = require( '@stdlib/ndarray/shape' );
var emptyLike = require( '@stdlib/ndarray/empty-like' );
var sliceBase = require( '@stdlib/ndarray/base/slice' );
var assign = require( '@stdlib/ndarray/base/assign' );
var fillBase = require( '@stdlib/ndarray/base/fill' );
var format = require( '@stdlib/string/format' );
var slab = require( './slab.js' );
// MAIN //
/**
* Returns a new ndarray with a specified slice region filled with a provided value.
*
* @param {ndarray} x - input ndarray
* @param {*} value - fill value
* @param {...*} s - slice arguments
* @param {Options} [options] - options
* @param {boolean} [options.strict] - boolean indicating whether to enforce strict bounds checking
* @throws {TypeError} first argument must be an ndarray-like object
* @throws {TypeError} second argument cannot be safely cast to the input ndarray data type
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @throws {RangeError} number of slice dimensions must match the number of input array dimensions
* @throws {RangeError} slice arguments must have an absolute index increment equal to one
* @throws {Error} too many arguments
* @returns {ndarray} output ndarray
*
* @example
* var zeros = require( '@stdlib/ndarray/zeros' );
* var MultiSlice = require( '@stdlib/slice/multi' );
* var Slice = require( '@stdlib/slice/ctor' );
*
* var x = zeros( [ 3, 4 ], {
* 'dtype': 'float64'
* });
* // returns <ndarray>[ [ 0.0, 0.0, 0.0, 0.0 ], [ 0.0, 0.0, 0.0, 0.0 ], [ 0.0, 0.0, 0.0, 0.0 ] ]
*
* // Define an interior fill region:
* var s0 = new Slice( 1, 2 );
* var s1 = new Slice( 1, 3 );
* var s = new MultiSlice( s0, s1 );
*
* // Fill the region with a scalar value:
* var y = toFilledSlice( x, 9.0, s );
* // returns <ndarray>[ [ 0.0, 0.0, 0.0, 0.0 ], [ 0.0, 9.0, 9.0, 0.0 ], [ 0.0, 0.0, 0.0, 0.0 ] ]
*
* var bool = ( y === x );
* // returns false
*/
function toFilledSlice( x, value, s ) {
var options;
var slices;
var nargs;
var args;
var norm;
var opts;
var out;
var hi;
var lo;
var ms;
var sd;
var sh;
var S;
var d;
var i;
opts = {
'strict': true
};
nargs = arguments.length;
if ( !isndarrayLike( x ) ) {
throw new TypeError( format( 'invalid argument. First argument must be an ndarray. Value: `%s`.', x ) );
}
sh = getShape( x );
if ( isPlainObject( arguments[ nargs-1 ] ) ) {
nargs -= 1;
options = arguments[ nargs ];
if ( hasOwnProp( options, 'strict' ) ) {
if ( !isBoolean( options.strict ) ) {
throw new TypeError( format( 'invalid option. `%s` option must be a boolean. Option: `%s`.', 'strict', options.strict ) );
}
opts.strict = options.strict;
}
}
if ( isMultiSlice( s ) ) {
S = s;
if ( nargs > 3 ) {
throw new Error( 'invalid invocation. Too many arguments.' );
}
} else {
if ( isArrayLikeObject( s ) ) {
args = s;
if ( nargs > 3 ) {
throw new Error( 'invalid invocation. Too many arguments.' );
}
} else {
args = [];
for ( i = 2; i < nargs; i++ ) {
args.push( arguments[ i ] );
}
}
try {
S = args2multislice( args );
} catch ( err ) { // eslint-disable-line no-unused-vars
// Search for the first offending value...
for ( i = 0; i < args.length; i++ ) {
try {
new MultiSlice( args[ i ] ); // eslint-disable-line no-new
} catch ( err ) { // eslint-disable-line no-unused-vars
throw new TypeError( format( 'invalid argument. Slice arguments must be either a Slice, integer, null, or undefined. Value: `%s`.', String( args[ i ] ) ) );
}
}
}
}
// Validate that the number of slice dimensions matches the number of input array dimensions:
if ( S.ndims !== sh.length ) {
throw new RangeError( format( 'invalid argument. Number of slice dimensions does not match the number of array dimensions. Array shape: (%s). Slice dimensions: %u.', sh.join( ',' ), S.ndims ) );
}
out = emptyLike( x );
// If a zero-dimensional input array, the slab loop is a no-op, and we only need to fill the zero-dimensional view of `out`:
if ( sh.length === 0 ) {
fillBase( sliceBase( out, S, opts.strict, true ), value );
return out;
}
// Resolve normalized slices in order to carve out complement slabs:
norm = normalizeMultiSlice( S, sh, opts.strict );
if ( norm.code ) {
throw new RangeError( format( 'invalid argument. Slice exceeds array bounds. Array shape: (%s).', sh.join( ',' ) ) );
}
slices = norm.data;
// Reject slices having a non-unit absolute index increment:
for ( i = 0; i < slices.length; i++ ) {
if ( slices[ i ].step !== 1 ) {
throw new RangeError( format( 'invalid argument. Slice arguments must have an absolute index increment equal to one. Value: `%d`.', slices[ i ].step ) );
}
if ( slices[ i ].start === slices[ i ].stop ) {
assign( [ x, out ] );
return out;
}
}
// Carve `2N` complement slabs by, for each dimension, copying the cells which fall before and after the fill region along that dimension:
for ( d = 0; d < sh.length; d++ ) {
sd = slices[ d ];
lo = sd.start;
hi = sd.stop;
// "Before" slab on dimension `d`:
if ( lo > 0 ) {
ms = slab( sh, slices, d, 0, lo );
assign( [ sliceBase( x, ms, false, false ), sliceBase( out, ms, false, true ) ] ); // eslint-disable-line max-len
}
// "After" slab on dimension `d`:
if ( hi < sh[ d ] ) {
ms = slab( sh, slices, d, hi, sh[ d ] );
assign( [ sliceBase( x, ms, false, false ), sliceBase( out, ms, false, true ) ] ); // eslint-disable-line max-len
}
}
// Fill the region itself with the provided value:
fillBase( sliceBase( out, S, opts.strict, true ), value );
return out;
}
// EXPORTS //
module.exports = toFilledSlice;
|