Skip to content

Commit 8bfb552

Browse files
Erennn7Sachinn-64
andauthored
feat: add C implementation for stats/base/ndarray/snanmax
PR-URL: #10198 Co-authored-by: orthodox-64 <sachinprogramming62@gmail.com> Reviewed-by: Philipp Burckhardt <pburckhardt@outlook.com> Reviewed-by: Sachinn-64 <Sachinn-64@users.noreply.github.com>
1 parent 5ae946b commit 8bfb552

File tree

20 files changed

+1848
-135
lines changed

20 files changed

+1848
-135
lines changed

lib/node_modules/@stdlib/stats/base/ndarray/snanmax/README.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,155 @@ console.log( v );
102102

103103
<!-- /.examples -->
104104

105+
<!-- C interface documentation. -->
106+
107+
* * *
108+
109+
<section class="c">
110+
111+
## C APIs
112+
113+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
114+
115+
<section class="intro">
116+
117+
</section>
118+
119+
<!-- /.intro -->
120+
121+
<!-- C usage documentation. -->
122+
123+
<section class="usage">
124+
125+
### Usage
126+
127+
```c
128+
#include "stdlib/stats/base/ndarray/snanmax.h"
129+
```
130+
131+
#### stdlib_stats_snanmax( arrays )
132+
133+
Computes the maximum value of a one-dimensional single-precision floating-point ndarray, ignoring `NaN` values.
134+
135+
```c
136+
#include "stdlib/ndarray/ctor.h"
137+
#include "stdlib/ndarray/dtypes.h"
138+
#include "stdlib/ndarray/index_modes.h"
139+
#include "stdlib/ndarray/orders.h"
140+
#include "stdlib/ndarray/base/bytes_per_element.h"
141+
#include <stdint.h>
142+
#include <math.h>
143+
144+
// Create an ndarray:
145+
const float data[] = { 1.0f, 2.0f, NAN, 4.0f };
146+
int64_t shape[] = { 4 };
147+
int64_t strides[] = { STDLIB_NDARRAY_FLOAT32_BYTES_PER_ELEMENT };
148+
int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR };
149+
150+
struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)data, 1, shape, strides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes );
151+
152+
// Compute the maximum value:
153+
const struct ndarray *arrays[] = { x };
154+
float v = stdlib_stats_snanmax( arrays );
155+
// returns 4.0f
156+
157+
// Free allocated memory:
158+
stdlib_ndarray_free( x );
159+
```
160+
161+
The function accepts the following arguments:
162+
163+
- **arrays**: `[in] struct ndarray**` list containing a one-dimensional input ndarray.
164+
165+
```c
166+
float stdlib_stats_snanmax( const struct ndarray *arrays[] );
167+
```
168+
169+
</section>
170+
171+
<!-- /.usage -->
172+
173+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
174+
175+
<section class="notes">
176+
177+
</section>
178+
179+
<!-- /.notes -->
180+
181+
<!-- C API usage examples. -->
182+
183+
<section class="examples">
184+
185+
### Examples
186+
187+
```c
188+
#include "stdlib/stats/base/ndarray/snanmax.h"
189+
#include "stdlib/ndarray/ctor.h"
190+
#include "stdlib/ndarray/dtypes.h"
191+
#include "stdlib/ndarray/index_modes.h"
192+
#include "stdlib/ndarray/orders.h"
193+
#include "stdlib/ndarray/base/bytes_per_element.h"
194+
#include <stdint.h>
195+
#include <stdlib.h>
196+
#include <stdio.h>
197+
#include <math.h>
198+
199+
int main( void ) {
200+
// Create a data buffer:
201+
const float data[] = { 1.0f, -2.0f, 3.0f, NAN, 5.0f, -6.0f, 7.0f, -8.0f };
202+
203+
// Specify the number of array dimensions:
204+
const int64_t ndims = 1;
205+
206+
// Specify the array shape:
207+
int64_t shape[] = { 4 };
208+
209+
// Specify the array strides:
210+
int64_t strides[] = { 2*STDLIB_NDARRAY_FLOAT32_BYTES_PER_ELEMENT };
211+
212+
// Specify the byte offset:
213+
const int64_t offset = 0;
214+
215+
// Specify the array order:
216+
const enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR;
217+
218+
// Specify the index mode:
219+
const enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR;
220+
221+
// Specify the subscript index modes:
222+
int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR };
223+
const int64_t nsubmodes = 1;
224+
225+
// Create an ndarray:
226+
struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT32, (uint8_t *)data, ndims, shape, strides, offset, order, imode, nsubmodes, submodes );
227+
if ( x == NULL ) {
228+
fprintf( stderr, "Error allocating memory.\n" );
229+
exit( 1 );
230+
}
231+
232+
// Define a list of ndarrays:
233+
const struct ndarray *arrays[] = { x };
234+
235+
// Compute the maximum value:
236+
float v = stdlib_stats_snanmax( arrays );
237+
238+
// Print the result:
239+
printf( "max: %f\n", v );
240+
241+
// Free allocated memory:
242+
stdlib_ndarray_free( x );
243+
}
244+
```
245+
246+
</section>
247+
248+
<!-- /.examples -->
249+
250+
</section>
251+
252+
<!-- /.c -->
253+
105254
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
106255
107256
<section class="related">

