From fe8bbf17f4b9726fe383a214ed9dee8509c98f76 Mon Sep 17 00:00:00 2001 From: Abhist17 Date: Mon, 28 Sep 2026 04:39:17 +0530 Subject: [PATCH] fix: return the limiting density at `x = 0` in `stats/base/dists/log-logistic/pdf` `x <= 0` returned `0`, but the density `(beta/alpha) (x/alpha)^(beta-1) / (1+(x/alpha)^beta)^2` tends to `+Infinity`, `1/alpha`, or `0` at `x = 0` for `beta` less than, equal to, or greater than one. The documented example `pdf( 0.0, 1.0, 1.0 )` is the standard log-logistic, whose density `1/(1+x)^2` is `1` at `0`. --- .../base/dists/log-logistic/pdf/docs/repl.txt | 2 +- .../log-logistic/pdf/docs/types/index.d.ts | 2 +- .../dists/log-logistic/pdf/lib/factory.js | 10 ++++++++- .../base/dists/log-logistic/pdf/lib/main.js | 12 +++++++++-- .../base/dists/log-logistic/pdf/lib/native.js | 2 +- .../base/dists/log-logistic/pdf/manifest.json | 7 +++++-- .../base/dists/log-logistic/pdf/src/main.c | 10 ++++++++- .../log-logistic/pdf/test/test.factory.js | 21 +++++++++++++++---- .../log-logistic/pdf/test/test.native.js | 13 ++++++++---- .../dists/log-logistic/pdf/test/test.pdf.js | 13 ++++++++---- 10 files changed, 71 insertions(+), 21 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/repl.txt b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/repl.txt index 60bf56a476b1..4596f698787c 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/repl.txt +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/repl.txt @@ -33,7 +33,7 @@ > y = {{alias}}( -1.0, 1.0, 1.0 ) 0.0 > y = {{alias}}( 0.0, 1.0, 1.0 ) - 0.0 + 1.0 > y = {{alias}}( NaN, 1.0, 1.0 ) NaN > y = {{alias}}( 1.0, NaN, 1.0 ) diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/types/index.d.ts b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/types/index.d.ts index 404904f052a4..1d2315c4f656 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/docs/types/index.d.ts @@ -56,7 +56,7 @@ interface PDF { * * @example * var y = pdf( 0.0, 1.0, 1.0 ); - * // returns 0.0 + * // returns 1.0 * * @example * var y = pdf( NaN, 1.0, 1.0 ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/factory.js index 8a51e53755a2..ae25828d2ba8 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/factory.js @@ -23,6 +23,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 PINF = require( '@stdlib/constants/float64/pinf' ); // MAIN // @@ -66,9 +67,16 @@ function factory( alpha, beta ) { if ( isnan( x ) ) { return NaN; } - if ( x <= 0.0 ) { + if ( x < 0.0 ) { return 0.0; } + // At `x = 0`, the density is infinite for `beta < 1`, `1/alpha` for `beta = 1`, and `0` for `beta > 1`: + if ( x === 0.0 ) { + if ( beta < 1.0 ) { + return PINF; + } + return ( beta === 1.0 ) ? 1.0 / alpha : 0.0; + } xa = x / alpha; xb = pow( xa, beta ); return ( beta / alpha ) * pow( xa, beta - 1.0 ) / pow( 1.0 + xb, 2.0 ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/main.js index cf107599b6cb..9d3ae32fee04 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/main.js @@ -22,6 +22,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); var pow = require( '@stdlib/math/base/special/pow' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); // MAIN // @@ -48,7 +49,7 @@ var pow = require( '@stdlib/math/base/special/pow' ); * * @example * var y = pdf( 0.0, 1.0, 1.0 ); -* // returns 0.0 +* // returns 1.0 * * @example * var y = pdf( NaN, 1.0, 1.0 ); @@ -82,9 +83,16 @@ function pdf( x, alpha, beta ) { ) { return NaN; } - if ( x <= 0.0 ) { + if ( x < 0.0 ) { return 0.0; } + // At `x = 0`, the density is infinite for `beta < 1`, `1/alpha` for `beta = 1`, and `0` for `beta > 1`: + if ( x === 0.0 ) { + if ( beta < 1.0 ) { + return PINF; + } + return ( beta === 1.0 ) ? 1.0 / alpha : 0.0; + } xa = x / alpha; xb = pow( xa, beta ); return ( beta / alpha ) * pow( xa, beta - 1.0 ) / pow( 1.0 + xb, 2.0 ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/native.js b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/native.js index 16e762d7956e..8584fec072a7 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/native.js +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/lib/native.js @@ -48,7 +48,7 @@ var addon = require( './../src/addon.node' ); * * @example * var y = pdf( 0.0, 1.0, 1.0 ); -* // returns 0.0 +* // returns 1.0 * * @example * var y = pdf( NaN, 1.0, 1.0 ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/manifest.json b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/manifest.json index 444a3a08bea9..ea518b08a88f 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/manifest.json +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/manifest.json @@ -40,7 +40,8 @@ "dependencies": [ "@stdlib/math/base/napi/ternary", "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/pow" + "@stdlib/math/base/special/pow", + "@stdlib/constants/float64/pinf" ] }, { @@ -57,6 +58,7 @@ "dependencies": [ "@stdlib/math/base/assert/is-nan", "@stdlib/math/base/special/pow", + "@stdlib/constants/float64/pinf", "@stdlib/constants/float64/eps" ] }, @@ -73,7 +75,8 @@ "libpath": [], "dependencies": [ "@stdlib/math/base/assert/is-nan", - "@stdlib/math/base/special/pow" + "@stdlib/math/base/special/pow", + "@stdlib/constants/float64/pinf" ] } ] diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/src/main.c index 9cb95dcce78a..89f9cfdd1569 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/src/main.c @@ -19,6 +19,7 @@ #include "stdlib/stats/base/dists/log-logistic/pdf.h" #include "stdlib/math/base/assert/is_nan.h" #include "stdlib/math/base/special/pow.h" +#include "stdlib/constants/float64/pinf.h" /** * Evaluates the probability density function (PDF) for a log-logistic distribution with scale parameter `alpha` and shape parameter `beta` at a value `x`. @@ -45,9 +46,16 @@ double stdlib_base_dists_log_logistic_pdf( const double x, const double alpha, c ) { return 0.0 / 0.0; // NaN } - if ( x <= 0.0 ) { + if ( x < 0.0 ) { return 0.0; } + // At `x = 0`, the density is infinite for `beta < 1`, `1/alpha` for `beta = 1`, and `0` for `beta > 1`: + if ( x == 0.0 ) { + if ( beta < 1.0 ) { + return STDLIB_CONSTANT_FLOAT64_PINF; + } + return ( beta == 1.0 ) ? 1.0 / alpha : 0.0; + } xa = x / alpha; xb = stdlib_base_pow( xa, beta ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.factory.js b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.factory.js index cb18f3280d0a..941e0ed968be 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.factory.js @@ -21,6 +21,7 @@ // MODULES // var tape = require( 'tape' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var isAlmostSameValue = require( '@stdlib/assert/is-almost-same-value' ); var NINF = require( '@stdlib/constants/float64/ninf' ); @@ -103,15 +104,12 @@ tape( 'the returned function returns `NaN` if provided `NaN` for `x`', function t.end(); }); -tape( 'the returned function returns `0` if provided `x <= 0`', function test( t ) { +tape( 'the returned function returns `0` if provided `x < 0`', function test( t ) { var pdf; var y; pdf = factory( 1.0, 1.0 ); - y = pdf( 0.0 ); - t.strictEqual( y, 0.0, 'returns expected value' ); - y = pdf( -1.0 ); t.strictEqual( y, 0.0, 'returns expected value' ); y = pdf( NINF ); @@ -120,6 +118,21 @@ tape( 'the returned function returns `0` if provided `x <= 0`', function test( t t.end(); }); +tape( 'the returned function returns `+infinity`, `1/alpha`, or `0` at `x = 0` when `beta` is less than, equal to, or greater than one', function test( t ) { + var pdf; + + pdf = factory( 2.0, 0.5 ); + t.strictEqual( pdf( 0.0 ), PINF, 'returns expected value' ); + + pdf = factory( 2.0, 1.0 ); + t.strictEqual( pdf( 0.0 ), 0.5, 'returns expected value' ); + + pdf = factory( 2.0, 3.0 ); + t.strictEqual( pdf( 0.0 ), 0.0, 'returns expected value' ); + + t.end(); +}); + tape( 'the returned function evaluates the log-logistic pdf for positive `x`, `alpha`, and `beta`', function test( t ) { var expected; var alpha; diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.native.js b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.native.js index 6d805f062fb5..1c64a29433fb 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.native.js +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.native.js @@ -22,6 +22,7 @@ var resolve = require( 'path' ).resolve; var tape = require( 'tape' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); var tryRequire = require( '@stdlib/utils/try-require' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var isAlmostSameValue = require( '@stdlib/assert/is-almost-same-value' ); @@ -97,12 +98,9 @@ tape( 'if provided a non-positive `beta`, the function returns `NaN`', opts, fun t.end(); }); -tape( 'if provided `x <= 0`, the function returns `0`', opts, function test( t ) { +tape( 'if provided `x < 0`, the function returns `0`', opts, function test( t ) { var y; - y = pdf( 0.0, 1.0, 1.0 ); - t.strictEqual( y, 0.0, 'returns expected value' ); - y = pdf( -1.0, 1.0, 1.0 ); t.strictEqual( y, 0.0, 'returns expected value' ); @@ -115,6 +113,13 @@ tape( 'if provided `x <= 0`, the function returns `0`', opts, function test( t ) t.end(); }); +tape( 'the function returns `+infinity`, `1/alpha`, or `0` at `x = 0` when `beta` is less than, equal to, or greater than one', opts, function test( t ) { + t.strictEqual( pdf( 0.0, 2.0, 0.5 ), PINF, 'returns expected value' ); + t.strictEqual( pdf( 0.0, 2.0, 1.0 ), 0.5, 'returns expected value' ); + t.strictEqual( pdf( 0.0, 2.0, 3.0 ), 0.0, 'returns expected value' ); + t.end(); +}); + tape( 'the function evaluates the log-logistic pdf for positive `x`, `alpha`, and `beta`', opts, function test( t ) { var expected; var alpha; diff --git a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.pdf.js b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.pdf.js index ea99ba13b48f..8617742bf0bb 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.pdf.js +++ b/lib/node_modules/@stdlib/stats/base/dists/log-logistic/pdf/test/test.pdf.js @@ -21,6 +21,7 @@ // MODULES // var tape = require( 'tape' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var isAlmostSameValue = require( '@stdlib/assert/is-almost-same-value' ); var NINF = require( '@stdlib/constants/float64/ninf' ); @@ -88,12 +89,9 @@ tape( 'if provided a non-positive `beta`, the function returns `NaN`', function t.end(); }); -tape( 'if provided `x <= 0`, the function returns `0`', function test( t ) { +tape( 'if provided `x < 0`, the function returns `0`', function test( t ) { var y; - y = pdf( 0.0, 1.0, 1.0 ); - t.strictEqual( y, 0.0, 'returns expected value' ); - y = pdf( -1.0, 1.0, 1.0 ); t.strictEqual( y, 0.0, 'returns expected value' ); @@ -106,6 +104,13 @@ tape( 'if provided `x <= 0`, the function returns `0`', function test( t ) { t.end(); }); +tape( 'the function returns `+infinity`, `1/alpha`, or `0` at `x = 0` when `beta` is less than, equal to, or greater than one', function test( t ) { + t.strictEqual( pdf( 0.0, 2.0, 0.5 ), PINF, 'returns expected value' ); + t.strictEqual( pdf( 0.0, 2.0, 1.0 ), 0.5, 'returns expected value' ); + t.strictEqual( pdf( 0.0, 2.0, 3.0 ), 0.0, 'returns expected value' ); + t.end(); +}); + tape( 'the function evaluates the log-logistic pdf for positive `x`, `alpha`, and `beta`', function test( t ) { var expected; var alpha;