Esempio n. 1
0
def icoxian2(prob, means, probs):
    """
    The Coxian phased distribution, which is based on the exponential.
    probs is a list of probabilities for GOING ON TO THE NEXT PHASE rather 
    than reaching the absorbing state prematurely. The number of means must 
    (of course) be one more than the number of probabilities! 
    
    NB No two means[k] must be equal - if equal means are is desired, use 
    icoxian instead (slower, however). 
    """

    _assertprob(prob, 'icoxian2')
    # Everything else will be checked in dcoxian2 and ccoxian2

   # ------------------------------------
    def _fifi2fid(x):
        x      = kept_within(0.0, x)
        cdf    = ccoxian2(means, probs, x)
        pdf    = dcoxian2(means, probs, x)
        fi     = cdf - prob
        if pdf <= 0.0:
            if fi == 0.0: fi2fid = 1.0
            else:         fi2fid = MAXFLOAT
        else:
            fi2fid = fi/pdf
        return fi, fi2fid
   # ------------------------------------

    x = znewton(_fifi2fid, 0.0, 'icoxian2', tolf=SQRTMACHEPS)

    x = kept_within(0.0, x)
    
    return x
Esempio n. 2
0
def ierlang(prob, nshape, phasemean=1.0):
    """
    Represents the sum of nshape exponentially distributed random variables, 
    each having the same mean value = phasemean 
    """

    _assertprob(prob, 'ierlang')
    # Everything else will be checked in iexpo, cerlang and derlang

    if nshape == 1:
        x = iexpo(prob, phasemean)

    else:
       # ------------------------------------
        def _fifi2fid(x):
            x      = kept_within(0.0, x)
            cdf    = cerlang(nshape, phasemean, x)
            pdf    = derlang(nshape, phasemean, x)
            fi     = cdf - prob
            if pdf <= 0.0:
                if fi == 0.0: fi2fid = 1.0
                else:         fi2fid = MAXFLOAT
            else:
                fi2fid = fi/pdf
            return fi, fi2fid
       # ------------------------------------

        x = znewton(_fifi2fid, (nshape-1.0)*phasemean, 'ierlang', \
                                                     tolf=SQRTMACHEPS)

        x = kept_within(0.0, x)
    
    return x
Esempio n. 3
0
def iNexpo2(prob, means):
    """
    A distribution of a sum of exponential random variables.
    
    NB No two means are allowed to be equal!!!! 
    """

    _assertprob(prob, 'iNexpo2')
    # Everything else will be checked in iexpo, cNexpo2 and dNexpo2

    if len(means) == 1:
        x = iexpo(prob, means[0])

    else:
       # ------------------------------------
        def _fifi2fid(x):
            x      = kept_within(0.0, x)
            cdf    = cNexpo2(means, x)
            pdf    = dNexpo2(means, x)
            fi     = cdf - prob
            if pdf <= 0.0:
                if fi == 0.0: fi2fid = 1.0
                else:         fi2fid = MAXFLOAT
            else:
                fi2fid = fi/pdf
            return fi, fi2fid
       # ------------------------------------

        x = znewton(_fifi2fid, max(means), 'iNexpo2', tolf=SQRTMACHEPS)

        x = kept_within(0.0, x)
    
    return x
Esempio n. 4
0
def igamma(prob, alpha, lam=1.0, lngalpha=False, tolf=FOURMACHEPS, itmax=128):
    """
    The gamma distrib. f = lam * exp(-lam*x) * (lam*x)**(alpha-1) / gamma(alpha)
    F is the integral = the incomplete gamma or the incomplete gamma / complete 
    gamma depending on how the incomplete gamma function is defined.
    x, lam, alpha >= 0

    NB It is possible to provide the value of the natural logarithm of the 
    complete gamma function lngamma(alpha) as a pre-computed input (may be 
    computed using numlib.specfunc.lngamma) instead of the default "False", 
    a feature that will make igamma more than 50 % faster!

    tolf and itmax are the numerical control parameters of cgamma.
    """

    _assertprob(prob, 'igamma')
    # Everything else will be checked in cgamma and dgamma

    f, i = modf(alpha)
    if f == 0.0 and lam > 0.0: return ierlang(prob, int(i), 1.0/lam)

   # --------------------------------------------
    def _fifi2fid(x):
        x      = kept_within(0.0, x)
        cdf    = cgamma(alpha, lam, x, lngalpha, tolf, itmax)
        pdf    = dgamma(alpha, lam, x, lngalpha)
        fi     = cdf - prob
        if pdf <= 0.0:
            if fi == 0.0: fi2fid = 1.0
            else:         fi2fid = MAXFLOAT
        else:
            fi2fid = fi/pdf
        return fi, fi2fid
   # -------------------------------------------

    if alpha >= 2.0:  mean = alpha/lam
    else:             mean = SQRTMACHEPS
    x = znewton(_fifi2fid, mean, 'igamma', tolf=SQRTMACHEPS)

    x = kept_within(0.0, x)
    
    return x
