Skip to content

Commit e457e47

Browse files
ShabiShett07kgrytestdlib-bot
authored
feat: add C implementation for blas/base/zaxpy
PR-URL: #7594 Ref: #2039 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]> Co-authored-by: stdlib-bot <[email protected]>
1 parent 9fc1333 commit e457e47

34 files changed

+3892
-67
lines changed

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

Lines changed: 165 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ The function has the following parameters:
5151
- **N**: number of indexed elements.
5252
- **alpha**: scalar [`Complex128`][@stdlib/complex/float64/ctor] constant.
5353
- **x**: first input [`Complex128Array`][@stdlib/array/complex128].
54-
- **strideX**: index increment for `x`.
54+
- **strideX**: stride length for `x`.
5555
- **y**: second input [`Complex128Array`][@stdlib/array/complex128].
56-
- **strideY**: index increment for `y`.
56+
- **strideY**: stride length for `y`.
5757

58-
The `N` and stride parameters determine how values from `x` are scaled by `alpha` and added to `y`. For example, to scale every other value in `x` by `alpha` and add the result to every other value of `y`,
58+
The `N` and stride parameters determine how elements from `x` are scaled by `alpha` and added to `y`. For example, to scale every other element in `x` by `alpha` and add the result to every other element of `y`,
5959

6060
```javascript
6161
var Complex128Array = require( '@stdlib/array/complex128' );
@@ -88,7 +88,7 @@ var alpha = new Complex128( 2.0, 2.0 );
8888
var x1 = new Complex128Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
8989
var y1 = new Complex128Array( y0.buffer, y0.BYTES_PER_ELEMENT*2 ); // start at 3rd element
9090

91-
// Scales values of `x0` by `alpha` starting from second index and add the result to `y0` starting from third index...
91+
// Perform operation:
9292
zaxpy( 2, alpha, x1, 1, y1, 1 );
9393
// y0 => <Complex128Array>[ 1.0, 1.0, 1.0, 1.0, -1.0, 15.0, -1.0, 23.0 ]
9494
```
@@ -114,7 +114,7 @@ The function has the following additional parameters:
114114
- **offsetX**: starting index for `x`.
115115
- **offsetY**: starting index for `y`.
116116

117-
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on starting indices. For example, to scale values in the first input strided array starting from the second element and add the result to the second input array starting from the second element,
117+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on starting indices. For example, to scale elements in the first input strided array starting from the second element and add the result to the second input array starting from the second element,
118118

