fun forceSide()

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")
    }