Skip to content

Commit 74d5f40

Browse files
committed
feat: add C ndarray API and refactor
1 parent ec4730b commit 74d5f40

File tree

16 files changed

+342
-162
lines changed

16 files changed

+342
-162
lines changed

lib/node_modules/@stdlib/blas/ext/base/dnannsumors/README.md

Lines changed: 128 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ The function has the following parameters:
5858
- **out**: output [`Float64Array`][@stdlib/array/float64] whose first element is the sum and whose second element is the number of non-NaN elements.
5959
- **strideOut**: index increment for `out`.
6060

61-
The `N` and `stride` parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in `x`,
61+
The `N` and stride parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in `x`,
6262

6363
```javascript
6464
var Float64Array = require( '@stdlib/array/float64' );
@@ -106,7 +106,7 @@ The function has the following additional parameters:
106106
- **offsetX**: starting index for `x`.
107107
- **offsetOut**: starting index for `out`.
108108

109-
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to calculate the sum of every other value in `x` starting from the second value
109+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, offset parameters support indexing semantics based on starting indices. For example, to calculate the sum of every other value in `x` starting from the second value:
110110

111111
```javascript
112112
var Float64Array = require( '@stdlib/array/float64' );
@@ -166,6 +166,132 @@ console.log( out );
166166

167167
<!-- /.examples -->
168168

169+
<!-- C interface documentation. -->
170+
171+
* * *
172+
173+
<section class="c">
174+
175+
## C APIs
176+
177+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
178+
179+
<section class="intro">
180+
181+
</section>
182+
183+
<!-- /.intro -->
184+
185+
<!-- C usage documentation. -->
186+
187+
<section class="usage">
188+
189+
### Usage
190+
191+
```c
192+
#include "stdlib/blas/ext/base/dnannsumors.h"
193+
```
194+
195+
#### stdlib_strided_dnannsumors( N, \*X, strideX, \*n )
196+
197+
Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation.
198+
199+
```c
200+
const double x[] = { 1.0, 2.0, 0.0/0.0, 4.0 };
201+
CBLAS_INT n = 0;
202+
203+
double v = stdlib_strided_dnannsumors( 4, x, 1, &n );
204+
// returns 7.0
205+
```
206+
207+
The function accepts the following arguments:
208+
209+
- **N**: `[in] CBLAS_INT` number of indexed elements.
210+
- **X**: `[in] double*` input array.
211+
- **strideX**: `[in] CBLAS_INT` index increment for `X`.
212+
- **n**: `[out] CBLAS_INT*` number of non-NaN elements.
213+
214+
```c
215+
double stdlib_strided_dnannsumors( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, CBLAS_INT *n );
216+
```
217+
218+
#### stdlib_strided_dnannsumors_ndarray( N, \*X, strideX, offsetX, \*n )
219+
220+
Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation and alternative indexing semantics.
221+
222+
```c
223+
const double x[] = { 1.0, 2.0, 0.0/0.0, 4.0 };
224+
CBLAS_INT n = 0;
225+
226+
double v = stdlib_strided_dnannsumors_ndarray( 4, x, 1, 0, &n );
227+
// returns 7.0
228+
```
229+
230+
The function accepts the following arguments:
231+
232+
- **N**: `[in] CBLAS_INT` number of indexed elements.
233+
- **X**: `[in] double*` input array.
234+
- **strideX**: `[in] CBLAS_INT` index increment for `X`.
235+
- **offsetX**: `[in] CBLAS_INT` starting index for `X`.
236+
- **n**: `[out] CBLAS_INT*` number of non-NaN elements.
237+
238+
```c
239+
double stdlib_strided_dnannsumors_ndarray( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n );
240+
```
241+
242+
</section>
243+
244+
<!-- /.usage -->
245+
246+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
247+
248+
<section class="notes">
249+
250+
</section>
251+
252+
<!-- /.notes -->
253+
254+
<!-- C API usage examples. -->
255+
256+
<section class="examples">
257+
258+
### Examples
259+
260+
```c
261+
#include "stdlib/blas/ext/base/dnannsumors.h"
262+
#include "stdlib/blase/base/shared.h"
263+
#include <stdio.h>
264+
265+
int main( void ) {
266+
// Create a strided array:
267+
const double x[] = { 1.0, 2.0, -3.0, -4.0, 5.0, -6.0, -7.0, 8.0, 0.0/0.0, 0.0/0.0 };
268+
269+
// Specify the number of elements:
270+
const int N = 5;
271+
272+
// Specify the stride length:
273+
const int strideX = 2;
274+
275+
// Initialize a variable for storing the number of non-NaN elements:
276+
CBLAS_INT n = 0;
277+
278+
// Compute the sum:
279+
double v = stdlib_strided_dnannsumors( N, x, strideX, &n );
280+
281+
// Print the result:
282+
printf( "sum: %lf\n", v );
283+
printf( "n: %"CBLAS_IFMT"\n", n );
284+
}
285+
```
286+
287+
</section>
288+
289+
<!-- /.examples -->
290+
291+
</section>
292+
293+
<!-- /.c -->
294+
169295
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
170296
171297
<section class="related">

