Skip to content

Commit 0c7c973

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: na - 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 00d8714 commit 0c7c973

File tree

3 files changed

+49
-10
lines changed

3 files changed

+49
-10
lines changed

lib/node_modules/@stdlib/blas/ext/base/gsumkbn/lib/accessors.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ function gsumkbn( N, x, strideX, offsetX ) {
5858
var xbuf;
5959
var get;
6060
var sum;
61+
var flg;
6162
var ix;
6263
var v;
6364
var t;
@@ -74,9 +75,27 @@ function gsumkbn( N, x, strideX, offsetX ) {
7475
if ( strideX === 0 ) {
7576
return N * get( xbuf, ix );
7677
}
77-
sum = 0.0;
78+
v = get( xbuf, ix );
79+
sum = v;
80+
81+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
82+
if ( sum === 0.0 ) {
83+
for ( i = 1; i < N; i++ ) {
84+
v = get( xbuf, ix );
85+
if ( v !== 0.0 ) {
86+
flg = true;
87+
break;
88+
}
89+
sum += v;
90+
ix += strideX;
91+
}
92+
} else {
93+
flg = true;
94+
ix += strideX;
95+
i = 1;
96+
}
7897
c = 0.0;
79-
for ( i = 0; i < N; i++ ) {
98+
for ( ; i < N; i++ ) {
8099
v = get( xbuf, ix );
81100
t = sum + v;
82101
if ( abs( sum ) >= abs( v ) ) {
@@ -87,7 +106,7 @@ function gsumkbn( N, x, strideX, offsetX ) {
87106
sum = t;
88107
ix += strideX;
89108
}
90-
return sum + c;
109+
return ( flg ) ? sum+c : sum;
91110
}
92111

93112

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ var accessors = require( './accessors.js' );
5252
*/
5353
function gsumkbn( N, x, strideX, offsetX ) {
5454
var sum;
55+
var flg;
5556
var ix;
5657
var o;
5758
var v;
@@ -70,9 +71,27 @@ function gsumkbn( N, x, strideX, offsetX ) {
7071
if ( strideX === 0 ) {
7172
return N * x[ ix ];
7273
}
73-
sum = 0.0;
74+
v = x[ ix ];
75+
sum = v;
76+
77+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
78+
if ( sum === 0.0 ) {
79+
for ( i = 1; i < N; i++ ) {
80+
v = x[ ix ];
81+
if ( v !== 0.0 ) {
82+
flg = true;
83+
break;
84+
}
85+
sum += v;
86+
ix += strideX;
87+
}
88+
} else {
89+
flg = true;
90+
ix += strideX;
91+
i = 1;
92+
}
7493
c = 0.0;
75-
for ( i = 0; i < N; i++ ) {
94+
for ( ; i < N; i++ ) {
7695
v = x[ ix ];
7796
t = sum + v;
7897
if ( abs( sum ) >= abs( v ) ) {
@@ -83,7 +102,7 @@ function gsumkbn( N, x, strideX, offsetX ) {
83102
sum = t;
84103
ix += strideX;
85104
}
86-
return sum + c;
105+
return ( flg ) ? sum+c : sum;
87106
}
88107

89108

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
var tape = require( 'tape' );
2424
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2525
var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
26+
var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' );
2627
var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' );
2728
var gsumkbn = require( './../lib/ndarray.js' );
2829

@@ -94,14 +95,14 @@ tape( 'the function calculates the sum of all strided array elements (accessors)
9495
t.end();
9596
});
9697

97-
tape( 'the function does not preserve the sign of zero', function test( t ) {
98+
tape( 'the function preserves the sign of zero', function test( t ) {
9899
var x;
99100
var v;
100101

101102
x = [ -0.0, -0.0, -0.0 ];
102103

103104
v = gsumkbn( x.length, x, 1, 0 );
104-
t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
105+
t.strictEqual( isNegativeZero( v ), true, 'returns expected value' );
105106

106107
x = [ 0.0, -0.0, -0.0 ];
107108

@@ -111,14 +112,14 @@ tape( 'the function does not preserve the sign of zero', function test( t ) {
111112
t.end();
112113
});
113114

114-
tape( 'the function does not preserve the sign of zero (accessors)', function test( t ) {
115+
tape( 'the function preserves the sign of zero (accessors)', function test( t ) {
115116
var x;
116117
var v;
117118

118119
x = toAccessorArray( [ -0.0, -0.0, -0.0 ] );
119120

120121
v = gsumkbn( x.length, x, 1, 0 );
121-
t.strictEqual( isPositiveZero( v ), true, 'returns expected value' );
122+
t.strictEqual( isNegativeZero( v ), true, 'returns expected value' );
122123

123124
x = toAccessorArray( [ 0.0, -0.0, -0.0 ] );
124125

0 commit comments

Comments
 (0)