LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
}
// by default, do simple root finding using bracketing and default solver.
// subclasses can override if there is a better method.
UnivariateRealFunction rootFindingFunction =
new UnivariateRealFunction() {
public double value(double x) throws FunctionEvaluationException {
double ret = Double.NaN;
try {
ret = cumulativeProbability(x) - p;
} catch (MathException ex) {
throw new FunctionEvaluationException(x, ex.getSpecificPattern(), ex.getGeneralPattern(), ex.getArguments());
}
if (Double.isNaN(ret)) {
throw new FunctionEvaluationException(x, LocalizedFormats.CUMULATIVE_PROBABILITY_RETURNED_NAN, x, p);
}
return ret;
}
};
// Try to bracket root, test domain endpoints 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).
*/
if (FastMath.abs(rootFindingFunction.value(lowerBound)) < getSolverAbsoluteAccuracy()) {
return lowerBound;
}
if (FastMath.abs(rootFindingFunction.value(upperBound)) < getSolverAbsoluteAccuracy()) {
return upperBound;
}
// Failed bracket convergence was not because of corner solution
throw new MathException(ex);
}