Skip to content

Commit 67a91d6

Browse files
committed
fix: update implementation to preserve signed zeros
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: passed - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent 3d59edd commit 67a91d6

File tree

4 files changed

+56
-15
lines changed

4 files changed

+56
-15
lines changed

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

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

2121
// MODULES //
2222

23-
var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
23+
var f32 = require( '@stdlib/number/float64/base/to-float32' );
2424
var absf = require( '@stdlib/math/base/special/absf' );
2525

2626

@@ -53,6 +53,7 @@ var absf = require( '@stdlib/math/base/special/absf' );
5353
*/
5454
function ssumkbn( N, x, strideX, offsetX ) {
5555
var sum;
56+
var flg;
5657
var ix;
5758
var v;
5859
var t;
@@ -64,22 +65,40 @@ function ssumkbn( N, x, strideX, offsetX ) {
6465
}
6566
ix = offsetX;
6667
if ( strideX === 0 ) {
67-
return float64ToFloat32( N * x[ ix ] );
68+
return f32( N * x[ ix ] );
69+
}
70+
v = x[ ix ];
71+
sum = v;
72+
73+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
74+
if ( sum === 0.0 ) {
75+
for ( i = 1; i < N; i++ ) {
76+
v = x[ ix ];
77+
if ( v !== 0.0 ) {
78+
flg = true;
79+
break;
80+
}
81+
sum = f32( sum + v );
82+
ix += strideX;
83+
}
84+
} else {
85+
flg = true;
86+
ix += strideX;
87+
i = 1;
6888
}
69-
sum = 0.0;
7089
c = 0.0;
71-
for ( i = 0; i < N; i++ ) {
90+
for ( ; i < N; i++ ) {
7291
v = x[ ix ];
73-
t = float64ToFloat32( sum + v );
92+
t = f32( sum + v );
7493
if ( absf( sum ) >= absf( v ) ) {
75-
c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( sum-t ) + v ) ); // eslint-disable-line max-len
94+
c = f32( c + f32( f32( sum-t ) + v ) );
7695
} else {
77-
c = float64ToFloat32( c + float64ToFloat32( float64ToFloat32( v-t ) + sum ) ); // eslint-disable-line max-len
96+
c = f32( c + f32( f32( v-t ) + sum ) );
7897
}
7998
sum = t;
8099
ix += strideX;
81100
}
82-
return float64ToFloat32( sum + c );
101+
return ( flg ) ? f32( sum+c ) : sum;
83102
}
84103

85104

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ float API_SUFFIX(stdlib_strided_ssumkbn_ndarray)( const CBLAS_INT N, const float
6666
float v;
6767
float t;
6868
float c;
69+
int flg;
6970

7071
if ( N <= 0 ) {
7172
return 0.0f;
@@ -74,9 +75,28 @@ float API_SUFFIX(stdlib_strided_ssumkbn_ndarray)( const CBLAS_INT N, const float
7475
if ( strideX == 0 ) {
7576
return N * X[ ix ];
7677
}
77-
sum = 0.0f;
78+
v = X[ ix ];
79+
sum = v;
80+
flg = 0;
81+
82+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
83+
if ( sum == 0.0f ) {
84+
for ( i = 1; i < N; i++ ) {
85+
v = X[ ix ];
86+
if ( v != 0.0f ) {
87+
flg = 1;
88+
break;
89+
}
90+
sum += v;
91+
ix += strideX;
92+
}
93+
} else {
94+
flg = 1;
95+
ix += strideX;
96+
i = 1;
97+
}
7898
c = 0.0f;
79-
for ( i = 0; i < N; i++ ) {
99+
for ( ; i < N; i++ ) {
80100
v = X[ ix ];
81101
t = sum + v;
82102
if ( stdlib_base_absf( sum ) >= stdlib_base_absf( v ) ) {
@@ -87,5 +107,5 @@ float API_SUFFIX(stdlib_strided_ssumkbn_ndarray)( const CBLAS_INT N, const float
87107
sum = t;
88108
ix += strideX;
89109
}
90-
return sum + c;
110+
return ( flg == 1 ) ? sum+c : sum;
91111
}

lib/node_modules/@stdlib/blas/ext/base/ssumkbn/test/test.ndarray.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
var tape = require( 'tape' );
2424
var isPositiveZerof = require( '@stdlib/math/base/assert/is-positive-zerof' );
25+
var isNegativeZerof = require( '@stdlib/math/base/assert/is-negative-zerof' );
2526
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
2627
var Float32Array = require( '@stdlib/array/float32' );
2728
var ssumkbn = require( './../lib/ndarray.js' );
@@ -67,14 +68,14 @@ tape( 'the function calculates the sum of all strided array elements', function
6768
t.end();
6869
});
6970

70-
tape( 'the function does not preserve the sign of zero', function test( t ) {
71+
tape( 'the function preserves the sign of zero', function test( t ) {
7172
var x;
7273
var v;
7374

7475
x = new Float32Array( [ -0.0, -0.0, -0.0 ] );
7576

7677
v = ssumkbn( x.length, x, 1, 0 );
77-
t.strictEqual( isPositiveZerof( v ), true, 'returns expected value' );
78+
t.strictEqual( isNegativeZerof( v ), true, 'returns expected value' );
7879

7980
x = new Float32Array( [ 0.0, -0.0, -0.0 ] );
8081

lib/node_modules/@stdlib/blas/ext/base/ssumkbn/test/test.ndarray.native.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
var resolve = require( 'path' ).resolve;
2424
var tape = require( 'tape' );
2525
var isPositiveZerof = require( '@stdlib/math/base/assert/is-positive-zerof' );
26+
var isNegativeZerof = require( '@stdlib/math/base/assert/is-negative-zerof' );
2627
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
2728
var Float32Array = require( '@stdlib/array/float32' );
2829
var tryRequire = require( '@stdlib/utils/try-require' );
@@ -76,14 +77,14 @@ tape( 'the function calculates the sum of all strided array elements', opts, fun
7677
t.end();
7778
});
7879

79-
tape( 'the function does not preserve the sign of zero', opts, function test( t ) {
80+
tape( 'the function preserves the sign of zero', opts, function test( t ) {
8081
var x;
8182
var v;
8283

8384
x = new Float32Array( [ -0.0, -0.0, -0.0 ] );
8485

8586
v = ssumkbn( x.length, x, 1, 0 );
86-
t.strictEqual( isPositiveZerof( v ), true, 'returns expected value' );
87+
t.strictEqual( isNegativeZerof( v ), true, 'returns expected value' );
8788

8889
x = new Float32Array( [ 0.0, -0.0, -0.0 ] );
8990

0 commit comments

Comments
 (0)