Skip to content

Commit fc7a8ac

Browse files
aayush0325kgrytestdlib-bot
authored andcommitted
feat: add C ndarray interface and refactor implementation for stats/base/smskrange
PR-URL: stdlib-js#4404 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]> Co-authored-by: stdlib-bot <[email protected]>
1 parent 4af50dd commit fc7a8ac

23 files changed

+455
-430
lines changed

Diff for: lib/node_modules/@stdlib/stats/base/smskrange/README.md

+139-34
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ var smskrange = require( '@stdlib/stats/base/smskrange' );
4040

4141
#### smskrange( N, x, strideX, mask, strideMask )
4242

43-
Computes the [range][range] of a single-precision floating-point strided array `x` according to a `mask`.
43+
Computes the [range][range] of a single-precision floating-point strided array according to a mask.
4444

4545
```javascript
4646
var Float32Array = require( '@stdlib/array/float32' );
@@ -57,22 +57,20 @@ The function has the following parameters:
5757

5858
- **N**: number of indexed elements.
5959
- **x**: input [`Float32Array`][@stdlib/array/float32].
60-
- **strideX**: index increment for `x`.
60+
- **strideX**: stride length for `x`.
6161
- **mask**: mask [`Uint8Array`][@stdlib/array/uint8]. If a `mask` array element is `0`, the corresponding element in `x` is considered valid and **included** in computation. If a `mask` array element is `1`, the corresponding element in `x` is considered invalid/missing and **excluded** from computation.
62-
- **strideMask**: index increment for `mask`.
62+
- **strideMask**: stride length for `mask`.
6363

64-
The `N` and `stride` parameters determine which elements are accessed at runtime. For example, to compute the [range][range] of every other element in `x`,
64+
The `N` and stride parameters determine which elements in the strided arrays are accessed at runtime. For example, to compute the [range][range] of every other element in `x`,
6565

6666
```javascript
6767
var Float32Array = require( '@stdlib/array/float32' );
6868
var Uint8Array = require( '@stdlib/array/uint8' );
69-
var floor = require( '@stdlib/math/base/special/floor' );
7069

7170
var x = new Float32Array( [ 1.0, 2.0, -7.0, -2.0, 4.0, 3.0, 5.0, 6.0 ] );
7271
var mask = new Uint8Array( [ 0, 0, 0, 0, 0, 0, 1, 1 ] );
73-
var N = floor( x.length / 2 );
7472

75-
var v = smskrange( N, x, 2, mask, 2 );
73+
var v = smskrange( 4, x, 2, mask, 2 );
7674
// returns 11.0
7775
```
7876

@@ -83,23 +81,20 @@ Note that indexing is relative to the first index. To introduce offsets, use [`t
8381
```javascript
8482
var Float32Array = require( '@stdlib/array/float32' );
8583
var Uint8Array = require( '@stdlib/array/uint8' );
86-
var floor = require( '@stdlib/math/base/special/floor' );
8784

8885
var x0 = new Float32Array( [ 2.0, 1.0, -2.0, -2.0, 3.0, 4.0, 5.0, 6.0 ] );
8986
var x1 = new Float32Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
9087

9188
var mask0 = new Uint8Array( [ 0, 0, 0, 0, 0, 0, 1, 1 ] );
9289
var mask1 = new Uint8Array( mask0.buffer, mask0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
9390

94-
var N = floor( x0.length / 2 );
95-
96-
var v = smskrange( N, x1, 2, mask1, 2 );
91+
var v = smskrange( 4, x1, 2, mask1, 2 );
9792
// returns 6.0
9893
```
9994

10095
#### smskrange.ndarray( N, x, strideX, offsetX, mask, strideMask, offsetMask )
10196

102-
Computes the [range][range] of a single-precision floating-point strided array according to a `mask` and using alternative indexing semantics.
97+
Computes the [range][range] of a single-precision floating-point strided array according to a mask and using alternative indexing semantics.
10398

