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 pdtri(k, p): """Inverse of Poisson distribution. Finds Poission mean such that integral from 0 to k is p. """ p = fix_rounding_error(p) if k < 0 or p < 0.0 or p >= 1.0: raise ZeroDivisionError("k must be >=0, p between 1 and 0.") v = k + 1 return igami(v, p)
def gdtri(a, b, y): """Returns Gamma such that y is the probability in the integral. WARNING: if 1-y == 1, gives incorrect result. The scipy implementation gets around this by using cdflib, which is in Fortran. Until someone gets around to translating that, only use this function for values of p greater than 1e-15 or so! """ y = fix_rounding_error(y) if y < 0.0 or y > 1.0 or a <= 0.0 or b < 0.0: raise ZeroDivisionError("a and b must be non-negative, y from 0 to 1.") return igami(b, 1.0 - y) / a
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 chi_high(x, df): """Returns right-hand tail of chi-square distribution (x to infinity). df, the degrees of freedom, ranges from 1 to infinity (assume integers). Typically, df is (r-1)*(c-1) for a r by c table. Result ranges from 0 to 1. See Cephes docs for details. """ x = fix_rounding_error(x) if x < 0: raise ValueError("chi_high: x must be >= 0 (got %s)." % x) if df < 1: raise ValueError("chi_high: df must be >= 1 (got %s)." % df) return igamc(df / 2, x / 2)
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 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 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 < 0.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
def chdtri(df, y): """Returns inverse of chi-squared distribution.""" y = fix_rounding_error(y) if y < 0.0 or y > 1.0 or df < 1.0: raise ZeroDivisionError("y must be between 0 and 1; df >= 1") return 2 * igami(0.5 * df, y)