diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/README.md b/lib/node_modules/@stdlib/blas/base/dznrm2/README.md index c7ffa367638f..f98c2f9cb8f4 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/README.md +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/README.md @@ -194,6 +194,28 @@ The function accepts the following arguments: double c_dznrm2( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX ); ``` +#### c_dznrm2_ndarray( N, \*ZX, strideX, offsetX ) + +Computes the L2-norm of a complex double-precision floating-point vector using alternative indexing semantics. + +```c +const double zx[] = { 0.3, 0.1, 0.5, 0.0, 0.0, 0.5, 0.0, 0.2 }; + +double norm = c_dznrm2_ndarray( 4, (void *)zx, 1, 0 ); +// returns 0.8 +``` + +The function accepts the following arguments: + +- **N**: `[in] CBLAS_INT` number of indexed elements. +- **ZX**: `[in] void*` input array. +- **strideX**: `[in] CBLAS_INT` index increment for `ZX`. +- **offsetX**: `[in] CBLAS_INT` starting index for `ZX`. + +```c +double c_dznrm2_ndarray( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX, const CBLAS_INT offsetX ); +``` + @@ -227,7 +249,13 @@ int main( void ) { const int strideX = 1; // Compute the L2-norm: - c_dznrm2( N, (void *)zx, strideX ); + double norm = c_dznrm2( N, (void *)zx, strideX ); + + // Print the result: + printf( "L2-norm: %lf\n", norm ); + + // Compute the L2-norm using alternative indexing semantics: + norm = c_dznrm2_ndarray( N, (void *)zx, -strideX, N-1 ); // Print the result: printf( "L2-norm: %lf\n", norm ); diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/benchmark/c/benchmark.length.c b/lib/node_modules/@stdlib/blas/base/dznrm2/benchmark/c/benchmark.length.c index db19e1ea3ff6..aec045524417 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/benchmark/c/benchmark.length.c +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/benchmark/c/benchmark.length.c @@ -94,7 +94,7 @@ 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 zx[ len*2 ]; double elapsed; double norm; @@ -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 zx[ len*2 ]; + double elapsed; + double norm; + double t; + int i; + + for ( i = 0; i < len*2; i += 2 ) { + zx[ i ] = ( rand_double()*10000.0 ) - 5000.0; + zx[ i+1 ] = ( rand_double()*10000.0 ) - 5000.0; + } + norm = 0.0; + t = tic(); + for ( i = 0; i < iterations; i++ ) { + norm = c_dznrm2_ndarray( len, (void *)zx, 1, 0 ); + if ( norm != norm ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( norm != norm ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + /** * Main execution sequence. */ @@ -143,7 +177,14 @@ 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 ( 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/base/dznrm2/examples/c/example.c b/lib/node_modules/@stdlib/blas/base/dznrm2/examples/c/example.c index 45aac519f2c6..ce62c54d34fe 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/examples/c/example.c +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/examples/c/example.c @@ -34,4 +34,10 @@ int main( void ) { // Print the result: printf( "L2-norm: %lf\n", norm ); + + // Compute the L2-norm using alternative indexing semantics: + norm = c_dznrm2_ndarray( N, (void *)zx, -strideX, N-1 ); + + // Print the result: + printf( "L2-norm: %lf\n", norm ); } diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/include/stdlib/blas/base/dznrm2.h b/lib/node_modules/@stdlib/blas/base/dznrm2/include/stdlib/blas/base/dznrm2.h index e2b5c0087b43..1d1cec032929 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/include/stdlib/blas/base/dznrm2.h +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/include/stdlib/blas/base/dznrm2.h @@ -36,6 +36,11 @@ extern "C" { */ double API_SUFFIX(c_dznrm2)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX ); +/** +* Computes the L2-norm of a complex double-precision floating-point vector using alternative indexing semantics. +*/ +double API_SUFFIX(c_dznrm2_ndarray)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX, const CBLAS_INT offsetX ); + #ifdef __cplusplus } #endif diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/lib/ndarray.native.js b/lib/node_modules/@stdlib/blas/base/dznrm2/lib/ndarray.native.js index 6b71ead5effb..3151a368e863 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/lib/ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/lib/ndarray.native.js @@ -21,7 +21,6 @@ // MODULES // var reinterpret = require( '@stdlib/strided/base/reinterpret-complex128' ); -var minViewBufferIndex = require( '@stdlib/strided/base/min-view-buffer-index' ); var addon = require( './../src/addon.node' ); @@ -46,10 +45,8 @@ var addon = require( './../src/addon.node' ); * // returns ~0.8 */ function dznrm2( N, zx, strideX, offsetX ) { - var viewZX; - offsetX = minViewBufferIndex( N, strideX, offsetX ); - viewZX = reinterpret( zx, offsetX ); - return addon( N, viewZX, strideX ); + var viewZX = reinterpret( zx, 0 ); + return addon.ndarray( N, viewZX, strideX, offsetX ); } diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/manifest.json b/lib/node_modules/@stdlib/blas/base/dznrm2/manifest.json index 7abbcb4e360c..cad308a32a3e 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/manifest.json +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/manifest.json @@ -49,6 +49,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex128array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor", "@stdlib/napi/create-double" ] }, @@ -58,7 +60,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -67,6 +70,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", @@ -79,7 +83,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -88,6 +93,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", @@ -117,6 +123,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex128array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor", "@stdlib/napi/create-double" ] }, @@ -137,7 +145,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor" ] }, { @@ -157,7 +167,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor" ] }, @@ -182,6 +194,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex128array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor", "@stdlib/napi/create-double" ] }, @@ -191,7 +205,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -200,6 +215,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", @@ -212,7 +228,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -221,6 +238,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", @@ -249,6 +267,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex128array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor", "@stdlib/napi/create-double" ] }, @@ -268,7 +288,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor" ] }, { @@ -287,7 +309,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor" ] }, @@ -313,6 +337,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex128array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor", "@stdlib/napi/create-double" ] }, @@ -333,7 +359,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor" ] }, { @@ -353,7 +381,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float64/ctor" ] }, @@ -363,7 +393,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -376,6 +407,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex128array", + "@stdlib/strided/base/stride2offset", + "@stdlib/complex/float64/ctor", "@stdlib/napi/create-double", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", @@ -389,7 +422,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -398,6 +432,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", @@ -410,7 +445,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -419,6 +455,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", @@ -432,7 +469,8 @@ "blas": "", "wasm": true, "src": [ - "./src/dznrm2.c" + "./src/dznrm2.c", + "./src/dznrm2_ndarray.c" ], "include": [ "./include" @@ -441,6 +479,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/abs", "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/sqrt", diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/src/addon.c b/lib/node_modules/@stdlib/blas/base/dznrm2/src/addon.c index 38fb0a20b2b9..872d89236cfd 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/src/addon.c +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/src/addon.c @@ -37,8 +37,25 @@ static napi_value addon( napi_env env, napi_callback_info info ) { STDLIB_NAPI_ARGV_INT64( env, N, argv, 0 ); STDLIB_NAPI_ARGV_INT64( env, strideX, argv, 2 ); STDLIB_NAPI_ARGV_STRIDED_COMPLEX128ARRAY( env, ZX, N, strideX, argv, 1 ); - STDLIB_NAPI_CREATE_DOUBLE( env, API_SUFFIX(c_dznrm2)( N, ZX, strideX ), norm ); + STDLIB_NAPI_CREATE_DOUBLE( env, API_SUFFIX(c_dznrm2)( N, (void *)ZX, strideX ), norm ); return norm; } -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, 4 ); + 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_STRIDED_COMPLEX128ARRAY( env, ZX, N, strideX, argv, 1 ); + STDLIB_NAPI_CREATE_DOUBLE( env, API_SUFFIX(c_dznrm2_ndarray)( N, (void *)ZX, strideX, offsetX ), norm ); + return norm; +} + +STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method ) diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2.c b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2.c index e75fb386f759..a10a3c743aa8 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2.c +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2.c @@ -18,17 +18,7 @@ #include "stdlib/blas/base/dznrm2.h" #include "stdlib/blas/base/shared.h" -#include "stdlib/math/base/special/abs.h" -#include "stdlib/math/base/special/abs2.h" -#include "stdlib/math/base/special/sqrt.h" -#include "stdlib/constants/float64/max.h" -#include - -// Blue's scaling constants... -static const double tsml = 1.4916681462400413E-154; -static const double tbig = 1.9979190722022350E+146; -static const double ssml = 4.4989137945431964E+161; -static const double sbig = 1.1113793747425387E-162; +#include "stdlib/strided/base/stride2offset.h" /** * Computes the L2-norm of a complex double-precision floating-point vector. @@ -38,90 +28,6 @@ static const double sbig = 1.1113793747425387E-162; * @param strideX ZX stride length */ double API_SUFFIX(c_dznrm2)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX ) { - double *x = (double *)ZX; - CBLAS_INT sx; - CBLAS_INT ix; - bool notbig; - CBLAS_INT i; - double sumsq; - double abig; - double amed; - double asml; - double ymax; - double ymin; - double scl; - double ax; - - if ( N <= 0 ) { - return 0.0; - } - sx = strideX * 2; - if ( sx < 0 ) { - ix = ( 1 - N ) * sx; - } else { - ix = 0; - } - // Compute the sum of squares using 3 accumulators--`abig` (sum of squares scaled down to avoid overflow), `asml` (sum of squares scaled up to avoid underflow), `amed` (sum of squares that do not require scaling)--and thresholds and multipliers--`tbig` (values bigger than this are scaled down by `sbig`) and `tsml` (values smaller than this are scaled up by `ssml`)... - notbig = true; - sumsq = 0.0; - abig = 0.0; - amed = 0.0; - asml = 0.0; - for ( i = 0; i < N; i++ ) { - ax = stdlib_base_abs( x[ ix ] ); - if ( ax > tbig ) { - abig += stdlib_base_abs2( ax * sbig ); - notbig = false; - } else if ( ax < tsml ) { - if ( notbig ) { - asml += stdlib_base_abs2( ax * ssml ); - } - } else { - amed += stdlib_base_abs2( ax ); - } - ax = stdlib_base_abs( x[ ix + 1 ] ); - if ( ax > tbig ) { - abig += stdlib_base_abs2( ax * sbig ); - notbig = false; - } else if ( ax < tsml ) { - if ( notbig ) { - asml += stdlib_base_abs2( ax * ssml ); - } - } else { - amed += stdlib_base_abs2( ax ); - } - ix += sx; - } - // Combine `abig` and `amed` or `amed` and `asml` if more than one accumulator was used... - if ( abig > 0.0 ) { - // Combine `abig` and `amed` if `abig` > 0... - if ( amed > 0.0 || ( amed > STDLIB_CONSTANT_FLOAT64_MAX ) || ( amed != amed ) ) { - abig += ( amed * sbig ) * sbig; - } - scl = 1.0 / sbig; - sumsq = abig; - } else if ( asml > 0.0 ) { - // Combine `amed` and `asml` if `asml` > 0... - if ( amed > 0.0 || amed > STDLIB_CONSTANT_FLOAT64_MAX || ( amed != amed ) ) { - amed = stdlib_base_sqrt( amed ); - asml = stdlib_base_sqrt( asml ) / ssml; - if ( asml > amed ) { - ymin = amed; - ymax = asml; - } else { - ymin = asml; - ymax = amed; - } - scl = 1.0; - sumsq = stdlib_base_abs2( ymax ) * ( 1.0 + stdlib_base_abs2( ymin / ymax ) ); - } else { - scl = 1.0 / ssml; - sumsq = asml; - } - } else { - // All values are mid-range... - scl = 1.0; - sumsq = amed; - } - return stdlib_base_sqrt( sumsq ) * scl; + CBLAS_INT ox = stdlib_strided_stride2offset( N, strideX ); + return API_SUFFIX(c_dznrm2_ndarray)( N, ZX, strideX, ox ); } diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_cblas.c b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_cblas.c index f809ea2cff89..beade39c8f30 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_cblas.c +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_cblas.c @@ -19,6 +19,8 @@ #include "stdlib/blas/base/dznrm2.h" #include "stdlib/blas/base/dznrm2_cblas.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/complex/float64/ctor.h" +#include "stdlib/strided/base/min_view_buffer_index.h" /** * Computes the L2-norm of a complex double-precision floating-point vector. @@ -30,3 +32,17 @@ double API_SUFFIX(c_dznrm2)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX ) { return API_SUFFIX(cblas_dznrm2)( N, ZX, strideX ); } + +/** +* Computes the L2-norm of a complex double-precision floating-point vector using alternative indexing semantics. +* +* @param N number of indexed elements +* @param ZX input array +* @param strideX ZX stride length +* @param offsetX starting index for ZX +*/ +double API_SUFFIX(c_dznrm2_ndarray)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX , const CBLAS_INT offsetX ) { + stdlib_complex128_t *zx = (stdlib_complex128_t *)ZX; + zx += stdlib_strided_min_view_buffer_index( N, strideX, offsetX ); + return API_SUFFIX(cblas_dznrm2)( N, (void *)zx, strideX ); +} diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_f.c b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_f.c index a2b41fc95663..d43863c791d3 100644 --- a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_f.c +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_f.c @@ -19,6 +19,8 @@ #include "stdlib/blas/base/dznrm2.h" #include "stdlib/blas/base/dznrm2_fortran.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/complex/float64/ctor.h" +#include "stdlib/strided/base/min_view_buffer_index.h" /** * Computes the L2-norm of a complex double-precision floating-point vector. @@ -33,3 +35,20 @@ double API_SUFFIX(c_dznrm2)( const CBLAS_INT N, const void *ZX, const CBLAS_INT dznrm2sub( &N, ZX, &strideX, &nrm2 ); return nrm2; } + +/** +* Computes the L2-norm of a complex double-precision floating-point vector using alternative indexing semantics. +* +* @param N number of indexed elements +* @param ZX input array +* @param strideX ZX stride length +* @param offsetX starting index for ZX +* @return L2-norm +*/ +double API_SUFFIX(c_dznrm2_ndarray)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX, const CBLAS_INT offsetX ) { + stdlib_complex128_t *zx = (stdlib_complex128_t *)ZX; + double nrm2; + zx += stdlib_strided_min_view_buffer_index( N, strideX, offsetX ); + dznrm2sub( &N, (void *)zx, &strideX, &nrm2 ); + return nrm2; +} diff --git a/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_ndarray.c b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_ndarray.c new file mode 100644 index 000000000000..727b729aa59c --- /dev/null +++ b/lib/node_modules/@stdlib/blas/base/dznrm2/src/dznrm2_ndarray.c @@ -0,0 +1,125 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "stdlib/blas/base/dznrm2.h" +#include "stdlib/blas/base/shared.h" +#include "stdlib/math/base/special/abs.h" +#include "stdlib/math/base/special/abs2.h" +#include "stdlib/math/base/special/sqrt.h" +#include "stdlib/constants/float64/max.h" +#include + +// Blue's scaling constants... +static const double tsml = 1.4916681462400413E-154; +static const double tbig = 1.9979190722022350E+146; +static const double ssml = 4.4989137945431964E+161; +static const double sbig = 1.1113793747425387E-162; + +/** +* Computes the L2-norm of a complex double-precision floating-point vector using alternative indexing semantics. +* +* @param N number of indexed elements +* @param ZX input array +* @param strideX ZX stride length +* @param offsetX starting index for ZX +*/ +double API_SUFFIX(c_dznrm2_ndarray)( const CBLAS_INT N, const void *ZX, const CBLAS_INT strideX, const CBLAS_INT offsetX ) { + const double *x = (double *)ZX; + CBLAS_INT sx; + CBLAS_INT ix; + bool notbig; + CBLAS_INT i; + double sumsq; + double abig; + double amed; + double asml; + double ymax; + double ymin; + double scl; + double ax; + + if ( N <= 0 ) { + return 0.0; + } + sx = strideX * 2; + ix = offsetX * 2; + + // Compute the sum of squares using 3 accumulators--`abig` (sum of squares scaled down to avoid overflow), `asml` (sum of squares scaled up to avoid underflow), `amed` (sum of squares that do not require scaling)--and thresholds and multipliers--`tbig` (values bigger than this are scaled down by `sbig`) and `tsml` (values smaller than this are scaled up by `ssml`)... + notbig = true; + sumsq = 0.0; + abig = 0.0; + amed = 0.0; + asml = 0.0; + for ( i = 0; i < N; i++ ) { + ax = stdlib_base_abs( x[ ix ] ); + if ( ax > tbig ) { + abig += stdlib_base_abs2( ax * sbig ); + notbig = false; + } else if ( ax < tsml ) { + if ( notbig ) { + asml += stdlib_base_abs2( ax * ssml ); + } + } else { + amed += stdlib_base_abs2( ax ); + } + ax = stdlib_base_abs( x[ ix + 1 ] ); + if ( ax > tbig ) { + abig += stdlib_base_abs2( ax * sbig ); + notbig = false; + } else if ( ax < tsml ) { + if ( notbig ) { + asml += stdlib_base_abs2( ax * ssml ); + } + } else { + amed += stdlib_base_abs2( ax ); + } + ix += sx; + } + // Combine `abig` and `amed` or `amed` and `asml` if more than one accumulator was used... + if ( abig > 0.0 ) { + // Combine `abig` and `amed` if `abig` > 0... + if ( amed > 0.0 || ( amed > STDLIB_CONSTANT_FLOAT64_MAX ) || ( amed != amed ) ) { + abig += ( amed * sbig ) * sbig; + } + scl = 1.0 / sbig; + sumsq = abig; + } else if ( asml > 0.0 ) { + // Combine `amed` and `asml` if `asml` > 0... + if ( amed > 0.0 || amed > STDLIB_CONSTANT_FLOAT64_MAX || ( amed != amed ) ) { + amed = stdlib_base_sqrt( amed ); + asml = stdlib_base_sqrt( asml ) / ssml; + if ( asml > amed ) { + ymin = amed; + ymax = asml; + } else { + ymin = asml; + ymax = amed; + } + scl = 1.0; + sumsq = stdlib_base_abs2( ymax ) * ( 1.0 + stdlib_base_abs2( ymin / ymax ) ); + } else { + scl = 1.0 / ssml; + sumsq = asml; + } + } else { + // All values are mid-range... + scl = 1.0; + sumsq = amed; + } + return stdlib_base_sqrt( sumsq ) * scl; +}