def _binary_search(error_fn, low_value, high_value):
  """Binary search for a function given start and end interval.

  This is a simple binary search over the values of the function error_fn given
  the interval [low_value, high_value]. We expect that the starting condition is
  error_fn(low_value) < 0 and error_fn(high_value) > 0 and we bisect the
  interval until the exit conditions are met. The result is the final interval
  [low_value, high_value] that is normally much smaller than the initial one,
  but still satisfying the starting condition.

  Args:
    error_fn: Function mapping values to errors.
    low_value: Lower interval endpoint. We expect f(low_value) < 0.
    high_value: Higher interval endpoint. We expect f(high_value) > 0.

  Returns:
    The final interval endpoints (low_value, high_value) after the sequence of
    bisections.
  """
  # Exit conditions.
  stop_iter_step = 10  # Max number of iterations.
  stop_error_step = 1e-6  # Minimum function variation.
  stop_value_step = 1e-6  # Minimum variable variation.

  current_iter = 0
  while True:
    current_value = (low_value + high_value) / 2.0
    current_error = error_fn(current_value)
    if current_error < 0.0:
      low_value = current_value
    else:
      high_value = current_value
    current_iter += 1
    if (current_iter > stop_iter_step or
        np.abs(current_error) < stop_error_step or
        high_value - low_value < stop_value_step):
      break
  return low_value, high_value
Binary search for a function given start and end interval.

  This is a simple binary search over the values of the function error_fn given
  the interval [low_value, high_value]. We expect that the starting condition is
  error_fn(low_value) < 0 and error_fn(high_value) > 0 and we bisect the
  interval until the exit conditions are met. The result is the final interval
  [low_value, high_value] that is normally much smaller than the initial one,
  but still satisfying the starting condition.

  Args:
    error_fn: Function mapping values to errors.
    low_value: Lower interval endpoint. We expect f(low_value) < 0.
    high_value: Higher interval endpoint. We expect f(high_value) > 0.

  Returns:
    The final interval endpoints (low_value, high_value) after the sequence of
    bisections.
  
tensorflow_transform/gaussianization.py