예제 #1
0
 def _betainc(_a, _b, _y):
     comp = (_a + 1.0) / (_a + _b + 2.0)
     _cy = 1.0 - _y
     _poverbeta = pow(_y, _a) * pow(_cy, _b) / beta(_a, _b)
     if _y < comp:
         bi = _poverbeta * _betaicf(_a, _b, _y, tolf, itmax) / _a
     else:
         bi = 1.0 - _poverbeta * _betaicf(_b, _a, _cy, tolf, itmax) / _b
     return bi
예제 #2
0
 def _betainc(_a, _b, _y):
     comp = (_a + 1.0) / (_a + _b + 2.0)
     _cy = 1.0 - _y
     _poverbeta = pow(_y, _a) * pow(_cy, _b) / beta(_a, _b)
     if _y < comp:
         bi = _poverbeta * _betaicf(_a, _b, _y, tolf, itmax) / _a
     else:
         bi = 1.0 - _poverbeta * _betaicf(_b, _a, _cy, tolf, itmax) / _b
     return bi
예제 #3
0
def cbeta(a, b, x1, x2, x, betaab=False, tolf=FOURMACHEPS, itmax=128):
    """
    The cdf of the beta distribution:
    f = x**(a-1) * (1-x)**(b-1) / beta(a, b)
    a, b >= 0; 0 <= x <= 1
    F is the integral = the incomplete beta or the incomplete beta ratio 
    function depending on how the incomplete beta function is defined.

    NB It is possible to gain efficiency by providing the value of the complete 
    beta function beta(a, b) as a pre-computed input (may be computed using 
    numlib.specfunc.beta) instead of the default "False".

    a and/or b <= 1 is handled using a recurrence formula from Abramowitz & 
    Stegun (G is the gamma function, B is the beta function and I is the 
    incomplete beta):
    I(a, b, x)   =  G(a+b) / (G(a+1)*G(b)) * x^a * (1-x)^b  +  I(a+1, b, x)
    G(a+b) / (G(a+1)*G(b)) = 1/(a*B(a, b))  
    I(a, b, x)   =  1 - I(b, a, 1-x)
    I(b, a, 1-x) =  G(a+b) / (G(b+1)*G(a)) * x^a * (1-x)^b  +  I(b+1, a, 1-x)
    So then - if a < 1:
    I(a, b, x)  =  1/(a*B(a, b)) * x^a * (1-x)^b  +  I(a+1, b, x)
    or, if b < 1:
    I(a, b, x)  =  1  -  1/(b*B(a, b)) * x^a * (1-x)^b  -  I(b+1, a, 1-x)
    If both a and b < 1 then first
    I(a+1, b, x)  =  1 - 1/(b*B(a+1, b)) * x^(a+1) * (1-x)^b - I(b+1, a+1, 1-x)
    and then
    I(a, b, x)  =  1/(a*B(a, b)) * x^a * (1-x)^b  +  I(a+1, b, x)

    For the general interval must hold that x2 > x1  !!!!
    """

    assert a >= 0.0, "both parameters must be non-negative in cbeta!"
    assert b >= 0.0, "both parameters must be non-negative in cbeta!"
    assert x2 >= x1, "support range must not be negative in cbeta!"
    assert x1 <= x and x <= x2, "variate must be within support range in cbeta!"

    if a == 1.0 and b == 1.0:
        return cunifab(x1, x2, x)

    y = (x - x1) / (x2 - x1)
    cy = 1.0 - y

    if y == 0.0:
        return 0.0
    if y == 1.0:
        return 1.0

    # -------------------------------------------------------------------------
    def _betainc(_a, _b, _y):
        comp = (_a + 1.0) / (_a + _b + 2.0)
        _cy = 1.0 - _y
        _poverbeta = pow(_y, _a) * pow(_cy, _b) / beta(_a, _b)
        if _y < comp:
            bi = _poverbeta * _betaicf(_a, _b, _y, tolf, itmax) / _a
        else:
            bi = 1.0 - _poverbeta * _betaicf(_b, _a, _cy, tolf, itmax) / _b
        return bi

    # -------------------------------------------------------------------------

    if betaab:
        betaf = betaab
    else:
        betaf = beta(a, b)

    if a <= 1.0 and b <= 1.0:
        ap1 = a + 1.0
        # beta(a, b)    = gamma(a) * gamma(b) / gamma(a+b)
        # beta(a+1, b)  = gamma(a+1) * gamma(b) / gamma(a+b+1)
        # gamma(a+1)    = a * gamma(a)
        # gamma(a+b+1)  = (a+b) * gamma(a+b)
        # beta(a+1, b)  = a * gamma(a) * gamma(b) / ((a+b)*gamma(a+b)) =
        #               = a * beta(a, b) / (a+b)
        betaf1 = a * beta(a, b) / (a + b)  # = beta(ap1, b)
        cdf = 1.0 - (1.0 / (b * betaf1)) * pow(y, ap1) * pow(cy, b) - _betainc(b + 1.0, ap1, cy)
        poverbeta = pow(y, a) * pow(cy, b) / betaf
        cdf += poverbeta / a

    elif a <= 1.0:
        poverbeta = pow(y, a) * pow(cy, b) / beta(a, b)
        cdf = poverbeta / a + _betainc(a + 1.0, b, y)

    elif b <= 1.0:
        poverbeta = pow(y, a) * pow(cy, b) / beta(a, b)
        cdf = 1.0 - poverbeta / b - _betainc(b + 1.0, a, cy)

    else:
        cdf = _betainc(a, b, y)

    cdf = kept_within(0.0, cdf, 1.0)

    return cdf
