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]