diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/README.md b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/README.md index ac28485e833e..98bed025a670 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/README.md +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/README.md @@ -54,11 +54,11 @@ The function has the following parameters: - **N**: number of indexed elements. - **x**: input [`Float64Array`][@stdlib/array/float64]. -- **strideX**: index increment for the strided array. +- **strideX**: stride length for `x`. - **out**: output [`Float64Array`][@stdlib/array/float64] whose first element is the sum and whose second element is the number of non-NaN elements. -- **strideOut**: index increment for `out`. +- **strideOut**: stride length for `out`. -The `N` and `stride` parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in the strided array, +The `N` and stride parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in the strided array, ```javascript var Float64Array = require( '@stdlib/array/float64' ); @@ -103,10 +103,10 @@ var v = dnannsumpw.ndarray( x.length, x, 1, 0, out, 1, 0 ); The function has the following additional parameters: -- **offsetX**: starting index for the strided array. +- **offsetX**: starting index for `x`. - **offsetOut**: starting index for `out`. -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 sum of every other value in the strided array starting from the second value +While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, offset parameters support indexing semantics based on starting indices. For example, to calculate the sum of every other element starting from the second element: ```javascript var Float64Array = require( '@stdlib/array/float64' ); @@ -165,8 +165,136 @@ console.log( out ); + + * * * +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/blas/ext/base/dnannsumpw.h" +``` + +#### stdlib_strided_dnannsumpw( N, \*X, strideX, \*n ) + +Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation. + +```c +#include "stdlib/blas/base/shared.h" + +const double x[] = { 1.0, 2.0, 0.0/0.0, 4.0 }; +CBLAS_INT n = 0; + +double v = stdlib_strided_dnannsumpw( 4, x, 1, &n ); +// returns 7.0 +``` + +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 for `X`. +- **n**: `[out] CBLAS_INT*` pointer for storing the number of non-NaN elements. + +```c +double stdlib_strided_dnannsumpw( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, CBLAS_INT *n ); +``` + +#### stdlib_strided_dnannsumpw_ndarray( N, \*X, strideX, offsetX, \*n ) + +Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation and alternative indexing semantics. + +```c +#include "stdlib/blas/base/shared.h" + +const double x[] = { 1.0, 2.0, 0.0/0.0, 4.0 }; +CBLAS_INT n = 0; + +double v = stdlib_strided_dnannsumpw_ndarray( 4, x, 1, 0, &n ); +// returns 7.0 +``` + +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 for `X`. +- **offsetX**: `[in] CBLAS_INT` starting index for `X`. +- **n**: `[out] CBLAS_INT*` pointer for storing the number of non-NaN elements. + +```c +double stdlib_strided_dnannsumpw_ndarray( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n ); +``` + +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/blas/ext/base/dnannsumpw.h" +#include "stdlib/blase/base/shared.h" +#include + +int main( void ) { + // Create a strided array: + const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 0.0/0.0, 0.0/0.0 }; + + // Specify the number of elements: + const int N = 5; + + // Specify the stride length: + const int strideX = 2; + + // Initialize a variable for storing the number of non-NaN elements: + CBLAS_INT n = 0; + + // Compute the sum: + double v = stdlib_strided_dnannsumpw( N, x, strideX, &n ); + + // Print the result: + printf( "sum: %lf\n", v ); + printf( "n: %"CBLAS_IFMT"\n", n ); +} +``` + +
+ + + +
+ + +
## References diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.js index a9a4f5f23f07..45120e4e7b57 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.js @@ -33,6 +33,19 @@ var dnannsumpw = require( './../lib/dnannsumpw.js' ); // FUNCTIONS // +/** +* Returns a random number. +* +* @private +* @returns {number} random number +*/ +function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; +} + /** * Creates a benchmark function. * @@ -48,13 +61,6 @@ function createBenchmark( len ) { out = new Float64Array( 2 ); return benchmark; - function rand() { - if ( bernoulli( 0.8 ) > 0 ) { - return uniform( -10.0, 10.0 ); - } - return NaN; - } - function benchmark( b ) { var i; diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.native.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.native.js index 7f92db217940..08369d93594d 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.native.js @@ -42,6 +42,19 @@ var opts = { // FUNCTIONS // +/** +* Returns a random number. +* +* @private +* @returns {number} random number +*/ +function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; +} + /** * Creates a benchmark function. * @@ -57,13 +70,6 @@ function createBenchmark( len ) { out = new Float64Array( 2 ); return benchmark; - function rand() { - if ( bernoulli( 0.8 ) > 0 ) { - return uniform( -10.0, 10.0 ); - } - return NaN; - } - function benchmark( b ) { var i; diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.js index 27f46c98249c..387aea7dd0c7 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.js @@ -33,6 +33,19 @@ var dnannsumpw = require( './../lib/ndarray.js' ); // FUNCTIONS // +/** +* Returns a random number. +* +* @private +* @returns {number} random number +*/ +function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; +} + /** * Creates a benchmark function. * @@ -48,13 +61,6 @@ function createBenchmark( len ) { out = new Float64Array( 2 ); return benchmark; - function rand() { - if ( bernoulli( 0.8 ) > 0 ) { - return uniform( -10.0, 10.0 ); - } - return NaN; - } - function benchmark( b ) { var i; diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.native.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.native.js index 87555212004a..57b7e7f82b58 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/benchmark.ndarray.native.js @@ -42,6 +42,19 @@ var opts = { // FUNCTIONS // +/** +* Returns a random number. +* +* @private +* @returns {number} random number +*/ +function rand() { + if ( bernoulli( 0.8 ) > 0 ) { + return uniform( -10.0, 10.0 ); + } + return NaN; +} + /** * Creates a benchmark function. * @@ -57,13 +70,6 @@ function createBenchmark( len ) { out = new Float64Array( 2 ); return benchmark; - function rand() { - if ( bernoulli( 0.8 ) > 0 ) { - return uniform( -10.0, 10.0 ); - } - return NaN; - } - function benchmark( b ) { var i; diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/c/benchmark.length.c b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/c/benchmark.length.c index ed0058b4c274..fc00c28830cf 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/c/benchmark.length.c +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/benchmark/c/benchmark.length.c @@ -17,6 +17,7 @@ */ #include "stdlib/blas/ext/base/dnannsumpw.h" +#include "stdlib/blas/base/shared.h" #include #include #include @@ -94,10 +95,10 @@ static double rand_double( void ) { * @param len array length * @return elapsed time in seconds */ -static double benchmark( int iterations, int len ) { +static double benchmark1( int iterations, int len ) { double elapsed; double x[ len ]; - int64_t n; + CBLAS_INT n; double v; double t; int i; @@ -113,6 +114,7 @@ static double benchmark( int iterations, int len ) { n = 0; t = tic(); for ( i = 0; i < iterations; i++ ) { + // cppcheck-suppress uninitvar v = stdlib_strided_dnannsumpw( len, x, 1, &n ); if ( v != v || n < 0 ) { printf( "should not return NaN\n" ); @@ -126,6 +128,46 @@ static double benchmark( int iterations, int len ) { return elapsed; } +/** +* Runs a benchmark. +* +* @param iterations number of iterations +* @param len array length +* @return elapsed time in seconds +*/ +static double benchmark2( int iterations, int len ) { + double elapsed; + double x[ len ]; + CBLAS_INT n; + double v; + double t; + int i; + + for ( i = 0; i < len; i++ ) { + if ( rand_double() < 0.2 ) { + x[ i ] = 0.0 / 0.0; // NaN + } else { + x[ i ] = ( rand_double() * 20000.0 ) - 10000.0; + } + } + v = 0.0; + n = 0; + t = tic(); + for ( i = 0; i < iterations; i++ ) { + // cppcheck-suppress uninitvar + v = stdlib_strided_dnannsumpw_ndarray( len, x, 1, 0, &n ); + if ( v != v || n < 0 ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( v != v || n < 0 ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + /** * Main execution sequence. */ @@ -148,7 +190,18 @@ int main( void ) { for ( j = 0; j < REPEATS; j++ ) { count += 1; printf( "# c::%s:len=%d\n", NAME, len ); - elapsed = benchmark( iter, len ); + elapsed = benchmark1( iter, len ); + print_results( iter, elapsed ); + printf( "ok %d benchmark finished\n", count ); + } + } + for ( i = MIN; i <= MAX; i++ ) { + len = pow( 10, i ); + iter = ITERATIONS / pow( 10, i-1 ); + for ( j = 0; j < REPEATS; j++ ) { + count += 1; + printf( "# c::%s:ndarray:len=%d\n", NAME, len ); + elapsed = benchmark2( iter, len ); print_results( iter, elapsed ); printf( "ok %d benchmark finished\n", count ); } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/docs/repl.txt b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/docs/repl.txt index 7a9cab8d5a14..f25ec2c1eaf6 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/docs/repl.txt +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/docs/repl.txt @@ -3,7 +3,7 @@ Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation. - The `N` and `stride` parameters determine which elements are accessed at + The `N` and stride parameters determine which elements are accessed at runtime. Indexing is relative to the first index. To introduce an offset, use a typed @@ -20,13 +20,13 @@ Input array. strideX: integer - Index increment for the strided array. + Stride length for `x`. out: Float64Array Output array. strideOut: integer - Index increment for `out`. + Stride length for `out`. Returns ------- @@ -42,7 +42,7 @@ > {{alias}}( x.length, x, 1, out, 1 ) [ 1.0, 3 ] - // Using `N` and `stride` parameters: + // Using `N` and stride parameters: > x = new {{alias:@stdlib/array/float64}}( [ -2.0, 1.0, 1.0, -5.0, 2.0, -1.0, NaN, NaN ] ); > out = new {{alias:@stdlib/array/float64}}( 2 ); > {{alias}}( 4, x, 2, out, 1 ) @@ -62,8 +62,8 @@ semantics. While typed array views mandate a view offset based on the underlying - buffer, the `offset` parameter supports indexing semantics based on a - starting index. + buffer, offset parameters support indexing semantics based on starting + indices. Parameters ---------- @@ -74,7 +74,7 @@ Input array. strideX: integer - Index increment for the strided array. + Stride length for `x`. offsetX: integer Starting index for the strided array. @@ -83,7 +83,7 @@ Output array. strideOut: integer - Index increment for `out`. + Stride length for `out`. offsetOut: integer Starting index for `out`. diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/examples/c/example.c b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/examples/c/example.c index 5a3a8cd14119..c46893ab378d 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/examples/c/example.c +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/examples/c/example.c @@ -17,27 +17,26 @@ */ #include "stdlib/blas/ext/base/dnannsumpw.h" -#include +#include "stdlib/blas/base/shared.h" #include -#include int main( void ) { // Create a strided array: const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 0.0/0.0, 0.0/0.0 }; // Specify the number of elements: - const int64_t N = 5; + const int N = 5; // Specify the stride length: - const int64_t stride = 2; + const int strideX = 2; // Initialize a variable for storing the number of non-NaN elements: - int64_t n = 0; + CBLAS_INT n = 0; // Compute the sum: - double v = stdlib_strided_dnannsumpw( N, x, stride, &n ); + double v = stdlib_strided_dnannsumpw( N, x, strideX, &n ); // Print the result: printf( "sum: %lf\n", v ); - printf( "n: %"PRId64"\n", n ); + printf( "n: %"CBLAS_IFMT"\n", n ); } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/include/stdlib/blas/ext/base/dnannsumpw.h b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/include/stdlib/blas/ext/base/dnannsumpw.h index 6380bc832703..436aaab6c9b3 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/include/stdlib/blas/ext/base/dnannsumpw.h +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/include/stdlib/blas/ext/base/dnannsumpw.h @@ -19,7 +19,7 @@ #ifndef STDLIB_BLAS_EXT_BASE_DNANNSUMPW_H #define STDLIB_BLAS_EXT_BASE_DNANNSUMPW_H -#include +#include "stdlib/blas/base/shared.h" /* * If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler. @@ -31,7 +31,12 @@ extern "C" { /** * Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation. */ -double stdlib_strided_dnannsumpw( const int64_t N, const double *X, const int64_t stride, int64_t *n ); +double API_SUFFIX(stdlib_strided_dnannsumpw)( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, CBLAS_INT *n ); + +/** +* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation and alternative indexing semantics. +*/ +double API_SUFFIX(stdlib_strided_dnannsumpw_ndarray)( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n ); #ifdef __cplusplus } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/dnannsumpw.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/dnannsumpw.js index 1ce83c440c6a..5f61c70dc4ee 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/dnannsumpw.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/dnannsumpw.js @@ -20,7 +20,8 @@ // MODULES // -var sumpw = require( './sumpw.js' ); +var stride2offset = require( '@stdlib/strided/base/stride2offset' ); +var ndarray = require( './ndarray.js' ); // MAIN // @@ -55,20 +56,12 @@ var sumpw = require( './sumpw.js' ); function dnannsumpw( N, x, strideX, out, strideOut ) { var ix; var io; - if ( strideX < 0 ) { - ix = (1-N) * strideX; - } else { - ix = 0; - } - if ( strideOut < 0 ) { - io = -strideOut; - } else { - io = 0; - } + + ix = stride2offset( N, strideX ); + io = stride2offset( 2, strideOut ); out[ io ] = 0.0; out[ io+strideOut ] = 0; - sumpw( N, x, strideX, ix, out, strideOut, io ); - return out; + return ndarray( N, x, strideX, ix, out, strideOut, io ); } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.js index 33b88afce3cc..fca24fbc8d69 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.js @@ -57,8 +57,7 @@ var sumpw = require( './sumpw.js' ); function dnannsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { out[ offsetOut ] = 0.0; out[ offsetOut+strideOut ] = 0; - sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ); - return out; + return sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ); } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.native.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.native.js index 3cf957affba4..ff2bfb3f4b62 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/ndarray.native.js @@ -20,9 +20,7 @@ // MODULES // -var minViewBufferIndex = require( '@stdlib/strided/base/min-view-buffer-index' ); -var offsetView = require( '@stdlib/strided/base/offset-view' ); -var addon = require( './dnannsumpw.native.js' ); +var addon = require( './../src/addon.node' ); // MAIN // @@ -49,17 +47,7 @@ var addon = require( './dnannsumpw.native.js' ); * // returns [ 5.0, 4 ] */ function dnannsumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { - var viewOut; - var viewX; - - offsetX = minViewBufferIndex( N, strideX, offsetX ); - if ( strideOut < 0 ) { - offsetOut += strideOut; - } - - viewX = offsetView( x, offsetX ); - viewOut = offsetView( out, offsetOut ); - addon( N, viewX, strideX, viewOut, strideOut ); + addon.ndarray( N, x, strideX, offsetX, out, strideOut, offsetOut ); return out; } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/sumpw.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/sumpw.js index be329386ceb1..ca04003c0190 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/sumpw.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/lib/sumpw.js @@ -58,15 +58,13 @@ var BLOCKSIZE = 128; * 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, NaN ] ); -* var N = floor( x.length / 2 ); * * var out = new Float64Array( [ 0.0, 0 ] ); -* var v = sumpw( N, x, 2, 1, out, 1, 0 ); +* var v = sumpw( 5.0, x, 2, 1, out, 1, 0 ); * // returns [ 5.0, 4 ] */ function sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { var ix; - var io; var s0; var s1; var s2; @@ -85,13 +83,12 @@ function sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { return out; } ix = offsetX; - io = offsetOut; - if ( N === 1 || strideX === 0 ) { + if ( strideX === 0 ) { if ( isnan( x[ ix ] ) ) { return out; } - out[ io ] += x[ ix ]; - out[ io+strideOut ] += 1; + out[ offsetOut ] += x[ ix ] * N; + out[ offsetOut+strideOut ] += N; return out; } if ( N < 8 ) { @@ -106,8 +103,8 @@ function sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { } ix += strideX; } - out[ io ] += s; - out[ io+strideOut ] += n; + out[ offsetOut ] += s; + out[ offsetOut+strideOut ] += n; return out; } if ( N <= BLOCKSIZE ) { @@ -174,7 +171,7 @@ function sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { ix += strideX; } // Pairwise sum the accumulators: - s = ((s0+s1) + (s2+s3)) + ((s4+s5) + (s6+s7)); + s = ( (s0+s1) + (s2+s3) ) + ( (s4+s5) + (s6+s7) ); // Clean-up loop... for ( i; i < N; i++ ) { @@ -185,8 +182,8 @@ function sumpw( N, x, strideX, offsetX, out, strideOut, offsetOut ) { } ix += strideX; } - out[ io ] += s; - out[ io+strideOut ] += n; + out[ offsetOut ] += s; + out[ offsetOut+strideOut ] += n; return out; } // Recurse by dividing by two, but avoiding non-multiples of unroll factor... diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/manifest.json b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/manifest.json index c6e264b64d2a..afff6bbbe3e4 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/manifest.json +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/manifest.json @@ -28,49 +28,54 @@ { "task": "build", "src": [ - "./src/dnannsumpw.c" + "./src/main.c" ], "include": [ "./include" ], - "libraries": [ - "-lm" - ], + "libraries": [], "libpath": [], "dependencies": [ "@stdlib/napi/export", "@stdlib/napi/argv", "@stdlib/napi/argv-int64", - "@stdlib/napi/argv-strided-float64array" + "@stdlib/napi/argv-strided-float64array", + "@stdlib/math/base/assert/is-nan", + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, { "task": "benchmark", "src": [ - "./src/dnannsumpw.c" + "./src/main.c" ], "include": [ "./include" ], - "libraries": [ - "-lm" - ], + "libraries": [], "libpath": [], - "dependencies": [] + "dependencies": [ + "@stdlib/math/base/assert/is-nan", + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" + ] }, { "task": "examples", "src": [ - "./src/dnannsumpw.c" + "./src/main.c" ], "include": [ "./include" ], - "libraries": [ - "-lm" - ], + "libraries": [], "libpath": [], - "dependencies": [] + "dependencies": [ + "@stdlib/math/base/assert/is-nan", + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" + ] } ] } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/addon.c b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/addon.c index 54705f129b12..432ea3a13952 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/addon.c +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/addon.c @@ -17,10 +17,13 @@ */ #include "stdlib/blas/ext/base/dnannsumpw.h" +#include "stdlib/blas/base/shared.h" #include "stdlib/napi/export.h" #include "stdlib/napi/argv.h" #include "stdlib/napi/argv_int64.h" #include "stdlib/napi/argv_strided_float64array.h" +#include "stdlib/strided/base/stride2offset.h" +#include #include /** @@ -38,20 +41,36 @@ static napi_value addon( napi_env env, napi_callback_info info ) { STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, strideX, argv, 1 ); STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, Out, 2, strideOut, argv, 3 ); - int64_t io; - if ( strideOut < 0 ) { - io = -strideOut; - } - else { - io = 0; - } - - double *out = Out; - int64_t n; - out[ io ] = stdlib_strided_dnannsumpw( N, X, strideX, &n ); - out[ io + strideOut ] = (double)n; + int64_t io = stdlib_strided_stride2offset( 2, strideOut ); + CBLAS_INT n; + Out[ io ] = API_SUFFIX(stdlib_strided_dnannsumpw)( N, X, strideX, &n ); + Out[ io + strideOut ] = (double)n; return NULL; } -STDLIB_NAPI_MODULE_EXPORT_FCN( addon ) +/** +* Receives JavaScript callback invocation data. +* +* @param env environment under which the function is invoked +* @param info callback data +* @return Node-API value +*/ +static napi_value addon_method( napi_env env, napi_callback_info info ) { + STDLIB_NAPI_ARGV( env, info, argv, argc, 7 ); + STDLIB_NAPI_ARGV_INT64( env, N, argv, 0 ); + STDLIB_NAPI_ARGV_INT64( env, strideX, argv, 2 ); + STDLIB_NAPI_ARGV_INT64( env, offsetX, argv, 3 ); + STDLIB_NAPI_ARGV_INT64( env, strideOut, argv, 5 ); + STDLIB_NAPI_ARGV_INT64( env, offsetOut, argv, 6 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, strideX, argv, 1 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, Out, 2, strideOut, argv, 4 ); + + CBLAS_INT n; + Out[ offsetOut ] = API_SUFFIX(stdlib_strided_dnannsumpw_ndarray)( N, X, strideX, offsetX, &n ); + Out[ offsetOut+strideOut ] = (double)n; + + return NULL; +} + +STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method ) diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/dnannsumpw.c b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/main.c similarity index 54% rename from lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/dnannsumpw.c rename to lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/main.c index 575e1df464a5..de333666e8f9 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/dnannsumpw.c +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/src/main.c @@ -17,25 +17,26 @@ */ #include "stdlib/blas/ext/base/dnannsumpw.h" -#include +#include "stdlib/strided/base/stride2offset.h" +#include "stdlib/math/base/assert/is_nan.h" +#include "stdlib/blas/base/shared.h" /** * Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation. * -* @param N number of indexed elements -* @param X input array -* @param stride stride length -* @param n pointer for storing the number of non-NaN elements -* @return output value +* @param N number of indexed elements +* @param X input array +* @param strideX stride length +* @param offsetX starting index +* @param n pointer for storing the number of non-NaN elements +* @return output value */ -static double sumpw( const int64_t N, const double *X, const int64_t stride, int64_t *n ) { - double *xp1; - double *xp2; +static double sumpw( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n ) { + CBLAS_INT ix; + CBLAS_INT M; + CBLAS_INT m; + CBLAS_INT i; double sum; - int64_t ix; - int64_t M; - int64_t m; - int64_t i; double s0; double s1; double s2; @@ -46,21 +47,18 @@ static double sumpw( const int64_t N, const double *X, const int64_t stride, int double s7; double v; + sum = 0.0; if ( N <= 0 ) { - return 0.0; + return sum; } - if ( N == 1 || stride == 0 ) { - v = X[ 0 ]; - if ( v == v ) { - *n += 1; - return v; + ix = offsetX; + if ( strideX == 0 ) { + if ( stdlib_base_is_nan( X[ ix ] ) ) { + return sum; } - return 0.0; - } - if ( stride < 0 ) { - ix = (1-N) * stride; - } else { - ix = 0; + sum = X[ ix ] * N; + *n += N; + return sum; } if ( N < 8 ) { // Use simple summation... @@ -71,7 +69,7 @@ static double sumpw( const int64_t N, const double *X, const int64_t stride, int sum += v; *n += 1; } - ix += stride; + ix += strideX; } return sum; } @@ -94,52 +92,52 @@ static double sumpw( const int64_t N, const double *X, const int64_t stride, int s0 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s1 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s2 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s3 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s4 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s5 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s6 += v; *n += 1; } - ix += stride; + ix += strideX; v = X[ ix ]; if ( v == v ) { s7 += v; *n += 1; } - ix += stride; + ix += strideX; } // Pairwise sum the accumulators: - sum = ((s0+s1) + (s2+s3)) + ((s4+s5) + (s6+s7)); + sum = ( (s0+s1) + (s2+s3) ) + ( (s4+s5) + (s6+s7) ); // Clean-up loop... for (; i < N; i++ ) { @@ -148,21 +146,14 @@ static double sumpw( const int64_t N, const double *X, const int64_t stride, int sum += v; *n += 1; } - ix += stride; + ix += strideX; } return sum; } // Recurse by dividing by two, but avoiding non-multiples of unroll factor... m = N / 2; m -= m % 8; - if ( stride < 0 ) { - xp1 = (double *)X + ( (m-N)*stride ); - xp2 = (double *)X; - } else { - xp1 = (double *)X; - xp2 = (double *)X + ( m*stride ); - } - return sumpw( m, xp1, stride, n ) + sumpw( N-m, xp2, stride, n ); + return sumpw( m, X, strideX, ix, n ) + sumpw( N-m, X, strideX, ix+(m*strideX), n ); } /** @@ -176,13 +167,39 @@ static double sumpw( const int64_t N, const double *X, const int64_t stride, int * * - Higham, Nicholas J. 1993. "The Accuracy of Floating Point Summation." _SIAM Journal on Scientific Computing_ 14 (4): 783–99. doi:[10.1137/0914050](https://doi.org/10.1137/0914050). * -* @param N number of indexed elements -* @param X input array -* @param stride stride length -* @param n pointer for storing the number of non-NaN elements -* @return output value +* @param N number of indexed elements +* @param X input array +* @param strideX stride length +* @param n pointer for storing the number of non-NaN elements +* @return output value +*/ +double API_SUFFIX(stdlib_strided_dnannsumpw)( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, CBLAS_INT *n ) { + CBLAS_INT ox; + + *n = 0; + ox = stdlib_strided_stride2offset( N, strideX ); + return API_SUFFIX(stdlib_strided_dnannsumpw_ndarray)( N, X, strideX, ox, n ); +} + +/** +* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation and alternative indexing semantics. +* +* ## Method +* +* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`. +* +* ## References +* +* - Higham, Nicholas J. 1993. "The Accuracy of Floating Point Summation." _SIAM Journal on Scientific Computing_ 14 (4): 783–99. doi:[10.1137/0914050](https://doi.org/10.1137/0914050). +* +* @param N number of indexed elements +* @param X input array +* @param strideX stride length +* @param offsetX starting index +* @param n pointer for storing the number of non-NaN elements +* @return output value */ -double stdlib_strided_dnannsumpw( const int64_t N, const double *X, const int64_t stride, int64_t *n ) { +double API_SUFFIX(stdlib_strided_dnannsumpw_ndarray)( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n ) { *n = 0; - return sumpw( N, X, stride, n ); + return sumpw( N, X, strideX, offsetX, n ); } diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.js index 67bab782e80d..8f81d9232b02 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.js @@ -228,7 +228,7 @@ tape( 'the function supports negative `stride` parameters', function test( t ) { t.end(); }); -tape( 'if provided a `stride` parameter equal to `0`, the function returns a sum equal to the first element', function test( t ) { +tape( 'if provided a `stride` parameter equal to `0`, the function returns the sum of the first element repeated N times', function test( t ) { var expected; var out; var x; @@ -239,7 +239,7 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns a sum out = new Float64Array( 2 ); v = dnannsumpw( x.length, x, 0, out, 1 ); - expected = new Float64Array( [ 1.0, 1.0 ] ); + expected = new Float64Array( [ 5.0, 5.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); t.end(); diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.native.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.native.js index 4861b86c57d5..003d044b0847 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.dnannsumpw.native.js @@ -237,7 +237,7 @@ tape( 'the function supports negative `stride` parameters', opts, function test( t.end(); }); -tape( 'if provided a `stride` parameter equal to `0`, the function returns a sum equal to the first element', opts, function test( t ) { +tape( 'if provided a `stride` parameter equal to `0`, the function returns the sum of the first element repeated N times', opts, function test( t ) { var expected; var out; var x; @@ -248,7 +248,7 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns a sum out = new Float64Array( 2 ); v = dnannsumpw( x.length, x, 0, out, 1 ); - expected = new Float64Array( [ 1.0, 1.0 ] ); + expected = new Float64Array( [ 5.0, 5.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); t.end(); diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.js index b6cf906bfc35..940a884bacb2 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.js @@ -228,7 +228,7 @@ tape( 'the function supports a negative `stride` parameter', function test( t ) t.end(); }); -tape( 'if provided a `stride` parameter equal to `0`, the function returns the first indexed element', function test( t ) { +tape( 'if provided a `stride` parameter equal to `0`, the function returns the sum of the first element repeated N times', function test( t ) { var expected; var out; var x; @@ -239,7 +239,7 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns the f out = new Float64Array( 2 ); v = dnannsumpw( x.length, x, 0, 0, out, 1, 0 ); - expected = new Float64Array( [ 1.0, 1.0 ] ); + expected = new Float64Array( [ 5.0, 5.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); t.end(); diff --git a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.native.js b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.native.js index dc96f01a09bf..ed07ad902921 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/dnannsumpw/test/test.ndarray.native.js @@ -237,7 +237,7 @@ tape( 'the function supports a negative `stride` parameter', opts, function test t.end(); }); -tape( 'if provided a `stride` parameter equal to `0`, the function returns the first indexed element', opts, function test( t ) { +tape( 'if provided a `stride` parameter equal to `0`, the function returns the sum of the first element repeated N times', opts, function test( t ) { var expected; var out; var x; @@ -248,7 +248,7 @@ tape( 'if provided a `stride` parameter equal to `0`, the function returns the f out = new Float64Array( 2 ); v = dnannsumpw( x.length, x, 0, 0, out, 1, 0 ); - expected = new Float64Array( [ 1.0, 1.0 ] ); + expected = new Float64Array( [ 5.0, 5.0 ] ); t.deepEqual( v, expected, 'returns expected value' ); t.end();