Skip to content

Commit c4b3073

Browse files
committed
feat: add support for accessor arrays
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed ---
1 parent 3081c13 commit c4b3073

File tree

7 files changed

+336
-3
lines changed

7 files changed

+336
-3
lines changed

lib/node_modules/@stdlib/stats/base/nanmax/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ var v = nanmax.ndarray( 5, x, 2, 1 );
109109
## Notes
110110

111111
- If `N <= 0`, both functions return `NaN`.
112+
- 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]).
112113
- Depending on the environment, the typed versions ([`dnanmax`][@stdlib/stats/base/dnanmax], [`snanmax`][@stdlib/stats/base/snanmax], etc.) are likely to be significantly more performant.
113114

114115
</section>
@@ -170,6 +171,8 @@ console.log( v );
170171

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

174+
[@stdlib/array/base/accessor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/array/base/accessor
175+
173176
<!-- <related-links> -->
174177

175178
[@stdlib/stats/base/dnanmax]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/stats/base/dnanmax

lib/node_modules/@stdlib/stats/base/nanmax/docs/types/index.d.ts

Lines changed: 8 additions & 3 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 `nanmax`.
@@ -40,7 +45,7 @@ interface Routine {
4045
* var v = nanmax( x.length, x, 1 );
4146
* // returns 2.0
4247
*/
43-
( N: number, x: NumericArray, strideX: number ): number;
48+
( N: number, x: InputArray, strideX: number ): number;
4449

4550
/**
4651
* Computes the maximum value of a strided array, ignoring `NaN` values and using alternative indexing semantics.
@@ -57,7 +62,7 @@ interface Routine {
5762
* var v = nanmax.ndarray( x.length, x, 1, 0 );
5863
* // returns 2.0
5964
*/
60-
ndarray( N: number, x: NumericArray, strideX: number, offsetX: number ): number;
65+
ndarray( N: number, x: InputArray, strideX: number, offsetX: number ): number;
6166
}
6267

6368
/**

lib/node_modules/@stdlib/stats/base/nanmax/docs/types/test.ts

Lines changed: 3 additions & 0 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 nanmax = require( './index' );
2021

2122

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

2829
nanmax( x.length, x, 1 ); // $ExpectType number
30+
nanmax( x.length, new AccessorArray( x ), 1 ); // $ExpectType number
2931
}
3032

3133
// The compiler throws an error if the function is provided a first argument which is not a number...
@@ -85,6 +87,7 @@ import nanmax = require( './index' );
8587
const x = new Float64Array( 10 );
8688

8789
nanmax.ndarray( x.length, x, 1, 0 ); // $ExpectType number
90+
nanmax.ndarray( x.length, new AccessorArray( x ), 1, 0 ); // $ExpectType number
8891
}
8992

9093
// The compiler throws an error if the `ndarray` method is provided a first argument which is not a number...
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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+
// MODULES //
22+
23+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
24+
var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
25+
26+
27+
// MAIN //
28+
29+
/**
30+
* Computes the maximum value of a strided array, ignoring `NaN` values.
31+
*
32+
* @private
33+
* @param {PositiveInteger} N - number of indexed elements
34+
* @param {Object} x - input array object
35+
* @param {Collection} x.data - input array data
36+
* @param {Array<Function>} x.accessors - array element accessors
37+
* @param {integer} strideX - stride length
38+
* @param {NonNegativeInteger} offsetX - starting index
39+
* @returns {number} maximum value
40+
*
41+
* @example
42+
* var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
43+
* var arraylike2object = require( '@stdlib/array/base/arraylike2object' );
44+
*
45+
* var x = toAccessorArray( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );
46+
*
47+
* var v = nanmax( 5, arraylike2object( x ), 2, 1 );
48+
* // returns 4.0
49+
*/
50+
function nanmax( N, x, strideX, offsetX ) {
51+
var xbuf;
52+
var get;
53+
var max;
54+
var ix;
55+
var v;
56+
var i;
57+
58+
// Cache reference to array data:
59+
xbuf = x.data;
60+
61+
// Cache a reference to the element accessor:
62+
get = x.accessors[ 0 ];
63+
64+
if ( N === 1 || strideX === 0 ) {
65+
return get( xbuf, offsetX );
66+
}
67+
ix = offsetX;
68+
for ( i = 0; i < N; i++ ) {
69+
v = get( xbuf, ix );
70+
if ( v === v ) {
71+
break;
72+
}
73+
ix += strideX;
74+
}
75+
if ( i === N ) {
76+
return NaN;
77+
}
78+
max = v;
79+
i += 1;
80+
for ( i; i < N; i++ ) {
81+
ix += strideX;
82+
v = get( xbuf, ix );
83+
if ( isnan( v ) ) {
84+
continue;
85+
}
86+
if ( v > max || ( v === max && isPositiveZero( v ) ) ) {
87+
max = v;
88+
}
89+
}
90+
return max;
91+
}
92+
93+
94+
// EXPORTS //
95+
96+
module.exports = nanmax;

lib/node_modules/@stdlib/stats/base/nanmax/lib/ndarray.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2424
var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
25+
var arraylike2object = require( '@stdlib/array/base/arraylike2object' );
26+
var accessors = require( './accessors.js' );
2527

2628

2729
// MAIN //
@@ -44,12 +46,17 @@ var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
4446
function nanmax( N, x, strideX, offsetX ) {
4547
var max;
4648
var ix;
49+
var o;
4750
var v;
4851
var i;
4952

5053
if ( N <= 0 ) {
5154
return NaN;
5255
}
56+
o = arraylike2object( x );
57+
if ( o.accessorProtocol ) {
58+
return accessors( N, o, strideX, offsetX );
59+
}
5360
if ( N === 1 || strideX === 0 ) {
5461
return x[ offsetX ];
5562
}

lib/node_modules/@stdlib/stats/base/nanmax/test/test.main.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
var tape = require( 'tape' );
2424
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2525
var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
26+
var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
2627
var Float64Array = require( '@stdlib/array/float64' );
2728
var nanmax = require( './../lib/main.js' );
2829

@@ -67,6 +68,33 @@ tape( 'the function calculates the maximum value of a strided array', function t
6768
t.end();
6869
});
6970

71+
tape( 'the function calculates the maximum value of a strided array (accessors)', function test( t ) {
72+
var x;
73+
var v;
74+
75+
x = [ 1.0, -2.0, -4.0, 5.0, 0.0, 3.0, NaN, NaN ];
76+
v = nanmax( x.length, toAccessorArray( x ), 1 );
77+
t.strictEqual( v, 5.0, 'returns expected value' );
78+
79+
x = [ -4.0, NaN, -5.0 ];
80+
v = nanmax( x.length, toAccessorArray( x ), 1 );
81+
t.strictEqual( v, -4.0, 'returns expected value' );
82+
83+
x = [ -0.0, NaN, 0.0, -0.0 ];
84+
v = nanmax( x.length, toAccessorArray( x ), 1 );
85+
t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
86+
87+
x = [ NaN ];
88+
v = nanmax( x.length, toAccessorArray( x ), 1 );
89+
t.strictEqual( isnan( v ), true, 'returns expected value' );
90+
91+
x = [ NaN, NaN ];
92+
v = nanmax( x.length, toAccessorArray( x ), 1 );
93+
t.strictEqual( isnan( v ), true, 'returns expected value' );
94+
95+
t.end();
96+
});
97+
7098
tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `NaN`', function test( t ) {
7199
var x;
72100
var v;
@@ -94,6 +122,18 @@ tape( 'if provided an `N` parameter equal to `1`, the function returns the first
94122
t.end();
95123
});
96124

