in plot-base/src/commonMain/kotlin/org/jetbrains/letsPlot/core/plot/base/stat/math3/UnivariateSolverUtils.kt [90:160]
fun forceSide(
maxEval: Int, f: UnivariateFunction,
bracketing: BracketedUnivariateSolver<UnivariateFunction>,
baseRoot: Double, min: Double, max: Double,
allowedSolution: AllowedSolution
): Double {
if (allowedSolution == AllowedSolution.ANY_SIDE) {
// no further bracketing required
return baseRoot
}
// find a very small interval bracketing the root
val step = max(
bracketing.absoluteAccuracy,
abs(baseRoot * bracketing.relativeAccuracy)
)
var xLo = max(min, baseRoot - step)
var fLo = f.value(xLo)
var xHi = min(max, baseRoot + step)
var fHi = f.value(xHi)
var remainingEval = maxEval - 2
while (remainingEval > 0) {
if (fLo >= 0 && fHi <= 0 || fLo <= 0 && fHi >= 0) {
// compute the root on the selected side
return bracketing.solve(remainingEval, f, xLo, xHi, baseRoot, allowedSolution)
}
// try increasing the interval
var changeLo = false
var changeHi = false
if (fLo < fHi) {
// increasing function
if (fLo >= 0) {
changeLo = true
} else {
changeHi = true
}
} else if (fLo > fHi) {
// decreasing function
if (fLo <= 0) {
changeLo = true
} else {
changeHi = true
}
} else {
// unknown variation
changeLo = true
changeHi = true
}
// update the lower bound
if (changeLo) {
xLo = max(min, xLo - step)
fLo = f.value(xLo)
remainingEval--
}
// update the higher bound
if (changeHi) {
xHi = min(max, xHi + step)
fHi = f.value(xHi)
remainingEval--
}
}
error("NoBracketing")
//Exception - FAILED_BRACKETING xLo:$xLo, xHi: $xHi, fLo: $fLo, fHi: $fHi, maxEval: ${maxEval - remainingEval}, maxEval: $maxEval, baseRoot: $baseRoot, min: $min, max: $max")
}