def stdtri(k, p): """Returns inverse of Student's t distribution. k = df.""" p = fix_rounding_error(p) # handle easy cases if k <= 0 or p < 0.0 or p > 1.0: raise ZeroDivisionError, "k must be >= 1, p between 1 and 0." rk = k #handle intermediate values if p > 0.25 and p < 0.75: if p == 0.5: return 0.0 z = 1.0 - 2.0 * p; z = incbi(0.5, 0.5*rk, abs(z)) t = sqrt(rk*z/(1.0-z)) if p < 0.5: t = -t return t #handle extreme values rflg = -1 if p >= 0.5: p = 1.0 - p; rflg = 1 z = incbi(0.5*rk, 0.5, 2.0*p) if MAXNUM * z < rk: return rflg * MAXNUM t = sqrt(rk/z - rk) return rflg * t
def fdtri(a, b, y): """Returns inverse of F distribution.""" y = fix_rounding_error(y) if( a < 1.0 or b < 1.0 or y <= 0.0 or y > 1.0): raise ZeroDivisionError, "y must be between 0 and 1; a and b >= 1" y = 1.0-y # Compute probability for x = 0.5 w = incbet(0.5*b, 0.5*a, 0.5) # If that is greater than y, then the solution w < .5. # Otherwise, solve at 1-y to remove cancellation in (b - b*w). if w > y or y < 0.001: w = incbi(0.5*b, 0.5*a, y) x = (b - b*w)/(a*w) else: w = incbi(0.5*a, 0.5*b, 1.0-y) x = b*w/(a*(1.0-w)) return x
def bdtri(k, n, y): """Inverse of binomial distribution. Finds binomial p such that sum of terms 0-k reaches cum probability y. """ y = fix_rounding_error(y) if y < 0.0 or y > 1.0: raise ZeroDivisionError, "y must be between 1 and 0." if k < 0 or n <= k: raise ZeroDivisionError, "k must be between 0 and n" dn = n - k if k == 0: if y > 0.8: p = -expm1(log1p(y-1.0) / dn) else: p = 1.0 - y**(1.0/dn) else: dk = k + 1; p = incbet(dn, dk, 0.5) if p > 0.5: p = incbi(dk, dn, 1.0-y) else: p = 1.0 - incbi(dn, dk, y) return p
def test_incbi(self): """incbi results should match cephes libraries""" aa_range = [0.1, 0.2, 0.5, 1, 2, 5] bb_range = aa_range yy_range = [0.1, 0.2, 0.5, 0.9] exp = [ 8.86928001193e-08, 9.08146855855e-05, 0.5, 0.999999911307, 4.39887474012e-09, 4.50443299194e-06, 0.0416524955556, 0.997881005025, 3.46456275553e-10, 3.54771169012e-07, 0.00337816430373, 0.732777808689, 1e-10, 1.024e-07, 0.0009765625, 0.3486784401, 3.85543289443e-11, 3.94796342545e-08, 0.000376636057552, 0.154915841005, 1.33210087225e-11, 1.36407136078e-08, 0.000130149552409, 0.056682323296, 0.00211899497509, 0.0646097657259, 0.958347504444, 0.999999995601, 0.000247764691908, 0.00788804962659, 0.5, 0.999752235308, 3.09753032747e-05, 0.000990813218262, 0.092990311753, 0.906714634947, 1e-05, 0.00032, 0.03125, 0.59049, 4.01878917904e-06, 0.000128614607219, 0.0126923538971, 0.309157452156, 1.41593162013e-06, 4.5316442592e-05, 0.00449136140034, 0.122896698096, 0.267222191311, 0.684264602461, 0.996621835696, 0.999999999654, 0.0932853650529, 0.321847764104, 0.907009688247, 0.999969024697, 0.0244717418524, 0.0954915028125, 0.5, 0.975528258148, 0.01, 0.04, 0.25, 0.81, 0.00445768188762, 0.0179929616503, 0.120614758428, 0.531877433474, 0.00165851285512, 0.00672409501831, 0.046687245337, 0.247272226803, 0.6513215599, 0.8926258176, 0.9990234375, 0.9999999999, 0.40951, 0.67232, 0.96875, 0.99999, 0.19, 0.36, 0.75, 0.99, 0.1, 0.2, 0.5, 0.9, 0.0513167019495, 0.105572809, 0.292893218813, 0.683772233983, 0.020851637639, 0.04364750021, 0.129449436704, 0.36904265552, 0.845084158995, 0.956946913164, 0.999623363942, 0.999999999961, 0.690842547844, 0.850620771098, 0.987307646103, 0.999995981211, 0.468122566526, 0.629849697132, 0.879385241572, 0.995542318112, 0.316227766017, 0.4472135955, 0.707106781187, 0.948683298051, 0.195800105659, 0.287140725417, 0.5, 0.804199894341, 0.0925952589131, 0.13988068827, 0.264449983296, 0.510316306551, 0.943317676704, 0.984896695084, 0.999869850448, 0.999999999987, 0.877103301904, 0.944441767096, 0.9955086386, 0.999998584068, 0.752727773197, 0.841546267738, 0.953312754663, 0.998341487145, 0.63095734448, 0.724779663678, 0.870550563296, 0.979148362361, 0.489683693449, 0.577552475154, 0.735550016704, 0.907404741087, 0.300968763593, 0.366086516536, 0.5, 0.699031236407, ] i = 0 for a in aa_range: for b in bb_range: for y in yy_range: result = incbi(a,b,y) e = exp[i] self.assertFloatEqual(e, result) i += 1 #specific cases that failed elsewhere self.assertFloatEqual(incbi(999,2,1e-10), 0.97399698104554944)