Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion lib/node_modules/@stdlib/blas/base/dnrm2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ var z = dnrm2( 4, x1, 2 );
// returns 5.0
```

If either `N` or `stride` is less than or equal to `0`, the function returns `0`.
If `N` is less than or equal to `0`, the function returns `0`.

#### dnrm2.ndarray( N, x, stride, offset )

Expand Down Expand Up @@ -207,6 +207,28 @@ The function accepts the following arguments:
double c_dnrm2( const CBLAS_INT N, const double *X, const CBLAS_INT stride );
```

#### c_dnrm2_ndarray( N, \*X, stride, offset )

Computes the L2-norm of a double-precision floating-point vector using alternative indexing semantics.

```c
const double x[] = { 1.0, -2.0, 2.0 };

double v = c_dnrm2( 3, x, -1, 2 );
// returns 3.0
```
The function accepts the following arguments:
- **N**: `[in] CBLAS_INT` number of indexed elements.
- **X**: `[in] double*` input array.
- **stride**: `[in] CBLAS_INT` index increment for `X`.
- **offset**: `[in] CBLAS_INT` starting index for `X`.
```c
double c_dnrm2_ndarray( const CBLAS_INT N, const double *X, const CBLAS_INT stride, const CBLAS_INT offset );
```

</section>

<!-- /.usage -->
Expand Down Expand Up @@ -244,6 +266,12 @@ int main( void ) {

// Print the result:
printf( "L2-norm: %lf\n", l2 );

// Compute the L2-norm:
l2 = c_dnrm2_ndarray( N, x, -strideX, N-1 );

// Print the result:
printf( "L2-norm: %lf\n", l2 );
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 z;
Expand All @@ -120,6 +120,39 @@ 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 z;
double t;
int i;

for ( i = 0; i < len; i++ ) {
x[ i ] = ( rand_double() * 20000.0 ) - 10000.0;
}
z = 0.0;
t = tic();
for ( i = 0; i < iterations; i++ ) {
z = c_dnrm2_ndarray( len, x, 1, 0 );
if ( z != z ) {
printf( "should not return NaN\n" );
break;
}
}
elapsed = tic() - t;
if ( z != z ) {
printf( "should not return NaN\n" );
}
return elapsed;
}

/**
* Main execution sequence.
*/
Expand All @@ -142,7 +175,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 );
}
Expand Down
2 changes: 1 addition & 1 deletion lib/node_modules/@stdlib/blas/base/dnrm2/docs/repl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Indexing is relative to the first index. To introduce an offset, use a typed
array view.

If `N <= 0` or `stride <= 0`, the function returns `0`.
If `N <= 0`, the function returns `0`.

