diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/README.md b/lib/node_modules/@stdlib/blas/base/scnrm2/README.md index bb98b238b2f6..2d964a481936 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/README.md +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/README.md @@ -181,7 +181,7 @@ Computes the L2-norm of a complex single-precision floating-point vector. const float cx[] = { 0.3f, 0.1f, 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.2f }; float norm = c_scnrm2( 4, (void *)cx, 1 ); -// returns 0.8 +// returns 0.8f ``` The function accepts the following arguments: @@ -194,6 +194,27 @@ The function accepts the following arguments: float c_scnrm2( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX ); ``` +#### c_scnrm2_ndarray( N, \*CX, strideX, offsetX ) + +Computes the L2-norm of a complex single-precision floating-point vector using alternative indexing semantics. + +```c +const float cx[] = { 0.3f, 0.1f, 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.2f }; + +float norm = c_scnrm2_ndarray( 4, (void *)cx, 1, 0 ); +// returns 0.8f +``` + +The function accepts the following arguments: + +- **N**: `[in] CBLAS_INT` number of indexed elements. +- **CX**: `[in] void*` input array. +- **strideX**: `[in] CBLAS_INT` index increment for `CX`. + +```c +float c_scnrm2_ndarray( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX, const CBLAS_INT offsetX ); +``` + @@ -227,7 +248,13 @@ int main( void ) { const int strideX = 1; // Compute the L2-norm: - c_scnrm2( N, (void *)cx, strideX ); + float norm = c_scnrm2( N, (void *)cx, strideX ); + + // Print the result: + printf( "L2-norm: %f\n", norm ); + + // Compute the L2-norm using alternative indexing semantics: + norm = c_scnrm2_ndarray( N, (void *)cx, -strideX, N-1 ); // Print the result: printf( "L2-norm: %f\n", norm ); diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/benchmark/c/benchmark.length.c b/lib/node_modules/@stdlib/blas/base/scnrm2/benchmark/c/benchmark.length.c index 24554c656ea9..d481ff01b009 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/benchmark/c/benchmark.length.c +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/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 ) { float cx[ len*2 ]; double elapsed; float 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 ) { + float cx[ len*2 ]; + double elapsed; + float norm; + double t; + int i; + + for ( i = 0; i < len*2; i += 2 ) { + cx[ i ] = ( rand_float()*10000.0f ) - 5000.0f; + cx[ i+1 ] = ( rand_float()*10000.0f ) - 5000.0f; + } + norm = 0.0f; + t = tic(); + for ( i = 0; i < iterations; i++ ) { + norm = c_scnrm2_ndarray( len, (void *)cx, 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/scnrm2/examples/c/example.c b/lib/node_modules/@stdlib/blas/base/scnrm2/examples/c/example.c index c018f3a0d8d4..0bb2e89c6d0b 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/examples/c/example.c +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/examples/c/example.c @@ -34,4 +34,10 @@ int main( void ) { // Print the result: printf( "L2-norm: %f\n", norm ); + + // Compute the L2-norm using alternative indexing semantics: + norm = c_scnrm2_ndarray( N, (void *)cx, -strideX, N-1 ); + + // Print the result: + printf( "L2-norm: %f\n", norm ); } diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/include/stdlib/blas/base/scnrm2.h b/lib/node_modules/@stdlib/blas/base/scnrm2/include/stdlib/blas/base/scnrm2.h index bb6ae943f285..d58525eb9b69 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/include/stdlib/blas/base/scnrm2.h +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/include/stdlib/blas/base/scnrm2.h @@ -36,6 +36,11 @@ extern "C" { */ float API_SUFFIX(c_scnrm2)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX ); +/** +* Computes the L2-norm of a complex single-precision floating-point vector using alternative indexing semantics. +*/ +float API_SUFFIX(c_scnrm2_ndarray)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX, const CBLAS_INT offsetX ); + #ifdef __cplusplus } #endif diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/lib/ndarray.native.js b/lib/node_modules/@stdlib/blas/base/scnrm2/lib/ndarray.native.js index e34af47ce9d9..c5eea35b87ba 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/lib/ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/lib/ndarray.native.js @@ -21,7 +21,6 @@ // MODULES // var reinterpret = require( '@stdlib/strided/base/reinterpret-complex64' ); -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 scnrm2( N, cx, strideX, offsetX ) { - var viewCX; - offsetX = minViewBufferIndex( N, strideX, offsetX ); - viewCX = reinterpret( cx, offsetX ); - return addon( N, viewCX, strideX ); + var viewCX = reinterpret( cx, 0 ); + return addon.ndarray( N, viewCX, strideX, offsetX ); } diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/manifest.json b/lib/node_modules/@stdlib/blas/base/scnrm2/manifest.json index 17152eac553d..5e8b7543148f 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/manifest.json +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/manifest.json @@ -49,6 +49,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex64array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/ctor", "@stdlib/napi/create-double" ] }, @@ -58,7 +60,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -67,6 +70,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", @@ -79,7 +83,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -88,6 +93,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", @@ -117,6 +123,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex64array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/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/float32/ctor" ] }, { @@ -157,7 +167,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/ctor" ] }, @@ -182,6 +194,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex64array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/ctor", "@stdlib/napi/create-double" ] }, @@ -191,7 +205,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -200,6 +215,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", @@ -212,7 +228,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -221,6 +238,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", @@ -249,6 +267,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex64array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/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/float32/ctor" ] }, { @@ -287,7 +309,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/ctor" ] }, @@ -313,6 +337,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex64array", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/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/float32/ctor" ] }, { @@ -353,7 +381,9 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", + "@stdlib/complex/float32/ctor" ] }, @@ -363,7 +393,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -376,6 +407,8 @@ "@stdlib/napi/argv", "@stdlib/napi/argv-int64", "@stdlib/napi/argv-strided-complex64array", + "@stdlib/strided/base/stride2offset", + "@stdlib/complex/float32/ctor", "@stdlib/napi/create-double", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", @@ -389,7 +422,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -398,6 +432,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", @@ -410,7 +445,8 @@ "blas": "", "wasm": false, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -419,6 +455,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", @@ -432,7 +469,8 @@ "blas": "", "wasm": true, "src": [ - "./src/scnrm2.c" + "./src/scnrm2.c", + "./src/scnrm2_ndarray.c" ], "include": [ "./include" @@ -441,6 +479,7 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/math/base/special/absf", "@stdlib/math/base/special/abs2f", "@stdlib/math/base/special/sqrtf", diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/src/addon.c b/lib/node_modules/@stdlib/blas/base/scnrm2/src/addon.c index 18ece50984e7..3812b55475b9 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/src/addon.c +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/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_COMPLEX64ARRAY( env, CX, N, strideX, argv, 1 ); - STDLIB_NAPI_CREATE_DOUBLE( env, (double)API_SUFFIX(c_scnrm2)( N, CX, strideX ), norm ); + STDLIB_NAPI_CREATE_DOUBLE( env, (double)API_SUFFIX(c_scnrm2)( N, (void *)CX, 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_COMPLEX64ARRAY( env, CX, N, strideX, argv, 1 ); + STDLIB_NAPI_CREATE_DOUBLE( env, (double)API_SUFFIX(c_scnrm2_ndarray)( N, (void *)CX, 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/scnrm2/src/scnrm2.c b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2.c index 8c17b8dc0e0a..65528d4966d1 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2.c +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2.c @@ -18,17 +18,7 @@ #include "stdlib/blas/base/scnrm2.h" #include "stdlib/blas/base/shared.h" -#include "stdlib/math/base/special/absf.h" -#include "stdlib/math/base/special/abs2f.h" -#include "stdlib/math/base/special/sqrtf.h" -#include "stdlib/constants/float32/max.h" -#include - -// Blue's scaling constants... -static const float tsml = 1.08420217E-19f; -static const float tbig = 4.50359963E+15f; -static const float ssml = 3.77789319E+22f; -static const float sbig = 1.32348898E-23f; +#include "stdlib/strided/base/stride2offset.h" /** * Computes the L2-norm of a complex single-precision floating-point vector. @@ -38,90 +28,6 @@ static const float sbig = 1.32348898E-23f; * @param strideX CX stride length */ float API_SUFFIX(c_scnrm2)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX ) { - float *x = (float *)CX; - CBLAS_INT sx; - CBLAS_INT ix; - bool notbig; - CBLAS_INT i; - float sumsq; - float abig; - float amed; - float asml; - float ymax; - float ymin; - float scl; - float ax; - - if ( N <= 0 ) { - return 0.0f; - } - 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.0f; - abig = 0.0f; - amed = 0.0f; - asml = 0.0f; - for ( i = 0; i < N; i++ ) { - ax = stdlib_base_absf( x[ ix ] ); - if ( ax > tbig ) { - abig += stdlib_base_abs2f( ax * sbig ); - notbig = false; - } else if ( ax < tsml ) { - if ( notbig ) { - asml += stdlib_base_abs2f( ax * ssml ); - } - } else { - amed += stdlib_base_abs2f( ax ); - } - ax = stdlib_base_absf( x[ ix + 1 ] ); - if ( ax > tbig ) { - abig += stdlib_base_abs2f( ax * sbig ); - notbig = false; - } else if ( ax < tsml ) { - if ( notbig ) { - asml += stdlib_base_abs2f( ax * ssml ); - } - } else { - amed += stdlib_base_abs2f( ax ); - } - ix += sx; - } - // Combine `abig` and `amed` or `amed` and `asml` if more than one accumulator was used... - if ( abig > 0.0f ) { - // Combine `abig` and `amed` if `abig` > 0... - if ( amed > 0.0f || ( amed > STDLIB_CONSTANT_FLOAT32_MAX ) || ( amed != amed ) ) { - abig += ( amed * sbig ) * sbig; - } - scl = 1.0f / sbig; - sumsq = abig; - } else if ( asml > 0.0f ) { - // Combine `amed` and `asml` if `asml` > 0... - if ( amed > 0.0f || amed > STDLIB_CONSTANT_FLOAT32_MAX || ( amed != amed ) ) { - amed = stdlib_base_sqrtf( amed ); - asml = stdlib_base_sqrtf( asml ) / ssml; - if ( asml > amed ) { - ymin = amed; - ymax = asml; - } else { - ymin = asml; - ymax = amed; - } - scl = 1.0f; - sumsq = stdlib_base_abs2f( ymax ) * ( 1.0 + stdlib_base_abs2f( ymin / ymax ) ); - } else { - scl = 1.0f / ssml; - sumsq = asml; - } - } else { - // All values are mid-range... - scl = 1.0f; - sumsq = amed; - } - return stdlib_base_sqrtf( sumsq ) * scl; + CBLAS_INT ox = stdlib_strided_stride2offset( N, strideX ); + return API_SUFFIX(c_scnrm2_ndarray)( N, CX, strideX, ox ); } diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_cblas.c b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_cblas.c index 532a7000fd18..92fc95b5a3c5 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_cblas.c +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_cblas.c @@ -19,6 +19,8 @@ #include "stdlib/blas/base/scnrm2.h" #include "stdlib/blas/base/scnrm2_cblas.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/complex/float32/ctor.h" +#include "stdlib/strided/base/min_view_buffer_index.h" /** * Computes the L2-norm of a complex single-precision floating-point vector. @@ -30,3 +32,17 @@ float API_SUFFIX(c_scnrm2)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX ) { return API_SUFFIX(cblas_scnrm2)( N, CX, strideX ); } + +/** +* Computes the L2-norm of a complex single-precision floating-point vector using alternative indexing semantics. +* +* @param N number of indexed elements +* @param CX input array +* @param strideX CX stride length +* @param offsetX starting index for CX +*/ +float API_SUFFIX(c_scnrm2_ndarray)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX, const CBLAS_INT offsetX ) { + stdlib_complex64_t *cx = (stdlib_complex64_t *)CX; + cx += stdlib_strided_min_view_buffer_index( N, strideX, offsetX ); + return API_SUFFIX(cblas_scnrm2)( N, (void *)cx, strideX ); +} diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_f.c b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_f.c index d7332f87cadd..3e3ec36b5e20 100644 --- a/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_f.c +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_f.c @@ -19,6 +19,8 @@ #include "stdlib/blas/base/scnrm2.h" #include "stdlib/blas/base/scnrm2_fortran.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/complex/float32/ctor.h" +#include "stdlib/strided/base/min_view_buffer_index.h" /** * Computes the L2-norm of a complex single-precision floating-point vector. @@ -33,3 +35,20 @@ float API_SUFFIX(c_scnrm2)( const CBLAS_INT N, const void *CX, const CBLAS_INT s scnrm2sub( &N, CX, &strideX, &nrm2 ); return nrm2; } + +/** +* Computes the L2-norm of a complex single-precision floating-point vector using alternative indexing semantics. +* +* @param N number of indexed elements +* @param CX input array +* @param strideX CX stride length +* @param offsetX starting index for CX +* @return L2-norm +*/ +float API_SUFFIX(c_scnrm2_ndarray)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX, const CBLAS_INT offsetX ) { + stdlib_complex64_t *cx = (stdlib_complex64_t *)CX; + float nrm2; + cx += stdlib_strided_min_view_buffer_index( N, strideX, offsetX ); + scnrm2sub( &N, (void *)cx, &strideX, &nrm2 ); + return nrm2; +} diff --git a/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_ndarray.c b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_ndarray.c new file mode 100644 index 000000000000..94c703be9330 --- /dev/null +++ b/lib/node_modules/@stdlib/blas/base/scnrm2/src/scnrm2_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/scnrm2.h" +#include "stdlib/blas/base/shared.h" +#include "stdlib/math/base/special/absf.h" +#include "stdlib/math/base/special/abs2f.h" +#include "stdlib/math/base/special/sqrtf.h" +#include "stdlib/constants/float32/max.h" +#include + +// Blue's scaling constants... +static const float tsml = 1.08420217E-19f; +static const float tbig = 4.50359963E+15f; +static const float ssml = 3.77789319E+22f; +static const float sbig = 1.32348898E-23f; + +/** +* Computes the L2-norm of a complex single-precision floating-point vector using alternative indexing semantics. +* +* @param N number of indexed elements +* @param CX input array +* @param strideX CX stride length +* @param offsetX starting index for CX +*/ +float API_SUFFIX(c_scnrm2_ndarray)( const CBLAS_INT N, const void *CX, const CBLAS_INT strideX, const CBLAS_INT offsetX ) { + const float *x = (float *)CX; + CBLAS_INT sx; + CBLAS_INT ix; + bool notbig; + CBLAS_INT i; + float sumsq; + float abig; + float amed; + float asml; + float ymax; + float ymin; + float scl; + float ax; + + if ( N <= 0 ) { + return 0.0f; + } + 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.0f; + abig = 0.0f; + amed = 0.0f; + asml = 0.0f; + for ( i = 0; i < N; i++ ) { + ax = stdlib_base_absf( x[ ix ] ); + if ( ax > tbig ) { + abig += stdlib_base_abs2f( ax * sbig ); + notbig = false; + } else if ( ax < tsml ) { + if ( notbig ) { + asml += stdlib_base_abs2f( ax * ssml ); + } + } else { + amed += stdlib_base_abs2f( ax ); + } + ax = stdlib_base_absf( x[ ix + 1 ] ); + if ( ax > tbig ) { + abig += stdlib_base_abs2f( ax * sbig ); + notbig = false; + } else if ( ax < tsml ) { + if ( notbig ) { + asml += stdlib_base_abs2f( ax * ssml ); + } + } else { + amed += stdlib_base_abs2f( ax ); + } + ix += sx; + } + // Combine `abig` and `amed` or `amed` and `asml` if more than one accumulator was used... + if ( abig > 0.0f ) { + // Combine `abig` and `amed` if `abig` > 0... + if ( amed > 0.0f || ( amed > STDLIB_CONSTANT_FLOAT32_MAX ) || ( amed != amed ) ) { + abig += ( amed * sbig ) * sbig; + } + scl = 1.0f / sbig; + sumsq = abig; + } else if ( asml > 0.0f ) { + // Combine `amed` and `asml` if `asml` > 0... + if ( amed > 0.0f || amed > STDLIB_CONSTANT_FLOAT32_MAX || ( amed != amed ) ) { + amed = stdlib_base_sqrtf( amed ); + asml = stdlib_base_sqrtf( asml ) / ssml; + if ( asml > amed ) { + ymin = amed; + ymax = asml; + } else { + ymin = asml; + ymax = amed; + } + scl = 1.0f; + sumsq = stdlib_base_abs2f( ymax ) * ( 1.0 + stdlib_base_abs2f( ymin / ymax ) ); + } else { + scl = 1.0f / ssml; + sumsq = asml; + } + } else { + // All values are mid-range... + scl = 1.0f; + sumsq = amed; + } + return stdlib_base_sqrtf( sumsq ) * scl; +}