Skip to content

Commit

Permalink
feat: add with method to array/fixed-endian-factory
Browse files Browse the repository at this point in the history
PR-URL: #3291
Closes: #3162

Co-authored-by: Philipp Burckhardt <[email protected]>
Reviewed-by: Philipp Burckhardt <[email protected]>
Signed-off-by: Philipp Burckhardt <[email protected]>
  • Loading branch information
aayush0325 and Planeshifter authored Dec 2, 2024
1 parent c0d083d commit a0ba090
Show file tree
Hide file tree
Showing 5 changed files with 450 additions and 3 deletions.
19 changes: 19 additions & 0 deletions lib/node_modules/@stdlib/array/fixed-endian-factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,25 @@ var str = arr.join( 0 );
// returns '10203'
```

<a name="method-with"></a>

#### TypedArrayFE.prototype.with( index, value )

Returns a new typed array with the element at a provided index replaced with a provided value.

```javascript
var Float64ArrayFE = fixedEndianFactory( 'float64' );

var arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0, 3.0 ] );
// returns <Float64ArrayFE>

var out = arr.with( 0, 0.0 );
// returns <Float64ArrayFE>

var v = out.get( 0 );
// returns 0.0
```

</section>

<!-- /.usage -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* @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 factory = require( './../lib' );


// VARIABLES //

var Float64ArrayFE = factory( 'float64' );


// MAIN //

bench( pkg+':with', function benchmark( b ) {
var values;
var out;
var arr;
var i;

values = [
1.0,
2.0,
3.0
];
arr = new Float64ArrayFE( 'little-endian', [ 1.0, 2.0, 2.0, 1.0 ] );

b.tic();
for ( i = 0; i < b.iterations; i++ ) {
out = arr.with( i % arr.length, values[ i % values.length ] );
if ( typeof out !== 'object' ) {
b.fail( 'should return an object' );
}
}
b.toc();
if ( !( out instanceof Float64ArrayFE ) ) {
b.fail( 'should return a typed array' );
}
b.pass( 'benchmark finished' );
b.end();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/**
* @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( '@stdlib/array/zero-to' );
var pkg = require( './../package.json' ).name;
var factory = require( './../lib' );


// VARIABLES //

var Float64ArrayFE = factory( 'float64' );


// 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 values;
var out;
var i;

values = [
1.0,
2.0,
3.0
];

b.tic();
for ( i = 0; i < b.iterations; i++ ) {
out = arr.with( i % arr.length, values[ i % values.length ] );
if ( typeof out !== 'object' ) {
b.fail( 'should return an object' );
}
}
b.toc();
if ( !( out instanceof Float64ArrayFE ) ) {
b.fail( 'should return a typed 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+':with:len='+len, f );
}
}

main();
47 changes: 44 additions & 3 deletions lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive;
var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive;
var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive;
var isCollection = require( '@stdlib/assert/is-collection' );
var isArrayBuffer = require( '@stdlib/assert/is-arraybuffer' );
var isObject = require( '@stdlib/assert/is-object' );
Expand Down Expand Up @@ -1059,22 +1060,62 @@ function factory( dtype ) { // eslint-disable-line max-lines-per-function, stdli
if ( !isTypedArray( this ) ) {
throw new TypeError( format( 'invalid invocation. `this` is not %s %s.', CHAR2ARTICLE[ dtype[0] ], CTOR_NAME ) );
}

if ( arguments.length > 0 ) {
sep = String( separator );
} else {
sep = ',';
}

out = [];
buf = this._buffer;
for ( i = 0; i < this._length; i++ ) {
out.push( buf[ GETTER ]( i * BYTES_PER_ELEMENT, this._isLE ) );
}

return out.join( sep );
});

/**
* Returns a new typed array with the element at a provided index replaced with a provided value.
*
* @name with

This comment has been minimized.

Copy link
@kgryte

kgryte Dec 3, 2024

Member

@Planeshifter Missing @private.

This comment has been minimized.

Copy link
@Planeshifter

Planeshifter Dec 14, 2024

Author Member

Added.

* @memberof TypedArray.prototype
* @type {Function}
* @param {integer} index - element index
* @param {number} value - new value
* @throws {TypeError} `this` must be a typed array instance
* @throws {TypeError} first argument must be an integer
* @throws {RangeError} index argument is out-of-bounds
* @throws {TypeError} second argument must be a number

This comment has been minimized.

Copy link
@kgryte

kgryte Dec 3, 2024

Member

@Planeshifter This is incorrect. The second argument can be any value. It depends on the underlying array type. For the purposes of this method, we shouldn't assume that value must be numeric.

This comment has been minimized.

Copy link
@Planeshifter

Planeshifter Dec 3, 2024

Author Member

Addressed.

* @returns {TypedArray} new typed array
*/
setReadOnly( TypedArray.prototype, 'with', function copyWith( index, value ) {
var outbuf;
var buf;
var out;
var len;

if ( !isTypedArray( this ) ) {
throw new TypeError( format( 'invalid invocation. `this` is not %s %s.', CHAR2ARTICLE[ dtype[0] ], CTOR_NAME ) );
}
if ( !isInteger( index ) ) {
throw new TypeError( format( 'invalid argument. First argument must be an integer. Value: `%s`.', index ) );
}
len = this._length;
buf = this._buffer;
if ( index < 0 ) {
index += len;
}
if ( index < 0 || index >= len ) {
throw new RangeError( format( 'invalid argument. Index argument is out-of-bounds. Value: `%s`.', index ) );
}
if ( !isNumber( value ) ) {

This comment has been minimized.

Copy link
@kgryte

kgryte Dec 3, 2024

Member

@Planeshifter This check should be removed.

This comment has been minimized.

Copy link
@Planeshifter

Planeshifter Dec 3, 2024

Author Member

Removed.

throw new TypeError( format( 'invalid argument. Second argument must be a number. Value: `%s`.', value ) );
}
out = new this.constructor( flag2byteOrder( this._isLE ), buf.buffer );

This comment has been minimized.

Copy link
@kgryte

kgryte Dec 3, 2024

Member

@Planeshifter This logic is incorrect. This currently passes the entire ArrayBuffer, which is not what we want, especially as this means that the input buffer is mutated.

Values should be explicitly copied to a fresh buffer and the selected element replaced.

outbuf = out._buffer; // eslint-disable-line no-underscore-dangle
outbuf[ SETTER ]( index * BYTES_PER_ELEMENT, value, this._isLE );
return out;
});

return TypedArray;

/**
Expand Down
Loading

1 comment on commit a0ba090

@stdlib-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage Report

Package Statements Branches Functions Lines
array/fixed-endian-factory $\color{red}1131/1388$
$\color{green}+81.48\%$
$\color{red}142/152$
$\color{green}+93.42\%$
$\color{red}21/32$
$\color{green}+65.62\%$
$\color{red}1131/1388$
$\color{green}+81.48\%$

The above coverage report was generated for the changes in this push.

Please sign in to comment.