From b7ae2b1c7057700ea39e13c793ddbe20ffb6f299 Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Thu, 20 Aug 2026 14:14:24 +0000 Subject: [PATCH 1/5] fix: avoid intermediate overflow across `stats/base/dists` Propagates fix from 76d80cc4 ("fix: avoid overflow in `stats/base/dists/wald/logpdf`") to sibling distribution functions exhibiting the same defect: normalizing a deviate by its scale parameter only after squaring, so that intermediate products overflow or underflow and the function returns NaN where the true double-precision value is representable. Normalizing before squaring and regrouping the surrounding quotients repairs, e.g., wald/pdf( 1e-200, 1e-200, 1.0 ), normal/pdf( 1e200, 0.0, 1e200 ), lognormal/logpdf( 1.0, -1e200, 1e200 ) and halfnormal/logpdf( 1e200, 1e195 ), each of which previously returned NaN. Ordinary inputs are unchanged to within a few ULP, and all existing R and Julia fixture assertions continue to pass. Affected packages: wald/pdf, normal/pdf, normal/logpdf, lognormal/pdf, lognormal/logpdf, truncated-normal/pdf, halfnormal/logpdf. --- .../stats/base/dists/halfnormal/logpdf/lib/factory.js | 6 +++--- .../stats/base/dists/halfnormal/logpdf/lib/main.js | 4 +++- .../@stdlib/stats/base/dists/halfnormal/logpdf/src/main.c | 4 +++- .../stats/base/dists/lognormal/logpdf/lib/factory.js | 8 ++------ .../@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js | 8 ++------ .../@stdlib/stats/base/dists/lognormal/logpdf/src/main.c | 8 ++------ .../@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js | 8 ++------ .../@stdlib/stats/base/dists/lognormal/pdf/lib/main.js | 8 ++------ .../@stdlib/stats/base/dists/lognormal/pdf/src/main.c | 6 ++---- .../@stdlib/stats/base/dists/normal/logpdf/lib/factory.js | 6 +----- .../@stdlib/stats/base/dists/normal/logpdf/lib/main.js | 6 +----- .../@stdlib/stats/base/dists/normal/logpdf/src/main.c | 6 +----- .../@stdlib/stats/base/dists/normal/pdf/lib/factory.js | 8 ++------ .../@stdlib/stats/base/dists/normal/pdf/lib/main.js | 8 ++------ .../@stdlib/stats/base/dists/normal/pdf/src/main.c | 8 ++------ .../stats/base/dists/truncated-normal/pdf/lib/factory.js | 8 ++------ .../stats/base/dists/truncated-normal/pdf/lib/main.js | 8 ++------ .../@stdlib/stats/base/dists/wald/pdf/lib/factory.js | 6 +++--- .../@stdlib/stats/base/dists/wald/pdf/lib/main.js | 6 +++--- .../@stdlib/stats/base/dists/wald/pdf/src/main.c | 6 +++--- 20 files changed, 43 insertions(+), 93 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/factory.js index 433044e3ab0a..edfa8a299c52 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/factory.js @@ -49,7 +49,6 @@ var C = 0.5 * ( LN2 - LNPI ); */ function factory( sigma ) { var lsigma; - var sigma2; if ( isnan( sigma ) || sigma <= 0.0 @@ -57,7 +56,6 @@ function factory( sigma ) { return constantFunction( NaN ); } lsigma = ln( sigma ); - sigma2 = sigma * sigma; return logpdf; /** @@ -72,13 +70,15 @@ function factory( sigma ) { * // returns */ function logpdf( x ) { + var v; if ( isnan( x ) ) { return NaN; } if ( x < 0.0 ) { return NINF; } - return C - lsigma - ( (x*x) / ( 2.0 * sigma2 ) ); + v = x / sigma; + return C - lsigma - ( (v*v) / 2.0 ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/main.js index d0a9ff5be121..cc83fdc7d1bd 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/lib/main.js @@ -76,6 +76,7 @@ var C = 0.5 * ( LN2 - LNPI ); * // returns NaN */ function logpdf( x, sigma ) { + var v; if ( isnan( x ) || isnan( sigma ) || @@ -86,7 +87,8 @@ function logpdf( x, sigma ) { if ( x < 0.0 ) { return NINF; } - return C - ln( sigma ) - ( (x*x) / ( 2.0 * (sigma*sigma) ) ); + v = x / sigma; + return C - ln( sigma ) - ( (v*v) / 2.0 ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/src/main.c index fce0b2e9256e..2bd046194f48 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/halfnormal/logpdf/src/main.c @@ -38,6 +38,7 @@ static const double C = 0.5 * ( STDLIB_CONSTANT_FLOAT64_LN2 - STDLIB_CONSTANT_FL * // returns ~-0.546 */ double stdlib_base_dists_halfnormal_logpdf( const double x, const double sigma ) { + double v; if ( stdlib_base_is_nan( x ) || stdlib_base_is_nan( sigma ) || @@ -48,5 +49,6 @@ double stdlib_base_dists_halfnormal_logpdf( const double x, const double sigma ) if ( x < 0.0 ) { return STDLIB_CONSTANT_FLOAT64_NINF; } - return C - stdlib_base_ln( sigma ) - ( (x*x) / ( 2.0 * (sigma*sigma) ) ); + v = x / sigma; + return C - stdlib_base_ln( sigma ) - ( (v*v) / 2.0 ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js index b958366b3fae..2e348eefc8b6 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js @@ -46,9 +46,7 @@ var PI = require( '@stdlib/constants/float64/pi' ); * // returns ~-3.672 */ function factory( mu, sigma ) { - var s2; var A; - var B; if ( isnan( mu ) || isnan( sigma ) || @@ -56,9 +54,7 @@ function factory( mu, sigma ) { ) { return constantFunction( NaN ); } - s2 = pow( sigma, 2.0 ); - A = -0.5 * ln( 2.0 * s2 * PI ); - B = -1.0 / ( 2.0 * s2 ); + A = ( -0.5 * ln( 2.0 * PI ) ) - ln( sigma ); return logpdf; /** @@ -79,7 +75,7 @@ function factory( mu, sigma ) { if ( x <= 0.0 ) { return NINF; } - return A - ln( x ) + ( B * pow( ln(x) - mu, 2.0 ) ); + return A - ln( x ) - ( 0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js index 0749d31da819..653518494df9 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js @@ -71,9 +71,7 @@ var PI = require( '@stdlib/constants/float64/pi' ); * // returns NaN */ function logpdf( x, mu, sigma ) { - var s2; var A; - var B; if ( isnan( x ) || isnan( mu ) || @@ -85,10 +83,8 @@ function logpdf( x, mu, sigma ) { if ( x <= 0.0 ) { return NINF; } - s2 = pow( sigma, 2.0 ); - A = -0.5 * ln( 2.0 * s2 * PI ); - B = -1.0 / ( 2.0 * s2 ); - return A - ln( x ) + ( B * pow( ln(x) - mu, 2.0 ) ); + A = ( -0.5 * ln( 2.0 * PI ) ) - ln( sigma ); + return A - ln( x ) - ( 0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c index 310e71488243..3af792a3689a 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c @@ -37,9 +37,7 @@ */ double stdlib_base_dists_lognormal_logpdf( const double x, const double mu, const double sigma ) { double lnx; - double s2; double A; - double B; if ( stdlib_base_is_nan( x ) || @@ -52,9 +50,7 @@ double stdlib_base_dists_lognormal_logpdf( const double x, const double mu, cons if ( x <= 0.0 ) { return STDLIB_CONSTANT_FLOAT64_NINF; } - s2 = stdlib_base_pow( sigma, 2.0 ); lnx = stdlib_base_ln( x ); - A = -0.5 * stdlib_base_ln( 2.0 * s2 * STDLIB_CONSTANT_FLOAT64_PI ); - B = -1.0 / ( 2.0 * s2 ); - return A - lnx + ( B * stdlib_base_pow( lnx - mu, 2.0 ) ); + A = ( -0.5 * stdlib_base_ln( 2.0 * STDLIB_CONSTANT_FLOAT64_PI ) ) - stdlib_base_ln( sigma ); + return A - lnx - ( 0.5 * stdlib_base_pow( ( lnx - mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js index 0a67d308ed6b..946e6f6f3ddf 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js @@ -47,9 +47,7 @@ var PI = require( '@stdlib/constants/float64/pi' ); * // returns ~0.025 */ function factory( mu, sigma ) { - var s2; var A; - var B; if ( isnan( mu ) || isnan( sigma ) || @@ -57,9 +55,7 @@ function factory( mu, sigma ) { ) { return constantFunction( NaN ); } - s2 = pow( sigma, 2.0 ); - A = 1.0 / ( sqrt( 2.0 * s2 * PI ) ); - B = -1.0 / ( 2.0 * s2 ); + A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); return pdf; /** @@ -80,7 +76,7 @@ function factory( mu, sigma ) { if ( x <= 0.0 ) { return 0.0; } - return (1.0/x) * A * exp( B * pow( ln(x) - mu, 2.0 ) ); + return (1.0/x) * A * exp( -0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js index 45aec9384530..0e221513fd55 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js @@ -72,9 +72,7 @@ var PI = require( '@stdlib/constants/float64/pi' ); * // returns NaN */ function pdf( x, mu, sigma ) { - var s2; var A; - var B; if ( isnan( x ) || isnan( mu ) || @@ -86,10 +84,8 @@ function pdf( x, mu, sigma ) { if ( x <= 0.0 ) { return 0.0; } - s2 = pow( sigma, 2.0 ); - A = 1.0 / ( sqrt( 2.0 * s2 * PI ) ); - B = -1.0 / ( 2.0 * s2 ); - return (1.0/x) * A * exp( B * pow( ln(x) - mu, 2.0 ) ); + A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); + return (1.0/x) * A * exp( -0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c index f1e2f994c64e..189ce29b7003 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c @@ -39,7 +39,6 @@ double stdlib_base_dists_lognormal_pdf( const double x, const double mu, const double sigma ) { double exp_value; double lnx_u; - double s2; double z; double y; if ( @@ -53,9 +52,8 @@ double stdlib_base_dists_lognormal_pdf( const double x, const double mu, const d if ( x <= 0.0 ) { return 0.0; } - s2 = stdlib_base_pow( sigma, 2.0 ); - lnx_u = stdlib_base_pow( ( stdlib_base_ln( x ) - mu ), 2.0 ); - z = -lnx_u / ( 2.0 * s2 ); + lnx_u = stdlib_base_pow( ( stdlib_base_ln( x ) - mu ) / sigma, 2.0 ); + z = -0.5 * lnx_u; exp_value = stdlib_base_exp( z ); y = 1.0 / ( x * sigma * stdlib_base_sqrt( 2.0 * STDLIB_CONSTANT_FLOAT64_PI ) ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js index 0db82b30d052..8622980e456a 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js @@ -46,9 +46,7 @@ var ln = require( '@stdlib/math/base/special/ln' ); * // returns ~-4.737 */ function factory( mu, sigma ) { - var s2; var A; - var B; if ( isnan( mu ) || isnan( sigma ) || @@ -59,9 +57,7 @@ function factory( mu, sigma ) { if ( sigma === 0.0 ) { return degenerate( mu ); } - s2 = pow( sigma, 2.0 ); A = (-0.5) * ( ( 2.0*ln( sigma ) ) + LN_TWO_PI ); - B = -1.0 / ( 2.0*s2 ); return logpdf; /** @@ -76,7 +72,7 @@ function factory( mu, sigma ) { * // returns */ function logpdf( x ) { - return A + ( B * pow( x-mu, 2.0 ) ); + return A - ( 0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js index b42945dc60ec..1a5023a00eab 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js @@ -72,9 +72,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); * // returns Infinity */ function logpdf( x, mu, sigma ) { - var s2; var A; - var B; if ( isnan( x ) || isnan( mu ) || @@ -86,10 +84,8 @@ function logpdf( x, mu, sigma ) { if ( sigma === 0.0 ) { return ( x === mu ) ? PINF : NINF; } - s2 = pow( sigma, 2.0 ); A = (-0.5) * ( ( 2.0*ln( sigma ) ) + LN_TWO_PI ); - B = -1.0 / ( 2.0*s2 ); - return A + ( B * pow( x-mu, 2.0 ) ); + return A - ( 0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c index 99ed1fd3c4ae..ddf3a0cf0deb 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c @@ -37,9 +37,7 @@ * // returns ~-2.919 */ double stdlib_base_dists_normal_logpdf( const double x, const double mu, const double sigma ) { - double s2; double A; - double B; if ( stdlib_base_is_nan( x ) || @@ -52,8 +50,6 @@ double stdlib_base_dists_normal_logpdf( const double x, const double mu, const d if ( sigma == 0.0 ) { return (x == mu) ? STDLIB_CONSTANT_FLOAT64_PINF : STDLIB_CONSTANT_FLOAT64_NINF; } - s2 = stdlib_base_pow( sigma, 2.0 ); A = (-0.5) * ( ( 2.0 * stdlib_base_ln(sigma) ) + STDLIB_CONSTANT_FLOAT64_LN_TWO_PI ); - B = -1.0 / ( 2.0 * s2 ); - return A + ( B * stdlib_base_pow( x - mu, 2.0 ) ); + return A - ( 0.5 * stdlib_base_pow( ( x - mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js index 4dcdb8846cf7..8b2674d28229 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js @@ -47,9 +47,7 @@ var TWO_PI = require( '@stdlib/constants/float64/two-pi' ); * // returns ~0.009 */ function factory( mu, sigma ) { - var s2; var A; - var B; if ( isnan( mu ) || isnan( sigma ) || @@ -60,9 +58,7 @@ function factory( mu, sigma ) { if ( sigma === 0.0 ) { return degenerate( mu ); } - s2 = pow( sigma, 2.0 ); - A = 1.0 / sqrt( s2*TWO_PI ); - B = -1.0 / ( 2.0*s2 ); + A = 1.0 / ( sigma * sqrt( TWO_PI ) ); return pdf; /** @@ -80,7 +76,7 @@ function factory( mu, sigma ) { if ( isnan( x ) ) { return NaN; } - return A * exp( B * pow(x-mu, 2.0) ); + return A * exp( -0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js index 9821ea17faa2..e619c4b20622 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js @@ -72,9 +72,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); * // returns Infinity */ function pdf( x, mu, sigma ) { - var s2; var A; - var B; if ( isnan( x ) || isnan( mu ) || @@ -86,10 +84,8 @@ function pdf( x, mu, sigma ) { if ( sigma === 0.0 ) { return ( x === mu ) ? PINF : 0.0; } - s2 = pow( sigma, 2.0 ); - A = 1.0 / sqrt( s2*TWO_PI ); - B = -1.0 / ( 2.0*s2 ); - return A * exp( B * pow(x-mu, 2.0) ); + A = 1.0 / ( sigma * sqrt( TWO_PI ) ); + return A * exp( -0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c index c871049729e6..d88221955b3e 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c @@ -37,9 +37,7 @@ * // returns ~0.054 */ double stdlib_base_dists_normal_pdf( const double x, const double mu, const double sigma ) { - double s2; double A; - double B; if ( stdlib_base_is_nan( x ) || stdlib_base_is_nan( mu ) || @@ -51,8 +49,6 @@ double stdlib_base_dists_normal_pdf( const double x, const double mu, const doub if ( sigma == 0.0 ) { return ( x == mu ) ? STDLIB_CONSTANT_FLOAT64_PINF : 0.0; } - s2 = stdlib_base_pow( sigma, 2.0 ); - A = 1.0 / stdlib_base_sqrt( s2 * STDLIB_CONSTANT_FLOAT64_TWO_PI ); - B = -1.0 / ( 2.0 * s2 ); - return A * stdlib_base_exp( B * stdlib_base_pow( x - mu, 2.0 ) ); + A = 1.0 / ( sigma * stdlib_base_sqrt( STDLIB_CONSTANT_FLOAT64_TWO_PI ) ); + return A * stdlib_base_exp( -0.5 * stdlib_base_pow( ( x - mu ) / sigma, 2.0 ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js index 551a56c7110f..9283cec9faf2 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js @@ -66,9 +66,7 @@ var normalCDF = normal( 0.0, 1.0 ); * // returns 0.0 */ function factory( a, b, mu, sigma ) { - var s2x2; var A; - var B; var C; if ( @@ -81,9 +79,7 @@ function factory( a, b, mu, sigma ) { ) { return constantFunction( NaN ); } - s2x2 = 2.0 * pow( sigma, 2.0 ); - A = 1.0 / ( sqrt( s2x2 * PI ) ); - B = -1.0 / ( s2x2 ); + A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); C = normalCDF( (b-mu)/sigma ) - normalCDF( (a-mu)/sigma ); return pdf; @@ -101,7 +97,7 @@ function factory( a, b, mu, sigma ) { if ( x < a || x > b ) { return 0.0; } - return A * exp( B * pow( x - mu, 2.0 ) ) / C; + return A * exp( -0.5 * pow( ( x - mu ) / sigma, 2.0 ) ) / C; } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js index 236211d53c5d..9ae8a3e8354b 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js @@ -66,9 +66,7 @@ var normalCDF = normal( 0.0, 1.0 ); * // returns 0.0 */ function pdf( x, a, b, mu, sigma ) { - var s2x2; var A; - var B; var C; if ( @@ -83,11 +81,9 @@ function pdf( x, a, b, mu, sigma ) { if ( x < a || x > b ) { return 0.0; } - s2x2 = 2.0 * pow( sigma, 2.0 ); - A = 1.0 / ( sqrt( s2x2 * PI ) ); - B = -1.0 / ( s2x2 ); + A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); C = normalCDF( (b-mu)/sigma ) - normalCDF( (a-mu)/sigma ); - return A * exp( B * pow( x - mu, 2.0 ) ) / C; + return A * exp( -0.5 * pow( ( x - mu ) / sigma, 2.0 ) ) / C; } diff --git a/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/factory.js index 26ef7a8a4046..b8f2e3923bc5 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/factory.js @@ -60,7 +60,7 @@ function factory( mu, lambda ) { return degenerate( mu ); } A = sqrt( lambda / TWO_PI ); - B = -lambda / ( 2.0 * mu * mu ); + B = -0.5 * lambda; return pdf; /** @@ -82,8 +82,8 @@ function factory( mu, lambda ) { if ( x <= 0.0 || !isFinite( x ) ) { return 0.0; } - v = x - mu; - return A / ( x * sqrt( x ) ) * exp( B * v * v / x ); + v = ( x - mu ) / mu; + return A / ( x * sqrt( x ) ) * exp( ( ( B / x ) * v ) * v ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/main.js index 2f6fca31a297..b3afbda20390 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/lib/main.js @@ -109,9 +109,9 @@ function pdf( x, mu, lambda ) { return 0.0; } A = sqrt( lambda / TWO_PI ); - B = -lambda / ( 2.0 * mu * mu ); - v = x - mu; - return A / ( x * sqrt( x ) ) * exp( B * v * v / x ); + B = -0.5 * lambda; + v = ( x - mu ) / mu; + return A / ( x * sqrt( x ) ) * exp( ( ( B / x ) * v ) * v ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/src/main.c index 63cf95e435e3..99877f48a195 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/src/main.c @@ -56,7 +56,7 @@ double stdlib_base_dists_wald_pdf( const double x, const double mu, const double return 0.0; } A = stdlib_base_sqrt( lambda / STDLIB_CONSTANT_FLOAT64_TWO_PI ); - B = -lambda / ( 2.0 * mu * mu ); - v = x - mu; - return A / ( x * stdlib_base_sqrt( x ) ) * stdlib_base_exp( B * v * v / x ); + B = -0.5 * lambda; + v = ( x - mu ) / mu; + return A / ( x * stdlib_base_sqrt( x ) ) * stdlib_base_exp( ( ( B / x ) * v ) * v ); } From cb24c61a0667d3b3d6936c424e0bed6410e41551 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 00:07:59 +0000 Subject: [PATCH 2/5] refactor: use `abs2` for squaring in `stats/base/dists/*` densities Addresses review feedback on the propagation of 76d80cc4b: replace `pow( x, 2.0 )` with `abs2( x )` when squaring standardized values in the JavaScript implementations. C implementations retain `stdlib_base_pow` to avoid manifest dependency changes. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01DbLWivyEpdcK8DSErG9UjP --- .../@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js | 4 ++-- .../@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js | 4 ++-- .../@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js | 4 ++-- .../@stdlib/stats/base/dists/lognormal/pdf/lib/main.js | 4 ++-- .../@stdlib/stats/base/dists/normal/logpdf/lib/factory.js | 4 ++-- .../@stdlib/stats/base/dists/normal/logpdf/lib/main.js | 4 ++-- .../@stdlib/stats/base/dists/normal/pdf/lib/factory.js | 4 ++-- .../@stdlib/stats/base/dists/normal/pdf/lib/main.js | 4 ++-- .../stats/base/dists/truncated-normal/pdf/lib/factory.js | 4 ++-- .../@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js index 2e348eefc8b6..50cd38754b4e 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js @@ -22,7 +22,7 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); var NINF = require( '@stdlib/constants/float64/ninf' ); var PI = require( '@stdlib/constants/float64/pi' ); @@ -75,7 +75,7 @@ function factory( mu, sigma ) { if ( x <= 0.0 ) { return NINF; } - return A - ln( x ) - ( 0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); + return A - ln( x ) - ( 0.5 * abs2( ( ln(x) - mu ) / sigma ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js index 653518494df9..c07426a57730 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js @@ -21,7 +21,7 @@ // MODULES // var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); var NINF = require( '@stdlib/constants/float64/ninf' ); var PI = require( '@stdlib/constants/float64/pi' ); @@ -84,7 +84,7 @@ function logpdf( x, mu, sigma ) { return NINF; } A = ( -0.5 * ln( 2.0 * PI ) ) - ln( sigma ); - return A - ln( x ) - ( 0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); + return A - ln( x ) - ( 0.5 * abs2( ( ln(x) - mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js index 946e6f6f3ddf..1dbcd7afcedd 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js @@ -24,7 +24,7 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); var exp = require( '@stdlib/math/base/special/exp' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); var PI = require( '@stdlib/constants/float64/pi' ); @@ -76,7 +76,7 @@ function factory( mu, sigma ) { if ( x <= 0.0 ) { return 0.0; } - return (1.0/x) * A * exp( -0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); + return (1.0/x) * A * exp( -0.5 * abs2( ( ln(x) - mu ) / sigma ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js index 0e221513fd55..c6d264cfab62 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js @@ -23,7 +23,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); var exp = require( '@stdlib/math/base/special/exp' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); var PI = require( '@stdlib/constants/float64/pi' ); @@ -85,7 +85,7 @@ function pdf( x, mu, sigma ) { return 0.0; } A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); - return (1.0/x) * A * exp( -0.5 * pow( ( ln(x) - mu ) / sigma, 2.0 ) ); + return (1.0/x) * A * exp( -0.5 * abs2( ( ln(x) - mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js index 8622980e456a..d4294b7d9334 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/factory.js @@ -24,7 +24,7 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var degenerate = require( '@stdlib/stats/base/dists/degenerate/logpdf' ).factory; var LN_TWO_PI = require( '@stdlib/constants/float64/ln-two-pi' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); @@ -72,7 +72,7 @@ function factory( mu, sigma ) { * // returns */ function logpdf( x ) { - return A - ( 0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); + return A - ( 0.5 * abs2( ( x-mu ) / sigma ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js index 1a5023a00eab..0e45c1ffb33b 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/lib/main.js @@ -21,7 +21,7 @@ // MODULES // var ln = require( '@stdlib/math/base/special/ln' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var LN_TWO_PI = require( '@stdlib/constants/float64/ln-two-pi' ); var NINF = require( '@stdlib/constants/float64/ninf' ); var PINF = require( '@stdlib/constants/float64/pinf' ); @@ -85,7 +85,7 @@ function logpdf( x, mu, sigma ) { return ( x === mu ) ? PINF : NINF; } A = (-0.5) * ( ( 2.0*ln( sigma ) ) + LN_TWO_PI ); - return A - ( 0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); + return A - ( 0.5 * abs2( ( x-mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js index 8b2674d28229..2ea60983882a 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js @@ -25,7 +25,7 @@ var degenerate = require( '@stdlib/stats/base/dists/degenerate/pdf' ).factory; var isnan = require( '@stdlib/math/base/assert/is-nan' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); var exp = require( '@stdlib/math/base/special/exp' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var TWO_PI = require( '@stdlib/constants/float64/two-pi' ); @@ -76,7 +76,7 @@ function factory( mu, sigma ) { if ( isnan( x ) ) { return NaN; } - return A * exp( -0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); + return A * exp( -0.5 * abs2( ( x-mu ) / sigma ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js index e619c4b20622..406936f75771 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js @@ -21,7 +21,7 @@ // MODULES // var exp = require( '@stdlib/math/base/special/exp' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); var TWO_PI = require( '@stdlib/constants/float64/two-pi' ); var PINF = require( '@stdlib/constants/float64/pinf' ); @@ -85,7 +85,7 @@ function pdf( x, mu, sigma ) { return ( x === mu ) ? PINF : 0.0; } A = 1.0 / ( sigma * sqrt( TWO_PI ) ); - return A * exp( -0.5 * pow( ( x-mu ) / sigma, 2.0 ) ); + return A * exp( -0.5 * abs2( ( x-mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js index 9283cec9faf2..0680ed361741 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js @@ -22,7 +22,7 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var exp = require( '@stdlib/math/base/special/exp' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); var normal = require( '@stdlib/stats/base/dists/normal/cdf' ).factory; @@ -97,7 +97,7 @@ function factory( a, b, mu, sigma ) { if ( x < a || x > b ) { return 0.0; } - return A * exp( -0.5 * pow( ( x - mu ) / sigma, 2.0 ) ) / C; + return A * exp( -0.5 * abs2( ( x - mu ) / sigma ) ) / C; } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js index 9ae8a3e8354b..3dcf39e043f5 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js @@ -21,7 +21,7 @@ // MODULES // var exp = require( '@stdlib/math/base/special/exp' ); -var pow = require( '@stdlib/math/base/special/pow' ); +var abs2 = require( '@stdlib/math/base/special/abs2' ); var sqrt = require( '@stdlib/math/base/special/sqrt' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var normal = require( '@stdlib/stats/base/dists/normal/cdf' ).factory; @@ -83,7 +83,7 @@ function pdf( x, a, b, mu, sigma ) { } A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); C = normalCDF( (b-mu)/sigma ) - normalCDF( (a-mu)/sigma ); - return A * exp( -0.5 * pow( ( x - mu ) / sigma, 2.0 ) ) / C; + return A * exp( -0.5 * abs2( ( x - mu ) / sigma ) ) / C; } From 9fe65d032b410ff9c46b4062d6cea7d2ff48050f Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 00:10:56 +0000 Subject: [PATCH 3/5] refactor: use `LN_TWO_PI` and `SQRT_TWO_PI` constants in `stats/base/dists/*` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review feedback: replace computed `-0.5 * ln( 2.0 * PI )` with the `LN_TWO_PI` constant in `lognormal/logpdf` and, following the same principle, replace `sqrt( 2π )` prefactor computations with the `SQRT_TWO_PI` constant in `normal/pdf`, `lognormal/pdf`, and `truncated-normal/pdf` JavaScript implementations. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01DbLWivyEpdcK8DSErG9UjP --- .../@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js | 4 ++-- .../@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js | 4 ++-- .../@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js | 5 ++--- .../@stdlib/stats/base/dists/lognormal/pdf/lib/main.js | 5 ++--- .../@stdlib/stats/base/dists/normal/pdf/lib/factory.js | 5 ++--- .../@stdlib/stats/base/dists/normal/pdf/lib/main.js | 5 ++--- .../stats/base/dists/truncated-normal/pdf/lib/factory.js | 5 ++--- .../stats/base/dists/truncated-normal/pdf/lib/main.js | 5 ++--- 8 files changed, 16 insertions(+), 22 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js index 50cd38754b4e..ca3d6d93c100 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js @@ -25,7 +25,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); var NINF = require( '@stdlib/constants/float64/ninf' ); -var PI = require( '@stdlib/constants/float64/pi' ); +var LN_TWO_PI = require( '@stdlib/constants/float64/ln-two-pi' ); // MAIN // @@ -54,7 +54,7 @@ function factory( mu, sigma ) { ) { return constantFunction( NaN ); } - A = ( -0.5 * ln( 2.0 * PI ) ) - ln( sigma ); + A = ( -0.5 * LN_TWO_PI ) - ln( sigma ); return logpdf; /** diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js index c07426a57730..88afc4f09acb 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js @@ -24,7 +24,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); var NINF = require( '@stdlib/constants/float64/ninf' ); -var PI = require( '@stdlib/constants/float64/pi' ); +var LN_TWO_PI = require( '@stdlib/constants/float64/ln-two-pi' ); // MAIN // @@ -83,7 +83,7 @@ function logpdf( x, mu, sigma ) { if ( x <= 0.0 ) { return NINF; } - A = ( -0.5 * ln( 2.0 * PI ) ) - ln( sigma ); + A = ( -0.5 * LN_TWO_PI ) - ln( sigma ); return A - ln( x ) - ( 0.5 * abs2( ( ln(x) - mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js index 1dbcd7afcedd..5b14c2e9aad2 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/factory.js @@ -22,11 +22,10 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var sqrt = require( '@stdlib/math/base/special/sqrt' ); var exp = require( '@stdlib/math/base/special/exp' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); -var PI = require( '@stdlib/constants/float64/pi' ); +var SQRT_TWO_PI = require( '@stdlib/constants/float64/sqrt-two-pi' ); // MAIN // @@ -55,7 +54,7 @@ function factory( mu, sigma ) { ) { return constantFunction( NaN ); } - A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); + A = 1.0 / ( sigma * SQRT_TWO_PI ); return pdf; /** diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js index c6d264cfab62..27b61e4c7720 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/lib/main.js @@ -21,11 +21,10 @@ // MODULES // var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var sqrt = require( '@stdlib/math/base/special/sqrt' ); var exp = require( '@stdlib/math/base/special/exp' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); var ln = require( '@stdlib/math/base/special/ln' ); -var PI = require( '@stdlib/constants/float64/pi' ); +var SQRT_TWO_PI = require( '@stdlib/constants/float64/sqrt-two-pi' ); // MAIN // @@ -84,7 +83,7 @@ function pdf( x, mu, sigma ) { if ( x <= 0.0 ) { return 0.0; } - A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); + A = 1.0 / ( sigma * SQRT_TWO_PI ); return (1.0/x) * A * exp( -0.5 * abs2( ( ln(x) - mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js index 2ea60983882a..c7b55b915622 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/factory.js @@ -23,10 +23,9 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var degenerate = require( '@stdlib/stats/base/dists/degenerate/pdf' ).factory; var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var sqrt = require( '@stdlib/math/base/special/sqrt' ); var exp = require( '@stdlib/math/base/special/exp' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); -var TWO_PI = require( '@stdlib/constants/float64/two-pi' ); +var SQRT_TWO_PI = require( '@stdlib/constants/float64/sqrt-two-pi' ); // MAIN // @@ -58,7 +57,7 @@ function factory( mu, sigma ) { if ( sigma === 0.0 ) { return degenerate( mu ); } - A = 1.0 / ( sigma * sqrt( TWO_PI ) ); + A = 1.0 / ( sigma * SQRT_TWO_PI ); return pdf; /** diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js index 406936f75771..a82e95c9a88e 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/lib/main.js @@ -22,8 +22,7 @@ var exp = require( '@stdlib/math/base/special/exp' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); -var sqrt = require( '@stdlib/math/base/special/sqrt' ); -var TWO_PI = require( '@stdlib/constants/float64/two-pi' ); +var SQRT_TWO_PI = require( '@stdlib/constants/float64/sqrt-two-pi' ); var PINF = require( '@stdlib/constants/float64/pinf' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); @@ -84,7 +83,7 @@ function pdf( x, mu, sigma ) { if ( sigma === 0.0 ) { return ( x === mu ) ? PINF : 0.0; } - A = 1.0 / ( sigma * sqrt( TWO_PI ) ); + A = 1.0 / ( sigma * SQRT_TWO_PI ); return A * exp( -0.5 * abs2( ( x-mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js index 0680ed361741..3fd133fa8007 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/factory.js @@ -24,9 +24,8 @@ var constantFunction = require( '@stdlib/utils/constant-function' ); var exp = require( '@stdlib/math/base/special/exp' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); -var sqrt = require( '@stdlib/math/base/special/sqrt' ); var normal = require( '@stdlib/stats/base/dists/normal/cdf' ).factory; -var PI = require( '@stdlib/constants/float64/pi' ); +var SQRT_TWO_PI = require( '@stdlib/constants/float64/sqrt-two-pi' ); // VARIABLES // @@ -79,7 +78,7 @@ function factory( a, b, mu, sigma ) { ) { return constantFunction( NaN ); } - A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); + A = 1.0 / ( sigma * SQRT_TWO_PI ); C = normalCDF( (b-mu)/sigma ) - normalCDF( (a-mu)/sigma ); return pdf; diff --git a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js index 3dcf39e043f5..ac390d8251cc 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/truncated-normal/pdf/lib/main.js @@ -22,10 +22,9 @@ var exp = require( '@stdlib/math/base/special/exp' ); var abs2 = require( '@stdlib/math/base/special/abs2' ); -var sqrt = require( '@stdlib/math/base/special/sqrt' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var normal = require( '@stdlib/stats/base/dists/normal/cdf' ).factory; -var PI = require( '@stdlib/constants/float64/pi' ); +var SQRT_TWO_PI = require( '@stdlib/constants/float64/sqrt-two-pi' ); // VARIABLES // @@ -81,7 +80,7 @@ function pdf( x, a, b, mu, sigma ) { if ( x < a || x > b ) { return 0.0; } - A = 1.0 / ( sigma * sqrt( 2.0 * PI ) ); + A = 1.0 / ( sigma * SQRT_TWO_PI ); C = normalCDF( (b-mu)/sigma ) - normalCDF( (a-mu)/sigma ); return A * exp( -0.5 * abs2( ( x - mu ) / sigma ) ) / C; } From f8d5cf68689c99e356eccc13cf15c95b82f80991 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 00:12:46 +0000 Subject: [PATCH 4/5] refactor: use `abs2` and constants in C implementations Addresses review feedback: mirror the JavaScript changes in the C implementations of `normal/pdf`, `normal/logpdf`, `lognormal/pdf`, and `lognormal/logpdf` by using `stdlib_base_abs2` for squaring and the `LN_TWO_PI`/`SQRT_TWO_PI` constants, with corresponding manifest dependency updates. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01DbLWivyEpdcK8DSErG9UjP --- .../base/dists/lognormal/logpdf/manifest.json | 12 ++++++------ .../stats/base/dists/lognormal/logpdf/src/main.c | 8 ++++---- .../stats/base/dists/lognormal/pdf/manifest.json | 15 ++++++--------- .../stats/base/dists/lognormal/pdf/src/main.c | 9 ++++----- .../stats/base/dists/normal/logpdf/manifest.json | 6 +++--- .../stats/base/dists/normal/logpdf/src/main.c | 4 ++-- .../stats/base/dists/normal/pdf/manifest.json | 15 ++++++--------- .../stats/base/dists/normal/pdf/src/main.c | 9 ++++----- 8 files changed, 35 insertions(+), 43 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/manifest.json b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/manifest.json index 9e8f2feb817a..335b608a0857 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/manifest.json +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/manifest.json @@ -40,10 +40,10 @@ "dependencies": [ "@stdlib/math/base/napi/ternary", "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/ln", "@stdlib/constants/float64/ninf", - "@stdlib/constants/float64/pi" + "@stdlib/constants/float64/ln-two-pi" ] }, { @@ -59,11 +59,11 @@ "libpath": [], "dependencies": [ "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/ln", "@stdlib/constants/float64/ninf", "@stdlib/constants/float64/eps", - "@stdlib/constants/float64/pi" + "@stdlib/constants/float64/ln-two-pi" ] }, { @@ -79,10 +79,10 @@ "libpath": [], "dependencies": [ "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/ln", "@stdlib/constants/float64/ninf", - "@stdlib/constants/float64/pi" + "@stdlib/constants/float64/ln-two-pi" ] } ] diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c index 3af792a3689a..46e213e080e1 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/src/main.c @@ -18,10 +18,10 @@ #include "stdlib/stats/base/dists/lognormal/logpdf.h" #include "stdlib/math/base/assert/is_nan.h" -#include "stdlib/math/base/special/pow.h" +#include "stdlib/math/base/special/abs2.h" #include "stdlib/math/base/special/ln.h" #include "stdlib/constants/float64/ninf.h" -#include "stdlib/constants/float64/pi.h" +#include "stdlib/constants/float64/ln_two_pi.h" /** * Evaluates the natural logarithm of the probability density function (PDF) for a lognormal distribution with location parameter `mu` and scale parameter `sigma` at a value `x`. @@ -51,6 +51,6 @@ double stdlib_base_dists_lognormal_logpdf( const double x, const double mu, cons return STDLIB_CONSTANT_FLOAT64_NINF; } lnx = stdlib_base_ln( x ); - A = ( -0.5 * stdlib_base_ln( 2.0 * STDLIB_CONSTANT_FLOAT64_PI ) ) - stdlib_base_ln( sigma ); - return A - lnx - ( 0.5 * stdlib_base_pow( ( lnx - mu ) / sigma, 2.0 ) ); + A = ( -0.5 * STDLIB_CONSTANT_FLOAT64_LN_TWO_PI ) - stdlib_base_ln( sigma ); + return A - lnx - ( 0.5 * stdlib_base_abs2( ( lnx - mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/manifest.json b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/manifest.json index bec2ec21d922..af11707d0b85 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/manifest.json +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/manifest.json @@ -41,10 +41,9 @@ "@stdlib/math/base/napi/ternary", "@stdlib/math/base/assert/is-nan", "@stdlib/math/base/special/exp", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/ln", - "@stdlib/math/base/special/sqrt", - "@stdlib/constants/float64/pi" + "@stdlib/constants/float64/sqrt-two-pi" ] }, { @@ -62,10 +61,9 @@ "@stdlib/math/base/assert/is-nan", "@stdlib/constants/float64/eps", "@stdlib/math/base/special/exp", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/ln", - "@stdlib/math/base/special/sqrt", - "@stdlib/constants/float64/pi" + "@stdlib/constants/float64/sqrt-two-pi" ] }, { @@ -83,10 +81,9 @@ "@stdlib/math/base/assert/is-nan", "@stdlib/constants/float64/eps", "@stdlib/math/base/special/exp", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/ln", - "@stdlib/math/base/special/sqrt", - "@stdlib/constants/float64/pi" + "@stdlib/constants/float64/sqrt-two-pi" ] } ] diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c index 189ce29b7003..5a3d7a498123 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/pdf/src/main.c @@ -20,9 +20,8 @@ #include "stdlib/math/base/special/ln.h" #include "stdlib/math/base/assert/is_nan.h" #include "stdlib/math/base/special/exp.h" -#include "stdlib/math/base/special/pow.h" -#include "stdlib/math/base/special/sqrt.h" -#include "stdlib/constants/float64/pi.h" +#include "stdlib/math/base/special/abs2.h" +#include "stdlib/constants/float64/sqrt_two_pi.h" /** * Evaluates the PDF for a lognormal distribution with location `mu` and scale `sigma`. @@ -52,10 +51,10 @@ double stdlib_base_dists_lognormal_pdf( const double x, const double mu, const d if ( x <= 0.0 ) { return 0.0; } - lnx_u = stdlib_base_pow( ( stdlib_base_ln( x ) - mu ) / sigma, 2.0 ); + lnx_u = stdlib_base_abs2( ( stdlib_base_ln( x ) - mu ) / sigma ); z = -0.5 * lnx_u; exp_value = stdlib_base_exp( z ); - y = 1.0 / ( x * sigma * stdlib_base_sqrt( 2.0 * STDLIB_CONSTANT_FLOAT64_PI ) ); + y = 1.0 / ( x * sigma * STDLIB_CONSTANT_FLOAT64_SQRT_TWO_PI ); return y * exp_value; } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/manifest.json b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/manifest.json index a8682b1f4de8..5c0f38c7533a 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/manifest.json +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/manifest.json @@ -41,7 +41,7 @@ "@stdlib/math/base/napi/ternary", "@stdlib/math/base/assert/is-nan", "@stdlib/math/base/special/ln", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/constants/float64/ln-two-pi", "@stdlib/constants/float64/pinf", "@stdlib/constants/float64/ninf" @@ -61,7 +61,7 @@ "dependencies": [ "@stdlib/math/base/assert/is-nan", "@stdlib/math/base/special/ln", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/constants/float64/ln-two-pi", "@stdlib/constants/float64/pinf", "@stdlib/constants/float64/ninf" @@ -81,7 +81,7 @@ "dependencies": [ "@stdlib/math/base/assert/is-nan", "@stdlib/math/base/special/ln", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/constants/float64/ln-two-pi", "@stdlib/constants/float64/pinf", "@stdlib/constants/float64/ninf" diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c index ddf3a0cf0deb..54e621daedd7 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/logpdf/src/main.c @@ -19,7 +19,7 @@ #include "stdlib/stats/base/dists/normal/logpdf.h" #include "stdlib/math/base/assert/is_nan.h" #include "stdlib/math/base/special/ln.h" -#include "stdlib/math/base/special/pow.h" +#include "stdlib/math/base/special/abs2.h" #include "stdlib/constants/float64/ln_two_pi.h" #include "stdlib/constants/float64/ninf.h" #include "stdlib/constants/float64/pinf.h" @@ -51,5 +51,5 @@ double stdlib_base_dists_normal_logpdf( const double x, const double mu, const d return (x == mu) ? STDLIB_CONSTANT_FLOAT64_PINF : STDLIB_CONSTANT_FLOAT64_NINF; } A = (-0.5) * ( ( 2.0 * stdlib_base_ln(sigma) ) + STDLIB_CONSTANT_FLOAT64_LN_TWO_PI ); - return A - ( 0.5 * stdlib_base_pow( ( x - mu ) / sigma, 2.0 ) ); + return A - ( 0.5 * stdlib_base_abs2( ( x - mu ) / sigma ) ); } diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/manifest.json b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/manifest.json index 2dac8970622a..03210b36c3fa 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/manifest.json +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/manifest.json @@ -39,10 +39,9 @@ "libpath": [], "dependencies": [ "@stdlib/math/base/napi/ternary", - "@stdlib/constants/float64/two-pi", + "@stdlib/constants/float64/sqrt-two-pi", "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/sqrt", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/exp", "@stdlib/constants/float64/pinf" ] @@ -59,10 +58,9 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/constants/float64/two-pi", + "@stdlib/constants/float64/sqrt-two-pi", "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/sqrt", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/exp", "@stdlib/constants/float64/pinf", "@stdlib/constants/float64/eps" @@ -80,10 +78,9 @@ "libraries": [], "libpath": [], "dependencies": [ - "@stdlib/constants/float64/two-pi", + "@stdlib/constants/float64/sqrt-two-pi", "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/sqrt", - "@stdlib/math/base/special/pow", + "@stdlib/math/base/special/abs2", "@stdlib/math/base/special/exp", "@stdlib/constants/float64/pinf", "@stdlib/constants/float64/eps" diff --git a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c index d88221955b3e..4358e3dbd963 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/normal/pdf/src/main.c @@ -18,10 +18,9 @@ #include "stdlib/stats/base/dists/normal/pdf.h" #include "stdlib/math/base/assert/is_nan.h" -#include "stdlib/math/base/special/sqrt.h" -#include "stdlib/math/base/special/pow.h" +#include "stdlib/math/base/special/abs2.h" #include "stdlib/math/base/special/exp.h" -#include "stdlib/constants/float64/two_pi.h" +#include "stdlib/constants/float64/sqrt_two_pi.h" #include "stdlib/constants/float64/pinf.h" /** @@ -49,6 +48,6 @@ double stdlib_base_dists_normal_pdf( const double x, const double mu, const doub if ( sigma == 0.0 ) { return ( x == mu ) ? STDLIB_CONSTANT_FLOAT64_PINF : 0.0; } - A = 1.0 / ( sigma * stdlib_base_sqrt( STDLIB_CONSTANT_FLOAT64_TWO_PI ) ); - return A * stdlib_base_exp( -0.5 * stdlib_base_pow( ( x - mu ) / sigma, 2.0 ) ); + A = 1.0 / ( sigma * STDLIB_CONSTANT_FLOAT64_SQRT_TWO_PI ); + return A * stdlib_base_exp( -0.5 * stdlib_base_abs2( ( x - mu ) / sigma ) ); } From 739ba257588f0761db0d445c68f8abb0224312d4 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 00:14:27 +0000 Subject: [PATCH 5/5] refactor: avoid duplicate computation in `stats/base/dists/lognormal/logpdf` Addresses review feedback: compute `ln( x )` once and reuse via a temporary variable, mirroring the C implementation. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01DbLWivyEpdcK8DSErG9UjP --- .../@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js | 4 +++- .../@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js index ca3d6d93c100..4c2bf31b519d 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/factory.js @@ -69,13 +69,15 @@ function factory( mu, sigma ) { * // returns */ function logpdf( x ) { + var lnx; if ( isnan( x ) ) { return NaN; } if ( x <= 0.0 ) { return NINF; } - return A - ln( x ) - ( 0.5 * abs2( ( ln(x) - mu ) / sigma ) ); + lnx = ln( x ); + return A - lnx - ( 0.5 * abs2( ( lnx - mu ) / sigma ) ); } } diff --git a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js index 88afc4f09acb..1694898dfa5d 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/lognormal/logpdf/lib/main.js @@ -71,6 +71,7 @@ var LN_TWO_PI = require( '@stdlib/constants/float64/ln-two-pi' ); * // returns NaN */ function logpdf( x, mu, sigma ) { + var lnx; var A; if ( isnan( x ) || @@ -83,8 +84,9 @@ function logpdf( x, mu, sigma ) { if ( x <= 0.0 ) { return NINF; } + lnx = ln( x ); A = ( -0.5 * LN_TWO_PI ) - ln( sigma ); - return A - ln( x ) - ( 0.5 * abs2( ( ln(x) - mu ) / sigma ) ); + return A - lnx - ( 0.5 * abs2( ( lnx - mu ) / sigma ) ); }