Skip to content

Commit 8ad374c

Browse files
authored
feat: add accessor arrays support and refactor blas/ext/base/gsort2sh
PR-URL: #5113 Reviewed-by: Athan Reines <kgryte@gmail.com>
1 parent bce4dac commit 8ad374c

File tree

10 files changed

+1700
-223
lines changed

10 files changed

+1700
-223
lines changed

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

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

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

35-
Simultaneously sorts two strided arrays based on the sort order of the first array `x` using Shellsort.
35+
Simultaneously sorts two strided arrays based on the sort order of the first array using Shellsort.
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-
gsort2sh( N, -1.0, x, 2, y, 2 );
65+
gsort2sh( 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-
gsort2sh( N, -1.0, x1, 2, y1, 2 );
88+
gsort2sh( 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
#### gsort2sh.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 Shellsort and alternative indexing semantics.
99+
Simultaneously sorts two strided arrays based on the sort order of the first array using Shellsort 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^(4/3))`.
@@ -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 gsort2sh = require( '@stdlib/blas/ext/base/gsort2sh' );
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

@@ -238,6 +219,8 @@ console.log( y );
238219

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

222+
[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
223+
241224
[@shell:1959a]: https://doi.org/10.1145/368370.368387
242225

243226
[@sedgewick:1986a]: https://doi.org/10.1016/0196-6774(86)90001-5

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

Lines changed: 15 additions & 17 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 Shellsort.
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 arrays
7+
are accessed at runtime.
88

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

4646
strideX: integer
47-
Index increment for `x`.
47+
Stride length for `x`.
4848

4949
y: Array<number>|TypedArray
5050
Second input array.
5151

5252
strideY: integer
53-
Index increment for `y`.
53+
Stride length for `y`.
5454

5555
Returns
5656
-------
@@ -67,11 +67,10 @@
6767
> y
6868
[ 3.0, 1.0, 0.0, 2.0 ]
6969

70-
// Using `N` and `stride` parameters:
70+
// Using `N` and stride parameters:
7171
> x = [ 1.0, -2.0, 3.0, -4.0 ];
7272
> y = [ 0.0, 1.0, 2.0, 3.0 ];
73-
> var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
74-
> {{alias}}( N, -1, x, 2, y, 2 )
73+
> {{alias}}( 2, -1, x, 2, y, 2 )
7574
[ 3.0, -2.0, 1.0, -4.0 ]
7675
> y
7776
[ 2.0, 1.0, 0.0, 3.0 ]
@@ -81,21 +80,21 @@
8180
> var x1 = new {{alias:@stdlib/array/float64}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 );
8281
> var y0 = new {{alias:@stdlib/array/float64}}( [ 0.0, 1.0, 2.0, 3.0 ] );
8382
> var y1 = new {{alias:@stdlib/array/float64}}( y0.buffer, y0.BYTES_PER_ELEMENT*1 );
84-
> N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 );
85-
> {{alias}}( N, 1, x1, 2, y1, 2 )
83+
> {{alias}}( 2, 1, x1, 2, y1, 2 )
8684
<Float64Array>[ -4.0, 3.0, -2.0 ]
8785
> x0
8886
<Float64Array>[ 1.0, -4.0, 3.0, -2.0 ]
8987
> y0
9088
<Float64Array>[ 0.0, 3.0, 2.0, 1.0 ]
9189

90+
9291
{{alias}}.ndarray( N, order, x, strideX, offsetX, y, strideY, offsetY )
9392
Simultaneously sorts two strided arrays based on the sort order of the first
9493
array using Shellsort and alternative indexing semantics.
9594

9695
While typed array views mandate a view offset based on the underlying
97-
buffer, the `offset` parameter supports indexing semantics based on a
98-
starting index.
96+
buffer, the offset parameters support indexing semantics based on starting
97+
indices.
9998

10099
Parameters
101100
----------
@@ -110,19 +109,19 @@
110109
First input array.
111110

112111
strideX: integer
113-
Index increment for `x`.
112+
Stride length for `x`.
114113

115114
offsetX: integer
116-
Starting index of `x`.
115+
Starting index for `x`.
117116

118117
y: Array<number>|TypedArray
119118
Second input array.
120119

121120
strideY: integer
122-
Index increment for `y`.
121+
Stride length for `y`.
123122

124123
offsetY: integer
125-
Starting index of `y`.
124+
Starting index for `y`.
126125

127126
Returns
128127
-------
@@ -142,8 +141,7 @@
142141
// Using an index offset:
143142
> x = [ 1.0, -2.0, 3.0, -4.0 ];
144143
> y = [ 0.0, 1.0, 2.0, 3.0 ];
145-
> var N = {{alias:@stdlib/math/base/special/floor}}( x.length / 2 );
146-
> {{alias}}.ndarray( N, 1, x, 2, 1, y, 2, 1 )
144+
> {{alias}}.ndarray( 2, 1, x, 2, 1, y, 2, 1 )
147145
[ 1.0, -4.0, 3.0, -2.0 ]
148146
> y
149147
[ 0.0, 3.0, 2.0, 1.0 ]

lib/node_modules/@stdlib/blas/ext/base/gsort2sh/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 `gsort2sh`.
@@ -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 `y`
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 Shellsort 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 `y`
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 `y`
9196
* @returns `x`
9297
*
9398
* @example

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

2122

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

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

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