125+
tape( 'if provided an `N` parameter equal to `1`, the function returns the first element (accessors)', function test( t ) {
126+
var x;
127+
var v;
128+
129+
x = [ 1.0, -2.0, -4.0, 5.0, 3.0 ];
130+
131+
v = nanmax( 1, toAccessorArray( x ), 1 );
132+
t.strictEqual( v, 1.0, 'returns expected value' );
133+
134+
t.end();
135+
});
136+
97137
tape( 'the function supports a `stride` parameter', function test( t ) {
98138
var x;
99139
var v;
@@ -117,6 +157,29 @@ tape( 'the function supports a `stride` parameter', function test( t ) {
117157
t.end();
118158
});
119159

160+
tape( 'the function supports a `stride` parameter (accessors)', function test( t ) {
161+
var x;
162+
var v;
163+
164+
x = [
165+
1.0, // 0
166+
2.0,
167+
2.0, // 1
168+
-7.0,
169+
-2.0, // 2
170+
3.0,
171+
4.0, // 3
172+
2.0,
173+
NaN, // 4
174+
NaN
175+
];
176+
177+
v = nanmax( 5, toAccessorArray( x ), 2 );
178+
179+
t.strictEqual( v, 4.0, 'returns expected value' );
180+
t.end();
181+
});
182+
120183
tape( 'the function supports a negative `stride` parameter', function test( t ) {
121184
var x;
122185
var v;
@@ -140,6 +203,29 @@ tape( 'the function supports a negative `stride` parameter', function test( t )
140203
t.end();
141204
});
142205

206+
tape( 'the function supports a negative `stride` parameter (accessors)', function test( t ) {
207+
var x;
208+
var v;
209+
210+
x = [
211+
NaN, // 4
212+
NaN,
213+
1.0, // 3
214+
2.0,
215+
2.0, // 2
216+
-7.0,
217+
-2.0, // 1
218+
3.0,
219+
4.0, // 0
220+
2.0
221+
];
222+
223+
v = nanmax( 5, toAccessorArray( x ), -2 );
224+
225+
t.strictEqual( v, 4.0, 'returns expected value' );
226+
t.end();
227+
});
228+
143229
tape( 'if provided a `stride` parameter equal to `0`, the function returns the first element', function test( t ) {
144230
var x;
145231
var v;
@@ -152,6 +238,18 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns the f
152238
t.end();
153239
});
154240

241+
tape( 'if provided a `stride` parameter equal to `0`, the function returns the first element (accessors)', function test( t ) {
242+
var x;
243+
var v;
244+
245+
x = [ 1.0, -2.0, -4.0, 5.0, 3.0 ];
246+
247+
v = nanmax( x.length, toAccessorArray( x ), 0 );
248+
t.strictEqual( v, 1.0, 'returns expected value' );
249+
250+
t.end();
251+
});
252+
155253
tape( 'the function supports view offsets', function test( t ) {
156254
var x0;
157255
var x1;

0 commit comments

Comments
 (0)