public static double findZero(FunctionModel f, double start, double eps) { double[] bounds = findZeroBrackets(f, start); double lower = bounds[0], upper = bounds[1]; double ly = f.eval(lower), uy = f.eval(upper); // System.out.println(String.format("Zero: [%f, %f] (%f, %f)", lower, upper, ly, uy)); boolean lsign = ly < 0.0; boolean usign = uy <= 0.0; while (Math.abs(upper - lower) > eps) { double middle = (upper + lower) / 2.0; double my = f.eval(middle); boolean msign = my < 0.0; if (my == 0.0) { return middle; } else if (msign == lsign) { lower = middle; ly = my; lsign = msign; // System.out.println(String.format("\tU: [%f, %f] (%f, %f)", lower, upper, ly, uy)); } else { upper = middle; uy = my; usign = msign; // System.out.println(String.format("\tL: [%f, %f] (%f, %f)", lower, upper, ly, uy)); } } double v = (lower + upper) / 2.0; // System.out.println(String.format("\t-> %f", v)); return v; }
public static double[] findZeroBrackets(FunctionModel f, double start) { double fstart = f.eval(start); if (Double.isInfinite(fstart) || Double.isNaN(fstart)) { throw new IllegalArgumentException( String.format("Illegal start: %f (%f)", start, f.eval(start))); } boolean sign = fstart >= 0.0; double lowerSpace = 1.0, upperSpace = 1.0; double upper = start + upperSpace, lower = start - lowerSpace; double pupper = start, plower = start; double fupper = f.eval(upper), flower = f.eval(lower); boolean usign = fupper >= 0.0, lsign = flower >= 0.0; int iters = 0; while ((isBad(fupper) || usign == sign) && (isBad(flower) || lsign == sign)) { iters += 1; if (isBad(fupper)) { upperSpace /= 2.0; upper -= upperSpace; } else { upperSpace *= 2.0; upper += upperSpace; } fupper = f.eval(upper); usign = fupper >= 0.0; if (isBad(flower)) { lowerSpace /= 2.0; lower += lowerSpace; } else { lowerSpace *= 2.0; lower -= lowerSpace; } flower = f.eval(lower); lsign = flower >= 0.0; } if (usign != sign) { // System.out.println(String.format("\n%f -> (%f, %f]", start, start, upper)); return new double[] {start, upper}; } if (lsign != sign) { // System.out.println(String.format("\n%f -> [%f, %f)", start, lower, start)); return new double[] {lower, start}; } throw new IllegalArgumentException("Couldn't find zero brackets!"); }