示例#1
0
  /** {@inheritDoc} */
  public double solve(final UnivariateRealFunction f, double min, double max)
      throws MaxIterationsExceededException, FunctionEvaluationException {

    clearResult();
    verifyInterval(min, max);
    double m;
    double fm;
    double fmin;

    int i = 0;
    while (i < maximalIterationCount) {
      m = UnivariateRealSolverUtils.midpoint(min, max);
      fmin = f.value(min);
      fm = f.value(m);

      if (fm * fmin > 0.0) {
        // max and m bracket the root.
        min = m;
      } else {
        // min and m bracket the root.
        max = m;
      }

      if (Math.abs(max - min) <= absoluteAccuracy) {
        m = UnivariateRealSolverUtils.midpoint(min, max);
        setResult(m, i);
        return m;
      }
      ++i;
    }

    throw new MaxIterationsExceededException(maximalIterationCount);
  }
  /**
   * For this distribution, X, this method returns the critical point x, such that P(X &lt; x) =
   * <code>p</code>.
   *
   * @param p the desired probability
   * @return x, such that P(X &lt; x) = <code>p</code>
   * @throws MathException if the inverse cumulative probability can not be computed due to
   *     convergence or other numerical errors.
   * @throws IllegalArgumentException if <code>p</code> is not a valid probability.
   */
  public double inverseCumulativeProbability(final double p) throws MathException {
    if (p < 0.0 || p > 1.0) {
      throw MathRuntimeException.createIllegalArgumentException(
          "{0} out of [{1}, {2}] range", p, 0.0, 1.0);
    }

    // by default, do simple root finding using bracketing and default solver.
    // subclasses can overide if there is a better method.
    UnivariateRealFunction rootFindingFunction =
        new UnivariateRealFunction() {
          private static final long serialVersionUID = 1043729002768873023L;

          public double value(double x) throws FunctionEvaluationException {
            try {
              return cumulativeProbability(x) - p;
            } catch (MathException ex) {
              throw new FunctionEvaluationException(ex, x, ex.getPattern(), ex.getArguments());
            }
          }
        };

    // Try to bracket root, test domain endoints if this fails
    double lowerBound = getDomainLowerBound(p);
    double upperBound = getDomainUpperBound(p);
    double[] bracket = null;
    try {
      bracket =
          UnivariateRealSolverUtils.bracket(
              rootFindingFunction, getInitialDomain(p), lowerBound, upperBound);
    } catch (ConvergenceException ex) {
      /*
       * Check domain endpoints to see if one gives value that is within
       * the default solver's defaultAbsoluteAccuracy of 0 (will be the
       * case if density has bounded support and p is 0 or 1).
       *
       * TODO: expose the default solver, defaultAbsoluteAccuracy as
       * a constant.
       */
      if (Math.abs(rootFindingFunction.value(lowerBound)) < 1E-6) {
        return lowerBound;
      }
      if (Math.abs(rootFindingFunction.value(upperBound)) < 1E-6) {
        return upperBound;
      }
      // Failed bracket convergence was not because of corner solution
      throw new MathException(ex);
    }

    // find root
    double root = UnivariateRealSolverUtils.solve(rootFindingFunction, bracket[0], bracket[1]);
    return root;
  }