diff --git a/src/java/org/apache/commons/math/analysis/BrentSolver.java b/src/java/org/apache/commons/math/analysis/BrentSolver.java
new file mode 100644
index 000000000..6541c3e95
--- /dev/null
+++ b/src/java/org/apache/commons/math/analysis/BrentSolver.java
@@ -0,0 +1,197 @@
+/* ====================================================================
+ * 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
+ * .
+ */
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Provide the Brent 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 pietsch at apache.org
+ */
+public class BrentSolver extends UnivariateRealSolverImpl {
+
+ private UnivariateRealFunction f;
+
+ public BrentSolver(UnivariateRealFunction f) {
+ super(100, 1E-6);
+ this.f = f;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
+ */
+ public double solve(double min, double max) throws MathException {
+ clearResult();
+ // Index 0 is the old approximation for the root.
+ // Index 1 is the last calculated approximation for the root.
+ // Index 2 is a bracket for the root with respect to x1.
+ double x0 = min;
+ double x1 = max;
+ double y0 = f.value(x0);
+ double y1 = f.value(x1);
+ if ((y0 > 0) == (y1 > 0)) {
+ throw new MathException("Interval doesn't bracket a zero.");
+ }
+ double x2 = x0;
+ double y2 = y0;
+ double delta = x1 - x0;
+ double oldDelta = delta;
+
+ int i = 0;
+ while (i < maximalIterationCount) {
+ if (Math.abs(y2) < Math.abs(y1)) {
+ x0 = x1;
+ x1 = x2;
+ x2 = x0;
+ y0 = y1;
+ y1 = y2;
+ y2 = y0;
+ }
+ if (Math.abs(y1) <= functionValueAccuracy) {
+ // Avoid division by very small values. Assume
+ // the iteration has converged (the problem may
+ // still be ill conditioned)
+ setResult(x1, i);
+ return result;
+ }
+ double dx = (x2 - x1);
+ double tolerance =
+ Math.max(relativeAccuracy * Math.abs(x1), absoluteAccuracy);
+ if (Math.abs(dx) <= tolerance) {
+ 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;
+ } else {
+ double r3 = y1 / y0;
+ double p;
+ 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));
+ p1 = (r1 - 1.0) * (r2 - 1.0) * (r3 - 1.0);
+ }
+ if (p > 0.0) {
+ p1 = -p1;
+ } 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 {
+ oldDelta = delta;
+ delta = p / p1;
+ }
+ }
+ // Save old X1, Y1
+ x0 = x1;
+ y0 = y1;
+ // Compute new X1, Y1
+ if (Math.abs(delta) > tolerance) {
+ x1 = x1 + delta;
+ } else if (dx > 0.0) {
+ x1 = x1 + 0.5*tolerance;
+ } else if (dx <= 0.0) {
+ x1 = x1 - 0.5*tolerance;
+ }
+ y1 = f.value(x1);
+ if ((y1 > 0) == (y2 > 0)) {
+ x2 = x0;
+ y2 = y0;
+ delta = x1 - x0;
+ oldDelta = delta;
+ }
+ i++;
+ }
+ throw new MathException("Maximal iteration number exceeded.");
+ }
+
+}
diff --git a/src/java/org/apache/commons/math/analysis/SecantSolver.java b/src/java/org/apache/commons/math/analysis/SecantSolver.java
new file mode 100644
index 000000000..140261bcf
--- /dev/null
+++ b/src/java/org/apache/commons/math/analysis/SecantSolver.java
@@ -0,0 +1,145 @@
+/* ====================================================================
+ * 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
+ * .
+ */
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Provide the secant algorithm for solving for zeros of real univariate
+ * functions. Because of forced bracketing, convergence is slower than
+ * the unrestricted secant algorithm. However, slow convergence of the
+ * Regula Falsi can be avoided.
+ * It will only search for one zero in the given interval.
+ * The function is supposed to be continuous but not necessarily smooth.
+ *
+ * @author pietsch at apache.org
+ */
+public class SecantSolver extends UnivariateRealSolverImpl {
+
+ private UnivariateRealFunction f;
+
+ public SecantSolver(UnivariateRealFunction f) {
+ super(100, 1E-6);
+ this.f = f;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
+ */
+ public double solve(double min, double max) throws MathException {
+ clearResult();
+ // Index 0 is the old approximation for the root.
+ // Index 1 is the last calculated approximation for the root.
+ // Index 2 is a bracket for the root with respect to x0.
+ // OldDelta is the length of the bracketing interval of the last
+ // iteration.
+ double x0 = min;
+ double x1 = max;
+ double y0 = f.value(x0);
+ double y1 = f.value(x1);
+ if ((y0>0)== (y1>0)) {
+ throw new MathException("Interval doesn't bracket a zero.");
+ }
+ double x2 = x0;
+ double y2 = y0;
+ double oldDelta = x2 - x1;
+ int i = 0;
+ while (i < maximalIterationCount) {
+ if (Math.abs(y2) < Math.abs(y1)) {
+ x0 = x1;
+ x1 = x2;
+ x2 = x0;
+ y0 = y1;
+ y1 = y2;
+ y2 = y0;
+ }
+ if (Math.abs(y1) <= functionValueAccuracy) {
+ setResult(x1, i);
+ return result;
+ }
+ if (Math.abs(oldDelta)
+ < Math.max(relativeAccuracy * Math.abs(x1), absoluteAccuracy)) {
+ setResult(x1, i);
+ return result;
+ }
+ double delta;
+ 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.
+ 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)) {
+ // New bracket is (x0,x1).
+ x2 = x0;
+ y2 = y0;
+ }
+ oldDelta = x2 - x1;
+ i++;
+ }
+ throw new MathException("Maximal iteration number exceeded");
+ }
+
+}
diff --git a/src/java/org/apache/commons/math/analysis/UnivariateRealFunction.java b/src/java/org/apache/commons/math/analysis/UnivariateRealFunction.java
new file mode 100644
index 000000000..182055e24
--- /dev/null
+++ b/src/java/org/apache/commons/math/analysis/UnivariateRealFunction.java
@@ -0,0 +1,110 @@
+/* ====================================================================
+ * 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
+ * .
+ */
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Provide an interface univariate real functions.
+ * The object may held temporary data which is shared between calculations
+ * of the value and the derivatives for the same argument. It is not guaranteed
+ * that derivatives are evaluated after the value, the evaluation algorithm
+ * should throw an InvalidStateException if it can't cope with this.
+ *
+ * @author pietsch at apache.org
+ */
+public interface UnivariateRealFunction {
+
+ /**
+ * Compute the value for the function.
+ * @param x the point for which the function value should be computed
+ * @return the value
+ * @throws MathException if the function couldn't be computed due to
+ * missing additional data or other environmental problems.
+ * @throws RuntimeException if the operation isn't supported, the argument
+ * was outside the supported domain or any other problem.
+ *
+ */
+ public double value(double x) throws MathException;
+
+ /**
+ * Compute the value for the first derivative of the function.
+ * It is recommended to provide this method only if the first derivative is
+ * analytical. Numerical derivatives may be acceptable in some cases.
+ * An implementation should throw an UnsupportedOperationException if
+ * this method is not implemented.
+ * @param x the point for which the first derivative should be computed
+ * @return the value
+ * @throws MathException if the derivative couldn't be computed.
+ * @throws RuntimeException if the operation isn't supported, the argument
+ * was outside the supported domain or any other problem.
+ *
+ */
+ public double firstDerivative(double x) throws MathException;
+
+ /**
+ * Compute the value for the second derivative of the function.
+ * It is recommended to provide this method only if the second derivative is
+ * analytical. Numerical derivatives may be acceptable in some cases.
+ * An implementation should throw an UnsupportedOperationException if
+ * this method is not implemented.
+ * @param x the point for which the first derivative should be computed
+ * @return the value
+ * @throws MathException if the second derivative couldn't be computed.
+ * @throws RuntimeException if the operation isn't supported, the argument
+ * was outside the supported domain or any other problem.
+ *
+ */
+ public double secondDerivative(double x) throws MathException;
+}
diff --git a/src/java/org/apache/commons/math/analysis/UnivariateRealSolver.java b/src/java/org/apache/commons/math/analysis/UnivariateRealSolver.java
new file mode 100644
index 000000000..c8669d451
--- /dev/null
+++ b/src/java/org/apache/commons/math/analysis/UnivariateRealSolver.java
@@ -0,0 +1,209 @@
+/* ====================================================================
+ * 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
+ * .
+ */
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Provide an interface to algorithms for solving for zeros of real univariate
+ * functions.
+ * An implementation will only search for one zero in the given interval.
+ *
+ * @author pietsch at apache.org
+ */
+public interface UnivariateRealSolver {
+
+ /**
+ * 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.
+ * An exception will be thrown if the number is exceeded.
+ *
+ * @param count
+ */
+ 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)
+ */
+ public void resetMaximalIterationCount();
+
+ /**
+ * 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.
+ * @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;
+
+ /**
+ * 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.
+ * @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;
+
+ /**
+ * Get the actual relative accuracy.
+ * @return the accuracy
+ */
+ public double getRelativeAccuracy();
+
+ /**
+ * Reset the relative accuracy to the default.
+ * The default value is provided by the solver implementation.
+ */
+ public void resetRelativeAccuracy();
+
+ /**
+ * 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.
+ * @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;
+
+ /**
+ * Get the actual function value accuracy.
+ * @return the accuracy
+ */
+ public double getFunctionValueAccuracy();
+
+ /**
+ * Reset the actual function accuracy to the default.
+ * The default value is provided by the solver implementation.
+ */
+ public void resetFunctionValueAccuracy();
+
+ /**
+ * Solve for a zero root in the given interval.
+ * A solver may require that the interval brackets a single zero root.
+ * @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;
+
+ /**
+ * Solve for a zero in the given interval, start at startValue.
+ * A solver may require that the interval brackets a single zero root.
+ * @param min the lower bound for the interval.
+ * @param max the upper bound for the interval.
+ * @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;
+
+ /**
+ * Get the result of the last run of the solver.
+ * @return the last result.
+ * @throws MathException if there is no result available, either
+ * because no result was yet computed or the last attempt failed.
+ */
+ public double getResult() throws MathException;
+
+ /**
+ * Get the number of iterations in the last run of the solver.
+ * This is mainly meant for testing purposes. It may occasionally
+ * help track down performance problems: if the iteration count
+ * is notoriously high, check whether the function is evaluated
+ * properly, and whether another solver is more amenable to the
+ * problem.
+ * @return the last iteration count.
+ * @throws MathException if there is no result available, either
+ * because no result was yet computed or the last attempt failed.
+ */
+ public int getIterationCount() throws MathException;
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactory.java b/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactory.java
new file mode 100644
index 000000000..abeb3440a
--- /dev/null
+++ b/src/java/org/apache/commons/math/analysis/UnivariateRealSolverFactory.java
@@ -0,0 +1,136 @@
+/* ====================================================================
+ * 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
+ * .
+ */
+package org.apache.commons.math.analysis;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.math.MathConfigurationException;
+import org.apache.commons.math.MathException;
+
+/**
+ * @author pietsch at apache.org
+ *
+ * A factory to easily get a default solver and some convenience
+ * functions.
+ * Because solvers are easily reusable, the factory does not
+ * store configuration data and creates preconfigured solvers
+ * (this may be controversial, because the configuration data
+ * may also be used for the default solver used by the static
+ * solve() method).
+ *
+ */
+public class UnivariateRealSolverFactory {
+ protected UnivariateRealSolverFactory() {
+ }
+
+ public static UnivariateRealSolver newSolver(UnivariateRealFunction f)
+ throws MathConfigurationException {
+ String solverClassName =
+ System.getProperty(
+ "org.apache.commons.math.analysis.UnivariateRealSolver",
+ "org.apache.commons.math.analysis.BrentSolver");
+ try {
+ Class clazz = Class.forName(solverClassName);
+ Class paramClass[] = new Class[1];
+ paramClass[0] =
+ Class.forName("org.apache.commons.math.analysis.UnivariateRealFunction");
+ Object param[] = new Object[1];
+ param[0] = f;
+ return (UnivariateRealSolver)clazz.getConstructor(
+ paramClass).newInstance(
+ param);
+ } catch (IllegalArgumentException e) {
+ throw new MathConfigurationException(e);
+ } catch (SecurityException e) {
+ throw new MathConfigurationException(
+ "Can't access " + solverClassName,
+ e);
+ } catch (ClassNotFoundException e) {
+ throw new MathConfigurationException(
+ "Class not found: " + solverClassName,
+ e);
+ } catch (InstantiationException e) {
+ throw new MathConfigurationException(
+ "Can't instantiate " + solverClassName,
+ e);
+ } catch (IllegalAccessException e) {
+ throw new MathConfigurationException(
+ "Can't access " + solverClassName,
+ e);
+ } catch (InvocationTargetException e) {
+ throw new MathConfigurationException(e);
+ } catch (NoSuchMethodException e) {
+ throw new MathConfigurationException(
+ "No constructor with UnivariateRealFunction in "
+ + solverClassName,
+ e);
+ }
+ }
+
+ public static double solve(UnivariateRealFunction f, double x0, double x1)
+ throws MathException {
+ return newSolver(f).solve(x0, x1);
+ }
+
+ public static double solve(
+ UnivariateRealFunction f,
+ double x0,
+ double x1,
+ double absoluteAccuracy)
+ throws MathException {
+ UnivariateRealSolver solver = newSolver(f);
+ solver.setAbsoluteAccuracy(absoluteAccuracy);
+ return solver.solve(x0, x1);
+ }
+}
diff --git a/src/java/org/apache/commons/math/analysis/UnivariateRealSolverImpl.java b/src/java/org/apache/commons/math/analysis/UnivariateRealSolverImpl.java
new file mode 100644
index 000000000..3c825b868
--- /dev/null
+++ b/src/java/org/apache/commons/math/analysis/UnivariateRealSolverImpl.java
@@ -0,0 +1,238 @@
+/* ====================================================================
+ * 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
+ * .
+ */
+
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Provide a default implementation for several functions useful to generic
+ * solvers.
+ *
+ * @author pietsch at apache.org
+ */
+public abstract class UnivariateRealSolverImpl
+ implements UnivariateRealSolver {
+
+ protected double absoluteAccuracy;
+ protected double relativeAccuracy;
+ protected double functionValueAccuracy;
+ protected int maximalIterationCount;
+
+ protected double defaultAbsoluteAccuracy;
+ protected double defaultRelativeAccuracy;
+ protected double defaultFunctionValueAccuracy;
+ protected int defaultMaximalIterationCount;
+
+ protected boolean resultComputed = false;
+ protected double result;
+ // Mainly for test framework.
+ protected int iterationCount;
+
+ protected UnivariateRealSolverImpl(
+ int defaultMaximalIterationCount,
+ double defaultAbsoluteAccuracy) {
+ this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy;
+ this.defaultRelativeAccuracy = 1E-14;
+ this.defaultFunctionValueAccuracy = 1E-15;
+ this.absoluteAccuracy = defaultAbsoluteAccuracy;
+ this.relativeAccuracy = defaultRelativeAccuracy;
+ this.functionValueAccuracy = defaultFunctionValueAccuracy;
+ this.defaultMaximalIterationCount = defaultMaximalIterationCount;
+ 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()
+ */
+ public double getResult() throws MathException {
+ if (resultComputed) {
+ return result;
+ } else {
+ throw new MathException("No result available");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#getIterationCount()
+ */
+ public int getIterationCount() throws MathException {
+ if (resultComputed) {
+ return iterationCount;
+ } else {
+ throw new MathException("No result available");
+ }
+ }
+
+ /*
+ * Convenience function for implementations.
+ * @param result the result to set
+ * @param iteratinCount the iteration count to set
+ */
+ protected final void setResult(double result, int iterationCount) {
+ this.result = result;
+ this.iterationCount = iterationCount;
+ this.resultComputed = true;
+ }
+
+ /*
+ * Convenience function for implementations.
+ */
+ protected final void clearResult() {
+ this.resultComputed = false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#setAccuracy(double)
+ */
+ public void setAbsoluteAccuracy(double accuracy)
+ throws MathException {
+ absoluteAccuracy = accuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#getAccuracy()
+ */
+ public double getAbsoluteAccuracy() {
+ return absoluteAccuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#resetAbsoluteAccuracy()
+ */
+ public void resetAbsoluteAccuracy() {
+ absoluteAccuracy = defaultAbsoluteAccuracy;
+ }
+
+ /* Set maximum iteration count.
+ * @see org.apache.commons.math.UnivariateRealSolver#setMaximalIterationCount(int)
+ */
+ public void setMaximalIterationCount(int count) {
+ maximalIterationCount = count;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#getMaximalIterationCount()
+ */
+ public int getMaximalIterationCount() {
+ return maximalIterationCount;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#resetMaximalIterationCount()
+ */
+ public void resetMaximalIterationCount() {
+ maximalIterationCount = defaultMaximalIterationCount;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#setRelativeAccuracy(double)
+ */
+ public void setRelativeAccuracy(double accuracy) throws MathException {
+ relativeAccuracy = accuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#getRelativeAccuracy()
+ */
+ public double getRelativeAccuracy() {
+ return relativeAccuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#resetRelativeAccuracy()
+ */
+ public void resetRelativeAccuracy() {
+ relativeAccuracy = defaultRelativeAccuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#setFunctionValueAccuracy(double)
+ */
+ public void setFunctionValueAccuracy(double accuracy)
+ throws MathException {
+ functionValueAccuracy = accuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#getFunctionValueAccuracy()
+ */
+ public double getFunctionValueAccuracy() {
+ return functionValueAccuracy;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.math.UnivariateRealSolver#resetFunctionValueAccuracy()
+ */
+ public void resetFunctionValueAccuracy() {
+ functionValueAccuracy = defaultFunctionValueAccuracy;
+ }
+
+}