lib/node_modules/@stdlib/stats/base/ndarray/snanmax/benchmark/benchmark.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,16 @@ var filledarrayBy = require( '@stdlib/array/filled-by' );
2727
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
2828
var pow = require( '@stdlib/math/base/special/pow' );
2929
var ndarray = require( '@stdlib/ndarray/base/ctor' );
30+
var format = require( '@stdlib/string/format' );
3031
var pkg = require( './../package.json' ).name;
31-
var snanmax = require( './../lib' );
32+
var snanmax = require( './../lib/main.js' );
33+
34+
35+
// VARIABLES //
36+
37+
var options = {
38+
'dtype': 'float32'
39+
};
3240

3341

3442
// FUNCTIONS //
@@ -58,7 +66,7 @@ function createBenchmark( len ) {
5866
var x;
5967

6068
xbuf = filledarrayBy( len, 'float32', rand );
61-
x = new ndarray( 'float32', xbuf, [ len ], [ 1 ], 0, 'row-major' );
69+
x = new ndarray( options.dtype, xbuf, [ len ], [ 1 ], 0, 'row-major' );
6270

6371
return benchmark;
6472

@@ -109,7 +117,7 @@ function main() {
109117
for ( i = min; i <= max; i++ ) {
110118
len = pow( 10, i );
111119
f = createBenchmark( len );
112-
bench( pkg+':len='+len, f );
120+
bench( format( '%s:len=%d', pkg, len ), f );
113121
}
114122
}
115123

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 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 resolve = require( 'path' ).resolve;
24+
var bench = require( '@stdlib/bench' );
25+
var uniform = require( '@stdlib/random/base/uniform' );
26+
var bernoulli = require( '@stdlib/random/base/bernoulli' );
27+
var filledarrayBy = require( '@stdlib/array/filled-by' );
28+
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
29+
var pow = require( '@stdlib/math/base/special/pow' );
30+
var ndarray = require( '@stdlib/ndarray/base/ctor' );
31+
var format = require( '@stdlib/string/format' );
32+
var tryRequire = require( '@stdlib/utils/try-require' );
33+
var pkg = require( './../package.json' ).name;
34+
35+
36+
// VARIABLES //
37+
38+
var snanmax = tryRequire( resolve( __dirname, './../lib/native.js' ) );
39+
var opts = {
40+
'skip': ( snanmax instanceof Error )
41+
};
42+
var options = {
43+
'dtype': 'float32'
44+
};
45+
46+
47+
// FUNCTIONS //
48+
49+
/**
50+
* Returns a random number.
51+
*
52+
* @private
53+
* @returns {number} random number or `NaN`
54+
*/
55+
function rand() {
56+
if ( bernoulli( 0.8 ) < 1 ) {
57+
return NaN;
58+
}
59+
return uniform( -10.0, 10.0 );
60+
}
61+
62+
/**
63+
* Creates a benchmark function.
64+
*
65+
* @private
66+
* @param {PositiveInteger} len - array length
67+
* @returns {Function} benchmark function
68+
*/
69+
function createBenchmark( len ) {
70+
var xbuf;
71+
var x;
72+
73+
xbuf = filledarrayBy( len, 'float32', rand );
74+
x = new ndarray( options.dtype, xbuf, [ len ], [ 1 ], 0, 'row-major' );
75+
76+
return benchmark;
77+
78+
/**
79+
* Benchmark function.
80+
*
81+
* @private
82+
* @param {Benchmark} b - benchmark instance
83+
*/
84+
function benchmark( b ) {
85+
var v;
86+
var i;
87+
88+
b.tic();
89+
for ( i = 0; i < b.iterations; i++ ) {
90+
v = snanmax( [ x ] );
91+
if ( isnanf( v ) ) {
92+
b.fail( 'should not return NaN' );
93+
}
94+
}
95+
b.toc();
96+
if ( isnanf( v ) ) {
97+
b.fail( 'should not return NaN' );
98+
}
99+
b.pass( 'benchmark finished' );
100+
b.end();
101+
}
102+
}
103+
104+
105+
// MAIN //
106+
107+
/**
108+
* Main execution sequence.
109+
*
110+
* @private
111+
*/
112+
function main() {
113+
var len;
114+
var min;
115+
var max;
116+
var f;
117+
var i;
118+
119+
min = 1; // 10^min
120+
max = 6; // 10^max
121+
122+
for ( i = min; i <= max; i++ ) {
123+
len = pow( 10, i );
124+
f = createBenchmark( len );
125+
bench( format( '%s::native:len=%d', pkg, len ), opts, f );
126+
}
127+
}
128+
129+
main();

0 commit comments

Comments
 (0)