Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java Thu Nov 25 16:22:00 2010
@@ -16,95 +16,116 @@
*/
package org.apache.commons.math.analysis.solvers;
-import org.apache.commons.math.ConvergenceException;
-import org.apache.commons.math.MaxIterationsExceededException;
-import org.apache.commons.math.analysis.UnivariateRealFunction;
-import org.apache.commons.math.exception.MathUserException;
import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.util.MathUtils;
/**
- * Implements the <a href="http://mathworld.wolfram.com/MullersMethod.html">
+ * This class implements the <a href="http://mathworld.wolfram.com/MullersMethod.html">
* Muller's Method</a> for root finding of real univariate functions. For
* reference, see <b>Elementary Numerical Analysis</b>, ISBN 0070124477,
* chapter 3.
* <p>
* Muller's method applies to both real and complex functions, but here we
- * restrict ourselves to real functions. Methods solve() and solve2() find
- * real zeros, using different ways to bypass complex arithmetics.</p>
+ * restrict ourselves to real functions.
+ * This class differs from {@link MullerSolver} in the way it avoids complex
+ * operations.</p>
+ * Muller's original method would have function evaluation at complex point.
+ * Since our f(x) is real, we have to find ways to avoid that. Bracketing
+ * condition is one way to go: by requiring bracketing in every iteration,
+ * the newly computed approximation is guaranteed to be real.</p>
+ * <p>
+ * Normally Muller's method converges quadratically in the vicinity of a
+ * zero, however it may be very slow in regions far away from zeros. For
+ * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use
+ * bisection as a safety backup if it performs very poorly.</p>
+ * <p>
+ * The formulas here use divided differences directly.</p>
*
* @version $Revision$ $Date$
* @since 1.2
+ * @see MullerSolver2
*/
-public class MullerSolver extends UnivariateRealSolverImpl {
+public class MullerSolver extends AbstractUnivariateRealSolver {
+ /** Serializable version identifier */
+ private static final long serialVersionUID = 7694577816772532779L;
+ /** Default absolute accuracy. */
+ public static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;
/**
- * Construct a solver.
+ * Construct a solver with default accuracies.
*/
public MullerSolver() {
- super(100, 1E-6);
+ this(DEFAULT_ABSOLUTE_ACCURACY);
+ }
+ /**
+ * Construct a solver.
+ *
+ * @param absoluteAccuracy Absolute accuracy.
+ */
+ public MullerSolver(double absoluteAccuracy) {
+ super(absoluteAccuracy);
}
-
/**
- * Find a real root in the given interval with initial value.
- * <p>
- * Requires bracketing condition.</p>
+ * Construct a solver.
*
- * @param f the function to solve
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @param initial the start value to use
- * @return the point at which the function value is zero
- * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
- * or the solver detects convergence problems otherwise
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if any parameters are invalid
+ * @param relativeAccuracy Relative accuracy.
+ * @param absoluteAccuracy Absolute accuracy.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max, final double initial)
- throws MaxIterationsExceededException, MathUserException {
+ public MullerSolver(double relativeAccuracy,
+ double absoluteAccuracy) {
+ super(relativeAccuracy, absoluteAccuracy);
+ }
- // check for zeros before verifying bracketing
- if (f.value(min) == 0.0) { return min; }
- if (f.value(max) == 0.0) { return max; }
- if (f.value(initial) == 0.0) { return initial; }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected double doSolve() {
+ final double min = getMin();
+ final double max = getMax();
+ final double initial = getStartValue();
+
+ final double functionValueAccuracy = getFunctionValueAccuracy();
- verifyBracketing(min, max, f);
verifySequence(min, initial, max);
- if (isBracketing(min, initial, f)) {
- return solve(f, min, initial);
+
+ // check for zeros before verifying bracketing
+ final double fMin = computeObjectiveValue(min);
+ if (FastMath.abs(fMin) < functionValueAccuracy) {
+ return min;
+ }
+ final double fMax = computeObjectiveValue(max);
+ if (FastMath.abs(fMax) < functionValueAccuracy) {
+ return max;
+ }
+ final double fInitial = computeObjectiveValue(initial);
+ if (FastMath.abs(fInitial) < functionValueAccuracy) {
+ return initial;
+ }
+
+ verifyBracketing(min, max);
+
+ if (isBracketing(min, initial)) {
+ return solve(min, initial, fMin, fInitial);
} else {
- return solve(f, initial, max);
+ return solve(initial, max, fInitial, fMax);
}
}
/**
* Find a real root in the given interval.
- * <p>
- * Original Muller's method would have function evaluation at complex point.
- * Since our f(x) is real, we have to find ways to avoid that. Bracketing
- * condition is one way to go: by requiring bracketing in every iteration,
- * the newly computed approximation is guaranteed to be real.</p>
- * <p>
- * Normally Muller's method converges quadratically in the vicinity of a
- * zero, however it may be very slow in regions far away from zeros. For
- * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use
- * bisection as a safety backup if it performs very poorly.</p>
- * <p>
- * The formulas here use divided differences directly.</p>
*
- * @param f the function to solve
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @return the point at which the function value is zero
- * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
- * or the solver detects convergence problems otherwise
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if any parameters are invalid
+ * @param min Lower bound for the interval.
+ * @param max Upper bound for the interval.
+ * @param fMin function value at the lower bound.
+ * @param fMax function value at the upper bound.
+ * @return the point at which the function value is zero.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max)
- throws MaxIterationsExceededException, MathUserException {
+ private double solve(double min, double max,
+ double fMin, double fMax) {
+ final double relativeAccuracy = getRelativeAccuracy();
+ final double absoluteAccuracy = getAbsoluteAccuracy();
+ final double functionValueAccuracy = getFunctionValueAccuracy();
// [x0, x2] is the bracketing interval in each iteration
// x1 is the last approximation and an interpolation point in (x0, x2)
@@ -112,23 +133,14 @@ public class MullerSolver extends Univar
// d01, d12, d012 are divided differences
double x0 = min;
- double y0 = f.value(x0);
+ double y0 = fMin;
double x2 = max;
- double y2 = f.value(x2);
+ double y2 = fMax;
double x1 = 0.5 * (x0 + x2);
- double y1 = f.value(x1);
-
- // check for zeros before verifying bracketing
- if (y0 == 0.0) {
- return min;
- }
- if (y2 == 0.0) {
- return max;
- }
- verifyBracketing(min, max, f);
+ double y1 = computeObjectiveValue(x1);
double oldx = Double.POSITIVE_INFINITY;
- for (int i = 1; i <= maximalIterationCount; ++i) {
+ while (true) {
// Muller's method employs quadratic interpolation through
// x0, x1, x2 and x is the zero of the interpolating parabola.
// Due to bracketing condition, this parabola must have two
@@ -143,17 +155,13 @@ public class MullerSolver extends Univar
// xplus and xminus are two roots of parabola and at least
// one of them should lie in (x0, x2)
final double x = isSequence(x0, xplus, x2) ? xplus : xminus;
- final double y = f.value(x);
+ final double y = computeObjectiveValue(x);
// check for convergence
final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
- if (FastMath.abs(x - oldx) <= tolerance) {
- setResult(x, i);
- return result;
- }
- if (FastMath.abs(y) <= functionValueAccuracy) {
- setResult(x, i);
- return result;
+ if (FastMath.abs(x - oldx) <= tolerance ||
+ FastMath.abs(y) <= functionValueAccuracy) {
+ return x;
}
// Bisect if convergence is too slow. Bisection would waste
@@ -173,118 +181,16 @@ public class MullerSolver extends Univar
oldx = x;
} else {
double xm = 0.5 * (x0 + x2);
- double ym = f.value(xm);
+ double ym = computeObjectiveValue(xm);
if (MathUtils.sign(y0) + MathUtils.sign(ym) == 0.0) {
x2 = xm; y2 = ym;
} else {
x0 = xm; y0 = ym;
}
x1 = 0.5 * (x0 + x2);
- y1 = f.value(x1);
- oldx = Double.POSITIVE_INFINITY;
- }
- }
- throw new MaxIterationsExceededException(maximalIterationCount);
- }
-
- /**
- * Find a real root in the given interval.
- * <p>
- * solve2() differs from solve() in the way it avoids complex operations.
- * Except for the initial [min, max], solve2() does not require bracketing
- * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex
- * number arises in the computation, we simply use its modulus as real
- * approximation.</p>
- * <p>
- * Because the interval may not be bracketing, bisection alternative is
- * not applicable here. However in practice our treatment usually works
- * well, especially near real zeros where the imaginary part of complex
- * approximation is often negligible.</p>
- * <p>
- * The formulas here do not use divided differences directly.</p>
- *
- * @param f the function to solve
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @return the point at which the function value is zero
- * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
- * or the solver detects convergence problems otherwise
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if any parameters are invalid
- */
- public double solve2(final UnivariateRealFunction f,
- final double min, final double max)
- throws MaxIterationsExceededException, MathUserException {
-
- // x2 is the last root approximation
- // x is the new approximation and new x2 for next round
- // x0 < x1 < x2 does not hold here
-
- double x0 = min;
- double y0 = f.value(x0);
- double x1 = max;
- double y1 = f.value(x1);
- double x2 = 0.5 * (x0 + x1);
- double y2 = f.value(x2);
-
- // check for zeros before verifying bracketing
- if (y0 == 0.0) { return min; }
- if (y1 == 0.0) { return max; }
- verifyBracketing(min, max, f);
-
- double oldx = Double.POSITIVE_INFINITY;
- for (int i = 1; i <= maximalIterationCount; ++i) {
- // quadratic interpolation through x0, x1, x2
- final double q = (x2 - x1) / (x1 - x0);
- final double a = q * (y2 - (1 + q) * y1 + q * y0);
- final double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0;
- final double c = (1 + q) * y2;
- final double delta = b * b - 4 * a * c;
- double x;
- final double denominator;
- if (delta >= 0.0) {
- // choose a denominator larger in magnitude
- double dplus = b + FastMath.sqrt(delta);
- double dminus = b - FastMath.sqrt(delta);
- denominator = FastMath.abs(dplus) > FastMath.abs(dminus) ? dplus : dminus;
- } else {
- // take the modulus of (B +/- FastMath.sqrt(delta))
- denominator = FastMath.sqrt(b * b - delta);
- }
- if (denominator != 0) {
- x = x2 - 2.0 * c * (x2 - x1) / denominator;
- // perturb x if it exactly coincides with x1 or x2
- // the equality tests here are intentional
- while (x == x1 || x == x2) {
- x += absoluteAccuracy;
- }
- } else {
- // extremely rare case, get a random number to skip it
- x = min + FastMath.random() * (max - min);
+ y1 = computeObjectiveValue(x1);
oldx = Double.POSITIVE_INFINITY;
}
- final double y = f.value(x);
-
- // check for convergence
- final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
- if (FastMath.abs(x - oldx) <= tolerance) {
- setResult(x, i);
- return result;
- }
- if (FastMath.abs(y) <= functionValueAccuracy) {
- setResult(x, i);
- return result;
- }
-
- // prepare the next iteration
- x0 = x1;
- y0 = y1;
- x1 = x2;
- y1 = y2;
- x2 = x;
- y2 = y;
- oldx = x;
}
- throw new MaxIterationsExceededException(maximalIterationCount);
}
}
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver2.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver2.java?rev=1039083&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver2.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver2.java Thu Nov 25 16:22:00 2010
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.solvers;
+
+import org.apache.commons.math.exception.NoBracketingException;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements the <a href="http://mathworld.wolfram.com/MullersMethod.html">
+ * Muller's Method</a> for root finding of real univariate functions. For
+ * reference, see <b>Elementary Numerical Analysis</b>, ISBN 0070124477,
+ * chapter 3.
+ * <p>
+ * Muller's method applies to both real and complex functions, but here we
+ * restrict ourselves to real functions.<
+ * This class differs from {@link MullerSolver} in the way it avoids complex
+ * operations.</p>
+ * Except for the initial [min, max], it does not require bracketing
+ * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex
+ * number arises in the computation, we simply use its modulus as real
+ * approximation.</p>
+ * <p>
+ * Because the interval may not be bracketing, bisection alternative is
+ * not applicable here. However in practice our treatment usually works
+ * well, especially near real zeroes where the imaginary part of complex
+ * approximation is often negligible.</p>
+ * <p>
+ * The formulas here do not use divided differences directly.</p>
+ *
+ * @version $Revision: 1034896 $ $Date: 2010-11-13 23:27:34 +0100 (Sat, 13 Nov 2010) $
+ * @since 1.2
+ * @see MullerSolver
+ */
+public class MullerSolver2 extends AbstractUnivariateRealSolver {
+ /** Serializable version identifier */
+ private static final long serialVersionUID = 7694577816772532779L;
+ /** Default absolute accuracy. */
+ public static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;
+
+ /**
+ * Construct a solver with default accuracies.
+ */
+ public MullerSolver2() {
+ this(DEFAULT_ABSOLUTE_ACCURACY);
+ }
+ /**
+ * Construct a solver.
+ *
+ * @param absoluteAccuracy Absolute accuracy.
+ */
+ public MullerSolver2(double absoluteAccuracy) {
+ super(absoluteAccuracy);
+ }
+ /**
+ * Construct a solver.
+ *
+ * @param relativeAccuracy Relative accuracy.
+ * @param absoluteAccuracy Absolute accuracy.
+ */
+ public MullerSolver2(double relativeAccuracy,
+ double absoluteAccuracy) {
+ super(relativeAccuracy, absoluteAccuracy);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected double doSolve() {
+ final double min = getMin();
+ final double max = getMax();
+
+ verifyInterval(min, max);
+
+ final double relativeAccuracy = getRelativeAccuracy();
+ final double absoluteAccuracy = getAbsoluteAccuracy();
+ final double functionValueAccuracy = getFunctionValueAccuracy();
+
+ // x2 is the last root approximation
+ // x is the new approximation and new x2 for next round
+ // x0 < x1 < x2 does not hold here
+
+ double x0 = min;
+ double y0 = computeObjectiveValue(x0);
+ if (FastMath.abs(y0) < functionValueAccuracy) {
+ return x0;
+ }
+ double x1 = max;
+ double y1 = computeObjectiveValue(x1);
+ if (FastMath.abs(y1) < functionValueAccuracy) {
+ return x1;
+ }
+
+ if(y0 * y1 > 0) {
+ throw new NoBracketingException(x0, x1, y0, y1);
+ }
+
+ double x2 = 0.5 * (x0 + x1);
+ double y2 = computeObjectiveValue(x2);
+
+ double oldx = Double.POSITIVE_INFINITY;
+ while (true) {
+ // quadratic interpolation through x0, x1, x2
+ final double q = (x2 - x1) / (x1 - x0);
+ final double a = q * (y2 - (1 + q) * y1 + q * y0);
+ final double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0;
+ final double c = (1 + q) * y2;
+ final double delta = b * b - 4 * a * c;
+ double x;
+ final double denominator;
+ if (delta >= 0.0) {
+ // choose a denominator larger in magnitude
+ double dplus = b + FastMath.sqrt(delta);
+ double dminus = b - FastMath.sqrt(delta);
+ denominator = FastMath.abs(dplus) > FastMath.abs(dminus) ? dplus : dminus;
+ } else {
+ // take the modulus of (B +/- FastMath.sqrt(delta))
+ denominator = FastMath.sqrt(b * b - delta);
+ }
+ if (denominator != 0) {
+ x = x2 - 2.0 * c * (x2 - x1) / denominator;
+ // perturb x if it exactly coincides with x1 or x2
+ // the equality tests here are intentional
+ while (x == x1 || x == x2) {
+ x += absoluteAccuracy;
+ }
+ } else {
+ // extremely rare case, get a random number to skip it
+ x = min + FastMath.random() * (max - min);
+ oldx = Double.POSITIVE_INFINITY;
+ }
+ final double y = computeObjectiveValue(x);
+
+ // check for convergence
+ final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
+ if (FastMath.abs(x - oldx) <= tolerance ||
+ FastMath.abs(y) <= functionValueAccuracy) {
+ return x;
+ }
+
+ // prepare the next iteration
+ x0 = x1;
+ y0 = y1;
+ x1 = x2;
+ y1 = y2;
+ x2 = x;
+ y2 = y;
+ oldx = x;
+ }
+ }
+}
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver2.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java Thu Nov 25 16:22:00 2010
@@ -17,12 +17,7 @@
package org.apache.commons.math.analysis.solvers;
-import org.apache.commons.math.exception.MathUserException;
-import org.apache.commons.math.MathRuntimeException;
-import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
-import org.apache.commons.math.analysis.UnivariateRealFunction;
-import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.FastMath;
/**
@@ -33,76 +28,58 @@ import org.apache.commons.math.util.Fast
*
* @version $Revision$ $Date$
*/
-public class NewtonSolver extends UnivariateRealSolverImpl {
+public class NewtonSolver extends AbstractDifferentiableUnivariateRealSolver {
+ /** Default absolute accuracy. */
+ public static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;
/**
* Construct a solver.
*/
public NewtonSolver() {
- super(100, 1E-6);
+ this(DEFAULT_ABSOLUTE_ACCURACY);
}
-
/**
- * Find a zero near the midpoint of <code>min</code> and <code>max</code>.
+ * Construct a solver.
*
- * @param f the function to solve
- * @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 MaxIterationsExceededException if the maximum iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function or derivative
- * @throws IllegalArgumentException if min is not less than max
+ * @param absoluteAccuracy Absolute accuracy.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max)
- throws MaxIterationsExceededException, MathUserException {
- return solve(f, min, max, UnivariateRealSolverUtils.midpoint(min, max));
+ public NewtonSolver(double absoluteAccuracy) {
+ super(absoluteAccuracy);
}
/**
- * Find a zero near the value <code>startValue</code>.
+ * Find a zero near the midpoint of {@code min} and {@code max}.
*
- * @param f the function to solve
- * @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 MaxIterationsExceededException if the maximum iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function or derivative
- * @throws IllegalArgumentException if startValue is not between min and max or
- * if function is not a {@link DifferentiableUnivariateRealFunction} instance
+ * @param f Function to solve.
+ * @param min Lower bound for the interval?
+ * @param max Upper bound for the interval.
+ * @return the value where the function is zero.
+ * @throws org.apache.commons.math.exception.TooManyEvaluationsException
+ * if the maximum evaluation count is exceeded.
+ * @throws IllegalArgumentException if {@code min >= max}.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max, final double startValue)
- throws MaxIterationsExceededException, MathUserException {
-
- try {
-
- final UnivariateRealFunction derivative =
- ((DifferentiableUnivariateRealFunction) f).derivative();
- clearResult();
- verifySequence(min, startValue, max);
-
- double x0 = startValue;
- double x1;
-
- int i = 0;
- while (i < maximalIterationCount) {
-
- x1 = x0 - (f.value(x0) / derivative.value(x0));
- if (FastMath.abs(x1 - x0) <= absoluteAccuracy) {
- setResult(x1, i);
- return x1;
- }
+ public double solve(final DifferentiableUnivariateRealFunction f,
+ final double min, final double max) {
+ return super.solve(f, UnivariateRealSolverUtils.midpoint(min, max));
+ }
- x0 = x1;
- ++i;
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected double doSolve() {
+ final double startValue = getStartValue();
+ final double absoluteAccuracy = getAbsoluteAccuracy();
+
+ double x0 = startValue;
+ double x1;
+ while (true) {
+ x1 = x0 - (computeObjectiveValue(x0) / computeDerivativeObjectiveValue(x0));
+ if (FastMath.abs(x1 - x0) <= absoluteAccuracy) {
+ return x1;
}
- throw new MaxIterationsExceededException(maximalIterationCount);
- } catch (ClassCastException cce) {
- throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_DIFFERENTIABLE);
+ x0 = x1;
}
}
-
}
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/PolynomialSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/PolynomialSolver.java?rev=1039083&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/PolynomialSolver.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/PolynomialSolver.java Thu Nov 25 16:22:00 2010
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.solvers;
+
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+
+/**
+ * Interface for (polynomial) root-finding algorithms.
+ * Implementations will search for only one zero in the given interval.
+ *
+ * @version $Revision$ $Date$
+ * @since 3.0
+ */
+public interface PolynomialSolver
+ extends BaseUnivariateRealSolver<PolynomialFunction> {}
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/PolynomialSolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java Thu Nov 25 16:22:00 2010
@@ -16,10 +16,6 @@
*/
package org.apache.commons.math.analysis.solvers;
-import org.apache.commons.math.ConvergenceException;
-import org.apache.commons.math.exception.MathUserException;
-import org.apache.commons.math.MaxIterationsExceededException;
-import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.util.MathUtils;
@@ -35,106 +31,84 @@ import org.apache.commons.math.util.Math
* @version $Revision$ $Date$
* @since 1.2
*/
-public class RiddersSolver extends UnivariateRealSolverImpl {
+public class RiddersSolver extends AbstractUnivariateRealSolver {
+ /** Default absolute accuracy. */
+ public static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;
/**
- * Construct a solver.
+ * Construct a solver with default accuracy.
*/
public RiddersSolver() {
- super(100, 1E-6);
+ this(DEFAULT_ABSOLUTE_ACCURACY);
}
-
/**
- * Find a root in the given interval with initial value.
- * <p>
- * Requires bracketing condition.</p>
+ * Construct a solver.
*
- * @param f the function to solve
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @param initial the start value to use
- * @return the point at which the function value is zero
- * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if any parameters are invalid
+ * @param absoluteAccuracy Absolute accuracy.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max, final double initial)
- throws MaxIterationsExceededException, MathUserException {
-
- // check for zeros before verifying bracketing
- if (f.value(min) == 0.0) { return min; }
- if (f.value(max) == 0.0) { return max; }
- if (f.value(initial) == 0.0) { return initial; }
-
- verifyBracketing(min, max, f);
- verifySequence(min, initial, max);
- if (isBracketing(min, initial, f)) {
- return solve(f, min, initial);
- } else {
- return solve(f, initial, max);
- }
+ public RiddersSolver(double absoluteAccuracy) {
+ super(absoluteAccuracy);
}
-
/**
- * Find a root in the given interval.
- * <p>
- * Requires bracketing condition.</p>
+ * Construct a solver.
*
- * @param f the function to solve
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @return the point at which the function value is zero
- * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if any parameters are invalid
+ * @param relativeAccuracy Relative accuracy.
+ * @param absoluteAccuracy Absolute accuracy.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max)
- throws MaxIterationsExceededException, MathUserException {
+ public RiddersSolver(double relativeAccuracy,
+ double absoluteAccuracy) {
+ super(relativeAccuracy, absoluteAccuracy);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected double doSolve() {
+ double min = getMin();
+ double max = getMax();
// [x1, x2] is the bracketing interval in each iteration
// x3 is the midpoint of [x1, x2]
// x is the new root approximation and an endpoint of the new interval
double x1 = min;
- double y1 = f.value(x1);
+ double y1 = computeObjectiveValue(x1);
double x2 = max;
- double y2 = f.value(x2);
+ double y2 = computeObjectiveValue(x2);
// check for zeros before verifying bracketing
- if (y1 == 0.0) {
+ if (y1 == 0) {
return min;
}
- if (y2 == 0.0) {
+ if (y2 == 0) {
return max;
}
- verifyBracketing(min, max, f);
+ verifyBracketing(min, max);
+
+ final double absoluteAccuracy = getAbsoluteAccuracy();
+ final double functionValueAccuracy = getFunctionValueAccuracy();
+ final double relativeAccuracy = getRelativeAccuracy();
- int i = 1;
double oldx = Double.POSITIVE_INFINITY;
- while (i <= maximalIterationCount) {
+ while (true) {
// calculate the new root approximation
final double x3 = 0.5 * (x1 + x2);
- final double y3 = f.value(x3);
+ final double y3 = computeObjectiveValue(x3);
if (FastMath.abs(y3) <= functionValueAccuracy) {
- setResult(x3, i);
- return result;
+ return x3;
}
final double delta = 1 - (y1 * y2) / (y3 * y3); // delta > 1 due to bracketing
final double correction = (MathUtils.sign(y2) * MathUtils.sign(y3)) *
(x3 - x1) / FastMath.sqrt(delta);
final double x = x3 - correction; // correction != 0
- final double y = f.value(x);
+ final double y = computeObjectiveValue(x);
// check for convergence
final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
if (FastMath.abs(x - oldx) <= tolerance) {
- setResult(x, i);
- return result;
+ return x;
}
if (FastMath.abs(y) <= functionValueAccuracy) {
- setResult(x, i);
- return result;
+ return x;
}
// prepare the new interval for next iteration
@@ -161,8 +135,6 @@ public class RiddersSolver extends Univa
}
}
oldx = x;
- i++;
}
- throw new MaxIterationsExceededException(maximalIterationCount);
}
}
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java Thu Nov 25 16:22:00 2010
@@ -16,12 +16,7 @@
*/
package org.apache.commons.math.analysis.solvers;
-import org.apache.commons.math.ConvergenceException;
-import org.apache.commons.math.exception.MathUserException;
-import org.apache.commons.math.MathRuntimeException;
-import org.apache.commons.math.MaxIterationsExceededException;
-import org.apache.commons.math.analysis.UnivariateRealFunction;
-import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NoBracketingException;
import org.apache.commons.math.util.FastMath;
@@ -41,52 +36,46 @@ import org.apache.commons.math.util.Fast
*
* @version $Revision$ $Date$
*/
-public class SecantSolver extends UnivariateRealSolverImpl {
+public class SecantSolver extends AbstractUnivariateRealSolver {
+ /** Default absolute accuracy. */
+ public static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;
/**
- * Construct a solver.
+ * Construct a solver with default accuracy.
*/
public SecantSolver() {
- super(100, 1E-6);
+ this(DEFAULT_ABSOLUTE_ACCURACY);
}
-
/**
- * Find a zero in the given interval.
+ * Construct a solver.
*
- * @param f the function to solve
- * @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 MaxIterationsExceededException if the maximum iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if min is not less than max or the
- * signs of the values of the function at the endpoints are not opposites
+ * @param absoluteAccuracy Absolute accuracy.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max, final double initial)
- throws MaxIterationsExceededException, MathUserException {
- return solve(f, min, max);
+ public SecantSolver(double absoluteAccuracy) {
+ super(absoluteAccuracy);
}
-
/**
- * Find a zero in the given interval.
- * @param f the function to solve
- * @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 MaxIterationsExceededException if the maximum iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if min is not less than max or the
- * signs of the values of the function at the endpoints are not opposites
+ * Construct a solver.
+ *
+ * @param relativeAccuracy Relative accuracy.
+ * @param absoluteAccuracy Absolute accuracy.
*/
- public double solve(final UnivariateRealFunction f,
- final double min, final double max)
- throws MaxIterationsExceededException, MathUserException {
+ public SecantSolver(double relativeAccuracy,
+ double absoluteAccuracy) {
+ super(relativeAccuracy, absoluteAccuracy);
+ }
- clearResult();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected double doSolve() {
+ double min = getMin();
+ double max = getMax();
verifyInterval(min, max);
+ final double functionValueAccuracy = getFunctionValueAccuracy();
+
// 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.
@@ -94,20 +83,31 @@ public class SecantSolver extends Univar
// iteration.
double x0 = min;
double x1 = max;
- double y0 = f.value(x0);
- double y1 = f.value(x1);
+
+ double y0 = computeObjectiveValue(x0);
+ // return the first endpoint if it is good enough
+ if (FastMath.abs(y0) <= functionValueAccuracy) {
+ return x0;
+ }
+
+ // return the second endpoint if it is good enough
+ double y1 = computeObjectiveValue(x1);
+ if (FastMath.abs(y1) <= functionValueAccuracy) {
+ return x1;
+ }
// Verify bracketing
if (y0 * y1 >= 0) {
- throw MathRuntimeException.createIllegalArgumentException(
- LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, y0, y1);
+ throw new NoBracketingException(min, max, y0, y1);
}
+ final double absoluteAccuracy = getAbsoluteAccuracy();
+ final double relativeAccuracy = getRelativeAccuracy();
+
double x2 = x0;
double y2 = y0;
double oldDelta = x2 - x1;
- int i = 0;
- while (i < maximalIterationCount) {
+ while (true) {
if (FastMath.abs(y2) < FastMath.abs(y1)) {
x0 = x1;
x1 = x2;
@@ -117,13 +117,11 @@ public class SecantSolver extends Univar
y2 = y0;
}
if (FastMath.abs(y1) <= functionValueAccuracy) {
- setResult(x1, i);
- return result;
+ return x1;
}
- if (FastMath.abs(oldDelta) <
- FastMath.max(relativeAccuracy * FastMath.abs(x1), absoluteAccuracy)) {
- setResult(x1, i);
- return result;
+ if (FastMath.abs(oldDelta) < FastMath.max(relativeAccuracy * FastMath.abs(x1),
+ absoluteAccuracy)) {
+ return x1;
}
double delta;
if (FastMath.abs(y1) > FastMath.abs(y0)) {
@@ -140,16 +138,13 @@ public class SecantSolver extends Univar
x0 = x1;
y0 = y1;
x1 = x1 + delta;
- y1 = f.value(x1);
+ y1 = computeObjectiveValue(x1);
if ((y1 > 0) == (y2 > 0)) {
// New bracket is (x0,x1).
x2 = x0;
y2 = y0;
}
oldDelta = x2 - x1;
- i++;
}
- throw new MaxIterationsExceededException(maximalIterationCount);
}
-
}
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java Thu Nov 25 16:22:00 2010
@@ -16,104 +16,14 @@
*/
package org.apache.commons.math.analysis.solvers;
-import org.apache.commons.math.ConvergenceException;
-import org.apache.commons.math.ConvergingAlgorithm;
-import org.apache.commons.math.exception.MathUserException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
/**
- * Interface for (univariate real) rootfinding algorithms.
- * <p>
- * Implementations will search for only one zero in the given interval.</p>
+ * Interface for (univariate real) root-finding algorithms.
+ * Implementations will search for only one zero in the given interval.
*
* @version $Revision$ $Date$
*/
-public interface UnivariateRealSolver extends ConvergingAlgorithm {
-
- /**
- * Set the function value accuracy.
- * <p>
- * This is used to determine when an evaluated function value or some other
- * value which is used as divisor is zero.</p>
- * <p>
- * This is a safety guard and it shouldn't be necessary to change this in
- * general.</p>
- *
- * @param accuracy the accuracy.
- * @throws IllegalArgumentException if the accuracy can't be achieved by
- * the solver or is otherwise deemed unreasonable.
- */
- void setFunctionValueAccuracy(double accuracy);
-
- /**
- * Get the actual function value accuracy.
- * @return the accuracy
- */
- double getFunctionValueAccuracy();
-
- /**
- * Reset the actual function accuracy to the default.
- * The default value is provided by the solver implementation.
- */
- void resetFunctionValueAccuracy();
-
- /**
- * Solve for a zero root in the given interval.
- * <p>A solver may require that the interval brackets a single zero root.
- * Solvers that do require bracketing should be able to handle the case
- * where one of the endpoints is itself a root.</p>
- *
- * @param f the function to solve.
- * @param min the lower bound for the interval.
- * @param max the upper bound for the interval.
- * @return a value where the function is zero
- * @throws ConvergenceException if the maximum iteration count is exceeded
- * or the solver detects convergence problems otherwise.
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if min > max or the endpoints do not
- * satisfy the requirements specified by the solver
- * @since 2.0
- */
- double solve(UnivariateRealFunction f, double min, double max)
- throws ConvergenceException, MathUserException;
-
- /**
- * Solve for a zero in the given interval, start at startValue.
- * <p>A solver may require that the interval brackets a single zero root.
- * Solvers that do require bracketing should be able to handle the case
- * where one of the endpoints is itself a root.</p>
- *
- * @param f the function to solve.
- * @param min the lower bound for the interval.
- * @param max the upper bound for the interval.
- * @param startValue the start value to use
- * @return a value where the function is zero
- * @throws ConvergenceException if the maximum iteration count is exceeded
- * or the solver detects convergence problems otherwise.
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if min > max or the arguments do not
- * satisfy the requirements specified by the solver
- * @since 2.0
- */
- double solve(UnivariateRealFunction f, double min, double max, double startValue)
- throws ConvergenceException, MathUserException, IllegalArgumentException;
-
- /**
- * Get the result of the last run of the solver.
- *
- * @return the last result.
- * @throws IllegalStateException if there is no result available, either
- * because no result was yet computed or the last attempt failed.
- */
- double getResult();
-
- /**
- * Get the result of the last run of the solver.
- *
- * @return the value of the function at the last result.
- * @throws IllegalStateException if there is no result available, either
- * because no result was yet computed or the last attempt failed.
- */
- double getFunctionValue();
-}
+public interface UnivariateRealSolver
+ extends BaseUnivariateRealSolver<UnivariateRealFunction> {}
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java Thu Nov 25 16:22:00 2010
@@ -22,16 +22,17 @@ import org.apache.commons.math.MathRunti
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.exception.MathUserException;
-import org.apache.commons.math.exception.NullArgumentException;
/**
* Provide a default implementation for several functions useful to generic
* solvers.
*
* @version $Revision$ $Date$
+ * @deprecated in 2.2 (to be removed in 3.0). Please use
+ * {@link AbstractUnivariateRealSolver} instead.
*/
-public abstract class UnivariateRealSolverImpl
- extends ConvergingAlgorithmImpl implements UnivariateRealSolver {
+@Deprecated
+public abstract class UnivariateRealSolverImpl extends ConvergingAlgorithmImpl {
/** Maximum error of function. */
protected double functionValueAccuracy;
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java Thu Nov 25 16:22:00 2010
@@ -16,12 +16,12 @@
*/
package org.apache.commons.math.analysis.solvers;
-import org.apache.commons.math.ConvergenceException;
-import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;
-import org.apache.commons.math.exception.MathUserException;
import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.NoBracketingException;
+import org.apache.commons.math.exception.NumberIsTooLargeException;
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.util.FastMath;
/**
@@ -30,56 +30,53 @@ import org.apache.commons.math.util.Fast
* @version $Revision$ $Date$
*/
public class UnivariateRealSolverUtils {
-
/**
- * Default constructor.
+ * Class contains only static methods.
*/
- private UnivariateRealSolverUtils() {
- super();
- }
+ private UnivariateRealSolverUtils() {}
/**
* Convenience method to find a zero of a univariate real function. A default
* solver is used.
*
- * @param f the function.
- * @param x0 the lower bound for the interval.
- * @param x1 the upper bound for the interval.
+ * @param function Function.
+ * @param x0 Lower bound for the interval.
+ * @param x1 Upper bound for the interval.
* @return a value where the function is zero.
- * @throws ConvergenceException if the iteration count was exceeded
- * @throws MathUserException if an error occurs evaluating the function
* @throws IllegalArgumentException if f is null or the endpoints do not
- * specify a valid interval
+ * specify a valid interval.
*/
- public static double solve(UnivariateRealFunction f, double x0, double x1)
- throws ConvergenceException, MathUserException {
- setup(f);
- return LazyHolder.FACTORY.newDefaultSolver().solve(f, x0, x1);
+ public static double solve(UnivariateRealFunction function, double x0, double x1) {
+ if (function == null) {
+ throw new NullArgumentException(LocalizedFormats.FUNCTION);
+ }
+ final UnivariateRealSolver solver = new BrentSolver();
+ solver.setMaxEvaluations(Integer.MAX_VALUE);
+ return solver.solve(function, x0, x1);
}
/**
* Convenience method to find a zero of a univariate real function. A default
* solver is used.
*
- * @param f the function
- * @param x0 the lower bound for the interval
- * @param x1 the upper bound for the interval
- * @param absoluteAccuracy the accuracy to be used by the solver
- * @return a value where the function is zero
- * @throws ConvergenceException if the iteration count is exceeded
- * @throws MathUserException if an error occurs evaluating the function
- * @throws IllegalArgumentException if f is null, the endpoints do not
- * specify a valid interval, or the absoluteAccuracy is not valid for the
- * default solver
- */
- public static double solve(UnivariateRealFunction f, double x0, double x1,
- double absoluteAccuracy) throws ConvergenceException,
- MathUserException {
-
- setup(f);
- UnivariateRealSolver solver = LazyHolder.FACTORY.newDefaultSolver();
- solver.setAbsoluteAccuracy(absoluteAccuracy);
- return solver.solve(f, x0, x1);
+ * @param function Function.
+ * @param x0 Lower bound for the interval.
+ * @param x1 Upper bound for the interval.
+ * @param absoluteAccuracy Accuracy to be used by the solver.
+ * @return a value where the function is zero.
+ * @throws IllegalArgumentException if {@code function} is {@code null},
+ * the endpoints do not specify a valid interval, or the absolute accuracy
+ * is not valid for the default solver.
+ */
+ public static double solve(UnivariateRealFunction function,
+ double x0, double x1,
+ double absoluteAccuracy) {
+ if (function == null) {
+ throw new NullArgumentException(LocalizedFormats.FUNCTION);
+ }
+ final UnivariateRealSolver solver = new BrentSolver(absoluteAccuracy);
+ solver.setMaxEvaluations(Integer.MAX_VALUE);
+ return solver.solve(function, x0, x1);
}
/**
@@ -110,23 +107,21 @@ public class UnivariateRealSolverUtils {
* {@link #bracket(UnivariateRealFunction, double, double, double, int)},
* explicitly specifying the maximum number of iterations.</p>
*
- * @param function the function
- * @param initial initial midpoint of interval being expanded to
- * bracket a root
- * @param lowerBound lower bound (a is never lower than this value)
- * @param upperBound upper bound (b never is greater than this
- * value)
- * @return a two element array holding {a, b}
- * @throws ConvergenceException if a root can not be bracketted
- * @throws MathUserException if an error occurs evaluating the function
+ * @param function Function.
+ * @param initial Initial midpoint of interval being expanded to
+ * bracket a root.
+ * @param lowerBound Lower bound (a is never lower than this value)
+ * @param upperBound Upper bound (b never is greater than this
+ * value).
+ * @return a two-element array holding a and b.
+ * @throws NoBracketingException if a root cannot be bracketted.
* @throws IllegalArgumentException if function is null, maximumIterations
- * is not positive, or initial is not between lowerBound and upperBound
+ * is not positive, or initial is not between lowerBound and upperBound.
*/
public static double[] bracket(UnivariateRealFunction function,
- double initial, double lowerBound, double upperBound)
- throws ConvergenceException, MathUserException {
- return bracket( function, initial, lowerBound, upperBound,
- Integer.MAX_VALUE ) ;
+ double initial,
+ double lowerBound, double upperBound) {
+ return bracket(function, initial, lowerBound, upperBound, Integer.MAX_VALUE);
}
/**
@@ -148,42 +143,36 @@ public class UnivariateRealSolverUtils {
* <li> <code> maximumIterations</code> iterations elapse
* -- ConvergenceException </li></ul></p>
*
- * @param function the function
- * @param initial initial midpoint of interval being expanded to
- * bracket a root
- * @param lowerBound lower bound (a is never lower than this value)
- * @param upperBound upper bound (b never is greater than this
- * value)
- * @param maximumIterations maximum number of iterations to perform
- * @return a two element array holding {a, b}.
- * @throws ConvergenceException if the algorithm fails to find a and b
- * satisfying the desired conditions
- * @throws MathUserException if an error occurs evaluating the function
+ * @param function Function.
+ * @param initial Initial midpoint of interval being expanded to
+ * bracket a root.
+ * @param lowerBound Lower bound (a is never lower than this value).
+ * @param upperBound Upper bound (b never is greater than this
+ * value).
+ * @param maximumIterations Maximum number of iterations to perform
+ * @return a two element array holding a and b.
+ * @throws NoBracketingException if the algorithm fails to find a and b
+ * satisfying the desired conditions.
* @throws IllegalArgumentException if function is null, maximumIterations
- * is not positive, or initial is not between lowerBound and upperBound
+ * is not positive, or initial is not between lowerBound and upperBound.
*/
public static double[] bracket(UnivariateRealFunction function,
- double initial, double lowerBound, double upperBound,
- int maximumIterations) throws ConvergenceException,
- MathUserException {
-
+ double initial,
+ double lowerBound, double upperBound,
+ int maximumIterations) {
if (function == null) {
throw new NullArgumentException(LocalizedFormats.FUNCTION);
}
if (maximumIterations <= 0) {
- throw MathRuntimeException.createIllegalArgumentException(
- LocalizedFormats.INVALID_MAX_ITERATIONS, maximumIterations);
- }
- if (initial < lowerBound || initial > upperBound || lowerBound >= upperBound) {
- throw MathRuntimeException.createIllegalArgumentException(
- LocalizedFormats.INVALID_BRACKETING_PARAMETERS,
- lowerBound, initial, upperBound);
+ throw new NotStrictlyPositiveException(LocalizedFormats.INVALID_MAX_ITERATIONS, maximumIterations);
}
+ verifySequence(lowerBound, initial, upperBound);
+
double a = initial;
double b = initial;
double fa;
double fb;
- int numIterations = 0 ;
+ int numIterations = 0;
do {
a = FastMath.max(a - 1.0, lowerBound);
@@ -191,18 +180,18 @@ public class UnivariateRealSolverUtils {
fa = function.value(a);
fb = function.value(b);
- numIterations++ ;
+ ++numIterations;
} while ((fa * fb > 0.0) && (numIterations < maximumIterations) &&
((a > lowerBound) || (b < upperBound)));
- if (fa * fb > 0.0 ) {
- throw new ConvergenceException(
- LocalizedFormats.FAILED_BRACKETING,
- numIterations, maximumIterations, initial,
- lowerBound, upperBound, a, b, fa, fb);
+ if (fa * fb > 0.0) {
+ throw new NoBracketingException(LocalizedFormats.FAILED_BRACKETING,
+ a, b, fa, fb,
+ numIterations, maximumIterations, initial,
+ lowerBound, upperBound);
}
- return new double[]{a, b};
+ return new double[] {a, b};
}
/**
@@ -213,28 +202,95 @@ public class UnivariateRealSolverUtils {
* @return the midpoint.
*/
public static double midpoint(double a, double b) {
- return (a + b) * .5;
+ return (a + b) * 0.5;
}
/**
- * Checks to see if f is null, throwing IllegalArgumentException if so.
- * @param f input function
- * @throws IllegalArgumentException if f is null
+ * Check whether the function takes opposite signs at the endpoints.
+ *
+ * @param function Function.
+ * @param lower Lower endpoint.
+ * @param upper Upper endpoint.
+ * @return {@code true} if the function values have opposite signs at the
+ * given points.
*/
- private static void setup(UnivariateRealFunction f) {
- if (f == null) {
+ public static boolean isBracketing(UnivariateRealFunction function,
+ final double lower,
+ final double upper) {
+ if (function == null) {
throw new NullArgumentException(LocalizedFormats.FUNCTION);
}
+ final double fLo = function.value(lower);
+ final double fHi = function.value(upper);
+ return (fLo > 0 && fHi < 0) || (fLo < 0 && fHi > 0);
}
- // CHECKSTYLE: stop HideUtilityClassConstructor
- /** Holder for the factory.
- * <p>We use here the Initialization On Demand Holder Idiom.</p>
- */
- private static class LazyHolder {
- /** Cached solver factory */
- private static final UnivariateRealSolverFactory FACTORY = UnivariateRealSolverFactory.newInstance();
+ /**
+ * Check whether the arguments form a (strictly) increasing sequence.
+ *
+ * @param start First number.
+ * @param mid Second number.
+ * @param end Third number.
+ * @return {@code true} if the arguments form an increasing sequence.
+ */
+ public static boolean isSequence(final double start,
+ final double mid,
+ final double end) {
+ return (start < mid) && (mid < end);
}
- // CHECKSTYLE: resume HideUtilityClassConstructor
+ /**
+ * Check that the endpoints specify an interval.
+ *
+ * @param lower Lower endpoint.
+ * @param upper Upper endpoint.
+ * @throws NumberIsTooLargeException if {@code lower >= upper}.
+ */
+ public static void verifyInterval(final double lower,
+ final double upper) {
+ if (lower >= upper) {
+ throw new NumberIsTooLargeException(LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
+ lower, upper, false);
+ }
+ }
+
+ /**
+ * Check that {@code lower < initial < upper}.
+ *
+ * @param lower Lower endpoint.
+ * @param initial Initial value.
+ * @param upper Upper endpoint.
+ * @throws NumberIsTooLargeException if {@code lower >= initial} or
+ * {@code initial >= upper}.
+ */
+ public static void verifySequence(final double lower,
+ final double initial,
+ final double upper) {
+ verifyInterval(lower, initial);
+ verifyInterval(initial, upper);
+ }
+
+ /**
+ * Check that the endpoints specify an interval and the function takes
+ * opposite signs at the endpoints.
+ *
+ * @param function Function.
+ * @param lower Lower endpoint.
+ * @param upper Upper endpoint.
+ * @throws NoBracketingException if function has the same sign at the
+ * endpoints.
+ */
+ public static void verifyBracketing(UnivariateRealFunction function,
+ final double lower,
+ final double upper) {
+ if (function == null) {
+ throw new NullArgumentException(LocalizedFormats.FUNCTION);
+ }
+ verifyInterval(lower, upper);
+ if (!isBracketing(function, lower, upper)) {
+ throw new NoBracketingException(lower, upper,
+ function.value(lower),
+ function.value(upper));
+ }
+ }
}
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java Thu Nov 25 16:22:00 2010
@@ -18,7 +18,6 @@ package org.apache.commons.math.distribu
import java.io.Serializable;
-import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.MathException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.solvers.BrentSolver;
@@ -27,6 +26,7 @@ import org.apache.commons.math.exception
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.OutOfRangeException;
import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NumberIsTooLargeException;
import org.apache.commons.math.random.RandomDataImpl;
import org.apache.commons.math.util.FastMath;
@@ -106,7 +106,7 @@ public abstract class AbstractContinuous
bracket = UnivariateRealSolverUtils.bracket(
rootFindingFunction, getInitialDomain(p),
lowerBound, upperBound);
- } catch (ConvergenceException ex) {
+ } catch (NumberIsTooLargeException ex) {
/*
* Check domain endpoints to see if one gives value that is within
* the default solver's defaultAbsoluteAccuracy of 0 (will be the
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NoBracketingException.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NoBracketingException.java?rev=1039083&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NoBracketingException.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NoBracketingException.java Thu Nov 25 16:22:00 2010
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when function values have the same sign at both
+ * ends of an interval.
+ *
+ * @since 3.0
+ * @version $Revision$ $Date$
+ */
+public class NoBracketingException extends MathIllegalArgumentException {
+ /** Serializable version Id. */
+ private static final long serialVersionUID = -3629324471511904459L;
+ /** Lower end of the interval. */
+ private final double lo;
+ /** Higher end of the interval. */
+ private final double hi;
+ /** Value at lower end of the interval. */
+ private final double fLo;
+ /** Value at higher end of the interval. */
+ private final double fHi;
+
+ /**
+ * Construct the exception.
+ *
+ * @param lo Lower end of the interval.
+ * @param hi Higher end of the interval.
+ * @param fLo Value at lower end of the interval.
+ * @param fHi Value at higher end of the interval.
+ */
+ public NoBracketingException(double lo, double hi,
+ double fLo, double fHi) {
+ this(null, lo, hi, fLo, fHi);
+ }
+ /**
+ * Construct the exception with a specific context.
+ *
+ * @param specific Contextual information on what caused the exception.
+ * @param lo Lower end of the interval.
+ * @param hi Higher end of the interval.
+ * @param fLo Value at lower end of the interval.
+ * @param fHi Value at higher end of the interval.
+ */
+ public NoBracketingException(Localizable specific,
+ double lo, double hi,
+ double fLo, double fHi) {
+ super(specific, LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, lo, hi, fLo, fHi);
+ this.lo = lo;
+ this.hi = hi;
+ this.fLo = fLo;
+ this.fHi = fHi;
+ }
+ /**
+ * Construct the exception with a specific context.
+ *
+ * @param specific Contextual information on what caused the exception.
+ * @param lo Lower end of the interval.
+ * @param hi Higher end of the interval.
+ * @param fLo Value at lower end of the interval.
+ * @param fHi Value at higher end of the interval.
+ * @param args Additional arguments.
+ */
+ public NoBracketingException(Localizable specific,
+ double lo, double hi,
+ double fLo, double fHi,
+ Object ... args) {
+ super(specific, LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, lo, hi, fLo, fHi, args);
+ this.lo = lo;
+ this.hi = hi;
+ this.fLo = fLo;
+ this.fHi = fHi;
+ }
+
+ /**
+ * Get the lower end of the interval.
+ *
+ * @return the lower end.
+ */
+ public double getLo() {
+ return lo;
+ }
+ /**
+ * Get the higher end of the interval.
+ *
+ * @return the higher end.
+ */
+ public double getHi() {
+ return hi;
+ }
+ /**
+ * Get the value at the lower end of the interval.
+ *
+ * @return the value at the lower end.
+ */
+ public double getFLo() {
+ return fLo;
+ }
+ /**
+ * Get the value at the higher end of the interval.
+ *
+ * @return the value at the higher end.
+ */
+ public double getFHi() {
+ return fHi;
+ }
+}
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NoBracketingException.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java Thu Nov 25 16:22:00 2010
@@ -98,7 +98,7 @@ public enum LocalizedFormats implements
EVALUATION("evaluation"), /* keep */
EXPANSION_FACTOR_SMALLER_THAN_ONE("expansion factor smaller than one ({0})"),
FACTORIAL_NEGATIVE_PARAMETER("must have n >= 0 for n!, got n = {0}"),
- FAILED_BRACKETING("number of iterations={0}, maximum iterations={1}, initial={2}, lower bound={3}, upper bound={4}, final a value={5}, final b value={6}, f(a)={7}, f(b)={8}"),
+ FAILED_BRACKETING("number of iterations={4}, maximum iterations={5}, initial={6}, lower bound={7}, upper bound={8}, final a value={0}, final b value={1}, f(a)={2}, f(b)={3}"),
FAILED_FRACTION_CONVERSION("Unable to convert {0} to fraction after {1} iterations"),
FIRST_COLUMNS_NOT_INITIALIZED_YET("first {0} columns are not initialized yet"),
FIRST_ELEMENT_NOT_ZERO("first element is not 0: {0}"),
@@ -263,6 +263,7 @@ public enum LocalizedFormats implements
PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD("cannot access {0} method in percentile implementation {1}"),
PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD("percentile implementation {0} does not support {1}"),
PERMUTATION_EXCEEDS_N("permutation size ({0}) exceeds permuation domain ({1})"), /* keep */
+ POLYNOMIAL("polynomial"), /* keep */
POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS("number of polynomial interpolants must match the number of segments ({0} != {1} - 1)"),
POPULATION_LIMIT_NOT_POSITIVE("population limit has to be positive"),
POSITION_SIZE_MISMATCH_INPUT_ARRAY("position {0} and size {1} don't fit to the size of the input array {2}"),
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/events/EventState.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/events/EventState.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/events/EventState.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/events/EventState.java Thu Nov 25 16:22:00 2010
@@ -252,7 +252,8 @@ public class EventState {
}
}
};
- final BrentSolver solver = new BrentSolver(maxIterationCount, convergence);
+ final BrentSolver solver = new BrentSolver(convergence);
+ solver.setMaxEvaluations(maxIterationCount);
final double root = (ta <= tb) ? solver.solve(f, ta, tb) : solver.solve(f, tb, ta);
if ((FastMath.abs(root - ta) <= convergence) &&
(FastMath.abs(root - previousEventTime) <= convergence)) {
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java Thu Nov 25 16:22:00 2010
@@ -109,8 +109,7 @@ public class LeastSquaresConverter imple
* the {@link #value(double[])} method is called)
*/
public LeastSquaresConverter(final MultivariateVectorialFunction function,
- final double[] observations, final double[] weights)
- throws IllegalArgumentException {
+ final double[] observations, final double[] weights) {
if (observations.length != weights.length) {
throw new DimensionMismatchException(observations.length, weights.length);
}
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java Thu Nov 25 16:22:00 2010
@@ -18,7 +18,6 @@
package org.apache.commons.math.optimization.fitting;
import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
-import org.apache.commons.math.optimization.OptimizationException;
import org.apache.commons.math.optimization.fitting.CurveFitter;
import org.apache.commons.math.optimization.fitting.WeightedObservedPoint;
@@ -86,7 +85,8 @@ public class GaussianFitter {
/**
* Fits Gaussian function to the observed points.
- * It will call {@link CurveFitter#fit()}.
+ * It will call the base class
+ * {@link CurveFitter#fit(ParametricRealFunction,double[]) fit} method.
*
* @return the Gaussian function that best fits the observed points.
* @see CurveFitter
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java Thu Nov 25 16:22:00 2010
@@ -77,6 +77,7 @@ public class HarmonicFitter {
* @return harmonic Function that best fits the observed points.
* @throws NumberIsTooSmallException if the sample is too short or if
* the first guess cannot be computed.
+ * @throws OptimizationException
*/
public HarmonicFunction fit() throws OptimizationException {
// shall we compute the first guess of the parameters ourselves ?
@@ -93,7 +94,7 @@ public class HarmonicFitter {
guesser.getGuessedAmplitude(),
guesser.getGuessedPulsation(),
guesser.getGuessedPhase()
- };
+ };
}
double[] fitted = fitter.fit(new ParametricHarmonicFunction(), parameters);
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java Thu Nov 25 16:22:00 2010
@@ -97,11 +97,9 @@ public class ParametricGaussianFunction
* respect to {@code c}, and the partial derivative of {@code f(a, b, c,
* d)} with respect to {@code d}.
*
- * @param x {@code x} value to be used as constant in {@code f(a, b, c, d)}.
- * @param parameters values of {@code a}, {@code b}, {@code c}, and
- * {@code d} for computation of gradient vector of {@code f(a, b, c, d)}.
- * @return the gradient vector of {@code f(a, b, c, d)}.
+ * @param x Value to be used as constant in {@code f(x, a, b, c, d)}.
* @param parameters Values of {@code a}, {@code b}, {@code c}, and {@code d}.
+ * @return the gradient vector of {@code f(a, b, c, d)}.
* @throws NullArgumentException if {@code parameters} is {@code null}.
* @throws DimensionMismatchException if the size of {@code parameters} is
* not 4.
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java Thu Nov 25 16:22:00 2010
@@ -17,7 +17,6 @@
package org.apache.commons.math.optimization.general;
-import org.apache.commons.math.exception.MathUserException;
import org.apache.commons.math.exception.NumberIsTooSmallException;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
@@ -98,9 +97,10 @@ public abstract class AbstractLeastSquar
*
* @throws DimensionMismatchException if the Jacobian dimension does not
* match problem dimension.
- * @throws MathUserException if users jacobian function throws one
+ * @throws org.apache.commons.math.exception.MathUserException if the jacobian
+ * function throws one.
*/
- protected void updateJacobian() throws MathUserException {
+ protected void updateJacobian() {
++jacobianEvaluations;
weightedResidualJacobian = jF.value(point);
if (weightedResidualJacobian.length != rows) {
@@ -126,7 +126,7 @@ public abstract class AbstractLeastSquar
* @throws org.apache.commons.math.exception.TooManyEvaluationsException
* if the maximal number of evaluations is exceeded.
*/
- protected void updateResidualsAndCost() throws MathUserException {
+ protected void updateResidualsAndCost() {
objective = computeObjectiveValue(point);
if (objective.length != rows) {
throw new DimensionMismatchException(objective.length, rows);
@@ -176,9 +176,10 @@ public abstract class AbstractLeastSquar
* @return the covariance matrix.
* @throws org.apache.commons.math.exception.SingularMatrixException
* if the covariance matrix cannot be computed (singular problem).
- * @throws MathUserException if jacobian function throws one
+ * @throws org.apache.commons.math.exception.MathUserException if the jacobian
+ * function throws one.
*/
- public double[][] getCovariances() throws MathUserException {
+ public double[][] getCovariances() {
// set up the jacobian
updateJacobian();
@@ -211,9 +212,10 @@ public abstract class AbstractLeastSquar
* @throws NumberIsTooSmallException if the number of degrees of freedom is not
* positive, i.e. the number of measurements is less or equal to the number of
* parameters.
- * @throws MathUserException if jacobian function throws one
+ * @throws org.apache.commons.math.exception.MathUserException if the jacobian
+ * function throws one.
*/
- public double[] guessParametersErrors() throws MathUserException {
+ public double[] guessParametersErrors() {
if (rows <= cols) {
throw new NumberIsTooSmallException(LocalizedFormats.NO_DEGREES_OF_FREEDOM,
rows, cols, false);
@@ -231,7 +233,7 @@ public abstract class AbstractLeastSquar
@Override
public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f,
final double[] target, final double[] weights,
- final double[] startPoint) throws MathUserException {
+ final double[] startPoint) {
// Reset counter.
jacobianEvaluations = 0;
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java?rev=1039083&r1=1039082&r2=1039083&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java Thu Nov 25 16:22:00 2010
@@ -18,7 +18,6 @@
package org.apache.commons.math.optimization.general;
import org.apache.commons.math.exception.MathIllegalStateException;
-import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.exception.MathUserException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.solvers.BrentSolver;
@@ -40,7 +39,6 @@ import org.apache.commons.math.util.Fast
* @since 2.0
*
*/
-
public class NonLinearConjugateGradientOptimizer
extends AbstractScalarDifferentiableOptimizer {
/** Update formula for the beta parameter. */
@@ -86,7 +84,8 @@ public class NonLinearConjugateGradientO
* default {@link BrentSolver Brent solver}.
*/
public void setLineSearchSolver(final UnivariateRealSolver lineSearchSolver) {
- this.solver = lineSearchSolver;
+ solver = lineSearchSolver;
+ solver.setMaxEvaluations(getMaxEvaluations());
}
/**
@@ -116,6 +115,7 @@ public class NonLinearConjugateGradientO
}
if (solver == null) {
solver = new BrentSolver();
+ solver.setMaxEvaluations(getMaxEvaluations());
}
point = getStartPoint();
final GoalType goal = getGoalType();
@@ -158,15 +158,15 @@ public class NonLinearConjugateGradientO
// Find the optimal step in the search direction.
final UnivariateRealFunction lsf = new LineSearchFunction(searchDirection);
- try {
- final double step = solver.solve(lsf, 0, findUpperBound(lsf, 0, initialStep));
-
- // Validate new point.
- for (int i = 0; i < point.length; ++i) {
- point[i] += step * searchDirection[i];
- }
- } catch (org.apache.commons.math.ConvergenceException e) {
- throw new ConvergenceException(); // XXX ugly workaround.
+ final double uB = findUpperBound(lsf, 0, initialStep);
+ // XXX Last parameters is set to a value clode to zero in order to
+ // work around the divergence problem in the "testCircleFitting"
+ // unit test (see MATH-439).
+ final double step = solver.solve(lsf, 0, uB, 1e-15);
+
+ // Validate new point.
+ for (int i = 0; i < point.length; ++i) {
+ point[i] += step * searchDirection[i];
}
r = computeObjectiveGradient(point);
@@ -242,7 +242,6 @@ public class NonLinearConjugateGradientO
public double[] precondition(double[] variables, double[] r) {
return r.clone();
}
-
}
/** Internal class for line search.
@@ -267,7 +266,6 @@ public class NonLinearConjugateGradientO
/** {@inheritDoc} */
public double value(double x) throws MathUserException {
-
// current point in the search direction
final double[] shiftedPoint = point.clone();
for (int i = 0; i < shiftedPoint.length; ++i) {
@@ -284,9 +282,6 @@ public class NonLinearConjugateGradientO
}
return dotProduct;
-
}
-
}
-
}
|