Skip to content

Commit 308e19a

Browse files
committed
fix: reorder Wald mode evaluation to avoid catastrophic cancellation
1 parent 0150602 commit 308e19a

4 files changed

Lines changed: 8 additions & 8 deletions

File tree

lib/node_modules/@stdlib/stats/base/dists/wald/mode/lib/main.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ var sqrt = require( '@stdlib/math/base/special/sqrt' );
5454
* // returns NaN
5555
*/
5656
function mode( mu, lambda ) {
57-
var numerator;
57+
var r;
5858
if (
5959
isnan( mu ) ||
6060
isnan( lambda ) ||
@@ -63,8 +63,8 @@ function mode( mu, lambda ) {
6363
) {
6464
return NaN;
6565
}
66-
numerator = sqrt( 4.0*lambda*lambda + 9.0*mu*mu ) - 3.0*mu;
67-
return ( mu*numerator ) / ( 2.0*lambda );
66+
r = mu / lambda;
67+
return mu * ( sqrt( 1.0 + ( ( 3.0*r/2.0 ) * ( 3.0*r/2.0 ) ) ) - ( 3.0*r/2.0 ) );
6868
}
6969

7070

lib/node_modules/@stdlib/stats/base/dists/wald/mode/src/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* // returns ~0.325
3333
*/
3434
double stdlib_base_dists_wald_mode( const double mu, const double lambda ) {
35-
double numerator;
35+
double r;
3636
if (
3737
stdlib_base_is_nan( mu ) ||
3838
stdlib_base_is_nan( lambda ) ||
@@ -41,6 +41,6 @@ double stdlib_base_dists_wald_mode( const double mu, const double lambda ) {
4141
) {
4242
return 0.0/0.0; // NaN
4343
}
44-
numerator = stdlib_base_sqrt( 4.0*lambda*lambda + 9.0*mu*mu ) - 3.0*mu;
45-
return mu * numerator / ( 2.0*lambda );
44+
r = mu / lambda;
45+
return mu * ( stdlib_base_sqrt( 1.0 + ( ( 3.0*r/2.0 ) * ( 3.0*r/2.0 ) ) ) - ( 3.0*r/2.0 ) );
4646
}

lib/node_modules/@stdlib/stats/base/dists/wald/mode/test/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ tape( 'the function returns the mode of a Wald distribution', function test( t )
117117
if ( y === expected[i] ) {
118118
t.strictEqual( y, expected[i], 'mu:'+mu[i]+', lambda: '+lambda[i]+', y: '+y+', expected: '+expected[i] );
119119
} else {
120-
t.ok( isAlmostSameValue( y, expected[i], 1000 ), 'within tolerance. mu: '+mu[i]+'. lambda: '+lambda[i]+'. y: '+y+'. E: '+expected[ i ]+'.' );
120+
t.ok( isAlmostSameValue( y, expected[i], 2 ), 'within tolerance. mu: '+mu[i]+'. lambda: '+lambda[i]+'. y: '+y+'. E: '+expected[ i ]+'.' );
121121
}
122122
}
123123
t.end();

lib/node_modules/@stdlib/stats/base/dists/wald/mode/test/test.native.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ tape( 'the function returns the mode of a Wald distribution', opts, function tes
126126
if ( y === expected[i] ) {
127127
t.strictEqual( y, expected[i], 'mu:'+mu[i]+', lambda: '+lambda[i]+', y: '+y+', expected: '+expected[i] );
128128
} else {
129-
t.ok( isAlmostSameValue( y, expected[i], 1000 ), 'within tolerance. mu: '+mu[i]+'. lambda: '+lambda[i]+'. y: '+y+'. E: '+expected[ i ]+'.' );
129+
t.ok( isAlmostSameValue( y, expected[i], 2 ), 'within tolerance. mu: '+mu[i]+'. lambda: '+lambda[i]+'. y: '+y+'. E: '+expected[ i ]+'.' );
130130
}
131131
}
132132
t.end();

0 commit comments

Comments
 (0)