Esempio n. 5
0
def istable_sym(prob, alpha, location=0.0, scale=1.0):
    """
    The inverse of a SYMMETRICAL stable distribution where alpha is the tail 
    exponent. For numerical reasons alpha is restricted to [0.25, 0.9] and 
    [1.125, 1.9] - but alpha = 1.0 (the Cauchy) and alpha = 2.0 (scaled normal) 
    are allowed!

    Numerics are somewhat crude but the fractional error is < 0.001 - and the
    absolute error is almost always < 0.001 - sometimes much less... 

    NB This function is slow, particularly for small alpha !!!!!
    """

    _assertprob(prob, 'istable_sym')
    # Everything else will be checked in cstable_sym and dstable_sym!

    if alpha == 1.0: return icauchy(prob, location, scale)
    if alpha == 2.0: return inormal(prob, location, SQRT2*scale)

    if prob == 0.0: return -float('-inf')
    if 0.5-MACHEPS <= prob and prob <= 0.5+MACHEPS: return location
    if prob == 1.0: return  float('inf')

   # -----------------------------------------------
    def _fifi2fid(x):
        cdf  = cstable_sym(alpha, location, scale, x)
        pdf  = dstable_sym(alpha, location, scale, x)
        fi   = cdf - prob
        if pdf <= 0.0:
            if fi == 0.0: fi2fid = 1.0
            else:         fi2fid = MAXFLOAT
        else:
            fi2fid = fi/pdf
        return fi, fi2fid
   # -----------------------------------------------

    tolr = 4.8828125e-4  # = 0.5**11 - no reason to spend excess. accuracy here!
    x = znewton(_fifi2fid, location, 'istable_sym', tolf=tolr, tola=MACHEPS)

    return x
Esempio n. 6
0
def ierlang_gen(prob, nshapes, qumul, phasemean=1.0):
    """
    The inverse of the generalized Erlang distribution - the Erlang 
    equivalent of the hyperexpo distribution f = sumk pk * ferlang(m, nk), 
    F = sumk pk * Ferlang(m, nk), the same mean for all phases.
    
    NB Input to the function is the list of CUMULATIVE FREQUENCIES ! 
    
    NB Slow function !
    """

    _assertprob(prob, 'iexpo')
    # Everything else will be checked in cerlang_gen and derlang_gen

    if len(nshapes) == 1 and len(qumul) == 1 and qumul[0] == 1.0:
        x = ierlang(nshapes[0], phasemean)

    else:
       # -----------------------------------
        def _fifi2fid(x):
            x      = kept_within(0.0, x)
            cdf    = cerlang_gen(nshapes, qumul, phasemean, x)
            pdf    = derlang_gen(nshapes, qumul, phasemean, x)
            fi     = cdf - prob
            if pdf <= 0.0:
                if fi == 0.0: fi2fid = 1.0
                else:         fi2fid = MAXFLOAT
            else:
                fi2fid = fi/pdf
            return fi, fi2fid
       # ------------------------------------

        x = znewton(_fifi2fid, phasemean, 'ierlang_gen', tolf=SQRTMACHEPS)

        x = kept_within(0.0, x)

    return x
