From 533e82c152133b2eaced4888c403f73124e8a914 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Sat, 1 Feb 2025 09:55:49 +0000 Subject: [PATCH 1/4] feat: add accessor arrays support --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed --- --- type: pre_push_report description: Results of running various checks prior to pushing changes. report: - task: run_javascript_examples status: na - task: run_c_examples status: na - task: run_cpp_examples status: na - task: run_javascript_readme_examples status: na - task: run_c_benchmarks status: na - task: run_cpp_benchmarks status: na - task: run_fortran_benchmarks status: na - task: run_javascript_benchmarks status: na - task: run_julia_benchmarks status: na - task: run_python_benchmarks status: na - task: run_r_benchmarks status: na - task: run_javascript_tests status: na --- --- .../@stdlib/blas/ext/base/gcusumpw/README.md | 3 + .../ext/base/gcusumpw/docs/types/index.d.ts | 16 +- .../blas/ext/base/gcusumpw/docs/types/test.ts | 7 +- .../blas/ext/base/gcusumpw/lib/accessors.js | 112 ++++++++ .../blas/ext/base/gcusumpw/lib/ndarray.js | 9 + .../blas/ext/base/gcusumpw/test/test.main.js | 195 +++++++++++-- .../ext/base/gcusumpw/test/test.ndarray.js | 265 ++++++++++++++++-- 7 files changed, 566 insertions(+), 41 deletions(-) create mode 100644 lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/README.md b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/README.md index d440bee86270..5d3b3d0f6ec1 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/README.md +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/README.md @@ -129,6 +129,7 @@ gcusumpw.ndarray( 4, 0.0, x, 2, 1, y, -1, y.length-1 ); - If `N <= 0`, both functions return `y` unchanged. - In general, pairwise summation is more numerically stable than ordinary recursive summation (i.e., "simple" summation), with slightly worse performance. While not the most numerically stable summation technique (e.g., compensated summation techniques such as the Kahan–Babuška-Neumaier algorithm are generally more numerically stable), pairwise summation strikes a reasonable balance between numerical stability and performance. If either numerical stability or performance is more desirable for your use case, consider alternative summation techniques. +- Both functions support array-like objects having getter and setter accessors for array element access (e.g., [`@stdlib/array/base/accessor`][@stdlib/array/base/accessor]) - Depending on the environment, the typed versions ([`dcusumpw`][@stdlib/blas/ext/base/dcusumpw], [`scusumpw`][@stdlib/blas/ext/base/scusumpw], etc.) are likely to be significantly more performant. @@ -197,6 +198,8 @@ console.log( y ); [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray +[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor + [@higham:1993a]: https://doi.org/10.1137/0914050 diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts index b020bdf932f1..3d712760843f 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts @@ -20,7 +20,17 @@ /// -import { NumericArray } from '@stdlib/types/array'; +import { NumericArray, Collection, AccessorArrayLike } from '@stdlib/types/array'; + +/** +* Input array. +*/ +type InputArray = NumericArray | Collection | AccessorArrayLike; + +/** +* Input array. +*/ +type OutputArray = NumericArray | Collection | AccessorArrayLike; /** * Interface describing `gcusumpw`. @@ -44,7 +54,7 @@ interface Routine { * gcusumpw( x.length, 0.0, x, 1, y, 1 ); * // y => [ 1.0, -1.0, 1.0 ] */ - ( N: number, sum: number, x: NumericArray, strideX: number, y: NumericArray, strideY: number ): NumericArray; + ( N: number, sum: number, x: InputArray, strideX: number, y: OutputArray, strideY: number ): OutputArray; /** * Computes the cumulative sum of strided array elements using pairwise summation and alternative indexing semantics. @@ -66,7 +76,7 @@ interface Routine { * gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); * // y => [ 1.0, -1.0, 1.0 ] */ - ndarray( N: number, sum: number, x: NumericArray, strideX: number, offsetX: number, y: NumericArray, strideY: number, offsetY: number ): NumericArray; + ndarray( N: number, sum: number, x: InputArray, strideX: number, offsetX: number, y: OutputArray, strideY: number, offsetY: number ): OutputArray; } /** diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts index fc7347f15937..86bb05c0f5f4 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts @@ -16,6 +16,7 @@ * limitations under the License. */ +import AccessorArray = require( '@stdlib/array/base/accessor' ); import gcusumpw = require( './index' ); @@ -26,7 +27,8 @@ import gcusumpw = require( './index' ); const x = new Float64Array( 10 ); const y = new Float64Array( 10 ); - gcusumpw( x.length, 0.0, x, 1, y, 1 ); // $ExpectType NumericArray + gcusumpw( x.length, 0.0, x, 1, y, 1 ); // $ExpectType OutputArray + gcusumpw( x.length, 0.0, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType OutputArray } // The compiler throws an error if the function is provided a first argument which is not a number... @@ -139,7 +141,8 @@ import gcusumpw = require( './index' ); const x = new Float64Array( 10 ); const y = new Float64Array( 10 ); - gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType NumericArray + gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType OutputArray + gcusumpw.ndarray( x.length, 0.0, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType OutputArray } // The compiler throws an error if the `ndarray` method is provided a first argument which is not a number... diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js new file mode 100644 index 000000000000..358f203dc59a --- /dev/null +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js @@ -0,0 +1,112 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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 floor = require( '@stdlib/math/base/special/floor' ); + + +// VARIABLES // + +// Blocksize for pairwise summation: +var BLOCKSIZE = 128; + + +// MAIN // + +/** +* Computes the cumulative sum of strided array elements using pairwise summation. +* +* ## Method +* +* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`. +* +* ## References +* +* - Higham, Nicholas J. 1993. "The Accuracy of Floating Point Summation." _SIAM Journal on Scientific Computing_ 14 (4): 783–99. doi:[10.1137/0914050](https://doi.org/10.1137/0914050). +* +* @private +* @param {PositiveInteger} N - number of indexed elements +* @param {number} sum - initial sum +* @param {Object} x - input array object +* @param {Collection} x.data - input array data +* @param {Array} x.accessors - array element accessors +* @param {integer} strideX - stride length for `x` +* @param {NonNegativeInteger} offsetX - starting index for `x` +* @param {Object} y - output array object +* @param {Collection} y.data - output array data +* @param {Array} y.accessors - array element accessors +* @param {integer} strideY - stride length for `y` +* @param {NonNegativeInteger} offsetY - starting index for `y` +* @returns {Object} output array object +* +* @example +* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); +* var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +* +* var x = toAccessorArray( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); +* var y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] ); +* +* gcusumpw( 4, 0.0, arraylike2object( x ), 2, 1, arrayLike2object( y ), 1, 0 ); +*/ +function gcusumpw( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { + var xbuf; + var ybuf; + var xget; + var yget; + var yset; + var ix; + var iy; + var s; + var n; + var i; + + // Cache reference to array data: + xbuf = x.data; + ybuf = y.data; + + // Cache reference to the element accessors: + xget = x.accessors[ 0 ]; + yget = y.accessors[ 0 ]; + yset = y.accessors[ 1 ]; + + ix = offsetX; + iy = offsetY; + if ( N <= BLOCKSIZE ) { + s = 0.0; + for ( i = 0; i < N; i++ ) { + s += xget( xbuf, ix ); + yset( ybuf, iy, sum + s); + ix += strideX; + iy += strideY; + } + return y; + } + n = floor( N/2 ); + gcusumpw( n, sum, x, strideX, ix, y, strideY, iy ); + iy += (n-1) * strideY; + gcusumpw( N-n, yget( ybuf, iy ), x, strideX, ix+(n*strideX), y, strideY, iy+strideY ); // eslint-disable-line max-len + return y; +} + + +// EXPORTS // + +module.exports = gcusumpw; diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js index a8ddbf1fc7b4..a06da1aa72a7 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js @@ -20,7 +20,9 @@ // MODULES // +var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); var floor = require( '@stdlib/math/base/special/floor' ); +var accessors = require( './accessors.js' ); // VARIABLES // @@ -62,6 +64,8 @@ var BLOCKSIZE = 128; function gcusumpw( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { var ix; var iy; + var ox; + var oy; var s; var n; var i; @@ -69,6 +73,11 @@ function gcusumpw( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { if ( N <= 0 ) { return y; } + ox = arraylike2object( x ); + oy = arraylike2object( y ); + if ( ox.accessorProtocol || oy.accessorProtocol ) { + return accessors( N, sum, ox, strideX, offsetX, oy, strideY, offsetY ); + } ix = offsetX; iy = offsetY; if ( N <= BLOCKSIZE ) { diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js index 9dded209f761..333548697817 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js @@ -21,8 +21,8 @@ // MODULES // var tape = require( 'tape' ); -var floor = require( '@stdlib/math/base/special/floor' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var Float64Array = require( '@stdlib/array/float64' ); var gcusumpw = require( './../lib' ); @@ -128,6 +128,94 @@ tape( 'the function computes the cumulative sum', function test( t ) { t.end(); }); +tape( 'the function computes the cumulative sum (accessors)', function test( t ) { + var expected; + var x; + var y; + var i; + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ]; + + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + expected = [ + 1.0, + 3.0, + 6.0, + 10.0, + 15.0 + ]; + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ]; + + gcusumpw( x.length, 10.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + expected = [ + 11.0, + 13.0, + 16.0, + 20.0, + 25.0 + ]; + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ NaN, NaN ]; + y = [ 0.0, 0.0 ]; + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + + for ( i = 0; i < y.length; i++ ) { + t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i ); + } + + x = [ 1.0, NaN, 3.0, NaN ]; + y = [ 0.0, 0.0, 0.0, 0.0 ]; + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + + expected = [ + 1.0, + NaN, + NaN, + NaN + ]; + for ( i = 0; i < y.length; i++ ) { + if ( isnan( expected[ i ] ) ) { + t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i ); + } else { + t.strictEqual( y[ i ], expected[ i ], true, 'returns expected value. i: ' + i ); + } + } + + x = [ 1.0, 1.0e100, 1.0, -1.0e100 ]; + y = [ 0.0, 0.0, 0.0, 0.0 ]; + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + + expected = [ + 1.0, + 1.0e100, + 1.0e100, + 0.0 + ]; + t.deepEqual( y, expected, 'returns expected value' ); + + x = []; + y = []; + expected = []; + for ( i = 0; i < 1e3; i++ ) { + x.push( i+1 ); + y.push( 0.0 ); + if ( i === 0 ) { + expected.push( x[ i ] ); + } else { + expected.push( expected[ i-1 ] + x[ i ] ); + } + } + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function returns a reference to the output array', function test( t ) { var out; var x; @@ -165,7 +253,6 @@ tape( 'the function supports an `x` stride', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 0 @@ -181,9 +268,36 @@ tape( 'the function supports an `x` stride', function test( t ) { 0.0, 0.0 ]; - N = 3; - gcusumpw( N, 0.0, x, 2, y, 1 ); + gcusumpw( 3, 0.0, x, 2, y, 1 ); + + expected = [ 1.0, 4.0, 9.0, 0.0, 0.0 ]; + + t.deepEqual( y, expected, 'deep equal' ); + t.end(); +}); + +tape( 'the function supports an `x` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 1.0, // 0 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 2 + ]; + y = [ + 0.0, // 0 + 0.0, // 1 + 0.0, // 2 + 0.0, + 0.0 + ]; + + gcusumpw( 3, 0.0, toAccessorArray( x ), 2, toAccessorArray( y ), 1 ); expected = [ 1.0, 4.0, 9.0, 0.0, 0.0 ]; @@ -195,7 +309,6 @@ tape( 'the function supports a `y` stride', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 0 @@ -211,9 +324,36 @@ tape( 'the function supports a `y` stride', function test( t ) { 0.0, 0.0 // 2 ]; - N = 3; - gcusumpw( N, 0.0, x, 1, y, 2 ); + gcusumpw( 3, 0.0, x, 1, y, 2 ); + + expected = [ 1.0, 0.0, 3.0, 0.0, 6.0 ]; + + t.deepEqual( y, expected, 'deep equal' ); + t.end(); +}); + +tape( 'the function supports a `y` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 1.0, // 0 + 2.0, // 1 + 3.0, // 2 + 4.0, + 5.0 + ]; + y = [ + 0.0, // 0 + 0.0, + 0.0, // 1 + 0.0, + 0.0 // 2 + ]; + + gcusumpw( 3, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 2 ); expected = [ 1.0, 0.0, 3.0, 0.0, 6.0 ]; @@ -225,7 +365,6 @@ tape( 'the function supports negative strides', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 2 @@ -241,9 +380,36 @@ tape( 'the function supports negative strides', function test( t ) { 0.0, 0.0 ]; - N = 3; - gcusumpw( N, 0.0, x, -2, y, -1 ); + gcusumpw( 3, 0.0, x, -2, y, -1 ); + + expected = [ 9.0, 8.0, 5.0, 0.0, 0.0 ]; + + t.deepEqual( y, expected, 'deep equal' ); + t.end(); +}); + +tape( 'the function supports negative strides (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 1.0, // 2 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 0 + ]; + y = [ + 0.0, // 2 + 0.0, // 1 + 0.0, // 0 + 0.0, + 0.0 + ]; + + gcusumpw( 3, 0.0, toAccessorArray( x ), -2, toAccessorArray( y ), -1 ); expected = [ 9.0, 8.0, 5.0, 0.0, 0.0 ]; @@ -255,7 +421,6 @@ tape( 'the function supports complex access patterns', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 0 @@ -273,9 +438,8 @@ tape( 'the function supports complex access patterns', function test( t ) { 0.0, 0.0 ]; - N = 3; - gcusumpw( N, 0.0, x, 2, y, -1 ); + gcusumpw( 3, 0.0, x, 2, y, -1 ); expected = [ 9.0, 4.0, 1.0, 0.0, 0.0, 0.0 ]; @@ -289,7 +453,6 @@ tape( 'the function supports view offsets', function test( t ) { var y0; var x1; var y1; - var N; // Initial arrays... x0 = new Float64Array([ @@ -313,9 +476,7 @@ tape( 'the function supports view offsets', function test( t ) { x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // begin at 2nd element y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // begin at the 4th element - N = floor( x0.length / 2 ); - - gcusumpw( N, 0.0, x1, -2, y1, 1 ); + gcusumpw( 3, 0.0, x1, -2, y1, 1 ); expected = new Float64Array( [ 0.0, 0.0, 0.0, 6.0, 10.0, 12.0 ] ); t.deepEqual( y0, expected, 'deep equal' ); diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js index f9cc204d07bb..873380a6f7e1 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js @@ -21,8 +21,8 @@ // MODULES // var tape = require( 'tape' ); -var floor = require( '@stdlib/math/base/special/floor' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var gcusumpw = require( './../lib/ndarray.js' ); @@ -126,6 +126,93 @@ tape( 'the function calculates the cumulative sum', function test( t ) { t.end(); }); +tape( 'the function calculates the cumulative sum (accessors)', function test( t ) { + var expected; + var x; + var y; + var i; + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ]; + + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + expected = [ + 1.0, + 3.0, + 6.0, + 10.0, + 15.0 + ]; + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ]; + + gcusumpw( x.length, 10.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + expected = [ + 11.0, + 13.0, + 16.0, + 20.0, + 25.0 + ]; + t.deepEqual( y, expected, 'returns expected value' ); + + x = [ NaN, NaN ]; + y = [ 0.0, 0.0 ]; + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + + for ( i = 0; i < y.length; i++ ) { + t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i ); + } + + x = [ 1.0, NaN, 3.0, NaN ]; + y = [ 0.0, 0.0, 0.0, 0.0 ]; + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + + expected = [ + 1.0, + NaN, + NaN, + NaN + ]; + for ( i = 0; i < y.length; i++ ) { + if ( isnan( expected[ i ] ) ) { + t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i ); + } else { + t.strictEqual( y[ i ], expected[ i ], true, 'returns expected value. i: ' + i ); + } + } + + x = [ 1.0, 1.0e100, 1.0, -1.0e100 ]; + y = [ 0.0, 0.0, 0.0, 0.0 ]; + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + + expected = [ + 1.0, + 1.0e100, + 1.0e100, + 0.0 + ]; + t.deepEqual( y, expected, 'returns expected value' ); + + x = []; + y = []; + expected = []; + for ( i = 0; i < 1e3; i++ ) { + x.push( i+1 ); + if ( i === 0 ) { + expected.push( x[ i ] ); + } else { + expected.push( expected[ i-1 ] + x[ i ] ); + } + } + gcusumpw( x.length, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function returns a reference to the output array', function test( t ) { var out; var x; @@ -163,7 +250,6 @@ tape( 'the function supports an `x` stride', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 0 @@ -179,9 +265,36 @@ tape( 'the function supports an `x` stride', function test( t ) { 0.0, 0.0 ]; - N = 3; - gcusumpw( N, 0.0, x, 2, 0, y, 1, 0 ); + gcusumpw( 3, 0.0, x, 2, 0, y, 1, 0 ); + + expected = [ 1.0, 4.0, 9.0, 0.0, 0.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports an `x` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 1.0, // 0 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 2 + ]; + y = [ + 0.0, // 0 + 0.0, // 1 + 0.0, // 2 + 0.0, + 0.0 + ]; + + gcusumpw( 3, 0.0, toAccessorArray( x ), 2, 0, toAccessorArray( y ), 1, 0 ); expected = [ 1.0, 4.0, 9.0, 0.0, 0.0 ]; @@ -193,7 +306,6 @@ tape( 'the function supports a `y` stride', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 0 @@ -209,9 +321,36 @@ tape( 'the function supports a `y` stride', function test( t ) { 0.0, 0.0 // 2 ]; - N = 3; - gcusumpw( N, 0.0, x, 1, 0, y, 2, 0 ); + gcusumpw( 3, 0.0, x, 1, 0, y, 2, 0 ); + + expected = [ 1.0, 0.0, 3.0, 0.0, 6.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports a `y` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 1.0, // 0 + 2.0, // 1 + 3.0, // 2 + 4.0, + 5.0 + ]; + y = [ + 0.0, // 0 + 0.0, + 0.0, // 1 + 0.0, + 0.0 // 2 + ]; + + gcusumpw( 3, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 2, 0 ); expected = [ 1.0, 0.0, 3.0, 0.0, 6.0 ]; @@ -223,7 +362,6 @@ tape( 'the function supports negative strides', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 2 @@ -239,9 +377,36 @@ tape( 'the function supports negative strides', function test( t ) { 0.0, 0.0 ]; - N = 3; - gcusumpw( N, 0.0, x, -2, x.length-1, y, -1, 2 ); + gcusumpw( 3, 0.0, x, -2, x.length-1, y, -1, 2 ); + + expected = [ 9.0, 8.0, 5.0, 0.0, 0.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports negative strides (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 1.0, // 2 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 0 + ]; + y = [ + 0.0, // 2 + 0.0, // 1 + 0.0, // 0 + 0.0, + 0.0 + ]; + + gcusumpw( 3, 0.0, toAccessorArray( x ), -2, x.length-1, toAccessorArray( y ), -1, 2 ); expected = [ 9.0, 8.0, 5.0, 0.0, 0.0 ]; @@ -251,7 +416,6 @@ tape( 'the function supports negative strides', function test( t ) { tape( 'the function supports an `x` offset', function test( t ) { var expected; - var N; var x; var y; @@ -275,9 +439,42 @@ tape( 'the function supports an `x` offset', function test( t ) { 0.0, 0.0 ]; - N = floor( x.length / 2 ); - gcusumpw( N, 0.0, x, 2, 1, y, 1, 0 ); + gcusumpw( 4, 0.0, x, 2, 1, y, 1, 0 ); + + expected = [ 1.0, -1.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports an `x` offset (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 2.0, + 1.0, // 0 + 2.0, + -2.0, // 1 + -2.0, + 2.0, // 2 + 3.0, + 4.0 // 3 + ]; + y = [ + 0.0, // 0 + 0.0, // 1 + 0.0, // 2 + 0.0, // 3 + 0.0, + 0.0, + 0.0, + 0.0 + ]; + + gcusumpw( 4, 0.0, toAccessorArray( x ), 2, 1, toAccessorArray( y ), 1, 0 ); expected = [ 1.0, -1.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0 ]; @@ -287,7 +484,6 @@ tape( 'the function supports an `x` offset', function test( t ) { tape( 'the function supports a `y` offset', function test( t ) { var expected; - var N; var x; var y; @@ -311,9 +507,42 @@ tape( 'the function supports a `y` offset', function test( t ) { 0.0, 0.0 // 3 ]; - N = floor( x.length / 2 ); - gcusumpw( N, 0.0, x, 1, 0, y, 2, 1 ); + gcusumpw( 4, 0.0, x, 1, 0, y, 2, 1 ); + + expected = [ 0.0, 2.0, 0.0, 3.0, 0.0, 5.0, 0.0, 3.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports a `y` offset (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ + 2.0, // 0 + 1.0, // 1 + 2.0, // 2 + -2.0, // 3 + -2.0, + 2.0, + 3.0, + 4.0 + ]; + y = [ + 0.0, + 0.0, // 0 + 0.0, + 0.0, // 1 + 0.0, + 0.0, // 2 + 0.0, + 0.0 // 3 + ]; + + gcusumpw( 4, 0.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 2, 1 ); expected = [ 0.0, 2.0, 0.0, 3.0, 0.0, 5.0, 0.0, 3.0 ]; @@ -325,7 +554,6 @@ tape( 'the function supports complex access patterns', function test( t ) { var expected; var x; var y; - var N; x = [ 1.0, // 0 @@ -343,9 +571,8 @@ tape( 'the function supports complex access patterns', function test( t ) { 0.0, 0.0 ]; - N = 3; - gcusumpw( N, 0.0, x, 2, 0, y, -1, 2 ); + gcusumpw( 3, 0.0, x, 2, 0, y, -1, 2 ); expected = [ 9.0, 4.0, 1.0, 0.0, 0.0, 0.0 ]; From db5f07b8fa2ba9add51e7b9919495bd399cdc880 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Sat, 1 Feb 2025 16:57:13 +0500 Subject: [PATCH 2/4] docs: apply review suggestion Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- .../@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts index 3d712760843f..28082406018f 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts @@ -28,7 +28,7 @@ import { NumericArray, Collection, AccessorArrayLike } from '@stdlib/types/array type InputArray = NumericArray | Collection | AccessorArrayLike; /** -* Input array. +* Output array. */ type OutputArray = NumericArray | Collection | AccessorArrayLike; From e36fdd21e8e7f0bf7500a28eedb73a2124c7439f Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Sat, 1 Feb 2025 17:09:44 +0500 Subject: [PATCH 3/4] refactor: apply suggestions from code review Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- .../@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts | 4 ++-- .../@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts index 28082406018f..bb75facb92ca 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/index.d.ts @@ -54,7 +54,7 @@ interface Routine { * gcusumpw( x.length, 0.0, x, 1, y, 1 ); * // y => [ 1.0, -1.0, 1.0 ] */ - ( N: number, sum: number, x: InputArray, strideX: number, y: OutputArray, strideY: number ): OutputArray; + ( N: number, sum: number, x: InputArray, strideX: number, y: T, strideY: number ): T; /** * Computes the cumulative sum of strided array elements using pairwise summation and alternative indexing semantics. @@ -76,7 +76,7 @@ interface Routine { * gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); * // y => [ 1.0, -1.0, 1.0 ] */ - ndarray( N: number, sum: number, x: InputArray, strideX: number, offsetX: number, y: OutputArray, strideY: number, offsetY: number ): OutputArray; + ndarray( N: number, sum: number, x: InputArray, strideX: number, offsetX: number, y: T, strideY: number, offsetY: number ): T; } /** diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts index 86bb05c0f5f4..1fbbd269aa62 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts @@ -27,8 +27,8 @@ import gcusumpw = require( './index' ); const x = new Float64Array( 10 ); const y = new Float64Array( 10 ); - gcusumpw( x.length, 0.0, x, 1, y, 1 ); // $ExpectType OutputArray - gcusumpw( x.length, 0.0, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType OutputArray + gcusumpw( x.length, 0.0, x, 1, y, 1 ); // $ExpectType Float64Array + gcusumpw( x.length, 0.0, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType AccessorArray } // The compiler throws an error if the function is provided a first argument which is not a number... @@ -141,8 +141,8 @@ import gcusumpw = require( './index' ); const x = new Float64Array( 10 ); const y = new Float64Array( 10 ); - gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType OutputArray - gcusumpw.ndarray( x.length, 0.0, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType OutputArray + gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType Float64Array + gcusumpw.ndarray( x.length, 0.0, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType AccessorArray } // The compiler throws an error if the `ndarray` method is provided a first argument which is not a number... From a6bc0715b71447cb490c0fd241cad0e14fa19fdd Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Wed, 5 Feb 2025 08:58:37 +0000 Subject: [PATCH 4/4] refactor: apply suggestions from code review --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed --- --- type: pre_push_report description: Results of running various checks prior to pushing changes. report: - task: run_javascript_examples status: na - task: run_c_examples status: na - task: run_cpp_examples status: na - task: run_javascript_readme_examples status: na - task: run_c_benchmarks status: na - task: run_cpp_benchmarks status: na - task: run_fortran_benchmarks status: na - task: run_javascript_benchmarks status: na - task: run_julia_benchmarks status: na - task: run_python_benchmarks status: na - task: run_r_benchmarks status: na - task: run_javascript_tests status: passed --- --- .../blas/ext/base/gcusumpw/docs/types/test.ts | 4 ++-- .../blas/ext/base/gcusumpw/lib/accessors.js | 7 ++++--- .../@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js | 3 ++- .../blas/ext/base/gcusumpw/test/test.main.js | 14 ++++++++++++++ .../blas/ext/base/gcusumpw/test/test.ndarray.js | 14 ++++++++++++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts index 1fbbd269aa62..0bd6cddb1d6a 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/docs/types/test.ts @@ -28,7 +28,7 @@ import gcusumpw = require( './index' ); const y = new Float64Array( 10 ); gcusumpw( x.length, 0.0, x, 1, y, 1 ); // $ExpectType Float64Array - gcusumpw( x.length, 0.0, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType AccessorArray + gcusumpw( x.length, 0.0, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType AccessorArray } // The compiler throws an error if the function is provided a first argument which is not a number... @@ -142,7 +142,7 @@ import gcusumpw = require( './index' ); const y = new Float64Array( 10 ); gcusumpw.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType Float64Array - gcusumpw.ndarray( x.length, 0.0, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType AccessorArray + gcusumpw.ndarray( x.length, 0.0, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType AccessorArray } // The compiler throws an error if the `ndarray` method is provided a first argument which is not a number... diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js index 358f203dc59a..6db272d06c1e 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/accessors.js @@ -61,10 +61,11 @@ var BLOCKSIZE = 128; * var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); * var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); * -* var x = toAccessorArray( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); -* var y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] ); +* var x = [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ]; +* var y = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ]; * -* gcusumpw( 4, 0.0, arraylike2object( x ), 2, 1, arrayLike2object( y ), 1, 0 ); +* gcusumpw( 4, 0.0, arraylike2object( toAccessorArray( x ) ), 2, 1, arraylike2object( toAccessorArray( y ) ), 1, 0 ); +* // y => [ 1.0, -1.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0 ] */ function gcusumpw( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { var xbuf; diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js index a06da1aa72a7..186af6732f46 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/lib/ndarray.js @@ -76,7 +76,8 @@ function gcusumpw( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { ox = arraylike2object( x ); oy = arraylike2object( y ); if ( ox.accessorProtocol || oy.accessorProtocol ) { - return accessors( N, sum, ox, strideX, offsetX, oy, strideY, offsetY ); + accessors( N, sum, ox, strideX, offsetX, oy, strideY, offsetY ); + return y; } ix = offsetX; iy = offsetY; diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js index 333548697817..a10e0bddaead 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.main.js @@ -230,6 +230,20 @@ tape( 'the function returns a reference to the output array', function test( t ) t.end(); }); +tape( 'the function returns a reference to the output array (accessors)', function test( t ) { + var out; + var x; + var y; + + x = toAccessorArray( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] ); + + out = gcusumpw( x.length, 0.0, x, 1, y, 1 ); + + t.strictEqual( out, y, 'same reference' ); + t.end(); +}); + tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) { var expected; var x; diff --git a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js index 873380a6f7e1..b4536873cda7 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/gcusumpw/test/test.ndarray.js @@ -227,6 +227,20 @@ tape( 'the function returns a reference to the output array', function test( t ) t.end(); }); +tape( 'the function returns a reference to the output array (accessors)', function test( t ) { + var out; + var x; + var y; + + x = toAccessorArray( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] ); + + out = gcusumpw( x.length, 0.0, x, 1, 0, y, 1, 0 ); + + t.strictEqual( out, y, 'same reference' ); + t.end(); +}); + tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) { var expected; var x;