commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdigg...@apache.org
Subject cvs commit: jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis BisectionSolver.java RootFinding.java BrentSolver.java UnivariateRealSolverImpl.java UnivariateRealSolver.java SecantSolver.java
Date Sat, 05 Jul 2003 18:05:02 GMT
mdiggory    2003/07/05 11:05:02

  Modified:    math/src/java/org/apache/commons/math/analysis
                        RootFinding.java BrentSolver.java
                        UnivariateRealSolverImpl.java
                        UnivariateRealSolver.java SecantSolver.java
  Added:       math/src/java/org/apache/commons/math/analysis
                        BisectionSolver.java
  Log:
  PR: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21313
  Submitted by:	brent@worden.org
  
  Revision  Changes    Path
  1.2       +18 -51    jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/RootFinding.java
  
  Index: RootFinding.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/RootFinding.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RootFinding.java	22 Jun 2003 03:57:53 -0000	1.1
  +++ RootFinding.java	5 Jul 2003 18:05:02 -0000	1.2
  @@ -53,6 +53,8 @@
    */
   package org.apache.commons.math.analysis;
   
  +import org.apache.commons.math.MathException;
  +
   /**
    * Utility class comprised of root finding techniques.
    *
  @@ -77,14 +79,17 @@
        * @param function the function
        * @param initial midpoint of the returned range.
        * @param lowerBound for numerical safety, a never is less than this value.
  -     * @param upperBound for numerical safety, b never is greater than this value.
  +     * @param upperBound for numerical safety, b never is greater than this
  +     *                   value.
        * @return a two element array holding {a, b}.
  +     * @throws MathException if a root can not be bracketted.
        */
  -    public static double[] bracket(UnivariateFunction function,
  +    public static double[] bracket(UnivariateRealFunction function,
                                      double initial,
                                      double lowerBound,
  -                                   double upperBound) {
  -        return bracket( function, initial, lowerBound, upperBound, Integer.MAX_VALUE )
;
  +                                   double upperBound) throws MathException {
  +        return bracket( function, initial, lowerBound, upperBound,
  +            Integer.MAX_VALUE ) ;
       }
   
       /**
  @@ -95,15 +100,18 @@
        * @param function the function
        * @param initial midpoint of the returned range.
        * @param lowerBound for numerical safety, a never is less than this value.
  -     * @param upperBound for numerical safety, b never is greater than this value.
  -     * @param maximumIterations to guard against infinite looping, maximum number of iterations
to perform
  +     * @param upperBound for numerical safety, b never is greater than this
  +     *                   value.
  +     * @param maximumIterations to guard against infinite looping, maximum
  +     *                          number of iterations to perform
        * @return a two element array holding {a, b}.
  +     * @throws MathException if a root can not be bracketted.
        */
  -    public static double[] bracket(UnivariateFunction function,
  +    public static double[] bracket(UnivariateRealFunction function,
                                      double initial,
                                      double lowerBound,
                                      double upperBound,
  -                                   int maximumIterations) {
  +                                   int maximumIterations) throws MathException {
           double a = initial;
           double b = initial;
           double fa;
  @@ -113,52 +121,11 @@
           do {
               a = Math.max(a - 1.0, lowerBound);
               b = Math.min(b + 1.0, upperBound);
  -            fa = function.evaluate(a);
  -            fb = function.evaluate(b);
  +            fa = function.value(a);
  +            fb = function.value(b);
               numIterations += 1 ;
           } while ( (fa * fb > 0.0) && ( numIterations < maximumIterations
) );
   
           return new double[]{a, b};
  -    }
  -
  -    /**
  -     * For a function, f, this method returns a root c that lies between a and
  -     * b, and satisfies f(c) = 0.
  -     *
  -     * @param function the function
  -     * @param a lower (or upper) bound of a root
  -     * @param b upper (or lower) bound of a root
  -     * @return a root of f
  -     */
  -    public static double bisection(UnivariateFunction function,
  -                                   double a,
  -                                   double b) {
  -        double m;
  -        double fm;
  -        double fa;
  -
  -        if ( b < a ) {
  -            double xtemp = a ;
  -            a = b ;
  -            b = xtemp ;
  -        }
  -
  -        fa = function.evaluate(a);
  -
  -        while(Math.abs(a - b) > EPSILON) {
  -            m = (a + b) * 0.5;  // midpoint
  -            fm = function.evaluate(m);
  -
  -            if(fm * fa > 0.0) {
  -                // b and m bracket the root.
  -                a = m;
  -                fa = fm;
  -            } else {
  -                // a and m bracket the root.
  -                b = m;
  -            }
  -        }
  -
  -        return (a + b) * 0.5;
       }
   }
  
  
  
  1.2       +29 -28    jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/BrentSolver.java
  
  Index: BrentSolver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/BrentSolver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BrentSolver.java	24 Jun 2003 03:01:40 -0000	1.1
  +++ BrentSolver.java	5 Jul 2003 18:05:02 -0000	1.2
  @@ -64,16 +64,36 @@
    * @author pietsch at apache.org
    */
   public class BrentSolver extends UnivariateRealSolverImpl {
  -
  -    private UnivariateRealFunction f;
  -
  +    /**
  +     * Construct a solver for the given function.
  +     * @param f function to solve.
  +     */
       public BrentSolver(UnivariateRealFunction f) {
  -        super(100, 1E-6);
  -        this.f = f;
  +        super(f, 100, 1E-6);
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
  +    /**
  +     * Solve for a zero in the given interval.
  +     * @param min the lower bound for the interval.
  +     * @param max the upper bound for the interval.
  +     * @param initial the start value to use (ignored).
  +     * @return the value where the function is zero
  +     * @throws MathException if the iteration count was exceeded or the
  +     *  solver detects convergence problems otherwise.
  +     */
  +    public double solve(double min, double max, double initial)
  +        throws MathException {
  +            
  +        return solve(min, max);
  +    }
  +    
  +    /**
  +     * Solve for a zero root in the given interval.
  +     * @param min the lower bound for the interval.
  +     * @param max the upper bound for the interval.
  +     * @return the value where the function is zero
  +     * @throws MathException if the iteration count was exceeded or the
  +     *  solver detects convergence problems otherwise.
        */
       public double solve(double min, double max) throws MathException {
           clearResult();
  @@ -116,21 +136,8 @@
                   setResult(x1, i);
                   return result;
               }
  -//          System.out.println(
  -//              " x0="
  -//                  + x0
  -//                  + " y0="
  -//                  + y0
  -//                  + " x1="
  -//                  + x1
  -//                  + " y1="
  -//                  + y1
  -//                  + " x2="
  -//                  + x2+" y2="+y2);
  -//            System.out.println(" dx="+dx+"   delta: "+delta+"   olddelta: "+oldDelta);
               if (Math.abs(oldDelta) < tolerance
                   || Math.abs(y0) <= Math.abs(y1)) {
  -//                    System.out.println("bisection");
                   // Force bisection.
                   delta = 0.5 * dx;
                   oldDelta = delta;
  @@ -140,12 +147,10 @@
                   double p1;
                   if (x0 == x2) {
                       // Linear interpolation.
  -//                    System.out.println("linear");
                       p = dx * r3;
                       p1 = 1.0 - r3;
                   } else {
                       // Inverse quadratic interpolation.
  -//                    System.out.println("invers quad");
                       double r1 = y0 / y2;
                       double r2 = y1 / y2;
                       p = r3 * (dx * r1 * (r1 - r2) - (x1 - x0) * (r2 - 1.0));
  @@ -156,14 +161,11 @@
                   } else {
                       p = -p;
                   }
  -//                System.out.println("  p="+p+" p1="+p1+" qq: "+(1.5 * dx * p1 - Math.abs(tolerance
* p1)));
  -//                System.out.println("  p="+p+" q: "+p1+" ad="+Math.abs(0.5 * oldDelta
* p1));
                   if (2.0 * p >= 1.5 * dx * p1 - Math.abs(tolerance * p1)
                       || p >= Math.abs(0.5 * oldDelta * p1)) {
                       // Inverse quadratic interpolation gives a value
                       // in the wrong direction, or progress is slow.
                       // Fall back to bisection.
  -//                    System.out.println("bisection fallback");
                       delta = 0.5 * dx;
                       oldDelta = delta;
                   } else {
  @@ -178,9 +180,9 @@
               if (Math.abs(delta) > tolerance) {
                   x1 = x1 + delta;
               } else if (dx > 0.0) {
  -                x1 = x1 + 0.5*tolerance;
  +                x1 = x1 + 0.5 * tolerance;
               } else if (dx <= 0.0) {
  -                x1 = x1 - 0.5*tolerance;
  +                x1 = x1 - 0.5 * tolerance;
               }
               y1 = f.value(x1);
               if ((y1 > 0) == (y2 > 0)) {
  @@ -193,5 +195,4 @@
           }
           throw new MathException("Maximal iteration number exceeded.");
       }
  -
   }
  
  
  
  1.2       +91 -48    jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverImpl.java
  
  Index: UnivariateRealSolverImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- UnivariateRealSolverImpl.java	24 Jun 2003 03:01:40 -0000	1.1
  +++ UnivariateRealSolverImpl.java	5 Jul 2003 18:05:02 -0000	1.2
  @@ -65,24 +65,57 @@
   public abstract class UnivariateRealSolverImpl
       implements UnivariateRealSolver {
   
  +    /** Maximum absolute error. */
       protected double absoluteAccuracy;
  +
  +    /** Maximum relative error. */
       protected double relativeAccuracy;
  +
  +    /** Maximum error of function. */
       protected double functionValueAccuracy;
  +
  +    /** Maximum number of iterations. */
       protected int maximalIterationCount;
   
  +    /** Default maximum absolute error. */
       protected double defaultAbsoluteAccuracy;
  +
  +    /** Default maximum relative error. */
       protected double defaultRelativeAccuracy;
  +
  +    /** Default maximum error of function. */
       protected double defaultFunctionValueAccuracy;
  +
  +    /** Default maximum number of iterations. */
       protected int defaultMaximalIterationCount;
   
  +    /** Indicates where a root has been computed. */
       protected boolean resultComputed = false;
  +
  +    /** The last computed root. */
       protected double result;
  +
       // Mainly for test framework.
  +    /** The last iteration count. */
       protected int iterationCount;
   
  +    /** The function to solve. */
  +    protected UnivariateRealFunction f;
  +
  +    /**
  +     * Construct a solver with given iteration count and accuracy.
  +     * @param f the function to solve.
  +     * @param defaultAbsoluteAccuracy maximum absolue error.
  +     * @param defaultMaximalIterationCount maximum number of iterations.
  +     */
       protected UnivariateRealSolverImpl(
  +        UnivariateRealFunction f,
           int defaultMaximalIterationCount,
           double defaultAbsoluteAccuracy) {
  +        
  +        super();
  +        
  +        this.f = f;
           this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy;
           this.defaultRelativeAccuracy = 1E-14;
           this.defaultFunctionValueAccuracy = 1E-15;
  @@ -93,48 +126,39 @@
           this.maximalIterationCount = defaultMaximalIterationCount;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
  -     */
  -    public double solve(double min, double max) throws MathException {
  -        throw new UnsupportedOperationException();
  -    }
  -
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#solve(double, double, double)
  -     */
  -    public double solve(double min, double max, double startValue)
  -        throws MathException {
  -        throw new UnsupportedOperationException();
  -    }
  -
  -    /*
  -     * Get result of last solver run.
  -     * @see org.apache.commons.math.UnivariateRealSolver#getResult()
  +    /**
  +     * Access the last computed root.
  +     * @return the last computed root.
  +     * @throws MathException if no root has been computed.
        */
       public double getResult() throws MathException {
           if (resultComputed) {
               return result;
           } else {
  +            // TODO: could this be an IllegalStateException instead?
               throw new MathException("No result available");
           }
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#getIterationCount()
  +    /**
  +     * Access the last iteration count.
  +     * @return the last iteration count.
  +     * @throws MathException if no root has been computed.
  +     *  
        */
       public int getIterationCount() throws MathException {
           if (resultComputed) {
               return iterationCount;
           } else {
  +            // TODO: could this be an IllegalStateException instead?
               throw new MathException("No result available");
           }
       }
   
  -    /*
  +    /**
        * Convenience function for implementations.
        * @param result the result to set
  -     * @param iteratinCount the iteration count to set
  +     * @param iterationCount the iteration count to set
        */
       protected final void setResult(double result, int iterationCount) {
           this.result = result;
  @@ -142,97 +166,116 @@
           this.resultComputed = true;
       }
   
  -    /*
  +    /**
        * Convenience function for implementations.
        */
       protected final void clearResult() {
           this.resultComputed = false;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#setAccuracy(double)
  +    /**
  +     * Set the absolute accuracy.
  +     * 
  +     * @param accuracy the accuracy.
  +     * @throws MathException if the accuracy can't be achieved by the solver or
  +     *         is otherwise deemed unreasonable. 
        */
       public void setAbsoluteAccuracy(double accuracy)
           throws MathException {
           absoluteAccuracy = accuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#getAccuracy()
  +    /**
  +     * Get the actual absolute accuracy.
  +     * 
  +     * @return the accuracy
        */
       public double getAbsoluteAccuracy() {
           return absoluteAccuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#resetAbsoluteAccuracy()
  +    /**
  +     * Reset the absolute accuracy to the default.
        */
       public void resetAbsoluteAccuracy() {
           absoluteAccuracy = defaultAbsoluteAccuracy;
       }
   
  -    /* Set maximum iteration count.
  -     * @see org.apache.commons.math.UnivariateRealSolver#setMaximalIterationCount(int)
  +    /**
  +     * Set the upper limit for the number of iterations.
  +     * 
  +     * @param count maximum number of iterations
        */
       public void setMaximalIterationCount(int count) {
           maximalIterationCount = count;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#getMaximalIterationCount()
  +    /**
  +     * Get the upper limit for the number of iterations.
  +     * 
  +     * @return the actual upper limit
        */
       public int getMaximalIterationCount() {
           return maximalIterationCount;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#resetMaximalIterationCount()
  +    /**
  +     * Reset the upper limit for the number of iterations to the default.
        */
       public void resetMaximalIterationCount() {
           maximalIterationCount = defaultMaximalIterationCount;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#setRelativeAccuracy(double)
  +    /**
  +     * Set the relative accuracy.
  +     * 
  +     * @param accuracy the relative accuracy.
  +     * @throws MathException if the accuracy can't be achieved by the solver or
  +     *         is otherwise deemed unreasonable. 
        */
       public void setRelativeAccuracy(double accuracy) throws MathException {
           relativeAccuracy = accuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#getRelativeAccuracy()
  +    /**
  +     * Get the actual relative accuracy.
  +     * @return the accuracy
        */
       public double getRelativeAccuracy() {
           return relativeAccuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#resetRelativeAccuracy()
  +    /**
  +     * Reset the relative accuracy to the default.
        */
       public void resetRelativeAccuracy() {
           relativeAccuracy = defaultRelativeAccuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#setFunctionValueAccuracy(double)
  +    /**
  +     * Set the function value accuracy.
  +     * 
  +     * @param accuracy the accuracy.
  +     * @throws MathException if the accuracy can't be achieved by the solver or
  +     *         is otherwise deemed unreasonable. 
        */
       public void setFunctionValueAccuracy(double accuracy)
           throws MathException {
           functionValueAccuracy = accuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#getFunctionValueAccuracy()
  +    /**
  +     * Get the actual function value accuracy.
  +     * @return the accuracy
        */
       public double getFunctionValueAccuracy() {
           return functionValueAccuracy;
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#resetFunctionValueAccuracy()
  +    /**
  +     * Reset the actual function accuracy to the default.
        */
       public void resetFunctionValueAccuracy() {
           functionValueAccuracy = defaultFunctionValueAccuracy;
       }
  -
   }
  
  
  
  1.2       +37 -20    jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolver.java
  
  Index: UnivariateRealSolver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- UnivariateRealSolver.java	24 Jun 2003 03:01:40 -0000	1.1
  +++ UnivariateRealSolver.java	5 Jul 2003 18:05:02 -0000	1.2
  @@ -66,23 +66,27 @@
   
       /**
        * Set the upper limit for the number of iterations.
  +     * 
        * Usually a high iteration count indicates convergence problems. However,
        * the "reasonable value" varies widely for different solvers, users are
  -     * advised to use the default value supplied by the solver. 
  +     * advised to use the default value supplied by the solver.
  +     *  
        * An exception will be thrown if the number is exceeded.
        *  
  -     * @param count
  +     * @param count maximum number of iterations
        */
       public void setMaximalIterationCount(int count);
   
       /**
        * Get the upper limit for the number of iterations.
  +     * 
        * @return the actual upper limit
        */
       public int getMaximalIterationCount();
   
       /**
        * Reset the upper limit for the number of iterations to the default.
  +     * 
        * The default value is supplied by the solver implementation.
        * 
        * @see #setMaximalIterationCount(int)
  @@ -91,41 +95,50 @@
   
       /**
        * Set the absolute accuracy.
  +     * 
        * The default is usually choosen so taht roots in the interval
  -     * -10..-0.1 and +0.1..+10 can be found wit a reasonable accuracy. If the expected
  -     * absolute value of your roots is of much smaller magnitude, set this to a smaller
  -     * value.
  -     * Solvers are advised to do a plausibility check with the relative accuracy, but
  -     * clients should not rely on this. 
  +     * -10..-0.1 and +0.1..+10 can be found wit a reasonable accuracy. If the
  +     * expected absolute value of your roots is of much smaller magnitude, set
  +     * this to a smaller value.
  +     * 
  +     * Solvers are advised to do a plausibility check with the relative
  +     * accuracy, but clients should not rely on this.
  +     *  
        * @param accuracy the accuracy.
  -     * @throws MathException if the accuracy can't be achieved by the solver or is
  -     * otherwise deemed unreasonable. 
  +     * @throws MathException if the accuracy can't be achieved by the solver or
  +     *         is otherwise deemed unreasonable. 
        */
       public void setAbsoluteAccuracy(double accuracy) throws MathException;
   
       /**
        * Get the actual absolute accuracy.
  +     * 
        * @return the accuracy
        */
       public double getAbsoluteAccuracy();
   
       /**
        * Reset the absolute accuracy to the default.
  +     * 
        * The default value is provided by the solver implementation.
        */
       public void resetAbsoluteAccuracy();
   
       /**
        * Set the relative accuracy.
  -     * This is used to stop iterations if the absolute accuracy can't be achieved
  -     * due to large values or short mantissa length.
  -     * If this should be the primary criterium for convergence rather then a safety
  -     * measure, set the absolute accuracy to a ridiculously small value, like 1E-1000.
  +     * 
  +     * This is used to stop iterations if the absolute accuracy can't be
  +     * achieved due to large values or short mantissa length.
  +     * 
  +     * If this should be the primary criterium for convergence rather then a
  +     * safety measure, set the absolute accuracy to a ridiculously small value,
  +     * like 1E-1000.
  +     * 
        * @param accuracy the relative accuracy.
  -     * @throws MathException if the accuracy can't be achieved by the solver or is
  -     * otherwise deemed unreasonable. 
  +     * @throws MathException if the accuracy can't be achieved by the solver or
  +     *         is otherwise deemed unreasonable. 
        */
  -    public void setRelativeAccuracy(double Accuracy) throws MathException;
  +    public void setRelativeAccuracy(double accuracy) throws MathException;
   
       /**
        * Get the actual relative accuracy.
  @@ -141,14 +154,18 @@
   
       /**
        * Set the function value accuracy.
  +     * 
        * This is used to determine whan an evaluated function value or some other
        * value which is used as divisor is zero.
  -     * This is a safety guard and it shouldn't be necesary to change this in general.
  +     * 
  +     * This is a safety guard and it shouldn't be necesary to change this in
  +     * general.
  +     * 
        * @param accuracy the accuracy.
  -     * @throws MathException if the accuracy can't be achieved by the solver or is
  -     * otherwise deemed unreasonable. 
  +     * @throws MathException if the accuracy can't be achieved by the solver or
  +     *         is otherwise deemed unreasonable. 
        */
  -    public void setFunctionValueAccuracy(double Accuracy) throws MathException;
  +    public void setFunctionValueAccuracy(double accuracy) throws MathException;
   
       /**
        * Get the actual function value accuracy.
  
  
  
  1.2       +31 -13    jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/SecantSolver.java
  
  Index: SecantSolver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/SecantSolver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SecantSolver.java	24 Jun 2003 03:01:40 -0000	1.1
  +++ SecantSolver.java	5 Jul 2003 18:05:02 -0000	1.2
  @@ -66,16 +66,36 @@
    * @author pietsch at apache.org
    */
   public class SecantSolver extends UnivariateRealSolverImpl {
  -
  -    private UnivariateRealFunction f;
  -
  +    /**
  +     * Construct a solver for the given function.
  +     * @param f function to solve.
  +     */
       public SecantSolver(UnivariateRealFunction f) {
  -        super(100, 1E-6);
  -        this.f = f;
  +        super(f, 100, 1E-6);
       }
   
  -    /* (non-Javadoc)
  -     * @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
  +    /**
  +     * Solve for a zero in the given interval.
  +     * @param min the lower bound for the interval.
  +     * @param max the upper bound for the interval.
  +     * @param initial the start value to use (ignored).
  +     * @return the value where the function is zero
  +     * @throws MathException if the iteration count was exceeded or the
  +     *  solver detects convergence problems otherwise.
  +     */
  +    public double solve(double min, double max, double initial)
  +        throws MathException {
  +            
  +        return solve(min, max);
  +    }
  +    
  +    /**
  +     * Solve for a zero root in the given interval.
  +     * @param min the lower bound for the interval.
  +     * @param max the upper bound for the interval.
  +     * @return the value where the function is zero
  +     * @throws MathException if the iteration count was exceeded or the
  +     *  solver detects convergence problems otherwise.
        */
       public double solve(double min, double max) throws MathException {
           clearResult();
  @@ -88,7 +108,7 @@
           double x1 = max;
           double y0 = f.value(x0);
           double y1 = f.value(x1);
  -        if ((y0>0)== (y1>0)) {
  +        if ((y0 > 0) == (y1 > 0)) {
               throw new MathException("Interval doesn't bracket a zero.");
           }
           double x2 = x0;
  @@ -117,21 +137,19 @@
               if (Math.abs(y1) > Math.abs(y0)) {
                   // Function value increased in last iteration. Force bisection.
                   delta = 0.5 * oldDelta;
  -//                System.out.println("Forced Bisection");
               } else {
                   delta = (x0 - x1) / (1 - y0 / y1);
  -                // System.out.println("delta=" + delta + " olddelta=" + oldDelta);
                   if (delta / oldDelta > 1) {
  -                    // New approximation falls outside bracket. Fall back to bisection.
  +                    // New approximation falls outside bracket.
  +                    // Fall back to bisection.
                       delta = 0.5 * oldDelta;
  -//                    System.out.println("Fallback Bisection");
                   }
               }
               x0 = x1;
               y0 = y1;
               x1 = x1 + delta;
               y1 = f.value(x1);
  -            if ((y1>0) == (y2>0)) {
  +            if ((y1 > 0) == (y2 > 0)) {
                   // New bracket is (x0,x1).                    
                   x2 = x0;
                   y2 = y0;
  
  
  
  1.1                  jakarta-commons-sandbox/math/src/java/org/apache/commons/math/analysis/BisectionSolver.java
  
  Index: BisectionSolver.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.math.analysis;
  
  import org.apache.commons.math.MathException;
  
  /**
   * Provide the bisection algorithm for solving for zeros of real univariate
   * functions.  It will only search for one zero in the given interval.  The
   * function is supposed to be continuous but not necessarily smooth.
   *  
   * @author Brent Worden
   */
  public class BisectionSolver extends UnivariateRealSolverImpl {
      /**
       * Construct a solver for the given function.
       * @param f function to solve.
       */
      public BisectionSolver(UnivariateRealFunction f) {
          super(f, 100, 1E-6);
      }
  
      /**
       * Solve for a zero in the given interval.
       * @param min the lower bound for the interval.
       * @param max the upper bound for the interval.
       * @param initial the start value to use (ignored).
       * @return the value where the function is zero
       * @throws MathException if the iteration count was exceeded or the
       *  solver detects convergence problems otherwise.
       */
      public double solve(double min, double max, double initial)
          throws MathException {
              
          return solve(min, max);
      }
      
      /**
       * Solve for a zero root in the given interval.
       * @param min the lower bound for the interval.
       * @param max the upper bound for the interval.
       * @return the value where the function is zero
       * @throws MathException if the iteration count was exceeded or the
       *  solver detects convergence problems otherwise.
       */
      public double solve(double min, double max) throws MathException {
          clearResult();
  
          double m;
          double fm;
          double fmin;
          
          int i = 0;
          while (i < maximalIterationCount) {
              m = midpoint(min, max);
              fmin = f.value(min);
              fm = f.value(m);
  
              if (fm * fmin > 0.0) {
                  // max and m bracket the root.
                  min = m;
                  fmin = fm;
              } else {
                  // min and m bracket the root.
                  max = m;
              }
  
              if (Math.abs(max - min) <= absoluteAccuracy) {
                  m = midpoint(min, max);
                  setResult(m, i);
                  return m;
              }
              ++i;
          }
          
          throw new MathException("Maximal iteration number exceeded");
      }
  
      /**
       * Compute the midpoint of two values.
       * @param a first value.
       * @param b second value.
       * @return the midpoint. 
       */
      public static double midpoint(double a, double b) {
          return (a + b) * .5;
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message