brentworden    2004/04/08 14:19:17

  Modified:    math/src/java/org/apache/commons/math/analysis
                        UnivariateRealSolverFactoryImpl.java
                        BisectionSolver.java
                        UnivariateRealSolverFactory.java
                        UnivariateRealSolverUtils.java
               math/src/test/org/apache/commons/math/analysis
                        SinFunction.java QuinticFunction.java
  Added:       math/src/java/org/apache/commons/math/analysis
                        NewtonSolver.java
               math/src/test/org/apache/commons/math/analysis
                        NewtonSolverTest.java
  Log:
  Newton's method using the new differentiable interface.

  
  Revision  Changes    Path
  1.11      +14 -3     
jakarta-commons/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactoryImpl.java
  
  Index: UnivariateRealSolverFactoryImpl.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactoryImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- UnivariateRealSolverFactoryImpl.java      22 Feb 2004 22:01:29 -0000      1.10
  +++ UnivariateRealSolverFactoryImpl.java      8 Apr 2004 21:19:17 -0000       1.11
  @@ -17,7 +17,6 @@
   
   import java.io.Serializable;
   
  -
   /**
    * A concrete [EMAIL PROTECTED]  UnivariateRealSolverFactory}.  This is the default 
solver factory
    * used by commons-math.
  @@ -67,7 +66,19 @@
       public UnivariateRealSolver newBrentSolver(UnivariateRealFunction f) {
           return new BrentSolver(f);
       }
  -
  +    
  +    /**
  +     * Create a new [EMAIL PROTECTED] UnivariateRealSolver} for the given function. 
 The
  +     * solver is an implementation of Newton's Method.
  +     * @param f the function.
  +     * @return the new solver.
  +     */
  +    public UnivariateRealSolver newNewtonSolver(
  +        DifferentiableUnivariateRealFunction f) {
  +        
  +        return new NewtonSolver(f);
  +    }
  +    
       /**
        * Create a new [EMAIL PROTECTED] UnivariateRealSolver} for the given function. 
 The
        * solver is an implementation of the secant method.
  
  
  
  1.13      +3 -13     
jakarta-commons/math/src/java/org/apache/commons/math/analysis/BisectionSolver.java
  
  Index: BisectionSolver.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/analysis/BisectionSolver.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- BisectionSolver.java      20 Feb 2004 06:22:39 -0000      1.12
  +++ BisectionSolver.java      8 Apr 2004 21:19:17 -0000       1.13
  @@ -68,7 +68,7 @@
           
           int i = 0;
           while (i < maximalIterationCount) {
  -            m = midpoint(min, max);
  +            m = UnivariateRealSolverUtils.midpoint(min, max);
               fmin = f.value(min);
               fm = f.value(m);
   
  @@ -82,7 +82,7 @@
               }
   
               if (Math.abs(max - min) <= absoluteAccuracy) {
  -                m = midpoint(min, max);
  +                m = UnivariateRealSolverUtils.midpoint(min, max);
                   setResult(m, i);
                   return m;
               }
  @@ -90,15 +90,5 @@
           }
           
           throw new MathException("Maximum number of iterations 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;
       }
   }
  
  
  
  1.14      +10 -1     
jakarta-commons/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactory.java
  
  Index: UnivariateRealSolverFactory.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactory.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- UnivariateRealSolverFactory.java  22 Feb 2004 22:01:29 -0000      1.13
  +++ UnivariateRealSolverFactory.java  8 Apr 2004 21:19:17 -0000       1.14
  @@ -96,6 +96,15 @@
       
       /**
        * Create a new [EMAIL PROTECTED] UnivariateRealSolver} for the given function. 
 The
  +     * solver is an implementation of Newton's Method.
  +     * @param f the function.
  +     * @return the new solver.
  +     */
  +    public abstract UnivariateRealSolver newNewtonSolver(
  +        DifferentiableUnivariateRealFunction f);
  +    
  +    /**
  +     * Create a new [EMAIL PROTECTED] UnivariateRealSolver} for the given function. 
 The
        * solver is an implementation of the secant method.
        * @param f the function.
        * @return the new solver.
  
  
  
  1.8       +11 -1     
jakarta-commons/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverUtils.java
  
  Index: UnivariateRealSolverUtils.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/analysis/UnivariateRealSolverUtils.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- UnivariateRealSolverUtils.java    21 Feb 2004 21:35:14 -0000      1.7
  +++ UnivariateRealSolverUtils.java    8 Apr 2004 21:19:17 -0000       1.8
  @@ -135,4 +135,14 @@
       
           return new double[]{a, b};
       }
  +
  +    /**
  +     * 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;
  +    }
   }
  
  
  
  1.1                  
jakarta-commons/math/src/java/org/apache/commons/math/analysis/NewtonSolver.java
  
  Index: NewtonSolver.java
  ===================================================================
  /*
   *
   * Copyright 2004 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  
  package org.apache.commons.math.analysis;
  
  import java.io.Serializable;
  
  import org.apache.commons.math.MathException;
  
  /**
   * Implements <a href="http://mathworld.wolfram.com/NewtonsMethod.html";>\
   * Newton's Method</a> for finding zeros of real univariate functions. This
   * algorithm will find only one zero in the given interval.  The function should
   * be continuous but not necessarily smooth.
   *
   * @version $Revision: 1.1 $ $Date: 2004/04/08 21:19:17 $
   */
  public class NewtonSolver extends UnivariateRealSolverImpl implements Serializable {
      
      /** The first derivative of the target function. */
      private UnivariateRealFunction derivative;
      
      /**
       * Construct a solver for the given function.
       * @param f function to solve.
       */
      public NewtonSolver(DifferentiableUnivariateRealFunction f) {
          super(f, 100, 1E-6);
          derivative = f.derivative();
      }
  
      /**
       * Find a zero near the midpoint of <code>min</code> and <code>max</code>.
       * @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 {
          return solve(min, max, UnivariateRealSolverUtils.midpoint(min, max));
      }
  
      /**
       * Find a zero near the value <code>startValue</code>.
       * @param min the lower bound for the interval (ignored).
       * @param max the upper bound for the interval (ignored).
       * @param startValue the start value to use.
       * @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 startValue)
          throws MathException {
          
          clearResult();
  
          double x0 = startValue;
          double x1;
          
          int i = 0;
          while (i < maximalIterationCount) {
              x1 = x0 - (f.value(x0) / derivative.value(x0));
  
              if (Math.abs(x1 - x0) <= absoluteAccuracy) {
                  
                  setResult(x1, i);
                  return x1;
              }
              
              x0 = x1;
              ++i;
          }
          
          throw new MathException("Maximum number of iterations exceeded");
      }
  
  }
  
  
  
  1.12      +8 -4      
jakarta-commons/math/src/test/org/apache/commons/math/analysis/SinFunction.java
  
  Index: SinFunction.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/math/src/test/org/apache/commons/math/analysis/SinFunction.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- SinFunction.java  21 Feb 2004 21:35:16 -0000      1.11
  +++ SinFunction.java  8 Apr 2004 21:19:17 -0000       1.12
  @@ -27,7 +27,7 @@
    * 
    * @version $Revision$ $Date$
    */
  -public class SinFunction implements UnivariateRealFunction {
  +public class SinFunction implements DifferentiableUnivariateRealFunction {
   
       /* Evaluate sinus fuction.
        * @see org.apache.commons.math.UnivariateRealFunction#value(double)
  @@ -38,8 +38,12 @@
   
       /* First derivative of sinus function
        */
  -    public double firstDerivative(double x) throws MathException {
  -        return Math.cos(x);
  +    public UnivariateRealFunction derivative() {
  +        return new UnivariateRealFunction() {
  +            public double value(double x) throws MathException {
  +                return Math.cos(x);
  +            }
  +        };
       }
   
   }
  
  
  
  1.12      +8 -7      
jakarta-commons/math/src/test/org/apache/commons/math/analysis/QuinticFunction.java
  
  Index: QuinticFunction.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/math/src/test/org/apache/commons/math/analysis/QuinticFunction.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- QuinticFunction.java      21 Feb 2004 21:35:16 -0000      1.11
  +++ QuinticFunction.java      8 Apr 2004 21:19:17 -0000       1.12
  @@ -22,7 +22,7 @@
    *
    * @version $Revision$ $Date$ 
    */
  -public class QuinticFunction implements UnivariateRealFunction {
  +public class QuinticFunction implements DifferentiableUnivariateRealFunction {
   
       /* Evaluate quintic.
        * @see org.apache.commons.math.UnivariateRealFunction#value(double)
  @@ -31,10 +31,11 @@
           return (x-1)*(x-0.5)*x*(x+0.5)*(x+1);
       }
   
  -    /* First derivative of quintic.
  -     */
  -    public double firstDerivative(double x) throws MathException {
  -        return (5*x*x-3.75)*x*x+0.25;
  +    public UnivariateRealFunction derivative() {
  +        return new UnivariateRealFunction() {
  +            public double value(double x) throws MathException {
  +                return (5*x*x-3.75)*x*x+0.25;
  +            }
  +        };
       }
  -
   }
  
  
  
  1.1                  
jakarta-commons/math/src/test/org/apache/commons/math/analysis/NewtonSolverTest.java
  
  Index: NewtonSolverTest.java
  ===================================================================
  /*
   * 
   * Copyright (c) 2003-2004 The Apache Software Foundation. All rights reserved.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
   * use this file except in compliance with the License. You may obtain a copy
   * of the License at
   * 
   * http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   * License for the specific language governing permissions and limitations
   * under the License.
   *  
   */
  package org.apache.commons.math.analysis;
  
  import org.apache.commons.math.MathException;
  
  import junit.framework.TestCase;
  
  /**
   * @version $Revision: 1.1 $ $Date: 2004/04/08 21:19:17 $
   */
  public final class NewtonSolverTest extends TestCase {
      /**
       *
       */
      public void testSinZero() throws MathException {
          DifferentiableUnivariateRealFunction f = new SinFunction();
          double result;
          
          UnivariateRealSolver solver = new NewtonSolver(f);
          result = solver.solve(3, 4);
          assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
  
          result = solver.solve(1, 4);
          assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
      }
  
      /**
       *
       */
      public void testQuinticZero() throws MathException {
          DifferentiableUnivariateRealFunction f = new QuinticFunction();
          double result;
  
          UnivariateRealSolver solver = new BisectionSolver(f);
          result = solver.solve(-0.2, 0.2);
          assertEquals(result, 0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(-0.1, 0.3);
          assertEquals(result, 0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(-0.3, 0.45);
          assertEquals(result, 0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.3, 0.7);
          assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.2, 0.6);
          assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.05, 0.95);
          assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.85, 1.25);
          assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.8, 1.2);
          assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.85, 1.75);
          assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.55, 1.45);
          assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
  
          result = solver.solve(0.85, 5);
          assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to