diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/README.md b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/README.md index 514c3582dc53..e9442c156df4 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/README.md +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/README.md @@ -95,6 +95,13 @@ var y = quantile( 0.4, -1.0 ); // returns NaN ``` +If provided `lambda` equal to `+Infinity`, the function returns `NaN`. + +```javascript +var y = quantile( 0.4, Infinity ); +// returns NaN +``` + If provided `lambda = 0`, the function evaluates the [quantile function][quantile-function] of a [degenerate distribution][degenerate-distribution] centered at `0.0`. ```javascript diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/docs/repl.txt b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/docs/repl.txt index 2ca3089a607f..5558162ff663 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/docs/repl.txt +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/docs/repl.txt @@ -9,6 +9,8 @@ If provided a negative value for `λ`, the function returns `NaN`. + If provided `λ` equal to positive infinity, the function returns `NaN`. + Parameters ---------- p: number diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/factory.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/factory.js index 0815e345d400..8089b0dba5ba 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/factory.js @@ -55,7 +55,7 @@ function factory( lambda ) { var sigmaInv; var sigma; - if ( isnan( lambda ) || lambda < 0.0 ) { + if ( isnan( lambda ) || lambda < 0.0 || lambda === PINF ) { return constantFunction( NaN ); } if ( lambda === 0.0 ) { diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/main.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/main.js index 47bc6ce8b977..4c96601e0b0f 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/main.js @@ -66,6 +66,10 @@ var search = require( './search.js' ); * @example * var y = quantile( 0.0, NaN ); * // returns NaN +* +* @example +* var y = quantile( 0.5, Infinity ); +* // returns NaN */ function quantile( p, lambda ) { var sigmaInv; @@ -74,7 +78,7 @@ function quantile( p, lambda ) { var corr; var x2; var x; - if ( isnan( lambda ) || lambda < 0.0 ) { + if ( isnan( lambda ) || lambda < 0.0 || lambda === PINF ) { return NaN; } if ( isnan( p ) || p < 0.0 || p > 1.0 ) { diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/native.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/native.js index 090e55dc65e1..359941692a47 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/native.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/native.js @@ -62,6 +62,10 @@ var addon = require( './../src/addon.node' ); * // returns NaN * * @example +* var y = quantile( 0.5, Infinity ); +* // returns NaN +* +* @example * var y = quantile( 0.5, -1.0 ); * // returns NaN */ diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/search.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/search.js index b89cd7a80dad..0e2dda642884 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/search.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/lib/search.js @@ -40,11 +40,18 @@ var methods; * @returns {NonNegativeInteger} `p` quantile of the specified distribution */ function searchLeft( x, p, lambda ) { + var xp; while ( true ) { if ( x === 0 || cdf( x - 1.0, lambda ) < p ) { return x; } - x -= 1; + xp = x - 1.0; + + // Guard against non-advancing updates (e.g., when `x` is `NaN` or is so large that decrementing does not change its value) in order to avoid an infinite loop: + if ( !( xp < x ) ) { + return x; + } + x = xp; } } @@ -58,8 +65,15 @@ function searchLeft( x, p, lambda ) { * @returns {NonNegativeInteger} `p` quantile of the specified distribution */ function searchRight( x, p, lambda ) { + var xn; while ( true ) { - x += 1; + xn = x + 1.0; + + // Guard against non-advancing updates (e.g., when `x` is `NaN` or is so large that incrementing does not change its value) in order to avoid an infinite loop: + if ( !( xn > x ) ) { + return x; + } + x = xn; if ( cdf( x, lambda ) >= p ) { return x; } diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/src/main.c index 36e43abcfc30..4af928c40bc9 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/src/main.c @@ -34,8 +34,15 @@ * @return `p` quantile of the specified distribution */ static double search_left( double x, const double p, const double lambda ) { + double xp; while ( x > 0.0 && stdlib_base_dists_poisson_cdf( x - 1.0, lambda ) >= p ) { - x -= 1.0; + xp = x - 1.0; + + // Guard against non-advancing updates (e.g., when `x` is `NaN` or is so large that decrementing does not change its value) in order to avoid an infinite loop: + if ( !( xp < x ) ) { + return x; + } + x = xp; } return x; } @@ -49,9 +56,16 @@ static double search_left( double x, const double p, const double lambda ) { * @return `p` quantile of the specified distribution */ static double search_right( double x, const double p, const double lambda ) { - x += 1.0; - while ( stdlib_base_dists_poisson_cdf( x, lambda ) < p ) { - x += 1.0; + double xn; + + // Guard against non-advancing updates (e.g., when `x` is `NaN` or is so large that incrementing does not change its value) in order to avoid an infinite loop: + xn = x + 1.0; + while ( xn > x ) { + x = xn; + if ( stdlib_base_dists_poisson_cdf( x, lambda ) >= p ) { + return x; + } + xn = x + 1.0; } return x; } @@ -75,7 +89,11 @@ double stdlib_base_dists_poisson_quantile( const double p, const double lambda ) double x2; double x; - if ( stdlib_base_is_nan( lambda ) || lambda < 0.0 ) { + if ( + stdlib_base_is_nan( lambda ) || + lambda < 0.0 || + lambda == STDLIB_CONSTANT_FLOAT64_PINF + ) { return 0.0 / 0.0; // NaN } if ( stdlib_base_is_nan( p ) || p < 0.0 || p > 1.0 ) { diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.factory.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.factory.js index 77a8b667cfa9..0b0d239fd63b 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.factory.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.factory.js @@ -91,6 +91,36 @@ tape( 'if provided a negative `lambda`, the created function always returns `NaN t.end(); }); +tape( 'if provided `lambda` equal to `+infinity`, the created function always returns `NaN`', function test( t ) { + var quantile; + var y; + + quantile = factory( PINF ); + + y = quantile( 0.5 ); + t.strictEqual( isnan( y ), true, 'returns expected value' ); + + y = quantile( 0.9 ); + t.strictEqual( isnan( y ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the created function terminates for very large `lambda` for which unit increments can no longer advance the search', function test( t ) { + var quantile; + var y; + + quantile = factory( 1.0e300 ); + + y = quantile( 0.9 ); + t.strictEqual( y, 1.0e300, 'returns expected value' ); + + y = quantile( 0.1 ); + t.strictEqual( y, 1.0e300, 'returns expected value' ); + + t.end(); +}); + tape( 'if provided a finite `lambda`, the created function returns `0` for `p = 0`', function test( t ) { var quantile = factory( 3.0 ); var y = quantile( 0.0 ); diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.main.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.main.js index 9b4394e69181..a4ef75a25bc2 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.main.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.main.js @@ -89,6 +89,30 @@ tape( 'if provided a negative `lambda`, the function always returns `NaN`', func t.end(); }); +tape( 'if provided `lambda` equal to `+infinity`, the function returns `NaN`', function test( t ) { + var y; + + y = quantile( 0.5, PINF ); + t.strictEqual( isnan( y ), true, 'returns expected value' ); + + y = quantile( 0.0, PINF ); + t.strictEqual( isnan( y ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function terminates for very large `lambda` for which unit increments can no longer advance the search', function test( t ) { + var y; + + y = quantile( 0.9, 1.0e300 ); + t.strictEqual( y, 1.0e300, 'returns expected value' ); + + y = quantile( 0.1, 1.0e300 ); + t.strictEqual( y, 1.0e300, 'returns expected value' ); + + t.end(); +}); + tape( 'if provided a `lambda` equal to `0`, the function always returns `0`', function test( t ) { var y; diff --git a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.native.js b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.native.js index 8558b28de397..0c8bb0dd9e94 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.native.js +++ b/lib/node_modules/@stdlib/stats/base/dists/poisson/quantile/test/test.native.js @@ -98,6 +98,30 @@ tape( 'if provided a negative `lambda`, the function always returns `NaN`', opts t.end(); }); +tape( 'if provided `lambda` equal to `+infinity`, the function returns `NaN`', opts, function test( t ) { + var y; + + y = quantile( 0.5, PINF ); + t.strictEqual( isnan( y ), true, 'returns expected value' ); + + y = quantile( 0.0, PINF ); + t.strictEqual( isnan( y ), true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function terminates for very large `lambda` for which unit increments can no longer advance the search', opts, function test( t ) { + var y; + + y = quantile( 0.9, 1.0e300 ); + t.strictEqual( y, 1.0e300, 'returns expected value' ); + + y = quantile( 0.1, 1.0e300 ); + t.strictEqual( y, 1.0e300, 'returns expected value' ); + + t.end(); +}); + tape( 'if provided a `lambda` equal to `0`, the function always returns `0`', opts, function test( t ) { var y;