time-to-botec

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

factory.js (2472B)


      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 constantFunction = require( '@stdlib/utils/constant-function' );
     24 var isnan = require( '@stdlib/math/base/assert/is-nan' );
     25 var PINF = require( '@stdlib/constants/float64/pinf' );
     26 var ibetaDerivative = require( './ibeta_derivative.js' );
     27 
     28 
     29 // MAIN //
     30 
     31 /**
     32 * Returns a function for evaluating the probability density function (PDF) for an F distribution with numerator degrees of freedom `d1` and denominator degrees of freedom `d2`.
     33 *
     34 * @param {PositiveNumber} d1 - numerator degrees of freedom
     35 * @param {PositiveNumber} d2 - denominator degrees of freedom
     36 * @returns {Function} PDF
     37 *
     38 * @example
     39 * var pdf = factory( 6.0, 7.0 );
     40 * var y = pdf( 7.0 );
     41 * // returns ~0.004
     42 *
     43 * y = pdf( 2.0 );
     44 * // returns ~0.166
     45 */
     46 function factory( d1, d2 ) {
     47 	var zeroVal;
     48 	var d1by2;
     49 	var d2by2;
     50 	var d1d2;
     51 	if (
     52 		isnan( d1 ) ||
     53 		isnan( d2 ) ||
     54 		d1 <= 0.0 ||
     55 		d2 <= 0.0
     56 	) {
     57 		return constantFunction( NaN );
     58 	}
     59 	d1d2 = d1 * d2;
     60 	d1by2 = d1 / 2.0;
     61 	d2by2 = d2 / 2.0;
     62 	zeroVal = 0.0;
     63 	if ( d1 < 2.0 ) {
     64 		zeroVal = PINF;
     65 	}
     66 	else if ( d1 === 2.0 ) {
     67 		zeroVal = 1.0;
     68 	}
     69 	return pdf;
     70 
     71 	/**
     72 	* Evaluates the probability density function (PDF) for an F distribution.
     73 	*
     74 	* @private
     75 	* @param {number} x - input value
     76 	* @returns {number} evaluated PDF
     77 	*
     78 	* @example
     79 	* var y = pdf( 2.3 );
     80 	* // returns <number>
     81 	*/
     82 	function pdf( x ) {
     83 		var v1x;
     84 		var y;
     85 		var z;
     86 		if ( isnan( x ) ) {
     87 			return NaN;
     88 		}
     89 		if ( x < 0.0 || x === PINF ) {
     90 			return 0.0;
     91 		}
     92 		if ( x === 0.0 ) {
     93 			return zeroVal;
     94 		}
     95 		v1x = d1 * x;
     96 		if ( v1x > d2 ) {
     97 			y = d1d2 / ( ( d2 + v1x ) * ( d2 + v1x ) );
     98 			return y * ibetaDerivative( d2 / ( d2 + v1x ), d2by2, d1by2 );
     99 		}
    100 		z = d2 + v1x;
    101 		y = ((z * d1) - (x * d1 * d1)) / ( z * z );
    102 		return y * ibetaDerivative( d1 * x / ( d2 + v1x ), d1by2, d2by2 );
    103 	}
    104 }
    105 
    106 
    107 // EXPORTS //
    108 
    109 module.exports = factory;