Skip to content

Commit e5a8c65

Browse files
feat: add accessor arrays support to blas/ext/base/gcusum
PR-URL: #5065 Reviewed-by: Athan Reines <kgryte@gmail.com> Co-authored-by: stdlib-bot <82920195+stdlib-bot@users.noreply.github.com>
1 parent ae4d64e commit e5a8c65

File tree

5 files changed

+473
-41
lines changed

5 files changed

+473
-41
lines changed

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

+3
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ gcusum.ndarray( 4, 0.0, x, 2, 1, y, -1, y.length-1 );
128128
## Notes
129129

130130
- If `N <= 0`, both functions return `y` unchanged.
131+
- 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])
131132
- Depending on the environment, the typed versions ([`dcusum`][@stdlib/blas/ext/base/dcusum], [`scusum`][@stdlib/blas/ext/base/scusum], etc.) are likely to be significantly more performant.
132133

133134
</section>
@@ -190,6 +191,8 @@ console.log( y );
190191

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

194+
[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
195+
193196
<!-- <related-links> -->
194197

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

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

+13-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@
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>;
29+
30+
/**
31+
* Output array.
32+
*/
33+
type OutputArray = NumericArray | Collection<number> | AccessorArrayLike<number>;
2434

2535
/**
2636
* Interface describing `gcusum`.
@@ -44,7 +54,7 @@ interface Routine {
4454
* gcusum( x.length, 0.0, x, 1, y, 1 );
4555
* // y => [ 1.0, -1.0, 1.0 ]
4656
*/
47-
( N: number, sum: number, x: NumericArray, strideX: number, y: NumericArray, strideY: number ): NumericArray;
57+
<T extends OutputArray>( N: number, sum: number, x: InputArray, strideX: number, y: T, strideY: number ): T;
4858

4959
/**
5060
* Computes the cumulative sum of strided array elements using alternative indexing semantics.
@@ -66,7 +76,7 @@ interface Routine {
6676
* gcusum.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 );
6777
* // y => [ 1.0, -1.0, 1.0 ]
6878
*/
69-
ndarray( N: number, sum: number, x: NumericArray, strideX: number, offsetX: number, y: NumericArray, strideY: number, offsetY: number ): NumericArray;
79+
ndarray<T extends OutputArray>( N: number, sum: number, x: InputArray, strideX: number, offsetX: number, y: T, strideY: number, offsetY: number ): T;
7080
}
7181

