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)