diff --git a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/factory.js index ee0a6a7971ca..5674d72eaa28 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/factory.js @@ -81,7 +81,13 @@ function factory( k ) { if ( x < 0.0 || x === PINF ) { return NINF; } - out = ( ( 1.0-kh ) * LN2 ) + ( km1 * ln( x ) ) - ( (x*x) / 2.0 ); + out = ( 1.0-kh ) * LN2; + + // For `k = 1`, the `x^(k-1)` factor is `1` (including at `x = 0`), whereas `(k-1) * ln(x)` would evaluate to `0 * -infinity = NaN` at `x = 0`: + if ( km1 !== 0.0 ) { + out += km1 * ln( x ); + } + out -= ( x*x ) / 2.0; out -= gammaln( kh ); return out; } diff --git a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/main.js index 40600d324336..4b90f825bd2f 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/lib/main.js @@ -80,7 +80,13 @@ function logpdf( x, k ) { return NINF; } kh = k / 2.0; - out = ( ( 1.0-kh ) * LN2 ) + ( ( k-1.0 ) * ln( x ) ) - ( (x*x) / 2.0 ); + out = ( 1.0-kh ) * LN2; + + // For `k = 1`, the `x^(k-1)` factor is `1` (including at `x = 0`), whereas `(k-1) * ln(x)` would evaluate to `0 * -infinity = NaN` at `x = 0`: + if ( k !== 1.0 ) { + out += ( k-1.0 ) * ln( x ); + } + out -= ( x*x ) / 2.0; out -= gammaln( kh ); return out; } diff --git a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/src/main.c index 65ee4c29dbf2..44faee3f1fa4 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/src/main.c @@ -49,7 +49,13 @@ double stdlib_base_dists_chi_logpdf( const double x, const double k ) { return STDLIB_CONSTANT_FLOAT64_NINF; } kh = k / 2.0; - out = ( ( 1.0 - kh ) * STDLIB_CONSTANT_FLOAT64_LN2 ) + ( ( k - 1.0 ) * stdlib_base_ln( x ) ) - ( ( x * x ) / 2.0 ); + out = ( 1.0 - kh ) * STDLIB_CONSTANT_FLOAT64_LN2; + + // For `k = 1`, the `x^(k-1)` factor is `1` (including at `x = 0`), whereas `(k-1) * ln(x)` would evaluate to `0 * -infinity = NaN` at `x = 0`: + if ( k != 1.0 ) { + out += ( k - 1.0 ) * stdlib_base_ln( x ); + } + out -= ( x * x ) / 2.0; out -= stdlib_base_gammaln( kh ); return out; } diff --git a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.factory.js b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.factory.js index 9f299fb0741c..bd77af8d8e8d 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.factory.js @@ -143,6 +143,25 @@ tape( 'the returned function returns `-Infinity` for all `x < 0`', function test t.end(); }); +tape( 'if provided `x = 0`, the created function returns `ln(sqrt(2/π))` when `k = 1`, `+Infinity` when `k < 1`, and `-Infinity` when `k > 1`', function test( t ) { + var logpdf; + var y; + + logpdf = factory( 1.0 ); + y = logpdf( 0.0 ); + t.strictEqual( isAlmostSameValue( y, -0.22579135264472744, 1 ), true, 'returns expected value' ); + + logpdf = factory( 0.5 ); + y = logpdf( 0.0 ); + t.strictEqual( y, PINF, 'returns expected value' ); + + logpdf = factory( 2.0 ); + y = logpdf( 0.0 ); + t.strictEqual( y, NINF, 'returns expected value' ); + + t.end(); +}); + tape( 'the created function evaluates the logpdf for `x` given degrees of freedom `k`', function test( t ) { var expected; var logpdf; diff --git a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.logpdf.js b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.logpdf.js index b4b156a2cfb5..8b7fa6ef3cf6 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.logpdf.js +++ b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.logpdf.js @@ -115,6 +115,21 @@ tape( 'the function returns `-Infinity` for all `x < 0`', function test( t ) { t.end(); }); +tape( 'if provided `x = 0`, the function returns `ln(sqrt(2/π))` when `k = 1`, `+Infinity` when `k < 1`, and `-Infinity` when `k > 1`', function test( t ) { + var y; + + y = logpdf( 0.0, 1.0 ); + t.strictEqual( isAlmostSameValue( y, -0.22579135264472744, 1 ), true, 'returns expected value' ); + + y = logpdf( 0.0, 0.5 ); + t.strictEqual( y, PINF, 'returns expected value' ); + + y = logpdf( 0.0, 2.0 ); + t.strictEqual( y, NINF, 'returns expected value' ); + + t.end(); +}); + tape( 'the function evaluates the logpdf for `x` given degrees of freedom `k`', function test( t ) { var expected; var x; diff --git a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.native.js b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.native.js index b71677970303..054c2b62ffca 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.native.js +++ b/lib/node_modules/@stdlib/stats/base/dists/chi/logpdf/test/test.native.js @@ -94,6 +94,21 @@ tape( 'if provided `-infinity` for `x` and a valid `k`, the function returns `-i t.end(); }); +tape( 'if provided `x = 0`, the function returns `ln(sqrt(2/π))` when `k = 1`, `+Infinity` when `k < 1`, and `-Infinity` when `k > 1`', opts, function test( t ) { + var y; + + y = logpdf( 0.0, 1.0 ); + t.strictEqual( isAlmostSameValue( y, -0.22579135264472744, 1 ), true, 'returns expected value' ); + + y = logpdf( 0.0, 0.5 ); + t.strictEqual( y, PINF, 'returns expected value' ); + + y = logpdf( 0.0, 2.0 ); + t.strictEqual( y, NINF, 'returns expected value' ); + + t.end(); +}); + tape( 'the function evaluates the logpdf for given `x` and `k`', opts, function test( t ) { var expected; var x;