package ballistics.utils.math.minmax

import kotlin.math.sqrt

class MinMaxGoldenSectCalculator : AbstractMinMaxCalculator() {
    val tau = (sqrt(5.0) - 1) / 2

    override fun calculate(
        x1: Double,
        x2: Double,
        f: (Double) -> Double,
    ): Double? {
        var iteration = 0
        var x: Double?
        var xl = x1
        var xr = x2
        var x11: Double = xl + (1 - tau) * (xr - xl)
        var x22: Double = xl + tau * (xr - xl)

        var d = x22 - x11
        if (d < 0) d *= -1.0

        //x = x1

        var y1 = f(x11)
        var y2 = f(x22)

        while (d > delta) {
            if (sign * y1 > sign * y2) {
                xl = x11
                x11 = x22
                y1 = y2
                x22 = xl + tau * (xr - xl)
                y2 = f(x22)
            } else {
                xr = x22
                x22 = x11
                y2 = y1
                x11 = xl + (1 - tau) * (xr - xl)
                y1 = f(x11)
            }
            d = x22 - x11
            if (d < 0) d *= -1.0
            iteration++
        }

        x = (x11 + x22) / 2
        return if (iteration < maxIterations) x else null
    }
}
