Пример #1
0
 /**
  * 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
 }
Пример #2
0
 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;
 }
Пример #3
0
 /**
  * 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
 }
Пример #4
0
 /**
  * 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
 }
Пример #5
0
 /**
  * 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;
 }