Skip to content

feat: add C ndarray interface and refactor implementation for stats/base/dnanmeanpw #4763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
55ae65f
feat: add C ndarray interface and refactor implementation
aayush0325 Jan 15, 2025
483045f
fix: use CBLAS_INT instead of int32_t
aayush0325 Jan 15, 2025
35c57c4
refactor: update js implementation and tests
aayush0325 Jan 16, 2025
e49f048
fix: fix bugs
aayush0325 Jan 16, 2025
76732c8
refactor: update benchmarks, docs, examples
aayush0325 Jan 16, 2025
5352d04
docs: update readme
aayush0325 Jan 16, 2025
89874b2
chore: code review
aayush0325 Jan 17, 2025
29e4d14
docs: update examples
aayush0325 Jan 17, 2025
6905209
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
aayush0325 Jan 17, 2025
d628f06
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
aayush0325 Jan 17, 2025
8d9eb1f
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
aayush0325 Jan 17, 2025
7ce536f
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
aayush0325 Jan 17, 2025
3286c79
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
aayush0325 Jan 17, 2025
a2f5a64
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
aayush0325 Jan 17, 2025
2e6e724
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/lib/ndarray.js
aayush0325 Jan 17, 2025
696c3f2
Update lib/node_modules/@stdlib/stats/base/dnanmeanpw/src/main.c
aayush0325 Jan 17, 2025
473ceb6
chore: fix readme tests
aayush0325 Jan 18, 2025
756db93
docs: update examples
aayush0325 Jan 18, 2025
21b4bf0
style: enable lint rule
kgryte Jan 19, 2025
821d72b
style: disable ESLint rules
kgryte Jan 19, 2025
bc9fea3
refactor: avoid repeated temporary array allocation
kgryte Jan 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 126 additions & 35 deletions lib/node_modules/@stdlib/stats/base/dnanmeanpw/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,84 +51,77 @@ The [arithmetic mean][arithmetic-mean] is defined as
var dnanmeanpw = require( '@stdlib/stats/base/dnanmeanpw' );
```

#### dnanmeanpw( N, x, stride )
#### dnanmeanpw( N, x, strideX )

Computes the [arithmetic mean][arithmetic-mean] of a double-precision floating-point strided array `x`, ignoring `NaN` values and using pairwise summation.

```javascript
var Float64Array = require( '@stdlib/array/float64' );

var x = new Float64Array( [ 1.0, -2.0, NaN, 2.0 ] );
var N = x.length;

var v = dnanmeanpw( N, x, 1 );
var v = dnanmeanpw( x.length, x, 1 );
// returns ~0.3333
```

The function has the following parameters:

- **N**: number of indexed elements.
- **x**: input [`Float64Array`][@stdlib/array/float64].
- **stride**: index increment for `x`.
- **strideX**: stride length.

The `N` and `stride` parameters determine which elements in `x` are accessed at runtime. For example, to compute the [arithmetic mean][arithmetic-mean] of every other element in `x`,
The `N` and stride parameters determine which elements in the strided array are accessed at runtime. For example, to compute the [arithmetic mean][arithmetic-mean] of every other element:

```javascript
var Float64Array = require( '@stdlib/array/float64' );
var floor = require( '@stdlib/math/base/special/floor' );

var x = new Float64Array( [ 1.0, 2.0, 2.0, -7.0, -2.0, 3.0, 4.0, 2.0, NaN ] );
var N = floor( x.length / 2 );

var v = dnanmeanpw( N, x, 2 );
var v = dnanmeanpw( 5, x, 2 );
// returns 1.25
```

Note that indexing is relative to the first index. To introduce an offset, use [`typed array`][mdn-typed-array] views.

<!-- eslint-disable stdlib/capitalized-comments -->
<!-- eslint-disable stdlib/capitalized-comments, max-len -->

```javascript
var Float64Array = require( '@stdlib/array/float64' );
var floor = require( '@stdlib/math/base/special/floor' );

var x0 = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN ] );
var x0 = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );
var x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element

var N = floor( x0.length / 2 );

var v = dnanmeanpw( N, x1, 2 );
var v = dnanmeanpw( 5, x1, 2 );
// returns 1.25
```

#### dnanmeanpw.ndarray( N, x, stride, offset )
#### dnanmeanpw.ndarray( N, x, strideX, offsetX )

Computes the [arithmetic mean][arithmetic-mean] of a double-precision floating-point strided array, ignoring `NaN` values and using pairwise summation and alternative indexing semantics.

```javascript
var Float64Array = require( '@stdlib/array/float64' );

