def ternary_search(f, lo, hi, gap=1e-10):
    """Ternary maximum search for a bitonic function

    :param f: boolean bitonic function (increasing then decreasing, not necessarily strictly)
    :param int lo:
    :param int hi: with hi >= lo
    :param float gap:
    :returns: value x in [lo,hi] maximizing f(x),
             x is computed up to some precision
    :complexity: `O(log((hi-lo)/gap))`
    """
    while hi - lo > gap:
        step = (hi - lo) / 3.0
        if f(lo + step) < f(lo + 2 * step):
            lo += step
        else:
            hi -= step
    return lo
