Skip to content

feat: add boolean dtype support to array/base/mskfilter #2450

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 4 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
53 changes: 52 additions & 1 deletion lib/node_modules/@stdlib/array/base/mskfilter/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' );


// FUNCTIONS //
Expand Down Expand Up @@ -163,6 +165,48 @@ function complex( x, mask, out, stride, offset ) {
return out;
}

/**
* Applies a mask to a boolean array and assigns unmasked values to elements in a boolean output array.
*
* @private
* @param {Collection} x - boolean input array view
* @param {Object} mask - mask array object
* @param {Collection} out - boolean 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 mask = [ 0, 1, 0, 1 ];
*
* var out = new Uint8Array( 4 );
*
* var arr = boolean( x, arraylike2object( mask ), out, 1, 0 );
* // returns <Uint8Array>[ 0, 1, 0, 0 ]
*/
function boolean( x, mask, out, stride, offset ) {
var mdata;
var mget;
var io;
var i;

mdata = mask.data;
mget = mask.accessors[ 0 ];

io = offset;
for ( i = 0; i < mdata.length; i++ ) {
if ( mget( mdata, i ) ) {
out[ io ] = x[ i ];
io += stride;
}
}
return out;
}


// MAIN //

Expand Down Expand Up @@ -200,14 +244,21 @@ function assign( x, mask, out, stride, offset ) {
mo.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 ), mo, reinterpret( out, 0 ), stride, offset ); // eslint-disable-line max-len
return out;
}
if (
isBooleanDataType( xo.dtype ) &&
isBooleanDataType( oo.dtype )
) {
boolean( reinterpretBoolean( x, 0 ), mo, reinterpretBoolean( out, 0 ), stride, offset ); // eslint-disable-line max-len
return out;
}
accessors( xo, mo, oo, stride, offset );
return out;
}
Expand Down
60 changes: 60 additions & 0 deletions lib/node_modules/@stdlib/array/base/mskfilter/test/test.assign.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

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 Int32Array = require( '@stdlib/array/int32' );
var isSameComplex64Array = require( '@stdlib/assert/is-same-complex64array' );
var isSameBooleanArray = require( '@stdlib/assert/is-same-booleanarray' );
var zeros = require( '@stdlib/array/zeros' );
var mskfilter = require( './../lib/assign.js' );

Expand Down Expand Up @@ -193,6 +195,58 @@ tape( 'the function filters array elements (complex typed array)', function test
t.end();
});

tape( 'the function filters array elements (boolean array)', function test( t ) {
var expected;
var actual;
var mask;
var out;
var x;

x = new BooleanArray( [ true, false, false, true ] );

mask = [ 0, 1, 0, 1 ];
out = new BooleanArray( 2 );
actual = mskfilter( x, mask, out, 1, 0 );
expected = new BooleanArray( [ false, true ] );

t.strictEqual( actual, out, 'returns expected value' );
t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' );

mask = [ 0, 0, 0, 0 ];
out = new BooleanArray( 0 );
actual = mskfilter( x, mask, out, 1, 0 );
expected = new BooleanArray( [] );

t.strictEqual( actual, out, 'returns expected value' );
t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' );

mask = [ 0, 0, 0, 1 ];
out = new BooleanArray( 1 );
actual = mskfilter( x, mask, out, 1, 0 );
expected = new BooleanArray( [ true ] );

t.strictEqual( actual, out, 'returns expected value' );
t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' );

mask = [ 1, 1, 1, 1 ];
out = new BooleanArray( 4 );
actual = mskfilter( x, mask, out, 1, 0 );
expected = new BooleanArray( [ true, false, false, true ] );

t.strictEqual( actual, out, 'returns expected value' );
t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' );

mask = [ 0, 1, 0, 1 ];
out = new BooleanArray( 4 );
actual = mskfilter( x, mask, out, -2, out.length-1 );
expected = new BooleanArray( [ false, true, false, false ] );

t.strictEqual( actual, out, 'returns expected value' );
t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' );

t.end();
});

tape( 'the function filters array elements (accessors)', function test( t ) {
var expected;
var actual;
Expand Down Expand Up @@ -285,5 +339,11 @@ tape( 'the function returns leaves an output array unchanged if provided a secon
actual = mskfilter( x, mask, out, 1, 0 );
t.strictEqual( isSameComplex64Array( 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 = mskfilter( x, mask, out, 1, 0 );
t.strictEqual( isSameBooleanArray( actual, expected ), true, 'returns expected value' );

t.end();
});
13 changes: 13 additions & 0 deletions lib/node_modules/@stdlib/array/base/mskfilter/test/test.main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

var tape = require( 'tape' );
var Complex64Array = require( '@stdlib/array/complex64' );
var BooleanArray = require( '@stdlib/array/bool' );
var isSameComplex64 = require( '@stdlib/assert/is-same-complex64' );
var isArray = require( '@stdlib/assert/is-array' );
var mskfilter = require( './../lib' );
Expand Down Expand Up @@ -91,6 +92,18 @@ tape( 'the function filters array elements (accessors)', function test( t ) {
for ( i = 0; i < expected.length; i++ ) {
t.strictEqual( isSameComplex64( actual[ i ], expected[ i ] ), true, 'returns expected value' );
}

x = new BooleanArray( [ true, false, false, true ] );
mask = [ 0, 1, 0, 1 ];
actual = mskfilter( x, mask );
expected = [ x.get( 1 ), x.get( 3 ) ];

t.strictEqual( isArray( actual ), true, 'returns expected value' );
t.notEqual( actual, x, 'returns different reference' );
for ( i = 0; i < expected.length; i++ ) {
t.strictEqual( actual[ i ], expected[ i ], 'returns expected value' );
}

t.end();
});

Expand Down
Loading