Skip to content

Commit 326e25e

Browse files
committed
feat: update Js implementation and add C ndarray implementation for snrm2
1 parent 69234e5 commit 326e25e

File tree

17 files changed

+765
-182
lines changed

17 files changed

+765
-182
lines changed

lib/node_modules/@stdlib/blas/base/snrm2/README.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,129 @@ console.log( out );
160160

161161
<!-- /.examples -->
162162

163+
<!-- C interface documentation. -->
164+
165+
* * *
166+
167+
<section class="c">
168+
169+
## C APIs
170+
171+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
172+
173+
<section class="intro">
174+
175+
</section>
176+
177+
<!-- /.intro -->
178+
179+
<!-- C usage documentation. -->
180+
181+
<section class="usage">
182+
183+
### Usage
184+
185+
```c
186+
#include "stdlib/blas/base/snrm2.h"
187+
```
188+
189+
#### c_snrm2( N, \*X, stride )
190+
191+
Computes the L2-norm of a complex single-precision floating-point vector.
192+
193+
```c
194+
const float x[] = { 1.0f, -2.0f, 3.0f, -4.0f, 5.0f, -6.0f, 7.0f, -8.0f };
195+
196+
float norm = c_snrm2( 8, x, 1 );
197+
// returns 14.3
198+
```
199+
200+
The function accepts the following arguments:
201+
202+
- **N**: `[in] CBLAS_INT` number of indexed elements.
203+
- **X**: `[in] float*` input array.
204+
- **stride**: `[in] CBLAS_INT` index increment for `X`.
205+
206+
```c
207+
float c_snrm2( const CBLAS_INT N, const float *X, const CBLAS_INT stride );
208+
```
209+
210+
#### c_snrm2_ndarray( N, \*X, stride, offset )
211+
212+
Computes the L2-norm of a complex single-precision floating-point vector using alternative indexing semantics.
213+
214+
```c
215+
const float x[] = { 1.0f, -2.0f, 3.0f, -4.0f, 5.0f, -6.0f, 7.0f, -8.0f };
216+
217+
float norm = c_snrm2_ndarray( 8, x, 1, 0 );
218+
// returns 14.3
219+
```
220+
221+
The function accepts the following arguments:
222+
223+
- **N**: `[in] CBLAS_INT` number of indexed elements.
224+
- **X**: `[in] float*` input array.
225+
- **stride**: `[in] CBLAS_INT` index increment for `X`.
226+
- **offset**: `[in] CBLAS_INT` starting index for `X`.
227+
228+
```c
229+
float c_snrm2_ndarray( const CBLAS_INT N, const float *X, const CBLAS_INT stride, const CBLAS_INT offset );
230+
```
231+
232+
</section>
233+
234+
<!-- /.usage -->
235+
236+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
237+
238+
<section class="notes">
239+
240+
</section>
241+
242+
<!-- /.notes -->
243+
244+
<!-- C API usage examples. -->
245+
246+
<section class="examples">
247+
248+
### Examples
249+
250+
```c
251+
#include "stdlib/blas/base/snrm2.h"
252+
#include <stdio.h>
253+
254+
int main( void ) {
255+
// Create a strided array:
256+
const float x[] = { 1.0f, -2.0f, 3.0f, -4.0f, 5.0f, -6.0f, 7.0f, -8.0f };
257+
258+
// Specify the number of indexed elements:
259+
const int N = 8;
260+
261+
// Specify a stride:
262+
const int strideX = 1;
263+
264+
// Compute the L2-norm:
265+
float l2 = c_snrm2( N, x, strideX );
266+
267+
// Print the result:
268+
printf( "L2-norm: %f\n", l2 );
269+
270+
// Compute the L2-norm:
271+
l2 = c_snrm2_ndarray( N, x, strideX, 0 );
272+
273+
// Print the result:
274+
printf( "L2-norm: %f\n", l2 );
275+
}
276+
```
277+
278+
</section>
279+
280+
<!-- /.examples -->
281+
282+
</section>
283+
284+
<!-- /.c -->
285+
163286
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
164287
165288
<section class="related">

lib/node_modules/@stdlib/blas/base/snrm2/docs/repl.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Indexing is relative to the first index. To introduce an offset, use a typed
99
array view.
1010

