Skip to content

Commit 20f7173

Browse files
headlessNodekgryte
andauthored
feat: add accessor arrays support and refactor blas/ext/base/gsort2hp
PR-URL: stdlib-js#4660 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]>
1 parent 1c89f82 commit 20f7173

File tree

10 files changed

+1744
-265
lines changed

10 files changed

+1744
-265
lines changed

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

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var gsort2hp = require( '@stdlib/blas/ext/base/gsort2hp' );
3232

3333
#### gsort2hp( N, order, x, strideX, y, strideY )
3434

35-
Simultaneously sorts two strided arrays based on the sort order of the first array `x` using heapsort.
35+
Simultaneously sorts two strided arrays based on the sort order of the first array using heapsort.
3636

3737
```javascript
3838
var x = [ 1.0, -2.0, 3.0, -4.0 ];
@@ -52,20 +52,17 @@ The function has the following parameters:
5252
- **N**: number of indexed elements.
5353
- **order**: sort order. If `order < 0.0`, the input strided array `x` is sorted in **decreasing** order. If `order > 0.0`, the input strided array `x` is sorted in **increasing** order. If `order == 0.0`, the input strided arrays are left unchanged.
5454
- **x**: first input [`Array`][mdn-array] or [`typed array`][mdn-typed-array].
55-
- **strideX**: `x` index increment.
55+
- **strideX**: stride length for `x`.
5656
- **y**: second input [`Array`][mdn-array] or [`typed array`][mdn-typed-array].
57-
- **strideY**: `y` index increment.
57+
- **strideY**: stride length for `y`.
5858

59-
The `N` and `stride` parameters determine which elements in `x` and `y` are accessed at runtime. For example, to sort every other element
59+
The `N` and stride parameters determine which elements in the strided arrays are accessed at runtime. For example, to sort every other element:
6060

6161
```javascript
62-
var floor = require( '@stdlib/math/base/special/floor' );
63-
6462
var x = [ 1.0, -2.0, 3.0, -4.0 ];
6563
var y = [ 0.0, 1.0, 2.0, 3.0 ];
66-
var N = floor( x.length / 2 );
6764

68-
gsort2hp( N, -1.0, x, 2, y, 2 );
65+
gsort2hp( 2, -1.0, x, 2, y, 2 );
6966

