time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

logpmf.js (3050B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 'use strict';
     20 
     21 // MODULES //
     22 
     23 var isNonNegativeInteger = require( '@stdlib/math/base/assert/is-nonnegative-integer' );
     24 var isnan = require( '@stdlib/math/base/assert/is-nan' );
     25 var fln = require( '@stdlib/math/base/special/factorialln' );
     26 var max = require( '@stdlib/math/base/special/max' );
     27 var min = require( '@stdlib/math/base/special/min' );
     28 var NINF = require( '@stdlib/constants/float64/ninf' );
     29 var PINF = require( '@stdlib/constants/float64/pinf' );
     30 
     31 
     32 // MAIN //
     33 
     34 /**
     35 * Evaluates the natural logarithm of the probability mass function (PMF) for a hypergeometric distribution with population size `N`, subpopulation size `K` and number of draws `n`.
     36 *
     37 * @param {number} x - input value
     38 * @param {NonNegativeInteger} N - population size
     39 * @param {NonNegativeInteger} K - subpopulation size
     40 * @param {NonNegativeInteger} n - number of draws
     41 * @returns {number} evaluated logPMF
     42 *
     43 * @example
     44 * var y = logpmf( 1.0, 8, 4, 2 );
     45 * // returns ~-0.56
     46 *
     47 * @example
     48 * var y = logpmf( 2.0, 8, 4, 2 );
     49 * // returns ~-1.54
     50 *
     51 * @example
     52 * var y = logpmf( 0.0, 8, 4, 2 );
     53 * // returns ~-1.54
     54 *
     55 * @example
     56 * var y = logpmf( 1.5, 8, 4, 2 );
     57 * // returns -Infinity
     58 *
     59 * @example
     60 * var y = logpmf( NaN, 10, 5, 2 );
     61 * // returns NaN
     62 *
     63 * @example
     64 * var y = logpmf( 0.0, NaN, 5, 2 );
     65 * // returns NaN
     66 *
     67 * @example
     68 * var y = logpmf( 0.0, 10, NaN, 2 );
     69 * // returns NaN
     70 *
     71 * @example
     72 * var y = logpmf( 0.0, 10, 5, NaN );
     73 * // returns NaN
     74 *
     75 * @example
     76 * var y = logpmf( 2.0, 10.5, 5, 2 );
     77 * // returns NaN
     78 *
     79 * @example
     80 * var y = logpmf( 2.0, 5, 1.5, 2 );
     81 * // returns NaN
     82 *
     83 * @example
     84 * var y = logpmf( 2.0, 10, 5, -2.0 );
     85 * // returns NaN
     86 *
     87 * @example
     88 * var y = logpmf( 2.0, 10, 5, 12 );
     89 * // returns NaN
     90 *
     91 * @example
     92 * var y = logpmf( 2.0, 8, 3, 9 );
     93 * // returns NaN
     94 */
     95 function logpmf( x, N, K, n ) {
     96 	var ldenom;
     97 	var lnum;
     98 	var maxs;
     99 	var mins;
    100 
    101 	if (
    102 		isnan( x ) ||
    103 		isnan( N ) ||
    104 		isnan( K ) ||
    105 		isnan( n ) ||
    106 		!isNonNegativeInteger( N ) ||
    107 		!isNonNegativeInteger( K ) ||
    108 		!isNonNegativeInteger( n ) ||
    109 		N === PINF ||
    110 		K === PINF ||
    111 		K > N ||
    112 		n > N
    113 	) {
    114 		return NaN;
    115 	}
    116 	mins = max( 0, n + K - N );
    117 	maxs = min( K, n );
    118 	if (
    119 		isNonNegativeInteger( x ) &&
    120 		mins <= x &&
    121 		x <= maxs
    122 	) {
    123 		lnum = fln( n ) + fln( K ) + fln( N - n ) + fln( N - K );
    124 		ldenom = fln( N ) + fln( x ) + fln( n - x );
    125 		ldenom += fln( K - x ) + fln( N - K + x - n );
    126 		return lnum - ldenom;
    127 	}
    128 	return NINF;
    129 }
    130 
    131 
    132 // EXPORTS //
    133 
    134 module.exports = logpmf;