From 2848cd1dacd0229bd84ff97dd77063cdf03ee60c Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Thu, 16 Jan 2025 19:31:34 +0000 Subject: [PATCH] feat: add C ndarray API and refactor --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: na - task: lint_repl_help status: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: missing_dependencies - task: lint_c_examples status: missing_dependencies - task: lint_c_benchmarks status: missing_dependencies - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- type: pre_push_report description: Results of running various checks prior to pushing changes. report: - task: run_javascript_examples status: na - task: run_c_examples status: na - task: run_cpp_examples status: na - task: run_javascript_readme_examples status: na - task: run_c_benchmarks status: na - task: run_cpp_benchmarks status: na - task: run_fortran_benchmarks status: na - task: run_javascript_benchmarks status: na - task: run_julia_benchmarks status: na - task: run_python_benchmarks status: na - task: run_r_benchmarks status: na - task: run_javascript_tests status: na --- --- .../@stdlib/blas/ext/base/scusumkbn/README.md | 149 +++++++++++++++++- .../ext/base/scusumkbn/benchmark/benchmark.js | 11 +- .../scusumkbn/benchmark/benchmark.native.js | 11 +- .../scusumkbn/benchmark/benchmark.ndarray.js | 11 +- .../benchmark/benchmark.ndarray.native.js | 11 +- .../scusumkbn/benchmark/c/benchmark.length.c | 49 +++++- .../blas/ext/base/scusumkbn/docs/repl.txt | 15 +- .../ext/base/scusumkbn/docs/types/index.d.ts | 12 +- .../ext/base/scusumkbn/examples/c/example.c | 16 +- .../blas/ext/base/scusumkbn/examples/index.js | 11 +- .../include/stdlib/blas/ext/base/scusumkbn.h | 9 +- .../blas/ext/base/scusumkbn/lib/index.js | 7 +- .../blas/ext/base/scusumkbn/lib/ndarray.js | 12 +- .../ext/base/scusumkbn/lib/ndarray.native.js | 21 +-- .../blas/ext/base/scusumkbn/lib/scusumkbn.js | 48 +----- .../base/scusumkbn/lib/scusumkbn.native.js | 7 +- .../blas/ext/base/scusumkbn/manifest.json | 18 ++- .../blas/ext/base/scusumkbn/src/addon.c | 26 ++- .../scusumkbn/src/{scusumkbn.c => main.c} | 53 +++++-- 19 files changed, 339 insertions(+), 158 deletions(-) rename lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/{scusumkbn.c => main.c} (50%) diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/README.md b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/README.md index 9959aa54cf6a..a886b5b06ff3 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/README.md +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/README.md @@ -61,11 +61,11 @@ The function has the following parameters: - **N**: number of indexed elements. - **sum**: initial sum. - **x**: input [`Float32Array`][@stdlib/array/float32]. -- **strideX**: index increment for `x`. +- **strideX**: stride length for `x`. - **y**: output [`Float32Array`][@stdlib/array/float32]. -- **strideY**: index increment for `y`. +- **strideY**: stride length for `y`. -The `N` and stride parameters determine which elements in the strided arrays are accessed at runtime. For example, to compute the cumulative sum of every other element in `x`, +The `N` and stride parameters determine which elements in the strided arrays are accessed at runtime. For example, to compute the cumulative sum of every other element: ```javascript var Float32Array = require( '@stdlib/array/float32' ); @@ -114,7 +114,7 @@ The function has the following additional parameters: - **offsetX**: starting index for `x`. - **offsetY**: starting index for `y`. -While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, offset parameters support indexing semantics based on a starting indices. For example, to calculate the cumulative sum of every other value in `x` starting from the second value and to store in the last `N` elements of `y` starting from the last element +While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on starting indices. For example, to calculate the cumulative sum of every other element starting from the second element and to store in the last `N` elements of `y` starting from the last element: ```javascript var Float32Array = require( '@stdlib/array/float32' ); @@ -147,14 +147,17 @@ scusumkbn.ndarray( 4, 0.0, x, 2, 1, y, -1, y.length-1 ); ```javascript -var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ).factory; -var filledarrayBy = require( '@stdlib/array/filled-by' ); +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); var scusumkbn = require( '@stdlib/blas/ext/base/scusumkbn' ); -var x = filledarrayBy( 10, 'float32', discreteUniform( 0, 100 ) ); +var x = discreteUniform( 10, -100, 100, { + 'dtype': 'float32' +}); console.log( x ); -var y = filledarrayBy( x.length, 'float32', discreteUniform( 0, 10 ) ); +var y = discreteUniform( 10, -100, 100, { + 'dtype': 'float32' +}); console.log( y ); scusumkbn( x.length, 0.0, x, 1, y, -1 ); @@ -165,8 +168,138 @@ console.log( y ); + + * * * +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/blas/ext/base/scusumkbn.h" +``` + +#### stdlib_strided_scusumkbn( N, sum, \*X, strideX, \*Y, strideY ) + +Computes the cumulative sum of single-precision floating-point strided array elements using an improved Kahan–Babuška algorithm. + +```c +const float x[] = { 1.0f, 2.0f, 3.0f, 4.0f }; +float y[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + +stdlib_strided_scusumkbn( 4, 0.0f, x, 1, y, 1 ); +``` + +The function accepts the following arguments: + +- **N**: `[in] CBLAS_INT` number of indexed elements. +- **sum**: `[in] float` initial sum. +- **X**: `[in] float*` input array. +- **strideX**: `[in] CBLAS_INT` stride length for `X`. +- **Y**: `[out] float*` output array. +- **strideY**: `[in] CBLAS_INT` stride length for `Y`. + +```c +void stdlib_strided_scusumkbn( const CBLAS_INT N, const float sum, const float *X, const CBLAS_INT strideX, float *Y, const CBLAS_INT strideY ); +``` + + + +#### stdlib_strided_scusumkbn_ndarray( N, sum, \*X, strideX, offsetX, \*Y, strideY, offsetY ) + + + +Computes the cumulative sum of single-precision floating-point strided array elements using an improved Kahan–Babuška algorithm and alternative indexing semantics. + +```c +const float x[] = { 1.0f, 2.0f, 3.0f, 4.0f }; +float y[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + +stdlib_strided_scusumkbn_ndarray( 4, 0.0f, x, 1, 0, y, 1, 0 ); +``` + +The function accepts the following arguments: + +- **N**: `[in] CBLAS_INT` number of indexed elements. +- **sum**: `[in] float` initial sum. +- **X**: `[in] float*` input array. +- **strideX**: `[in] CBLAS_INT` stride length for `X`. +- **offsetX**: `[in] CBLAS_INT` starting index for `X`. +- **Y**: `[out] float*` output array. +- **strideY**: `[in] CBLAS_INT` stride length for `Y`. +- **offsetY**: `[in] CBLAS_INT` starting index for `Y`. + +```c +void stdlib_strided_scusumkbn_ndarray( const CBLAS_INT N, const float sum, const float *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, float *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY ); +``` + +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/blas/ext/base/scusumkbn.h" +#include + +int main( void ) { + // Create strided arrays: + const float x[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; + float y[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + + // Specify the number of elements: + const int N = 4; + + // Specify stride lengths: + const int strideX = 2; + const int strideY = -2; + + // Compute the cumulative sum: + stdlib_strided_scusumkbn( N, 0.0f, x, strideX, y, strideY ); + + // Print the result: + for ( int i = 0; i < 8; i++ ) { + printf( "y[ %d ] = %f\n", i, y[ i ] ); + } +} +``` + +
+ + + +
+ + +
## References diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.js index d3306232854f..c6bc32f4b5be 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.js @@ -21,8 +21,7 @@ // MODULES // var bench = require( '@stdlib/bench' ); -var uniform = require( '@stdlib/random/base/uniform' ).factory; -var filledarrayBy = require( '@stdlib/array/filled-by' ); +var uniform = require( '@stdlib/random/array/uniform' ); var isnanf = require( '@stdlib/math/base/assert/is-nanf' ); var pow = require( '@stdlib/math/base/special/pow' ); var pkg = require( './../package.json' ).name; @@ -31,7 +30,9 @@ var scusumkbn = require( './../lib/scusumkbn.js' ); // VARIABLES // -var rand = uniform( -100.0, 100.0 ); +var options = { + 'dtype': 'float32' +}; // FUNCTIONS // @@ -44,8 +45,8 @@ var rand = uniform( -100.0, 100.0 ); * @returns {Function} benchmark function */ function createBenchmark( len ) { - var x = filledarrayBy( len, 'float32', rand ); - var y = filledarrayBy( len, 'float32', rand ); + var x = uniform( len, -100, 100, options ); + var y = uniform( len, -100, 100, options ); return benchmark; function benchmark( b ) { diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.native.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.native.js index 5ec896713745..0e7b58b7ca4c 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.native.js @@ -22,8 +22,7 @@ var resolve = require( 'path' ).resolve; var bench = require( '@stdlib/bench' ); -var uniform = require( '@stdlib/random/base/uniform' ).factory; -var filledarrayBy = require( '@stdlib/array/filled-by' ); +var uniform = require( '@stdlib/random/array/uniform' ); var isnanf = require( '@stdlib/math/base/assert/is-nanf' ); var pow = require( '@stdlib/math/base/special/pow' ); var tryRequire = require( '@stdlib/utils/try-require' ); @@ -36,7 +35,9 @@ var scusumkbn = tryRequire( resolve( __dirname, './../lib/scusumkbn.native.js' ) var opts = { 'skip': ( scusumkbn instanceof Error ) }; -var rand = uniform( -100.0, 100.0 ); +var options = { + 'dtype': 'float32' +}; // FUNCTIONS // @@ -49,8 +50,8 @@ var rand = uniform( -100.0, 100.0 ); * @returns {Function} benchmark function */ function createBenchmark( len ) { - var x = filledarrayBy( len, 'float32', rand ); - var y = filledarrayBy( len, 'float32', rand ); + var x = uniform( len, -100, 100, options ); + var y = uniform( len, -100, 100, options ); return benchmark; function benchmark( b ) { diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.js index b515bb63eec5..04ee413248f4 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.js @@ -21,8 +21,7 @@ // MODULES // var bench = require( '@stdlib/bench' ); -var uniform = require( '@stdlib/random/base/uniform' ).factory; -var filledarrayBy = require( '@stdlib/array/filled-by' ); +var uniform = require( '@stdlib/random/array/uniform' ); var isnanf = require( '@stdlib/math/base/assert/is-nanf' ); var pow = require( '@stdlib/math/base/special/pow' ); var pkg = require( './../package.json' ).name; @@ -31,7 +30,9 @@ var scusumkbn = require( './../lib/ndarray.js' ); // VARIABLES // -var rand = uniform( -100.0, 100.0 ); +var options = { + 'dtype': 'float32' +}; // FUNCTIONS // @@ -44,8 +45,8 @@ var rand = uniform( -100.0, 100.0 ); * @returns {Function} benchmark function */ function createBenchmark( len ) { - var x = filledarrayBy( len, 'float32', rand ); - var y = filledarrayBy( len, 'float32', rand ); + var x = uniform( len, -100, 100, options ); + var y = uniform( len, -100, 100, options ); return benchmark; function benchmark( b ) { diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.native.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.native.js index a9ac4955e25a..2ac5c4647a5d 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/benchmark.ndarray.native.js @@ -22,8 +22,7 @@ var resolve = require( 'path' ).resolve; var bench = require( '@stdlib/bench' ); -var uniform = require( '@stdlib/random/base/uniform' ).factory; -var filledarrayBy = require( '@stdlib/array/filled-by' ); +var uniform = require( '@stdlib/random/array/uniform' ); var isnanf = require( '@stdlib/math/base/assert/is-nanf' ); var pow = require( '@stdlib/math/base/special/pow' ); var tryRequire = require( '@stdlib/utils/try-require' ); @@ -36,7 +35,9 @@ var scusumkbn = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) ) var opts = { 'skip': ( scusumkbn instanceof Error ) }; -var rand = uniform( -100.0, 100.0 ); +var options = { + 'dtype': 'float32' +}; // FUNCTIONS // @@ -49,8 +50,8 @@ var rand = uniform( -100.0, 100.0 ); * @returns {Function} benchmark function */ function createBenchmark( len ) { - var x = filledarrayBy( len, 'float32', rand ); - var y = filledarrayBy( len, 'float32', rand ); + var x = uniform( len, -100, 100, options ); + var y = uniform( len, -100, 100, options ); return benchmark; function benchmark( b ) { diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/c/benchmark.length.c b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/c/benchmark.length.c index db6994749941..7a00351ca445 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/c/benchmark.length.c +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/benchmark/c/benchmark.length.c @@ -94,7 +94,7 @@ static float rand_float( 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; float x[ len ]; float y[ len ]; @@ -121,6 +121,40 @@ 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; + float x[ len ]; + float y[ len ]; + double t; + int i; + + for ( i = 0; i < len; i++ ) { + x[ i ] = ( rand_float() * 20000.0f ) - 10000.0f; + y[ i ] = 0.0f; + } + t = tic(); + for ( i = 0; i < iterations; i++ ) { + x[ 0 ] += 1.0f; + stdlib_strided_scusumkbn_ndarray( len, 0.0f, x, 1, 0, y, 1, 0 ); + if ( y[ 0 ] != y[ 0 ] ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( y[ len-1 ] != y[ len-1 ] ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + /** * Main execution sequence. */ @@ -143,7 +177,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/scusumkbn/docs/repl.txt b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/repl.txt index a64a884cd6b1..ac7d807b96cb 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/repl.txt +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/repl.txt @@ -23,13 +23,13 @@ Input array. strideX: integer - Index increment for `x`. + Stride length for `x`. y: Float32Array Output array. strideY: integer - Index increment for `y`. + Stride length for `y`. Returns ------- @@ -55,8 +55,7 @@ > var y0 = new {{alias:@stdlib/array/float32}}( x0.length ); > var x1 = new {{alias:@stdlib/array/float32}}( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); > var y1 = new {{alias:@stdlib/array/float32}}( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); - > N = {{alias:@stdlib/math/base/special/floor}}( x0.length / 2 ); - > {{alias}}( N, 0.0, x1, 2, y1, 1 ) + > {{alias}}( 3, 0.0, x1, 2, y1, 1 ) [ -2.0, 0.0, -1.0 ] > y0 [ 0.0, 0.0, 0.0, -2.0, 0.0, -1.0 ] @@ -68,8 +67,8 @@ semantics. While typed array views mandate a view offset based on the underlying - buffer, the offset parameters support indexing semantics based on - starting indices. + buffer, the offset parameters support indexing semantics based on starting + indices. Parameters ---------- @@ -83,7 +82,7 @@ Input array. strideX: integer - Index increment for `x`. + Stride length for `x`. offsetX: integer Starting index for `x`. @@ -92,7 +91,7 @@ Output array. strideY: integer - Index increment for `y`. + Stride length for `y`. offsetY: integer Starting index for `y`. diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/types/index.d.ts b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/types/index.d.ts index eba0f2fcf550..9124a74cf282 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/docs/types/index.d.ts @@ -28,9 +28,9 @@ interface Routine { * @param N - number of indexed elements * @param sum - initial sum * @param x - input array - * @param strideX - `x` stride length + * @param strideX - stride length for `x` * @param y - output array - * @param strideY - `y` stride length + * @param strideY - stride length for `y` * @returns output array * * @example @@ -50,10 +50,10 @@ interface Routine { * @param N - number of indexed elements * @param sum - initial sum * @param x - input array - * @param strideX - `x` stride length + * @param strideX - stride length for `x` * @param offsetX - starting index for `x` * @param y - output array - * @param strideY - `y` stride length + * @param strideY - stride length for `y` * @param offsetY - starting index for `y` * @returns output array * @@ -75,9 +75,9 @@ interface Routine { * @param N - number of indexed elements * @param sum - initial sum * @param x - input array -* @param strideX - `x` stride length +* @param strideX - stride length for `x` * @param y - output array -* @param strideY - `y` stride length +* @param strideY - stride length for `y` * @returns output array * * @example diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/c/example.c b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/c/example.c index f57296b2794f..b05a93fa29a7 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/c/example.c +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/c/example.c @@ -17,27 +17,25 @@ */ #include "stdlib/blas/ext/base/scusumkbn.h" -#include #include -#include int main( void ) { // Create strided arrays: - const float x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 }; - float y[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + const float x[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; + float y[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; // Specify the number of elements: - const int64_t N = 4; + const int N = 4; // Specify stride lengths: - const int64_t strideX = 2; - const int64_t strideY = -2; + const int strideX = 2; + const int strideY = -2; // Compute the cumulative sum: stdlib_strided_scusumkbn( N, 0.0f, x, strideX, y, strideY ); // Print the result: - for ( int64_t i = 0; i < 8; i++ ) { - printf( "y[ %"PRId64" ] = %f\n", i, y[ i ] ); + for ( int i = 0; i < 8; i++ ) { + printf( "y[ %d ] = %f\n", i, y[ i ] ); } } diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/index.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/index.js index c3c81e53b3b9..87a31dfa72d2 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/index.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/examples/index.js @@ -18,14 +18,17 @@ 'use strict'; -var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ).factory; -var filledarrayBy = require( '@stdlib/array/filled-by' ); +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); var scusumkbn = require( './../lib' ); -var x = filledarrayBy( 10, 'float32', discreteUniform( 0, 100 ) ); +var x = discreteUniform( 10, -100, 100, { + 'dtype': 'float32' +}); console.log( x ); -var y = filledarrayBy( x.length, 'float32', discreteUniform( 0, 10 ) ); +var y = discreteUniform( 10, -100, 100, { + 'dtype': 'float32' +}); console.log( y ); scusumkbn( x.length, 0.0, x, 1, y, -1 ); diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/include/stdlib/blas/ext/base/scusumkbn.h b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/include/stdlib/blas/ext/base/scusumkbn.h index efd09cd3770f..8d285545d4aa 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/include/stdlib/blas/ext/base/scusumkbn.h +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/include/stdlib/blas/ext/base/scusumkbn.h @@ -19,7 +19,7 @@ #ifndef STDLIB_BLAS_EXT_BASE_SCUSUMKBN_H #define STDLIB_BLAS_EXT_BASE_SCUSUMKBN_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 cumulative sum of single-precision floating-point strided array elements using an improved Kahan–Babuška algorithm. */ -void stdlib_strided_scusumkbn( const int64_t N, const float sum, const float *X, const int64_t strideX, float *Y, const int64_t strideY ); +void API_SUFFIX(stdlib_strided_scusumkbn)( const CBLAS_INT N, const float sum, const float *X, const CBLAS_INT strideX, float *Y, const CBLAS_INT strideY ); + +/** +* Computes the cumulative sum of single-precision floating-point strided array elements using an improved Kahan–Babuška algorithm and alternative indexing semantics. +*/ +void API_SUFFIX(stdlib_strided_scusumkbn_ndarray)( const CBLAS_INT N, const float sum, const float *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, float *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY ); #ifdef __cplusplus } diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/index.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/index.js index 77e8a723b0c8..c162885e8cb5 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/index.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/index.js @@ -29,21 +29,18 @@ * * var x = new Float32Array( [ 1.0, -2.0, 2.0 ] ); * var y = new Float32Array( x.length ); -* var N = x.length; * -* scusumkbn( N, 0.0, x, 1, y, 1 ); +* scusumkbn( x.length, 0.0, x, 1, y, 1 ); * // y => [ 1.0, -1.0, 1.0 ] * * @example * var Float32Array = require( '@stdlib/array/float32' ); -* var floor = require( '@stdlib/math/base/special/floor' ); * var scusumkbn = require( '@stdlib/blas/ext/base/scusumkbn' ); * * var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); * var y = new Float32Array( x.length ); -* var N = floor( x.length / 2 ); * -* scusumkbn.ndarray( N, 0.0, x, 2, 1, y, 1, 0 ); +* scusumkbn.ndarray( 4, 0.0, x, 2, 1, y, 1, 0 ); * // y => [ 1.0, -1.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0 ] */ diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.js index 128fe7c6f470..ff59c13b518c 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.js @@ -40,22 +40,20 @@ var abs = require( '@stdlib/math/base/special/abs' ); * @param {PositiveInteger} N - number of indexed elements * @param {number} sum - initial sum * @param {Float32Array} x - input array -* @param {integer} strideX - `x` stride length +* @param {integer} strideX - stride length for `x` * @param {NonNegativeInteger} offsetX - starting index for `x` * @param {Float32Array} y - output array -* @param {integer} strideY - `y` stride length +* @param {integer} strideY - stride length for `y` * @param {NonNegativeInteger} offsetY - starting index for `y` * @returns {Float32Array} output array * * @example * var Float32Array = require( '@stdlib/array/float32' ); -* var floor = require( '@stdlib/math/base/special/floor' ); * * var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); * var y = new Float32Array( x.length ); -* var N = floor( x.length / 2 ); * -* var v = scusumkbn( N, 0.0, x, 2, 1, y, 1, 0 ); +* var v = scusumkbn( 4, 0.0, x, 2, 1, y, 1, 0 ); * // returns [ 1.0, -1.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0 ] */ function scusumkbn( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { @@ -78,9 +76,9 @@ function scusumkbn( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { v = x[ ix ]; t = float64ToFloat32( s + v ); if ( abs( s ) >= abs( v ) ) { - c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( s-t ) + v ) ); // eslint-disable-line max-len + c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( s - t ) + v ) ); // eslint-disable-line max-len } else { - c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( v-t ) + s ) ); // eslint-disable-line max-len + c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( v - t ) + s ) ); // eslint-disable-line max-len } s = t; y[ iy ] = float64ToFloat32( s + c ); diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.native.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.native.js index a90fbd186970..f8d25cf3ba79 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/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( './scusumkbn.native.js' ); +var addon = require( './../src/addon.node' ); // MAIN // @@ -33,33 +31,24 @@ var addon = require( './scusumkbn.native.js' ); * @param {PositiveInteger} N - number of indexed elements * @param {number} sum - initial sum * @param {Float32Array} x - input array -* @param {integer} strideX - `x` stride length +* @param {integer} strideX - stride length for `x` * @param {NonNegativeInteger} offsetX - starting index for `x` * @param {Float32Array} y - output array -* @param {integer} strideY - `y` stride length +* @param {integer} strideY - stride length for `y` * @param {NonNegativeInteger} offsetY - starting index for `y` * @returns {Float32Array} output array * * @example * var Float32Array = require( '@stdlib/array/float32' ); -* var floor = require( '@stdlib/math/base/special/floor' ); * * var x = new Float32Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] ); * var y = new Float32Array( x.length ); -* var N = floor( x.length / 2 ); * -* var v = scusumkbn( N, 0.0, x, 2, 1, y, 1, 0 ); +* var v = scusumkbn( 4, 0.0, x, 2, 1, y, 1, 0 ); * // returns [ 1.0, -1.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0 ] */ function scusumkbn( N, sum, x, strideX, offsetX, y, strideY, offsetY ) { - var viewX; - var viewY; - offsetX = minViewBufferIndex( N, strideX, offsetX ); - offsetY = minViewBufferIndex( N, strideY, offsetY ); - - viewX = offsetView( x, offsetX ); - viewY = offsetView( y, offsetY ); - addon( N, sum, viewX, strideX, viewY, strideY ); + addon.ndarray( N, sum, x, strideX, offsetX, y, strideY, offsetY ); return y; } diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.js index ebddb73d9957..3bfaad0300ae 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.js @@ -20,8 +20,8 @@ // MODULES // -var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' ); -var abs = require( '@stdlib/math/base/special/abs' ); +var stride2offset = require( '@stdlib/strided/base/stride2offset' ); +var ndarray = require( './ndarray.js' ); // MAIN // @@ -40,9 +40,9 @@ var abs = require( '@stdlib/math/base/special/abs' ); * @param {PositiveInteger} N - number of indexed elements * @param {number} sum - initial sum * @param {Float32Array} x - input array -* @param {integer} strideX - `x` stride length +* @param {integer} strideX - stride length for `x` * @param {Float32Array} y - output array -* @param {integer} strideY - `y` stride length +* @param {integer} strideY - stride length for `y` * @returns {Float32Array} output array * * @example @@ -50,48 +50,12 @@ var abs = require( '@stdlib/math/base/special/abs' ); * * var x = new Float32Array( [ 1.0, -2.0, 2.0 ] ); * var y = new Float32Array( x.length ); -* var N = x.length; * -* var v = scusumkbn( N, 0.0, x, 1, y, 1 ); +* var v = scusumkbn( x.length, 0.0, x, 1, y, 1 ); * // returns [ 1.0, -1.0, 1.0 ] */ function scusumkbn( N, sum, x, strideX, y, strideY ) { - var ix; - var iy; - var s; - var v; - var t; - var c; - var i; - - if ( N <= 0 ) { - return y; - } - if ( strideX < 0 ) { - ix = (1-N) * strideX; - } else { - ix = 0; - } - if ( strideY < 0 ) { - iy = (1-N) * strideY; - } else { - iy = 0; - } - s = sum; - c = 0.0; - for ( i = 0; i < N; i++ ) { - v = x[ ix ]; - t = float64ToFloat32( s + v ); - if ( abs( s ) >= abs( v ) ) { - c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( s-t ) + v ) ); // eslint-disable-line max-len - } else { - c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( v-t ) + s ) ); // eslint-disable-line max-len - } - s = t; - y[ iy ] = float64ToFloat32( s + c ); - ix += strideX; - iy += strideY; - } + ndarray( N, sum, x, strideX, stride2offset( N, strideX ), y, strideY, stride2offset( N, strideY ) ); // eslint-disable-line max-len return y; } diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.native.js b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.native.js index 9743aa6b2401..8b578e9ac7b2 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.native.js +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/lib/scusumkbn.native.js @@ -31,9 +31,9 @@ var addon = require( './../src/addon.node' ); * @param {PositiveInteger} N - number of indexed elements * @param {number} sum - initial sum * @param {Float32Array} x - input array -* @param {integer} strideX - `x` stride length +* @param {integer} strideX - stride length for `x` * @param {Float32Array} y - output array -* @param {integer} strideY - `y` stride length +* @param {integer} strideY - stride length for `y` * @returns {Float32Array} output array * * @example @@ -41,9 +41,8 @@ var addon = require( './../src/addon.node' ); * * var x = new Float32Array( [ 1.0, -2.0, 2.0 ] ); * var y = new Float32Array( x.length ); -* var N = x.length; * -* var v = scusumkbn( N, 0.0, x, 1, y, 1 ); +* var v = scusumkbn( x.length, 0.0, x, 1, y, 1 ); * // returns [ 1.0, -1.0, 1.0 ] */ function scusumkbn( N, sum, x, strideX, y, strideY ) { diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/manifest.json b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/manifest.json index a25295fc9fe6..af6a8bb276be 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/manifest.json +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/manifest.json @@ -28,7 +28,7 @@ { "task": "build", "src": [ - "./src/scusumkbn.c" + "./src/main.c" ], "include": [ "./include" @@ -41,13 +41,15 @@ "@stdlib/napi/argv-float", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-float32array", - "@stdlib/math/base/special/absf" + "@stdlib/math/base/special/absf", + "@stdlib/strided/base/stride2offset", + "@stdlib/blas/base/shared" ] }, { "task": "benchmark", "src": [ - "./src/scusumkbn.c" + "./src/main.c" ], "include": [ "./include" @@ -55,13 +57,15 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/math/base/special/absf" + "@stdlib/math/base/special/absf", + "@stdlib/strided/base/stride2offset", + "@stdlib/blas/base/shared" ] }, { "task": "examples", "src": [ - "./src/scusumkbn.c" + "./src/main.c" ], "include": [ "./include" @@ -69,7 +73,9 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/math/base/special/absf" + "@stdlib/math/base/special/absf", + "@stdlib/strided/base/stride2offset", + "@stdlib/blas/base/shared" ] } ] diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/addon.c b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/addon.c index 6e9988f0c84e..2da790c46ed8 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/addon.c +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/addon.c @@ -17,6 +17,7 @@ */ #include "stdlib/blas/ext/base/scusumkbn.h" +#include "stdlib/blas/base/shared.h" #include "stdlib/napi/export.h" #include "stdlib/napi/argv.h" #include "stdlib/napi/argv_float.h" @@ -39,8 +40,29 @@ static napi_value addon( napi_env env, napi_callback_info info ) { STDLIB_NAPI_ARGV_INT64( env, strideY, argv, 5 ); STDLIB_NAPI_ARGV_STRIDED_FLOAT32ARRAY( env, X, N, strideX, argv, 2 ); STDLIB_NAPI_ARGV_STRIDED_FLOAT32ARRAY( env, Y, N, strideY, argv, 4 ); - stdlib_strided_scusumkbn( N, sum, X, strideX, Y, strideY ); + API_SUFFIX(stdlib_strided_scusumkbn)( N, sum, X, strideX, Y, strideY ); 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, 8 ); + STDLIB_NAPI_ARGV_INT64( env, N, argv, 0 ); + STDLIB_NAPI_ARGV_FLOAT( env, sum, argv, 1 ); + STDLIB_NAPI_ARGV_INT64( env, strideX, argv, 3 ); + STDLIB_NAPI_ARGV_INT64( env, offsetX, argv, 4 ); + STDLIB_NAPI_ARGV_INT64( env, strideY, argv, 6 ); + STDLIB_NAPI_ARGV_INT64( env, offsetY, argv, 7 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT32ARRAY( env, X, N, strideX, argv, 2 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT32ARRAY( env, Y, N, strideY, argv, 5 ); + API_SUFFIX(stdlib_strided_scusumkbn_ndarray)( N, sum, X, strideX, offsetX, Y, strideY, offsetY ); + return NULL; +} + +STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method ) diff --git a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/scusumkbn.c b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/main.c similarity index 50% rename from lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/scusumkbn.c rename to lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/main.c index 131f3e09eeee..36708668335f 100644 --- a/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/scusumkbn.c +++ b/lib/node_modules/@stdlib/blas/ext/base/scusumkbn/src/main.c @@ -18,7 +18,8 @@ #include "stdlib/blas/ext/base/scusumkbn.h" #include "stdlib/math/base/special/absf.h" -#include +#include "stdlib/strided/base/stride2offset.h" +#include "stdlib/blas/base/shared.h" /** * Computes the cumulative sum of single-precision floating-point strided array elements using an improved Kahan–Babuška algorithm. @@ -34,14 +35,40 @@ * @param N number of indexed elements * @param sum initial sum * @param X input array -* @param strideX X stride length +* @param strideX stride length for X * @param Y output array -* @param strideY Y stride length +* @param strideY stride length for Y */ -void stdlib_strided_scusumkbn( const int64_t N, const float sum, const float *X, const int64_t strideX, float *Y, const int64_t strideY ) { - int64_t ix; - int64_t iy; - int64_t i; +void API_SUFFIX(stdlib_strided_scusumkbn)( const CBLAS_INT N, const float sum, const float *X, const CBLAS_INT strideX, float *Y, const CBLAS_INT strideY ) { + const CBLAS_INT ox = stdlib_strided_stride2offset( N, strideX ); + const CBLAS_INT oy = stdlib_strided_stride2offset( N, strideY ); + API_SUFFIX(stdlib_strided_scusumkbn_ndarray)( N, sum, X, strideX, ox, Y, strideY, oy ); +} + +/** +* Computes the cumulative sum of single-precision floating-point strided array elements using an improved Kahan–Babuška algorithm and alternative indexing semantics. +* +* ## Method +* +* - This implementation uses an "improved Kahan–Babuška algorithm", as described by Neumaier (1974). +* +* ## References +* +* - Neumaier, Arnold. 1974. "Rounding Error Analysis of Some Methods for Summing Finite Sums." _Zeitschrift Für Angewandte Mathematik Und Mechanik_ 54 (1): 39–51. doi:[10.1002/zamm.19740540106](https://doi.org/10.1002/zamm.19740540106). +* +* @param N number of indexed elements +* @param sum initial sum +* @param X input array +* @param strideX stride length for X +* @param offsetX starting index for X +* @param Y output array +* @param strideY stride length for Y +* @param offsetY starting index for Y +*/ +void API_SUFFIX(stdlib_strided_scusumkbn_ndarray)( const CBLAS_INT N, const float sum, const float *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, float *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY ) { + CBLAS_INT ix; + CBLAS_INT iy; + CBLAS_INT i; float s; float v; float t; @@ -50,16 +77,8 @@ void stdlib_strided_scusumkbn( const int64_t N, const float sum, const float *X, if ( N <= 0 ) { return; } - if ( strideX < 0 ) { - ix = (1-N) * strideX; - } else { - ix = 0; - } - if ( strideY < 0 ) { - iy = (1-N) * strideY; - } else { - iy = 0; - } + ix = offsetX; + iy = offsetY; s = sum; c = 0.0f; for ( i = 0; i < N; i++ ) {