code: static Interval gridSearch(UnivariateFunction fn, double start,
        double end, double step) {
      double lowMax = start;  // lower bound on interval surrounding alphaMax
      double alphaMax = start - step;
      double likMax = 0.0;
  
      double lastAlpha = start;
      double alpha = start;
      while (alpha < end) {
        double likelihood = fn.value(alpha);
        if (alphaMax < start || likelihood > likMax) {
          lowMax = lastAlpha;
          alphaMax = alpha;
          likMax = likelihood;
        }
        lastAlpha = alpha;
        alpha += step;
      }
      // make sure we've checked the rightmost endpoint (won't happen if
      // end - start is not an integer multiple of step, because of roundoff
      // errors, etc)
      double likelihood = fn.value(end);
      if (likelihood > likMax) {
        lowMax = lastAlpha;
        alphaMax = end;
        likMax = likelihood;
      }
      return new Interval(lowMax, Math.min(end, alphaMax + step));
    }
docs: Runs a grid search for the maximum value of a univariate function.
  
  @param fn the likelihood function to minimize
  @param start lower bound of the interval to search
  @param end upper bound of the interval to search
  @param step grid step size
  @return an Interval bracketing the minimum