def bounded_binary_search(generator, length, target, lower_bound, upper_bound):
    """
    efficient binary search for a <target> value within bounds [<lower_bound>, <upper_bound>]
    - converges to a locally optimal result within the bounds
    - instead of indexing an iterable, lazy evaluate a functor for performance
    :param generator: a generator or functor that yields a value of the search area given an index
    :param length: full length of the search area
    :param target: the value to search
    :param lower_bound: the lower bound up to which results are accepted
    :param upper_bound: the upper bound up to which results are accepted
    :return: success: (True, the index of the target) - fail: (False, -1)
    """
    start, mid = 0, -1
    end = length - 1
    residual = 0.0
    found = False
    num_iter = 0
    while start <= end and not found:
        num_iter += 1
        mid = (start + end) // 2
        val = generator(mid)
        if lower_bound <= val <= upper_bound:
            residual = abs(val - target)
            if abs(generator(mid - 1) - target) <= residual:
                end = mid - 1
                continue  # refinement possible in left direction
            elif abs(generator(mid + 1) - target) < residual:
                start = mid + 1
                continue  # refinement possible in right direction
            else:
                found = True  # converged
        if not found:
            if target < val:
                end = mid - 1
            else:
                start = mid + 1
    return found, mid, residual, num_iter