Skip to content

feat: add boolean dtype support to array/base/take #2453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion lib/node_modules/@stdlib/array/base/take/lib/assign.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;


Expand Down Expand Up @@ -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 <Uint8Array>[ 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;

// 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 //

Expand Down Expand Up @@ -229,14 +283,21 @@ 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 )
) {
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;
}
Expand Down
71 changes: 70 additions & 1 deletion lib/node_modules/@stdlib/array/base/take/test/test.assign.js
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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' );

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
});

Expand Down Expand Up @@ -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;
Expand Down
15 changes: 14 additions & 1 deletion lib/node_modules/@stdlib/array/base/take/test/test.main.js
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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' );
Expand Down Expand Up @@ -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();
});

Expand Down
Loading