예제 #4
0
def cbeta(a, b, x1, x2, x, betaab=False, tolf=FOURMACHEPS, itmax=128):
    """
    The cdf of the beta distribution:
    f = x**(a-1) * (1-x)**(b-1) / beta(a, b)
    a, b >= 0; 0 <= x <= 1
    F is the integral = the incomplete beta or the incomplete beta ratio 
    function depending on how the incomplete beta function is defined.

    NB It is possible to gain efficiency by providing the value of the complete 
    beta function beta(a, b) as a pre-computed input (may be computed using 
    numlib.specfunc.beta) instead of the default "False".

    a and/or b <= 1 is handled using a recurrence formula from Abramowitz & 
    Stegun (G is the gamma function, B is the beta function and I is the 
    incomplete beta):
    I(a, b, x)   =  G(a+b) / (G(a+1)*G(b)) * x^a * (1-x)^b  +  I(a+1, b, x)
    G(a+b) / (G(a+1)*G(b)) = 1/(a*B(a, b))  
    I(a, b, x)   =  1 - I(b, a, 1-x)
    I(b, a, 1-x) =  G(a+b) / (G(b+1)*G(a)) * x^a * (1-x)^b  +  I(b+1, a, 1-x)
    So then - if a < 1:
    I(a, b, x)  =  1/(a*B(a, b)) * x^a * (1-x)^b  +  I(a+1, b, x)
    or, if b < 1:
    I(a, b, x)  =  1  -  1/(b*B(a, b)) * x^a * (1-x)^b  -  I(b+1, a, 1-x)
    If both a and b < 1 then first
    I(a+1, b, x)  =  1 - 1/(b*B(a+1, b)) * x^(a+1) * (1-x)^b - I(b+1, a+1, 1-x)
    and then
    I(a, b, x)  =  1/(a*B(a, b)) * x^a * (1-x)^b  +  I(a+1, b, x)

    For the general interval must hold that x2 > x1  !!!!
    """

    assert a >= 0.0, "both parameters must be non-negative in cbeta!"
    assert b >= 0.0, "both parameters must be non-negative in cbeta!"
    assert x2 >= x1, "support range must not be negative in cbeta!"
    assert x1 <= x and x <= x2, \
            "variate must be within support range in cbeta!"

    if a == 1.0 and b == 1.0: return cunifab(x1, x2, x)

    y = (x - x1) / (x2 - x1)
    cy = 1.0 - y

    if y == 0.0: return 0.0
    if y == 1.0: return 1.0

    # -------------------------------------------------------------------------
    def _betainc(_a, _b, _y):
        comp = (_a + 1.0) / (_a + _b + 2.0)
        _cy = 1.0 - _y
        _poverbeta = pow(_y, _a) * pow(_cy, _b) / beta(_a, _b)
        if _y < comp:
            bi = _poverbeta * _betaicf(_a, _b, _y, tolf, itmax) / _a
        else:
            bi = 1.0 - _poverbeta * _betaicf(_b, _a, _cy, tolf, itmax) / _b
        return bi

    # -------------------------------------------------------------------------

    if betaab: betaf = betaab
    else: betaf = beta(a, b)

    if a <= 1.0 and b <= 1.0:
        ap1 = a + 1.0
        # beta(a, b)    = gamma(a) * gamma(b) / gamma(a+b)
        # beta(a+1, b)  = gamma(a+1) * gamma(b) / gamma(a+b+1)
        # gamma(a+1)    = a * gamma(a)
        # gamma(a+b+1)  = (a+b) * gamma(a+b)
        # beta(a+1, b)  = a * gamma(a) * gamma(b) / ((a+b)*gamma(a+b)) =
        #               = a * beta(a, b) / (a+b)
        betaf1 = a * beta(a, b) / (a + b)  # = beta(ap1, b)
        cdf    = 1.0 - (1.0/(b*betaf1))*pow(y, ap1)*pow(cy, b) - \
                                                 _betainc(b+1.0, ap1, cy)
        poverbeta = pow(y, a) * pow(cy, b) / betaf
        cdf += poverbeta / a

    elif a <= 1.0:
        poverbeta = pow(y, a) * pow(cy, b) / beta(a, b)
        cdf = poverbeta / a + _betainc(a + 1.0, b, y)

    elif b <= 1.0:
        poverbeta = pow(y, a) * pow(cy, b) / beta(a, b)
        cdf = 1.0 - poverbeta / b - _betainc(b + 1.0, a, cy)

    else:
        cdf = _betainc(a, b, y)

    cdf = kept_within(0.0, cdf, 1.0)

    return cdf