in commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/AbstractContinuousDistribution.java [376:407]
private double searchPlateau(boolean complement, double lower, final double x) {
// Test for plateau. Lower the value x if the probability is the same.
// Ensure the step is robust to the solver accuracy being less
// than 1 ulp of x (e.g. dx=0 will infinite loop)
final double dx = Math.max(SOLVER_ABSOLUTE_ACCURACY, Math.ulp(x));
if (x - dx >= lower) {
final DoubleUnaryOperator fun = complement ?
this::survivalProbability :
this::cumulativeProbability;
final double px = fun.applyAsDouble(x);
if (fun.applyAsDouble(x - dx) == px) {
double upperBound = x;
double lowerBound = lower;
// Bisection search
// Require cdf(x) < px and sf(x) > px to move the lower bound
// to the midpoint.
final DoubleBinaryOperator cmp = complement ?
(a, b) -> a > b ? -1 : 1 :
(a, b) -> a < b ? -1 : 1;
while (upperBound - lowerBound > dx) {
final double midPoint = 0.5 * (lowerBound + upperBound);
if (cmp.applyAsDouble(fun.applyAsDouble(midPoint), px) < 0) {
lowerBound = midPoint;
} else {
upperBound = midPoint;
}
}
return upperBound;
}
}
return x;
}