From a9318d2b094e974d68404a67a542b7a236d07f8e Mon Sep 17 00:00:00 2001 From: Jaysukh-409 Date: Tue, 25 Jun 2024 16:03:15 +0530 Subject: [PATCH 1/3] feat: add boolean dtype support to array/base/take --- .../@stdlib/array/base/take/lib/assign.js | 61 ++++++++++++++++ .../array/base/take/test/test.assign.js | 71 ++++++++++++++++++- .../@stdlib/array/base/take/test/test.main.js | 15 +++- 3 files changed, 145 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/array/base/take/lib/assign.js b/lib/node_modules/@stdlib/array/base/take/lib/assign.js index 85f37e73d6ee..f98c17caa286 100644 --- a/lib/node_modules/@stdlib/array/base/take/lib/assign.js +++ b/lib/node_modules/@stdlib/array/base/take/lib/assign.js @@ -21,8 +21,10 @@ // MODULES // var isComplexDataType = require( '@stdlib/array/base/assert/is-complex-floating-point-data-type' ); +var isBooleanDataType = require( '@stdlib/array/base/assert/is-boolean-data-type' ); var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); var reinterpret = require( '@stdlib/strided/base/reinterpret-complex' ); +var reinterpretBoolean = require( '@stdlib/strided/base/reinterpret-boolean' ); var ind = require( '@stdlib/ndarray/base/ind' ).factory; @@ -191,6 +193,58 @@ function complex( x, indices, mode, out, stride, offset ) { return out; } +/** +* Takes elements from a boolean array and assigns the values to elements in a boolean output array. +* +* @private +* @param {Collection} x - boolean value input array view +* @param {Object} indices - index array object +* @param {string} mode - index mode +* @param {Collection} out - boolean value output array view +* @param {integer} stride - output array stride +* @param {NonNegativeInteger} offset - output array offset +* @returns {Collection} output array view +* +* @example +* var Uint8Array = require( '@stdlib/array/uint8' ); +* var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +* +* var x = new Uint8Array( [ 1, 0, 0, 1 ] ); +* var indices = [ 0, 0, 1, 1 ]; +* +* var out = new Uint8Array( 4 ); +* +* var arr = boolean( x, arraylike2object( indices ), 'throw', out, 1, 0 ); +* // returns [ 1, 1, 0, 0 ] +*/ +function boolean( x, indices, mode, out, stride, offset ) { + var getIndex; + var idata; + var iget; + var max; + var io; + var i; + var j; + + idata = indices.data; + iget = indices.accessors[ 0 ]; + + // Resolve a function for returning an index according to the specified index mode: + getIndex = ind( mode ); + + // Resolve the maximum index: + max = x.length - 1; // resolve the length of the original boolean array + + // Extract each desired element from the provided array... + io = offset; + for ( i = 0; i < idata.length; i++ ) { + j = getIndex( iget( idata, i ), max ); + out[ io ] = x[ j ]; + io += stride; + } + return out; +} + // MAIN // @@ -237,6 +291,13 @@ function assign( x, indices, mode, out, stride, offset ) { complex( reinterpret( x, 0 ), io, mode, reinterpret( out, 0 ), stride, offset ); // eslint-disable-line max-len return out; } + if ( + isBooleanDataType( xo.dtype ) && + isBooleanDataType( oo.dtype ) + ) { + boolean( reinterpretBoolean( x, 0 ), io, mode, reinterpretBoolean( out, 0 ), stride, offset ); // eslint-disable-line max-len + return out; + } accessors( xo, io, mode, oo, stride, offset ); return out; } diff --git a/lib/node_modules/@stdlib/array/base/take/test/test.assign.js b/lib/node_modules/@stdlib/array/base/take/test/test.assign.js index a394c9a724e2..1fad572c9b60 100644 --- a/lib/node_modules/@stdlib/array/base/take/test/test.assign.js +++ b/lib/node_modules/@stdlib/array/base/take/test/test.assign.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2022 The Stdlib Authors. +* Copyright (c) 2024 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. @@ -23,10 +23,12 @@ var tape = require( 'tape' ); var Complex128Array = require( '@stdlib/array/complex128' ); var Complex64Array = require( '@stdlib/array/complex64' ); +var BooleanArray = require( '@stdlib/array/bool' ); var Float64Array = require( '@stdlib/array/float64' ); var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var isSameComplex128Array = require( '@stdlib/assert/is-same-complex128array' ); var isSameComplex64Array = require( '@stdlib/assert/is-same-complex64array' ); +var isSameBooleanArray = require( '@stdlib/assert/is-same-booleanarray' ); var zeros = require( '@stdlib/array/zeros' ); var take = require( './../lib/assign.js' ); @@ -173,6 +175,50 @@ tape( 'the function takes elements from an array (complex typed array)', functio t.end(); }); +tape( 'the function takes elements from an array (boolean array)', function test( t ) { + var expected; + var indices; + var actual; + var out; + var x; + + x = new BooleanArray( [ true, false, false, true ] ); + + indices = [ 1, 3 ]; + out = new BooleanArray( indices.length ); + actual = take( x, indices, 'throw', out, 1, 0 ); + expected = new BooleanArray( [ false, true ] ); + + t.strictEqual( actual, out, 'returns expected value' ); + t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' ); + + indices = [ 1, 1, 3, 3 ]; + out = new BooleanArray( indices.length*2 ); + actual = take( x, indices, 'throw', out, 2, 0 ); + expected = new BooleanArray( [ false, false, false, false, true, false, true, false ] ); // eslint-disable-line max-len + + t.strictEqual( actual, out, 'returns expected value' ); + t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' ); + + indices = [ 3, 2, 1, 0 ]; + out = new BooleanArray( indices.length ); + actual = take( x, indices, 'throw', out, -1, out.length-1 ); + expected = new BooleanArray( [ true, false, false, true ] ); + + t.strictEqual( actual, out, 'returns expected value' ); + t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' ); + + indices = [ 1, 1, 1, 1 ]; + out = new BooleanArray( indices.length+1 ); + actual = take( x, indices, 'throw', out, 1, 1 ); + expected = new BooleanArray( [ false, false, false, false, false ] ); + + t.strictEqual( actual, out, 'returns expected value' ); + t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' ); + + t.end(); +}); + tape( 'the function takes elements from an array (accessors)', function test( t ) { var expected; var indices; @@ -254,6 +300,12 @@ tape( 'the function returns leaves an output array unchanged if provided a secon actual = take( x, [], 'throw', out, 1, 0 ); t.strictEqual( isSameComplex128Array( actual, expected ), true, 'returns expected value' ); + x = new BooleanArray( [ true, false, false, true ] ); + out = new BooleanArray( [ false, false, false, false ] ); + expected = new BooleanArray( [ false, false, false, false ] ); + actual = take( x, [], 'throw', out, 1, 0 ); + t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' ); + t.end(); }); @@ -325,6 +377,23 @@ tape( 'when the "mode" is "throw", the function throws an error if provided an o } }); +tape( 'when the "mode" is "throw", the function throws an error if provided an out-of-bounds index (boolean)', function test( t ) { + var indices; + var out; + var x; + + x = new BooleanArray( [ true, false ] ); + indices = [ 4, 5, 1, 2 ]; + out = new BooleanArray( x.length ); + + t.throws( badValue, RangeError, 'throws an error' ); + t.end(); + + function badValue() { + take( x, indices, 'throw', out, 1, 0 ); + } +}); + tape( 'when the "mode" is "normalize", the function normalizes negative indices (generic)', function test( t ) { var expected; var indices; diff --git a/lib/node_modules/@stdlib/array/base/take/test/test.main.js b/lib/node_modules/@stdlib/array/base/take/test/test.main.js index 16a8a1079625..5c67170d6e8d 100644 --- a/lib/node_modules/@stdlib/array/base/take/test/test.main.js +++ b/lib/node_modules/@stdlib/array/base/take/test/test.main.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2022 The Stdlib Authors. +* Copyright (c) 2024 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. @@ -22,6 +22,7 @@ var tape = require( 'tape' ); var Complex64Array = require( '@stdlib/array/complex64' ); +var BooleanArray = require( '@stdlib/array/bool' ); var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var realf = require( '@stdlib/complex/realf' ); var imagf = require( '@stdlib/complex/imagf' ); @@ -88,6 +89,18 @@ tape( 'the function takes elements from an array (accessors)', function test( t t.strictEqual( realf( v ), realf( expected ), 'returns expected value' ); t.strictEqual( imagf( v ), imagf( expected ), 'returns expected value' ); } + + x = new BooleanArray( [ true, false, false, true ] ); + indices = toAccessorArray( [ 1, 1, 3, 3 ] ); + actual = take( x, indices, 'throw' ); + + t.notEqual( actual, x, 'returns different reference' ); + for ( i = 0; i < indices.length; i++ ) { + v = actual[ i ]; + expected = x.get( indices.get( i ) ); + t.strictEqual( v, expected, 'returns expected value' ); + } + t.end(); }); From 2d881ebf7a6415026efbd948d57c1d4102c26ad3 Mon Sep 17 00:00:00 2001 From: Athan Date: Tue, 25 Jun 2024 12:41:26 -0700 Subject: [PATCH 2/3] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/array/base/take/lib/assign.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/array/base/take/lib/assign.js b/lib/node_modules/@stdlib/array/base/take/lib/assign.js index f98c17caa286..8d52c764dc0b 100644 --- a/lib/node_modules/@stdlib/array/base/take/lib/assign.js +++ b/lib/node_modules/@stdlib/array/base/take/lib/assign.js @@ -233,7 +233,7 @@ function boolean( x, indices, mode, out, stride, offset ) { getIndex = ind( mode ); // Resolve the maximum index: - max = x.length - 1; // resolve the length of the original boolean array + max = x.length - 1; // Extract each desired element from the provided array... io = offset; From 000186c11a09d35c1ede5c9931f5f961dac39106 Mon Sep 17 00:00:00 2001 From: Athan Date: Tue, 25 Jun 2024 12:45:34 -0700 Subject: [PATCH 3/3] docs: update comment Signed-off-by: Athan --- lib/node_modules/@stdlib/array/base/take/lib/assign.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/array/base/take/lib/assign.js b/lib/node_modules/@stdlib/array/base/take/lib/assign.js index 8d52c764dc0b..091a54e1979d 100644 --- a/lib/node_modules/@stdlib/array/base/take/lib/assign.js +++ b/lib/node_modules/@stdlib/array/base/take/lib/assign.js @@ -283,7 +283,7 @@ function assign( x, indices, mode, out, stride, offset ) { io.accessorProtocol || oo.accessorProtocol ) { - // Note: we only explicitly support complex-to-complex, as this function should not be concerned with casting rules, etc. That is left to userland... + // Note: we only explicitly support a limited set of dtype-to-dtype pairs, as this function should not be concerned with casting rules, etc. That is left to userland... if ( isComplexDataType( xo.dtype ) && isComplexDataType( oo.dtype )