Ejemplo n.º 1
0
 private static function _logGamma($x)
 {
     // Log Gamma related constants
     static $lg_d1 = -0.5772156649015329;
     static $lg_d2 = 0.42278433509846713;
     static $lg_d4 = 1.791759469228055;
     static $lg_p1 = array(4.945235359296727, 201.8112620856775, 2290.8383738313464, 11319.672059033808, 28557.246356716354, 38484.962284437934, 26377.487876241954, 7225.813979700288);
     static $lg_p2 = array(4.974607845568932, 542.4138599891071, 15506.93864978365, 184793.29044456323, 1088204.7694688288, 3338152.96798703, 5106661.678927353, 3074109.0548505397);
     static $lg_p4 = array(14745.0216605994, 2426813.3694867045, 121475557.40450932, 2663432449.630977, 29403789566.34554, 170266573776.5399, 492612579337.7431, 560625185622.3951);
     static $lg_q1 = array(67.48212550303778, 1113.3323938571993, 7738.757056935398, 27639.870744033407, 54993.102062261576, 61611.22180066002, 36351.2759150194, 8785.536302431014);
     static $lg_q2 = array(183.03283993705926, 7765.049321445006, 133190.38279660742, 1136705.8213219696, 5267964.117437947, 13467014.543111017, 17827365.303532742, 9533095.591844354);
     static $lg_q4 = array(2690.5301758708993, 639388.5654300093, 41355999.30241388, 1120872109.616148, 14886137286.788137, 101680358627.24382, 341747634550.73773, 446315818741.9713);
     static $lg_c = array(-0.001910444077728, 0.0008417138778129501, -0.0005952379913043012, 0.0007936507935003503, -0.0027777777777776816, 0.08333333333333333, 0.0057083835261);
     // Rough estimate of the fourth root of logGamma_xBig
     static $lg_frtbig = 2.25E+76;
     static $pnt68 = 0.6796875;
     if ($x == self::$_logGammaCache_x) {
         return self::$_logGammaCache_result;
     }
     $y = $x;
     if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) {
         if ($y <= EPS) {
             $res = -log(y);
         } elseif ($y <= 1.5) {
             // ---------------------
             //	EPS .LT. X .LE. 1.5
             // ---------------------
             if ($y < $pnt68) {
                 $corr = -log($y);
                 $xm1 = $y;
             } else {
                 $corr = 0.0;
                 $xm1 = $y - 1.0;
             }
             if ($y <= 0.5 || $y >= $pnt68) {
                 $xden = 1.0;
                 $xnum = 0.0;
                 for ($i = 0; $i < 8; ++$i) {
                     $xnum = $xnum * $xm1 + $lg_p1[$i];
                     $xden = $xden * $xm1 + $lg_q1[$i];
                 }
                 $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden));
             } else {
                 $xm2 = $y - 1.0;
                 $xden = 1.0;
                 $xnum = 0.0;
                 for ($i = 0; $i < 8; ++$i) {
                     $xnum = $xnum * $xm2 + $lg_p2[$i];
                     $xden = $xden * $xm2 + $lg_q2[$i];
                 }
                 $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden));
             }
         } elseif ($y <= 4.0) {
             // ---------------------
             //	1.5 .LT. X .LE. 4.0
             // ---------------------
             $xm2 = $y - 2.0;
             $xden = 1.0;
             $xnum = 0.0;
             for ($i = 0; $i < 8; ++$i) {
                 $xnum = $xnum * $xm2 + $lg_p2[$i];
                 $xden = $xden * $xm2 + $lg_q2[$i];
             }
             $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden));
         } elseif ($y <= 12.0) {
             // ----------------------
             //	4.0 .LT. X .LE. 12.0
             // ----------------------
             $xm4 = $y - 4.0;
             $xden = -1.0;
             $xnum = 0.0;
             for ($i = 0; $i < 8; ++$i) {
                 $xnum = $xnum * $xm4 + $lg_p4[$i];
                 $xden = $xden * $xm4 + $lg_q4[$i];
             }
             $res = $lg_d4 + $xm4 * ($xnum / $xden);
         } else {
             // ---------------------------------
             //	Evaluate for argument .GE. 12.0
             // ---------------------------------
             $res = 0.0;
             if ($y <= $lg_frtbig) {
                 $res = $lg_c[6];
                 $ysq = $y * $y;
                 for ($i = 0; $i < 6; ++$i) {
                     $res = $res / $ysq + $lg_c[$i];
                 }
             }
             $res /= $y;
             $corr = log($y);
             $res = $res + log(SQRT2PI) - 0.5 * $corr;
             $res += $y * ($corr - 1.0);
         }
     } else {
         // --------------------------
         //	Return for bad arguments
         // --------------------------
         $res = MAX_VALUE;
     }
     // ------------------------------
     //	Final adjustments and return
     // ------------------------------
     self::$_logGammaCache_x = $x;
     self::$_logGammaCache_result = $res;
     return $res;
 }