var x = new Float64Array( [ 1.0, -2.0, NaN, 2.0 ] );
var N = x.length;

var v = dnanmeanpw.ndarray( N, x, 1, 0 );
var v = dnanmeanpw.ndarray( x.length, x, 1, 0 );
// returns ~0.33333
```

The function has the following additional parameters:

- **offset**: starting index for `x`.
- **offsetX**: starting index.

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 [arithmetic mean][arithmetic-mean] for every other value in `x` starting from the second value
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 [arithmetic mean][arithmetic-mean] for every other element starting from the second element:

<!-- eslint-disable max-len -->

```javascript
var Float64Array = require( '@stdlib/array/float64' );
var floor = require( '@stdlib/math/base/special/floor' );

var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN ] );
var N = floor( x.length / 2 );
var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0, NaN, NaN ] );

var v = dnanmeanpw.ndarray( N, x, 2, 1 );
var v = dnanmeanpw.ndarray( 5, x, 2, 1 );
// returns 1.25
```

Expand All @@ -155,22 +148,19 @@ var v = dnanmeanpw.ndarray( N, x, 2, 1 );
<!-- eslint no-undef: "error" -->

```javascript
var randu = require( '@stdlib/random/base/randu' );
var round = require( '@stdlib/math/base/special/round' );
var Float64Array = require( '@stdlib/array/float64' );
var uniform = require( '@stdlib/random/base/uniform' );
var filledarrayBy = require( '@stdlib/array/filled-by' );
var bernoulli = require( '@stdlib/random/base/bernoulli' );
var dnanmeanpw = require( '@stdlib/stats/base/dnanmeanpw' );

var x;
var i;

