/**
 * Newtonian solver, works by moving along the curve in the direction of gradient.
 * Solving for f(x) = 0
 * @param {function(number):number} f Function for which we are trying to solve
 * @param {number} xStart initial guess for input value
 * @param {number} [max_steps]
 * @param {number} [eps]
 * @returns {number} value for X where function is close to 0 or exactly at 0
 */
export function newton_solver_1d(
    f,
    xStart,
    max_steps = 1000,
    eps = 1e-7
) {
    let x = xStart, fx;

    let remaining_steps = max_steps;

    while ((remaining_steps--) && Math.abs(fx = f(x)) > eps) {

        const fx_eps = f(x + eps);

        const dfdx = (fx_eps - fx) / eps;

        x = x - fx / dfdx;

    }

    return x;
}
