def __cmp__(self, other): if isinstance(other, Infinity): d_cmp = math_tools.cmp(self.direction, other.direction) if d_cmp != 0: return d_cmp else: raise InfinityRaceError elif is_floatable(other): return self.direction else: raise NotImplementedError
def __get_node_by_monotonic_function_with_both_rounding(self, function, value): ''' Get a node by specifying a measure function and a desired value. The function must be a monotonic rising function on the timeline. The rounding option used is `binary_search.BOTH`. Note that this function does not let you specify a tail node. Currently we're not optimizing for the case where you have a tail node and this function might waste resources exploring beyond it. ''' root = self.root cmp_root = cmp(function(root), value) if cmp_root == 1: # function(root) > value return (None, root) if cmp_root == 0: # function(root) == value return (root, root) assert cmp_root == -1 # and function(root) < value # Now we've established that the first node in the path has a strictly # lower value than what we're looking for. # A rule we will strictly obey in this function: `low` will always be a # member whose value is lower than the desired value. (Strictly lower, # meaning not lower-or-equal.) low = self.root for thing in self.iterate_blockwise(): # Rule: Every time we inspect a new node/block, `low` will be the # node that is its immediate parent. i.e. The highest node possible # from those that we have previously examined. if isinstance(thing, Block): block = thing first = block[0] cmp_first = cmp(function(first), value) if cmp_first == -1: # function(first) < value low = first elif cmp_first == 0: # function(first) == value return (first, first) else: # cmp_first == 1 and function(first) > value return (low, first) # At this point we know that the first node in the block has a # strictly lower value than the target value. last = block[-1] cmp_last = cmp(function(last), value) if cmp_last == -1: # function(last) < value low = last continue elif cmp_last == 0: # function(last) == value return (last, last) else: # cmp_last == 1 and function(last) > value # The two final results are both in the block. return binary_search.binary_search( block, function, value, rounding=binary_search.BOTH ) else: # thing is a Node node = thing cmp_node = cmp(function(node), value) if cmp_node == -1: # function(node) < value low = node continue elif cmp_node == 0: # function(node) == value return (node, node) else: # function(node) > value return (low, node) # If the flow reached here, that means that even the last node in the # path has lower value than the value we're looking for. return (low, None)