Barak 0.3.2 documentation

barak.stats

Contents

Source code for barak.stats

""" Statistics-related functions.
"""
import numpy as np

def _bisect(func, target, xlo=-10, xhi=10):
    """ Find x value such that func(x) = target.

    Assumes the value is positive and does log bisection.
    """
    if np.isnan([target, xlo, xhi]).any():
        return np.nan, np.nan
    target, xlo, xhi = (float(val) for val in (target, xlo, xhi))

    fmin = lambda x: func(10**x) - target

    dlo = fmin(xlo)
    dhi = fmin(xhi)
    if not np.sign(dlo * dhi) < 0:
        raise ValueError('Min and max x values do not bracket the target')

    if dhi < dlo:
        fmin = lambda x: - (func(10**x) - target)

    n = 0
    while True:
        x = 0.5 * (xlo + xhi)
        diff = fmin(x)
        if abs(diff) < 1e-6:
            break
        if n == 1000:
            raise RuntimeError('Max evaluations reached (1000)')
        elif diff > 0:
            xhi = x
        else:
            xlo = x
        n += 1

    return 10**x

[docs]def poisson_min_max_limits(conf, nevents): """ Calculate the minimum and maximum mean Poisson value mu consistent with seeing nevents at a given confidence level. conf: float 95%, 90%, 68.3% or similar. nevents: int The number of events observed. Returns ------- mulo, mhi : floats Mean number of events such that >= observed number of events nevents occurs in fewer than conf% of cases (mulo), and mean number of events such that <= nevents occurs in fewer than conf% of cases (muhi) """ from scipy.stats import poisson nevents = int(nevents) conf = float(conf) if np.isnan(conf) or np.isnan(nevents): return np.nan, np.nan target = 1 - conf/100. if nevents == 0: mulo = 0 else: mulo = _bisect(lambda mu: 1 - poisson.cdf(nevents-1, mu), target) muhi = _bisect(lambda mu: poisson.cdf(nevents, mu), target) return mulo, muhi
[docs]def poisson_confidence_interval(conf, nevents): """ Find the Poisson confidence interval. Parameters ---------- conf: float Confidence level in percent (95, 90, 68.3% or similar). nevents: int The number of events observed. If 0, then return the 1-sided upper limit. Returns ------- mulo, mhi : floats The two-sided confidence interval such that for mulo, >= observed number of events occurs in fewer than conf% of cases, and for muhi, <= nevents occurs in fewer than conf% of cases. """ if nevents == 0: return poisson_min_max_limits(conf, nevents) return poisson_min_max_limits(conf + 0.5*(100-conf), nevents)
[docs]def binomial_min_max_limits(conf, ntrial, nsuccess): """ Calculate the minimum and maximum binomial probability consistent with seeing nsuccess from ntrial at a given confidence level. conf: float 95%, 90%, 68.3% or similar. ntrial, nsuccess: int The number of trials and successes. Returns ------- plo, phi : floats Mean number of events such that >= observed number of events nevents occurs in fewer than conf% of cases (mulo), and mean number of events such that <= nevents occurs in fewer than conf% of cases (muhi) """ from scipy.stats import binom nsuccess = int(nsuccess) ntrial = int(ntrial) conf = float(conf) if np.isnan(conf): return np.nan, np.nan target = 1 - conf/100. if nsuccess == 0: plo = 0 else: plo = _bisect(lambda p: 1 - binom.cdf(nsuccess-1, ntrial, p), target, xhi=0) if nsuccess == ntrial: phi = 1 else: phi = _bisect(lambda p: binom.cdf(nsuccess, ntrial, p), target, xhi=0) return plo, phi
[docs]def binomial_confidence_interval(conf, ntrial, nsuccess): """ Find the binomial confidence level. Parameters ---------- conf: float Confidence level in percent (95, 90, 68.3% or similar). ntrial: int The number of trials. nsuccess: int The number of successes from the trials. If 0, then return the 1-sided upper limit. Returns ------- plo, phi : floats The two-sided confidence interval: probabilities such that >= observed number of successes occurs in fewer than conf% of cases (plo), and prob such that <= number of success occurs in fewer than conf% of cases (phi). """ if nsuccess == 0: return binomial_min_max_limits(conf, ntrial, nsuccess) return binomial_min_max_limits(conf + 0.5*(100 - conf), ntrial, nsuccess)
[docs]def blackbody_nu(nu, T): """ Blackbody as a function of frequency (Hz) and temperature (K). Parameters ---------- nu : array_like Frequency in Hz. Returns ------- Jnu : ndarray Intensity with units of erg/s/cm^2/Hz/steradian See Also -------- blackbody_lam """ from constants import hplanck, c, kboltz return 2*hplanck*nu**3 / (c**2 * (np.exp(hplanck*nu / (kboltz*T)) - 1))
[docs]def blackbody_lam(lam, T): """ Blackbody as a function of wavelength (Angstroms) and temperature (K). Parameters ---------- lam : array_like Wavelength in Angstroms. Returns ------- Jlam : ndarray Intensity with units erg/s/cm^2/Ang/steradian See Also -------- blackbody_nu """ from constants import hplanck, c, kboltz # to cm lam = lam * 1e-8 # erg/s/cm^2/cm/sr Jlam = 2*hplanck*c**2 / (lam**5 * (np.exp(hplanck*c / (lam*kboltz*T)) - 1)) # erg/s/cm^2/Ang/sr return Jlam * 1e8

Contents