7282
/**

lib/node_modules/@stdlib/blas/ext/base/gcusum/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 gcusum = require( './index' );
2021

2122

@@ -26,7 +27,8 @@ import gcusum = require( './index' );
2627
const x = new Float64Array( 10 );
2728
const y = new Float64Array( 10 );
2829

29-
gcusum( x.length, 0.0, x, 1, y, 1 ); // $ExpectType NumericArray
30+
gcusum( x.length, 0.0, x, 1, y, 1 ); // $ExpectType Float64Array
31+
gcusum( x.length, 0.0, new AccessorArray( x ), 1, new AccessorArray( y ), 1 ); // $ExpectType AccessorArray<number>
3032
}
3133

3234
// The compiler throws an error if the function is provided a first argument which is not a number...
@@ -139,7 +141,8 @@ import gcusum = require( './index' );
139141
const x = new Float64Array( 10 );
140142
const y = new Float64Array( 10 );
141143

142-
gcusum.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType NumericArray
144+
gcusum.ndarray( x.length, 0.0, x, 1, 0, y, 1, 0 ); // $ExpectType Float64Array
145+
gcusum.ndarray( x.length, 0.0, new AccessorArray( x ), 1, 0, new AccessorArray( y ), 1, 0 ); // $ExpectType AccessorArray<number>
143146
}
144147

145148
// The compiler throws an error if the `ndarray` method is provided a first argument which is not a number...

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

+192-17
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
// MODULES //
2222

2323
var tape = require( 'tape' );
24-
var floor = require( '@stdlib/math/base/special/floor' );
2524
var isnan = require( '@stdlib/math/base/assert/is-nan' );
25+
var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
2626
var Float64Array = require( '@stdlib/array/float64' );
2727
var gcusum = require( './../lib' );
2828

@@ -128,6 +128,94 @@ tape( 'the function computes the cumulative sum', function test( t ) {
128128
t.end();
129129
});
130130

131+
tape( 'the function computes the cumulative sum (accessors)', function test( t ) {
132+
var expected;
133+
var x;
134+
var y;
135+
var i;
136+
137+
x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ];
138+
y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ];
139+
140+
gcusum( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
141+
expected = [
142+
1.0,
143+
3.0,
144+
6.0,
145+
10.0,
146+
15.0
147+
];
148+
t.deepEqual( y, expected, 'returns expected value' );
149+
150+
x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ];
151+
y = [ 0.0, 0.0, 0.0, 0.0, 0.0 ];
152+
153+
gcusum( x.length, 10.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
154+
expected = [
155+
11.0,
156+
13.0,
157+
16.0,
158+
20.0,
159+
25.0
160+
];
161+
t.deepEqual( y, expected, 'returns expected value' );
162+
163+
x = [ NaN, NaN ];
164+
y = [ 0.0, 0.0 ];
165+
gcusum( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
166+
167+
for ( i = 0; i < y.length; i++ ) {
168+
t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
169+
}
170+
171+
x = [ 1.0, NaN, 3.0, NaN ];
172+
y = [ 0.0, 0.0, 0.0, 0.0 ];
173+
gcusum( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
174+
175+
expected = [
176+
1.0,
177+
NaN,
178+
NaN,
179+
NaN
180+
];
181+
for ( i = 0; i < y.length; i++ ) {
182+
if ( isnan( expected[ i ] ) ) {
183+
t.strictEqual( isnan( y[ i ] ), true, 'returns expected value. i: ' + i );
184+
} else {
185+
t.strictEqual( y[ i ], expected[ i ], true, 'returns expected value. i: ' + i );
186+
}
187+
}
188+
189+
x = [ 1.0, 1.0e100, 1.0, -1.0e100 ];
190+
y = [ 0.0, 0.0, 0.0, 0.0 ];
191+
gcusum( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
192+
193+
expected = [
194+
1.0,
195+
1.0e100,
196+
1.0e100,
197+
2.0
198+
];
199+
t.deepEqual( y, expected, 'returns expected value' );
200+
201+
x = [];
202+
y = [];
203+
expected = [];
204+
for ( i = 0; i < 1e3; i++ ) {
205+
x.push( i+1 );
206+
y.push( 0.0 );
207+
if ( i === 0 ) {
208+
expected.push( x[ i ] );
209+
} else {
210+
expected.push( expected[ i-1 ] + x[ i ] );
211+
}
212+
}
213+
gcusum( x.length, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 1 );
214+
t.deepEqual( y, expected, 'returns expected value' );
215+
216+
t.end();
217+
});
218+
131219
tape( 'the function returns a reference to the output array', function test( t ) {
132220
var out;
133221
var x;
@@ -142,6 +230,20 @@ tape( 'the function returns a reference to the output array', function test( t )
142230
t.end();
143231
});
144232

233+
tape( 'the function returns a reference to the output array (accessors)', function test( t ) {
234+
var out;
235+
var x;
236+
var y;
237+
238+
x = toAccessorArray( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
239+
y = toAccessorArray( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] );
240+
241+
out = gcusum( x.length, 0.0, x, 1, y, 1 );
242+
243+
t.strictEqual( out, y, 'same reference' );
244+
t.end();
245+
});
246+
145247
tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) {
146248
var expected;
147249
var x;
@@ -165,7 +267,6 @@ tape( 'the function supports an `x` stride', function test( t ) {
165267
var expected;
166268
var x;
167269
var y;
168-
var N;
169270

170271
x = [
171272
1.0, // 0
@@ -181,9 +282,36 @@ tape( 'the function supports an `x` stride', function test( t ) {
181282
0.0,
182283
0.0
183284
];
184-
N = 3;
185285

186-
gcusum( N, 0.0, x, 2, y, 1 );
286+
gcusum( 3, 0.0, x, 2, y, 1 );
287+
288+
expected = [ 1.0, 4.0, 9.0, 0.0, 0.0 ];
289+
290+
t.deepEqual( y, expected, 'deep equal' );
291+
t.end();
292+
});
293+
294+
tape( 'the function supports an `x` stride (accessors)', function test( t ) {
295+
var expected;
296+
var x;
297+
var y;
298+
299+
x = [
300+
1.0, // 0
301+
2.0,
302+
3.0, // 1
303+
4.0,
304+
5.0 // 2
305+
];
306+
y = [
307+
0.0, // 0
308+
0.0, // 1
309+
0.0, // 2
310+
0.0,
311+
0.0
312+
];
313+
314+
gcusum( 3, 0.0, toAccessorArray( x ), 2, toAccessorArray( y ), 1 );
187315

188316
expected = [ 1.0, 4.0, 9.0, 0.0, 0.0 ];
189317

@@ -195,7 +323,6 @@ tape( 'the function supports a `y` stride', function test( t ) {
195323
var expected;
196324
var x;
197325
var y;
198-
var N;
199326

200327
x = [
201328
1.0, // 0
@@ -211,9 +338,36 @@ tape( 'the function supports a `y` stride', function test( t ) {
211338
0.0,
212339
0.0 // 2
213340
];
214-
N = 3;
215341

216-
gcusum( N, 0.0, x, 1, y, 2 );
342+
gcusum( 3, 0.0, x, 1, y, 2 );
343+
344+
expected = [ 1.0, 0.0, 3.0, 0.0, 6.0 ];
345+
346+
t.deepEqual( y, expected, 'deep equal' );
347+
t.end();
348+
});
349+
350+
tape( 'the function supports a `y` stride (accessors)', function test( t ) {
351+
var expected;
352+
var x;
353+
var y;
354+
355+
x = [
356+
1.0, // 0
357+
2.0, // 1
358+
3.0, // 2
359+
4.0,
360+
5.0
361+
];
362+
y = [
363+
0.0, // 0
364+
0.0,
365+
0.0, // 1
366+
0.0,
367+
0.0 // 2
368+
];
369+
370+
gcusum( 3, 0.0, toAccessorArray( x ), 1, toAccessorArray( y ), 2 );
217371

218372
expected = [ 1.0, 0.0, 3.0, 0.0, 6.0 ];
219373

@@ -225,7 +379,6 @@ tape( 'the function supports negative strides', function test( t ) {
225379
var expected;
226380
var x;
227381
var y;
228-
var N;
229382

230383
x = [
231384
1.0, // 2
@@ -241,9 +394,36 @@ tape( 'the function supports negative strides', function test( t ) {
241394
0.0,
242395
0.0
243396
];
244-
N = 3;
245397

246-
gcusum( N, 0.0, x, -2, y, -1 );
398+
gcusum( 3, 0.0, x, -2, y, -1 );
399+
400+
expected = [ 9.0, 8.0, 5.0, 0.0, 0.0 ];
401+
402+
t.deepEqual( y, expected, 'deep equal' );
403+
t.end();
404+
});
405+
406+
tape( 'the function supports negative strides (accessors)', function test( t ) {
407+
var expected;
408+
var x;
409+
var y;
410+
411+
x = [
412+
1.0, // 2
413+
2.0,
414+
3.0, // 1
415+
4.0,
416+
5.0 // 0
417+
];
418+
y = [
419+
0.0, // 2
420+
0.0, // 1
421+
0.0, // 0
422+
0.0,
423+
0.0
424+
];
425+
426+
gcusum( 3, 0.0, toAccessorArray( x ), -2, toAccessorArray( y ), -1 );
247427

248428
expected = [ 9.0, 8.0, 5.0, 0.0, 0.0 ];
249429

@@ -255,7 +435,6 @@ tape( 'the function supports complex access patterns', function test( t ) {
255435
var expected;
256436
var x;
257437
var y;
258-
var N;
259438

260439
x = [
261440
1.0, // 0
@@ -273,9 +452,8 @@ tape( 'the function supports complex access patterns', function test( t ) {
273452
0.0,
274453
0.0
275454
];
276-
N = 3;
277455

278-
gcusum( N, 0.0, x, 2, y, -1 );
456+
gcusum( 3, 0.0, x, 2, y, -1 );
279457

280458
expected = [ 9.0, 4.0, 1.0, 0.0, 0.0, 0.0 ];
281459

@@ -289,7 +467,6 @@ tape( 'the function supports view offsets', function test( t ) {
289467
var y0;
290468
var x1;
291469
var y1;
292-
var N;
293470

294471
// Initial arrays...
295472
x0 = new Float64Array([
@@ -313,9 +490,7 @@ tape( 'the function supports view offsets', function test( t ) {
313490
x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // begin at 2nd element
314491
y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // begin at the 4th element
315492

316-
N = floor( x0.length / 2 );
317-
318-
gcusum( N, 0.0, x1, -2, y1, 1 );
493+
gcusum( 3, 0.0, x1, -2, y1, 1 );
319494
expected = new Float64Array( [ 0.0, 0.0, 0.0, 6.0, 10.0, 12.0 ] );
320495

321496
t.deepEqual( y0, expected, 'deep equal' );

0 commit comments

Comments
 (0)