def fdtrc(a, b, x):
    """Returns right tail of F distribution, x to infinity.

    See Cephes docs for details.
    """
    if min(a, b) < 1:
        raise ValueError, "F a and b (degrees of freedom) must both be >= 1."
    if x < 0:
        raise ValueError, "F distribution value of f must be >= 0."
    w = float(b) / (b + a * x)
    return betai(0.5 * b, 0.5 * a, w)
def fdtr(a, b, x):
    """Returns left tail of F distribution, 0 to x.

    See Cephes docs for details.
    """
    if min(a, b) < 1:
        raise ValueError, "F a and b (degrees of freedom) must both be >= 1."
    if x < 0:
        raise ValueError, "F distribution value of f must be >= 0."
    w = a * x
    w /= float(b + w)
    return betai(0.5 * a, 0.5 * b, w)
def stdtr(k, t):
    """Student's t distribution, -infinity to t.

    See Cephes docs for details.
    """
    if k <= 0:
        raise ValueError, 'stdtr: df must be > 0.'
    if t == 0:
        return 0.5
    if t < -2:
        rk = k
        z = rk / (rk + t * t)
        return 0.5 * betai(0.5 * rk, 0.5, z)
    #compute integral from -t to + t
    if t < 0:
        x = -t
    else:
        x = t

    rk = k  #degrees of freedom
    z = 1 + (x * x)/rk
    #test if k is odd or even
    if (k & 1) != 0:
        #odd k
        xsqk = x/sqrt(rk)
        p = atan(xsqk)
        if k > 1:
            f = 1
            tz = 1
            j = 3
            while (j <= (k-2)) and ((tz/f) > MACHEP):
                tz *= (j-1)/(z*j)
                f += tz
                j += 2
            p += f * xsqk/z
        p *= 2/PI
    else:
        #even k
        f = 1
        tz = 1
        j = 2
        while (j <= (k-2)) and ((tz/f) > MACHEP):
            tz *= (j-1)/(z*j)
            f += tz
            j += 2
        p = f * x/sqrt(z*rk)
    #common exit
    if t < 0:
        p = -p  #note destruction of relative accuracy
    p = 0.5 + 0.5 * p
    return p
def bdtr(k, n, p):
    """Binomial distribution, 0 through k.

    Uses formula bdtr(k, n, p) = betai(n-k, k+1, 1-p)

    See Cephes docs for details.
    """
    p = fix_rounding_error(p)
    if (p < 0) or (p > 1):
        raise ValueError, "Binomial p must be between 0 and 1."
    if (k < 0) or (n < k):
        raise ValueError, "Binomial k must be between 0 and n."
    if k == n:
        return 1
    dn = n - k
    if k == 0:
        return  pow(1-p, dn)
    else:
        return  betai(dn, k+1, 1-p)
def bdtrc(k, n, p):
    """Complement of binomial distribution, k+1 through n.

    Uses formula bdtrc(k, n, p) = betai(k+1, n-k, p)

    See Cephes docs for details.
    """
    p = fix_rounding_error(p)
    if (p < 0) or (p > 1):
        raise ValueError, "Binomial p must be between 0 and 1."
    if (k < 0) or (n < k):
        raise ValueError, "Binomial k must be between 0 and n."
    if k == n:
        return 0
    dn = n - k
    if k == 0:
        if p < .01:
            dk = -expm1(dn * log1p(-p))
        else:
            dk = 1 - pow(1.0-p, dn)
    else:
        dk = k + 1
        dk = betai(dk, dn, p)
    return dk