lib/node_modules/@stdlib/blas/ext/base/dnannsumors/benchmark/c/benchmark.length.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include "stdlib/blas/ext/base/dnannsumors.h"
20+
#include "stdlib/blas/base/shared.h"
2021
#include <stdlib.h>
2122
#include <stdio.h>
2223
#include <math.h>
@@ -94,10 +95,10 @@ static double rand_double( void ) {
9495
* @param len array length
9596
* @return elapsed time in seconds
9697
*/
97-
static double benchmark( int iterations, int len ) {
98+
static double benchmark1( int iterations, int len ) {
9899
double elapsed;
99100
double x[ len ];
100-
int64_t n;
101+
CBLAS_INT n;
101102
double v;
102103
double t;
103104
int i;
@@ -126,6 +127,45 @@ static double benchmark( int iterations, int len ) {
126127
return elapsed;
127128
}
128129

130+
/**
131+
* Runs a benchmark.
132+
*
133+
* @param iterations number of iterations
134+
* @param len array length
135+
* @return elapsed time in seconds
136+
*/
137+
static double benchmark2( int iterations, int len ) {
138+
double elapsed;
139+
double x[ len ];
140+
CBLAS_INT n;
141+
double v;
142+
double t;
143+
int i;
144+
145+
for ( i = 0; i < len; i++ ) {
146+
if ( rand_double() < 0.2 ) {
147+
x[ i ] = 0.0 / 0.0; // NaN
148+
} else {
149+
x[ i ] = ( rand_double() * 20000.0 ) - 10000.0;
150+
}
151+
}
152+
v = 0.0;
153+
n = 0;
154+
t = tic();
155+
for ( i = 0; i < iterations; i++ ) {
156+
v = stdlib_strided_dnannsumors_ndarray( len, x, 1, 0, &n );
157+
if ( v != v || n < 0 ) {
158+
printf( "should not return NaN\n" );
159+
break;
160+
}
161+
}
162+
elapsed = tic() - t;
163+
if ( v != v || n < 0 ) {
164+
printf( "should not return NaN\n" );
165+
}
166+
return elapsed;
167+
}
168+
129169
/**
130170
* Main execution sequence.
131171
*/
@@ -148,7 +188,18 @@ int main( void ) {
148188
for ( j = 0; j < REPEATS; j++ ) {
149189
count += 1;
150190
printf( "# c::%s:len=%d\n", NAME, len );
151-
elapsed = benchmark( iter, len );
191+
elapsed = benchmark1( iter, len );
192+
print_results( iter, elapsed );
193+
printf( "ok %d benchmark finished\n", count );
194+
}
195+
}
196+
for ( i = MIN; i <= MAX; i++ ) {
197+
len = pow( 10, i );
198+
iter = ITERATIONS / pow( 10, i-1 );
199+
for ( j = 0; j < REPEATS; j++ ) {
200+
count += 1;
201+
printf( "# c::%s:ndarray:len=%d\n", NAME, len );
202+
elapsed = benchmark2( iter, len );
152203
print_results( iter, elapsed );
153204
printf( "ok %d benchmark finished\n", count );
154205
}

lib/node_modules/@stdlib/blas/ext/base/dnannsumors/docs/repl.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Computes the sum of double-precision floating-point strided array elements,
44
ignoring `NaN` values and using ordinary recursive summation.
55

6-
The `N` and `stride` parameters determine which elements are accessed at
6+
The `N` and stride parameters determine which elements are accessed at
77
runtime.
88

99
Indexing is relative to the first index. To introduce an offset, use a typed
@@ -57,14 +57,15 @@
5757
> {{alias}}( N, x1, 2, out, 1 )
5858
<Float64Array>[ 1.0, 3 ]
5959

60+
6061
{{alias}}.ndarray( N, x, strideX, offsetX, out, strideOut, offsetOut )
6162
Computes the sum of double-precision floating-point strided array elements,
6263
ignoring `NaN` values and using ordinary recursive summation and alternative
6364
indexing semantics.
6465

6566
While typed array views mandate a view offset based on the underlying
66-
buffer, the `offset` parameter supports indexing semantics based on a
67-
starting index.
67+
buffer, offset parameters support indexing semantics based on starting
68+
indices.
6869

6970
Parameters
7071
----------

lib/node_modules/@stdlib/blas/ext/base/dnannsumors/examples/c/example.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,27 @@
1717
*/
1818

1919
#include "stdlib/blas/ext/base/dnannsumors.h"
20-
#include <stdint.h>
20+
#include "stdlib/blas/base/shared.h"
2121
#include <stdio.h>
22-
#include <inttypes.h>
22+
2323

2424
int main( void ) {
2525
// Create a strided array:
2626
const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 0.0/0.0, 0.0/0.0 };
2727

2828
// Specify the number of elements:
29-
const int64_t N = 5;
29+
const int N = 5;
3030

3131
// Specify the stride length:
32-
const int64_t stride = 2;
32+
const int strideX = 2;
3333

3434
// Initialize a variable for storing the number of non-NaN elements:
35-
int64_t n = 0;
35+
CBLAS_INT n = 0;
3636

3737
// Compute the sum:
38-
double v = stdlib_strided_dnannsumors( N, x, stride, &n );
38+
double v = stdlib_strided_dnannsumors( N, x, strideX, &n );
3939

4040
// Print the result:
4141
printf( "sum: %lf\n", v );
42-
printf( "n: %"PRId64"\n", n );
42+
printf( "n: %"CBLAS_IFMT"\n", n );
4343
}

lib/node_modules/@stdlib/blas/ext/base/dnannsumors/include/stdlib/blas/ext/base/dnannsumors.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#ifndef STDLIB_BLAS_EXT_BASE_DNANNSUMORS_H
2020
#define STDLIB_BLAS_EXT_BASE_DNANNSUMORS_H
2121

22-
#include <stdint.h>
22+
#include "stdlib/blas/base/shared.h"
2323

2424
/*
2525
* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler.
@@ -31,7 +31,12 @@ extern "C" {
3131
/**
3232
* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation.
3333
*/
34-
double stdlib_strided_dnannsumors( const int64_t N, const double *X, const int64_t stride, int64_t *n );
34+
double API_SUFFIX(stdlib_strided_dnannsumors)( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, CBLAS_INT *n );
35+
36+
/**
37+
* Computes the sum of double-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation and alternative indexing semantics.
38+
*/
39+
double API_SUFFIX(stdlib_strided_dnannsumors_ndarray)( const CBLAS_INT N, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n );
3540

3641
#ifdef __cplusplus
3742
}

lib/node_modules/@stdlib/blas/ext/base/dnannsumors/lib/dnannsumors.js

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
// MODULES //
2222

23-
var isnan = require( '@stdlib/math/base/assert/is-nan' );
23+
var stride2offset = require( '@stdlib/strided/base/stride2offset' );
24+
var ndarray = require( './ndarray.js' );
2425

2526

2627
// MAIN //
@@ -45,49 +46,16 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' );
4546
* // returns <Float64Array>[ 1.0, 3 ]
4647
*/
4748
function dnannsumors( N, x, strideX, out, strideOut ) {
48-
var sum;
4949
var ix;
5050
var io;
51-
var n;
52-
var i;
5351

54-
if ( strideX < 0 ) {
55-
ix = (1-N) * strideX;
56-
} else {
57-
ix = 0;
58-
}
52+
ix = stride2offset( N, strideX );
5953
if ( strideOut < 0 ) {
6054
io = -strideOut;
6155
} else {
6256
io = 0;
6357
}
64-
sum = 0.0;
65-
if ( N <= 0 ) {
66-
out[ io ] = sum;
67-
out[ io+strideOut ] = 0;
68-
return out;
69-
}
70-
if ( N === 1 || strideX === 0 ) {
71-
if ( isnan( x[ ix ] ) ) {
72-
out[ io ] = sum;
73-
out[ io+strideOut ] = 0;
74-
return out;
75-
}
76-
out[ io ] = x[ ix ];
77-
out[ io+strideOut ] = 1;
78-
return out;
79-
}
80-
n = 0;
81-
for ( i = 0; i < N; i++ ) {
82-
if ( isnan( x[ ix ] ) === false ) {
83-
sum += x[ ix ];
84-
n += 1;
85-
}
86-
ix += strideX;
87-
}
88-
out[ io ] = sum;
89-
out[ io+strideOut ] = n;
90-
return out;
58+
return ndarray( N, x, strideX, ix, out, strideOut, io );
9159
}
9260

9361

0 commit comments

Comments
 (0)