diff --git a/CHANGELOG.md b/CHANGELOG.md index 04817dd7..8b113f14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -219,6 +219,28 @@ +
+ +#### [@stdlib/array/fixed-endian-float64](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/fixed-endian-float64) + +
+ +
+ +##### Features + +- [`9325d5f`](https://github.com/stdlib-js/stdlib/commit/9325d5fcb04b58b7405cc9fd387935d9707cfb0e) - add `array/fixed-endian-float64` + +
+ + + +
+ +
+ + + @@ -245,7 +267,11 @@ A total of 5 people contributed to this release. Thank you to the following cont
+- [`9325d5f`](https://github.com/stdlib-js/stdlib/commit/9325d5fcb04b58b7405cc9fd387935d9707cfb0e) - **feat:** add `array/fixed-endian-float64` _(by Athan Reines)_ - [`6e9f42e`](https://github.com/stdlib-js/stdlib/commit/6e9f42e4c912485d9896eaa16c88b70fd3688e97) - **docs:** harmonize list formatting in repl.txt and ensure starting newline _(by Philipp Burckhardt)_ +- [`6feb08f`](https://github.com/stdlib-js/stdlib/commit/6feb08f927a08bc7fbb29a721e04218cbd618200) - **style:** fix missing space _(by Athan Reines)_ +- [`988ba2c`](https://github.com/stdlib-js/stdlib/commit/988ba2c59bc5112d3c4e468245a69ce4ebe92109) - **docs:** fix example _(by Athan Reines)_ +- [`2faaf21`](https://github.com/stdlib-js/stdlib/commit/2faaf217eab865f9e40abbb0bf21b374595853e9) - **docs:** fix example _(by Athan Reines)_ - [`20dea8a`](https://github.com/stdlib-js/stdlib/commit/20dea8af2b14181aa75354f7e3aeb65b955904b9) - **docs:** remove extraneous newline _(by Athan Reines)_ - [`f387603`](https://github.com/stdlib-js/stdlib/commit/f387603e739f88a38af3263ce6ff675ad903ee8c) - **docs:** consistently use declarative instead of imperative sentences outside of intros _(by Philipp Burckhardt)_ - [`31fd427`](https://github.com/stdlib-js/stdlib/commit/31fd42744ec5d7073041f97c6f72350b8005c0fc) - **style:** remove unwanted empty lines _(by Philipp Burckhardt)_ diff --git a/bool/lib/main.js b/bool/lib/main.js index 965e4973..cf0ebe85 100644 --- a/bool/lib/main.js +++ b/bool/lib/main.js @@ -78,7 +78,7 @@ function isBooleanArray( value ) { * @returns {boolean} boolean indicating if a value is a boolean typed array constructor */ function isBooleanArrayConstructor( value ) { - return ( value === BooleanArray); + return ( value === BooleanArray ); } diff --git a/complex128/lib/index.js b/complex128/lib/index.js index 0e040a2d..90dee3a4 100644 --- a/complex128/lib/index.js +++ b/complex128/lib/index.js @@ -70,7 +70,7 @@ * // returns * * var len = arr.length; -* // returns 2 +* // returns 1 * * @example * var ArrayBuffer = require( '@stdlib/array/buffer' ); diff --git a/complex64/lib/index.js b/complex64/lib/index.js index 232abcc3..1e9841f3 100644 --- a/complex64/lib/index.js +++ b/complex64/lib/index.js @@ -59,7 +59,7 @@ * // returns * * var len = arr.length; -* // returns 2 +* // returns 1 * * @example * var ArrayBuffer = require( '@stdlib/array/buffer' ); diff --git a/fixed-endian-float64/README.md b/fixed-endian-float64/README.md new file mode 100644 index 00000000..f2ea710c --- /dev/null +++ b/fixed-endian-float64/README.md @@ -0,0 +1,445 @@ + + +# Float64ArrayFE + +> Typed array constructor which returns a typed array representing an array of double-precision floating-point numbers in a specified byte order. + + + +
+ +In contrast to the [`Float64Array`][@stdlib/array/float64] typed array constructor which stores values according to the platform byte order, the `Float64ArrayFE` constructor allows enforcing a specific byte order. Such enforcement can be particularly advantageous when working with memory buffers which do not necessarily follow host byte order, such as [WebAssembly memory][@stdlib/wasm/memory]. + +
+ + + + + +
+ +## Usage + +```javascript +var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +``` + +#### Float64ArrayFE( endianness ) + +A typed array constructor which returns a typed array representing an array of double-precision floating-point numbers in a specified byte order. + +```javascript +var arr = new Float64ArrayFE( 'little-endian' ); +// returns +``` + +#### Float64ArrayFE( endianness, length ) + +Returns a typed array having a specified length and byte order. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 5 ); +// returns +``` + +#### Float64ArrayFE( endianness, typedarray ) + +Creates a typed array from another typed array. + +```javascript +var Float32Array = require( '@stdlib/array/float32' ); + +var arr1 = new Float32Array( [ 0.5, 0.5, 0.5 ] ); +var arr2 = new Float64ArrayFE( 'little-endian', arr1 ); +// returns + +var v = arr2.get( 0 ); +// returns 0.5 +``` + +#### Float64ArrayFE( endianness, obj ) + +Creates a typed array from an array-like object or iterable. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', [ 0.5, 0.5, 0.5 ] ); +// returns + +var v = arr.get( 0 ); +// returns 0.5 +``` + +#### Float64ArrayFE( endianness, buffer\[, byteOffset\[, length]] ) + +Returns a typed array view of an [`ArrayBuffer`][@stdlib/array/buffer]. + +```javascript +var ArrayBuffer = require( '@stdlib/array/buffer' ); + +var buf = new ArrayBuffer( 32 ); +var arr = new Float64ArrayFE( 'little-endian', buf, 0, 4 ); +// returns +``` + +* * * + +### Properties + + + +#### Float64ArrayFE.BYTES_PER_ELEMENT + +Number of bytes per view element. + +```javascript +var nbytes = Float64ArrayFE.BYTES_PER_ELEMENT; +// returns 8 +``` + + + +#### Float64ArrayFE.name + +Typed array constructor name. + +```javascript +var str = Float64ArrayFE.name; +// returns 'Float64ArrayFE' +``` + + + +#### Float64ArrayFE.prototype.buffer + +**Read-only** property which returns the [`ArrayBuffer`][@stdlib/array/buffer] referenced by the typed array. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 5 ); +var buf = arr.buffer; +// returns +``` + + + +#### Float64ArrayFE.prototype.byteLength + +**Read-only** property which returns the length (in bytes) of the typed array. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 5 ); +var byteLength = arr.byteLength; +// returns 40 +``` + + + +#### Float64ArrayFE.prototype.byteOffset + +**Read-only** property which returns the offset (in bytes) of the typed array from the start of its [`ArrayBuffer`][@stdlib/array/buffer]. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 5 ); +var byteOffset = arr.byteOffset; +// returns 0 +``` + + + +#### Float64ArrayFE.prototype.BYTES_PER_ELEMENT + +Number of bytes per view element. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 5 ); +var nbytes = arr.BYTES_PER_ELEMENT; +// returns 8 +``` + + + +#### Float64ArrayFE.prototype.length + +**Read-only** property which returns the number of view elements. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 5 ); +var len = arr.length; +// returns 5 +``` + +* * * + +### Methods + + + +#### Float64ArrayFE.from( endianness, src\[, map\[, thisArg]] ) + +Creates a new typed array from an array-like object or an iterable. + +```javascript +var arr = Float64ArrayFE.from( 'little-endian', [ 1.0, -1.0 ] ); +// returns + +var v = arr.get( 0 ); +// returns 1.0 +``` + +To invoke a function for each `src` value, provide a callback function. + +```javascript +function mapFcn( v ) { + return v * 2.0; +} + +var arr = Float64ArrayFE.from( 'little-endian', [ 1.0, -1.0 ], mapFcn ); +// returns + +var v = arr.get( 0 ); +// returns 2.0 +``` + +A callback function is provided two arguments: + +- **value**: source value. +- **index**: source index. + +To set the callback execution context, provide a `thisArg`. + +```javascript +function mapFcn( v ) { + this.count += 1; + return v * 2.0; +} + +var ctx = { + 'count': 0 +}; + +var arr = Float64ArrayFE.from( 'little-endian', [ 1.0, -1.0 ], mapFcn, ctx ); +// returns + +var v = arr.get( 0 ); +// returns 2.0 + +var n = ctx.count; +// returns 2 +``` + + + +#### Float64ArrayFE.of( endianness, element0\[, element1\[, ...elementN]] ) + +Creates a new typed array from a variable number of arguments. + +```javascript +var arr = Float64ArrayFE.of( 'little-endian', 1.0, -1.0 ); +// returns + +var v = arr.get( 0 ); +// returns 1.0 +``` + + + +#### Float64ArrayFE.prototype.get( i ) + +Returns an array element located at a nonnegative integer position (index) `i`. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 10 ); + +// Set the first element: +arr.set( 1.0, 0 ); + +// Get the first element: +var v = arr.get( 0 ); +// returns 1.0 +``` + +If provided an out-of-bounds index, the method returns `undefined`. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', 10 ); + +var v = arr.get( 100 ); +// returns undefined +``` + + + +#### Float64ArrayFE.prototype.set( arr\[, offset] ) + +Sets array elements. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0, 3.0 ] ); +// returns + +var v = arr.get( 0 ); +// returns 1.0 + +v = arr.get( 1 ); +// returns 2.0 + +// Set the first two array elements: +arr.set( [ 4.0, 5.0 ] ); + +v = arr.get( 0 ); +// returns 4.0 + +v = arr.get( 1 ); +// returns 5.0 +``` + +By default, the method starts writing values at the first array index. To specify an alternative index, provide an index `offset`. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0, 3.0 ] ); +// returns + +// Set the last two array elements: +arr.set( [ 4.0, 5.0 ], 1 ); + +var v = arr.get( 1 ); +// returns 4.0 + +v = arr.get( 2 ); +// returns 5.0 +``` + +A few notes: + +- If `i` is out-of-bounds, the method throws an error. +- If a target array cannot accommodate all values (i.e., the length of source array plus `i` exceeds the target array length), the method throws an error. +- If provided a typed array which shares an [`ArrayBuffer`][@stdlib/array/buffer] with the target array, the method will intelligently copy the source range to the destination range. + + + +#### Float64ArrayFE.prototype.toString() + +Serializes an array as a string. + +```javascript +var arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0, 3.0 ] ); + +var str = arr.toString(); +// returns '1,2,3' +``` + +
+ + + +* * * + + + +
+ +* * * + +## Notes + +- The constructor supports the following byte orders: + + - **little-endian**: store values such that bytes are stored from least-to-most significant bytes. This is the dominant ordering for processor architectures and their associated memory. This is also the ordering for [WebAssembly memory][@stdlib/wasm/memory]. + - **big-endian**: store values such that bytes are stored from most-to-least significant bytes. This is the dominant ordering in network protocols. + +- While a `Float64ArrayFE` _strives_ to maintain (but does not **guarantee**) consistency with [typed arrays][@stdlib/array/typed], significant deviations from ECMAScript-defined [typed array][@stdlib/array/typed] behavior are as follows: + + - The constructor does **not** require the `new` operator. + - Accessing array elements using bracket syntax (e.g., `X[i]`) is **not** supported. Instead, one **must** use the `.get()` method. + +
+ + + + + +
+ +* * * + +## Examples + + + +```javascript +var Float64Array = require( '@stdlib/array/float64' ); +var logEach = require( '@stdlib/console/log-each' ); +var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); + +// Create a typed array by specifying a length: +var out = new Float64ArrayFE( 'little-endian', 3 ); +logEach( '%s', out ); + +// Create a typed array from an array: +var arr = [ 1.0, -1.0, -3.14, 3.14, 0.5, 0.5 ]; +out = new Float64ArrayFE( 'big-endian', arr ); +logEach( '%s', out ); + +// Create a typed array from an array buffer: +arr = new Float64Array( [ 1.0, -1.0, -3.14, 3.14, 0.5, 0.5 ] ); // host byte order +out = new Float64ArrayFE( 'little-endian', arr.buffer ); +logEach( '%s', out ); + +// Create a typed array from an array buffer view: +arr = new Float64Array( [ 1.0, -1.0, -3.14, 3.14, 0.5, 0.5 ] ); // host byte order +out = new Float64ArrayFE( 'big-endian', arr.buffer, 8, 2 ); +logEach( '%s', out ); +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/fixed-endian-float64/benchmark/benchmark.from.js b/fixed-endian-float64/benchmark/benchmark.from.js new file mode 100644 index 00000000..62c07c39 --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.from.js @@ -0,0 +1,310 @@ +/** +* @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 Float64Array = require( './../../float64' ); +var ITERATOR_SYMBOL = require( '@stdlib/symbol/iterator' ); +var pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': ( ITERATOR_SYMBOL === null ) +}; + + +// MAIN // + +bench( pkg+'::typed_array:from', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Float64Array( 'little-endian', 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Float64Array( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', buf ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array,clbk:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Float64Array( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', buf, clbk ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function clbk( v ) { + return v * 2.0; + } +}); + +bench( pkg+'::array:from', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = []; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', buf ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array,clbk:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', buf, clbk ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function clbk( v ) { + return v * 2.0; + } +}); + +bench( pkg+'::iterable:from', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', createIterable() ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + return { + 'next': next + }; + } + + function next() { + return { + 'done': true + }; + } + } +}); + +bench( pkg+'::iterable:from:len=5', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', createIterable() ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + var it = { + 'next': next, + 'i': 0, + 'N': 5 + }; + return it; + + function next() { + it.i += 1; + if ( it.i <= it.N ) { + return { + 'value': 1.0 + }; + } + return { + 'done': true + }; + } + } + } +}); + +bench( pkg+'::iterable,clbk:from:len=5', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.from( 'little-endian', createIterable(), clbk ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + var it = { + 'next': next, + 'i': 0, + 'N': 5 + }; + return it; + + function next() { + it.i += 1; + if ( it.i <= it.N ) { + return { + 'value': 1.0 + }; + } + return { + 'done': true + }; + } + } + } + + function clbk( v ) { + return v * 2.0; + } +}); diff --git a/fixed-endian-float64/benchmark/benchmark.get.js b/fixed-endian-float64/benchmark/benchmark.get.js new file mode 100644 index 00000000..5ac1002f --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.get.js @@ -0,0 +1,85 @@ +/** +* @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 isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// MAIN // + +bench( pkg+':get:endianness=little-endian', function benchmark( b ) { + var arr; + var N; + var v; + var i; + + arr = []; + for ( i = 0; i < 10; i++ ) { + arr.push( i ); + } + arr = new Float64ArrayFE( 'little-endian', arr ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.get( i%N ); + if ( typeof v !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isNumber( v ) ) { + b.fail( 'should return a number' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':get:endianness=big-endian', function benchmark( b ) { + var arr; + var N; + var v; + var i; + + arr = []; + for ( i = 0; i < 10; i++ ) { + arr.push( i ); + } + arr = new Float64ArrayFE( 'big-endian', arr ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.get( i%N ); + if ( typeof v !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isNumber( v ) ) { + b.fail( 'should return a number' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/fixed-endian-float64/benchmark/benchmark.js b/fixed-endian-float64/benchmark/benchmark.js new file mode 100644 index 00000000..3c4838ff --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.js @@ -0,0 +1,533 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 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 ArrayBuffer = require( './../../buffer' ); +var Float64Array = require( './../../float64' ); +var isArrayBuffer = require( '@stdlib/assert/is-arraybuffer' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var ITERATOR_SYMBOL = require( '@stdlib/symbol/iterator' ); +var pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': ( ITERATOR_SYMBOL === null ) +}; + + +// FUNCTIONS // + +/** +* Returns an "iterable" object. +* +* @private +* @returns {Object} iterable object +*/ +function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + return { + 'next': next + }; + } + + function next() { + return { + 'done': true + }; + } +} + + +// MAIN // + +bench( pkg+'::instantiation,new:endianness=little-endian', function benchmark( b ) { + var arr; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian' ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,new:endianness=big-endian', function benchmark( b ) { + var arr; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian' ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,no_new:endianness=little-endian', function benchmark( b ) { + var ctor; + var arr; + var i; + + ctor = Float64ArrayFE; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = ctor( 'little-endian' ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,no_new:endianness=big-endian', function benchmark( b ) { + var ctor; + var arr; + var i; + + ctor = Float64ArrayFE; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = ctor( 'big-endian' ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,length:endianness=little-endian', function benchmark( b ) { + var arr; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', 0 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,length:endianness=big-endian', function benchmark( b ) { + var arr; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', 0 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,typed_array:endianness=little-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Float64Array( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,typed_array:endianness=big-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Float64Array( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,array:endianness=little-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = []; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,array:endianness=big-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = []; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,iterable:endianness=little-endian', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', createIterable() ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,iterable:endianness=big-endian', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', createIterable() ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer:endianness=little-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer:endianness=big-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer,byte_offset:endianness=little-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 8 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', buf, 8 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer,byte_offset:endianness=big-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 8 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', buf, 8 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer,byte_offset,length:endianness=little-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 8 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'little-endian', buf, 8, 0 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer,byte_offset,length:endianness=big-endian', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 8 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new Float64ArrayFE( 'big-endian', buf, 8, 0 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:buffer', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new Float64ArrayFE( 'little-endian' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.buffer; + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isArrayBuffer( v ) ) { + b.fail( 'should return an ArrayBuffer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:byteLength', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new Float64ArrayFE( 'little-endian' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.byteLength; + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( v ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:byteOffset', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new Float64ArrayFE( 'little-endian' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.byteOffset; + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( v ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:length', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new Float64ArrayFE( 'little-endian' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.length; + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( v ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/fixed-endian-float64/benchmark/benchmark.of.js b/fixed-endian-float64/benchmark/benchmark.of.js new file mode 100644 index 00000000..2222d5c8 --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.of.js @@ -0,0 +1,69 @@ +/** +* @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 pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// MAIN // + +bench( pkg+':of', function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.of( 'little-endian' ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = [ 'little-endian', 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = Float64ArrayFE.of.apply( Float64ArrayFE, buf ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof Float64ArrayFE) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/fixed-endian-float64/benchmark/benchmark.set.js b/fixed-endian-float64/benchmark/benchmark.set.js new file mode 100644 index 00000000..2cb98412 --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.set.js @@ -0,0 +1,209 @@ +/** +* @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 Float64Array = require( './../../float64' ); +var pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::number:set:endianness=little-endian', function benchmark( b ) { + var values; + var arr; + var N; + var v; + var i; + + values = []; + for ( i = 0; i < 10; i++ ) { + values.push( i ); + } + arr = new Float64ArrayFE( 'little-endian', values ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.set( values[ (i+1)%N ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::number:set:endianness=big-endian', function benchmark( b ) { + var values; + var arr; + var N; + var v; + var i; + + values = []; + for ( i = 0; i < 10; i++ ) { + values.push( i ); + } + arr = new Float64ArrayFE( 'big-endian', values ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.set( values[ (i+1)%N ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array:set:endianness=little-endian', function benchmark( b ) { + var values; + var arr; + var N; + var v; + var i; + + values = []; + for ( i = 0; i < 10; i++ ) { + values.push( i ); + } + arr = new Float64ArrayFE( 'little-endian', values ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.set( [ values[ (i+1)%N ] ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array:set:endianness=big-endian', function benchmark( b ) { + var values; + var arr; + var N; + var v; + var i; + + values = []; + for ( i = 0; i < 10; i++ ) { + values.push( i ); + } + arr = new Float64ArrayFE( 'big-endian', values ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.set( [ values[ (i+1)%N ] ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array:set:endianness=little-endian', function benchmark( b ) { + var values; + var arr; + var buf; + var N; + var v; + var i; + + values = new Float64Array( 20 ); + N = values.length; + for ( i = 0; i < N; i++ ) { + values[ i ] = i; + } + arr = new Float64ArrayFE( 'little-endian', values ); + buf = new Float64Array( 1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buf[ 0 ] = values[ i%N ]; + v = arr.set( buf ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array:set:endianness=big-endian', function benchmark( b ) { + var values; + var arr; + var buf; + var N; + var v; + var i; + + values = new Float64Array( 20 ); + N = values.length; + for ( i = 0; i < N; i++ ) { + values[ i ] = i; + } + arr = new Float64ArrayFE( 'big-endian', values ); + buf = new Float64Array( 1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buf[ 0 ] = values[ i%N ]; + v = arr.set( buf ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/fixed-endian-float64/benchmark/benchmark.set.length.js b/fixed-endian-float64/benchmark/benchmark.set.length.js new file mode 100644 index 00000000..5848832e --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.set.length.js @@ -0,0 +1,110 @@ +/** +* @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 randu = require( '@stdlib/random/array/randu' ); +var pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - array length +* @returns {Function} benchmark function +*/ +function createBenchmark( len ) { + var values; + var arr1; + var arr2; + var arr3; + var N; + + arr1 = randu( len ); + arr2 = randu( len ); + arr3 = randu( len ); + arr1 = new Float64ArrayFE( 'little-endian', arr1 ); + + values = [ + new Float64ArrayFE( 'little-endian', arr2 ), + new Float64ArrayFE( 'big-endian', arr3 ) + ]; + N = values.length; + + 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 = arr1.set( values[ i%N ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + 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+':set:len='+len, f ); + } +} + +main(); diff --git a/fixed-endian-float64/benchmark/benchmark.to_string.js b/fixed-endian-float64/benchmark/benchmark.to_string.js new file mode 100644 index 00000000..f042a11e --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.to_string.js @@ -0,0 +1,50 @@ +/** +* @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 pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// MAIN // + +bench( pkg+':toString', function benchmark( b ) { + var out; + var arr; + var i; + + arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0, 2.0, 1.0 ] ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = arr.toString(); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/fixed-endian-float64/benchmark/benchmark.to_string.length.js b/fixed-endian-float64/benchmark/benchmark.to_string.length.js new file mode 100644 index 00000000..89e570b2 --- /dev/null +++ b/fixed-endian-float64/benchmark/benchmark.to_string.length.js @@ -0,0 +1,94 @@ +/** +* @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 zeroTo = require( './../../zero-to' ); +var pkg = require( './../package.json' ).name; +var Float64ArrayFE = require( './../lib' ); + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - array length +* @returns {Function} benchmark function +*/ +function createBenchmark( len ) { + var arr = new Float64ArrayFE( 'little-endian', zeroTo( len ) ); + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var out; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = arr.toString(); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + 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+':toString:len='+len, f ); + } +} + +main(); diff --git a/fixed-endian-float64/examples/index.js b/fixed-endian-float64/examples/index.js new file mode 100644 index 00000000..632c5e32 --- /dev/null +++ b/fixed-endian-float64/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 Float64Array = require( './../../float64' ); +var logEach = require( '@stdlib/console/log-each' ); +var Float64ArrayFE = require( './../lib' ); + +// Create a typed array by specifying a length: +var out = new Float64ArrayFE( 'little-endian', 3 ); +logEach( '%s', out ); + +// Create a typed array from an array: +var arr = [ 1.0, -1.0, -3.14, 3.14, 0.5, 0.5 ]; +out = new Float64ArrayFE( 'big-endian', arr ); +logEach( '%s', out ); + +// Create a typed array from an array buffer: +arr = new Float64Array( [ 1.0, -1.0, -3.14, 3.14, 0.5, 0.5 ] ); // host byte order +out = new Float64ArrayFE( 'little-endian', arr.buffer ); +logEach( '%s', out ); + +// Create a typed array from an array buffer view: +arr = new Float64Array( [ 1.0, -1.0, -3.14, 3.14, 0.5, 0.5 ] ); // host byte order +out = new Float64ArrayFE( 'big-endian', arr.buffer, 8, 2 ); +logEach( '%s', out ); diff --git a/fixed-endian-float64/lib/from_array.js b/fixed-endian-float64/lib/from_array.js new file mode 100644 index 00000000..c8cfb23f --- /dev/null +++ b/fixed-endian-float64/lib/from_array.js @@ -0,0 +1,46 @@ +/** +* @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'; + +// MAIN // + +/** +* Fills an output DataView with double-precision values. +* +* @private +* @param {DataView} view - output data view +* @param {Array} arr - input array +* @param {boolean} isLE - boolean indicating whether the store values in little-endian byte order +* @returns {DataView} output data view +*/ +function fromArray( view, arr, isLE ) { + var len; + var i; + + len = arr.length; + for ( i = 0; i < len; i++ ) { + view.setFloat64( i*8, arr[ i ], isLE ); // FIXME: handle accessor arrays, FIXME: avoid hardcoding bytes per element + } + return view; +} + + +// EXPORTS // + +module.exports = fromArray; diff --git a/fixed-endian-float64/lib/from_iterator.js b/fixed-endian-float64/lib/from_iterator.js new file mode 100644 index 00000000..c1adb5d9 --- /dev/null +++ b/fixed-endian-float64/lib/from_iterator.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'; + +// MAIN // + +/** +* Returns an array of iterated values. +* +* @private +* @param {Object} it - iterator +* @returns {Array} output array +*/ +function fromIterator( it ) { + var out; + var v; + + out = []; + while ( true ) { + v = it.next(); + if ( v.done ) { + break; + } + out.push( v.value ); + } + return out; +} + + +// EXPORTS // + +module.exports = fromIterator; diff --git a/fixed-endian-float64/lib/from_iterator_map.js b/fixed-endian-float64/lib/from_iterator_map.js new file mode 100644 index 00000000..9a6e354e --- /dev/null +++ b/fixed-endian-float64/lib/from_iterator_map.js @@ -0,0 +1,53 @@ +/** +* @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'; + +// MAIN // + +/** +* Returns an array of iterated values. +* +* @private +* @param {Object} it - iterator +* @param {Function} clbk - callback to invoke for each iterated value +* @param {*} thisArg - invocation context +* @returns {Array} output array +*/ +function fromIteratorMap( it, clbk, thisArg ) { + var out; + var v; + var i; + + out = []; + i = -1; + while ( true ) { + v = it.next(); + if ( v.done ) { + break; + } + i += 1; + out.push( clbk.call( thisArg, v.value, i ) ); + } + return out; +} + + +// EXPORTS // + +module.exports = fromIteratorMap; diff --git a/fixed-endian-float64/lib/index.js b/fixed-endian-float64/lib/index.js new file mode 100644 index 00000000..a4841f91 --- /dev/null +++ b/fixed-endian-float64/lib/index.js @@ -0,0 +1,94 @@ +/** +* @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'; + +/** +* Typed array constructor which returns a typed array representing an array of double-precision floating-point numbers in a specified byte order. +* +* @module @stdlib/array/fixed-endian-float64 +* +* @example +* var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +* +* var arr = new Float64ArrayFE( 'little-endian' ); +* // returns +* +* var len = arr.length; +* // returns 0 +* +* @example +* var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +* +* var arr = new Float64ArrayFE( 'little-endian', 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +* +* var arr = new Float64ArrayFE( 'little-endian', [ 1.0 ] ); +* // returns +* +* var len = arr.length; +* // returns 1 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new Float64ArrayFE( 'little-endian', buf ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new Float64ArrayFE( 'little-endian', buf, 8 ); +* // returns +* +* var len = arr.length; +* // returns 1 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* var Float64ArrayFE = require( '@stdlib/array/fixed-endian-float64' ); +* +* var buf = new ArrayBuffer( 32 ); +* var arr = new Float64ArrayFE( 'little-endian', buf, 8, 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/fixed-endian-float64/lib/main.js b/fixed-endian-float64/lib/main.js new file mode 100644 index 00000000..6eaca081 --- /dev/null +++ b/fixed-endian-float64/lib/main.js @@ -0,0 +1,708 @@ +/** +* @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. +*/ + +/* eslint-disable max-len, no-restricted-syntax, no-invalid-this */ + +'use strict'; + +// MODULES // + +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var isCollection = require( '@stdlib/assert/is-collection' ); +var isArrayBuffer = require( '@stdlib/assert/is-arraybuffer' ); +var isObject = require( '@stdlib/assert/is-object' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var contains = require( './../../base/assert/contains' ).factory; +var lowercase = require( '@stdlib/string/base/lowercase' ); +var hasIteratorSymbolSupport = require( '@stdlib/assert/has-iterator-symbol-support' ); +var ITERATOR_SYMBOL = require( '@stdlib/symbol/iterator' ); +var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var setReadOnlyAccessor = require( '@stdlib/utils/define-nonenumerable-read-only-accessor' ); +var ArrayBuffer = require( './../../buffer' ); +var DataView = require( './../../dataview' ); +var getter = require( './../../base/getter' ); +var accessorGetter = require( './../../base/accessor-getter' ); +var format = require( '@stdlib/string/format' ); +var fromIterator = require( './from_iterator.js' ); +var fromIteratorMap = require( './from_iterator_map.js' ); +var fromArray = require( './from_array.js' ); + + +// VARIABLES // + +var BYTES_PER_ELEMENT = 8; // 8 bytes per double +var HAS_ITERATOR_SYMBOL = hasIteratorSymbolSupport(); +var isByteOrder = contains( [ 'little-endian', 'big-endian' ] ); + + +// FUNCTIONS // + +/** +* Normalizes a byte order value. +* +* @private +* @param {*} value - byte order +* @returns {(string|null)} normalized byte order +*/ +function byteOrder( value ) { + return ( isString( value ) ) ? lowercase( value ) : null; +} + +/** +* Tests whether a provided byte order is little-endian byte order. +* +* @private +* @param {string} value - byte order +* @returns {boolean} boolean indicating whether a byte order is little-endian byte order +*/ +function isLittleEndian( value ) { + return ( value === 'little-endian' ); +} + +/** +* Returns a boolean indicating if a value is a `Float64ArrayFE` constructor. +* +* @private +* @param {*} value - value to test +* @returns {boolean} boolean indicating if a value is a `Float64ArrayFE` constructor +*/ +function isFloat64ArrayFEConstructor( value ) { // eslint-disable-line id-length + return ( value === Float64ArrayFE ); +} + +/** +* Returns a boolean indicating if a value is a `Float64ArrayFE`. +* +* @private +* @param {*} value - value to test +* @returns {boolean} boolean indicating if a value is a `Float64ArrayFE` +*/ +function isFloat64ArrayFE( value ) { + return ( + typeof value === 'object' && + value !== null && + value.constructor.name === 'Float64ArrayFE' && + value.BYTES_PER_ELEMENT === BYTES_PER_ELEMENT + ); +} + + +// MAIN // + +/** +* Typed array constructor which returns a typed array representing an array of double-precision floating-point numbers in a specified byte order. +* +* @constructor +* @param {string} endianness - byte order +* @param {(NonNegativeInteger|Collection|ArrayBuffer|Iterable)} [arg] - length, typed array, array-like object, buffer, or an iterable +* @param {NonNegativeInteger} [byteOffset=0] - byte offset +* @param {NonNegativeInteger} [length] - view length +* @throws {TypeError} first argument must be a supported byte order +* @throws {TypeError} if provided only two arguments, the second argument must be a valid argument +* @throws {TypeError} byte offset must be a nonnegative integer +* @throws {RangeError} must provide sufficient memory to accommodate byte offset and view length requirements +* @returns {Float64ArrayFE} typed array instance +* +* @example +* var arr = new Float64ArrayFE( 'little-endian' ); +* // returns +* +* var len = arr.length; +* // returns 0 +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0 ] ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new Float64ArrayFE( 'little-endian', buf ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new Float64ArrayFE( 'little-endian', buf, 8 ); +* // returns +* +* var len = arr.length; +* // returns 1 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* +* var buf = new ArrayBuffer( 32 ); +* var arr = new Float64ArrayFE( 'little-endian', buf, 8, 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +*/ +function Float64ArrayFE() { + var byteOffset; + var endianness; + var nargs; + var isLE; + var buf; + var len; + var arg; + var tmp; + + nargs = arguments.length; + if ( !(this instanceof Float64ArrayFE) ) { + if ( nargs < 2 ) { + return new Float64ArrayFE( arguments[0] ); + } + if ( nargs === 2 ) { + return new Float64ArrayFE( arguments[0], arguments[1] ); + } + if ( nargs === 3 ) { + return new Float64ArrayFE( arguments[0], arguments[1], arguments[2] ); + } + return new Float64ArrayFE( arguments[0], arguments[1], arguments[2], arguments[3] ); + } + endianness = byteOrder( arguments[ 0 ] ); + if ( endianness === null || !isByteOrder( endianness ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a supported byte order. Value: `%s`.', arguments[ 0 ] ) ); + } + isLE = isLittleEndian( endianness ); + + nargs -= 1; + + // Create the underlying data buffer... + if ( nargs === 0 ) { + buf = new DataView( new ArrayBuffer( 0 ) ); // backward-compatibility + } else if ( nargs === 1 ) { + arg = arguments[ nargs ]; + if ( isNonNegativeInteger( arg ) ) { + buf = new DataView( new ArrayBuffer( arg*BYTES_PER_ELEMENT ) ); + } else if ( isCollection( arg ) ) { + buf = fromArray( new DataView( new ArrayBuffer( arg.length*BYTES_PER_ELEMENT ) ), arg, isLE ); + } else if ( isArrayBuffer( arg ) ) { + buf = new DataView( arg ); + } else if ( isObject( arg ) ) { + if ( HAS_ITERATOR_SYMBOL === false ) { + throw new TypeError( format( 'invalid argument. Environment lacks Symbol.iterator support. Must provide a length, ArrayBuffer, typed array, or array-like object. Value: `%s`.', arg ) ); + } + if ( !isFunction( arg[ ITERATOR_SYMBOL ] ) ) { + throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', arg ) ); + } + buf = arg[ ITERATOR_SYMBOL ](); + if ( !isFunction( buf.next ) ) { + throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', arg ) ); + } + tmp = fromIterator( buf ); + buf = fromArray( new DataView( new ArrayBuffer( tmp.length*BYTES_PER_ELEMENT ) ), tmp, isLE ); + } else { + throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', arg ) ); + } + } else { + buf = arguments[ 1 ]; + if ( !isArrayBuffer( buf ) ) { + throw new TypeError( format( 'invalid argument. First argument must be an ArrayBuffer. Value: `%s`.', buf ) ); + } + byteOffset = arguments[ 2 ]; + if ( !isNonNegativeInteger( byteOffset ) ) { + throw new TypeError( format( 'invalid argument. Byte offset must be a nonnegative integer. Value: `%s`.', byteOffset ) ); + } + if ( nargs === 2 ) { + buf = new DataView( buf, byteOffset ); + } else { + len = arguments[ 3 ]; + if ( !isNonNegativeInteger( len ) ) { + throw new TypeError( format( 'invalid argument. Length must be a nonnegative integer. Value: `%s`.', len ) ); + } + len *= BYTES_PER_ELEMENT; + if ( len > (buf.byteLength-byteOffset) ) { + throw new RangeError( format( 'invalid arguments. ArrayBuffer has insufficient capacity. Either decrease the array length or provide a bigger buffer. Minimum capacity: `%u`.', len ) ); + } + buf = new DataView( buf, byteOffset, len ); + } + } + setReadOnly( this, '_buffer', buf ); + setReadOnly( this, '_length', buf.byteLength/BYTES_PER_ELEMENT ); + setReadOnly( this, '_isLE', isLE ); + + return this; +} + +/** +* Size (in bytes) of each array element. +* +* @name BYTES_PER_ELEMENT +* @memberof Float64ArrayFE +* @readonly +* @type {PositiveInteger} +* @default 8 +* +* @example +* var nbytes = Float64ArrayFE.BYTES_PER_ELEMENT; +* // returns 8 +*/ +setReadOnly( Float64ArrayFE, 'BYTES_PER_ELEMENT', BYTES_PER_ELEMENT ); + +/** +* Constructor name. +* +* @name name +* @memberof Float64ArrayFE +* @readonly +* @type {string} +* @default 'Float64ArrayFE' +* +* @example +* var str = Float64ArrayFE.name; +* // returns 'Float64ArrayFE' +*/ +setReadOnly( Float64ArrayFE, 'name', 'Float64ArrayFE' ); + +/** +* Creates a new `Float64ArrayFE` from an array-like object or an iterable. +* +* @name from +* @memberof Float64ArrayFE +* @type {Function} +* @param {string} endianness - byte order +* @param {(Collection|Iterable)} src - array-like object or iterable +* @param {Function} [clbk] - callback to invoke for each source element +* @param {*} [thisArg] - context +* @throws {TypeError} `this` context must be a constructor +* @throws {TypeError} `this` must be a Float64ArrayFE +* @throws {TypeError} first argument must be a supported byte order +* @throws {TypeError} second argument must be an array-like object or an iterable +* @throws {TypeError} third argument must be a function +* @returns {Float64ArrayFE} typed array instance +* +* @example +* var arr = Float64ArrayFE.from( 'little-endian', [ 1.0, 2.0 ] ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* function clbk( v ) { +* return v * 2.0; +* } +* +* var arr = Float64ArrayFE.from( 'big-endian', [ 1.0, 2.0 ], clbk ); +* // returns +* +* var len = arr.length; +* // returns 2 +*/ +setReadOnly( Float64ArrayFE, 'from', function from( endianness, src ) { + var thisArg; + var order; + var nargs; + var clbk; + var isLE; + var out; + var buf; + var tmp; + var get; + var len; + var i; + if ( !isFunction( this ) ) { + throw new TypeError( 'invalid invocation. `this` context must be a constructor.' ); + } + if ( !isFloat64ArrayFEConstructor( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a Float64ArrayFE.' ); + } + order = byteOrder( endianness ); + if ( order === null || !isByteOrder( order ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a supported byte order. Value: `%s`.', endianness ) ); + } + isLE = isLittleEndian( order ); + + nargs = arguments.length; + if ( nargs > 2 ) { + clbk = arguments[ 2 ]; + if ( !isFunction( clbk ) ) { + throw new TypeError( format( 'invalid argument. Third argument must be a function. Value: `%s`.', clbk ) ); + } + if ( nargs > 3 ) { + thisArg = arguments[ 3 ]; + } + } + if ( isCollection( src ) ) { + if ( clbk ) { + len = src.length; + if ( src.get && src.set ) { + get = accessorGetter( 'default' ); + } else { + get = getter( 'default' ); + } + out = new this( order, len ); + buf = out._buffer; // eslint-disable-line no-underscore-dangle + for ( i = 0; i < len; i++ ) { + buf.setFloat64( i*BYTES_PER_ELEMENT, clbk.call( thisArg, get( src, i ), i ), isLE ); + } + return out; + } + return new this( order, src ); + } + if ( isObject( src ) && HAS_ITERATOR_SYMBOL && isFunction( src[ ITERATOR_SYMBOL ] ) ) { + buf = src[ ITERATOR_SYMBOL ](); + if ( !isFunction( buf.next ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be an array-like object or an iterable. Value: `%s`.', src ) ); + } + if ( clbk ) { + tmp = fromIteratorMap( buf, clbk, thisArg ); + } else { + tmp = fromIterator( buf ); + } + len = tmp.length; + out = new this( order, len ); + buf = out._buffer; // eslint-disable-line no-underscore-dangle + for ( i = 0; i < len; i++ ) { + buf.setFloat64( i*BYTES_PER_ELEMENT, tmp[ i ], isLE ); + } + return out; + } + throw new TypeError( format( 'invalid argument. Second argument must be an array-like object or an iterable. Value: `%s`.', src ) ); +}); + +/** +* Creates a new `Float64ArrayFE` from a variable number of arguments. +* +* @name of +* @memberof Float64ArrayFE +* @type {Function} +* @param {string} endianness - byte order +* @param {...*} element - array elements +* @throws {TypeError} `this` context must be a constructor +* @throws {TypeError} `this` must be a Float64ArrayFE +* @throws {TypeError} first argument must be a supported byte order +* @returns {Float64ArrayFE} typed array instance +* +* @example +* var arr = Float64ArrayFE.of( 'little-endian', 1.0, 1.0, 1.0, 1.0 ); +* // returns +* +* var len = arr.length; +* // returns 4 +*/ +setReadOnly( Float64ArrayFE, 'of', function of( endianness ) { + var order; + var args; + var i; + if ( !isFunction( this ) ) { + throw new TypeError( 'invalid invocation. `this` context must be a constructor.' ); + } + if ( !isFloat64ArrayFEConstructor( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a Float64ArrayFE.' ); + } + order = byteOrder( endianness ); + if ( order === null || !isByteOrder( order ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a supported byte order. Value: `%s`.', endianness ) ); + } + args = []; + for ( i = 1; i < arguments.length; i++ ) { + args.push( arguments[ i ] ); + } + return new this( order, args ); +}); + +/** +* Pointer to the underlying data buffer. +* +* @name buffer +* @memberof Float64ArrayFE.prototype +* @readonly +* @type {ArrayBuffer} +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var buf = arr.buffer; +* // returns +*/ +setReadOnlyAccessor( Float64ArrayFE.prototype, 'buffer', function get() { + return this._buffer.buffer; +}); + +/** +* Size (in bytes) of the array. +* +* @name byteLength +* @memberof Float64ArrayFE.prototype +* @readonly +* @type {NonNegativeInteger} +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var byteLength = arr.byteLength; +* // returns 80 +*/ +setReadOnlyAccessor( Float64ArrayFE.prototype, 'byteLength', function get() { + return this._buffer.byteLength; +}); + +/** +* Offset (in bytes) of the array from the start of its underlying `ArrayBuffer`. +* +* @name byteOffset +* @memberof Float64ArrayFE.prototype +* @readonly +* @type {NonNegativeInteger} +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var byteOffset = arr.byteOffset; +* // returns 0 +*/ +setReadOnlyAccessor( Float64ArrayFE.prototype, 'byteOffset', function get() { + return this._buffer.byteOffset; +}); + +/** +* Size (in bytes) of each array element. +* +* @name BYTES_PER_ELEMENT +* @memberof Float64ArrayFE.prototype +* @readonly +* @type {PositiveInteger} +* @default 8 +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var nbytes = arr.BYTES_PER_ELEMENT; +* // returns 8 +*/ +setReadOnly( Float64ArrayFE.prototype, 'BYTES_PER_ELEMENT', Float64ArrayFE.BYTES_PER_ELEMENT ); + +/** +* Returns an array element. +* +* @name get +* @memberof Float64ArrayFE.prototype +* @type {Function} +* @param {NonNegativeInteger} idx - element index +* @throws {TypeError} `this` must be a Float64ArrayFE +* @throws {TypeError} must provide a nonnegative integer +* @returns {(number|void)} array element +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var v = arr.get( 0 ); +* // returns 0.0 +* +* arr.set( [ 1.0, 2.0 ], 0 ); +* +* v = arr.get( 0 ); +* // returns 1.0 +* +* v = arr.get( 100 ); +* // returns undefined +*/ +setReadOnly( Float64ArrayFE.prototype, 'get', function get( idx ) { + if ( !isFloat64ArrayFE( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a Float64ArrayFE.' ); + } + if ( !isNonNegativeInteger( idx ) ) { + throw new TypeError( format( 'invalid argument. Must provide a nonnegative integer. Value: `%s`.', idx ) ); + } + if ( idx >= this._length ) { + return; + } + return this._buffer.getFloat64( idx*BYTES_PER_ELEMENT, this._isLE ); +}); + +/** +* Number of array elements. +* +* @name length +* @memberof Float64ArrayFE.prototype +* @readonly +* @type {NonNegativeInteger} +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var len = arr.length; +* // returns 10 +*/ +setReadOnlyAccessor( Float64ArrayFE.prototype, 'length', function get() { + return this._length; +}); + +/** +* Sets an array element. +* +* ## Notes +* +* - When provided a typed array, we must check whether the source array shares the same buffer as the target array and whether the underlying memory overlaps. In particular, we are concerned with the following scenario: +* +* ```text +* buf: --------------------- +* src: --------------------- +* ``` +* +* In the above, as we copy values from `src`, we will overwrite values in the `src` view, resulting in duplicated values copied into the end of `buf`, which is not intended. Hence, to avoid overwriting source values, we must **copy** source values to a temporary array. +* +* In the other overlapping scenario, +* +* ```text +* buf: --------------------- +* src: --------------------- +* ``` +* +* by the time we begin copying into the overlapping region, we are copying from the end of `src`, a non-overlapping region, which means we don't run the risk of copying copied values, rather than the original `src` values, as intended. +* +* @name set +* @memberof Float64ArrayFE.prototype +* @type {Function} +* @param {(Collection|Float64ArrayFE|*)} value - value(s) +* @param {NonNegativeInteger} [i=0] - element index at which to start writing values +* @throws {TypeError} `this` must be a Float64ArrayFE +* @throws {TypeError} index argument must be a nonnegative integer +* @throws {RangeError} index argument is out-of-bounds +* @throws {RangeError} target array lacks sufficient storage to accommodate source values +* @returns {void} +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 10 ); +* +* var v = arr.get( 0 ); +* // returns 0.0 +* +* arr.set( [ 1.0, 2.0 ], 0 ); +* +* v = arr.get( 0 ); +* // returns 1.0 +*/ +setReadOnly( Float64ArrayFE.prototype, 'set', function set( value ) { + var sbuf; + var idx; + var buf; + var tmp; + var get; + var N; + var i; + var j; + if ( !isFloat64ArrayFE( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a Float64ArrayFE.' ); + } + buf = this._buffer; + if ( arguments.length > 1 ) { + idx = arguments[ 1 ]; + if ( !isNonNegativeInteger( idx ) ) { + throw new TypeError( format( 'invalid argument. Index argument must be a nonnegative integer. Value: `%s`.', idx ) ); + } + } else { + idx = 0; + } + if ( isCollection( value ) ) { + N = value.length; + if ( idx+N > this._length ) { + throw new RangeError( 'invalid arguments. Target array lacks sufficient storage to accommodate source values.' ); + } + sbuf = value; + if ( sbuf.get && sbuf.set ) { + get = accessorGetter( 'default' ); + } else { + get = getter( 'default' ); + } + // Check for overlapping memory... + j = buf.byteOffset + (idx*BYTES_PER_ELEMENT); + if ( + sbuf.buffer === buf.buffer && + ( + sbuf.byteOffset < j && + sbuf.byteOffset+sbuf.byteLength > j + ) + ) { + // We need to copy source values... + tmp = []; + for ( i = 0; i < value.length; i++ ) { + tmp.push( get( value, i ) ); + } + sbuf = tmp; + get = getter( 'default' ); + } + for ( i = 0; i < N; idx++, i++ ) { + buf.setFloat64( idx*BYTES_PER_ELEMENT, get( sbuf, i ), this._isLE ); + } + return; + } + if ( idx >= this._length ) { + throw new RangeError( format( 'invalid argument. Index argument is out-of-bounds. Value: `%u`.', idx ) ); + } + buf.setFloat64( idx*BYTES_PER_ELEMENT, value, this._isLE ); +}); + +/** +* Serializes an array as a string. +* +* @name toString +* @memberof Float64ArrayFE.prototype +* @type {Function} +* @throws {TypeError} `this` must be a Float64ArrayFE +* @returns {string} string representation +* +* @example +* var arr = new Float64ArrayFE( 'little-endian', 3 ); +* +* arr.set( 1.0, 0 ); +* arr.set( 2.0, 1 ); +* arr.set( 3.0, 2 ); +* +* var str = arr.toString(); +* // returns '1,2,3' +*/ +setReadOnly( Float64ArrayFE.prototype, 'toString', function toString() { + var out; + var buf; + var i; + if ( !isFloat64ArrayFE( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a Float64ArrayFE.' ); + } + out = []; + buf = this._buffer; + for ( i = 0; i < this._length; i++ ) { + out.push( buf.getFloat64( i*BYTES_PER_ELEMENT, this._isLE ) ); + } + return out.join( ',' ); +}); + + +// EXPORTS // + +module.exports = Float64ArrayFE; diff --git a/fixed-endian-float64/package.json b/fixed-endian-float64/package.json new file mode 100644 index 00000000..01457daa --- /dev/null +++ b/fixed-endian-float64/package.json @@ -0,0 +1,71 @@ +{ + "name": "@stdlib/array/fixed-endian-float64", + "version": "0.0.0", + "description": "Float64ArrayFE.", + "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", + "stdtypes", + "types", + "data", + "structure", + "array", + "typed", + "typed array", + "typed-array", + "float64array", + "float64", + "double", + "double-precision", + "ieee754", + "endian", + "little-endian", + "big-endian", + "byte-order" + ] +} diff --git a/fixed-endian-float64/test/test.js b/fixed-endian-float64/test/test.js new file mode 100644 index 00000000..fc72bbf8 --- /dev/null +++ b/fixed-endian-float64/test/test.js @@ -0,0 +1,35 @@ +/** +* @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 ctor = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof ctor, 'function', 'main export is a function' ); + t.end(); +}); + +// TODO: add tests