From e7c3207b052f44a36c94a6b684f44ab79df59b86 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 18 Jan 2009 14:47:51 +0000 Subject: [PATCH] extracted a superinterface ConvergingAlgorithm from UnivariateRealSolver for later reuse by upcoming minimization algorithms git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@735468 13f79535-47bb-0310-9956-ffa450edef68 --- .../commons/math/ConvergingAlgorithm.java | 121 ++++++++ .../commons/math/ConvergingAlgorithmImpl.java | 123 ++++++++ .../commons/math/MessagesResources_fr.java | 27 +- .../math/analysis/solvers/BrentSolver.java | 16 +- .../solvers/UnivariateRealSolver.java | 107 +------ .../solvers/UnivariateRealSolverImpl.java | 278 +++++------------- 6 files changed, 338 insertions(+), 334 deletions(-) create mode 100644 src/java/org/apache/commons/math/ConvergingAlgorithm.java create mode 100644 src/java/org/apache/commons/math/ConvergingAlgorithmImpl.java diff --git a/src/java/org/apache/commons/math/ConvergingAlgorithm.java b/src/java/org/apache/commons/math/ConvergingAlgorithm.java new file mode 100644 index 000000000..06c1f62d2 --- /dev/null +++ b/src/java/org/apache/commons/math/ConvergingAlgorithm.java @@ -0,0 +1,121 @@ +package org.apache.commons.math; + +import java.io.Serializable; + +/** + * Interface for algorithms handling convergence settings. + *

+ * This interface only deals with convergence parameters setting, not + * execution of the algorithms per se. + *

+ * @see ConvergenceException + * @version $Revision$ $Date$ + * @since 2.0 + */ +public interface ConvergingAlgorithm extends Serializable { + + /** + * 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 algorithms. Users are + * advised to use the default value supplied by the algorithm.

+ *

+ * A {@link ConvergenceException} will be thrown if this number + * is exceeded.

+ * + * @param count maximum number of iterations + */ + public abstract void setMaximalIterationCount(int count); + + /** + * Get the upper limit for the number of iterations. + * + * @return the actual upper limit + */ + public abstract int getMaximalIterationCount(); + + /** + * Reset the upper limit for the number of iterations to the default. + *

+ * The default value is supplied by the algorithm implementation.

+ * + * @see #setMaximalIterationCount(int) + */ + public abstract void resetMaximalIterationCount(); + + /** + * Set the absolute accuracy. + *

+ * The default is usually chosen so that results in the interval + * -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the + * expected absolute value of your results is of much smaller magnitude, set + * this to a smaller value.

+ *

+ * Algorithms are advised to do a plausibility check with the relative + * accuracy, but clients should not rely on this.

+ * + * @param accuracy the accuracy. + * @throws IllegalArgumentException if the accuracy can't be achieved by + * the solver or is otherwise deemed unreasonable. + */ + public abstract void setAbsoluteAccuracy(double accuracy); + + /** + * Get the actual absolute accuracy. + * + * @return the accuracy + */ + public abstract double getAbsoluteAccuracy(); + + /** + * Reset the absolute accuracy to the default. + *

+ * The default value is provided by the algorithm implementation.

+ */ + public abstract 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 criterion for convergence rather then a + * safety measure, set the absolute accuracy to a ridiculously small value, + * like {@link org.apache.commons.math.util.MathUtils#SAFE_MIN MathUtils.SAFE_MIN}.

+ * + * @param accuracy the relative accuracy. + * @throws IllegalArgumentException if the accuracy can't be achieved by + * the algorithm or is otherwise deemed unreasonable. + */ + public abstract void setRelativeAccuracy(double accuracy); + + /** + * Get the actual relative accuracy. + * @return the accuracy + */ + public abstract double getRelativeAccuracy(); + + /** + * Reset the relative accuracy to the default. + * The default value is provided by the algorithm implementation. + */ + public abstract void resetRelativeAccuracy(); + + /** + * Get the number of iterations in the last run of the algorithm. + *

+ * 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 problem is evaluated + * properly, and whether another algorithm is more amenable to the + * problem.

+ * + * @return the last iteration count. + * @throws IllegalStateException if there is no result available, either + * because no result was yet computed or the last attempt failed. + */ + public abstract int getIterationCount(); + +} \ No newline at end of file diff --git a/src/java/org/apache/commons/math/ConvergingAlgorithmImpl.java b/src/java/org/apache/commons/math/ConvergingAlgorithmImpl.java new file mode 100644 index 000000000..98bc234c8 --- /dev/null +++ b/src/java/org/apache/commons/math/ConvergingAlgorithmImpl.java @@ -0,0 +1,123 @@ +/* + * 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; + +/** + * Provide a default implementation for several functions useful to generic + * converging algorithms. + * + * @version $Revision$ $Date$ + * @since 2.0 + */ +public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm { + + /** Serializable version identifier. */ + private static final long serialVersionUID = 4059567655915789396L; + + /** Maximum absolute error. */ + protected double absoluteAccuracy; + + /** Maximum relative error. */ + protected double relativeAccuracy; + + /** Maximum number of iterations. */ + protected int maximalIterationCount; + + /** Default maximum absolute error. */ + protected double defaultAbsoluteAccuracy; + + /** Default maximum relative error. */ + protected double defaultRelativeAccuracy; + + /** Default maximum number of iterations. */ + protected int defaultMaximalIterationCount; + + // Mainly for test framework. + /** The last iteration count. */ + protected int iterationCount; + + /** + * Construct an algorithm with given iteration count and accuracy. + * + * @param defaultAbsoluteAccuracy maximum absolute error + * @param defaultMaximalIterationCount maximum number of iterations + * @throws IllegalArgumentException if f is null or the + * defaultAbsoluteAccuracy is not valid + */ + protected ConvergingAlgorithmImpl(final int defaultMaximalIterationCount, + final double defaultAbsoluteAccuracy) { + this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy; + this.defaultRelativeAccuracy = 1.0e-14; + this.absoluteAccuracy = defaultAbsoluteAccuracy; + this.relativeAccuracy = defaultRelativeAccuracy; + this.defaultMaximalIterationCount = defaultMaximalIterationCount; + this.maximalIterationCount = defaultMaximalIterationCount; + this.iterationCount = 0; + } + + /** {@inheritDoc} */ + public int getIterationCount() { + return iterationCount; + } + + /** {@inheritDoc} */ + public void setAbsoluteAccuracy(double accuracy) { + absoluteAccuracy = accuracy; + } + + /** {@inheritDoc} */ + public double getAbsoluteAccuracy() { + return absoluteAccuracy; + } + + /** {@inheritDoc} */ + public void resetAbsoluteAccuracy() { + absoluteAccuracy = defaultAbsoluteAccuracy; + } + + /** {@inheritDoc} */ + public void setMaximalIterationCount(int count) { + maximalIterationCount = count; + } + + /** {@inheritDoc} */ + public int getMaximalIterationCount() { + return maximalIterationCount; + } + + /** {@inheritDoc} */ + public void resetMaximalIterationCount() { + maximalIterationCount = defaultMaximalIterationCount; + } + + /** {@inheritDoc} */ + public void setRelativeAccuracy(double accuracy) { + relativeAccuracy = accuracy; + } + + /** {@inheritDoc} */ + public double getRelativeAccuracy() { + return relativeAccuracy; + } + + /** {@inheritDoc} */ + public void resetRelativeAccuracy() { + relativeAccuracy = defaultRelativeAccuracy; + } + +} diff --git a/src/java/org/apache/commons/math/MessagesResources_fr.java b/src/java/org/apache/commons/math/MessagesResources_fr.java index 39ec09d07..7bc01642f 100644 --- a/src/java/org/apache/commons/math/MessagesResources_fr.java +++ b/src/java/org/apache/commons/math/MessagesResources_fr.java @@ -78,7 +78,7 @@ public class MessagesResources_fr { "Overflow trying to convert {0} to fraction ({1}/{2})", "D\u00e9passement de capacit\u00e9 lors de la conversion de {0} en fraction ({1}/{2})" }, - // org.apache.commons.math.analysis.UnivariateRealSolverUtils + // org.apache.commons.math.analysis.solvers.UnivariateRealSolverUtils { "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}", "Nombre d''it\u00e9rations = {0}, it\u00e9rations maximum = {1}, valeur initiale = {2}," + @@ -267,19 +267,31 @@ public class MessagesResources_fr { "cannot substitute an element from an empty array", "impossible de substituer un \u00e9l\u00e9ment dans un tableau vide" }, - // org.apache.commons.math.analysis.PolynomialFunctionLagrangeForm + // org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm { "identical abscissas x[{0}] == x[{1}] == {2} cause division by zero", "division par z\u00e9ro caus\u00e9e par les abscisses identiques x[{0}] == x[{1}] == {2}" }, - // org.apache.commons.math.analysis.UnivariateRealSolverImpl + // org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl { "function to solve cannot be null", "la fonction \u00e0 r\u00e9soudre ne peux pas \u00eatre nulle" }, + { "invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}", + "param\u00e8tres de l''intervalle initial invalides : borne inf = {0}, valeur initiale = {1}, borne sup = {2}" }, - // org.apache.commons.math.analysis.LaguerreSolver + // org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl + // org.apache.commons.math.analysis.solvers.BrentSolver + { "function values at endpoints do not have different signs. Endpoints: [{0}, {1}], Values: [{2}, {3}]", + "les valeurs de la fonction aux bornes n''ont pas des signes diff\u00e9rents. Bornes : [{0}, {1}], valeurs : [{2}, {3}]" }, + + // org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl + // org.apache.commons.math.transform.FastFourierTransformer + { "endpoints do not specify an interval: [{0}, {1}]", + "les extr\u00e9mit\u00e9s ne constituent pas un intervalle : [{0}, {1}]" }, + + // org.apache.commons.math.analysis.solvers.LaguerreSolver { "function is not polynomial", "la fonction n''est pas p\u00f4lynomiale" }, - // org.apache.commons.math.analysis.NewtonSolver + // org.apache.commons.math.analysis.solvers.NewtonSolver { "function is not differentiable", "la fonction n''est pas diff\u00e9rentiable" }, @@ -304,8 +316,7 @@ public class MessagesResources_fr { "zero norm", "norme nulle" }, - // org.apache.commons.math.analysis.UnivariateRealIntegratorImpl - // org.apache.commons.math.analysis.UnivariateRealSolverImpl + // org.apache.commons.math.ConvergingAlgorithmImpl { "no result available", "aucun r\u00e9sultat n''est disponible" }, @@ -354,8 +365,6 @@ public class MessagesResources_fr "le nombre d''\u00e9chantillons n''est pas positif : {0}" }, { "{0} is not a power of 2, consider padding for fix", "{0} n''est pas une puissance de 2, ajoutez des \u00e9l\u00e9ments pour corriger" }, - { "endpoints do not specify an interval: [{0}, {1}]", - "les extr\u00e9mit\u00e9s ne constituent pas un intervalle : [{0}, {1}]" }, { "some dimensions don't math: {0} != {1}", "certaines dimensions sont incoh\u00e9rentes : {0} != {1}" }, diff --git a/src/java/org/apache/commons/math/analysis/solvers/BrentSolver.java b/src/java/org/apache/commons/math/analysis/solvers/BrentSolver.java index 3898f7645..df67e2a60 100644 --- a/src/java/org/apache/commons/math/analysis/solvers/BrentSolver.java +++ b/src/java/org/apache/commons/math/analysis/solvers/BrentSolver.java @@ -18,6 +18,7 @@ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.FunctionEvaluationException; +import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.analysis.UnivariateRealFunction; @@ -93,11 +94,8 @@ public class BrentSolver extends UnivariateRealSolverImpl { final double min, final double max, final double initial) throws MaxIterationsExceededException, FunctionEvaluationException { - if (((initial - min) * (max -initial)) < 0) { - throw new IllegalArgumentException("Initial guess is not in search" + - " interval." + " Initial: " + initial + - " Endpoints: [" + min + "," + max + "]"); - } + clearResult(); + verifySequence(min, initial, max); // return the initial guess if it is good enough double yInitial = f.value(initial); @@ -177,10 +175,10 @@ public class BrentSolver extends UnivariateRealSolverImpl { ret = max; } else { // neither value is close to zero and min and max do not bracket root. - throw new IllegalArgumentException - ("Function values at endpoints do not have different signs." + - " Endpoints: [" + min + "," + max + "]" + - " Values: [" + yMin + "," + yMax + "]"); + throw MathRuntimeException.createIllegalArgumentException( + "function values at endpoints do not have different signs. " + + "Endpoints: [{0}, {1}], Values: [{2}, {3}]", + new Object[] { min, max, yMin, yMax }); } } else if (sign < 0){ // solve using only the first endpoint as initial guess diff --git a/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java b/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java index b84c54865..f7936cd1d 100644 --- a/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java +++ b/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java @@ -17,6 +17,7 @@ package org.apache.commons.math.analysis.solvers; import org.apache.commons.math.ConvergenceException; +import org.apache.commons.math.ConvergingAlgorithm; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; @@ -28,96 +29,7 @@ import org.apache.commons.math.analysis.UnivariateRealFunction; * * @version $Revision: 724191 $ $Date: 2008-12-07 21:24:10 +0100 (Sun, 07 Dec 2008) $ */ -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.

- *

- * A ConvergenceException will be thrown if this number - * is exceeded.

- * - * @param count maximum number of iterations - */ - void setMaximalIterationCount(int count); - - /** - * Get the upper limit for the number of iterations. - * - * @return the actual upper limit - */ - 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) - */ - void resetMaximalIterationCount(); - - /** - * Set the absolute accuracy. - *

- * The default is usually choosen so that roots in the interval - * -10..-0.1 and +0.1..+10 can be found with 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 IllegalArgumentException if the accuracy can't be achieved by - * the solver or is otherwise deemed unreasonable. - */ - void setAbsoluteAccuracy(double accuracy); - - /** - * Get the actual absolute accuracy. - * - * @return the accuracy - */ - double getAbsoluteAccuracy(); - - /** - * Reset the absolute accuracy to the default. - *

- * The default value is provided by the solver implementation.

- */ - 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 criterion 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 IllegalArgumentException if the accuracy can't be achieved by - * the solver or is otherwise deemed unreasonable. - */ - void setRelativeAccuracy(double accuracy); - - /** - * Get the actual relative accuracy. - * @return the accuracy - */ - double getRelativeAccuracy(); - - /** - * Reset the relative accuracy to the default. - * The default value is provided by the solver implementation. - */ - void resetRelativeAccuracy(); +public interface UnivariateRealSolver extends ConvergingAlgorithm { /** * Set the function value accuracy. @@ -244,19 +156,4 @@ public interface UnivariateRealSolver { * because no result was yet computed or the last attempt failed. */ double getFunctionValue(); - - /** - * 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 IllegalStateException if there is no result available, either - * because no result was yet computed or the last attempt failed. - */ - int getIterationCount(); } \ No newline at end of file diff --git a/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java b/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java index 530b8e36b..4fffb5d3e 100644 --- a/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java +++ b/src/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java @@ -17,8 +17,7 @@ package org.apache.commons.math.analysis.solvers; -import java.io.Serializable; - +import org.apache.commons.math.ConvergingAlgorithmImpl; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.UnivariateRealFunction; @@ -29,36 +28,18 @@ import org.apache.commons.math.analysis.UnivariateRealFunction; * * @version $Revision: 724191 $ $Date: 2008-12-07 21:24:10 +0100 (Sun, 07 Dec 2008) $ */ -public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, - Serializable { +public abstract class UnivariateRealSolverImpl + extends ConvergingAlgorithmImpl implements UnivariateRealSolver { /** Serializable version identifier */ private static final long serialVersionUID = 1112491292565386596L; - /** Maximum absolute error. */ - protected double absoluteAccuracy; - - /** Maximum relative error. */ - protected double relativeAccuracy; - /** Maximum error of function. */ protected double functionValueAccuracy; - /** Maximum number of iterations. */ - protected int maximalIterationCount; - - /** Default maximum absolute error. */ - protected double defaultAbsoluteAccuracy; - - /** Default maximum relative error. */ - protected double defaultRelativeAccuracy; - /** Default maximum error of function. */ protected double defaultFunctionValueAccuracy; - /** Default maximum number of iterations. */ - protected int defaultMaximalIterationCount; - /** Indicates where a root has been computed. */ protected boolean resultComputed = false; @@ -68,10 +49,6 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, /** Value of the function at the last computed result. */ protected double functionValue; - // Mainly for test framework. - /** The last iteration count. */ - protected int iterationCount; - /** The function to solve. * @deprecated as of 2.0 the function to solve is passed as an argument * to the {@link #solve(UnivariateRealFunction, double, double)} or @@ -94,25 +71,17 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * method. */ @Deprecated - protected UnivariateRealSolverImpl( - UnivariateRealFunction f, - int defaultMaximalIterationCount, - double defaultAbsoluteAccuracy) { - + protected UnivariateRealSolverImpl(final UnivariateRealFunction f, + final int defaultMaximalIterationCount, + final double defaultAbsoluteAccuracy) { + super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); if (f == null) { throw MathRuntimeException.createIllegalArgumentException("function to solve cannot be null", null); } this.f = f; - - this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy; - this.defaultRelativeAccuracy = 1E-14; - this.defaultFunctionValueAccuracy = 1E-15; - this.absoluteAccuracy = defaultAbsoluteAccuracy; - this.relativeAccuracy = defaultRelativeAccuracy; + this.defaultFunctionValueAccuracy = 1.0e-15; this.functionValueAccuracy = defaultFunctionValueAccuracy; - this.defaultMaximalIterationCount = defaultMaximalIterationCount; - this.maximalIterationCount = defaultMaximalIterationCount; } /** @@ -123,59 +92,47 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @throws IllegalArgumentException if f is null or the * defaultAbsoluteAccuracy is not valid */ - protected UnivariateRealSolverImpl(int defaultMaximalIterationCount, - double defaultAbsoluteAccuracy) { - this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy; - this.defaultRelativeAccuracy = 1E-14; - this.defaultFunctionValueAccuracy = 1E-15; - this.absoluteAccuracy = defaultAbsoluteAccuracy; - this.relativeAccuracy = defaultRelativeAccuracy; + protected UnivariateRealSolverImpl(final int defaultMaximalIterationCount, + final double defaultAbsoluteAccuracy) { + super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); + this.defaultFunctionValueAccuracy = 1.0e-15; this.functionValueAccuracy = defaultFunctionValueAccuracy; - this.defaultMaximalIterationCount = defaultMaximalIterationCount; - this.maximalIterationCount = defaultMaximalIterationCount; } - /** - * Access the last computed root. - * - * @return the last computed root - * @throws IllegalStateException if no root has been computed + /** Check if a result has been computed. + * @exception IllegalStateException if no result has been computed */ + protected void checkResultComputed() throws IllegalArgumentException { + if (!resultComputed) { + throw MathRuntimeException.createIllegalStateException("no result available", null); + } + } + + /** {@inheritDoc} */ public double getResult() { - if (resultComputed) { - return result; - } else { - throw MathRuntimeException.createIllegalStateException("no result available", null); - } + checkResultComputed(); + return result; } - /** - * Access the value of the function at the last computed result. - * - * @return the function value at the last result. - * @throws IllegalStateException if no value has been computed. - */ + /** {@inheritDoc} */ public double getFunctionValue() { - if (resultComputed) { - return functionValue; - } else { - throw MathRuntimeException.createIllegalStateException("no result available", null); - } + checkResultComputed(); + return functionValue; } - /** - * Access the last iteration count. - * - * @return the last iteration count - * @throws IllegalStateException if no root has been computed - * - */ - public int getIterationCount() { - if (resultComputed) { - return iterationCount; - } else { - throw MathRuntimeException.createIllegalStateException("no result available", null); - } + /** {@inheritDoc} */ + public void setFunctionValueAccuracy(final double accuracy) { + functionValueAccuracy = accuracy; + } + + /** {@inheritDoc} */ + public double getFunctionValueAccuracy() { + return functionValueAccuracy; + } + + /** {@inheritDoc} */ + public void resetFunctionValueAccuracy() { + functionValueAccuracy = defaultFunctionValueAccuracy; } /** @@ -184,8 +141,8 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @param result the result to set * @param iterationCount the iteration count to set */ - protected final void setResult(double result, int iterationCount) { - this.result = result; + protected final void setResult(final double result, final int iterationCount) { + this.result = result; this.iterationCount = iterationCount; this.resultComputed = true; } @@ -197,9 +154,10 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @param fx the result to set * @param iterationCount the iteration count to set */ - protected final void setResult(double x, double fx, int iterationCount) { - this.result = x; - this.functionValue = fx; + protected final void setResult(final double x, final double fx, + final int iterationCount) { + this.result = x; + this.functionValue = fx; this.iterationCount = iterationCount; this.resultComputed = true; } @@ -208,114 +166,10 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * Convenience function for implementations. */ protected final void clearResult() { + this.iterationCount = 0; this.resultComputed = false; } - /** - * Set the absolute accuracy. - * - * @param accuracy the accuracy. - * @throws IllegalArgumentException if the accuracy can't be achieved by - * the solver or is otherwise deemed unreasonable. - */ - public void setAbsoluteAccuracy(double accuracy) { - absoluteAccuracy = accuracy; - } - - /** - * Get the actual absolute accuracy. - * - * @return the accuracy - */ - public double getAbsoluteAccuracy() { - return absoluteAccuracy; - } - - /** - * Reset the absolute accuracy to the default. - */ - public void resetAbsoluteAccuracy() { - absoluteAccuracy = defaultAbsoluteAccuracy; - } - - /** - * Set the upper limit for the number of iterations. - * - * @param count maximum number of iterations - */ - public void setMaximalIterationCount(int count) { - maximalIterationCount = count; - } - - /** - * Get the upper limit for the number of iterations. - * - * @return the actual upper limit - */ - public int getMaximalIterationCount() { - return maximalIterationCount; - } - - /** - * Reset the upper limit for the number of iterations to the default. - */ - public void resetMaximalIterationCount() { - maximalIterationCount = defaultMaximalIterationCount; - } - - /** - * Set the relative accuracy. - * - * @param accuracy the relative accuracy. - * @throws IllegalArgumentException if the accuracy can't be achieved by - * the solver or is otherwise deemed unreasonable. - */ - public void setRelativeAccuracy(double accuracy) { - relativeAccuracy = accuracy; - } - - /** - * Get the actual relative accuracy. - * @return the accuracy - */ - public double getRelativeAccuracy() { - return relativeAccuracy; - } - - /** - * Reset the relative accuracy to the default. - */ - public void resetRelativeAccuracy() { - relativeAccuracy = defaultRelativeAccuracy; - } - - /** - * Set the function value accuracy. - * - * @param accuracy the accuracy. - * @throws IllegalArgumentException if the accuracy can't be achieved by - * the solver or is otherwise deemed unreasonable. - */ - public void setFunctionValueAccuracy(double accuracy) { - functionValueAccuracy = accuracy; - } - - /** - * Get the actual function value accuracy. - * @return the accuracy - */ - public double getFunctionValueAccuracy() { - return functionValueAccuracy; - } - - /** - * Reset the actual function accuracy to the default. - */ - public void resetFunctionValueAccuracy() { - functionValueAccuracy = defaultFunctionValueAccuracy; - } - - /** * Returns true iff the function takes opposite signs at the endpoints. * @@ -326,10 +180,11 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @throws FunctionEvaluationException if an error occurs evaluating the * function at the endpoints */ - protected boolean isBracketing(double lower, double upper, - UnivariateRealFunction f) throws FunctionEvaluationException { - double f1 = f.value(lower); - double f2 = f.value(upper); + protected boolean isBracketing(final double lower, final double upper, + final UnivariateRealFunction f) + throws FunctionEvaluationException { + final double f1 = f.value(lower); + final double f2 = f.value(upper); return ((f1 > 0 && f2 < 0) || (f1 < 0 && f2 > 0)); } @@ -341,7 +196,7 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @param end third number * @return true if the arguments form an increasing sequence */ - protected boolean isSequence(double start, double mid, double end) { + protected boolean isSequence(final double start, final double mid, final double end) { return (start < mid) && (mid < end); } @@ -353,11 +208,11 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @param upper upper endpoint * @throws IllegalArgumentException */ - protected void verifyInterval(double lower, double upper) { + protected void verifyInterval(final double lower, final double upper) { if (lower >= upper) { - throw new IllegalArgumentException - ("Endpoints do not specify an interval: [" + lower + - "," + upper + "]"); + throw MathRuntimeException.createIllegalArgumentException( + "endpoints do not specify an interval: [{0}, {1}]", + new Object[] { lower, upper }); } } @@ -370,11 +225,11 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @param upper upper endpoint * @throws IllegalArgumentException */ - protected void verifySequence(double lower, double initial, double upper) { + protected void verifySequence(final double lower, final double initial, final double upper) { if (!isSequence(lower, initial, upper)) { - throw new IllegalArgumentException - ("Invalid interval, initial value parameters: lower=" + - lower + " initial=" + initial + " upper=" + upper); + throw MathRuntimeException.createIllegalArgumentException( + "invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}", + new Object[] { lower, initial, upper }); } } @@ -389,15 +244,16 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver, * @throws FunctionEvaluationException if an error occurs evaluating the * function at the endpoints */ - protected void verifyBracketing(double lower, double upper, - UnivariateRealFunction f) throws FunctionEvaluationException { + protected void verifyBracketing(final double lower, final double upper, + final UnivariateRealFunction f) + throws FunctionEvaluationException { verifyInterval(lower, upper); if (!isBracketing(lower, upper, f)) { - throw new IllegalArgumentException - ("Function values at endpoints do not have different signs." + - " Endpoints: [" + lower + "," + upper + "]" + - " Values: [" + f.value(lower) + "," + f.value(upper) + "]"); + throw MathRuntimeException.createIllegalArgumentException( + "function values at endpoints do not have different signs. " + + "Endpoints: [{0}, {1}], Values: [{2}, {3}]", + new Object[] { lower, upper, f.value(lower), f.value(upper) }); } } }