Skip to content

Commit 061b85a

Browse files
committed
add suggested changes
1 parent 768ade4 commit 061b85a

14 files changed

Lines changed: 132 additions & 115 deletions

File tree

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ The function has the following additional parameters:
115115
- **offsetX**: starting index for `x`.
116116
- **offsetY**: starting index for `y`.
117117

118-
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 calculate the cumulative sum of every other value in `x` starting from the second value and to store in the last `N` elements of `y` starting from the last element:
118+
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 calculate the cumulative sum of every other value in the strided input array starting from the second value and to store in the last `N` elements of the strided output array starting from the last element:
119119

120120
```javascript
121121
var Float64Array = require( '@stdlib/array/float64' );
@@ -308,7 +308,6 @@ int main( void ) {
308308
309309
<!-- /.c -->
310310
311-
312311
<section class="references">
313312
314313
## References

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/benchmark/benchmark.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ function createBenchmark( len ) {
7979
b.tic();
8080
for ( i = 0; i < b.iterations; i++ ) {
8181
v = dnancusumpw( x.length, 0.0, x, 1, y, 1 );
82-
if ( isnan( v[ i % len ] ) ) {
82+
if ( isnan( v[ i%len ] ) ) {
8383
b.fail( 'should not return NaN' );
8484
}
8585
}
8686
b.toc();
87-
if ( isnan( v[ i % len ] ) ) {
87+
if ( isnan( v[ i%len ] ) ) {
8888
b.fail( 'should not return NaN' );
8989
}
9090
b.pass( 'benchmark finished' );

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/benchmark/benchmark.native.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ function createBenchmark( len ) {
8484
b.tic();
8585
for ( i = 0; i < b.iterations; i++ ) {
8686
v = dnancusumpw( x.length, 0.0, x, 1, y, 1 );
87-
if ( isnan( v[ i % len ] ) ) {
87+
if ( isnan( v[ i%len ] ) ) {
8888
b.fail( 'should not return NaN' );
8989
}
9090
}
9191
b.toc();
92-
if ( isnan( v[ i % len ] ) ) {
92+
if ( isnan( v[ i%len ] ) ) {
9393
b.fail( 'should not return NaN' );
9494
}
9595
b.pass( 'benchmark finished' );

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/benchmark/benchmark.ndarray.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ function createBenchmark( len ) {
7979
b.tic();
8080
for ( i = 0; i < b.iterations; i++ ) {
8181
v = dnancusumpw( x.length, 0.0, x, 1, 0, y, 1, 0 );
82-
if ( isnan( v[ i % len ] ) ) {
82+
if ( isnan( v[ i%len ] ) ) {
8383
b.fail( 'should not return NaN' );
8484
}
8585
}
8686
b.toc();
87-
if ( isnan( v[ i % len ] ) ) {
87+
if ( isnan( v[ i%len ] ) ) {
8888
b.fail( 'should not return NaN' );
8989
}
9090
b.pass( 'benchmark finished' );

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/benchmark/benchmark.ndarray.native.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ function createBenchmark( len ) {
8484
b.tic();
8585
for ( i = 0; i < b.iterations; i++ ) {
8686
v = dnancusumpw( x.length, 0.0, x, 1, 0, y, 1, 0 );
87-
if ( isnan( v[ i % len ] ) ) {
87+
if ( isnan( v[ i%len ] ) ) {
8888
b.fail( 'should not return NaN' );
8989
}
9090
}
9191
b.toc();
92-
if ( isnan( v[ i % len ] ) ) {
92+
if ( isnan( v[ i%len ] ) ) {
9393
b.fail( 'should not return NaN' );
9494
}
9595
b.pass( 'benchmark finished' );

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
* limitations under the License.
1717
*/
1818

19-
#include <sys/time.h>
2019
#include "stdlib/blas/ext/base/dnancusumpw.h"
21-
#include <math.h>
22-
#include <stdio.h>
2320
#include <stdlib.h>
21+
#include <stdio.h>
22+
#include <math.h>
2423
#include <time.h>
24+
#include <sys/time.h>
2525

2626
#define NAME "dnancusumpw"
2727
#define ITERATIONS 1000000
@@ -101,8 +101,8 @@ static double benchmark1( int iterations, int len ) {
101101
double t;
102102
int i;
103103

104-
x = (double *)malloc( len * sizeof( double ) );
105-
y = (double *)malloc( len * sizeof( double ) );
104+
x = (double *)malloc( len * sizeof(double) );
105+
y = (double *)malloc( len * sizeof(double) );
106106

107107
for ( i = 0; i < len; i++ ) {
108108
if ( rand_double() < 0.2 ) {
@@ -121,7 +121,7 @@ static double benchmark1( int iterations, int len ) {
121121
}
122122
}
123123
elapsed = tic() - t;
124-
if ( y[ len - 1 ] != y[ len - 1 ] ) {
124+
if ( y[ len-1 ] != y[ len-1 ] ) {
125125
printf( "should not return NaN\n" );
126126
}
127127
free( x );
@@ -143,8 +143,8 @@ static double benchmark2( int iterations, int len ) {
143143
double t;
144144
int i;
145145

146-
x = (double *)malloc( len * sizeof( double ) );
147-
y = (double *)malloc( len * sizeof( double ) );
146+
x = (double *)malloc( len * sizeof(double) );
147+
y = (double *)malloc( len * sizeof(double) );
148148

149149
for ( i = 0; i < len; i++ ) {
150150
if ( rand_double() < 0.2 ) {
@@ -163,7 +163,7 @@ static double benchmark2( int iterations, int len ) {
163163
}
164164
}
165165
elapsed = tic() - t;
166-
if ( y[ len - 1 ] != y[ len - 1 ] ) {
166+
if ( y[ len-1 ] != y[ len-1 ] ) {
167167
printf( "should not return NaN\n" );
168168
}
169169
free( x );
@@ -189,7 +189,7 @@ int main( void ) {
189189
count = 0;
190190
for ( i = MIN; i <= MAX; i++ ) {
191191
len = pow( 10, i );
192-
iter = ITERATIONS / pow( 10, i - 1 );
192+
iter = ITERATIONS / pow( 10, i-1 );
193193
for ( j = 0; j < REPEATS; j++ ) {
194194
count += 1;
195195
printf( "# c::%s:len=%d\n", NAME, len );
@@ -200,7 +200,7 @@ int main( void ) {
200200
}
201201
for ( i = MIN; i <= MAX; i++ ) {
202202
len = pow( 10, i );
203-
iter = ITERATIONS / pow( 10, i - 1 );
203+
iter = ITERATIONS / pow( 10, i-1 );
204204
for ( j = 0; j < REPEATS; j++ ) {
205205
count += 1;
206206
printf( "# c::%s:ndarray:len=%d\n", NAME, len );

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ var ndarray = require( './ndarray.js' );
2929
/**
3030
* Computes the cumulative sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.
3131
*
32+
* ## Method
33+
*
34+
* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.
35+
*
36+
* ## References
37+
*
38+
* - Higham, Nicholas J. 1993. "The Accuracy of Floating Point Summation." _SIAM Journal on Scientific Computing_ 14 (4): 783–99. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).
39+
*
3240
* @param {PositiveInteger} N - number of indexed elements
3341
* @param {number} sum - initial sum
3442
* @param {Float64Array} x - input array
@@ -42,9 +50,8 @@ var ndarray = require( './ndarray.js' );
4250
*
4351
* var x = new Float64Array( [ 1.0, -2.0, NaN ] );
4452
* var y = new Float64Array( x.length );
45-
* var N = x.length;
4653
*
47-
* var v = dnancusumpw( N, 0.0, x, 1, y, 1 );
54+
* var v = dnancusumpw( x.length, 0.0, x, 1, y, 1 );
4855
* // returns <Float64Array>[ 1.0, -1.0, -1.0 ]
4956
*/
5057
function dnancusumpw( N, sum, x, strideX, y, strideY ) {

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/lib/ndarray.js

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,29 @@
2020

2121
// MODULES //
2222

23+
var floor = require( '@stdlib/math/base/special/floor' );
2324
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2425

2526

27+
// VARIABLES //
28+
29+
// Blocksize for pairwise summation:
30+
var BLOCKSIZE = 128;
31+
32+
2633
// MAIN //
2734

2835
/**
2936
* Computes the cumulative sum of double-precision floating-point strided array elements, ignoring `NaN` values and using pairwise summation.
3037
*
38+
* ## Method
39+
*
40+
* - This implementation uses pairwise summation, which accrues rounding error `O(log2 N)` instead of `O(N)`. The recursion depth is also `O(log2 N)`.
41+
*
42+
* ## References
43+
*
44+
* - Higham, Nicholas J. 1993. "The Accuracy of Floating Point Summation." _SIAM Journal on Scientific Computing_ 14 (4): 783–99. doi:[10.1137/0914050](https://doi.org/10.1137/0914050).
45+
*
3146
* @param {PositiveInteger} N - number of indexed elements
3247
* @param {number} sum - initial sum
3348
* @param {Float64Array} x - input array
@@ -50,21 +65,42 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' );
5065
function dnancusumpw( N, sum, x, strideX, offsetX, y, strideY, offsetY ) {
5166
var ix;
5267
var iy;
68+
var s;
69+
var n;
5370
var i;
5471

5572
if ( N <= 0 ) {
5673
return y;
5774
}
5875
ix = offsetX;
5976
iy = offsetY;
60-
for ( i = 0; i < N; i++ ) {
61-
if ( isnan( x[ ix ] ) === false ) {
62-
sum += x[ ix ];
77+
if ( N <= BLOCKSIZE ) {
78+
if ( isnan( x[ ix ] ) ) {
79+
s = 0.0;
80+
} else {
81+
s = x[ ix ];
6382
}
64-
y[ iy ] = sum;
83+
y[ iy ] = sum + s;
6584
ix += strideX;
6685
iy += strideY;
86+
for ( i = 1; i < N; i++ ) {
87+
if ( isnan( x[ ix ] ) ) {
88+
y[ iy ] = sum + s;
89+
ix += strideX;
90+
iy += strideY;
91+
continue;
92+
}
93+
s += x[ ix ];
94+
y[ iy ] = sum + s;
95+
ix += strideX;
96+
iy += strideY;
97+
}
98+
return y;
6799
}
100+
n = floor( N/2 );
101+
dnancusumpw( n, sum, x, strideX, ix, y, strideY, iy );
102+
iy += (n-1) * strideY;
103+
dnancusumpw( N-n, y[ iy ], x, strideX, ix+(n*strideX), y, strideY, iy+strideY ); // eslint-disable-line max-len
68104
return y;
69105
}
70106

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/src/addon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,4 @@ static napi_value addon_method( napi_env env, napi_callback_info info ) {
6565
return NULL;
6666
}
6767

68-
STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method );
68+
STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method )

lib/node_modules/@stdlib/blas/ext/base/dnancusumpw/src/main.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,42 @@ void API_SUFFIX(stdlib_strided_dnancusumpw_ndarray)( const CBLAS_INT N, const do
6161
CBLAS_INT ix;
6262
CBLAS_INT iy;
6363
CBLAS_INT i;
64+
CBLAS_INT n;
6465
double s;
6566

6667
if ( N <= 0 ) {
6768
return;
6869
}
6970
ix = offsetX;
7071
iy = offsetY;
71-
s = sum;
72-
for ( i = 0; i < N; i++ ) {
73-
if ( !stdlib_base_is_nan( X[ ix ] ) ) {
74-
s += X[ ix ];
72+
73+
// Blocksize for pairwise summation...
74+
if ( N <= 128 ) {
75+
if ( stdlib_base_is_nan( X[ ix ] ) ) {
76+
s = 0.0;
77+
} else {
78+
s = X[ ix ];
7579
}
76-
Y[ iy ] = s;
80+
Y[ iy ] = sum + s;
7781
ix += strideX;
7882
iy += strideY;
83+
for ( i = 1; i < N; i++ ) {
84+
if ( stdlib_base_is_nan( X[ ix ] ) ) {
85+
Y[ iy ] = sum + s;
86+
ix += strideX;
87+
iy += strideY;
88+
continue;
89+
}
90+
s += X[ ix ];
91+
Y[ iy ] = sum + s;
92+
ix += strideX;
93+
iy += strideY;
94+
}
95+
return;
7996
}
97+
n = N / 2;
98+
API_SUFFIX(stdlib_strided_dnancusumpw_ndarray)( n, sum, X, strideX, ix, Y, strideY, iy );
99+
iy += (n-1) * strideY;
100+
API_SUFFIX(stdlib_strided_dnancusumpw_ndarray)( N-n, Y[ iy ], X, strideX, ix+(n*strideX), Y, strideY, iy+strideY );
80101
return;
81102
}

0 commit comments

Comments
 (0)