From 3e4d535060d76bb3677445b849d5733e8d95acd5 Mon Sep 17 00:00:00 2001 From: stdlib-bot Date: Thu, 20 Jun 2024 08:31:07 +0000 Subject: [PATCH] Auto-generated commit --- CHANGELOG.md | 89 ++ base/lib/index.js | 9 + base/mskput/README.md | 16 +- base/mskput/benchmark/benchmark.js | 4 +- base/mskput/benchmark/benchmark.length.js | 2 +- base/mskput/docs/repl.txt | 31 +- base/mskput/docs/types/index.d.ts | 42 +- base/mskput/docs/types/test.ts | 50 +- base/mskput/examples/index.js | 2 +- base/mskput/lib/index.js | 2 +- base/mskput/lib/main.js | 30 +- base/mskput/test/test.js | 98 +- base/place/README.md | 150 ++ base/place/benchmark/benchmark.js | 79 ++ base/place/benchmark/benchmark.length.js | 113 ++ base/place/docs/repl.txt | 63 + base/place/docs/types/index.d.ts | 227 +++ base/place/docs/types/test.ts | 92 ++ base/place/examples/index.js | 42 + base/place/lib/index.js | 48 + base/place/lib/main.js | 309 +++++ base/place/package.json | 65 + base/place/test/test.js | 436 ++++++ to-fancy/lib/set_elements.js | 31 +- to-fancy/lib/set_slice.js | 2 +- to-fancy/test/test.set.boolean_array.js | 1518 +++++++++++++++++++++ to-fancy/test/test.set.integer_array.js | 96 +- to-fancy/test/test.set.mask_array.js | 1518 +++++++++++++++++++++ 28 files changed, 5011 insertions(+), 153 deletions(-) create mode 100644 base/place/README.md create mode 100644 base/place/benchmark/benchmark.js create mode 100644 base/place/benchmark/benchmark.length.js create mode 100644 base/place/docs/repl.txt create mode 100644 base/place/docs/types/index.d.ts create mode 100644 base/place/docs/types/test.ts create mode 100644 base/place/examples/index.js create mode 100644 base/place/lib/index.js create mode 100644 base/place/lib/main.js create mode 100644 base/place/package.json create mode 100644 base/place/test/test.js create mode 100644 to-fancy/test/test.set.boolean_array.js create mode 100644 to-fancy/test/test.set.mask_array.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 02e78212..55e916b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ ##### Features +- [`fd71d8a`](https://github.com/stdlib-js/stdlib/commit/fd71d8a39d9dc53b0d941945d26178e2e079edbc) - add `place` to namespace - [`20cd086`](https://github.com/stdlib-js/stdlib/commit/20cd0868236daf523fcd659d027e2277f7e1cb56) - add `mskput` to namespace - [`2827035`](https://github.com/stdlib-js/stdlib/commit/2827035933c44ebb301a44200ff9cd5ad73e9ef0) - add `where` to namespace - [`d626ffa`](https://github.com/stdlib-js/stdlib/commit/d626ffac9f0504be236c94afd4b920032272c8bf) - update namespace TypeScript declarations [(#2394)](https://github.com/stdlib-js/stdlib/pull/2394) @@ -932,6 +933,7 @@ This release closes the following issue: ##### Features +- [`7c3729c`](https://github.com/stdlib-js/stdlib/commit/7c3729c19fdda77bfb15009ab4e52a4dfb59f73d) - add support for additional modes - [`dc29f10`](https://github.com/stdlib-js/stdlib/commit/dc29f108e512a5ad2be34a7c3f539457648c1ee2) - add \"broadcasting\" mode to require broadcast compatibility - [`e9bf843`](https://github.com/stdlib-js/stdlib/commit/e9bf843b45b204ca61eca213575aa4933026b09b) - add `array/base/mskput` @@ -939,6 +941,29 @@ This release closes the following issue: +
+ +##### Bug Fixes + +- [`2769ce9`](https://github.com/stdlib-js/stdlib/commit/2769ce9e876c2a6de5735ffdbc4c79b3d26347b6) - require broadcast compatibility + +
+ + + +
+ +##### BREAKING CHANGES + +- [`7c3729c`](https://github.com/stdlib-js/stdlib/commit/7c3729c19fdda77bfb15009ab4e52a4dfb59f73d): add support for additional modes +- [`7c3729c`](https://github.com/stdlib-js/stdlib/commit/7c3729c19fdda77bfb15009ab4e52a4dfb59f73d): rename 'throw' mode to 'strict' + + - To migrate, users should simply update 'throw' to 'strict'. + +
+ + + @@ -989,6 +1014,52 @@ This release closes the following issue: +
+ +#### [@stdlib/array/base/place](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/place) + +
+ +
+ +##### Features + +- [`fdb5d94`](https://github.com/stdlib-js/stdlib/commit/fdb5d94eee5fc019bc358d799025cb2b5966d820) - add support for additional modes +- [`e8a8a6e`](https://github.com/stdlib-js/stdlib/commit/e8a8a6e61d01e96272408449f48f411c691f3aa0) - add `array/base/place` + +
+ + + +
+ +##### Bug Fixes + +- [`d903fc9`](https://github.com/stdlib-js/stdlib/commit/d903fc907ddaacc144a97edaaed0f05abadc470c) - require broadcast compatibility + +
+ + + +
+ +##### BREAKING CHANGES + +- [`fdb5d94`](https://github.com/stdlib-js/stdlib/commit/fdb5d94eee5fc019bc358d799025cb2b5966d820): add support for additional modes +- [`fdb5d94`](https://github.com/stdlib-js/stdlib/commit/fdb5d94eee5fc019bc358d799025cb2b5966d820): rename 'throw' mode to 'strict' + + - To migrate, users should simply replace 'throw' with 'strict'. + +
+ + + +
+ +
+ + +
#### [@stdlib/array/base/put](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/put) @@ -1974,6 +2045,16 @@ This release closes the following issue: ### BREAKING CHANGES +- [`fdb5d94`](https://github.com/stdlib-js/stdlib/commit/fdb5d94eee5fc019bc358d799025cb2b5966d820): add support for additional modes +- [`fdb5d94`](https://github.com/stdlib-js/stdlib/commit/fdb5d94eee5fc019bc358d799025cb2b5966d820): rename 'throw' mode to 'strict' + + - To migrate, users should simply replace 'throw' with 'strict'. + +- [`7c3729c`](https://github.com/stdlib-js/stdlib/commit/7c3729c19fdda77bfb15009ab4e52a4dfb59f73d): add support for additional modes +- [`7c3729c`](https://github.com/stdlib-js/stdlib/commit/7c3729c19fdda77bfb15009ab4e52a4dfb59f73d): rename 'throw' mode to 'strict' + + - To migrate, users should simply update 'throw' to 'strict'. + - [`0adcae5`](https://github.com/stdlib-js/stdlib/commit/0adcae51386086e2ef5fb5d78402389cff776deb): update namespace TypeScript declarations - [`0adcae5`](https://github.com/stdlib-js/stdlib/commit/0adcae51386086e2ef5fb5d78402389cff776deb): rename exported aliases @@ -2033,6 +2114,14 @@ A total of 13 people contributed to this release. Thank you to the following con
+- [`e57ccb2`](https://github.com/stdlib-js/stdlib/commit/e57ccb234687de4087aa12348d266ea448f3f241) - **refactor:** update boolean array indexing implementation and add tests _(by Athan Reines)_ +- [`d903fc9`](https://github.com/stdlib-js/stdlib/commit/d903fc907ddaacc144a97edaaed0f05abadc470c) - **fix:** require broadcast compatibility _(by Athan Reines)_ +- [`2769ce9`](https://github.com/stdlib-js/stdlib/commit/2769ce9e876c2a6de5735ffdbc4c79b3d26347b6) - **fix:** require broadcast compatibility _(by Athan Reines)_ +- [`fdb5d94`](https://github.com/stdlib-js/stdlib/commit/fdb5d94eee5fc019bc358d799025cb2b5966d820) - **feat:** add support for additional modes _(by Athan Reines)_ +- [`96f430f`](https://github.com/stdlib-js/stdlib/commit/96f430f4a1c3e3ded241118139d5359404963a99) - **test:** fix description and docs _(by Athan Reines)_ +- [`7c3729c`](https://github.com/stdlib-js/stdlib/commit/7c3729c19fdda77bfb15009ab4e52a4dfb59f73d) - **feat:** add support for additional modes _(by Athan Reines)_ +- [`fd71d8a`](https://github.com/stdlib-js/stdlib/commit/fd71d8a39d9dc53b0d941945d26178e2e079edbc) - **feat:** add `place` to namespace _(by Athan Reines)_ +- [`e8a8a6e`](https://github.com/stdlib-js/stdlib/commit/e8a8a6e61d01e96272408449f48f411c691f3aa0) - **feat:** add `array/base/place` _(by Athan Reines)_ - [`566c39c`](https://github.com/stdlib-js/stdlib/commit/566c39c0a5d5b19360ae92db2b1f50d6e9bef067) - **test:** fix description _(by Athan Reines)_ - [`dc29f10`](https://github.com/stdlib-js/stdlib/commit/dc29f108e512a5ad2be34a7c3f539457648c1ee2) - **feat:** add \"broadcasting\" mode to require broadcast compatibility _(by Athan Reines)_ - [`20cd086`](https://github.com/stdlib-js/stdlib/commit/20cd0868236daf523fcd659d027e2277f7e1cb56) - **feat:** add `mskput` to namespace _(by Athan Reines)_ diff --git a/base/lib/index.js b/base/lib/index.js index 4d11d287..685a577b 100644 --- a/base/lib/index.js +++ b/base/lib/index.js @@ -1170,6 +1170,15 @@ setReadOnly( ns, 'ones5d', require( './../../base/ones5d' ) ); */ setReadOnly( ns, 'onesnd', require( './../../base/onesnd' ) ); +/** +* @name place +* @memberof ns +* @readonly +* @type {Function} +* @see {@link module:@stdlib/array/base/place} +*/ +setReadOnly( ns, 'place', require( './../../base/place' ) ); + /** * @name put * @memberof ns diff --git a/base/mskput/README.md b/base/mskput/README.md index f8655d54..c291825e 100644 --- a/base/mskput/README.md +++ b/base/mskput/README.md @@ -37,7 +37,7 @@ Replaces elements of an array with provided values according to a provided mask ```javascript var x = [ 1, 2, 3, 4 ]; -var out = mskput( x, [ 1, 0, 1, 0 ], [ 20, 40 ], 'throw' ); +var out = mskput( x, [ 1, 0, 1, 0 ], [ 20, 40 ], 'strict' ); // returns [ 1, 20, 3, 40 ] var bool = ( out === x ); @@ -49,27 +49,29 @@ The function supports the following parameters: - **x**: input array. - **mask**: mask array. - **values**: values to set. -- **mode**: string specifying whether to raise an exception when the number of `values` is less than the number of falsy `mask` values. +- **mode**: string specifying behavior when the number of `values` does not equal the number of falsy `mask` values. The function supports the following modes: -- `'throw'`: specifies that the function must raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +- `'strict'`: specifies that the function must raise an exception when the number of `values` does not **exactly** equal the number of falsy `mask` values. +- `'non_strict'`: specifies that the function must raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +- `'strict_broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the number of `values` does not **exactly** equal the number of falsy `mask` values. - `'broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. - `'repeat'`: specifies that the function must reuse provided `values` when replacing elements in `x` in order to satisfy the `mask` array. -When `mode` is equal to `'broadcast`', the function supports broadcasting a `values` array containing a single element against the number of falsy values in the `mask` array. +In broadcasting modes, the function supports broadcasting a `values` array containing a single element against the number of falsy values in the `mask` array. ```javascript var x = [ 1, 2, 3, 4 ]; -var out = mskput( x, [ 1, 0, 1, 0 ], [ 20 ], 'broadcast' ); +var out = mskput( x, [ 1, 0, 1, 0 ], [ 20 ], 'strict_broadcast' ); // returns [ 1, 20, 3, 20 ] var bool = ( out === x ); // returns true ``` -When `mode` is equal to `repeat`, the function supports recycling elements in a `values` array to satisfy the number of falsy values in the `mask` array. +In repeat mode, the function supports recycling elements in a `values` array to satisfy the number of falsy values in the `mask` array. ```javascript var x = [ 1, 2, 3, 4 ]; @@ -123,7 +125,7 @@ var values = filledBy( N, discreteUniform.factory( 1000, 2000 ) ); console.log( values ); // Update a random sample of elements in `x`: -var out = mskput( x, mask, values, 'throw' ); +var out = mskput( x, mask, values, 'non_strict' ); console.log( out ); ``` diff --git a/base/mskput/benchmark/benchmark.js b/base/mskput/benchmark/benchmark.js index efa9eeab..d2b28115 100644 --- a/base/mskput/benchmark/benchmark.js +++ b/base/mskput/benchmark/benchmark.js @@ -41,7 +41,7 @@ bench( pkg+'::no_broadcasting:len=100', function benchmark( b ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - v = mskput( x, mask, x, 'throw' ); + v = mskput( x, mask, x, 'strict' ); if ( typeof v !== 'object' ) { b.fail( 'should return an array' ); } @@ -65,7 +65,7 @@ bench( pkg+'::broadcasting:len=100', function benchmark( b ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - v = mskput( x, mask, [ i ], 'broadcast' ); + v = mskput( x, mask, [ i ], 'strict_broadcast' ); if ( typeof v !== 'object' ) { b.fail( 'should return an array' ); } diff --git a/base/mskput/benchmark/benchmark.length.js b/base/mskput/benchmark/benchmark.length.js index e9260933..065ba5db 100644 --- a/base/mskput/benchmark/benchmark.length.js +++ b/base/mskput/benchmark/benchmark.length.js @@ -71,7 +71,7 @@ function createBenchmark( len ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - v = mskput( x, mask, values[ i%values.length ], 'throw' ); + v = mskput( x, mask, values[ i%values.length ], 'strict' ); if ( typeof v !== 'object' ) { b.fail( 'should return an array' ); } diff --git a/base/mskput/docs/repl.txt b/base/mskput/docs/repl.txt index 049bec77..4f542322 100644 --- a/base/mskput/docs/repl.txt +++ b/base/mskput/docs/repl.txt @@ -3,12 +3,12 @@ Replaces elements of an array with provided values according to a provided mask array. - When the `mode` is `'broadcast'`, the function supports broadcasting a - `values` array containing a single element against the number of falsy - values in the `mask` array. + In broadcasting modes, the function supports broadcasting a values array + containing a single element against the number of falsy values in the mask + array. - When the `mode` is `'repeat'`, the function supports recycling elements in a - `values` array to satisfy the number of falsy values in the `mask` array. + In repeat mode, the function supports recycling elements in a values array + to satisfy the number of falsy values in the mask array. The function mutates the input array. @@ -26,12 +26,19 @@ Values to set. mode: string - String specifying behavior when the number of values to set is less than - the number of falsy mask values. The function supports the following - modes: - - - 'throw': specifies that the function must raise an exception when the - function is provided insufficient values to satisfy the mask array. + String specifying behavior when the number of values to set does not + equal the number of falsy mask values. The function supports the + following modes: + + - 'strict': specifies that the function must raise an exception when the + number of values does not *exactly* equal the number of falsy mask + values. + - 'non_strict': specifies that the function must raise an exception when + the function is provided insufficient values to satisfy the mask array. + - 'strict_broadcast': specifies that the function must broadcast a + single-element values array and otherwise raise an exception when the + number of values does not **exactly** equal the number of falsy mask + values. - 'broadcast': specifies that the function must broadcast a single- element values array and otherwise raise an exception when the function is provided insufficient values to satisfy the mask array. @@ -46,7 +53,7 @@ Examples -------- > var x = [ 1, 2, 3, 4 ]; - > var out = {{alias}}( x, [ 1, 0, 1, 0 ], [ 20, 40 ], 'throw' ) + > var out = {{alias}}( x, [ 1, 0, 1, 0 ], [ 20, 40 ], 'strict' ) [ 1, 20, 3, 40 ] > var bool = ( out === x ) true diff --git a/base/mskput/docs/types/index.d.ts b/base/mskput/docs/types/index.d.ts index 30298cd6..6b717d6c 100644 --- a/base/mskput/docs/types/index.d.ts +++ b/base/mskput/docs/types/index.d.ts @@ -34,17 +34,19 @@ type MaskArray = Collection | AccessorArrayLike; type ValuesArray = Collection | AccessorArrayLike; /** -* Mode specifying behavior when the number of values to set is less than the number of falsy values in the mask array. +* Mode specifying behavior when the number of values to set does not equal the number of falsy values in the mask array. * * ## Notes * * - The function supports the following modes: * -* - `'throw'`: specifies that the function must raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. -* - `'broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. -* - `'repeat'`: specifies that the function must reuse provided `values` when replacing elements in `x` in order to satisfy the `mask` array. +* - `'strict'`: specifies that the function must raise an exception when the number of `values` does not **exactly** equal the number of falsy `mask` values. +* - `'non_strict'`: specifies that the function must raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +* - `'strict_broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the number of `values` does not **exactly** equal the number of falsy `mask` values. +* - `'broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +* - `'repeat'`: specifies that the function must reuse provided `values` when replacing elements in `x` in order to satisfy the `mask` array. */ -type Mode = 'throw' | 'broadcast' | 'repeat'; +type Mode = 'strict' | 'non_strict' | 'strict_broadcast' | 'broadcast' | 'repeat'; /** * Replaces elements of an array with provided values according to a provided mask array. @@ -52,7 +54,7 @@ type Mode = 'throw' | 'broadcast' | 'repeat'; * @param x - input array * @param mask - mask array * @param values - values to set -* @param mode - string specifying behavior when the number of values is less than the number of falsy values in the mask array +* @param mode - string specifying behavior when the number of values does not equal the number of falsy values in the mask array * @returns input array * * @example @@ -63,7 +65,7 @@ type Mode = 'throw' | 'broadcast' | 'repeat'; * var mask = [ 1, 0, 0, 1 ]; * var values = [ 20, 30 ]; * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * // returns [ 1, 20, 30, 4 ] * * var bool = ( out === x ); @@ -74,7 +76,7 @@ type Mode = 'throw' | 'broadcast' | 'repeat'; * * var x = new Int32Array( [ 1, 2, 3, 4 ] ); * -* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'broadcast' ); +* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'strict_broadcast' ); * // returns [ 1, 30, 30, 4 ] * * var bool = ( out === x ); @@ -88,7 +90,7 @@ declare function mskput( * @param x - input array * @param mask - mask array * @param values - values to set -* @param mode - string specifying behavior when the number of values is less than the number of falsy values in the mask array +* @param mode - string specifying behavior when the number of values does not equal the number of falsy values in the mask array * @returns input array * * @example @@ -99,7 +101,7 @@ declare function mskput( * var mask = [ 1, 0, 0, 1 ]; * var values = new Complex128Array( [ 20.0, 30.0, 40, 5.0 ] ); * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * // returns * * var bool = ( out === x ); @@ -113,7 +115,7 @@ declare function mskput( * var mask = [ 1, 0, 0, 1 ]; * var values = new Complex128Array( [ 20.0, 30.0 ] ); * -* var out = mskput( x, mask, values, 'broadcast' ); +* var out = mskput( x, mask, values, 'strict_broadcast' ); * // returns * * var bool = ( out === x ); @@ -127,7 +129,7 @@ declare function mskput( x: T, mask: MaskArray, val * @param x - input array * @param mask - mask array * @param values - values to set -* @param mode - string specifying behavior when the number of values is less than the number of falsy values in the mask array +* @param mode - string specifying behavior when the number of values does not equal the number of falsy values in the mask array * @returns input array * * @example @@ -136,7 +138,7 @@ declare function mskput( x: T, mask: MaskArray, val * var mask = [ 1, 0, 0, 1 ]; * var values = [ 20, 30 ]; * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * // returns [ 1, 20, 30, 4 ] * * var bool = ( out === x ); @@ -145,7 +147,7 @@ declare function mskput( x: T, mask: MaskArray, val * @example * var x = [ 1, 2, 3, 4 ]; * -* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'broadcast' ); +* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'strict_broadcast' ); * // returns [ 1, 30, 30, 4 ] * * var bool = ( out === x ); @@ -159,7 +161,7 @@ declare function mskput( x: Array, mask: MaskArray, * @param x - input array * @param mask - mask array * @param values - values to set -* @param mode - string specifying behavior when the number of values is less than the number of falsy values in the mask array +* @param mode - string specifying behavior when the number of values does not equal the number of falsy values in the mask array * @returns input array * * @example @@ -170,7 +172,7 @@ declare function mskput( x: Array, mask: MaskArray, * var mask = [ 1, 0, 0, 1 ]; * var values = [ 20, 30 ]; * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * * var bool = ( out === x ); * // returns true @@ -180,7 +182,7 @@ declare function mskput( x: Array, mask: MaskArray, * * var x = toAccessorArray( [ 1, 2, 3, 4 ] ); * -* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'broadcast' ); +* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'strict_broadcast' ); * * var bool = ( out === x ); * // returns true @@ -193,7 +195,7 @@ declare function mskput( x: AccessorArrayLike, mask * @param x - input array * @param mask - mask array * @param values - values to set -* @param mode - string specifying behavior when the number of values is less than the number of falsy values in the mask array +* @param mode - string specifying behavior when the number of values does not equal the number of falsy values in the mask array * @returns input array * * @example @@ -202,7 +204,7 @@ declare function mskput( x: AccessorArrayLike, mask * var mask = [ 1, 0, 0, 1 ]; * var values = [ 20, 30 ]; * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * // returns [ 1, 20, 30, 4 ] * * var bool = ( out === x ); @@ -211,7 +213,7 @@ declare function mskput( x: AccessorArrayLike, mask * @example * var x = [ 1, 2, 3, 4 ]; * -* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'throw' ); +* var out = mskput( x, [ 1, 0, 0, 1 ], [ 30 ], 'strict_broadcast' ); * // returns [ 1, 30, 30, 4 ] * * var bool = ( out === x ); diff --git a/base/mskput/docs/types/test.ts b/base/mskput/docs/types/test.ts index 11fda5eb..a67d5600 100644 --- a/base/mskput/docs/types/test.ts +++ b/base/mskput/docs/types/test.ts @@ -27,44 +27,46 @@ import mskput = require( './index' ); // The function returns an array... { - mskput( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectType number[] + mskput( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectType number[] + mskput( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'non_strict' ); // $ExpectType number[] + mskput( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict_broadcast' ); // $ExpectType number[] mskput( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'broadcast' ); // $ExpectType number[] mskput( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'repeat' ); // $ExpectType number[] - mskput( new Int32Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectType Int32Array - mskput( new Complex128Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ new Complex128( 20, 30 ), [ 40, 50 ] ], 'throw' ); // $ExpectType Complex128Array - mskput( new Complex64Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ new Complex128( 20, 30 ), [ 40, 50 ] ], 'throw' ); // $ExpectType Complex64Array - mskput( new AccessorArray( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], new AccessorArray( [ 20, 30 ] ), 'throw' ); // $ExpectType AccessorArrayLike + mskput( new Int32Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectType Int32Array + mskput( new Complex128Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ new Complex128( 20, 30 ), [ 40, 50 ] ], 'strict' ); // $ExpectType Complex128Array + mskput( new Complex64Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ new Complex128( 20, 30 ), [ 40, 50 ] ], 'strict' ); // $ExpectType Complex64Array + mskput( new AccessorArray( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], new AccessorArray( [ 20, 30 ] ), 'strict' ); // $ExpectType AccessorArrayLike } // The compiler throws an error if the function is provided a first argument which is not an array-like object... { - mskput( 1, [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectError - mskput( true, [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectError - mskput( false, [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectError - mskput( null, [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectError - mskput( void 0, [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectError - mskput( {}, [ 1, 0, 0, 1 ], [ 20, 30 ], 'throw' ); // $ExpectError + mskput( 1, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + mskput( true, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + mskput( false, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + mskput( null, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + mskput( void 0, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + mskput( {}, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError } // The compiler throws an error if the function is provided a second argument which is not an array-like object... { - mskput( [], 1, [ 20, 30 ], 'throw' ); // $ExpectError - mskput( [], true, [ 20, 30 ], 'throw' ); // $ExpectError - mskput( [], false, [ 20, 30 ], 'throw' ); // $ExpectError - mskput( [], null, [ 20, 30 ], 'throw' ); // $ExpectError - mskput( [], void 0, [ 20, 30 ], 'throw' ); // $ExpectError - mskput( [], {}, [ 20, 30 ], 'throw' ); // $ExpectError + mskput( [], 1, [ 20, 30 ], 'strict' ); // $ExpectError + mskput( [], true, [ 20, 30 ], 'strict' ); // $ExpectError + mskput( [], false, [ 20, 30 ], 'strict' ); // $ExpectError + mskput( [], null, [ 20, 30 ], 'strict' ); // $ExpectError + mskput( [], void 0, [ 20, 30 ], 'strict' ); // $ExpectError + mskput( [], {}, [ 20, 30 ], 'strict' ); // $ExpectError } // The compiler throws an error if the function is provided a third argument which is not an array-like object... { - mskput( [], [ 1, 0, 0, 1 ], 1, 'throw' ); // $ExpectError - mskput( [], [ 1, 0, 0, 1 ], true, 'throw' ); // $ExpectError - mskput( [], [ 1, 0, 0, 1 ], false, 'throw' ); // $ExpectError - mskput( [], [ 1, 0, 0, 1 ], null, 'throw' ); // $ExpectError - mskput( [], [ 1, 0, 0, 1 ], void 0, 'throw' ); // $ExpectError - mskput( [], [ 1, 0, 0, 1 ], {}, 'throw' ); // $ExpectError + mskput( [], [ 1, 0, 0, 1 ], 1, 'strict' ); // $ExpectError + mskput( [], [ 1, 0, 0, 1 ], true, 'strict' ); // $ExpectError + mskput( [], [ 1, 0, 0, 1 ], false, 'strict' ); // $ExpectError + mskput( [], [ 1, 0, 0, 1 ], null, 'strict' ); // $ExpectError + mskput( [], [ 1, 0, 0, 1 ], void 0, 'strict' ); // $ExpectError + mskput( [], [ 1, 0, 0, 1 ], {}, 'strict' ); // $ExpectError } // The compiler throws an error if the function is provided a fourth argument which is not a valid mode... @@ -86,5 +88,5 @@ import mskput = require( './index' ); mskput( [] ); // $ExpectError mskput( [], [] ); // $ExpectError mskput( [], [], [], ); // $ExpectError - mskput( [], [], [], 'throw', {} ); // $ExpectError + mskput( [], [], [], 'strict', {} ); // $ExpectError } diff --git a/base/mskput/examples/index.js b/base/mskput/examples/index.js index 160aa516..feafd49f 100644 --- a/base/mskput/examples/index.js +++ b/base/mskput/examples/index.js @@ -38,5 +38,5 @@ var values = filledBy( N, discreteUniform.factory( 1000, 2000 ) ); console.log( values ); // Update a random sample of elements in `x`: -var out = mskput( x, mask, values, 'throw' ); +var out = mskput( x, mask, values, 'non_strict' ); console.log( out ); diff --git a/base/mskput/lib/index.js b/base/mskput/lib/index.js index 24415143..3d52b155 100644 --- a/base/mskput/lib/index.js +++ b/base/mskput/lib/index.js @@ -31,7 +31,7 @@ * var mask = [ 1, 0, 0, 1 ]; * var values = [ 20, 30 ]; * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * // returns [ 1, 20, 30, 4 ] * * var bool = ( out === x ); diff --git a/base/mskput/lib/main.js b/base/mskput/lib/main.js index 3f56bc9f..1b6200cb 100644 --- a/base/mskput/lib/main.js +++ b/base/mskput/lib/main.js @@ -214,8 +214,9 @@ function boolean( x, mask, values ) { * @param {Collection} x - input array * @param {Collection} mask - mask array * @param {Collection} values - values to set -* @param {string} mode - string specifying behavior when the number of values is less than the number of falsy mask values +* @param {string} mode - string specifying behavior when the number of values does not equal the number of falsy mask values * @throws {Error} insufficient values to satisfy mask array +* @throws {Error} number of values does not equal the number of falsy mask values * @returns {Collection} input array * * @example @@ -224,7 +225,7 @@ function boolean( x, mask, values ) { * var mask = [ 1, 0, 0, 1 ]; * var values = [ 20, 30 ]; * -* var out = mskput( x, mask, values, 'throw' ); +* var out = mskput( x, mask, values, 'strict' ); * // returns [ 1, 20, 30, 4 ] * * var bool = ( out === x ); @@ -236,7 +237,7 @@ function boolean( x, mask, values ) { * var mask = [ 1, 0, 0, 1 ]; * var values = [ 30 ]; * -* var out = mskput( x, mask, values, 'broadcast' ); +* var out = mskput( x, mask, values, 'strict_broadcast' ); * // returns [ 1, 30, 30, 4 ] * * var bool = ( out === x ); @@ -258,12 +259,25 @@ function mskput( x, mask, values, mode ) { var xo; var mo; var vo; + var M; - if ( mode === 'throw' && countFalsy( mask ) > values.length ) { - throw new Error( 'invalid arguments. Insufficient values to satisfy mask array.' ); - } - if ( mode === 'broadcast' && values.length > 1 && countFalsy( mask ) > values.length ) { - throw new Error( 'invalid arguments. Insufficient values to satisfy mask array.' ); + M = values.length; + if ( mode === 'strict' ) { + if ( countFalsy( mask ) !== M ) { + throw new Error( 'invalid arguments. Number of values does not equal the number of falsy values in the mask array.' ); + } + } else if ( mode === 'broadcast' ) { + if ( M !== 1 && countFalsy( mask ) > M ) { + throw new Error( 'invalid arguments. Insufficient values to satisfy mask array.' ); + } + } else if ( mode === 'strict_broadcast' ) { + if ( M !== 1 && countFalsy( mask ) !== M ) { + throw new Error( 'invalid arguments. Number of values does not equal the number of falsy values in the mask array.' ); + } + } else if ( mode === 'non_strict' ) { + if ( countFalsy( mask ) > M ) { + throw new Error( 'invalid arguments. Insufficient values to satisfy mask array.' ); + } } xo = arraylike2object( x ); mo = arraylike2object( mask ); diff --git a/base/mskput/test/test.js b/base/mskput/test/test.js index b746e333..32b159a9 100644 --- a/base/mskput/test/test.js +++ b/base/mskput/test/test.js @@ -48,21 +48,21 @@ tape( 'the function replaces elements in an array (generic)', function test( t ) x = [ 1, 2, 3, 4 ]; mask = [ 1, 0, 1, 0 ]; - actual = mskput( x, mask, [ 20, 40 ], 'throw' ); + actual = mskput( x, mask, [ 20, 40 ], 'strict' ); expected = [ 1, 20, 3, 40 ]; t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); x = [ 1, 2, 3, 4 ]; mask = [ 0, 0, 0, 0 ]; - actual = mskput( x, mask, [ 20, 30, 40, 50 ], 'throw' ); + actual = mskput( x, mask, [ 20, 30, 40, 50 ], 'strict' ); expected = [ 20, 30, 40, 50 ]; t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); x = [ 1, 2, 3, 4 ]; mask = [ 1, 1, 1, 1 ]; - actual = mskput( x, mask, [ 20, 30, 40, 50 ], 'throw' ); + actual = mskput( x, mask, [ 20, 30, 40, 50 ], 'non_strict' ); expected = [ 1, 2, 3, 4 ]; t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); @@ -78,7 +78,7 @@ tape( 'the function replaces elements in an array (generic, broadcasting)', func x = [ 1, 2, 3, 4 ]; mask = [ 1, 0, 1, 0 ]; - actual = mskput( x, mask, [ 20 ], 'broadcast' ); + actual = mskput( x, mask, [ 20 ], 'strict_broadcast' ); expected = [ 1, 20, 3, 20 ]; t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); @@ -92,7 +92,7 @@ tape( 'the function replaces elements in an array (generic, broadcasting)', func x = [ 1, 2, 3, 4 ]; mask = [ 1, 1, 1, 1 ]; - actual = mskput( x, mask, [ 20 ], 'broadcast' ); + actual = mskput( x, mask, [ 20 ], 'strict_broadcast' ); expected = [ 1, 2, 3, 4 ]; t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); @@ -115,21 +115,21 @@ tape( 'the function replaces elements in an array (typed)', function test( t ) { x = new Int32Array( [ 1, 2, 3, 4 ] ); mask = [ 1, 0, 1, 0 ]; - actual = mskput( x, mask, new Int32Array( [ 20, 40 ] ), 'throw' ); + actual = mskput( x, mask, new Int32Array( [ 20, 40 ] ), 'strict' ); expected = new Int32Array( [ 1, 20, 3, 40 ] ); t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); x = new Int32Array( [ 1, 2, 3, 4 ] ); mask = [ 0, 0, 0, 0 ]; - actual = mskput( x, mask, new Int32Array( [ 20, 30, 40, 50 ] ), 'throw' ); + actual = mskput( x, mask, new Int32Array( [ 20, 30, 40, 50 ] ), 'strict' ); expected = new Int32Array( [ 20, 30, 40, 50 ] ); t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); x = new Int32Array( [ 1, 2, 3, 4 ] ); mask = [ 1, 1, 1, 1 ]; - actual = mskput( x, mask, new Int32Array( [ 20, 30, 40, 50 ] ), 'throw' ); + actual = mskput( x, mask, new Int32Array( [ 20, 30, 40, 50 ] ), 'non_strict' ); expected = new Int32Array( [ 1, 2, 3, 4 ] ); t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); @@ -145,7 +145,7 @@ tape( 'the function replaces elements in an array (typed, broadcasting)', functi x = new Int32Array( [ 1, 2, 3, 4 ] ); mask = [ 1, 0, 1, 0 ]; - actual = mskput( x, mask, [ 20 ], 'broadcast' ); + actual = mskput( x, mask, [ 20 ], 'strict_broadcast' ); expected = new Int32Array( [ 1, 20, 3, 20 ] ); t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); @@ -159,7 +159,7 @@ tape( 'the function replaces elements in an array (typed, broadcasting)', functi x = new Int32Array( [ 1, 2, 3, 4 ] ); mask = [ 1, 1, 1, 1 ]; - actual = mskput( x, mask, [ 20 ], 'broadcast' ); + actual = mskput( x, mask, [ 20 ], 'strict_broadcast' ); expected = new Int32Array( [ 1, 2, 3, 4 ] ); t.strictEqual( actual, x, 'returns expected value' ); t.deepEqual( actual, expected, 'returns expected value' ); @@ -195,7 +195,7 @@ tape( 'the function replaces elements in an array (accessors)', function test( t new Complex64( 5.0, 6.0 ), new Complex64( 70.0, 80.0 ) ]; - actual = mskput( x, mask, values, 'throw' ); + actual = mskput( x, mask, values, 'strict' ); t.strictEqual( actual, x, 'returns expected value' ); for ( i = 0; i < mask.length; i++ ) { @@ -227,7 +227,7 @@ tape( 'the function replaces elements in an array (accessors, broadcasting)', fu new Complex64( 5.0, 6.0 ), new Complex64( 100.0, 200.0 ) ]; - actual = mskput( x, mask, values, 'broadcast' ); + actual = mskput( x, mask, values, 'strict_broadcast' ); t.strictEqual( actual, x, 'returns expected value' ); for ( i = 0; i < mask.length; i++ ) { @@ -257,7 +257,7 @@ tape( 'the function replaces elements in an array (accessors, complex)', functio new Complex64( 5.0, 6.0 ), new Complex64( 70.0, 80.0 ) ]; - actual = mskput( x, mask, values, 'throw' ); + actual = mskput( x, mask, values, 'strict' ); t.strictEqual( actual, x, 'returns expected value' ); for ( i = 0; i < mask.length; i++ ) { @@ -287,7 +287,7 @@ tape( 'the function replaces elements in an array (accessors, complex, broadcast new Complex64( 5.0, 6.0 ), new Complex64( 100.0, 200.0 ) ]; - actual = mskput( x, mask, values, 'broadcast' ); + actual = mskput( x, mask, values, 'strict_broadcast' ); t.strictEqual( actual, x, 'returns expected value' ); for ( i = 0; i < mask.length; i++ ) { @@ -312,7 +312,7 @@ tape( 'the function replaces elements in an array (accessors, boolean)', functio mask = toAccessorArray( [ 1, 0, 1, 0 ] ); values = new BooleanArray( [ true, false ] ); expected = [ true, true, false, true ]; - actual = mskput( x, mask, values, 'throw' ); + actual = mskput( x, mask, values, 'strict' ); t.strictEqual( actual, x, 'returns expected value' ); for ( i = 0; i < mask.length; i++ ) { @@ -335,7 +335,7 @@ tape( 'the function replaces elements in an array (accessors, boolean, broadcast mask = toAccessorArray( [ 1, 0, 0, 1 ] ); values = [ true ]; expected = [ true, true, true, true ]; - actual = mskput( x, mask, values, 'broadcast' ); + actual = mskput( x, mask, values, 'strict_broadcast' ); t.strictEqual( actual, x, 'returns expected value' ); for ( i = 0; i < mask.length; i++ ) { @@ -345,7 +345,67 @@ tape( 'the function replaces elements in an array (accessors, boolean, broadcast t.end(); }); -tape( 'when the "mode" is "throw", the function throws an error if provided insufficient values to satisfy the mask array', function test( t ) { +tape( 'when the "mode" is "strict", the function throws an error if provided insufficient values to satisfy the mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 0, 0, 0 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + mskput( x, mask, [ 200 ], 'strict' ); + } +}); + +tape( 'when the "mode" is "strict", the function throws an error if provided too many values to satisfy the mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 0, 0, 0 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + mskput( x, mask, [ 200, 300, 400, 500, 600 ], 'strict' ); + } +}); + +tape( 'when the "mode" is "non_strict", the function throws an error if provided insufficient values to satisfy the mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 0, 0, 0 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + mskput( x, mask, [ 200 ], 'non_strict' ); + } +}); + +tape( 'when the "mode" is "strict_broadcast", the function throws an error if provided a values array which is broadcast incompatible with the number of falsy values in a mask array (insufficient)', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 0, 0, 0 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + mskput( x, mask, [ 200, 400 ], 'strict_broadcast' ); + } +}); + +tape( 'when the "mode" is "strict_broadcast", the function throws an error if provided a values array which is broadcast incompatible with the number of falsy values in a mask array (too many)', function test( t ) { var mask; var x; @@ -356,11 +416,11 @@ tape( 'when the "mode" is "throw", the function throws an error if provided insu t.end(); function badValue() { - mskput( x, mask, [ 200 ], 'throw' ); + mskput( x, mask, [ 200, 400, 500, 600, 700 ], 'strict_broadcast' ); } }); -tape( 'when the "mode" is "broadcast", the function throws an error if a provided values array which is broadcast incompatible with the number of falsy values in a mask array', function test( t ) { +tape( 'when the "mode" is "broadcast", the function throws an error if provided a values array which is broadcast incompatible with the number of falsy values in a mask array', function test( t ) { var mask; var x; diff --git a/base/place/README.md b/base/place/README.md new file mode 100644 index 00000000..713469bc --- /dev/null +++ b/base/place/README.md @@ -0,0 +1,150 @@ + + +# place + +> Replace elements of an array with provided values according to a provided mask array. + +
+ +## Usage + +```javascript +var place = require( '@stdlib/array/base/place' ); +``` + +#### place( x, mask, values, mode ) + +Replaces elements of an array with provided values according to a provided mask array. + +```javascript +var x = [ 1, 2, 3, 4 ]; + +var out = place( x, [ 0, 1, 0, 1 ], [ 20, 40 ], 'strict' ); +// returns [ 1, 20, 3, 40 ] + +var bool = ( out === x ); +// returns true +``` + +The function supports the following parameters: + +- **x**: input array. +- **mask**: mask array. +- **values**: values to set. +- **mode**: string specifying behavior when the number of `values` does not equal the number of truthy `mask` values. + +The function supports the following modes: + +- `'strict'`: specifies that the function must raise an exception when the number of `values` does not **exactly** equal the number of truthy `mask` values. +- `'non_strict'`: specifies that the function must raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +- `'strict_broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the number of `values` does not **exactly** equal the number of truthy `mask` values. +- `'broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +- `'repeat'`: specifies that the function must reuse provided `values` when replacing elements in `x` in order to satisfy the `mask` array. + +In broadcasting modes, the function supports broadcasting a `values` array containing a single element against the number of truthy values in the `mask` array. + +```javascript +var x = [ 1, 2, 3, 4 ]; + +var out = place( x, [ 0, 1, 0, 1 ], [ 20 ], 'strict_broadcast' ); +// returns [ 1, 20, 3, 20 ] + +var bool = ( out === x ); +// returns true +``` + +In repeat mode, the function supports recycling elements in a `values` array to satisfy the number of truthy values in the `mask` array. + +```javascript +var x = [ 1, 2, 3, 4 ]; + +var out = place( x, [ 1, 1, 0, 1 ], [ 20, 40 ], 'repeat' ); +// returns [ 20, 40, 3, 20 ] + +var bool = ( out === x ); +// returns true +``` + +
+ + + +
+ +## Notes + +- The function mutates the input array `x`. +- If a `mask` array element is truthy, the corresponding element in `x` is **replaced**; otherwise, the corresponding element in `x` is "masked" and thus left unchanged. + +
+ + + +
+ +## Examples + + + +```javascript +var filledBy = require( '@stdlib/array/base/filled-by' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var bernoulli = require( '@stdlib/random/base/bernoulli' ); +var linspace = require( '@stdlib/array/base/linspace' ); +var place = require( '@stdlib/array/base/place' ); + +// Generate a linearly spaced array: +var x = linspace( 0, 100, 11 ); +console.log( x ); + +// Generate a random mask array: +var N = discreteUniform( 5, 15 ); +var mask = filledBy( N, bernoulli.factory( 0.3 ) ); +console.log( mask ); + +// Generate an array of random values: +var values = filledBy( N, discreteUniform.factory( 1000, 2000 ) ); +console.log( values ); + +// Update a random sample of elements in `x`: +var out = place( x, mask, values, 'non_strict' ); +console.log( out ); +``` + +
+ + + + + + + + + + + + + + diff --git a/base/place/benchmark/benchmark.js b/base/place/benchmark/benchmark.js new file mode 100644 index 00000000..dee3b2c1 --- /dev/null +++ b/base/place/benchmark/benchmark.js @@ -0,0 +1,79 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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 bench = require( '@stdlib/bench' ); +var isArray = require( '@stdlib/assert/is-array' ); +var zeroTo = require( './../../../base/zero-to' ); +var ones = require( './../../../base/ones' ); +var pkg = require( './../package.json' ).name; +var place = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::no_broadcasting:len=100', function benchmark( b ) { + var mask; + var x; + var i; + var v; + + x = zeroTo( 100 ); + mask = ones( 100 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = place( x, mask, x, 'strict' ); + if ( typeof v !== 'object' ) { + b.fail( 'should return an array' ); + } + } + b.toc(); + if ( !isArray( v ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::broadcasting:len=100', function benchmark( b ) { + var mask; + var x; + var i; + var v; + + x = zeroTo( 100 ); + mask = ones( 100 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = place( x, mask, [ i ], 'strict_broadcast' ); + if ( typeof v !== 'object' ) { + b.fail( 'should return an array' ); + } + } + b.toc(); + if ( !isArray( v ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/place/benchmark/benchmark.length.js b/base/place/benchmark/benchmark.length.js new file mode 100644 index 00000000..189e0f8b --- /dev/null +++ b/base/place/benchmark/benchmark.length.js @@ -0,0 +1,113 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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 bench = require( '@stdlib/bench' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); +var ones = require( './../../../base/ones' ); +var isArray = require( '@stdlib/assert/is-array' ); +var pkg = require( './../package.json' ).name; +var place = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'dtype': 'generic' +}; + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - array length +* @returns {Function} benchmark function +*/ +function createBenchmark( len ) { + var values; + var mask; + var x; + + x = discreteUniform( len, 0, 10, opts ); + mask = ones( len ); + values = [ + discreteUniform( len, -10, 0, opts ), + discreteUniform( len, 0, 10, opts ) + ]; + + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var v; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = place( x, mask, values[ i%values.length ], 'strict' ); + if ( typeof v !== 'object' ) { + b.fail( 'should return an array' ); + } + } + b.toc(); + if ( !isArray( v ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var f; + var i; + + min = 1; // 10^min + max = 6; // 10^max + + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + f = createBenchmark( len ); + bench( pkg+':len='+len, f ); + } +} + +main(); diff --git a/base/place/docs/repl.txt b/base/place/docs/repl.txt new file mode 100644 index 00000000..4d21bf01 --- /dev/null +++ b/base/place/docs/repl.txt @@ -0,0 +1,63 @@ + +{{alias}}( x, mask, values, mode ) + Replaces elements of an array with provided values according to a provided + mask array. + + In broadcasting modes, the function supports broadcasting a values array + containing a single element against the number of truthy values in the mask + array. + + In repeat mode, the function supports recycling elements in a values array + to satisfy the number of truthy values in the mask array. + + The function mutates the input array. + + Parameters + ---------- + x: ArrayLikeObject + Input array. + + mask: ArrayLikeObject + Mask array. If a mask array element is truthy, the corresponding element + in `x` is *replaced*; otherwise, the corresponding element in `x` is + "masked" and thus left unchanged. + + values: ArrayLikeObject + Values to set. + + mode: string + String specifying behavior when the number of values to set does not + equal the number of truthy mask values. The function supports the + following modes: + + - 'strict': specifies that the function must raise an exception when the + number of values does not *exactly* equal the number of truthy mask + values. + - 'non_strict': specifies that the function must raise an exception when + the function is provided insufficient values to satisfy the mask array. + - 'strict_broadcast': specifies that the function must broadcast a + single-element values array and otherwise raise an exception when the + number of values does not **exactly** equal the number of truthy mask + values. + - 'broadcast': specifies that the function must broadcast a single- + element values array and otherwise raise an exception when the function + is provided insufficient values to satisfy the mask array. + - 'repeat': specifies that the function must reuse provided values when + replacing elements in `x` in order to satisfy the mask array. + + Returns + ------- + out: ArrayLikeObject + Input array. + + Examples + -------- + > var x = [ 1, 2, 3, 4 ]; + > var out = {{alias}}( x, [ 0, 1, 0, 1 ], [ 20, 40 ], 'strict' ) + [ 1, 20, 3, 40 ] + > var bool = ( out === x ) + true + + See Also + -------- + diff --git a/base/place/docs/types/index.d.ts b/base/place/docs/types/index.d.ts new file mode 100644 index 00000000..66eaac75 --- /dev/null +++ b/base/place/docs/types/index.d.ts @@ -0,0 +1,227 @@ +/* +* @license Apache-2.0 +* +* 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. +* 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. +*/ + +// TypeScript Version: 4.1 + +/// + +import { Collection, AccessorArrayLike, TypedArray, ComplexTypedArray, BooleanTypedArray } from '@stdlib/types/array'; +import { ComplexLike } from '@stdlib/types/complex'; + +/** +* Mask array. +*/ +type MaskArray = Collection | AccessorArrayLike; + +/** +* Values array. +*/ +type ValuesArray = Collection | AccessorArrayLike; + +/** +* Mode specifying behavior when the number of values to set does not equal the number of truthy values in the mask array. +* +* ## Notes +* +* - The function supports the following modes: +* +* - `'strict'`: specifies that the function must raise an exception when the number of `values` does not **exactly** equal the number of truthy `mask` values. +* - `'non_strict'`: specifies that the function must raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +* - `'strict_broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the number of `values` does not **exactly** equal the number of truthy `mask` values. +* - `'broadcast'`: specifies that the function must broadcast a single-element `values` array and otherwise raise an exception when the function is provided insufficient `values` to satisfy the `mask` array. +* - `'repeat'`: specifies that the function must reuse provided `values` when replacing elements in `x` in order to satisfy the `mask` array. +*/ +type Mode = 'strict' | 'non_strict' | 'strict_broadcast' | 'broadcast' | 'repeat'; + +/** +* Replaces elements of an array with provided values according to a provided mask array. +* +* @param x - input array +* @param mask - mask array +* @param values - values to set +* @param mode - string specifying behavior when the number of values does not equal the number of truthy values in the mask array +* @returns input array +* +* @example +* var Int32Array = require( '@stdlib/array/int32' ); +* +* var x = new Int32Array( [ 1, 2, 3, 4 ] ); +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'strict' ); +* // returns [ 1, 20, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var Int32Array = require( '@stdlib/array/int32' ); +* +* var x = new Int32Array( [ 1, 2, 3, 4 ] ); +* +* var out = place( x, [ 0, 1, 1, 0 ], [ 30 ], 'strict_broadcast' ); +* // returns [ 1, 30, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +*/ +declare function place( x: T, mask: MaskArray, values: ValuesArray, mode: Mode ): T; + +/** +* Replaces elements of an array with provided values according to a provided mask array. +* +* @param x - input array +* @param mask - mask array +* @param values - values to set +* @param mode - string specifying behavior when the number of values does not equal the number of truthy values in the mask array +* @returns input array +* +* @example +* var Complex128Array = require( '@stdlib/array/complex128' ); +* +* var x = new Complex128Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = new Complex128Array( [ 20.0, 30.0, 40, 5.0 ] ); +* +* var out = place( x, mask, values, 'strict' ); +* // returns +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var Complex128Array = require( '@stdlib/array/complex128' ); +* +* var x = new Complex128Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = new Complex128Array( [ 20.0, 30.0 ] ); +* +* var out = place( x, mask, values, 'strict_broadcast' ); +* // returns +* +* var bool = ( out === x ); +* // returns true +*/ +declare function place( x: T, mask: MaskArray, values: ValuesArray, mode: Mode ): T; + +/** +* Replaces elements of an array with provided values according to a provided mask array. +* +* @param x - input array +* @param mask - mask array +* @param values - values to set +* @param mode - string specifying behavior when the number of values does not equal the number of truthy values in the mask array +* @returns input array +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'strict' ); +* // returns [ 1, 20, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var out = place( x, [ 0, 1, 1, 0 ], [ 30 ], 'strict_broadcast' ); +* // returns [ 1, 30, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +*/ +declare function place( x: Array, mask: MaskArray, values: ValuesArray, mode: Mode ): Array; + +/** +* Replaces elements of an array with provided values according to a provided mask array. +* +* @param x - input array +* @param mask - mask array +* @param values - values to set +* @param mode - string specifying behavior when the number of values does not equal the number of truthy values in the mask array +* @returns input array +* +* @example +* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); +* +* var x = toAccessorArray( [ 1, 2, 3, 4 ] ); +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'strict' ); +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); +* +* var x = toAccessorArray( [ 1, 2, 3, 4 ] ); +* +* var out = place( x, [ 0, 1, 1, 0 ], [ 30 ], 'strict_broadcast' ); +* +* var bool = ( out === x ); +* // returns true +*/ +declare function place( x: AccessorArrayLike, mask: MaskArray, values: ValuesArray, mode: Mode ): AccessorArrayLike; + +/** +* Replaces elements of an array with provided values according to a provided mask array. +* +* @param x - input array +* @param mask - mask array +* @param values - values to set +* @param mode - string specifying behavior when the number of values does not equal the number of truthy values in the mask array +* @returns input array +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'strict' ); +* // returns [ 1, 20, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var out = place( x, [ 0, 1, 1, 0 ], [ 30 ], 'strict_broadcast' ); +* // returns [ 1, 30, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +*/ +declare function place( x: Collection, mask: MaskArray, values: ValuesArray, mode: Mode ): Collection; + + +// EXPORTS // + +export = place; diff --git a/base/place/docs/types/test.ts b/base/place/docs/types/test.ts new file mode 100644 index 00000000..4d7afd4c --- /dev/null +++ b/base/place/docs/types/test.ts @@ -0,0 +1,92 @@ +/* +* @license Apache-2.0 +* +* 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. +* 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. +*/ + +import Complex128Array = require( './../../../../complex128' ); +import Complex64Array = require( './../../../../complex64' ); +import Complex128 = require( '@stdlib/complex/float64' ); +import AccessorArray = require( './../../../../base/accessor' ); +import place = require( './index' ); + + +// TESTS // + +// The function returns an array... +{ + place( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectType number[] + place( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'non_strict' ); // $ExpectType number[] + place( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict_broadcast' ); // $ExpectType number[] + place( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'broadcast' ); // $ExpectType number[] + place( [ 1, 2, 3, 4 ], [ 1, 0, 0, 1 ], [ 20, 30 ], 'repeat' ); // $ExpectType number[] + + place( new Int32Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectType Int32Array + place( new Complex128Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ new Complex128( 20, 30 ), [ 40, 50 ] ], 'strict' ); // $ExpectType Complex128Array + place( new Complex64Array( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], [ new Complex128( 20, 30 ), [ 40, 50 ] ], 'strict' ); // $ExpectType Complex64Array + place( new AccessorArray( [ 1, 2, 3, 4 ] ), [ 1, 0, 0, 1 ], new AccessorArray( [ 20, 30 ] ), 'strict' ); // $ExpectType AccessorArrayLike +} + +// The compiler throws an error if the function is provided a first argument which is not an array-like object... +{ + place( 1, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + place( true, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + place( false, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + place( null, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + place( void 0, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError + place( {}, [ 1, 0, 0, 1 ], [ 20, 30 ], 'strict' ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument which is not an array-like object... +{ + place( [], 1, [ 20, 30 ], 'strict' ); // $ExpectError + place( [], true, [ 20, 30 ], 'strict' ); // $ExpectError + place( [], false, [ 20, 30 ], 'strict' ); // $ExpectError + place( [], null, [ 20, 30 ], 'strict' ); // $ExpectError + place( [], void 0, [ 20, 30 ], 'strict' ); // $ExpectError + place( [], {}, [ 20, 30 ], 'strict' ); // $ExpectError +} + +// The compiler throws an error if the function is provided a third argument which is not an array-like object... +{ + place( [], [ 1, 0, 0, 1 ], 1, 'strict' ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], true, 'strict' ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], false, 'strict' ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], null, 'strict' ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], void 0, 'strict' ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], {}, 'strict' ); // $ExpectError +} + +// The compiler throws an error if the function is provided a fourth argument which is not a valid mode... +{ + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], '1' ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], 1 ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], true ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], false ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], null ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], void 0 ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], {} ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], [] ); // $ExpectError + place( [], [ 1, 0, 0, 1 ], [ 20, 30 ], ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + place(); // $ExpectError + place( [] ); // $ExpectError + place( [], [] ); // $ExpectError + place( [], [], [], ); // $ExpectError + place( [], [], [], 'strict', {} ); // $ExpectError +} diff --git a/base/place/examples/index.js b/base/place/examples/index.js new file mode 100644 index 00000000..5c37273e --- /dev/null +++ b/base/place/examples/index.js @@ -0,0 +1,42 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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'; + +var filledBy = require( './../../../base/filled-by' ); +var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ); +var bernoulli = require( '@stdlib/random/base/bernoulli' ); +var linspace = require( './../../../base/linspace' ); +var place = require( './../lib' ); + +// Generate a linearly spaced array: +var x = linspace( 0, 100, 11 ); +console.log( x ); + +// Generate a random mask array: +var N = discreteUniform( 5, 15 ); +var mask = filledBy( N, bernoulli.factory( 0.3 ) ); +console.log( mask ); + +// Generate an array of random values: +var values = filledBy( N, discreteUniform.factory( 1000, 2000 ) ); +console.log( values ); + +// Update a random sample of elements in `x`: +var out = place( x, mask, values, 'non_strict' ); +console.log( out ); diff --git a/base/place/lib/index.js b/base/place/lib/index.js new file mode 100644 index 00000000..f8d8a4fa --- /dev/null +++ b/base/place/lib/index.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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'; + +/** +* Replace elements of an array with provided values according to a provided mask array. +* +* @module @stdlib/array/base/place +* +* @example +* var place = require( '@stdlib/array/base/place' ); +* +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'strict' ); +* // returns [ 1, 20, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/base/place/lib/main.js b/base/place/lib/main.js new file mode 100644 index 00000000..d2d9bf69 --- /dev/null +++ b/base/place/lib/main.js @@ -0,0 +1,309 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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 isComplexDataType = require( './../../../base/assert/is-complex-floating-point-data-type' ); +var isBooleanDataType = require( './../../../base/assert/is-boolean-data-type' ); +var arraylike2object = require( './../../../base/arraylike2object' ); +var reinterpretComplex = require( '@stdlib/strided/base/reinterpret-complex' ); +var reinterpretBoolean = require( '@stdlib/strided/base/reinterpret-boolean' ); +var countTruthy = require( './../../../base/count-truthy' ); + + +// FUNCTIONS // + +/** +* Replaces elements in an indexed array with provided values. +* +* @private +* @param {Collection} x - input array +* @param {Collection} mask - mask array +* @param {Collection} values - values to set +* @returns {Collection} input array +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = indexed( x, mask, values ); +* // returns [ 1, 20, 30, 4 ] +*/ +function indexed( x, mask, values ) { + var iv; + var N; + var i; + + N = values.length; + iv = 0; + for ( i = 0; i < x.length; i++ ) { + if ( mask[ i ] ) { + x[ i ] = values[ iv ]; + iv = ( iv+1 ) % N; + } + } + return x; +} + +/** +* Replaces elements of an accessor array with provided values. +* +* @private +* @param {Object} x - input array object +* @param {Object} mask - mask array object +* @param {Object} values - values object +* @returns {Collection} input array +* +* @example +* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); +* var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +* +* var x = toAccessorArray( [ 1, 2, 3, 4 ] ); +* +* var mask = toAccessorArray( [ 0, 1, 1, 0 ] ); +* var values = toAccessorArray( [ 20, 30 ] ); +* +* var out = accessors( arraylike2object( x ), arraylike2object( mask ), arraylike2object( values ) ); +* +* var v = x.get( 0 ); +* // returns 1 +* +* v = x.get( 1 ); +* // returns 20 +*/ +function accessors( x, mask, values ) { + var xdata; + var mdata; + var vdata; + var xset; + var mget; + var vget; + var iv; + var N; + var i; + + xdata = x.data; + mdata = mask.data; + vdata = values.data; + + xset = x.accessors[ 1 ]; + mget = mask.accessors[ 0 ]; + vget = values.accessors[ 0 ]; + + N = vdata.length; + iv = 0; + for ( i = 0; i < xdata.length; i++ ) { + if ( mget( mdata, i ) ) { + xset( xdata, i, vget( vdata, iv ) ); + iv = ( iv+1 ) % N; + } + } + return xdata; +} + +/** +* Replaces elements in a complex array with provided values. +* +* @private +* @param {Collection} x - real-valued floating-point input array view +* @param {Object} mask - mask array object +* @param {Collection} values - real-valued floating-point values array view +* @returns {Collection} input array view +* +* @example +* var Float64Array = require( '@stdlib/array/float64' ); +* var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +* +* var x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); +* +* var mask = [ 1, 0, 1, 0 ]; +* var values = new Float64Array( [ 10.0, 20.0, 50.0, 60.0 ] ); +* +* var out = complex( x, arraylike2object( mask ), values ); +* // returns [ 10.0, 20.0, 3.0, 4.0, 50.0, 60.0, 7.0, 8.0 ] +*/ +function complex( x, mask, values ) { + var mdata; + var mget; + var iv; + var N; + var i; + + mdata = mask.data; + mget = mask.accessors[ 0 ]; + + N = values.length; + iv = 0; + for ( i = 0; i < x.length; i += 2 ) { + if ( mget( mdata, i/2 ) ) { + x[ i ] = values[ iv ]; + x[ i+1 ] = values[ iv+1 ]; + iv = ( iv+2 ) % N; + } + } + return x; +} + +/** +* Replaces elements in a boolean array with provided values. +* +* @private +* @param {Uint8Array} x - input array +* @param {Object} mask - mask array object +* @param {Uint8Array} values - values to set +* @returns {Uint8Array} input array +* +* @example +* var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +* var Uint8Array = require( '@stdlib/array/uint8' ); +* +* var x = new Uint8Array( [ 0, 1, 1, 0 ] ); +* +* var mask = [ 1, 0, 0, 1 ]; +* var values = new Uint8Array( [ 1, 1 ] ); +* +* var out = boolean( x, arraylike2object( mask ), values ); +* // returns [ 1, 1, 1, 1 ] +*/ +function boolean( x, mask, values ) { + var mdata; + var mget; + var iv; + var N; + var i; + + mdata = mask.data; + mget = mask.accessors[ 0 ]; + + N = values.length; + iv = 0; + for ( i = 0; i < x.length; i++ ) { + if ( mget( mdata, i ) ) { + x[ i ] = values[ iv ]; + iv = ( i+1 ) % N; + } + } + return x; +} + + +// MAIN // + +/** +* Replaces elements of an array with provided values according to a provided mask array. +* +* @param {Collection} x - input array +* @param {Collection} mask - mask array +* @param {Collection} values - values to set +* @param {string} mode - string specifying behavior when the number of values does not equal the number of truthy mask values +* @throws {Error} insufficient values to satisfy mask array +* @throws {Error} number of values does not equal the number of truthy mask values +* @returns {Collection} input array +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'strict' ); +* // returns [ 1, 20, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 0, 1, 1, 0 ]; +* var values = [ 30 ]; +* +* var out = place( x, mask, values, 'strict_broadcast' ); +* // returns [ 1, 30, 30, 4 ] +* +* var bool = ( out === x ); +* // returns true +* +* @example +* var x = [ 1, 2, 3, 4 ]; +* +* var mask = [ 1, 1, 0, 1 ]; +* var values = [ 20, 30 ]; +* +* var out = place( x, mask, values, 'repeat' ); +* // returns [ 20, 30, 3, 20 ] +* +* var bool = ( out === x ); +* // returns true +*/ +function place( x, mask, values, mode ) { + var xo; + var mo; + var vo; + var M; + + M = values.length; + if ( mode === 'strict' ) { + if ( countTruthy( mask ) !== M ) { + throw new Error( 'invalid arguments. Number of values does not equal the number of truthy values in the mask array.' ); + } + } else if ( mode === 'broadcast' ) { + if ( M !== 1 && countTruthy( mask ) > M ) { + throw new Error( 'invalid arguments. Insufficient values to satisfy mask array.' ); + } + } else if ( mode === 'strict_broadcast' ) { + if ( M !== 1 && countTruthy( mask ) !== M ) { + throw new Error( 'invalid arguments. Number of values does not equal the number of truthy values in the mask array.' ); + } + } else if ( mode === 'non_strict' ) { + if ( countTruthy( mask ) > M ) { + throw new Error( 'invalid arguments. Insufficient values to satisfy mask array.' ); + } + } + xo = arraylike2object( x ); + mo = arraylike2object( mask ); + vo = arraylike2object( values ); + if ( + xo.accessorProtocol || + mo.accessorProtocol || + vo.accessorProtocol + ) { + // Note: we only explicitly support select dtype pairs, as this function should not be concerned with casting rules, etc. That is left to userland... + if ( isComplexDataType( xo.dtype ) && isComplexDataType( vo.dtype ) ) { + complex( reinterpretComplex( x, 0 ), mo, reinterpretComplex( values, 0 ) ); // eslint-disable-line max-len + return x; + } + if ( isBooleanDataType( xo.dtype ) && isBooleanDataType( vo.dtype ) ) { + boolean( reinterpretBoolean( x, 0 ), mo, reinterpretBoolean( values, 0 ) ); // eslint-disable-line max-len + return x; + } + accessors( xo, mo, vo ); + return x; + } + indexed( x, mask, values ); + return x; +} + + +// EXPORTS // + +module.exports = place; diff --git a/base/place/package.json b/base/place/package.json new file mode 100644 index 00000000..f333adf2 --- /dev/null +++ b/base/place/package.json @@ -0,0 +1,65 @@ +{ + "name": "@stdlib/array/base/place", + "version": "0.0.0", + "description": "Replace elements of an array with provided values according to a provided mask array.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "utilities", + "utils", + "generic", + "array", + "set", + "replace", + "put", + "update", + "mask", + "missing", + "na" + ] +} diff --git a/base/place/test/test.js b/base/place/test/test.js new file mode 100644 index 00000000..6753d41b --- /dev/null +++ b/base/place/test/test.js @@ -0,0 +1,436 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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 tape = require( 'tape' ); +var Complex64Array = require( './../../../complex64' ); +var Int32Array = require( './../../../int32' ); +var BooleanArray = require( './../../../bool' ); +var toAccessorArray = require( './../../../base/to-accessor-array' ); +var Complex64 = require( '@stdlib/complex/float32' ); +var realf = require( '@stdlib/complex/realf' ); +var imagf = require( '@stdlib/complex/imagf' ); +var isComplex64 = require( '@stdlib/assert/is-complex64' ); +var place = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof place, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function replaces elements in an array (generic)', function test( t ) { + var expected; + var actual; + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 1, 0, 1 ]; + actual = place( x, mask, [ 20, 40 ], 'strict' ); + expected = [ 1, 20, 3, 40 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + actual = place( x, mask, [ 20, 30, 40, 50 ], 'strict' ); + expected = [ 20, 30, 40, 50 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 0, 0, 0 ]; + actual = place( x, mask, [ 20, 30, 40, 50 ], 'non_strict' ); + expected = [ 1, 2, 3, 4 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function replaces elements in an array (generic, broadcasting)', function test( t ) { + var expected; + var actual; + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 1, 0, 1 ]; + actual = place( x, mask, [ 20 ], 'strict_broadcast' ); + expected = [ 1, 20, 3, 20 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + actual = place( x, mask, [ 20 ], 'broadcast' ); + expected = [ 20, 20, 20, 20 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + mask = [ 0, 0, 0, 0 ]; + actual = place( x, mask, [ 20 ], 'strict_broadcast' ); + expected = [ 1, 2, 3, 4 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + actual = place( x, mask, [ 100, 200 ], 'repeat' ); + expected = [ 100, 200, 100, 200 ]; + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function replaces elements in an array (typed)', function test( t ) { + var expected; + var actual; + var mask; + var x; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 0, 1, 0, 1 ]; + actual = place( x, mask, new Int32Array( [ 20, 40 ] ), 'strict' ); + expected = new Int32Array( [ 1, 20, 3, 40 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 1, 1, 1, 1 ]; + actual = place( x, mask, new Int32Array( [ 20, 30, 40, 50 ] ), 'strict' ); + expected = new Int32Array( [ 20, 30, 40, 50 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 0, 0, 0, 0 ]; + actual = place( x, mask, new Int32Array( [ 20, 30, 40, 50 ] ), 'non_strict' ); + expected = new Int32Array( [ 1, 2, 3, 4 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function replaces elements in an array (typed, broadcasting)', function test( t ) { + var expected; + var actual; + var mask; + var x; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 0, 1, 0, 1 ]; + actual = place( x, mask, [ 20 ], 'strict_broadcast' ); + expected = new Int32Array( [ 1, 20, 3, 20 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 1, 1, 1, 1 ]; + actual = place( x, mask, [ 20 ], 'broadcast' ); + expected = new Int32Array( [ 20, 20, 20, 20 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 0, 0, 0, 0 ]; + actual = place( x, mask, [ 20 ], 'strict_broadcast' ); + expected = new Int32Array( [ 1, 2, 3, 4 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + mask = [ 1, 1, 1, 1 ]; + actual = place( x, mask, [ 100, 200 ], 'repeat' ); + expected = new Int32Array( [ 100, 200, 100, 200 ] ); + t.strictEqual( actual, x, 'returns expected value' ); + t.deepEqual( actual, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function replaces elements in an array (accessors)', function test( t ) { + var expected; + var actual; + var values; + var mask; + var x; + var v; + var i; + + x = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + mask = toAccessorArray( [ 0, 1, 0, 1 ] ); + values = [ + new Complex64( 30.0, 40.0 ), + new Complex64( 70.0, 80.0 ) + ]; + expected = [ + new Complex64( 1.0, 2.0 ), + new Complex64( 30.0, 40.0 ), + new Complex64( 5.0, 6.0 ), + new Complex64( 70.0, 80.0 ) + ]; + actual = place( x, mask, values, 'strict' ); + + t.strictEqual( actual, x, 'returns expected value' ); + for ( i = 0; i < mask.length; i++ ) { + v = actual.get( i ); + t.strictEqual( isComplex64( v ), true, 'returns expected value' ); + t.strictEqual( realf( v ), realf( expected[ i ] ), 'returns expected value' ); + t.strictEqual( imagf( v ), imagf( expected[ i ] ), 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function replaces elements in an array (accessors, broadcasting)', function test( t ) { + var expected; + var actual; + var values; + var mask; + var x; + var v; + var i; + + x = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + mask = toAccessorArray( [ 0, 1, 0, 1 ] ); + values = [ + new Complex64( 100.0, 200.0 ) + ]; + expected = [ + new Complex64( 1.0, 2.0 ), + new Complex64( 100.0, 200.0 ), + new Complex64( 5.0, 6.0 ), + new Complex64( 100.0, 200.0 ) + ]; + actual = place( x, mask, values, 'strict_broadcast' ); + + t.strictEqual( actual, x, 'returns expected value' ); + for ( i = 0; i < mask.length; i++ ) { + v = actual.get( i ); + t.strictEqual( isComplex64( v ), true, 'returns expected value' ); + t.strictEqual( realf( v ), realf( expected[ i ] ), 'returns expected value' ); + t.strictEqual( imagf( v ), imagf( expected[ i ] ), 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function replaces elements in an array (accessors, complex)', function test( t ) { + var expected; + var actual; + var values; + var mask; + var x; + var v; + var i; + + x = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + mask = toAccessorArray( [ 0, 1, 0, 1 ] ); + values = new Complex64Array( [ 30.0, 40.0, 70.0, 80.0 ] ); + expected = [ + new Complex64( 1.0, 2.0 ), + new Complex64( 30.0, 40.0 ), + new Complex64( 5.0, 6.0 ), + new Complex64( 70.0, 80.0 ) + ]; + actual = place( x, mask, values, 'strict' ); + + t.strictEqual( actual, x, 'returns expected value' ); + for ( i = 0; i < mask.length; i++ ) { + v = actual.get( i ); + t.strictEqual( isComplex64( v ), true, 'returns expected value' ); + t.strictEqual( realf( v ), realf( expected[ i ] ), 'returns expected value' ); + t.strictEqual( imagf( v ), imagf( expected[ i ] ), 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function replaces elements in an array (accessors, complex, broadcasting)', function test( t ) { + var expected; + var actual; + var values; + var mask; + var x; + var v; + var i; + + x = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] ); + mask = toAccessorArray( [ 0, 1, 0, 1 ] ); + values = new Complex64Array( [ 100.0, 200.0 ] ); + expected = [ + new Complex64( 1.0, 2.0 ), + new Complex64( 100.0, 200.0 ), + new Complex64( 5.0, 6.0 ), + new Complex64( 100.0, 200.0 ) + ]; + actual = place( x, mask, values, 'strict_broadcast' ); + + t.strictEqual( actual, x, 'returns expected value' ); + for ( i = 0; i < mask.length; i++ ) { + v = actual.get( i ); + t.strictEqual( isComplex64( v ), true, 'returns expected value' ); + t.strictEqual( realf( v ), realf( expected[ i ] ), 'returns expected value' ); + t.strictEqual( imagf( v ), imagf( expected[ i ] ), 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function replaces elements in an array (accessors, boolean)', function test( t ) { + var expected; + var actual; + var values; + var mask; + var x; + var v; + var i; + + x = new BooleanArray( [ true, false, false, true ] ); + mask = toAccessorArray( [ 0, 1, 0, 1 ] ); + values = new BooleanArray( [ true, false ] ); + expected = [ true, true, false, true ]; + actual = place( x, mask, values, 'strict' ); + + t.strictEqual( actual, x, 'returns expected value' ); + for ( i = 0; i < mask.length; i++ ) { + v = actual.get( i ); + t.strictEqual( v, expected[ i ], 'returns expected value' ); + } + t.end(); +}); + +tape( 'the function replaces elements in an array (accessors, boolean, broadcasting)', function test( t ) { + var expected; + var actual; + var values; + var mask; + var x; + var v; + var i; + + x = new BooleanArray( [ true, false, false, true ] ); + mask = toAccessorArray( [ 0, 1, 1, 0 ] ); + values = [ true ]; + expected = [ true, true, true, true ]; + actual = place( x, mask, values, 'strict_broadcast' ); + + t.strictEqual( actual, x, 'returns expected value' ); + for ( i = 0; i < mask.length; i++ ) { + v = actual.get( i ); + t.strictEqual( v, expected[ i ], 'returns expected value' ); + } + t.end(); +}); + +tape( 'when the "mode" is "strict", the function throws an error if provided insufficient values to satisfy the mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + place( x, mask, [ 200 ], 'strict' ); + } +}); + +tape( 'when the "mode" is "strict", the function throws an error if provided too many values to satisfy the mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + place( x, mask, [ 200, 300, 400, 500, 600 ], 'strict' ); + } +}); + +tape( 'when the "mode" is "non_strict", the function throws an error if provided insufficient values to satisfy the mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + place( x, mask, [ 200 ], 'non_strict' ); + } +}); + +tape( 'when the "mode" is "strict_broadcast", the function throws an error if provided a values array which is broadcast incompatible with the number of truthy values in a mask array (insufficient)', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + place( x, mask, [ 200, 400 ], 'strict_broadcast' ); + } +}); + +tape( 'when the "mode" is "strict_broadcast", the function throws an error if provided a values array which is broadcast incompatible with the number of truthy values in a mask array (too many)', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + place( x, mask, [ 200, 400, 500, 600, 700 ], 'strict_broadcast' ); + } +}); + +tape( 'when the "mode" is "broadcast", the function throws an error if provided a values array which is broadcast incompatible with the number of truthy values in a mask array', function test( t ) { + var mask; + var x; + + x = [ 1, 2, 3, 4 ]; + mask = [ 1, 1, 1, 1 ]; + + t.throws( badValue, Error, 'throws an error' ); + t.end(); + + function badValue() { + place( x, mask, [ 200, 400 ], 'broadcast' ); + } +}); diff --git a/to-fancy/lib/set_elements.js b/to-fancy/lib/set_elements.js index 793c7146..45c32e26 100644 --- a/to-fancy/lib/set_elements.js +++ b/to-fancy/lib/set_elements.js @@ -26,6 +26,7 @@ var scalar2array = require( './../../from-scalar' ); var dtype = require( './../../dtype' ); var put = require( './../../put' ); var where = require( './../../base/where' ).assign; +var place = require( './../../base/place' ); var format = require( '@stdlib/string/format' ); var prop2array = require( './prop2array.js' ); var errMessage = require( './error_message.js' ); @@ -53,20 +54,20 @@ var errMessage = require( './error_message.js' ); * @returns {boolean} boolean indicating whether assignment succeeded */ function setElements( target, property, value, ctx ) { + var tdt; + var vdt; var idx; var err; - var dt; var v; idx = prop2array( property, ctx.cache ); + tdt = ctx.dtype || 'generic'; if ( isCollection( value ) ) { // When handling collections, we delegate to implementation APIs (see below) to perform argument validation (e.g., ensuring a (mostly) safe cast, broadcast compatibility, etc), so we just reassign the value here: v = value; - dt = dtype( value ) || 'generic'; } else { // When provided a "scalar", we need to check whether the value can be safely cast to the target array data type: - dt = ctx.dtype; - err = ctx.validator( value, dt ); + err = ctx.validator( value, tdt ); if ( err ) { throw err; } @@ -76,7 +77,8 @@ function setElements( target, property, value, ctx ) { v = value; } // As the scalar can be safely cast, convert the scalar to an array having the same data type as the target array to allow for broadcasting during assignment: - v = scalar2array( v, dt ); + v = scalar2array( v, tdt ); + vdt = tdt; } if ( idx.type === 'int' ) { try { @@ -86,16 +88,27 @@ function setElements( target, property, value, ctx ) { } return true; } + if ( vdt === void 0 ) { + vdt = dtype( value ) || 'generic'; + } // Safe casts are always allowed and allow same kind casts (i.e., downcasts) only when the target array data type is floating-point... - if ( !isMostlySafeCast( dt, ctx.dtype ) ) { - throw new TypeError( format( 'invalid operation. Assigned value cannot be safely cast to the target array data type. Data types: [%s, %s].', dt, ctx.dtype ) ); + if ( !isMostlySafeCast( vdt, tdt ) ) { + throw new TypeError( format( 'invalid operation. Assigned value cannot be safely cast to the target array data type. Data types: [%s, %s].', vdt, tdt ) ); } if ( idx.type === 'bool' ) { - where( idx.data, v, target, target, 1, 0 ); + try { + place( target, idx.data, v, 'strict_broadcast' ); + } catch ( err ) { + throw new err.constructor( errMessage( err.message ) ); + } return true; } if ( idx.type === 'mask' ) { - where( idx.data, target, v, target, 1, 0 ); + try { + where( idx.data, target, v, target, 1, 0 ); // note: intentionally deviate from boolean array indexing here and interpret the mask as applying to both the target and values array, thus requiring that the assigned value array be broadcast compatible with the target array and NOT just the selected elements as in boolean array indexing + } catch ( err ) { + throw new err.constructor( errMessage( err.message ) ); + } return true; } throw new Error( format( 'invalid operation. Unrecognized array index type. Value: `%s`.', idx.type ) ); diff --git a/to-fancy/lib/set_slice.js b/to-fancy/lib/set_slice.js index 8b20889f..2f18383b 100644 --- a/to-fancy/lib/set_slice.js +++ b/to-fancy/lib/set_slice.js @@ -68,7 +68,7 @@ function setSlice( target, property, value, receiver, ctx ) { throw err; } // As the scalar can be safely cast, convert the scalar to an array having the same data type as the target array to allow for broadcasting during slice assignment: - v = scalar2array( value, ctx.dtype ); + v = scalar2array( value, ctx.dtype || 'generic' ); } try { sliceAssign( v, receiver, s, ctx.strict ); diff --git a/to-fancy/test/test.set.boolean_array.js b/to-fancy/test/test.set.boolean_array.js new file mode 100644 index 00000000..346aec1d --- /dev/null +++ b/to-fancy/test/test.set.boolean_array.js @@ -0,0 +1,1518 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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 tape = require( 'tape' ); +var hasProxySupport = require( '@stdlib/assert/has-proxy-support' ); +var isSameComplex128Array = require( '@stdlib/assert/is-same-complex128array' ); +var isSameComplex64Array = require( '@stdlib/assert/is-same-complex64array' ); +var Complex128 = require( '@stdlib/complex/float64/ctor' ); +var Float64Array = require( './../../float64' ); +var Float32Array = require( './../../float32' ); +var Int32Array = require( './../../int32' ); +var Int8Array = require( './../../int8' ); +var Uint32Array = require( './../../uint32' ); +var Uint16Array = require( './../../uint16' ); +var Complex128Array = require( './../../complex128' ); +var Complex64Array = require( './../../complex64' ); +var toAccessorArray = require( './../../base/to-accessor-array' ); +var BooleanArray = require( './../../bool' ); +var array2fancy = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': !hasProxySupport() +}; + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof array2fancy, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an array-like object supporting boolean array assignment (generic)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = [ 5, 6, 7, 8 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = [ 5, 6, 3, 4 ]; + y[ idx ] = [ 5, 6 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = [ 1, 5, 6, 4 ]; + y[ idx ] = [ 5, 6 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = [ 5, 2, 6, 4 ]; + y[ idx ] = [ 5, 6 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting boolean array assignment ("unknown" dtype, accessor)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = [ 5, 6, 7, 8 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = [ 5, 6, 3, 4 ]; + y[ idx ] = [ 5, 6 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = [ 1, 5, 6, 4 ]; + y[ idx ] = [ 5, 6 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = [ 5, 2, 6, 4 ]; + y[ idx ] = [ 5, 6 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting boolean array assignment (int32)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Int32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Int32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Int32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Int32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Int32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Int32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Int32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting boolean array assignment (uint32)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Uint32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Uint32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Uint32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Uint32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Uint32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Uint32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Uint32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Uint32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting boolean array assignment (float64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Float64Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Float64Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Float64Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Float64Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Float64Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting boolean array assignment (complex128)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + y[ idx ] = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Complex128Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Complex128Array( [ 1, 2, 17, 18, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Complex128Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (generic, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = [ 5, 5, 5, 5 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = [ 5, 5, 3, 4 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = [ 1, 5, 5, 4 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = [ 5, 2, 5, 4 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (generic, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = [ 5, 5, 5, 5 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = [ 5, 5, 3, 4 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = [ 1, 5, 5, 4 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = [ 5, 2, 5, 4 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (float64, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Float64Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Float64Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Float64Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Float64Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (float64, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Float64Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Float64Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Float64Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Float64Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (int32, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Int32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Int32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Int32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Int32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ -1, -3 ] ); + expected = new Int32Array( [ 1, 5, 3, 5 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (int32, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Int32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Int32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Int32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Int32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (uint32, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Uint32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Uint32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Uint32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Uint32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (uint32, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Uint32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Uint32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Uint32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Uint32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (complex128, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Complex128Array( [ 9, 10, 9, 10, 9, 10, 9, 10 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Complex128Array( [ 9, 10, 9, 10, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Complex128Array( [ 1, 2, 9, 10, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Complex128Array( [ 9, 10, 3, 4, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (complex128, complex scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Complex128Array( [ 9, 10, 9, 10, 9, 10, 9, 10 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Complex128Array( [ 9, 10, 9, 10, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Complex128Array( [ 1, 2, 9, 10, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Complex128Array( [ 9, 10, 3, 4, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted boolean array assignment (complex128, real scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Complex128Array( [ 9, 0, 9, 0, 9, 0, 9, 0 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Complex128Array( [ 9, 0, 9, 0, 5, 6, 7, 8 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Complex128Array( [ 1, 2, 9, 0, 9, 0, 7, 8 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Complex128Array( [ 9, 0, 3, 4, 9, 0, 7, 8 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (generic, float64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = new Float64Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = [ 5, 6, 3, 4 ]; + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = [ 1, 5, 6, 4 ]; + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = [ 5, 2, 6, 4 ]; + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (float64, float32)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Float64Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Float32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Float64Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Float32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Float64Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Float32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Float64Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Float32Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (int32, int8)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Int8Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Int32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Int8Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Int32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Int8Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Int32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Int8Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (uint32, uint16)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Uint32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Uint16Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Uint32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Uint16Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Uint32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Uint16Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Uint32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Uint16Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (complex128, complex64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + y[ idx ] = new Complex64Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Complex128Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex64Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Complex128Array( [ 1, 2, 17, 18, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex64Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Complex128Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex64Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting downcasting of floating-point arrays (float32, float64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Float32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Float64Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Float32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Float32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Float32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting downcasting of floating-point arrays (complex64, complex128)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ] ); + expected = new Complex64Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + y[ idx ] = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, true, false, false ] ) ); + expected = new Complex64Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ false, true, true, false ] ); + expected = new Complex64Array( [ 1, 2, 17, 18, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new BooleanArray( [ true, false, true, false ] ) ); + expected = new Complex64Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object which throws an error when attempting to assign a broadcast-incompatible array (generic)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + [], + [ 5, 6 ], + [ 5, 6, 7 ], + [ 5, 6, 7, 8, 9 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to assign a broadcast-incompatible array (int32)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + new Int32Array( [] ), + new Int32Array( [ 5, 6 ] ), + new Int32Array( [ 5, 6, 7 ] ), + new Int32Array( [ 5, 6, 7, 8, 9 ] ) + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (float64)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + new Complex128Array( [ 5, 6 ] ), + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (complex128)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (int32)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + new Uint32Array( [ 1 ] ), + new Uint32Array( [ 5, 6, 7, 8 ] ), + new Float64Array( [ 1 ] ), + new Float64Array( [ 5, 6, 7, 8 ] ), + new Float32Array( [ 1 ] ), + new Float32Array( [ 5, 6, 7, 8 ] ), + new Complex128Array( [ 5, 6 ] ), + 3.14, + -3.14, + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (int8)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Int8Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + new Int32Array( [ 1 ] ), + new Int32Array( [ 5, 6, 7, 8 ] ), + new Float64Array( [ 1 ] ), + new Float64Array( [ 5, 6, 7, 8 ] ), + new Float32Array( [ 1 ] ), + new Float32Array( [ 5, 6, 7, 8 ] ), + new Complex128Array( [ 5, 6 ] ), + 999999, + 3.14, + -3.14, + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (uint32)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + + values = [ + new Int32Array( [ 1 ] ), + new Int32Array( [ 5, 6, 7, 8 ] ), + new Float64Array( [ 1 ] ), + new Float64Array( [ 5, 6, 7, 8 ] ), + new Float32Array( [ 1 ] ), + new Float32Array( [ 5, 6, 7, 8 ] ), + new Complex128Array( [ 5, 6 ] ), + -3, + 3.14, + -3.14, + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when unable to resolve an index array (generic)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': false + }); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = [ 5, 6, 7, 8 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.throws( badValue( idx ), Error, 'throws an error' ); + t.end(); + + function badValue( value ) { + return function badValue() { + y[ value ] = [ 9, 10, 11, 12 ]; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when unable to resolve an index array (typed)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': false + }); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Int32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.throws( badValue( idx ), Error, 'throws an error' ); + t.end(); + + function badValue( value ) { + return function badValue() { + y[ value ] = new Int32Array( [ 9, 10, 11, 12 ] ); + }; + } +}); + +tape( 'the function returns an array-like object which supports persisted index arrays (generic)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + expected = [ 5, 6, 7, 8 ]; + + y[ idx ] = [ 5, 6, 7, 8 ]; + t.deepEqual( y, expected, 'returns expected value' ); + + expected = [ 9, 10, 11, 12 ]; + + y[ idx ] = [ 9, 10, 11, 12 ]; + t.deepEqual( y, expected, 'returns expected value' ); + + array2fancy.idx.free( idx ); + + t.end(); +}); + +tape( 'the function returns an array-like object which supports persisted index arrays (typed)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ true, true, true, true ], { + 'persist': true + }); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + + y[ idx ] = new Int32Array( [ 5, 6, 7, 8 ] ); + t.deepEqual( y, expected, 'returns expected value' ); + + expected = new Int32Array( [ 9, 10, 11, 12 ] ); + + y[ idx ] = new Int32Array( [ 9, 10, 11, 12 ] ); + t.deepEqual( y, expected, 'returns expected value' ); + + array2fancy.idx.free( idx ); + + t.end(); +}); diff --git a/to-fancy/test/test.set.integer_array.js b/to-fancy/test/test.set.integer_array.js index d46d22dd..bee971a7 100644 --- a/to-fancy/test/test.set.integer_array.js +++ b/to-fancy/test/test.set.integer_array.js @@ -70,7 +70,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = [ 5, 6, 3, 4 ]; y[ idx ] = [ 5, 6 ]; @@ -88,7 +88,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = [ 5, 2, 6, 4 ]; y[ idx ] = [ 5, 6 ]; @@ -124,7 +124,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = [ 1, 2, 3, 4 ]; y = array2fancy( toAccessorArray( x ) ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = [ 5, 6, 3, 4 ]; y[ idx ] = [ 5, 6 ]; @@ -142,7 +142,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = [ 1, 2, 3, 4 ]; y = array2fancy( toAccessorArray( x ) ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = [ 5, 2, 6, 4 ]; y[ idx ] = [ 5, 6 ]; @@ -178,7 +178,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Int32Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Int32Array( [ 5, 6 ] ); @@ -196,7 +196,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Int32Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Int32Array( [ 5, 6 ] ); @@ -232,7 +232,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Uint32Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Uint32Array( [ 5, 6 ] ); @@ -250,7 +250,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Uint32Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Uint32Array( [ 5, 6 ] ); @@ -286,7 +286,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Float64Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Float64Array( [ 5, 6 ] ); @@ -304,7 +304,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Float64Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Float64Array( [ 5, 6 ] ); @@ -340,7 +340,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Complex128Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); @@ -358,7 +358,7 @@ tape( 'the function returns an array-like object supporting integer array assign x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Complex128Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); @@ -394,7 +394,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = [ 5, 5, 3, 4 ]; y[ idx ] = [ 5 ]; @@ -412,7 +412,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = [ 5, 2, 5, 4 ]; y[ idx ] = [ 5 ]; @@ -448,7 +448,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = [ 5, 5, 3, 4 ]; y[ idx ] = 5; @@ -466,7 +466,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = [ 5, 2, 5, 4 ]; y[ idx ] = 5; @@ -502,7 +502,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Float64Array( [ 5, 5, 3, 4 ] ); y[ idx ] = new Float64Array( [ 5 ] ); @@ -520,7 +520,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Float64Array( [ 5, 2, 5, 4 ] ); y[ idx ] = new Float64Array( [ 5 ] ); @@ -556,7 +556,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Float64Array( [ 5, 5, 3, 4 ] ); y[ idx ] = 5; @@ -574,7 +574,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Float64Array( [ 5, 2, 5, 4 ] ); y[ idx ] = 5; @@ -610,7 +610,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Int32Array( [ 5, 5, 3, 4 ] ); y[ idx ] = new Int32Array( [ 5 ] ); @@ -628,7 +628,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Int32Array( [ 5, 2, 5, 4 ] ); y[ idx ] = new Int32Array( [ 5 ] ); @@ -664,7 +664,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Int32Array( [ 5, 5, 3, 4 ] ); y[ idx ] = 5; @@ -682,7 +682,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Int32Array( [ 5, 2, 5, 4 ] ); y[ idx ] = 5; @@ -718,7 +718,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Uint32Array( [ 5, 5, 3, 4 ] ); y[ idx ] = new Uint32Array( [ 5 ] ); @@ -736,7 +736,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Uint32Array( [ 5, 2, 5, 4 ] ); y[ idx ] = new Uint32Array( [ 5 ] ); @@ -772,7 +772,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Uint32Array( [ 5, 5, 3, 4 ] ); y[ idx ] = 5; @@ -790,7 +790,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Uint32Array( [ 5, 2, 5, 4 ] ); y[ idx ] = 5; @@ -826,7 +826,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Complex128Array( [ 9, 10, 9, 10, 5, 6, 7, 8 ] ); y[ idx ] = new Complex128Array( [ 9, 10 ] ); @@ -844,7 +844,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Complex128Array( [ 9, 10, 3, 4, 9, 10, 7, 8 ] ); y[ idx ] = new Complex128Array( [ 9, 10 ] ); @@ -880,7 +880,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Complex128Array( [ 9, 10, 9, 10, 5, 6, 7, 8 ] ); y[ idx ] = new Complex128( 9, 10 ); @@ -898,7 +898,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Complex128Array( [ 9, 10, 3, 4, 9, 10, 7, 8 ] ); y[ idx ] = new Complex128( 9, 10 ); @@ -934,7 +934,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Complex128Array( [ 9, 0, 9, 0, 5, 6, 7, 8 ] ); y[ idx ] = 9; @@ -952,7 +952,7 @@ tape( 'the function returns an array-like object supporting broadcasted integer x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Complex128Array( [ 9, 0, 3, 4, 9, 0, 7, 8 ] ); y[ idx ] = 9; @@ -988,7 +988,7 @@ tape( 'the function returns an array-like object supporting casting (generic, fl x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = [ 5, 6, 3, 4 ]; y[ idx ] = new Float64Array( [ 5, 6 ] ); @@ -1006,7 +1006,7 @@ tape( 'the function returns an array-like object supporting casting (generic, fl x = [ 1, 2, 3, 4 ]; y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = [ 5, 2, 6, 4 ]; y[ idx ] = new Float64Array( [ 5, 6 ] ); @@ -1042,7 +1042,7 @@ tape( 'the function returns an array-like object supporting casting (float64, fl x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Float64Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Float32Array( [ 5, 6 ] ); @@ -1060,7 +1060,7 @@ tape( 'the function returns an array-like object supporting casting (float64, fl x = new Float64Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Float64Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Float32Array( [ 5, 6 ] ); @@ -1096,7 +1096,7 @@ tape( 'the function returns an array-like object supporting casting (int32, int8 x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Int32Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Int8Array( [ 5, 6 ] ); @@ -1114,7 +1114,7 @@ tape( 'the function returns an array-like object supporting casting (int32, int8 x = new Int32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Int32Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Int8Array( [ 5, 6 ] ); @@ -1150,7 +1150,7 @@ tape( 'the function returns an array-like object supporting casting (uint32, uin x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Uint32Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Uint16Array( [ 5, 6 ] ); @@ -1168,7 +1168,7 @@ tape( 'the function returns an array-like object supporting casting (uint32, uin x = new Uint32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Uint32Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Uint16Array( [ 5, 6 ] ); @@ -1204,7 +1204,7 @@ tape( 'the function returns an array-like object supporting casting (complex128, x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Complex128Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); y[ idx ] = new Complex64Array( [ 17, 18, 19, 20 ] ); @@ -1222,7 +1222,7 @@ tape( 'the function returns an array-like object supporting casting (complex128, x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Complex128Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); y[ idx ] = new Complex64Array( [ 17, 18, 19, 20 ] ); @@ -1258,7 +1258,7 @@ tape( 'the function returns an array-like object supporting downcasting of float x = new Float32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Float32Array( [ 5, 6, 3, 4 ] ); y[ idx ] = new Float64Array( [ 5, 6 ] ); @@ -1276,7 +1276,7 @@ tape( 'the function returns an array-like object supporting downcasting of float x = new Float32Array( [ 1, 2, 3, 4 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Float32Array( [ 5, 2, 6, 4 ] ); y[ idx ] = new Float64Array( [ 5, 6 ] ); @@ -1312,7 +1312,7 @@ tape( 'the function returns an array-like object supporting downcasting of float x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 1 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 1 ] ) ); expected = new Complex64Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); @@ -1330,7 +1330,7 @@ tape( 'the function returns an array-like object supporting downcasting of float x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); y = array2fancy( x ); - idx = array2fancy.idx( [ 0, 2 ] ); + idx = array2fancy.idx( new Int32Array( [ 0, 2 ] ) ); expected = new Complex64Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); y[ idx ] = new Complex128Array( [ 17, 18, 19, 20 ] ); diff --git a/to-fancy/test/test.set.mask_array.js b/to-fancy/test/test.set.mask_array.js new file mode 100644 index 00000000..bb1d908e --- /dev/null +++ b/to-fancy/test/test.set.mask_array.js @@ -0,0 +1,1518 @@ +/** +* @license Apache-2.0 +* +* 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. +* 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 tape = require( 'tape' ); +var hasProxySupport = require( '@stdlib/assert/has-proxy-support' ); +var isSameComplex128Array = require( '@stdlib/assert/is-same-complex128array' ); +var isSameComplex64Array = require( '@stdlib/assert/is-same-complex64array' ); +var Complex128 = require( '@stdlib/complex/float64/ctor' ); +var Float64Array = require( './../../float64' ); +var Float32Array = require( './../../float32' ); +var Int32Array = require( './../../int32' ); +var Int8Array = require( './../../int8' ); +var Uint32Array = require( './../../uint32' ); +var Uint16Array = require( './../../uint16' ); +var Uint8Array = require( './../../uint8' ); +var Complex128Array = require( './../../complex128' ); +var Complex64Array = require( './../../complex64' ); +var toAccessorArray = require( './../../base/to-accessor-array' ); +var array2fancy = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': !hasProxySupport() +}; + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof array2fancy, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an array-like object supporting mask array assignment (generic)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = [ 5, 6, 7, 8 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = [ 5, 6, 3, 4 ]; + y[ idx ] = [ 5, 6, 0, 0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = [ 1, 5, 6, 4 ]; + y[ idx ] = [ 0, 5, 6, 0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = [ 5, 2, 6, 4 ]; + y[ idx ] = [ 5, 0, 6, 0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting mask array assignment ("unknown" dtype, accessor)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = [ 5, 6, 7, 8 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = [ 5, 6, 3, 4 ]; + y[ idx ] = [ 5, 6, 0, 0 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = [ 1, 5, 6, 4 ]; + y[ idx ] = [ 0, 5, 6, 0 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( toAccessorArray( x ) ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = [ 5, 2, 6, 4 ]; + y[ idx ] = [ 5, 0, 6, 0 ]; + + t.deepEqual( x, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting mask array assignment (int32)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Int32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Int32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Int32Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Int32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Int32Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Int32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Int32Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting mask array assignment (uint32)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Uint32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Uint32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Uint32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Uint32Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Uint32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Uint32Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Uint32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Uint32Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting mask array assignment (float64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Float64Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Float64Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Float64Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Float64Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Float64Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting mask array assignment (complex128)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + y[ idx ] = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Complex128Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20, 0, 0, 0, 0 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Complex128Array( [ 1, 2, 17, 18, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 0, 0, 17, 18, 19, 20, 0, 0 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Complex128Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 0, 0, 19, 20, 0, 0 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (generic, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = [ 5, 5, 5, 5 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = [ 5, 5, 3, 4 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = [ 1, 5, 5, 4 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = [ 5, 2, 5, 4 ]; + y[ idx ] = [ 5 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (generic, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = [ 5, 5, 5, 5 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = [ 5, 5, 3, 4 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = [ 1, 5, 5, 4 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = [ 5, 2, 5, 4 ]; + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (float64, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Float64Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Float64Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Float64Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Float64Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = new Float64Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (float64, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Float64Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Float64Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Float64Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Float64Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (int32, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Int32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Int32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Int32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Int32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( [ -1, -3 ] ); + expected = new Int32Array( [ 1, 5, 3, 5 ] ); + y[ idx ] = new Int32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (int32, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Int32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Int32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Int32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Int32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (uint32, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Uint32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Uint32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Uint32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Uint32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = new Uint32Array( [ 5 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (uint32, scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Uint32Array( [ 5, 5, 5, 5 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Uint32Array( [ 5, 5, 3, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Uint32Array( [ 1, 5, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Uint32Array( [ 5, 2, 5, 4 ] ); + y[ idx ] = 5; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (complex128, array)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Complex128Array( [ 9, 10, 9, 10, 9, 10, 9, 10 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Complex128Array( [ 9, 10, 9, 10, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Complex128Array( [ 1, 2, 9, 10, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Complex128Array( [ 9, 10, 3, 4, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 9, 10 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (complex128, complex scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Complex128Array( [ 9, 10, 9, 10, 9, 10, 9, 10 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Complex128Array( [ 9, 10, 9, 10, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Complex128Array( [ 1, 2, 9, 10, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Complex128Array( [ 9, 10, 3, 4, 9, 10, 7, 8 ] ); + y[ idx ] = new Complex128( 9, 10 ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting broadcasted mask array assignment (complex128, real scalar)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Complex128Array( [ 9, 0, 9, 0, 9, 0, 9, 0 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Complex128Array( [ 9, 0, 9, 0, 5, 6, 7, 8 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Complex128Array( [ 1, 2, 9, 0, 9, 0, 7, 8 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Complex128Array( [ 9, 0, 3, 4, 9, 0, 7, 8 ] ); + y[ idx ] = 9; + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (generic, float64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = new Float64Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = [ 5, 6, 3, 4 ]; + y[ idx ] = new Float64Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = [ 1, 5, 6, 4 ]; + y[ idx ] = new Float64Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = [ 5, 2, 6, 4 ]; + y[ idx ] = new Float64Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (float64, float32)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Float64Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Float32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Float64Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Float32Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Float64Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Float32Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Float64Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Float32Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (int32, int8)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Int8Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Int32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Int8Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Int32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Int8Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Int32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Int8Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (uint32, uint16)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Uint32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Uint16Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Uint32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Uint16Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Uint32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Uint16Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Uint32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Uint16Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting casting (complex128, complex64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + y[ idx ] = new Complex64Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Complex128Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex64Array( [ 17, 18, 19, 20, 0, 0, 0, 0 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Complex128Array( [ 1, 2, 17, 18, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex64Array( [ 0, 0, 17, 18, 19, 20, 0, 0 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Complex128Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex64Array( [ 17, 18, 0, 0, 19, 20, 0, 0 ] ); + + t.strictEqual( isSameComplex128Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting downcasting of floating-point arrays (float32, float64)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Float32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Float64Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Float32Array( [ 5, 6, 3, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 6, 0, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Float32Array( [ 1, 5, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 0, 5, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + x = new Float32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Float32Array( [ 5, 2, 6, 4 ] ); + y[ idx ] = new Float64Array( [ 5, 0, 6, 0 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object supporting downcasting of floating-point arrays (complex64, complex128)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ) ); + expected = new Complex64Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + y[ idx ] = new Complex128Array( [ 9, 10, 11, 12, 13, 14, 15, 16 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 1, 1 ] ) ); + expected = new Complex64Array( [ 17, 18, 19, 20, 5, 6, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 19, 20, 0, 0, 0, 0 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 1, 0, 0, 1 ] ) ); + expected = new Complex64Array( [ 1, 2, 17, 18, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 0, 0, 17, 18, 19, 20, 0, 0 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + x = new Complex64Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 1, 0, 1 ] ) ); + expected = new Complex64Array( [ 17, 18, 3, 4, 19, 20, 7, 8 ] ); + y[ idx ] = new Complex128Array( [ 17, 18, 0, 0, 19, 20, 0, 0 ] ); + + t.strictEqual( isSameComplex64Array( y, expected ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns an array-like object which throws an error when attempting to assign a broadcast-incompatible array (generic)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + [], + [ 5, 6 ], + [ 5, 6, 7 ], + [ 5, 6, 7, 8, 9 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to assign a broadcast-incompatible array (int32)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + new Int32Array( [] ), + new Int32Array( [ 5, 6 ] ), + new Int32Array( [ 5, 6, 7 ] ), + new Int32Array( [ 5, 6, 7, 8, 9 ] ) + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), Error, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (float64)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Float64Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + new Complex128Array( [ 5, 6 ] ), + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (complex128)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Complex128Array( [ 1, 2, 3, 4, 5, 6, 7, 8 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (int32)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + new Uint32Array( [ 1 ] ), + new Uint32Array( [ 5, 6, 7, 8 ] ), + new Float64Array( [ 1 ] ), + new Float64Array( [ 5, 6, 7, 8 ] ), + new Float32Array( [ 1 ] ), + new Float32Array( [ 5, 6, 7, 8 ] ), + new Complex128Array( [ 5, 6 ] ), + 3.14, + -3.14, + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (int8)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Int8Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + new Int32Array( [ 1 ] ), + new Int32Array( [ 5, 6, 7, 8 ] ), + new Float64Array( [ 1 ] ), + new Float64Array( [ 5, 6, 7, 8 ] ), + new Float32Array( [ 1 ] ), + new Float32Array( [ 5, 6, 7, 8 ] ), + new Complex128Array( [ 5, 6 ] ), + 999999, + 3.14, + -3.14, + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when attempting to perform an unsafe cast (uint32)', function test( t ) { + var values; + var idx; + var x; + var y; + var i; + + x = new Uint32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + + values = [ + new Int32Array( [ 1 ] ), + new Int32Array( [ 5, 6, 7, 8 ] ), + new Float64Array( [ 1 ] ), + new Float64Array( [ 5, 6, 7, 8 ] ), + new Float32Array( [ 1 ] ), + new Float32Array( [ 5, 6, 7, 8 ] ), + new Complex128Array( [ 5, 6 ] ), + -3, + 3.14, + -3.14, + new Complex128( 5, 6 ), + '5', + true, + false + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + + array2fancy.idx.free( idx ); + + t.end(); + + function badValue( value ) { + return function badValue() { + y[ idx ] = value; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when unable to resolve an index array (generic)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': false + }); + expected = [ 5, 6, 7, 8 ]; + y[ idx ] = [ 5, 6, 7, 8 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + + t.throws( badValue( idx ), Error, 'throws an error' ); + t.end(); + + function badValue( value ) { + return function badValue() { + y[ value ] = [ 9, 10, 11, 12 ]; + }; + } +}); + +tape( 'the function returns an array-like object which throws an error when unable to resolve an index array (typed)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': false + }); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + y[ idx ] = new Int32Array( [ 5, 6, 7, 8 ] ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.throws( badValue( idx ), Error, 'throws an error' ); + t.end(); + + function badValue( value ) { + return function badValue() { + y[ value ] = new Int32Array( [ 9, 10, 11, 12 ] ); + }; + } +}); + +tape( 'the function returns an array-like object which supports persisted index arrays (generic)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = [ 1, 2, 3, 4 ]; + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + expected = [ 5, 6, 7, 8 ]; + + y[ idx ] = [ 5, 6, 7, 8 ]; + t.deepEqual( y, expected, 'returns expected value' ); + + expected = [ 9, 10, 11, 12 ]; + + y[ idx ] = [ 9, 10, 11, 12 ]; + t.deepEqual( y, expected, 'returns expected value' ); + + array2fancy.idx.free( idx ); + + t.end(); +}); + +tape( 'the function returns an array-like object which supports persisted index arrays (typed)', opts, function test( t ) { + var expected; + var idx; + var x; + var y; + + x = new Int32Array( [ 1, 2, 3, 4 ] ); + y = array2fancy( x ); + + idx = array2fancy.idx( new Uint8Array( [ 0, 0, 0, 0 ] ), { + 'persist': true + }); + expected = new Int32Array( [ 5, 6, 7, 8 ] ); + + y[ idx ] = new Int32Array( [ 5, 6, 7, 8 ] ); + t.deepEqual( y, expected, 'returns expected value' ); + + expected = new Int32Array( [ 9, 10, 11, 12 ] ); + + y[ idx ] = new Int32Array( [ 9, 10, 11, 12 ] ); + t.deepEqual( y, expected, 'returns expected value' ); + + array2fancy.idx.free( idx ); + + t.end(); +});