Skip to content

Commit d3451ce

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 0c7c973 commit d3451ce

File tree

3 files changed

+48
-10
lines changed

3 files changed

+48
-10
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function gsumkbn2( N, x, strideX, offsetX ) {
5959
var get;
6060
var sum;
6161
var ccs;
62+
var flg;
6263
var ix;
6364
var cs;
6465
var cc;
@@ -77,11 +78,28 @@ function gsumkbn2( N, x, strideX, offsetX ) {
7778
if ( strideX === 0 ) {
7879
return N * get( xbuf, ix );
7980
}
81+
v = get( xbuf, ix );
82+
sum = v;
8083

81-
sum = 0.0;
84+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
85+
if ( sum === 0.0 ) {
86+
for ( i = 1; i < N; i++ ) {
87+
v = get( xbuf, ix );
88+
if ( v !== 0.0 ) {
89+
flg = true;
90+
break;
91+
}
92+
sum += v;
93+
ix += strideX;
94+
}
95+
} else {
96+
flg = true;
97+
ix += strideX;
98+
i = 1;
99+
}
82100
ccs = 0.0; // second order correction term for lost low order bits
83101
cs = 0.0; // first order correction term for lost low order bits
84-
for ( i = 0; i < N; i++ ) {
102+
for ( ; i < N; i++ ) {
85103
v = get( xbuf, ix );
86104
t = sum + v;
87105
if ( abs( sum ) >= abs( v ) ) {
@@ -100,7 +118,7 @@ function gsumkbn2( N, x, strideX, offsetX ) {
100118
ccs += cc;
101119
ix += strideX;
102120
}
103-
return sum + cs + ccs;
121+
return ( flg ) ? sum+cs+ccs : sum;
104122
}
105123

106124

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ var accessors = require( './accessors.js' );
5353
function gsumkbn2( N, x, strideX, offsetX ) {
5454
var sum;
5555
var ccs;
56+
var flg;
5657
var ix;
5758
var cs;
5859
var cc;
@@ -73,10 +74,28 @@ function gsumkbn2( N, x, strideX, offsetX ) {
7374
if ( strideX === 0 ) {
7475
return N * x[ ix ];
7576
}
76-
sum = 0.0;
77+
v = x[ ix ];
78+
sum = v;
79+
80+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
81+
if ( sum === 0.0 ) {
82+
for ( i = 1; i < N; i++ ) {
83+
v = x[ ix ];
84+
if ( v !== 0.0 ) {
85+
flg = true;
86+
break;
87+
}
88+
sum += v;
89+
ix += strideX;
90+
}
91+
} else {
92+
flg = true;
93+
ix += strideX;
94+
i = 1;
95+
}
7796
ccs = 0.0; // second order correction term for lost low order bits
7897
cs = 0.0; // first order correction term for lost low order bits
79-
for ( i = 0; i < N; i++ ) {
98+
for ( ; i < N; i++ ) {
8099
v = x[ ix ];
81100
t = sum + v;
82101
if ( abs( sum ) >= abs( v ) ) {
@@ -95,7 +114,7 @@ function gsumkbn2( N, x, strideX, offsetX ) {
95114
ccs += cc;
96115
ix += strideX;
97116
}
98-
return sum + cs + ccs;
117+
return ( flg ) ? sum+cs+ccs : sum;
99118
}
100119

101120

lib/node_modules/@stdlib/blas/ext/base/gsumkbn2/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 gsumkbn2 = 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 = gsumkbn2( 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 = gsumkbn2( 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)