Skip to content

Commit 9b15f0d

Browse files
committed
fix: preserve the sign of zero
--- 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 b8e6c48 commit 9b15f0d

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,23 @@ function scusumkbn( N, sum, x, strideX, offsetX, y, strideY, offsetY ) {
7171
ix = offsetX;
7272
iy = offsetY;
7373
s = sum;
74+
75+
// In order to preserve the sign of zero which can be lost during compensated summation below, find the first non-zero element...
76+
if ( s === 0.0 ) {
77+
for ( i = 0; i < N; i++ ) {
78+
v = x[ ix ];
79+
if ( v !== 0.0 ) {
80+
break;
81+
}
82+
y[ iy ] = float64ToFloat32( s + v );
83+
ix += strideX;
84+
iy += strideY;
85+
}
86+
} else {
87+
i = 0;
88+
}
7489
c = 0.0;
75-
for ( i = 0; i < N; i++ ) {
90+
for ( ; i < N; i++ ) {
7691
v = x[ ix ];
7792
t = float64ToFloat32( s + v );
7893
if ( abs( s ) >= abs( v ) ) {

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,23 @@ void API_SUFFIX(stdlib_strided_scusumkbn_ndarray)( const CBLAS_INT N, const floa
8080
ix = offsetX;
8181
iy = offsetY;
8282
s = sum;
83+
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 ( s == 0.0 ) {
86+
for ( i = 0; i < N; i++ ) {
87+
v = X[ ix ];
88+
if ( v != 0.0f ) {
89+
break;
90+
}
91+
Y[ iy ] = s + v;
92+
ix += strideX;
93+
iy += strideY;
94+
}
95+
} else {
96+
i = 0;
97+
}
8398
c = 0.0f;
84-
for ( i = 0; i < N; i++ ) {
99+
for ( ; i < N; i++ ) {
85100
v = X[ ix ];
86101
t = s + v;
87102
if ( stdlib_base_absf( s ) >= stdlib_base_absf( v ) ) {

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

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

2323
var tape = require( 'tape' );
2424
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
25+
var isSameFloat32Array = require( '@stdlib/assert/is-same-float32array' );
2526
var Float32Array = require( '@stdlib/array/float32' );
2627
var scusumkbn = require( './../lib/ndarray.js' );
2728

@@ -126,6 +127,26 @@ tape( 'the function calculates the cumulative sum', function test( t ) {
126127
t.end();
127128
});
128129

130+
tape( 'the function preserves the sign of zero', function test( t ) {
131+
var expected;
132+
var x;
133+
var y;
134+
135+
x = new Float32Array( [ -0.0, -0.0, -0.0, 0.0, 1.0 ] );
136+
y = new Float32Array( x.length );
137+
138+
scusumkbn( x.length, -0.0, x, 1, 0, y, 1, 0 );
139+
expected = new Float32Array([
140+
-0.0,
141+
-0.0,
142+
-0.0,
143+
0.0,
144+
1.0
145+
]);
146+
t.strictEqual( isSameFloat32Array( y, expected ), true, 'returns expected value' );
147+
t.end();
148+
});
149+
129150
tape( 'the function returns a reference to the output array', function test( t ) {
130151
var out;
131152
var x;

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

Lines changed: 21 additions & 0 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 isnanf = require( '@stdlib/math/base/assert/is-nanf' );
26+
var isSameFloat32Array = require( '@stdlib/assert/is-same-float32array' );
2627
var Float32Array = require( '@stdlib/array/float32' );
2728
var tryRequire = require( '@stdlib/utils/try-require' );
2829

@@ -135,6 +136,26 @@ tape( 'the function calculates the cumulative sum', opts, function test( t ) {
135136
t.end();
136137
});
137138

139+
tape( 'the function preserves the sign of zero', opts, function test( t ) {
140+
var expected;
141+
var x;
142+
var y;
143+
144+
x = new Float32Array( [ -0.0, -0.0, -0.0, 0.0, 1.0 ] );
145+
y = new Float32Array( x.length );
146+
147+
scusumkbn( x.length, -0.0, x, 1, 0, y, 1, 0 );
148+
expected = new Float32Array([
149+
-0.0,
150+
-0.0,
151+
-0.0,
152+
0.0,
153+
1.0
154+
]);
155+
t.strictEqual( isSameFloat32Array( y, expected ), true, 'returns expected value' );
156+
t.end();
157+
});
158+
138159
tape( 'the function returns a reference to the output array', opts, function test( t ) {
139160
var out;
140161
var x;

0 commit comments

Comments
 (0)