/** * Implements the bisection method for finding the root of a function. * * @param f Function the function * @param x1 double lower * @param x2 double upper * @param tol double computation tolerance * @return double the root or NaN if root not found */ public static double bisection(final Function f, double x1, double x2, final double tol) { int count = 0; int maxCount = (int) (Math.log(Math.abs(x2 - x1) / tol) / Math.log(2)); maxCount = Math.max(MAX_ITERATIONS, maxCount) + 2; double y1 = f.evaluate(x1), y2 = f.evaluate(x2); if (y1 * y2 > 0) { // y1 and y2 must have opposite sign OSPLog.fine(count + " bisection root - interval endpoints must have opposite sign"); return Double.NaN; // interval does not contain a root } while (count < maxCount) { double x = (x1 + x2) / 2; double y = f.evaluate(x); if (Util.relativePrecision(Math.abs(x1 - x2), x) < tol) { return x; } if (y * y1 > 0) { // replace end-point that has the same sign x1 = x; y1 = y; } else { x2 = x; y2 = y; } count++; } OSPLog.fine(count + " bisection root trials made - no convergence achieved"); return Double.NaN; // did not converge in max iterations }
public boolean loadResource(String resourceName, Class<?> location) { Resource res = null; try { res = ResourceLoader.getResource(resourceName, location); } catch (Exception ex) { OSPLog.fine("Error getting resource: " + resourceName); // $NON-NLS-1$ return false; } if (res == null) { OSPLog.fine("Resource not found: " + resourceName); // $NON-NLS-1$ return false; } try { textPane.setPage(res.getURL()); } catch (IOException ex) { OSPLog.fine("Resource not loadeded: " + resourceName); // $NON-NLS-1$ return false; } setTitle(resourceName); return true; }
/** * Implements Newton's method for finding the root of a function. * * @param f Function the function * @param df Function the derivative of the function * @param x double guess the root * @param tol double computation tolerance * @return double the root or NaN if root not found. */ public static double newton(final Function f, final Function df, double x, final double tol) { int count = 0; while (count < MAX_ITERATIONS) { double xold = x; // save the old value to test for convergence // approximate the derivative using the given derivative function x -= f.evaluate(x) / df.evaluate(x); if (Util.relativePrecision(Math.abs(x - xold), x) < tol) { return x; } count++; } OSPLog.fine(count + " newton root trials made - no convergence achieved"); return Double.NaN; // did not converve in max iterations }
/** * Implements Newton's method for finding the root of a function. The derivative is calculated * numerically using the central difference approximation. * * @param f Function the function * @param x double guess the root * @param tol double computation tolerance * @return double the root or NaN if root not found. */ public static double newton(final Function f, double x, final double tol) { int count = 0; while (count < MAX_ITERATIONS) { double xold = x; // save the old value to test for convergence double df = 0; try { // df = Derivative.romberg(f, x, Math.max(0.001, 0.001*Math.abs(x)), tol/10); df = fxprime(f, x, tol); } catch (NumericMethodException ex) { return Double.NaN; // did not converve } x -= f.evaluate(x) / df; if (Util.relativePrecision(Math.abs(x - xold), x) < tol) { return x; } count++; } OSPLog.fine(count + " newton root trials made - no convergence achieved"); return Double.NaN; // did not converve in max iterations }
/** * Implements Newton's method for finding the root but switches to the bisection method if the the * estimate is not between xleft and xright. * * <p>Method contributed by: J E Hasbun * * <p>A Newton Raphson result is accepted if it is within the known bounds, else a bisection step * is taken. Ref: Computational Physics by P. L. Devries (J. Wiley, 1993) input: [xleft,xright] is * the interval wherein fx() has a root, icmax is the maximum iteration number, and tol is the * tolerance level output: returns xbest as the value of the function Reasonable values of icmax * and tol are 25, 5e-3. * * <p>Returns the root or NaN if root not found. * * @param xleft double * @param xright double * @param tol double tolerance * @param icmax int number of trials * @return double the root */ public static double newtonBisection( Function f, double xleft, double xright, double tol, int icmax) { double rtest = 10 * tol; double xbest, fleft, fright, fbest, derfbest, delta; int icount = 0, iflag = 0; // loop counter // variables fleft = f.evaluate(xleft); fright = f.evaluate(xright); if (fleft * fright >= 0) { iflag = 1; } switch (iflag) { case 1: System.out.println("No solution possible"); break; } if (Math.abs(fleft) <= Math.abs(fright)) { xbest = xleft; fbest = fleft; } else { xbest = xright; fbest = fright; } derfbest = fxprime(f, xbest, tol); while ((icount < icmax) && (rtest > tol)) { icount++; // decide Newton-Raphson or Bisection method to do: if ((derfbest * (xbest - xleft) - fbest) * (derfbest * (xbest - xright) - fbest) <= 0) { // Newton-Raphson step delta = -fbest / derfbest; xbest = xbest + delta; // System.out.println("Newton: count="+icount+", fx="+fbest); } else { // bisection step delta = (xright - xleft) / 2; xbest = (xleft + xright) / 2; // System.out.println("Bisection: count="+icount+", fx ="+fbest); } rtest = Math.abs(delta / xbest); // Compare the relative error to the tolerance if (rtest <= tol) { // if the error is small, the root has been found // System.out.println("root found="+xbest); } else { // the error is still large, so loop fbest = f.evaluate(xbest); derfbest = fxprime(f, xbest, tol); // adjust brackets if (fleft * fbest <= 0) { // root is in the xleft subinterval: xright = xbest; fright = fbest; } else { // root is in the xright subinterval: xleft = xbest; fleft = fbest; } } } // reach here if either the error is too large or icount reached icmax if ((icount > icmax) || (rtest > tol)) { OSPLog.fine(icmax + " Newton and bisection trials made - no convergence achieved"); return Double.NaN; } return xbest; }