diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/README.md b/lib/node_modules/@stdlib/blas/base/gaxpy/README.md index 5f70522fd423..ede380ac7470 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/README.md +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/README.md @@ -47,9 +47,9 @@ The function has the following parameters: - **N**: number of indexed elements. - **alpha**: `numeric` constant. -- **x**: input [`Array`][mdn-array] or [`typed array`][mdn-typed-array]. +- **x**: first input array. - **strideX**: index increment for `x`. -- **y**: input [`Array`][mdn-array] or [`typed array`][mdn-typed-array]. +- **y**: second input array. - **strideY**: index increment for `y`. The `N` and stride parameters determine which elements in the strided arrays are accessed at runtime. For example, to multiply every other value in `x` by `alpha` and add the result to the first `N` elements of `y` in reverse order, @@ -119,6 +119,7 @@ gaxpy.ndarray( 3, 5.0, x, 2, 1, y, -1, y.length-1 ); - If `N <= 0` or `alpha == 0`, both functions return `y` unchanged. - `gaxpy()` corresponds to the [BLAS][blas] level 1 function [`daxpy`][daxpy] with the exception that this implementation works with any array type, not just Float64Arrays. Depending on the environment, the typed versions ([`daxpy`][@stdlib/blas/base/daxpy], [`saxpy`][@stdlib/blas/base/saxpy], etc.) are likely to be significantly more performant. +- 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]). @@ -174,14 +175,14 @@ console.log( y ); [daxpy]: http://www.netlib.org/lapack/explore-html/de/da4/group__double__blas__level1.html -[mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array - [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray [@stdlib/blas/base/daxpy]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/base/daxpy [@stdlib/blas/base/saxpy]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/base/saxpy +[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor + diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/docs/repl.txt b/lib/node_modules/@stdlib/blas/base/gaxpy/docs/repl.txt index adeb7be941b5..330a5a8d813b 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/docs/repl.txt +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/docs/repl.txt @@ -19,13 +19,13 @@ Constant. x: Array|TypedArray - Input array. + First input array. strideX: integer Index increment for `x`. y: Array|TypedArray - Output array. + Second input array. strideY: integer Index increment for `y`. @@ -33,7 +33,7 @@ Returns ------- y: Array|TypedArray - Output array. + Input array `y`. Examples -------- @@ -77,7 +77,7 @@ Constant. x: Array|TypedArray - Input array. + First input array. strideX: integer Index increment for `x`. @@ -86,7 +86,7 @@ Starting index for `x`. y: Array|TypedArray - Output array. + Second input array. strideY: integer Index increment for `y`. @@ -97,7 +97,7 @@ Returns ------- y: Array|TypedArray - Output array. + Input array `y`. Examples -------- diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/index.d.ts b/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/index.d.ts index 24e19a343622..22c592ef6799 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/index.d.ts @@ -20,7 +20,12 @@ /// -import { NumericArray } from '@stdlib/types/array'; +import { NumericArray, Collection, AccessorArrayLike } from '@stdlib/types/array'; + +/** +* Input array. +*/ +type InputArray = NumericArray | Collection | AccessorArrayLike; /** * Interface describing `gaxpy`. @@ -44,7 +49,7 @@ interface Routine { * gaxpy( x.length, 5.0, x, 1, y, 1 ); * // y => [ 6.0, 11.0, 16.0, 21.0, 26.0 ] */ - ( N: number, alpha: number, x: NumericArray, strideX: number, y: NumericArray, strideY: number ): NumericArray; + ( N: number, alpha: number, x: InputArray, strideX: number, y: T, strideY: number ): T; /** * Multiplies `x` by a constant `alpha` and adds the result to `y` using alternative indexing semantics. @@ -66,7 +71,7 @@ interface Routine { * gaxpy.ndarray( x.length, 5.0, x, 1, 0, y, 1, 0 ); * // y => [ 6.0, 11.0, 16.0, 21.0, 26.0 ] */ - ndarray( N: number, alpha: number, x: NumericArray, strideX: number, offsetX: number, y: NumericArray, strideY: number, offsetY: number ): NumericArray; + ndarray( N: number, alpha: number, x: InputArray, strideX: number, offsetX: number, y: T, strideY: number, offsetY: number ): T; } /** diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/test.ts b/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/test.ts index 87f013357bdb..dce7e9be0ca0 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/test.ts +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/docs/types/test.ts @@ -21,12 +21,12 @@ import gaxpy = require( './index' ); // TESTS // -// The function returns a numeric array... +// The function returns an array... { const x = new Float64Array( 10 ); const y = new Float64Array( 10 ); - gaxpy( x.length, 5.0, x, 1, y, 1 ); // $ExpectType NumericArray + gaxpy( x.length, 5.0, x, 1, y, 1 ); // $ExpectType Float64Array } // The compiler throws an error if the function is provided a first argument which is not a number... @@ -134,12 +134,12 @@ import gaxpy = require( './index' ); gaxpy( x.length, 5.0, x, 1, y, 1, 10 ); // $ExpectError } -// Attached to main export is an `ndarray` method which returns a numeric array... +// Attached to main export is an `ndarray` method which returns an array... { const x = new Float64Array( 10 ); const y = new Float64Array( 10 ); - gaxpy.ndarray( x.length, 5.0, x, 1, 0, y, 1, 0 ); // $ExpectType NumericArray + gaxpy.ndarray( x.length, 5.0, x, 1, 0, y, 1, 0 ); // $ExpectType Float64Array } // 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/base/gaxpy/lib/accessors.js b/lib/node_modules/@stdlib/blas/base/gaxpy/lib/accessors.js new file mode 100644 index 000000000000..3140b6f9b07a --- /dev/null +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/lib/accessors.js @@ -0,0 +1,81 @@ +/** +* @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'; + +// MAIN // + +/** +* Multiplies a vector `x` by a constant and adds the result to `y`. +* +* @private +* @param {PositiveInteger} N - number of indexed elements +* @param {number} alpha - scalar +* @param {Object} x - input array object +* @param {Collection} x.data - input array data +* @param {Array} x.accessors - array element accessors +* @param {integer} strideX - `x` stride length +* @param {NonNegativeInteger} offsetX - starting `x` index +* @param {Object} y - output array object +* @param {Collection} y.data - output array data +* @param {Array} y.accessors - array element accessors +* @param {integer} strideY - `y` stride length +* @param {NonNegativeInteger} offsetY - starting `y` index +* @returns {Object} output array object +* +* @example +* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); +* var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +* +* var x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; +* var y = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; +* +* gaxpy( x.length, 5.0, arraylike2object( toAccessorArray( x ) ), 1, 0, arraylike2object( toAccessorArray( y ) ), 1, 0 ); +* // y => [ 6.0, 11.0, 16.0, 21.0, 26.0 ] +*/ +function gaxpy( N, alpha, x, strideX, offsetX, y, strideY, offsetY ) { + var xbuf; + var ybuf; + var set; + var get; + var ix; + var iy; + var i; + + // Cache references to array data: + xbuf = x.data; + ybuf = y.data; + + // Cache references to element accessors: + get = x.accessors[ 0 ]; + set = y.accessors[ 1 ]; + + ix = offsetX; + iy = offsetY; + for ( i = 0; i < N; i++ ) { + set( ybuf, iy, get( ybuf, iy ) + ( alpha * get( xbuf, ix ) ) ); + ix += strideX; + iy += strideY; + } + return y; +} + + +// EXPORTS // + +module.exports = gaxpy; diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/lib/main.js b/lib/node_modules/@stdlib/blas/base/gaxpy/lib/main.js index 9e1ae33b6461..7094c3fd2809 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/lib/main.js +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/lib/main.js @@ -18,9 +18,10 @@ 'use strict'; -// VARIABLES // +// MODULES // -var M = 4; +var stride2offset = require( '@stdlib/strided/base/stride2offset' ); +var ndarray = require( './ndarray.js' ); // MAIN // @@ -45,50 +46,7 @@ var M = 4; * // y => [ 6.0, 11.0, 16.0, 21.0, 26.0 ] */ function gaxpy( N, alpha, x, strideX, y, strideY ) { - var ix; - var iy; - var m; - var i; - if ( N <= 0 || alpha === 0.0 ) { - return y; - } - // Use unrolled loops if both strides are equal to `1`... - if ( strideX === 1 && strideY === 1 ) { - m = N % M; - - // If we have a remainder, run a clean-up loop... - if ( m > 0 ) { - for ( i = 0; i < m; i++ ) { - y[ i ] += alpha * x[ i ]; - } - } - if ( N < M ) { - return y; - } - for ( i = m; i < N; i += M ) { - y[ i ] += alpha * x[ i ]; - y[ i+1 ] += alpha * x[ i+1 ]; - y[ i+2 ] += alpha * x[ i+2 ]; - y[ i+3 ] += alpha * x[ i+3 ]; - } - return y; - } - if ( strideX < 0 ) { - ix = (1-N) * strideX; - } else { - ix = 0; - } - if ( strideY < 0 ) { - iy = (1-N) * strideY; - } else { - iy = 0; - } - for ( i = 0; i < N; i++ ) { - y[ iy ] += alpha * x[ ix ]; - ix += strideX; - iy += strideY; - } - return y; + return ndarray( N, alpha, x, strideX, stride2offset( N, strideX ), y, strideY, stride2offset( N, strideY ) ); // eslint-disable-line max-len } diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/lib/ndarray.js b/lib/node_modules/@stdlib/blas/base/gaxpy/lib/ndarray.js index 3b698477d6a6..92f6fb07497b 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/lib/ndarray.js +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/lib/ndarray.js @@ -18,6 +18,12 @@ 'use strict'; +// MODULES // + +var arraylike2object = require( '@stdlib/array/base/arraylike2object' ); +var accessors = require( './accessors.js' ); + + // VARIABLES // var M = 4; @@ -49,11 +55,19 @@ var M = 4; function gaxpy( N, alpha, x, strideX, offsetX, y, strideY, offsetY ) { var ix; var iy; + var ox; + var oy; var m; var i; if ( N <= 0 || alpha === 0.0 ) { return y; } + ox = arraylike2object( x ); + oy = arraylike2object( y ); + if ( ox.accessorProtocol || oy.accessorProtocol ) { + accessors( N, alpha, ox, strideX, offsetX, oy, strideY, offsetY ); + return oy.data; + } ix = offsetX; iy = offsetY; diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.main.js b/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.main.js index 0df2f972db81..9e5775411fa4 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.main.js +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.main.js @@ -22,6 +22,7 @@ var tape = require( 'tape' ); var Float64Array = require( '@stdlib/array/float64' ); +var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var gaxpy = require( './../lib/main.js' ); @@ -67,6 +68,35 @@ tape( 'the function multiplies `x` by a constant and adds the result to `y`', fu t.end(); }); +tape( 'the function multiplies `x` by a constant and adds the result to `y` (accessors)', function test( t ) { + var expected; + var alpha; + var x; + var y; + + alpha = 2.0; + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + expected = [ 3.0, 5.0, 7.0, 9.0, 11.0 ]; + + gaxpy( x.length, alpha, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + + t.deepEqual( y, expected, 'returns expected value' ); + + // Short datasets: + x = [ 1.0, 2.0 ]; + y = [ 1.0, 1.0 ]; + + expected = [ 3.0, 5.0 ]; + + gaxpy( x.length, alpha, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function efficiently handles the case where `alpha` is `0`', function test( t ) { var expected; var alpha; @@ -85,6 +115,24 @@ tape( 'the function efficiently handles the case where `alpha` is `0`', function t.end(); }); +tape( 'the function efficiently handles the case where `alpha` is `0` (accessors)', function test( t ) { + var expected; + var alpha; + var x; + var y; + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + alpha = 0.0; + + expected = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + gaxpy( x.length, alpha, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports an `x` stride', function test( t ) { var expected; var x; @@ -115,6 +163,36 @@ tape( 'the function supports an `x` stride', function test( t ) { t.end(); }); +tape( 'the function supports an `x` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 0 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 2 + ]; + y = [ + 1.0, // 0 + 1.0, // 1 + 1.0, // 2 + 1.0, + 1.0 + ]; + N = 3; + + gaxpy( N, 2.0, toAccessorArray( x ), 2, toAccessorArray( y ), 1 ); + + expected = [ 3.0, 7.0, 11.0, 1.0, 1.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports a `y` stride', function test( t ) { var expected; var x; @@ -145,6 +223,36 @@ tape( 'the function supports a `y` stride', function test( t ) { t.end(); }); +tape( 'the function supports a `y` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 0 + 2.0, // 1 + 3.0, // 2 + 4.0, + 5.0 + ]; + y = [ + 1.0, // 0 + 1.0, + 1.0, // 1 + 1.0, + 1.0 // 2 + ]; + N = 3; + + gaxpy( N, 2.0, toAccessorArray( x ), 1, toAccessorArray( y ), 2 ); + + expected = [ 3.0, 1.0, 5.0, 1.0, 7.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function returns a reference to the destination array', function test( t ) { var out; var x; @@ -159,6 +267,20 @@ tape( 'the function returns a reference to the destination array', function test t.end(); }); +tape( 'the function returns a reference to the destination 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( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] ); + + out = gaxpy( x.length, 3.0, x, 1, y, 1 ); + + t.strictEqual( out, y, 'returns expected value' ); + 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; @@ -178,6 +300,25 @@ tape( 'if provided an `N` parameter less than or equal to `0`, the function retu t.end(); }); +tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 6.0, 7.0, 8.0, 9.0, 10.0 ]; + + expected = [ 6.0, 7.0, 8.0, 9.0, 10.0 ]; + + gaxpy( -1, 3.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + t.deepEqual( y, expected, 'returns expected value' ); + + gaxpy( 0, 3.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 ); + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function supports negative strides', function test( t ) { var expected; var x; @@ -208,6 +349,36 @@ tape( 'the function supports negative strides', function test( t ) { t.end(); }); +tape( 'the function supports negative strides (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 2 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 0 + ]; + y = [ + 6.0, // 2 + 7.0, // 1 + 8.0, // 0 + 9.0, + 10.0 + ]; + N = 3; + + gaxpy( N, 3.0, toAccessorArray( x ), -2, toAccessorArray( y ), -1 ); + + expected = [ 9.0, 16.0, 23.0, 9.0, 10.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports complex access patterns', function test( t ) { var expected; var x; @@ -240,6 +411,38 @@ tape( 'the function supports complex access patterns', function test( t ) { t.end(); }); +tape( 'the function supports complex access patterns (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 0 + 2.0, + 3.0, // 1 + 4.0, + 5.0, // 2 + 6.0 + ]; + y = [ + 7.0, // 2 + 8.0, // 1 + 9.0, // 0 + 10.0, + 11.0, + 12.0 + ]; + N = 3; + + gaxpy( N, 3.0, toAccessorArray( x ), 2, toAccessorArray( y ), -1 ); + + expected = [ 22.0, 17.0, 12.0, 10.0, 11.0, 12.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports view offsets', function test( t ) { var expected; var x0; @@ -292,9 +495,9 @@ tape( 'if both strides are equal to `1`, the function efficiently multiplies `x` alpha = 3.0; - x = new Array( 100 ); - y = new Array( x.length ); - expected = new Array( x.length ); + x = new Float64Array( 100 ); + y = new Float64Array( x.length ); + expected = new Float64Array( x.length ); for ( i = 0; i < x.length; i++ ) { x[ i ] = i; y[ i ] = x.length - i; @@ -305,9 +508,9 @@ tape( 'if both strides are equal to `1`, the function efficiently multiplies `x` t.deepEqual( y, expected, 'returns expected value' ); - x = new Array( 123 ); - y = new Array( x.length ); - expected = new Array( x.length ); + x = new Float64Array( 123 ); + y = new Float64Array( x.length ); + expected = new Float64Array( x.length ); for ( i = 0; i < x.length; i++ ) { x[ i ] = i*2; y[ i ] = x.length - i; @@ -317,6 +520,5 @@ tape( 'if both strides are equal to `1`, the function efficiently multiplies `x` gaxpy( x.length, alpha, x, 1, y, 1 ); t.deepEqual( y, expected, 'returns expected value' ); - t.end(); }); diff --git a/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.ndarray.js b/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.ndarray.js index 492343253d65..420fc525878d 100644 --- a/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.ndarray.js +++ b/lib/node_modules/@stdlib/blas/base/gaxpy/test/test.ndarray.js @@ -16,11 +16,15 @@ * limitations under the License. */ +/* eslint-disable max-len */ + 'use strict'; // MODULES // var tape = require( 'tape' ); +var Float64Array = require( '@stdlib/array/float64' ); +var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var gaxpy = require( './../lib/ndarray.js' ); @@ -66,6 +70,35 @@ tape( 'the function multiplies `x` by a constant and adds the result to `y`', fu t.end(); }); +tape( 'the function multiplies `x` by a constant and adds the result to `y` (accessors)', function test( t ) { + var expected; + var alpha; + var x; + var y; + + alpha = 2.0; + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + expected = [ 3.0, 5.0, 7.0, 9.0, 11.0 ]; + + gaxpy( x.length, alpha, x, 1, 0, y, 1, 0 ); + + t.deepEqual( y, expected, 'returns expected value' ); + + // Short datasets: + x = [ 1.0, 2.0 ]; + y = [ 1.0, 1.0 ]; + + expected = [ 3.0, 5.0 ]; + + gaxpy( x.length, alpha, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function efficiently handles the case where `alpha` is `0`', function test( t ) { var expected; var alpha; @@ -84,6 +117,24 @@ tape( 'the function efficiently handles the case where `alpha` is `0`', function t.end(); }); +tape( 'the function efficiently handles the case where `alpha` is `0` (accessors)', function test( t ) { + var expected; + var alpha; + var x; + var y; + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + alpha = 0.0; + + expected = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; + + gaxpy( x.length, alpha, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports an `x` stride', function test( t ) { var expected; var x; @@ -114,6 +165,36 @@ tape( 'the function supports an `x` stride', function test( t ) { t.end(); }); +tape( 'the function supports an `x` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 0 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 2 + ]; + y = [ + 1.0, // 0 + 1.0, // 1 + 1.0, // 2 + 1.0, + 1.0 + ]; + N = 3; + + gaxpy( N, 2.0, toAccessorArray( x ), 2, 0, toAccessorArray( y ), 1, 0 ); + + expected = [ 3.0, 7.0, 11.0, 1.0, 1.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports an `x` offset', function test( t ) { var expected; var x; @@ -144,6 +225,36 @@ tape( 'the function supports an `x` offset', function test( t ) { t.end(); }); +tape( 'the function supports an `x` offset (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, + 2.0, + 3.0, // 0 + 4.0, // 1 + 5.0 // 2 + ]; + y = [ + 6.0, // 0 + 7.0, // 1 + 8.0, // 2 + 9.0, + 10.0 + ]; + N = 3; + + gaxpy( N, 3.0, toAccessorArray( x ), 1, 2, toAccessorArray( y ), 1, 0 ); + + expected = [ 15.0, 19.0, 23.0, 9.0, 10.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports a `y` stride', function test( t ) { var expected; var x; @@ -174,6 +285,36 @@ tape( 'the function supports a `y` stride', function test( t ) { t.end(); }); +tape( 'the function supports a `y` stride (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 0 + 2.0, // 1 + 3.0, // 2 + 4.0, + 5.0 + ]; + y = [ + 1.0, // 0 + 1.0, + 1.0, // 1 + 1.0, + 1.0 // 2 + ]; + N = 3; + + gaxpy( N, 2, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 2, 0 ); + + expected = [ 3.0, 1.0, 5.0, 1.0, 7.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports a `y` offset', function test( t ) { var expected; var x; @@ -204,6 +345,36 @@ tape( 'the function supports a `y` offset', function test( t ) { t.end(); }); +tape( 'the function supports a `y` offset (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 0 + 2.0, // 1 + 3.0, // 2 + 4.0, + 5.0 + ]; + y = [ + 6.0, + 7.0, + 8.0, // 0 + 9.0, // 1 + 10.0 // 2 + ]; + N = 3; + + gaxpy( N, 3.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 2 ); + + expected = [ 6.0, 7.0, 11.0, 15.0, 19.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function returns a reference to the destination array', function test( t ) { var out; var x; @@ -218,6 +389,20 @@ tape( 'the function returns a reference to the destination array', function test t.end(); }); +tape( 'the function returns a reference to the destination 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( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] ); + + out = gaxpy( x.length, 3.0, x, 1, 0, y, 1, 0 ); + + t.strictEqual( out, y, 'returns expected value' ); + 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; @@ -237,6 +422,25 @@ tape( 'if provided an `N` parameter less than or equal to `0`, the function retu t.end(); }); +tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged (accessors)', function test( t ) { + var expected; + var x; + var y; + + x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]; + y = [ 6.0, 7.0, 8.0, 9.0, 10.0 ]; + + expected = [ 6.0, 7.0, 8.0, 9.0, 10.0 ]; + + gaxpy( -1, 3.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + t.deepEqual( y, expected, 'returns expected value' ); + + gaxpy( 0, 3.0, toAccessorArray( x ), 1, 0, toAccessorArray( y ), 1, 0 ); + t.deepEqual( y, expected, 'returns expected value' ); + + t.end(); +}); + tape( 'the function supports negative strides', function test( t ) { var expected; var x; @@ -267,6 +471,36 @@ tape( 'the function supports negative strides', function test( t ) { t.end(); }); +tape( 'the function supports negative strides (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, // 2 + 2.0, + 3.0, // 1 + 4.0, + 5.0 // 0 + ]; + y = [ + 6.0, + 7.0, // 2 + 8.0, // 1 + 9.0, // 0 + 10.0 + ]; + N = 3; + + gaxpy( N, 3.0, toAccessorArray( x ), -2, x.length-1, toAccessorArray( y ), -1, y.length-2 ); + + expected = [ 6.0, 10.0, 17.0, 24.0, 10.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'the function supports complex access patterns', function test( t ) { var expected; var x; @@ -299,6 +533,38 @@ tape( 'the function supports complex access patterns', function test( t ) { t.end(); }); +tape( 'the function supports complex access patterns (accessors)', function test( t ) { + var expected; + var x; + var y; + var N; + + x = [ + 1.0, + 2.0, // 0 + 3.0, + 4.0, // 1 + 5.0, + 6.0 // 2 + ]; + y = [ + 7.0, + 8.0, + 9.0, + 10.0, // 2 + 11.0, // 1 + 12.0 // 0 + ]; + N = 3; + + gaxpy( N, 3.0, toAccessorArray( x ), 2, 1, toAccessorArray( y ), -1, y.length-1 ); + + expected = [ 7.0, 8.0, 9.0, 28.0, 23.0, 18.0 ]; + + t.deepEqual( y, expected, 'returns expected value' ); + t.end(); +}); + tape( 'if both strides are equal to `1`, the function efficiently iterates over provided arrays', function test( t ) { var expected; var alpha; @@ -308,9 +574,9 @@ tape( 'if both strides are equal to `1`, the function efficiently iterates over alpha = 3.0; - x = new Array( 100 ); - y = new Array( x.length ); - expected = new Array( x.length ); + x = new Float64Array( 100 ); + y = new Float64Array( x.length ); + expected = new Float64Array( x.length ); for ( i = 0; i < x.length; i++ ) { x[ i ] = i; y[ i ] = x.length - i; @@ -321,9 +587,9 @@ tape( 'if both strides are equal to `1`, the function efficiently iterates over t.deepEqual( y, expected, 'returns expected value' ); - x = new Array( 123 ); - y = new Array( x.length ); - expected = new Array( x.length ); + x = new Float64Array( 123 ); + y = new Float64Array( x.length ); + expected = new Float64Array( x.length ); for ( i = 0; i < x.length; i++ ) { x[ i ] = i*2; y[ i ] = x.length - i; @@ -333,6 +599,5 @@ tape( 'if both strides are equal to `1`, the function efficiently iterates over gaxpy( x.length, alpha, x, 1, 0, y, 1, 0 ); t.deepEqual( y, expected, 'returns expected value' ); - t.end(); });