119119
```javascript
120120
var Complex128Array = require( '@stdlib/array/complex128' );
@@ -136,7 +136,7 @@ zaxpy.ndarray( 3, alpha, x, 1, 1, y, 1, 1 );
136136

137137
## Notes
138138

139-
- If `N <= 0`, both functions return `y` unchanged.
139+
- If `N <= 0` or `alpha == 0`, both functions return `y` unchanged.
140140
- `zaxpy()` corresponds to the [BLAS][blas] level 1 function [`zaxpy`][zaxpy].
141141

142142
</section>
@@ -164,21 +164,175 @@ function rand() {
164164

165165
var x = filledarrayBy( 10, 'complex128', rand );
166166
var y = filledarrayBy( 10, 'complex128', rand );
167-
var yc = zcopy( y.length, y, 1, zeros( y.length, 'complex128' ), 1 );
167+
var yc1 = zcopy( y.length, y, 1, zeros( y.length, 'complex128' ), 1 );
168168

169169
var alpha = new Complex128( 2.0, 2.0 );
170170

171-
// Scale values from `x` by `alpha` and add the result to `y`:
172-
zaxpy( x.length, alpha, x, 1, y, 1 );
171+
// Perform operation:
172+
zaxpy( x.length, alpha, x, 1, yc1, 1 );
173173

174174
// Print the results:
175-
logEach( '(%s)*(%s) + (%s) = %s', alpha, x, yc, y );
175+
logEach( '(%s)*(%s) + (%s) = %s', alpha, x, y, yc1 );
176+
177+
var yc2 = zcopy( y.length, y, 1, zeros( y.length, 'complex128' ), 1 );
178+
179+
// Perform operation using alternative indexing semantics:
180+
zaxpy.ndarray( x.length, alpha, x, 1, 0, yc2, 1, 0 );
181+
182+
// Print the results:
183+
logEach( '(%s)*(%s) + (%s) = %s', alpha, x, y, yc2 );
184+
```
185+
186+
</section>
187+
188+
<!-- /.examples -->
189+
190+
<!-- C interface documentation. -->
191+
192+
* * *
193+
194+
<section class="c">
195+
196+
## C APIs
197+
198+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
199+
200+
<section class="intro">
201+
202+
</section>
203+
204+
<!-- /.intro -->
205+
206+
<!-- C usage documentation. -->
207+
208+
<section class="usage">
209+
210+
### Usage
211+
212+
```c
213+
#include "stdlib/blas/base/zaxpy.h"
214+
```
215+
216+
#### c_zaxpy( N, alpha, \*X, strideX, \*Y, strideY )
217+
218+
Scales values from `X` by `alpha` and adds the result to `Y`.
219+
220+
```c
221+
#include "stdlib/complex/float64/ctor.h"
222+
223+
const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };
224+
double y[] = { -1.0, -2.0, -3.0, -4.0, -5.0, -6.0, -7.0, -8.0 };
225+
const stdlib_complex128_t alpha = stdlib_complex128( 2.0, 2.0 );
226+
227+
c_zaxpy( 4, alpha, (void *)x, 1, (void *)y, 1 );
228+
```
229+
230+
The function accepts the following arguments:
231+
232+
- **N**: `[in] CBLAS_INT` number of indexed elements.
233+
- **alpha**: `[in] stdlib_complex128_t` scalar constant.
234+
- **X**: `[in] void*` input array.
235+
- **strideX**: `[in] CBLAS_INT` stride length for `X`.
236+
- **Y**: `[inout] void*` output array.
237+
- **strideY**: `[in] CBLAS_INT` stride length for `Y`.
238+
239+
```c
240+
void c_zaxpy( const CBLAS_INT N, const stdlib_complex128_t alpha, const void *X, const CBLAS_INT strideX, void *Y, const CBLAS_INT strideY );
241+
```
242+
243+
#### c_zaxpy_ndarray( N, alpha, \*X, strideX, offsetX, \*Y, strideY, offsetY )
244+
245+
Scales values from `X` by `alpha` and adds the result to `Y` using alternative indexing semantics.
246+
247+
```c
248+
#include "stdlib/complex/float64/ctor.h"
249+
250+
const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };
251+
double y[] = { -1.0, -2.0, -3.0, -4.0, -5.0, -6.0, -7.0, -8.0 };
252+
const stdlib_complex128_t alpha = stdlib_complex128( 2.0, 2.0 );
253+
254+
c_zaxpy_ndarray( 4, alpha, (void *)x, 1, 0, (void *)y, 1, 0 );
255+
```
256+
257+
The function accepts the following arguments:
258+
259+
- **N**: `[in] CBLAS_INT` number of indexed elements.
260+
- **alpha**: `[in] stdlib_complex128_t` scalar constant.
261+
- **X**: `[in] void*` input array.
262+
- **strideX**: `[in] CBLAS_INT` stride length for `X`.
263+
- **offsetX**: `[in] CBLAS_INT` starting index for `X`.
264+
- **Y**: `[inout] void*` output array.
265+
- **strideY**: `[in] CBLAS_INT` stride length for `Y`.
266+
- **offsetY**: `[in] CBLAS_INT` starting index for `Y`.
267+
268+
```c
269+
void c_zaxpy_ndarray( const CBLAS_INT N, const stdlib_complex128_t alpha, const void *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, void *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY );
270+
```
271+
272+
</section>
273+
274+
<!-- /.usage -->
275+
276+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
277+
278+
<section class="notes">
279+
280+
</section>
281+
282+
<!-- /.notes -->
283+
284+
<!-- C API usage examples. -->
285+
286+
<section class="examples">
287+
288+
### Examples
289+
290+
```c
291+
#include "stdlib/blas/base/zaxpy.h"
292+
#include "stdlib/complex/float64/ctor.h"
293+
#include <stdio.h>
294+
295+
int main( void ) {
296+
// Create strided arrays:
297+
const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };
298+
double y[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
299+
300+
// Create a complex scalar:
301+
const stdlib_complex128_t alpha = stdlib_complex128( 2.0, 2.0 );
302+
303+
// Specify the number of elements:
304+
const int N = 4;
305+
306+
// Specify stride lengths:
307+
const int strideX = 1;
308+
const int strideY = 1;
309+
310+
// Perform operation:
311+
c_zaxpy( N, alpha, (void *)x, strideX, (void *)y, strideY );
312+
313+
// Print the result:
314+
for ( int i = 0; i < N; i++ ) {
315+
printf( "zaxpy[ %i ] = %lf + %lfj\n", i, y[ i*2 ], y[ (i*2)+1 ] );
316+
}
317+
318+
// Perform operation using alternative indexing semantics:
319+
c_zaxpy_ndarray( N, alpha, (void *)x, strideX, 0, (void *)y, strideY, 0 );
320+
321+
// Print the result:
322+
for ( int i = 0; i < N; i++ ) {
323+
printf( "zaxpy[ %i ] = %lf + %lfj\n", i, y[ i*2 ], y[ (i*2)+1 ] );
324+
}
325+
}
176326
```
177327
178328
</section>
179329
180330
<!-- /.examples -->
181331
332+
</section>
333+
334+
<!-- /.c -->
335+
182336
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
183337
184338
<section class="related">
@@ -193,7 +347,7 @@ logEach( '(%s)*(%s) + (%s) = %s', alpha, x, yc, y );
193347
194348
[blas]: http://www.netlib.org/blas
195349
196-
[zaxpy]: https://www.netlib.org/lapack/explore-html/d5/d4b/group__axpy_ga0b7bac1f4d42514074a48f14f5f9caa0.html#ga0b7bac1f4d42514074a48f14f5f9caa0
350+
[zaxpy]: https://www.netlib.org/lapack/explore-html/d5/d4b/group__axpy_gaf603daa00d5c723d0e409d9b2d011bf4.html
197351
198352
[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
199353

lib/node_modules/@stdlib/blas/base/zaxpy/benchmark/benchmark.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@ var options = {
4444
* Creates a benchmark function.
4545
*
4646
* @private
47-
* @param {PositiveInteger} len - array length
47+
* @param {PositiveInteger} N - array length
4848
* @returns {Function} benchmark function
4949
*/
50-
function createBenchmark( len ) {
50+
function createBenchmark( N ) {
5151
var viewY;
5252
var alpha;
5353
var x;
5454
var y;
5555

56-
x = new Complex128Array( uniform( len*2, -100.0, 100.0, options ) );
57-
y = new Complex128Array( uniform( len*2, -100.0, 100.0, options ) );
56+
x = new Complex128Array( uniform( N*2, -100.0, 100.0, options ) );
57+
y = new Complex128Array( uniform( N*2, -100.0, 100.0, options ) );
5858

5959
viewY = reinterpret( y, 0 );
6060

@@ -74,12 +74,12 @@ function createBenchmark( len ) {
7474
b.tic();
7575
for ( i = 0; i < b.iterations; i++ ) {
7676
zaxpy( x.length, alpha, x, 1, y, 1 );
77-
if ( isnan( viewY[ i%(len*2) ] ) ) {
77+
if ( isnan( viewY[ i%(N*2) ] ) ) {
7878
b.fail( 'should not return NaN' );
7979
}
8080
}
8181
b.toc();
82-
if ( isnan( viewY[ i%(len*2) ] ) ) {
82+
if ( isnan( viewY[ i%(N*2) ] ) ) {
8383
b.fail( 'should not return NaN' );
8484
}
8585
b.pass( 'benchmark finished' );
@@ -96,19 +96,19 @@ function createBenchmark( len ) {
9696
* @private
9797
*/
9898
function main() {
99-
var len;
10099
var min;
101100
var max;
101+
var N;
102102
var f;
103103
var i;
104104

105105
min = 1; // 10^min
106106
max = 6; // 10^max
107107

108108
for ( i = min; i <= max; i++ ) {
109-
len = pow( 10, i );
110-
f = createBenchmark( len );
111-
bench( pkg+':len='+len, f );
109+
N = pow( 10, i );
110+
f = createBenchmark( N );
111+
bench( pkg+':len='+N, f );
112112
}
113113
}
114114

0 commit comments

Comments
 (0)