Esempio n. 7
0
def ihyperexpo(prob, means, qumul):
    """
    The inverse of the hyperexponential distribution 
    f = sumk pk * exp(x/mk) / mk
    F = sumk pk * (1-exp(x/mk)) 
    
    NB Input to the function is the list of CUMULATIVE FREQUENCIES ! 
    
    NB Slow function ! 
    """

    _assertprob(prob, 'ihyperexpo')
    # Everything else will be checked in iexpo, chyperexpo and dhyperexpo

    if len(means) == 1 and len(qumul) == 1 and qumul[0] == 1.0:
        x = iexpo(prob, means[0])

    else:
       # ------------------------------------
        def _fifi2fid(x):
            x      = kept_within(0.0, x)
            cdf    = chyperexpo(means, qumul, x)
            pdf    = dhyperexpo(means, qumul, x)
            fi     = cdf - prob
            if pdf <= 0.0:
                if fi == 0.0: fi2fid = 1.0
                else:         fi2fid = MAXFLOAT
            else:
                fi2fid = fi/pdf
            return fi, fi2fid
       # ------------------------------------

        x = znewton(_fifi2fid, 0.0, 'ihyperexpo', tolf=SQRTMACHEPS)
        x = kept_within(0.0, x)

    return x
Esempio n. 8
0
def ifoldednormal(prob, muunfold, sigmaunfold):
    """
    The inverse of a distribution of a random variable that is the absolute 
    value of a variate drawn from the normal distribution (i. e. the 
    distribution of a variate that is the absolute value of a normal variate, 
    the latter having muunfold as its mean and sigmaunfold as its standard 
    deviation). 
    
    sigmaunfold >= 0.0
    """

    _assertprob(prob, 'ifoldednormal')
    # Everything else will be checked in cfoldednormal and dfoldednormal

   # --------------------------------------------
    def _fifi2fid(x):
        x      = kept_within(0.0, x)
        cdf    = cfoldednormal(muunfold, sigmaunfold, x)
        pdf    = dfoldednormal(muunfold, sigmaunfold, x)
        fi     = cdf - prob
        if pdf <= 0.0:
            if fi == 0.0: fi2fid = 1.0
            else:         fi2fid = MAXFLOAT
        else:
            fi2fid = fi/pdf
        return fi, fi2fid
   # -------------------------------------------

    a = abs(muunfold)
    if a/sigmaunfold > 1.0: start =  a
    else:                   start = 0.0
    x  =  znewton(_fifi2fid, start, 'ifoldednormal', tolf=SQRTMACHEPS)

    x  =  kept_within(0.0, x)
    
    return x
Esempio n. 9
0
    def __init__(self, sequence, fraction, time_to):
        """
        Inputs to the class are the list or tuple containing the keys or range 
        associated with the state variables involved in the specific delay 
        (that also determines the order of the delay). 
        
        The characteristic time (time constant) of the delay is computed for 
        later use: if "fraction" is the string 'peak' the time constant for 
        an exponential delay of the present order for the time "time_to" for 
        the response to a delta (spike/pulse/Dirac) input to reach its peak. 
        For "fraction" in [0.0, 1.0] "time_to" is used to compute the time 
        constant for the response to a step input to reach the given fraction 
        of the step height. (The time to the peak and the time to a certain 
        fraction are referred to as "time to rise point" in the error messaging)
        """

        self.__sequence = sequence
        self.__nstop    = len(sequence)
        self.__ndelay   = self.__nstop - 1

        assert time_to >= 0.0, \
               "time to rise point must be a non-negative float in ExpDelay!"

        if fraction == 'peak':
            tau = time_to / self.__ndelay

        else:
            assert 0.0 <= fraction and fraction <= 1.0, \
                "fraction must be in [0.0, 1.0] in ExpDelay!"

            q = 1.0 - fraction
            # ------------------------------------
            def _taudelay(theta):
                fi  = 0.0
                fid = 0.0
                expfactor  = exp(-theta)
                plusfactor = exp( theta)

                if self.__ndelay == 1:
                    fi  = q - expfactor
                    #fid = expfactor
                    fid = plusfactor*q - 1.0
                else:
                    a   = 1.0
                    sum = a
                    for k in range(1, self.__ndelay):
                        a   = a * theta / k
                        sum = sum + a
                    fi  = q - expfactor*sum
                    #fid = expfactor * a
                    fid = (plusfactor*q - sum) / a
                    #fid = fi / fid

                return fi, fid
            # -------------------------------------

            start  = self.__ndelay - ExpDelay.__ONETHIRD
            tchar  = znewton(_taudelay, start, 'ExpDelay')
            tau    = time_to / tchar
            tau    = kept_within(0.0, tau)


        self.lam  = 1.0 / tau