10499
```javascript
105100
var Float32Array = require( '@stdlib/array/float32' );
@@ -117,18 +112,16 @@ The function has the following additional parameters:
117112
- **offsetX**: starting index for `x`.
118113
- **offsetMask**: starting index for `mask`.
119114

120-
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 calculate the [range][range] for every other value in `x` starting from the second value
115+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on a starting indices. For example, to calculate the [range][range] for every other element in `x` starting from the second element
121116

122117
```javascript
123118
var Float32Array = require( '@stdlib/array/float32' );
124119
var Uint8Array = require( '@stdlib/array/uint8' );
125-
var floor = require( '@stdlib/math/base/special/floor' );
126120

127121
var x = new Float32Array( [ 2.0, 1.0, -2.0, -2.0, 3.0, 4.0, 5.0, 6.0 ] );
128122
var mask = new Uint8Array( [ 0, 0, 0, 0, 0, 0, 1, 1 ] );
129-
var N = floor( x.length / 2 );
130123

131-
var v = smskrange.ndarray( N, x, 2, 1, mask, 2, 1 );
124+
var v = smskrange.ndarray( 4, x, 2, 1, mask, 2, 1 );
132125
// returns 6.0
133126
```
134127

@@ -153,26 +146,19 @@ var v = smskrange.ndarray( N, x, 2, 1, mask, 2, 1 );
153146
<!-- eslint no-undef: "error" -->
154147

155148
```javascript
156-
var randu = require( '@stdlib/random/base/randu' );
157-
var round = require( '@stdlib/math/base/special/round' );
158-
var Float32Array = require( '@stdlib/array/float32' );
159-
var Uint8Array = require( '@stdlib/array/uint8' );
149+
var uniform = require( '@stdlib/random/array/uniform' );
150+
var bernoulli = require( '@stdlib/random/array/bernoulli' );
160151
var smskrange = require( '@stdlib/stats/base/smskrange' );
161152

162-
var mask;
163-
var x;
164-
var i;
165-
166-
x = new Float32Array( 10 );
167-
mask = new Uint8Array( x.length );
168-
for ( i = 0; i < x.length; i++ ) {
169-
if ( randu() < 0.2 ) {
170-
mask[ i ] = 1;
171-
} else {
172-
mask[ i ] = 0;
173-
}
174-
x[ i ] = round( (randu()*100.0) - 50.0 );
175-
}
153+
var uniformOptions = {
154+
'dtype': 'float32'
155+
};
156+
var bernoulliOptions = {
157+
'dtype': 'uint8'
158+
};
159+
160+
var x = uniform( 10, -50.0, 50.0, uniformOptions );
161+
var mask = bernoulli( x.length, 0.2, bernoulliOptions );
176162
console.log( x );
177163
console.log( mask );
178164

@@ -184,6 +170,125 @@ console.log( v );
184170

185171
<!-- /.examples -->
186172

