diff options
Diffstat (limited to 'src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java')
-rw-r--r-- | src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java new file mode 100644 index 0000000..557c767 --- /dev/null +++ b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java @@ -0,0 +1,304 @@ +/* + * 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.ConvergingAlgorithmImpl; +import org.apache.commons.math.FunctionEvaluationException; +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.ConvergenceException; +import org.apache.commons.math.exception.NullArgumentException; + +/** + * Provide a default implementation for several functions useful to generic + * solvers. + * + * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ + * @deprecated in 2.2 (to be removed in 3.0). + */ +@Deprecated +public abstract class UnivariateRealSolverImpl + extends ConvergingAlgorithmImpl implements UnivariateRealSolver { + + /** Maximum error of function. */ + protected double functionValueAccuracy; + + /** Default maximum error of function. */ + protected double defaultFunctionValueAccuracy; + + /** Indicates where a root has been computed. */ + protected boolean resultComputed = false; + + /** The last computed root. */ + protected double result; + + /** Value of the function at the last computed result. */ + protected double functionValue; + + /** 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 + * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} + * method. */ + @Deprecated + protected UnivariateRealFunction f; + + /** + * Construct a solver with given iteration count and accuracy. + * + * @param f the function to solve. + * @param defaultAbsoluteAccuracy maximum absolute error + * @param defaultMaximalIterationCount maximum number of iterations + * @throws IllegalArgumentException if f is null or the + * defaultAbsoluteAccuracy is not valid + * @deprecated as of 2.0 the function to solve is passed as an argument + * to the {@link #solve(UnivariateRealFunction, double, double)} or + * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} + * method. + */ + @Deprecated + protected UnivariateRealSolverImpl(final UnivariateRealFunction f, + final int defaultMaximalIterationCount, + final double defaultAbsoluteAccuracy) { + super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); + if (f == null) { + throw new NullArgumentException(LocalizedFormats.FUNCTION); + } + this.f = f; + this.defaultFunctionValueAccuracy = 1.0e-15; + this.functionValueAccuracy = defaultFunctionValueAccuracy; + } + + /** + * Construct a solver 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 UnivariateRealSolverImpl(final int defaultMaximalIterationCount, + final double defaultAbsoluteAccuracy) { + super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); + this.defaultFunctionValueAccuracy = 1.0e-15; + this.functionValueAccuracy = defaultFunctionValueAccuracy; + } + + /** Check if a result has been computed. + * @exception IllegalStateException if no result has been computed + */ + protected void checkResultComputed() throws IllegalStateException { + if (!resultComputed) { + throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE); + } + } + + /** {@inheritDoc} */ + public double getResult() { + checkResultComputed(); + return result; + } + + /** {@inheritDoc} */ + public double getFunctionValue() { + checkResultComputed(); + return functionValue; + } + + /** {@inheritDoc} */ + public void setFunctionValueAccuracy(final double accuracy) { + functionValueAccuracy = accuracy; + } + + /** {@inheritDoc} */ + public double getFunctionValueAccuracy() { + return functionValueAccuracy; + } + + /** {@inheritDoc} */ + public void resetFunctionValueAccuracy() { + functionValueAccuracy = defaultFunctionValueAccuracy; + } + + /** + * 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 function the function to solve. + * @param min the lower bound for the interval. + * @param max the upper bound for the interval. + * @param maxEval Maximum number of evaluations. + * @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 FunctionEvaluationException 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.2 + */ + public double solve(int maxEval, UnivariateRealFunction function, double min, double max) + throws ConvergenceException, FunctionEvaluationException { + throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN); + } + + /** + * 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 function 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 + * @param maxEval Maximum number of evaluations. + * @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 FunctionEvaluationException 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.2 + */ + public double solve(int maxEval, UnivariateRealFunction function, double min, double max, double startValue) + throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException { + throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN); + } + + /** + * Convenience function for implementations. + * + * @param newResult the result to set + * @param iterationCount the iteration count to set + */ + protected final void setResult(final double newResult, final int iterationCount) { + this.result = newResult; + this.iterationCount = iterationCount; + this.resultComputed = true; + } + + /** + * Convenience function for implementations. + * + * @param x the result to set + * @param fx the result to set + * @param iterationCount the iteration count to set + */ + 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; + } + + /** + * Convenience function for implementations. + */ + protected final void clearResult() { + this.iterationCount = 0; + this.resultComputed = false; + } + + /** + * Returns true iff the function takes opposite signs at the endpoints. + * + * @param lower the lower endpoint + * @param upper the upper endpoint + * @param function the function + * @return true if f(lower) * f(upper) < 0 + * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints + */ + protected boolean isBracketing(final double lower, final double upper, + final UnivariateRealFunction function) + throws FunctionEvaluationException { + final double f1 = function.value(lower); + final double f2 = function.value(upper); + return (f1 > 0 && f2 < 0) || (f1 < 0 && f2 > 0); + } + + /** + * Returns true if the arguments form a (strictly) increasing sequence + * + * @param start first number + * @param mid second number + * @param end third number + * @return true if the arguments form an increasing sequence + */ + protected boolean isSequence(final double start, final double mid, final double end) { + return (start < mid) && (mid < end); + } + + /** + * Verifies that the endpoints specify an interval, + * throws IllegalArgumentException if not + * + * @param lower lower endpoint + * @param upper upper endpoint + * @throws IllegalArgumentException + */ + protected void verifyInterval(final double lower, final double upper) { + if (lower >= upper) { + throw MathRuntimeException.createIllegalArgumentException( + LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL, + lower, upper); + } + } + + /** + * Verifies that <code>lower < initial < upper</code> + * throws IllegalArgumentException if not + * + * @param lower lower endpoint + * @param initial initial value + * @param upper upper endpoint + * @throws IllegalArgumentException + */ + protected void verifySequence(final double lower, final double initial, final double upper) { + if (!isSequence(lower, initial, upper)) { + throw MathRuntimeException.createIllegalArgumentException( + LocalizedFormats.INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS, + lower, initial, upper); + } + } + + /** + * Verifies that the endpoints specify an interval and the function takes + * opposite signs at the endpoints, throws IllegalArgumentException if not + * + * @param lower lower endpoint + * @param upper upper endpoint + * @param function function + * @throws IllegalArgumentException + * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints + */ + protected void verifyBracketing(final double lower, final double upper, + final UnivariateRealFunction function) + throws FunctionEvaluationException { + + verifyInterval(lower, upper); + if (!isBracketing(lower, upper, function)) { + throw MathRuntimeException.createIllegalArgumentException( + LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, + lower, upper, function.value(lower), function.value(upper)); + } + } +} |