Parameters
----------
Expand Down
6 changes: 6 additions & 0 deletions lib/node_modules/@stdlib/blas/base/dnrm2/examples/c/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ int main( void ) {

// Print the result:
printf( "L2-norm: %lf\n", l2 );

// Compute the L2-norm:
l2 = c_dnrm2_ndarray( N, x, -strideX, N-1 );

// Print the result:
printf( "L2-norm: %lf\n", l2 );
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ extern "C" {
*/
double API_SUFFIX(c_dnrm2)( const CBLAS_INT N, const double *X, const CBLAS_INT stride );

/**
* Computes the L2-norm of a double-precision floating-point vector using alternative indexing semantics.
*/
double API_SUFFIX(c_dnrm2_ndarray)( const CBLAS_INT N, const double *X, const CBLAS_INT stride, const CBLAS_INT offset );

#ifdef __cplusplus
}
#endif
Expand Down
35 changes: 5 additions & 30 deletions lib/node_modules/@stdlib/blas/base/dnrm2/lib/dnrm2.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@

// MODULES //

var sqrt = require( '@stdlib/math/base/special/sqrt' );
var abs = require( '@stdlib/math/base/special/abs' );
var pow = require( '@stdlib/math/base/special/pow' );
var stride2offset = require( '@stdlib/strided/base/stride2offset' );
var ndarray = require( './ndarray.js' );


// MAIN //
Expand All @@ -32,7 +31,7 @@ var pow = require( '@stdlib/math/base/special/pow' );
*
* @param {PositiveInteger} N - number of indexed elements
* @param {Float64Array} x - input array
* @param {PositiveInteger} stride - stride length
* @param {integer} stride - stride length
* @returns {number} L2-norm
*
* @example
Expand All @@ -44,32 +43,8 @@ var pow = require( '@stdlib/math/base/special/pow' );
* // returns 3.0
*/
function dnrm2( N, x, stride ) {
var scale;
var ssq;
var ax;
var i;

if ( N <= 0 || stride <= 0 ) {
return 0.0;
}
if ( N === 1 ) {
return abs( x[ 0 ] );
}
scale = 0.0;
ssq = 1.0;
N *= stride;
for ( i = 0; i < N; i += stride ) {
if ( x[ i ] !== 0.0 ) {
ax = abs( x[ i ] );
if ( scale < ax ) {
ssq = 1.0 + ( ssq * pow( scale/ax, 2 ) );
scale = ax;
} else {
ssq += pow( ax/scale, 2 );
}
}
}
return scale * sqrt( ssq );
var ox = stride2offset( N, stride );
return ndarray( N, x, stride, ox );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var addon = require( './../src/addon.node' );
*
* @param {PositiveInteger} N - number of indexed elements
* @param {Float64Array} x - input array
* @param {PositiveInteger} stride - stride length
* @param {integer} stride - stride length
* @returns {number} L2-norm
*
* @example
Expand Down
93 changes: 74 additions & 19 deletions lib/node_modules/@stdlib/blas/base/dnrm2/lib/ndarray.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
* Copyright (c) 2023 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.
Expand All @@ -20,9 +20,19 @@

// MODULES //

var sqrt = require( '@stdlib/math/base/special/sqrt' );
var FLOAT64_MAX = require( '@stdlib/constants/float64/max' );
var abs = require( '@stdlib/math/base/special/abs' );
var pow = require( '@stdlib/math/base/special/pow' );
var abs2 = require( '@stdlib/math/base/special/abs2' );
var sqrt = require( '@stdlib/math/base/special/sqrt' );


// VARIABLES //

// Blue's scaling constants:
var tsml = 1.4916681462400413E-154;
var tbig = 1.9979190722022350E+146;
var ssml = 4.4989137945431964E+161;
var sbig = 1.1113793747425387E-162;


// MAIN //
Expand All @@ -41,38 +51,83 @@ var pow = require( '@stdlib/math/base/special/pow' );
*
* var x = new Float64Array( [ 2.0, 1.0, 2.0, -2.0, -2.0, 2.0, 3.0, 4.0 ] );
*
* var out = dnrm2( 4, x, 2, 1 );
* var z = dnrm2( 4, x, 2, 1 );
* // returns 5.0
*/
function dnrm2( N, x, stride, offset ) {
var scale;
var ssq;
var notbig;
var sumsq;
var abig;
var amed;
var asml;
var ymax;
var ymin;
var scl;
var ax;
var ix;
var i;

if ( N <= 0 ) {
return 0.0;
}
if ( N === 1 ) {
return abs( x[ offset ] );
}
ix = offset;
scale = 0.0;
ssq = 1.0;

// Initialize loop values for accumulation:
notbig = true;

sumsq = 0.0;
abig = 0.0;
amed = 0.0;
asml = 0.0;
scl = 1.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`)...
for ( i = 0; i < N; i++ ) {
if ( x[ ix ] !== 0.0 ) {
ax = abs( x[ ix ] );
if ( scale < ax ) {
ssq = 1.0 + ( ssq * pow( scale/ax, 2 ) );
scale = ax;
} else {
ssq += pow( ax/scale, 2 );
ax = abs( x[ ix ] );
if ( ax > tbig ) {
abig += abs2( ax * sbig );
notbig = false;
} else if ( ax < tsml ) {
if ( notbig ) {
asml += abs2( ax * ssml );
}
} else {
amed += ( ax * ax );
}
ix += stride;
}
return scale * sqrt( ssq );
// 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 > 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 > FLOAT64_MAX || ( amed !== amed ) ) {
amed = sqrt( amed );
asml = sqrt( asml ) / ssml;
if ( asml > amed ) {
ymin = amed;
ymax = asml;
} else {
ymin = asml;
ymax = amed;
}
scl = 1.0;
sumsq = ( ymax * ymax ) * ( 1.0 + abs2( ymin / ymax ) );
} else {
scl = 1.0 / ssml;
sumsq = asml;
}
} else {
// All values are mid-range...
scl = 1.0;
sumsq = amed;
}
return sqrt( sumsq ) * scl;
}


Expand Down
12 changes: 2 additions & 10 deletions lib/node_modules/@stdlib/blas/base/dnrm2/lib/ndarray.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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( './dnrm2.native.js' );
var addon = require( './../src/addon.node' );


// MAIN //
Expand All @@ -45,13 +43,7 @@ var addon = require( './dnrm2.native.js' );
* // returns 5.0
*/
function dnrm2( N, x, stride, offset ) {
var view;
offset = minViewBufferIndex( N, stride, offset );
if ( stride < 0 ) {
stride *= -1;
}
view = offsetView( x, offset );
return addon( N, view, stride );
return addon.ndarray( N, x, stride, offset );
}


Expand Down
Loading
Loading