173+
<!-- C usage documentation. -->
174+
175+
<section class="usage">
176+
177+
### Usage
178+
179+
```c
180+
#include "stdlib/stats/base/smskrange.h"
181+
```
182+
183+
#### stdlib_strided_smskrange( N, \*X, strideX, \*Mask, strideMask )
184+
185+
Computes the [range][range] of a single-precision floating-point strided array according to a mask.
186+
187+
```c
188+
#include <stdint.h>
189+
190+
const float x[] = { 1.0f, -2.0f, 2.0f };
191+
const uint8_t mask[] = { 0, 1, 0 };
192+
193+
float v = stdlib_strided_smskrange( 3, x, 1, mask, 1 );
194+
// returns 1.0f
195+
```
196+
197+
The function accepts the following arguments:
198+
199+
- **N**: `[in] CBLAS_INT` number of indexed elements.
200+
- **X**: `[in] float*` input array.
201+
- **strideX**: `[in] CBLAS_INT` stride length for `X`.
202+
- **Mask**: `[in] uint8_t*` mask array. If a `Mask` array element is `0`, the corresponding element in `X` is considered valid and included in computation. If a `Mask` array element is `1`, the corresponding element in `X` is considered invalid/missing and excluded from computation.
203+
- **strideMask**: `[in] CBLAS_INT` stride length for `Mask`.
204+
205+
```c
206+
float stdlib_strided_smskrange( const CBLAS_INT N, const float *X, const CBLAS_INT strideX, const uint8_t *Mask, const CBLAS_INT strideMask );
207+
```
208+
209+
<!-- lint disable maximum-heading-length -->
210+
211+
#### stdlib_strided_smskrange_ndarray( N, \*X, strideX, offsetX, \*Mask, strideMask, offsetMask )
212+
213+
Computes the [range][range] of a single-precision floating-point strided array according to a mask and using alternative indexing semantics.
214+
215+
```c
216+
#include <stdint.h>
217+
218+
const float x[] = { 1.0f, -2.0f, 2.0f };
219+
const uint8_t mask[] = { 0, 1, 0 };
220+
221+
float v = stdlib_strided_smskrange( 3, x, 1, 0, mask, 1, 0 );
222+
// returns 1.0f
223+
```
224+
225+
The function accepts the following arguments:
226+
227+
- **N**: `[in] CBLAS_INT` number of indexed elements.
228+
- **X**: `[in] float*` input array.
229+
- **strideX**: `[in] CBLAS_INT` stride length for `X`.
230+
- **offsetX**: `[in] CBLAS_INT` starting index for `X`.
231+
- **Mask**: `[in] uint8_t*` mask array. If a `Mask` array element is `0`, the corresponding element in `X` is considered valid and included in computation. If a `Mask` array element is `1`, the corresponding element in `X` is considered invalid/missing and excluded from computation.
232+
- **strideMask**: `[in] CBLAS_INT` stride length for `Mask`.
233+
- **offsetMask**: `[in] CBLAS_INT` starting index for `Mask`.
234+
235+
```c
236+
float stdlib_strided_smskrange_ndarray( const CBLAS_INT N, const float *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, const uint8_t *Mask, const CBLAS_INT strideMask, const CBLAS_INT offsetMask );
237+
```
238+
239+
</section>
240+
241+
<!-- /.usage -->
242+
243+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
244+
245+
<section class="notes">
246+
247+
</section>
248+
249+
<!-- /.notes -->
250+
251+
<!-- C API usage examples. -->
252+
253+
<section class="examples">
254+
255+
### Examples
256+
257+
```c
258+
#include "stdlib/stats/base/smskrange.h"
259+
#include <stdint.h>
260+
#include <stdio.h>
261+
262+
int main( void ) {
263+
// Create a strided array:
264+
const float x[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f };
265+
266+
// Create a mask array:
267+
const uint8_t mask[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
268+
269+
// Specify the number of elements:
270+
const int N = 5;
271+
272+
// Specify the stride lengths:
273+
const int strideX = 2;
274+
const int strideMask = 2;
275+
276+
// Compute the range:
277+
float v = stdlib_strided_smskrange( N, x, strideX, mask, strideMask );
278+
279+
// Print the result:
280+
printf( "range: %f\n", v );
281+
}
282+
```
283+
284+
</section>
285+
286+
<!-- /.examples -->
287+
288+
</section>
289+
290+
<!-- /.c -->
291+
187292
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
188293
189294
<section class="related">

Diff for: lib/node_modules/@stdlib/stats/base/smskrange/benchmark/benchmark.js

+14-17
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,24 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var randu = require( '@stdlib/random/base/randu' );
24+
var uniform = require( '@stdlib/random/array/uniform' );
25+
var bernoulli = require( '@stdlib/random/array/bernoulli' );
2526
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
2627
var pow = require( '@stdlib/math/base/special/pow' );
27-
var Float32Array = require( '@stdlib/array/float32' );
28-
var Uint8Array = require( '@stdlib/array/uint8' );
2928
var pkg = require( './../package.json' ).name;
3029
var smskrange = require( './../lib/smskrange.js' );
3130

3231

32+
// VARIABLES //
33+
34+
var uniformOptions = {
35+
'dtype': 'float32'
36+
};
37+
var bernoulliOptions = {
38+
'dtype': 'uint8'
39+
};
40+
41+
3342
// FUNCTIONS //
3443

