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 void paintItem(Graphics g, int x1, int y1, int x2, int y2) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); PaintableScale xScale = getPropertyValue(xScaleKey); PaintableScale yScale = getPropertyValue(yScaleKey); Color color = getPropertyValue(colorKey); Double min = xScale.getMin(), max = xScale.getMax(); Double range = max - min; int w = x2 - x1 + 1; int h = y2 - y1 + 1; int px = -1, py = -1; g.setColor(Color.black); if (xScale.getMin() < 0.0 && xScale.getMax() > 0.0) { double zf = xScale.fractionalOffset(0.0); int x = x1 + (int) Math.round(zf * (double) w); g.drawLine(x, y1, x, y2); } if (yScale.getMin() < 0.0 && yScale.getMax() > 0.0) { double zf = yScale.fractionalOffset(0.0); int y = y2 - (int) Math.round(zf * (double) h); g.drawLine(x1, y, x2, y); } g.setColor(color); for (int x = x1; x <= x2; x++) { Double xInput = min + ((double) (x - x1) / (double) w) * range; Double yOutput = function.eval(xInput); if (yOutput != null) { double yf = yScale.fractionalOffset(yOutput); int y = y2 - (int) Math.round(yf * (double) h); if (px != -1 && py != -1) { g.drawLine(px, py, x, y); } px = x; py = y; } else { px = py = -1; } } }
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!"); }