x = new Float64Array( 10 );
for ( i = 0; i < x.length; i++ ) {
if ( randu() < 0.2 ) {
x[ i ] = NaN;
} else {
x[ i ] = round( (randu()*100.0) - 50.0 );
function rand() {
if ( bernoulli( 0.8 ) < 1 ) {
return NaN;
}
return uniform( -50.0, 50.0 );
}

var x = filledarrayBy( 10, 'float64', rand );
console.log( x );

var v = dnanmeanpw( x.length, x, 1 );
Expand All @@ -181,6 +171,107 @@ console.log( v );

<!-- /.examples -->

<!-- C usage documentation. -->

<section class="usage">

### Usage

```c
#include "stdlib/stats/base/dnanmeanpw.h"
```

#### stdlib_strided_dnanmeanpw( N, \*X, strideX )

Computes the [arithmetic mean][arithmetic-mean] of a double-precision floating-point strided array, ignoring `NaN` values and using pairwise summation.

```c
const double x[] = { 1.0, -2.0, 0.0/0.0, 2.0 };

double v = stdlib_strided_dnanmeanpw( 4, x, 1 );
// returns ~0.3333
```

The function accepts the following arguments:

- **N**: `[in] CBLAS_INT` number of indexed elements.
- **X**: `[in] double*` input array.
- **strideX**: `[in] CBLAS_INT` stride length.

```c
double stdlib_strided_dnanmeanpw( const CBLAS_INT N, const double *X, const CBLAS_INT strideX );
```

#### stdlib_strided_dnanmeanpw_ndarray( N, \*X, strideX, offsetX )

Computes the [arithmetic mean][arithmetic-mean] of a double-precision floating-point strided array, ignoring `NaN` values and using pairwise summation and alternative indexing semantics.

```c
const double x[] = { 1.0, -2.0, 0.0/0.0, 2.0 };

double v = stdlib_strided_dnanmeanpw_ndarray( 4, x, 1, 0 );
// returns ~0.3333
```

The function accepts the following arguments:

- **N**: `[in] CBLAS_INT` number of indexed elements.
- **X**: `[in] double*` input array.
- **strideX**: `[in] CBLAS_INT` stride length.
- **offsetX**: `[in] CBLAS_INT` starting index.

```c
double stdlib_strided_dnanmeanpw_ndarray( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX );
```

</section>

<!-- /.usage -->

<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="notes">

</section>

<!-- /.notes -->

<!-- C API usage examples. -->

<section class="examples">

### Examples

```c
#include "stdlib/stats/base/dnanmeanpw.h"
#include <stdio.h>

int main( void ) {
// Create a strided array:
const double x[] = { 1.0, 2.0, 0.0/0.0, 3.0, 0.0/0.0, 4.0, 5.0, 6.0, 0.0/0.0, 7.0, 8.0, 0.0/0.0 };

// Specify the number of elements:
const int N = 6;

// Specify the stride length:
const int strideX = 2;

// Compute the arithmetic mean:
double v = stdlib_strided_dnanmeanpw( N, x, strideX );

// Print the result:
printf( "mean: %lf\n", v );
}
```

</section>

<!-- /.examples -->

</section>

<!-- /.c -->

* * *

<section class="references">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,30 @@
// MODULES //

var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var pow = require( '@stdlib/math/base/special/pow' );
var Float64Array = require( '@stdlib/array/float64' );
var uniform = require( '@stdlib/random/base/uniform' );
var bernoulli = require( '@stdlib/random/base/bernoulli' );
var filledarrayBy = require( '@stdlib/array/filled-by' );
var pkg = require( './../package.json' ).name;
var dnanmeanpw = require( './../lib/dnanmeanpw.js' );


// FUNCTIONS //

/**
* Returns a random value or `NaN`.
*
* @private
* @returns {number} random number or `NaN`
*/
function rand() {
if ( bernoulli( 0.2 ) ) {
return NaN;
}
return uniform( -10.0, 10.0 );
}

/**
* Creates a benchmark function.
*
Expand All @@ -39,17 +53,7 @@ var dnanmeanpw = require( './../lib/dnanmeanpw.js' );
* @returns {Function} benchmark function
*/
function createBenchmark( len ) {
var x;
var i;

x = new Float64Array( len );
for ( i = 0; i < x.length; i++ ) {
if ( randu() < 0.2 ) {
x[ i ] = NaN;
} else {
x[ i ] = ( randu()*20.0 ) - 10.0;
}
}
var x = filledarrayBy( len, 'float64', rand );
return benchmark;

function benchmark( b ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@

var resolve = require( 'path' ).resolve;
var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var pow = require( '@stdlib/math/base/special/pow' );
var Float64Array = require( '@stdlib/array/float64' );
var uniform = require( '@stdlib/random/base/uniform' );
var bernoulli = require( '@stdlib/random/base/bernoulli' );
var filledarrayBy = require( '@stdlib/array/filled-by' );
var tryRequire = require( '@stdlib/utils/try-require' );
var pkg = require( './../package.json' ).name;

Expand All @@ -40,6 +41,19 @@ var opts = {

// FUNCTIONS //

/**
* Returns a random value or `NaN`.
*
* @private
* @returns {number} random number or `NaN`
*/
function rand() {
if ( bernoulli( 0.2 ) ) {
return NaN;
}
return uniform( -10.0, 10.0 );
}

/**
* Creates a benchmark function.
*
Expand All @@ -48,17 +62,7 @@ var opts = {
* @returns {Function} benchmark function
*/
function createBenchmark( len ) {
var x;
var i;

x = new Float64Array( len );
for ( i = 0; i < x.length; i++ ) {
if ( randu() < 0.2 ) {
x[ i ] = NaN;
} else {
x[ i ] = ( randu()*20.0 ) - 10.0;
}
}
var x = filledarrayBy( len, 'float64', rand );
return benchmark;

function benchmark( b ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,30 @@
// MODULES //

var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var pow = require( '@stdlib/math/base/special/pow' );
var Float64Array = require( '@stdlib/array/float64' );
var uniform = require( '@stdlib/random/base/uniform' );
var bernoulli = require( '@stdlib/random/base/bernoulli' );
var filledarrayBy = require( '@stdlib/array/filled-by' );
var pkg = require( './../package.json' ).name;
var dnanmeanpw = require( './../lib/ndarray.js' );


// FUNCTIONS //

/**
* Returns a random value or `NaN`.
*
* @private
* @returns {number} random number or `NaN`
*/
function rand() {
if ( bernoulli( 0.2 ) ) {
return NaN;
}
return uniform( -10.0, 10.0 );
}

/**
* Creates a benchmark function.
*
Expand All @@ -39,17 +53,7 @@ var dnanmeanpw = require( './../lib/ndarray.js' );
* @returns {Function} benchmark function
*/
function createBenchmark( len ) {
var x;
var i;

x = new Float64Array( len );
for ( i = 0; i < x.length; i++ ) {
if ( randu() < 0.2 ) {
x[ i ] = NaN;
} else {
x[ i ] = ( randu()*20.0 ) - 10.0;
}
}
var x = filledarrayBy( len, 'float64', rand );
return benchmark;

function benchmark( b ) {
Expand Down
Loading
Loading