Skip to content

Commit 6af5789

Browse files
headlessNodekgryte
andauthored
feat: add accessor arrays support to blas/ext/base/gapx
PR-URL: #4926 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com>
1 parent 82283c4 commit 6af5789

File tree

7 files changed

+295
-5
lines changed

7 files changed

+295
-5
lines changed

lib/node_modules/@stdlib/blas/ext/base/gapx/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ gapx.ndarray( 3, 5.0, x, 1, x.length-3 );
106106
## Notes
107107

108108
- If `N <= 0`, both functions return `x` unchanged.
109+
- 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])
109110
- Depending on the environment, the typed versions ([`dapx`][@stdlib/blas/ext/base/dapx], [`sapx`][@stdlib/blas/ext/base/sapx], etc.) are likely to be significantly more performant.
110111

111112
</section>
@@ -158,6 +159,8 @@ console.log( x );
158159

159160
[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
160161

162+
[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
163+
161164
<!-- <related-links> -->
162165

163166
[@stdlib/blas/ext/base/dapx]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/ext/base/dapx

lib/node_modules/@stdlib/blas/ext/base/gapx/docs/types/index.d.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@
2020

2121
/// <reference types="@stdlib/types"/>
2222

23-
import { NumericArray } from '@stdlib/types/array';
23+
import { NumericArray, Collection, AccessorArrayLike } from '@stdlib/types/array';
24+
25+
/**
26+
* Input array.
27+
*/
28+
type InputArray = NumericArray | Collection<number> | AccessorArrayLike<number>;
2429

2530
/**
2631
* Interface describing `gapx`.
@@ -41,7 +46,7 @@ interface Routine {
4146
* gapx( x.length, 5.0, x, 1 );
4247
* // x => [ 3.0, 6.0, 8.0, 0.0, 9.0, 5.0, 4.0, 2.0 ]
4348
*/
44-
( N: number, alpha: number, x: NumericArray, strideX: number ): NumericArray;
49+
<T extends InputArray>( N: number, alpha: number, x: T, strideX: number ): T;
4550

4651
/**
4752
* Adds a scalar constant to each element in a strided array using alternative indexing semantics.
@@ -59,7 +64,7 @@ interface Routine {
5964
* gapx.ndarray( x.length, 5.0, x, 1, 0 );
6065
* // x => [ 3.0, 6.0, 8.0, 0.0, 9.0, 5.0, 4.0, 2.0 ]
6166
*/
62-
ndarray( N: number, alpha: number, x: NumericArray, strideX: number, offsetX: number ): NumericArray;
67+
ndarray<T extends InputArray>( N: number, alpha: number, x: T, strideX: number, offsetX: number ): T;
6368
}
6469

6570
/**

lib/node_modules/@stdlib/blas/ext/base/gapx/docs/types/test.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* limitations under the License.
1717
*/
1818

19+
import AccessorArray = require( '@stdlib/array/base/accessor' );
1920
import gapx = require( './index' );
2021

2122

@@ -25,7 +26,8 @@ import gapx = require( './index' );
2526
{
2627
const x = new Float64Array( 10 );
2728

28-
gapx( x.length, 5.0, x, 1 ); // $ExpectType NumericArray
29+
gapx( x.length, 5.0, x, 1 ); // $ExpectType Float64Array
30+
gapx( x.length, 5.0, new AccessorArray( x ), 1 ); // $ExpectType AccessorArray
2931
}
3032

3133
// The compiler throws an error if the function is provided a first argument which is not a number...
@@ -100,7 +102,8 @@ import gapx = require( './index' );
100102
{
101103
const x = new Float64Array( 10 );
102104

103-
gapx.ndarray( x.length, 5.0, x, 1, 0 ); // $ExpectType NumericArray
105+
gapx.ndarray( x.length, 5.0, x, 1, 0 ); // $ExpectType Float64Array
106+
gapx.ndarray( x.length, 5.0, new AccessorArray( x ), 1, 0 ); // $ExpectType AccessorArray
104107
}
105108

106109
// The compiler throws an error if the `ndarray` method is provided a first argument which is not a number...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MAIN //
22+
23+
/**
24+
* Adds a scalar constant to each element in a strided array.
25+
*
26+
* @private
27+
* @param {PositiveInteger} N - number of indexed elements
28+
* @param {number} alpha - scalar constant
29+
* @param {Object} x - input array object
30+
* @param {Collection} x.data - input array data
31+
* @param {Array<Function>} x.accessors - array element accessors
32+
* @param {integer} strideX - stride length
33+
* @param {NonNegativeInteger} offsetX - starting index
34+
* @returns {Object} input array object
35+
*
36+
* @example
37+
* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
38+
* var arraylike2object = require( '@stdlib/array/base/arraylike2object' );
39+
*
40+
* var x = toAccessorArray( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
41+
*
42+
* var v = gapx( 4, 5.0, arraylike2object( x ), 2, 1 );
43+
* // returns {...}
44+
*/
45+
function gapx( N, alpha, x, strideX, offsetX ) {
46+
var xbuf;
47+
var get;
48+
var set;
49+
var ix;
50+
var i;
51+
52+
// Cache reference to array data:
53+
xbuf = x.data;
54+
55+
// Cache reference to the element accessors:
56+
get = x.accessors[ 0 ];
57+
set = x.accessors[ 1 ];
58+
59+
ix = offsetX;
60+
for ( i = 0; i < N; i++ ) {
61+
set( xbuf, ix, alpha + get( xbuf, ix ) );
62+
ix += strideX;
63+
}
64+
return x;
65+
}
66+
67+
68+
// EXPORTS //
69+
70+
module.exports = gapx;

lib/node_modules/@stdlib/blas/ext/base/gapx/lib/ndarray.js

+11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818

1919
'use strict';
2020

21+
// MODULES //
22+
23+
var arraylike2object = require( '@stdlib/array/base/arraylike2object' );
24+
var accessors = require( './accessors.js' );
25+
26+
2127
// VARIABLES //
2228

2329
var M = 5;
@@ -44,11 +50,16 @@ var M = 5;
4450
function gapx( N, alpha, x, strideX, offsetX ) {
4551
var ix;
4652
var m;
53+
var o;
4754
var i;
4855

4956
if ( N <= 0 || alpha === 0.0 ) {
5057
return x;
5158
}
59+
o = arraylike2object( x );
60+
if ( o.accessorProtocol ) {
61+
return accessors( N, alpha, o, strideX, offsetX );
62+
}
5263
ix = offsetX;
5364

5465
// Use loop unrolling if the stride is equal to `1`...

lib/node_modules/@stdlib/blas/ext/base/gapx/test/test.main.js

+86
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
var tape = require( 'tape' );
2424
var Float64Array = require( '@stdlib/array/float64' );
25+
var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
2526
var gapx = require( './../lib' );
2627

2728

@@ -75,6 +76,43 @@ tape( 'the function adds a constant to each element of a strided array', functio
7576
t.end();
7677
});
7778

79+
tape( 'the function adds a constant to each element of a strided array (accessors)', function test( t ) {
80+
var expected;
81+
var x;
82+
83+
x = [
84+
4.0,
85+
2.0,
86+
-3.0,
87+
5.0,
88+
-1.0,
89+
2.0,
90+
-5.0,
91+
6.0
92+
];
93+
expected = [
94+
9.0,
95+
7.0,
96+
2.0,
97+
10.0,
98+
4.0,
99+
7.0,
100+
0.0,
101+
11.0
102+
];
103+
104+
gapx( x.length, 5.0, toAccessorArray( x ), 1 );
105+
t.deepEqual( x, expected, 'returns expected value' );
106+
107+
x = [ 1.0, 2.0 ];
108+
expected = [ 6.0, 7.0 ];
109+
110+
gapx( x.length, 5.0, toAccessorArray( x ), 1 );
111+
t.deepEqual( x, expected, 'returns expected value' );
112+
113+
t.end();
114+
});
115+
78116
tape( 'the function returns a reference to the input array', function test( t ) {
79117
var out;
80118
var x;
@@ -139,6 +177,30 @@ tape( 'the function supports specifying a stride', function test( t ) {
139177
t.end();
140178
});
141179

180+
tape( 'the function supports specifying a stride (accessors)', function test( t ) {
181+
var expected;
182+
var x;
183+
184+
x = [
185+
2.0, // 0
186+
-3.0,
187+
-5.0, // 1
188+
7.0,
189+
6.0 // 2
190+
];
191+
expected = [
192+
7.0, // 0
193+
-3.0,
194+
0.0, // 1
195+
7.0,
196+
11.0 // 2
197+
];
198+
199+
gapx( 3, 5.0, toAccessorArray( x ), 2 );
200+
t.deepEqual( x, expected, 'returns expected value' );
201+
t.end();
202+
});
203+
142204
tape( 'the function supports specifying a negative stride', function test( t ) {
143205
var expected;
144206
var x;
@@ -163,6 +225,30 @@ tape( 'the function supports specifying a negative stride', function test( t ) {
163225
t.end();
164226
});
165227

228+
tape( 'the function supports specifying a negative stride (accessors)', function test( t ) {
229+
var expected;
230+
var x;
231+
232+
x = [
233+
2.0, // 2
234+
-3.0,
235+
-5.0, // 1
236+
7.0,
237+
6.0 // 0
238+
];
239+
expected = [
240+
7.0, // 2
241+
-3.0,
242+
0.0, // 1
243+
7.0,
244+
11.0 // 0
245+
];
246+
247+
gapx( 3, 5.0, toAccessorArray( x ), -2 );
248+
t.deepEqual( x, expected, 'returns expected value' );
249+
t.end();
250+
});
251+
166252
tape( 'the function supports view offsets', function test( t ) {
167253
var expected;
168254
var x0;

0 commit comments

Comments
 (0)