blob: 557c7670ac33bfb753f7a29cda925cde475bcfc7 [file] [log] [blame]
/*
* 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));
}
}
}