/**
   * Generic means to compute inverse cumulative probability values. This method uses the bisection
   * method to find inverse CDF values.
   *
   * @param p the cumulative probability.
   * @param lower the global lower bound of the inverse CDF value.
   * @param initial an initial guess at the inverse CDF value.
   * @param upper the global upper bound of the inverse CDF value.
   * @return x such that P(X < x) = p
   * @throws NumericException if the inverse cumulative probability can not be computed.
   */
  protected double findInverseCumulativeProbability(
      final double p, double lower, double initial, double upper) throws NumericException {
    Function f =
        new Function() {
          public double evaluate(double x) throws NumericException {
            return cumulativeProbability(x) - p;
          }
        };

    Bracket b = new Bracket(f);
    double[] bracket = b.bracketOut(lower, initial, upper);

    BisectionRootFinder bisection = new BisectionRootFinder(f);
    return bisection.findRoot(bracket[0], bracket[1]);
  }