11-
If `N <= 0` or `stride <= 0`, the function returns `0`.
11+
If `N <= 0` the function returns `0`.
1212

1313
Parameters
1414
----------

lib/node_modules/@stdlib/blas/base/snrm2/lib/ndarray.js

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,20 @@
2020

2121
// MODULES //
2222

23-
var sqrtf = require( '@stdlib/math/base/special/sqrtf' );
23+
var FLOAT32_MAX = require( '@stdlib/constants/float32/max' );
24+
var f32 = require( '@stdlib/number/float64/base/to-float32' );
2425
var absf = require( '@stdlib/math/base/special/absf' );
25-
var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
26+
var abs2f = require( '@stdlib/math/base/special/abs2f' );
27+
var sqrtf = require( '@stdlib/math/base/special/sqrtf' );
28+
29+
30+
// VARIABLES //
31+
32+
// Blue's scaling constants:
33+
var tsml = 1.08420217E-19;
34+
var tbig = 4.50359963E+15;
35+
var ssml = 3.77789319E+22;
36+
var sbig = 1.32348898E-23;
2637

2738

2839
// MAIN //
@@ -45,37 +56,79 @@ var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
4556
* // returns 5.0
4657
*/
4758
function snrm2( N, x, stride, offset ) {
48-
var scale;
49-
var ssq;
59+
var notbig;
60+
var sumsq;
61+
var abig;
62+
var amed;
63+
var asml;
64+
var ymax;
65+
var ymin;
66+
var scl;
5067
var ax;
5168
var ix;
52-
var v;
5369
var i;
5470

5571
if ( N <= 0 ) {
5672
return 0.0;
5773
}
58-
if ( N === 1 ) {
59-
return absf( x[ offset ] );
60-
}
6174
ix = offset;
62-
scale = 0.0;
63-
ssq = 1.0;
75+
76+
// Initialize loop values for accumulation:
77+
notbig = true;
78+
79+
sumsq = 0.0;
80+
abig = 0.0;
81+
amed = 0.0;
82+
asml = 0.0;
83+
scl = 1.0;
84+
85+
// 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`)...
6486
for ( i = 0; i < N; i++ ) {
65-
if ( x[ ix ] !== 0.0 ) {
66-
ax = absf( x[ ix ] );
67-
if ( scale < ax ) {
68-
v = float64ToFloat32( scale/ax );
69-
ssq = float64ToFloat32( 1.0 + float64ToFloat32( ssq * float64ToFloat32( v*v ) ) ); // eslint-disable-line max-len
70-
scale = ax;
71-
} else {
72-
v = float64ToFloat32( ax/scale );
73-
ssq = float64ToFloat32( ssq + float64ToFloat32( v*v ) );
87+
ax = absf( x[ ix ] );
88+
if ( ax > tbig ) {
89+
abig = f32( abig + abs2f( ax * sbig ) );
90+
notbig = false;
91+
} else if ( ax < tsml ) {
92+
if ( notbig ) {
93+
asml = f32( asml + abs2f( ax * ssml ) );
7494
}
95+
} else {
96+
amed = f32( amed + f32( ax * ax ) );
7597
}
7698
ix += stride;
7799
}
78-
return float64ToFloat32( scale * sqrtf( ssq ) );
100+
// Combine `abig` and `amed` or `amed` and `asml` if more than one accumulator was used...
101+
if ( abig > 0.0 ) {
102+
// Combine `abig` and `amed` if `abig` > 0...
103+
if ( amed > 0.0 || ( amed > FLOAT32_MAX ) || ( amed !== amed ) ) {
104+
abig = f32( abig + f32( f32( amed * sbig ) * sbig ) );
105+
}
106+
scl = f32( 1.0 / sbig );
107+
sumsq = abig;
108+
} else if ( asml > 0.0 ) {
109+
// Combine `amed` and `asml` if `asml` > 0...
110+
if ( amed > 0.0 || amed > FLOAT32_MAX || ( amed !== amed ) ) {
111+
amed = sqrtf( amed );
112+
asml = f32( sqrtf( asml ) / ssml );
113+
if ( asml > amed ) {
114+
ymin = amed;
115+
ymax = asml;
116+
} else {
117+
ymin = asml;
118+
ymax = amed;
119+
}
120+
scl = 1.0;
121+
sumsq = f32( f32( ymax * ymax ) * f32( 1.0 + abs2f( ymin / ymax ) ) ); // eslint-disable-line max-len
122+
} else {
123+
scl = f32( 1.0 / ssml );
124+
sumsq = asml;
125+
}
126+
} else {
127+
// All values are mid-range...
128+
scl = 1.0;
129+
sumsq = amed;
130+
}
131+
return f32( sqrtf( sumsq ) * scl );
79132
}
80133

81134

lib/node_modules/@stdlib/blas/base/snrm2/lib/ndarray.native.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020

2121
// MODULES //
2222

23-
var minViewBufferIndex = require( '@stdlib/strided/base/min-view-buffer-index' );
24-
var offsetView = require( '@stdlib/strided/base/offset-view' );
25-
var addon = require( './snrm2.native.js' );
23+
var addon = require( './../src/addon.node' );
2624

2725

2826
// MAIN //
@@ -45,13 +43,7 @@ var addon = require( './snrm2.native.js' );
4543
* // returns 5.0
4644
*/
4745
function snrm2( N, x, stride, offset ) {
48-
var view;
49-
offset = minViewBufferIndex( N, stride, offset );
50-
if ( stride < 0 ) {
51-
stride *= -1;
52-
}
53-
view = offsetView( x, offset );
54-
return addon( N, view, stride );
46+
return addon.ndarray( N, x, stride, offset );
5547
}
5648

5749

lib/node_modules/@stdlib/blas/base/snrm2/lib/snrm2.js

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020

2121
// MODULES //
2222

23-
var sqrtf = require( '@stdlib/math/base/special/sqrtf' );
24-
var absf = require( '@stdlib/math/base/special/absf' );
25-
var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
23+
var stride2offset = require( '@stdlib/strided/base/stride2offset' );
24+
var ndarray = require( './ndarray.js' );
2625

2726

2827
// MAIN //
@@ -32,7 +31,7 @@ var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
3231
*
3332
* @param {PositiveInteger} N - number of indexed elements
3433
* @param {Float32Array} x - input array
35-
* @param {PositiveInteger} stride - stride length
34+
* @param {integer} stride - stride length
3635
* @returns {number} L2-norm
3736
*
3837
* @example
@@ -44,35 +43,8 @@ var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
4443
* // returns 3.0
4544
*/
4645
function snrm2( N, x, stride ) {
47-
var scale;
48-
var ssq;
49-
var ax;
50-
var v;
51-
var i;
52-
53-
if ( N <= 0 || stride <= 0 ) {
54-
return 0.0;
55-
}
56-
if ( N === 1 ) {
57-
return absf( x[ 0 ] );
58-
}
59-
scale = 0.0;
60-
ssq = 1.0;
61-
N *= stride;
62-
for ( i = 0; i < N; i += stride ) {
63-
if ( x[ i ] !== 0.0 ) {
64-
ax = absf( x[ i ] );
65-
if ( scale < ax ) {
66-
v = float64ToFloat32( scale/ax );
67-
ssq = float64ToFloat32( 1.0 + float64ToFloat32( ssq * float64ToFloat32( v*v ) ) ); // eslint-disable-line max-len
68-
scale = ax;
69-
} else {
70-
v = float64ToFloat32( ax/scale );
71-
ssq = float64ToFloat32( ssq + float64ToFloat32( v*v ) );
72-
}
73-
}
74-
}
75-
return float64ToFloat32( scale * sqrtf( ssq ) );
46+
var ox = stride2offset( N, stride );
47+
return ndarray( N, x, stride, ox );
7648
}
7749

7850

lib/node_modules/@stdlib/blas/base/snrm2/lib/snrm2.native.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var addon = require( './../src/addon.node' );
3030
*
3131
* @param {PositiveInteger} N - number of indexed elements
3232
* @param {Float32Array} x - input array
33-
* @param {PositiveInteger} stride - stride length
33+
* @param {integer} stride - stride length
3434
* @returns {number} L2-norm
3535
*
3636
* @example

0 commit comments

Comments
 (0)