import java.util.function.DoubleFunction;

public class RegulaFalsi {

    public static double solve(double s, double t, DoubleFunction<Double> f, DoubleFunction<Double> fprime)
    {
        double epsilon = 1e-10;
        int maxIterations = 50;
        double r = 0.0, fr;
        int n, side = 0;

        // starting values at endpoints of interval
        double fs = f.apply(s);
        double ft = f.apply(t);

        for (n = 0; n < maxIterations; n++) {

            r = (fs * t - ft * s) / (fs - ft);
            if (Math.abs(t - s) < epsilon * Math.abs(t + s)) {
                break;
            }
            fr = f.apply(r);

            if (fr * ft > 0) {
                // fr and ft have same sign, copy r to t
                t = r;
                ft = fr;
                if (side == -1) {
                    fs /= 2;
                }
                side = -1;
            }
            else if (fs * fr > 0) {
                // fr and fs have same sign, copy r to s
                s = r;
                fs = fr;
                if (side == +1) {
                    ft /= 2;
                }
                side = +1;
            }
            else {
                // fr * f_ very small (looks like zero)
                break;
            }
        }

        return r;
    }
}