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
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)