diff --git a/lib/node_modules/@stdlib/blas/base/dscal/README.md b/lib/node_modules/@stdlib/blas/base/dscal/README.md index 81be24e7f422..0716abd284be 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/README.md +++ b/lib/node_modules/@stdlib/blas/base/dscal/README.md @@ -77,7 +77,7 @@ dscal( 3, 5.0, x1, 2 ); // x0 => [ 1.0, -10.0, 3.0, -20.0, 5.0, -30.0 ] ``` -If either `N` or `stride` is less than or equal to `0`, the function returns `x` unchanged. +If `N` is less than or equal to `0`, the function returns `x` unchanged. #### dscal.ndarray( N, alpha, x, stride, offset ) @@ -193,6 +193,28 @@ The function accepts the following arguments: void c_dscal( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride ); ``` +#### c_dscal_ndarray( N, alpha, \*X, stride, offset ) + +Multiplies each element of a double-precision floating-point vector by a constant using alternative indexing semantics. + +```c +double x[] = { 1.0, 2.0, 3.0, 4.0 }; + +c_dscal_ndarray( 4, 5.0, x, 1, 0 ); +``` + +The function accepts the following arguments: + +- **N**: `[in] CBLAS_INT` number of indexed elements. +- **alpha**: `[in] double` scalar constant. +- **X**: `[inout] double*` input array. +- **stride**: `[in] CBLAS_INT` index increment for `X`. +- **offset**: `[in] CBLAS_INT` starting index for `X`. + +```c +void c_dscal_ndarray( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset ); +``` + @@ -223,10 +245,18 @@ int main( void ) { const int N = 8; // Specify a stride: - const int strideX = 1; + const int stride = 1; + + // Scale the vector: + c_dscal( N, 5.0, x, stride ); + + // Print the result: + for ( int i = 0; i < 8; i++ ) { + printf( "x[ %i ] = %lf\n", i, x[ i ] ); + } // Scale the vector: - c_dscal( N, 5.0, x, strideX ); + c_dscal_ndarray( N, 5.0, x, -stride, N-1 ); // Print the result: for ( int i = 0; i < 8; i++ ) { diff --git a/lib/node_modules/@stdlib/blas/base/dscal/benchmark/c/benchmark.length.c b/lib/node_modules/@stdlib/blas/base/dscal/benchmark/c/benchmark.length.c index e4736730136c..53453be2991a 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/benchmark/c/benchmark.length.c +++ b/lib/node_modules/@stdlib/blas/base/dscal/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 elapsed; double x[ len ]; double t; @@ -118,6 +118,37 @@ 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 ]; + double t; + int i; + + for ( i = 0; i < len; i++ ) { + x[ i ] = ( rand_double()*200.0 ) - 100.0; + } + t = tic(); + for ( i = 0; i < iterations; i++ ) { + c_dscal_ndarray( len, 5.0, x, 1, 0 ); + if ( x[ 0 ] != x[ 0 ] ) { + printf( "should not return NaN\n" ); + break; + } + } + elapsed = tic() - t; + if ( x[ 0 ] != x[ 0 ] ) { + printf( "should not return NaN\n" ); + } + return elapsed; +} + /** * Main execution sequence. */ @@ -140,7 +171,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/dscal/docs/repl.txt b/lib/node_modules/@stdlib/blas/base/dscal/docs/repl.txt index b2ff25d608a7..611b788f461c 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/docs/repl.txt +++ b/lib/node_modules/@stdlib/blas/base/dscal/docs/repl.txt @@ -9,7 +9,7 @@ Indexing is relative to the first index. To introduce an offset, use typed array views. - If `N <= 0` or `stride <= 0`, the function returns `x` unchanged. + If `N <= 0` the function returns `x` unchanged. Parameters ---------- diff --git a/lib/node_modules/@stdlib/blas/base/dscal/docs/types/index.d.ts b/lib/node_modules/@stdlib/blas/base/dscal/docs/types/index.d.ts index 443f3a3bfc0c..487ce6f0eb34 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/blas/base/dscal/docs/types/index.d.ts @@ -28,7 +28,7 @@ interface Routine { * @param N - number of indexed elements * @param alpha - constant * @param x - input array - * @param stride - stride length + * @param stride - index increment * @returns input array * * @example @@ -47,7 +47,7 @@ interface Routine { * @param N - number of indexed elements * @param alpha - constant * @param x - input array - * @param stride - stride length + * @param stride - index increment * @param offset - starting index * @returns input array * @@ -68,7 +68,7 @@ interface Routine { * @param N - number of indexed elements * @param alpha - constant * @param x - input array -* @param stride - stride length +* @param stride - index increment * @returns input array * * @example diff --git a/lib/node_modules/@stdlib/blas/base/dscal/examples/c/example.c b/lib/node_modules/@stdlib/blas/base/dscal/examples/c/example.c index 432487bbf0cc..283ca4d9345a 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/examples/c/example.c +++ b/lib/node_modules/@stdlib/blas/base/dscal/examples/c/example.c @@ -36,4 +36,12 @@ int main( void ) { for ( int i = 0; i < 8; i++ ) { printf( "x[ %i ] = %lf\n", i, x[ i ] ); } + + // Scale the vector: + c_dscal_ndarray( N, 5.0, x, -strideX, N-1 ); + + // Print the result: + for ( int i = 0; i < 8; i++ ) { + printf( "x[ %i ] = %lf\n", i, x[ i ] ); + } } diff --git a/lib/node_modules/@stdlib/blas/base/dscal/include/stdlib/blas/base/dscal.h b/lib/node_modules/@stdlib/blas/base/dscal/include/stdlib/blas/base/dscal.h index e3150a8accf3..55e5b48dbf97 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/include/stdlib/blas/base/dscal.h +++ b/lib/node_modules/@stdlib/blas/base/dscal/include/stdlib/blas/base/dscal.h @@ -36,6 +36,11 @@ extern "C" { */ void API_SUFFIX(c_dscal)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride ); +/** +* Multiplies each element of a double-precision floating-point vector by a constant using alternative indexing semantics. +*/ +void API_SUFFIX(c_dscal_ndarray)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset ); + #ifdef __cplusplus } #endif diff --git a/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.js b/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.js index b51f598fcea9..213328697455 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.js +++ b/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.js @@ -18,9 +18,10 @@ 'use strict'; -// VARIABLES // +// MODULES // -var M = 5; +var stride2offset = require( '@stdlib/strided/base/stride2offset' ); +var ndarray = require( './ndarray.js' ); // MAIN // @@ -31,7 +32,7 @@ var M = 5; * @param {PositiveInteger} N - number of indexed elements * @param {number} alpha - scalar * @param {Float64Array} x - input array -* @param {PositiveInteger} stride - index increment +* @param {integer} stride - index increment * @returns {Float64Array} input array * * @example @@ -43,39 +44,8 @@ var M = 5; * // x => [ -10.0, 5.0, 15.0, -25.0, 20.0, 0.0, -5.0, -15.0 ] */ function dscal( N, alpha, x, stride ) { - var i; - var m; - - if ( N <= 0 || stride <= 0 || alpha === 1.0 ) { - return x; - } - // Use loop unrolling if the stride is equal to `1`... - if ( stride === 1 ) { - m = N % M; - - // If we have a remainder, run a clean-up loop... - if ( m > 0 ) { - for ( i = 0; i < m; i++ ) { - x[ i ] *= alpha; - } - } - if ( N < M ) { - return x; - } - for ( i = m; i < N; i += M ) { - x[ i ] *= alpha; - x[ i+1 ] *= alpha; - x[ i+2 ] *= alpha; - x[ i+3 ] *= alpha; - x[ i+4 ] *= alpha; - } - return x; - } - N *= stride; - for ( i = 0; i < N; i += stride ) { - x[ i ] *= alpha; - } - return x; + var ox = stride2offset( N, stride ); + return ndarray( N, alpha, x, stride, ox ); } diff --git a/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.native.js b/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.native.js index 742c1ad8b116..d17d329ad3ef 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.native.js +++ b/lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.native.js @@ -31,7 +31,7 @@ var addon = require( './../src/addon.node' ); * @param {PositiveInteger} N - number of indexed elements * @param {number} alpha - scalar * @param {Float64Array} x - input array -* @param {PositiveInteger} stride - index increment +* @param {integer} stride - index increment * @returns {Float64Array} input array * * @example diff --git a/lib/node_modules/@stdlib/blas/base/dscal/lib/ndarray.native.js b/lib/node_modules/@stdlib/blas/base/dscal/lib/ndarray.native.js index 149e4c9713e2..88a69f64c82b 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/lib/ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/base/dscal/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( './dscal.native.js' ); +var addon = require( './../src/addon.node' ); // MAIN // @@ -46,13 +44,7 @@ var addon = require( './dscal.native.js' ); * // x => [ 1.0, -2.0, 3.0, -20.0, 25.0, -30.0 ] */ function dscal( N, alpha, x, stride, offset ) { - var view; - offset = minViewBufferIndex( N, stride, offset ); - if ( stride < 0 ) { - stride *= -1; - } - view = offsetView( x, offset ); - addon( N, alpha, view, stride ); + addon.ndarray( N, alpha, x, stride, offset ); return x; } diff --git a/lib/node_modules/@stdlib/blas/base/dscal/manifest.json b/lib/node_modules/@stdlib/blas/base/dscal/manifest.json index c6c1578c53ee..7adcba295f54 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/manifest.json +++ b/lib/node_modules/@stdlib/blas/base/dscal/manifest.json @@ -44,10 +44,11 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", "@stdlib/napi/export", "@stdlib/napi/argv", - "@stdlib/napi/argv-double", "@stdlib/napi/argv-int64", + "@stdlib/napi/argv-double", "@stdlib/napi/argv-strided-float64array" ] }, @@ -57,7 +58,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -65,7 +67,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, { @@ -74,7 +77,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -82,7 +86,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, @@ -104,10 +109,11 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", "@stdlib/napi/export", "@stdlib/napi/argv", - "@stdlib/napi/argv-double", "@stdlib/napi/argv-int64", + "@stdlib/napi/argv-double", "@stdlib/napi/argv-strided-float64array" ] }, @@ -128,7 +134,8 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index" ] }, { @@ -148,7 +155,8 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index" ] }, @@ -168,10 +176,11 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", "@stdlib/napi/export", "@stdlib/napi/argv", - "@stdlib/napi/argv-double", "@stdlib/napi/argv-int64", + "@stdlib/napi/argv-double", "@stdlib/napi/argv-strided-float64array" ] }, @@ -181,7 +190,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -189,7 +199,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, { @@ -198,7 +209,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -206,7 +218,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, @@ -227,10 +240,11 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", "@stdlib/napi/export", "@stdlib/napi/argv", - "@stdlib/napi/argv-double", "@stdlib/napi/argv-int64", + "@stdlib/napi/argv-double", "@stdlib/napi/argv-strided-float64array" ] }, @@ -250,7 +264,8 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index" ] }, { @@ -269,7 +284,8 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index" ] }, @@ -291,10 +307,11 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index", "@stdlib/napi/export", "@stdlib/napi/argv", - "@stdlib/napi/argv-double", "@stdlib/napi/argv-int64", + "@stdlib/napi/argv-double", "@stdlib/napi/argv-strided-float64array" ] }, @@ -315,7 +332,8 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index" ] }, { @@ -335,7 +353,8 @@ ], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/min-view-buffer-index" ] }, @@ -345,7 +364,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -354,10 +374,11 @@ "libpath": [], "dependencies": [ "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset", "@stdlib/napi/export", "@stdlib/napi/argv", - "@stdlib/napi/argv-double", "@stdlib/napi/argv-int64", + "@stdlib/napi/argv-double", "@stdlib/napi/argv-strided-float64array" ] }, @@ -367,7 +388,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -375,7 +397,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, { @@ -384,7 +407,8 @@ "blas": "", "wasm": false, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -392,7 +416,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] }, @@ -402,7 +427,8 @@ "blas": "", "wasm": true, "src": [ - "./src/dscal.c" + "./src/dscal.c", + "./src/dscal_ndarray.c" ], "include": [ "./include" @@ -410,7 +436,8 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/blas/base/shared" + "@stdlib/blas/base/shared", + "@stdlib/strided/base/stride2offset" ] } ] diff --git a/lib/node_modules/@stdlib/blas/base/dscal/src/addon.c b/lib/node_modules/@stdlib/blas/base/dscal/src/addon.c index 13a42f4187af..e6f55f055fea 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/src/addon.c +++ b/lib/node_modules/@stdlib/blas/base/dscal/src/addon.c @@ -36,10 +36,28 @@ static napi_value addon( 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_DOUBLE( env, alpha, argv, 1 ); - STDLIB_NAPI_ARGV_INT64( env, strideX, argv, 3 ); - STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, strideX, argv, 2 ); - API_SUFFIX(c_dscal)( N, alpha, X, strideX ); + STDLIB_NAPI_ARGV_INT64( env, stride, argv, 3 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, stride, argv, 2 ); + API_SUFFIX(c_dscal)( N, alpha, X, stride ); 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, 5 ); + STDLIB_NAPI_ARGV_INT64( env, N, argv, 0 ); + STDLIB_NAPI_ARGV_DOUBLE( env, alpha, argv, 1 ); + STDLIB_NAPI_ARGV_INT64( env, stride, argv, 3 ); + STDLIB_NAPI_ARGV_INT64( env, offset, argv, 4 ); + STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, stride, argv, 2 ); + API_SUFFIX(c_dscal_ndarray)( N, alpha, X, stride, offset ); + return NULL; +} + +STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method ) diff --git a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal.c b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal.c index 712b4d62ab66..f98cdab0fef5 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal.c +++ b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal.c @@ -18,6 +18,7 @@ #include "stdlib/blas/base/dscal.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/strided/base/stride2offset.h" /** * Multiplies a double-precision floating-point vector `X` by a constant. @@ -28,36 +29,6 @@ * @param stride index increment */ void API_SUFFIX(c_dscal)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride ) { - CBLAS_INT m; - CBLAS_INT i; - - if ( N <= 0 || stride <= 0 || alpha == 1.0 ) { - return; - } - // Use loop unrolling if the stride is equal to `1`... - if ( stride == 1 ) { - m = N % 5; - - // If we have a remainder, run a clean-up loop... - if ( m > 0 ) { - for ( i = 0; i < m; i++ ) { - X[ i ] *= alpha; - } - } - if ( N < 5 ) { - return; - } - for ( i = m; i < N; i += 5 ) { - X[ i ] *= alpha; - X[ i+1 ] *= alpha; - X[ i+2 ] *= alpha; - X[ i+3 ] *= alpha; - X[ i+4 ] *= alpha; - } - return; - } - for ( i = 0; i < N*stride; i += stride ) { - X[ i ] *= alpha; - } - return; + CBLAS_INT ox = stdlib_strided_stride2offset( N, stride ); + API_SUFFIX(c_dscal_ndarray)( N, alpha, X, stride, ox ); } diff --git a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_cblas.c b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_cblas.c index 6613aad2dd7e..2de64f05b48b 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_cblas.c +++ b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_cblas.c @@ -19,6 +19,7 @@ #include "stdlib/blas/base/dscal.h" #include "stdlib/blas/base/dscal_cblas.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/strided/base/min_view_buffer_index.h" /** * Multiplies a double-precision floating-point vector `X` by a constant. @@ -29,5 +30,27 @@ * @param stride index increment */ void API_SUFFIX(c_dscal)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride ) { - API_SUFFIX(cblas_dscal)( N, alpha, X, stride ); + CBLAS_INT sx = stride; + if ( sx < 0 ) { + sx = -sx; + } + API_SUFFIX(cblas_dscal)( N, alpha, X, sx ); +} + +/** +* Multiplies a double-precision floating-point vector `X` by a constant using alternative indexing semantics. +* +* @param N number of indexed elements +* @param alpha scalar +* @param X input array +* @param stride index increment +* @param offset starting index +*/ +void API_SUFFIX(c_dscal_ndarray)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset ) { + CBLAS_INT sx = stride; + X += stdlib_strided_min_view_buffer_index( N, stride, offset ); // adjust array pointer + if ( sx < 0 ) { + sx = -sx; + } + API_SUFFIX(cblas_dscal)( N, alpha, X, sx ); } diff --git a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_f.c b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_f.c index 254e5083dbd8..57f359952d83 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_f.c +++ b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_f.c @@ -19,6 +19,7 @@ #include "stdlib/blas/base/dscal.h" #include "stdlib/blas/base/dscal_fortran.h" #include "stdlib/blas/base/shared.h" +#include "stdlib/strided/base/min_view_buffer_index.h" /** * Multiplies a double-precision floating-point vector `X` by a constant. @@ -29,5 +30,27 @@ * @param stride index increment */ void API_SUFFIX(c_dscal)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride ) { - dscal( &N, &alpha, X, &stride ); + CBLAS_INT sx = stride; + if ( sx < 0 ) { + sx = -sx; + } + dscal( &N, &alpha, X, &sx ); +} + +/** +* Multiplies a double-precision floating-point vector `X` by a constant using alternative indexing semantics. +* +* @param N number of indexed elements +* @param alpha scalar +* @param X input array +* @param stride index increment +* @param offset starting index +*/ +void API_SUFFIX(c_dscal_ndarray)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset ) { + CBLAS_INT sx = stride; + if ( sx < 0 ) { + sx = -sx; + } + X += stdlib_strided_min_view_buffer_index( N, stride, offset ); // adjust array pointer + dscal( &N, &alpha, X, &sx ); } diff --git a/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_ndarray.c b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_ndarray.c new file mode 100644 index 000000000000..5d63e2dec120 --- /dev/null +++ b/lib/node_modules/@stdlib/blas/base/dscal/src/dscal_ndarray.c @@ -0,0 +1,72 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2020 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/dscal.h" +#include "stdlib/blas/base/shared.h" + +static const CBLAS_INT M = 5; + +/** +* Multiplies a double-precision floating-point vector `X` by a constant using alternative indexing semantics. +* +* @param N number of indexed elements +* @param alpha scalar +* @param X input array +* @param stride index increment +* @param offset starting index +*/ +void API_SUFFIX(c_dscal_ndarray)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset ) { + CBLAS_INT ix; + CBLAS_INT i; + CBLAS_INT m; + + if ( N <= 0 || alpha == 1.0 ) { + return; + } + ix = offset; + + // Use loop unrolling if the stride is equal to `1`... + if ( stride == 1 ) { + m = N % M; + + // If we have a remainder, run a clean-up loop... + if ( m > 0 ) { + for ( i = 0; i < m; i++ ) { + X[ ix ] *= alpha; + ix += stride; + } + } + if ( N < M ) { + return; + } + for ( i = m; i < N; i += M ) { + X[ ix ] *= alpha; + X[ ix+1 ] *= alpha; + X[ ix+2 ] *= alpha; + X[ ix+3 ] *= alpha; + X[ ix+4 ] *= alpha; + ix += M; + } + return; + } + for ( i = 0; i < N; i++ ) { + X[ ix ] *= alpha; + ix += stride; + } + return; +} diff --git a/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.js b/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.js index e4c327a0cfc1..3e07fd0f4125 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.js +++ b/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.js @@ -139,19 +139,27 @@ tape( 'the function supports specifying a stride', function test( t ) { t.end(); }); -tape( 'if provided a `stride` less than or equal to `0`, the function returns `x` unchanged', function test( t ) { +tape( 'the function supports specifying a negative stride', function test( t ) { var expected; var x; - x = new Float64Array( [ 3.0, -4.0, 1.0 ] ); - expected = new Float64Array( [ 3.0, -4.0, 1.0 ] ); - - dscal( x.length, 5.0, x, 0 ); - t.deepEqual( x, expected, 'returns expected value' ); + x = new Float64Array([ + 2.0, // 2 + -3.0, + -5.0, // 1 + 7.0, + 6.0 // 0 + ]); + expected = new Float64Array([ + 10.0, // 2 + -3.0, + -25.0, // 1 + 7.0, + 30.0 // 0 + ]); - dscal( x.length, 5.0, x, -1 ); + dscal( 3, 5.0, x, -2 ); t.deepEqual( x, expected, 'returns expected value' ); - t.end(); }); diff --git a/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.native.js b/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.native.js index f72631941661..53fed2022f2d 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.native.js +++ b/lib/node_modules/@stdlib/blas/base/dscal/test/test.dscal.native.js @@ -148,19 +148,27 @@ tape( 'the function supports specifying a stride', opts, function test( t ) { t.end(); }); -tape( 'if provided a `stride` less than or equal to `0`, the function returns `x` unchanged', opts, function test( t ) { +tape( 'the function supports specifying a negative stride', opts, function test( t ) { var expected; var x; - x = new Float64Array( [ 3.0, -4.0, 1.0 ] ); - expected = new Float64Array( [ 3.0, -4.0, 1.0 ] ); - - dscal( x.length, 5.0, x, 0 ); - t.deepEqual( x, expected, 'returns expected value' ); + x = new Float64Array([ + 2.0, // 2 + -3.0, + -5.0, // 1 + 7.0, + 6.0 // 0 + ]); + expected = new Float64Array([ + 10.0, // 2 + -3.0, + -25.0, // 1 + 7.0, + 30.0 // 0 + ]); - dscal( x.length, 5.0, x, -1 ); + dscal( 3, 5.0, x, -2 ); t.deepEqual( x, expected, 'returns expected value' ); - t.end(); }); diff --git a/lib/node_modules/@stdlib/blas/base/dscal/test/test.ndarray.native.js b/lib/node_modules/@stdlib/blas/base/dscal/test/test.ndarray.native.js index e6fadd05aded..24963cf346a9 100644 --- a/lib/node_modules/@stdlib/blas/base/dscal/test/test.ndarray.native.js +++ b/lib/node_modules/@stdlib/blas/base/dscal/test/test.ndarray.native.js @@ -167,7 +167,7 @@ tape( 'the function supports specifying a negative stride', opts, function test( 30.0 // 0 ]); - dscal( 3, 5.0, x, -2, x.length-1 ); + dscal( 3, 5.0, x, -2, 4 ); t.deepEqual( x, expected, 'returns expected value' ); t.end(); });