7067
console.log( x );
7168
// => [ 3.0, -2.0, 1.0, -4.0 ]
@@ -78,7 +75,6 @@ Note that indexing is relative to the first index. To introduce an offset, use [
7875

7976
```javascript
8077
var Float64Array = require( '@stdlib/array/float64' );
81-
var floor = require( '@stdlib/math/base/special/floor' );
8278

8379
// Initial arrays...
8480
var x0 = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
@@ -87,10 +83,9 @@ var y0 = new Float64Array( [ 0.0, 1.0, 2.0, 3.0 ] );
8783
// Create offset views...
8884
var x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
8985
var y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
90-
var N = floor( x0.length/2 );
9186

9287
// Sort every other element...
93-
gsort2hp( N, -1.0, x1, 2, y1, 2 );
88+
gsort2hp( 2, -1.0, x1, 2, y1, 2 );
9489

9590
console.log( x0 );
9691
// => <Float64Array>[ 1.0, 4.0, 3.0, 2.0 ]
@@ -101,7 +96,7 @@ console.log( y0 );
10196

10297
#### gsort2hp.ndarray( N, order, x, strideX, offsetX, y, strideY, offsetY )
10398

104-
Simultaneously sorts two strided arrays based on the sort order of the first array `x` using heapsort and alternative indexing semantics.
99+
Simultaneously sorts two strided arrays based on the sort order of the first array using heapsort and alternative indexing semantics.
105100

106101
```javascript
107102
var x = [ 1.0, -2.0, 3.0, -4.0 ];
@@ -118,10 +113,10 @@ console.log( y );
118113

119114
The function has the following additional parameters:
120115

121-
- **offsetX**: `x` starting index.
122-
- **offsetY**: `y` starting index.
116+
- **offsetX**: starting index for `x`.
117+
- **offsetY**: starting index for `y`.
123118

124-
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to access only the last three elements of `x`
119+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on starting indices. For example, to access only the last three elements:
125120

126121
```javascript
127122
var x = [ 1.0, -2.0, 3.0, -4.0, 5.0, -6.0 ];
@@ -145,6 +140,7 @@ console.log( y );
145140
## Notes
146141

147142
- If `N <= 0` or `order == 0.0`, both functions leave `x` and `y` unchanged.
143+
- 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])
148144
- The algorithm distinguishes between `-0` and `+0`. When sorted in increasing order, `-0` is sorted before `+0`. When sorted in decreasing order, `-0` is sorted after `+0`.
149145
- The algorithm sorts `NaN` values to the end. When sorted in increasing order, `NaN` values are sorted last. When sorted in decreasing order, `NaN` values are sorted first.
150146
- The algorithm has space complexity `O(1)` and worst case time complexity `O(N^2)`.
@@ -164,30 +160,15 @@ console.log( y );
164160
<!-- eslint no-undef: "error" -->
165161

166162
```javascript
167-
var round = require( '@stdlib/math/base/special/round' );
168-
var randu = require( '@stdlib/random/base/randu' );
169-
var Float64Array = require( '@stdlib/array/float64' );
163+
var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
170164
var gsort2hp = require( '@stdlib/blas/ext/base/gsort2hp' );
171165

172-
var rand;
173-
var sign;
174-
var x;
175-
var y;
176-
var i;
177-
178-
x = new Float64Array( 10 );
179-
y = new Float64Array( 10 ); // index array
180-
for ( i = 0; i < x.length; i++ ) {
181-
rand = round( randu()*100.0 );
182-
sign = randu();
183-
if ( sign < 0.5 ) {
184-
sign = -1.0;
185-
} else {
186-
sign = 1.0;
187-
}
188-
x[ i ] = sign * rand;
189-
y[ i ] = i;
190-
}
166+
var x = discreteUniform( 10, -100, 100, {
167+
'dtype': 'float64'
168+
});
169+
var y = discreteUniform( 10, -100, 100, {
170+
'dtype': 'float64'
171+
});
191172
console.log( x );
192173
console.log( y );
193174

@@ -217,6 +198,8 @@ console.log( y );
217198

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

201+
[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
202+
220203
[@stdlib/blas/ext/base/dsort2hp]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/ext/base/dsort2hp
221204

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

lib/node_modules/@stdlib/blas/ext/base/gsort2hp/docs/repl.txt

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
Simultaneously sorts two strided arrays based on the sort order of the first
44
array using heapsort.
55

6-
The `N` and `stride` parameters determine which elements in `x` and `y` are
7-
accessed at runtime.
6+
The `N` and stride parameters determine which elements in the strided
7+
arrays are accessed at runtime.
88

99
Indexing is relative to the first index. To introduce an offset, use typed
1010
array views.
@@ -41,13 +41,13 @@
4141
First input array.
4242

4343
strideX: integer
44-
Index increment for `x`.
44+
Stride length for `x`.
4545

4646
y: Array<number>|TypedArray
4747
Second input array.
4848

4949
strideY: integer
50-
Index increment for `y`.
50+
Stride length for `y`.
5151

5252
Returns
5353
-------
@@ -64,11 +64,10 @@
6464
> y
6565
[ 3.0, 1.0, 0.0, 2.0 ]
6666

67-
// Using `N` and `stride` parameters:
67+
// Using `N` and stride parameters:
6868
> x = [ 1.0, -2.0, 3.0, -4.0 ];
6969
> y = [ 0.0, 1.0, 2.0, 3.0 ];
70-
> var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
71-
> {{alias}}( N, -1, x, 2, y, 2 )
70+
> {{alias}}( 2, -1, x, 2, y, 2 )
7271
[ 3.0, -2.0, 1.0, -4.0 ]
7372
> y
7473
[ 2.0, 1.0, 0.0, 3.0 ]
@@ -78,21 +77,21 @@
7877
> var x1 = new {{alias:@stdlib/array/float64}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 );
7978
> var y0 = new {{alias:@stdlib/array/float64}}( [ 0.0, 1.0, 2.0, 3.0 ] );
8079
> var y1 = new {{alias:@stdlib/array/float64}}( y0.buffer, y0.BYTES_PER_ELEMENT*1 );
81-
> N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 );
82-
> {{alias}}( N, 1, x1, 2, y1, 2 )
80+
> {{alias}}( 2, 1, x1, 2, y1, 2 )
8381
<Float64Array>[ -4.0, 3.0, -2.0 ]
8482
> x0
8583
<Float64Array>[ 1.0, -4.0, 3.0, -2.0 ]
8684
> y0
8785
<Float64Array>[ 0.0, 3.0, 2.0, 1.0 ]
8886

87+
8988
{{alias}}.ndarray( N, order, x, strideX, offsetX, y, strideY, offsetY )
9089
Simultaneously sorts two strided arrays based on the sort order of the first
9190
array using heapsort and alternative indexing semantics.
9291

9392
While typed array views mandate a view offset based on the underlying
94-
buffer, the `offset` parameter supports indexing semantics based on a
95-
starting index.
93+
buffer, the offset parameters support indexing semantics based on starting
94+
indices.
9695

9796
Parameters
9897
----------
@@ -107,7 +106,7 @@
107106
First input array.
108107

109108
strideX: integer
110-
Index increment for `x`.
109+
Stride length for `x`.
111110

112111
offsetX: integer
113112
Starting index of `x`.
@@ -116,7 +115,7 @@
116115
Second input array.
117116

118117
strideY: integer
119-
Index increment for `y`.
118+
Stride length for `y`.
120119

121120
offsetY: integer
122121
Starting index of `y`.
@@ -139,8 +138,7 @@
139138
// Using an index offset:
140139
> x = [ 1.0, -2.0, 3.0, -4.0 ];
141140
> y = [ 0.0, 1.0, 2.0, 3.0 ];
142-
> var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
143-
> {{alias}}.ndarray( N, 1, x, 2, 1, y, 2, 1 )
141+
> {{alias}}.ndarray( 2, 1, x, 2, 1, y, 2, 1 )
144142
[ 1.0, -4.0, 3.0, -2.0 ]
145143
> y
146144
[ 0.0, 3.0, 2.0, 1.0 ]

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

Lines changed: 16 additions & 11 deletions
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 `gsort2hp`.
@@ -32,9 +37,9 @@ interface Routine {
3237
* @param N - number of indexed elements
3338
* @param order - sort order
3439
* @param x - first input array
35-
* @param strideX - `x` stride length
40+
* @param strideX - stride length for `x`
3641
* @param y - second input array
37-
* @param strideY - `y` stride length
42+
* @param strideY - stride length for `x`
3843
* @returns `x`
3944
*
4045
* @example
@@ -49,19 +54,19 @@ interface Routine {
4954
* console.log( y );
5055
* // => [ 3.0, 1.0, 0.0, 2.0 ]
5156
*/
52-
( N: number, order: number, x: NumericArray, strideX: number, y: NumericArray, strideY: number ): NumericArray;
57+
<T extends InputArray>( N: number, order: number, x: InputArray, strideX: number, y: T, strideY: number ): T;
5358

5459
/**
5560
* Simultaneously sorts two strided arrays based on the sort order of the first array using heapsort and alternative indexing semantics.
5661
*
5762
* @param N - number of indexed elements
5863
* @param order - sort order
5964
* @param x - first input array
60-
* @param strideX - `x` stride length
61-
* @param offsetX - `x` starting index
65+
* @param strideX - stride length for `x`
66+
* @param offsetX - starting index for `x`
6267
* @param y - second input array
63-
* @param strideY - `y` stride length
64-
* @param offsetY - `y` starting index
68+
* @param strideY - stride length for `x`
69+
* @param offsetY - starting index for `y`
6570
* @returns `x`
6671
*
6772
* @example
@@ -76,7 +81,7 @@ interface Routine {
7681
* console.log( y );
7782
* // => [ 3.0, 1.0, 0.0, 2.0 ]
7883
*/
79-
ndarray( N: number, order: number, x: NumericArray, strideX: number, offsetX: number, y: NumericArray, strideY: number, offsetY: number ): NumericArray;
84+
ndarray<T extends InputArray>( N: number, order: number, x: InputArray, strideX: number, offsetX: number, y: T, strideY: number, offsetY: number ): T;
8085
}
8186

8287
/**
@@ -85,9 +90,9 @@ interface Routine {
8590
* @param N - number of indexed elements
8691
* @param order - sort order
8792
* @param x - first input array
88-
* @param strideX - `x` stride length
93+
* @param strideX - stride length for `x`
8994
* @param y - second input array
90-
* @param strideY - `y` stride length
95+
* @param strideY - stride length for `x`
9196
* @returns `x`
9297
*
9398
* @example

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

Lines changed: 5 additions & 2 deletions
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 gsort2hp = require( './index' );
2021

2122

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

29-
gsort2hp( x.length, 1, x, 1, y, 1 ); // $ExpectType NumericArray
30+
gsort2hp( x.length, 1, x, 1, y, 1 ); // $ExpectType Float64Array
31+
gsort2hp( x.length, 1, 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 gsort2hp = require( './index' );
139141
const x = new Float64Array( 10 );
140142
const y = new Float64Array( 10 );
141143

142-
gsort2hp.ndarray( x.length, 1, x, 1, 0, y, 1, 0 ); // $ExpectType NumericArray
144+
gsort2hp.ndarray( x.length, 1, x, 1, 0, y, 1, 0 ); // $ExpectType Float64Array
145+
gsort2hp.ndarray( x.length, 1, 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/gsort2hp/examples/index.js

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,15 @@
1818

1919
'use strict';
2020

21-
var round = require( '@stdlib/math/base/special/round' );
22-
var randu = require( '@stdlib/random/base/randu' );
23-
var Float64Array = require( '@stdlib/array/float64' );
21+
var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
2422
var gsort2hp = require( './../lib' );
2523

26-
var rand;
27-
var sign;
28-
var x;
29-
var y;
30-
var i;
31-
32-
x = new Float64Array( 10 );
33-
y = new Float64Array( 10 ); // index array
34-
for ( i = 0; i < x.length; i++ ) {
35-
if ( randu() < 0.2 ) {
36-
x[ i ] = NaN;
37-
} else {
38-
rand = round( randu()*100.0 );
39-
sign = randu();
40-
if ( sign < 0.5 ) {
41-
sign = -1.0;
42-
} else {
43-
sign = 1.0;
44-
}
45-
x[ i ] = sign * rand;
46-
}
47-
y[ i ] = i;
48-
}
24+
var x = discreteUniform( 10, -100, 100, {
25+
'dtype': 'float64'
26+
});
27+
var y = discreteUniform( 10, -100, 100, {
28+
'dtype': 'float64'
29+
});
4930
console.log( x );
5031
console.log( y );
5132

0 commit comments

Comments
 (0)