3544
/**
@@ -40,20 +49,8 @@ var smskrange = require( './../lib/smskrange.js' );
4049
* @returns {Function} benchmark function
4150
*/
4251
function createBenchmark( len ) {
43-
var mask;
44-
var x;
45-
var i;
46-
47-
x = new Float32Array( len );
48-
mask = new Uint8Array( len );
49-
for ( i = 0; i < x.length; i++ ) {
50-
if ( randu() < 0.2 ) {
51-
mask[ i ] = 1;
52-
} else {
53-
mask[ i ] = 0;
54-
}
55-
x[ i ] = ( randu()*20.0 ) - 10.0;
56-
}
52+
var mask = bernoulli( len, 0.2, bernoulliOptions );
53+
var x = uniform( len, -10.0, 10.0, uniformOptions );
5754
return benchmark;
5855

5956
function benchmark( b ) {

Diff for: lib/node_modules/@stdlib/stats/base/smskrange/benchmark/benchmark.native.js

+10-17
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@
2222

2323
var resolve = require( 'path' ).resolve;
2424
var bench = require( '@stdlib/bench' );
25-
var randu = require( '@stdlib/random/base/randu' );
25+
var uniform = require( '@stdlib/random/array/uniform' );
26+
var bernoulli = require( '@stdlib/random/array/bernoulli' );
2627
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
2728
var pow = require( '@stdlib/math/base/special/pow' );
28-
var Float32Array = require( '@stdlib/array/float32' );
29-
var Uint8Array = require( '@stdlib/array/uint8' );
3029
var tryRequire = require( '@stdlib/utils/try-require' );
3130
var pkg = require( './../package.json' ).name;
3231

@@ -37,6 +36,12 @@ var smskrange = tryRequire( resolve( __dirname, './../lib/smskrange.native.js' )
3736
var opts = {
3837
'skip': ( smskrange instanceof Error )
3938
};
39+
var uniformOptions = {
40+
'dtype': 'float32'
41+
};
42+
var bernoulliOptions = {
43+
'dtype': 'uint8'
44+
};
4045

4146

4247
// FUNCTIONS //
@@ -49,20 +54,8 @@ var opts = {
4954
* @returns {Function} benchmark function
5055
*/
5156
function createBenchmark( len ) {
52-
var mask;
53-
var x;
54-
var i;
55-
56-
x = new Float32Array( len );
57-
mask = new Uint8Array( len );
58-
for ( i = 0; i < x.length; i++ ) {
59-
if ( randu() < 0.2 ) {
60-
mask[ i ] = 1;
61-
} else {
62-
mask[ i ] = 0;
63-
}
64-
x[ i ] = ( randu()*20.0 ) - 10.0;
65-
}
57+
var mask = bernoulli( len, 0.2, bernoulliOptions );
58+
var x = uniform( len, -10.0, 10.0, uniformOptions );
6659
return benchmark;
6760

6861
function benchmark( b ) {

Diff for: lib/node_modules/@stdlib/stats/base/smskrange/benchmark/benchmark.ndarray.js

+14-17
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,24 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var randu = require( '@stdlib/random/base/randu' );
24+
var uniform = require( '@stdlib/random/array/uniform' );
25+
var bernoulli = require( '@stdlib/random/array/bernoulli' );
2526
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
2627
var pow = require( '@stdlib/math/base/special/pow' );
27-
var Float32Array = require( '@stdlib/array/float32' );
28-
var Uint8Array = require( '@stdlib/array/uint8' );
2928
var pkg = require( './../package.json' ).name;
3029
var smskrange = require( './../lib/ndarray.js' );
3130

3231

32+
// VARIABLES //
33+
34+
var uniformOptions = {
35+
'dtype': 'float32'
36+
};
37+
var bernoulliOptions = {
38+
'dtype': 'uint8'
39+
};
40+
41+
3342
// FUNCTIONS //
3443

3544
/**
@@ -40,20 +49,8 @@ var smskrange = require( './../lib/ndarray.js' );
4049
* @returns {Function} benchmark function
4150
*/
4251
function createBenchmark( len ) {
43-
var mask;
44-
var x;
45-
var i;
46-
47-
x = new Float32Array( len );
48-
mask = new Uint8Array( len );
49-
for ( i = 0; i < x.length; i++ ) {
50-
if ( randu() < 0.2 ) {
51-
mask[ i ] = 1;
52-
} else {
53-
mask[ i ] = 0;
54-
}
55-
x[ i ] = ( randu()*20.0 ) - 10.0;
56-
}
52+
var mask = bernoulli( len, 0.2, bernoulliOptions );
53+
var x = uniform( len, -10.0, 10.0, uniformOptions );
5754
return benchmark;
5855

5956
function benchmark( b ) {

0 commit comments

Comments
 (0)