Skip to content

Commit 5a64342

Browse files
feat: add C implementation for stats/base/ndarray/snanrange
PR-URL: stdlib-js#10258 Co-authored-by: Sachin Pangal <151670745+Sachinn-64@users.noreply.github.com> Reviewed-by: Philipp Burckhardt <pburckhardt@outlook.com> Signed-off-by: Bhargav Dabhade <bhargava2005dabhade@gmail.com> Signed-off-by: Sachin Pangal <151670745+Sachinn-64@users.noreply.github.com>
1 parent 0feb882 commit 5a64342

File tree

20 files changed

+1846
-132
lines changed

20 files changed

+1846
-132
lines changed

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

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

105105
<!-- /.examples -->
106106

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

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ 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 snanrange = require( './../lib' );
32+
var snanrange = require( './../lib/main.js' );
3233

3334

3435
// FUNCTIONS //
@@ -109,7 +110,7 @@ function main() {
109110
for ( i = min; i <= max; i++ ) {
110111
len = pow( 10, i );
111112
f = createBenchmark( len );
112-
bench( pkg+':len='+len, f );
113+
bench( format( '%s:len=%d', pkg, len ), f );
113114
}
114115
}
115116

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 snanrange = tryRequire( resolve( __dirname, './../lib/native.js' ) );
39+
var opts = {
40+
'skip': ( snanrange 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 = snanrange( [ 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)