Exemplo n.º 1
0
def ichistogram_int(prob, values, qumul):
    """
    Calculates the inverse value of an input CUMULATIVE histogram.
    'values' is a list/tuple with INTEGERS in ascending order - A MUST! 
    These values represent bin end points and must be one more than 
    the number of cumulative frequencies, and where...
    ...'qumul' are the corresponding CUMULATIVE FREQUENCIES such that 
    qumul[k] = P(x<=values[k+1]).

    NB The first element of the values list is will never be returned!
    The first integer to be returned is values[0] + 1   !!!!

    The cumulative frequencies must of course obey qumul[k+1] >= qumul[k],
    otherwise an exception will be raised!
        
    The values of the integer random variate are assumed to be uniformly 
    distributed within each bin.
    """

    nvalues = len(values)
    nqumul = len(qumul)

    # Input check ---
    _assertprob(prob, 'ichistogram_int')
    errtxt1 = "Lengths of input lists are incompatible in ichistogram_int!"
    assert nqumul == nvalues-1, errtxt1
    assert qumul[-1]  == 1.0
    assert 0.0 <= qumul[0] and qumul[0] <= 1.0
    # ---
    errtxt2 = "qumul list is not in order in ichistogram_int!"
    for k in range(1, nqumul):
        assert qumul[k] >= qumul[k-1], errtxt2
        pass
    # ---
    errtxt3 = "all values in values list must be integers in ichistogram_int!"
    errtxt4 = "values list is not in order in ichistogram_int!"
    assert is_integer(values[0]), errtxt3
    for k in range(1, nvalues):
        assert is_integer(values[k]), errtxt3
        assert values[k] >= values[k-1], errtxt4
        pass
    # ---

    # The routine itself.................

    pcopy = list(qumul)
    pcopy.insert(0, 0.0)

    k      = bisect(pcopy, prob)      # bisect used instead of binSearch
    pdiff  = prob - pcopy[k-1]
    pinter = pcopy[k]  - pcopy[k-1]
    vinter = values[k] - values[k-1]
    x      = values[k-1] + vinter*pdiff/float(pinter)
    x      = int(x+1.0)

    return x
Exemplo n.º 2
0
    def splice(self, offset, length, x):
        """
        Analogous to Perl's splice (but all arguments must be present and x 
        must be a single number/string or a list/stack)
        
        This is how it works: remove the slice self(offset:offset+length) 
        and replace it with the contents of x.
        
        If offset < 0 then the offset is from the bottom of the present 
        object and upward - offset will then be len(self) - abs(offset).
        
        If length < 0, then length = len(self) - 1 will be used.
        
        offset > len(self) or offset+length > len(self) is OK.
        
        Returns the slice removed as a stack (or None if nothing was removed).
        """

        assert is_integer(offset), "offset must be an integer in splice!"
        assert is_integer(length), "length must be an integer in splice!"
        if offset < 0: index1 = len(self) + offset
        else: index1 = offset
        errtxt = "Negative offset must not try to reach below the "
        errtxt += "bottom element of the object stack in splice!"
        assert index1 >= 0, errtxt
        if length < 0: index2 = len(self) - 1
        else: index2 = index1 + length

        try:
            removed = Stack(self[index1:index2])
            del self[index1:index2]
        except IndexError:
            removed = None
        if len(removed) == 0: removed = None

        if not isinstance(x, list): x = [x]
        for element in x:
            self.insert(index1, element)
            index1 += 1

        return removed  # A stack (or None)
Exemplo n.º 3
0
    def splice(self, offset, length, x):
        """
        Analogous to Perl's splice (but all arguments must be present and x 
        must be a single number/string or a list/stack)
        
        This is how it works: remove the slice self(offset:offset+length) 
        and replace it with the contents of x.
        
        If offset < 0 then the offset is from the bottom of the present 
        object and upward - offset will then be len(self) - abs(offset).
        
        If length < 0, then length = len(self) - 1 will be used.
        
        offset > len(self) or offset+length > len(self) is OK.
        
        Returns the slice removed as a stack (or None if nothing was removed).
        """

        assert is_integer(offset), "offset must be an integer in splice!"
        assert is_integer(length), "length must be an integer in splice!"
        if offset < 0: index1 = len(self) + offset
        else:          index1 = offset
        errtxt  = "Negative offset must not try to reach below the "
        errtxt += "bottom element of the object stack in splice!"
        assert index1 >= 0, errtxt
        if length < 0: index2 = len(self) - 1
        else:          index2 = index1 + length

        try:
            removed = Stack(self[index1:index2])
            del self[index1:index2]
        except IndexError:
            removed = None
        if len(removed) == 0: removed = None

        if not isinstance(x, list): x = [x]
        for element in x:
            self.insert(index1, element)
            index1 += 1

        return removed   # A stack (or None)