nfTlWNl rn Ѻq$³*%yNk9S maq.m>`iY v=78@?7 ~ CѶͫ\]*uQlf^ZL~`^ǥ_ 6E~/6._#1Iķխ}`[W">/m6NZDrjt(a_W Ѻq$³*%yNk9Sz ] 𓼾,_NgJ+4IzЗu&eKK$G|黾Uim[堋!T1QUx6ϥ!CKƞ>=x[Eug ffZk1#G D hIE^w^ ĢQ$3u>)h3jܮ 'gf\Ƶ t1O4t5y+:A={Ÿ8Dvw ĢQ$3dzq_BT[odMGjE]״NdY hu^*Wxپ51,1S]EyàL緁 ĢQ$3eMx%P]bAϴEZDQq*7&)7;/_b)`՞>ŮrGgt'ξp%?\R=>Ve*w4'Cy=bG,kPv}h0!$5sn >,笧kJ߇QI"֮m 5F |ndq '؄ݐ;f絇F8#oMka<^cSƙ[)7s39嬢AW1Ɂ\Hۄ M 5jȽ/r#8cB&J@xFO \] Ӥ+fu/-ej5ZiD°{ƹRSbSM~m6k:<+2D cS`߳a;˵K aI[WcWĒ.q>=]}n\'An殺˛ej^,w!yBhs)1 qTX.CLo'ke,9,虂?Hq 2* aplmjD ɍ 4XOѮj7 v㣘:okYA2wםENKɨ\G߾nnG;ͻFX}5-!G}˙d4mcghty*F8cP2en"!˙T(bemgx{0U_wYBW1D鹇PE"}@[ꩪ%KrKN^wDE$rr '#uf oWfϫ)ϲ=C&&dG))B 5Kpv~vA+'PqAZ] 3rZ qJ.oH֍`>@:a7*QL+[#to/0 /x@vI۸صw^J8=r*n&xy_J܉g:u"_1 (yYM YYscw]n}twK3pF#N$G^X쑵U$RE~J|@:@CҜS~8 X͐uvY[?U[4a4{ݴ (siv[ָ X$o(U}E =N.k2*탲udB_/; \va|wcrH:V|7Q?H&'.4{(+f8T?N#-ƲJv^{I\8~# 0<f*6(Y!FeA1d_g ^/C@auTԦ,=)32dW7OJƑ ff?y7‹euFE' A2Ԩ ĢQ$3o3* d82'J3FFŏ- 䡨!~E q*%!D1H>cr~YK<NЀh ĢQ$3L:[$Fec$ B2h]#Js 5-X pX7<>r;.)fgqy?@wөo ū@E&3 I]C63O3tQ%`ߌ;뱎0_C&A[lJs`}XF#Jph1Z0אe=ECjD¯hZRL[3'3`,JP8m' ib"!T*;{O"(83JPo_O-BL=c^!N*굡_* ,7N,]BR'~ڨ:~@:0a)V#:exfeXz" /;tV<99X:NLnq4] ˑwJ Y>~j%4#*Z=vߐA%ֺ@&;/ꃜǸ E;@5j҃ӵQp06F%b*S&Ng Om+bw,xx{4nT:>cӔu˾?WAєVHDqeۀڤ91(*G(KCȹljr)-RP':cNHG5?I <8R."#փ aFj {l˒?fϣzQ`nim6eOyh mɱ7cg' yc:C*7D.2^dKN&::0W)2n:6n)!r Cbzj\ QtjbR}<۰ getMessage(); } if ($rMin > $rMax) { $tmp = $rMin; $rMin = $rMax; $rMax = $tmp; } if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0.0)) { return ExcelError::NAN(); } return self::calculateInverse($probability, $alpha, $beta, $rMin, $rMax); } /** * @return float|string */ private static function calculateInverse(float $probability, float $alpha, float $beta, float $rMin, float $rMax) { $a = 0; $b = 2; $guess = ($a + $b) / 2; $i = 0; while ((($b - $a) > Functions::PRECISION) && (++$i <= self::MAX_ITERATIONS)) { $guess = ($a + $b) / 2; $result = self::distribution($guess, $alpha, $beta); if (($result === $probability) || ($result === 0.0)) { $b = $a; } elseif ($result > $probability) { $b = $guess; } else { $a = $guess; } } if ($i === self::MAX_ITERATIONS) { return ExcelError::NA(); } return round($rMin + $guess * ($rMax - $rMin), 12); } /** * Incomplete beta function. * * @author Jaco van Kooten * @author Paul Meagher * * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992). * * @param float $x require 0<=x<=1 * @param float $p require p>0 * @param float $q require q>0 * * @return float 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow */ public static function incompleteBeta(float $x, float $p, float $q): float { if ($x <= 0.0) { return 0.0; } elseif ($x >= 1.0) { return 1.0; } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > self::LOG_GAMMA_X_MAX_VALUE)) { return 0.0; } $beta_gam = exp((0 - self::logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); if ($x < ($p + 1.0) / ($p + $q + 2.0)) { return $beta_gam * self::betaFraction($x, $p, $q) / $p; } return 1.0 - ($beta_gam * self::betaFraction(1 - $x, $q, $p) / $q); } // Function cache for logBeta function /** @var float */ private static $logBetaCacheP = 0.0; /** @var float */ private static $logBetaCacheQ = 0.0; /** @var float */ private static $logBetaCacheResult = 0.0; /** * The natural logarithm of the beta function. * * @param float $p require p>0 * @param float $q require q>0 * * @return float 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow * * @author Jaco van Kooten */ private static function logBeta(float $p, float $q): float { if ($p != self::$logBetaCacheP || $q != self::$logBetaCacheQ) { self::$logBetaCacheP = $p; self::$logBetaCacheQ = $q; if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > self::LOG_GAMMA_X_MAX_VALUE)) { self::$logBetaCacheResult = 0.0; } else { self::$logBetaCacheResult = Gamma::logGamma($p) + Gamma::logGamma($q) - Gamma::logGamma($p + $q); } } return self::$logBetaCacheResult; } /** * Evaluates of continued fraction part of incomplete beta function. * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). * * @author Jaco van Kooten */ private static function betaFraction(float $x, float $p, float $q): float { $c = 1.0; $sum_pq = $p + $q; $p_plus = $p + 1.0; $p_minus = $p - 1.0; $h = 1.0 - $sum_pq * $x / $p_plus; if (abs($h) < self::XMININ) { $h = self::XMININ; } $h = 1.0 / $h; $frac = $h; $m = 1; $delta = 0.0; while ($m <= self::MAX_ITERATIONS && abs($delta - 1.0) > Functions::PRECISION) { $m2 = 2 * $m; // even index for d $d = $m * ($q - $m) * $x / (($p_minus + $m2) * ($p + $m2)); $h = 1.0 + $d * $h; if (abs($h) < self::XMININ) { $h = self::XMININ; } $h = 1.0 / $h; $c = 1.0 + $d / $c; if (abs($c) < self::XMININ) { $c = self::XMININ; } $frac *= $h * $c; // odd index for d $d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2)); $h = 1.0 + $d * $h; if (abs($h) < self::XMININ) { $h = self::XMININ; } $h = 1.0 / $h; $c = 1.0 + $d / $c; if (abs($c) < self::XMININ) { $c = self::XMININ; } $delta = $h * $c; $frac *= $delta; ++$m; } return $frac; } /* private static function betaValue(float $a, float $b): float { return (Gamma::gammaValue($a) * Gamma::gammaValue($b)) / Gamma::gammaValue($a + $b); } private static function regularizedIncompleteBeta(float $value, float $a, float $b): float { return self::incompleteBeta($value, $a, $b) / self::betaValue($a, $b); } */ }