1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.analysis.solvers;
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ConvergingAlgorithmImpl;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.FunctionEvaluationException;
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException;
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.analysis.UnivariateRealFunction;
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats;
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ConvergenceException;
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.NullArgumentException;
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/**
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Provide a default implementation for several functions useful to generic
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * solvers.
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @deprecated in 2.2 (to be removed in 3.0).
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond@Deprecated
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic abstract class UnivariateRealSolverImpl
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    extends ConvergingAlgorithmImpl implements UnivariateRealSolver {
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Maximum error of function. */
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double functionValueAccuracy;
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Default maximum error of function. */
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double defaultFunctionValueAccuracy;
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Indicates where a root has been computed. */
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected boolean resultComputed = false;
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** The last computed root. */
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double result;
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Value of the function at the last computed result. */
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double functionValue;
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** The function to solve.
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated as of 2.0 the function to solve is passed as an argument
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * to the {@link #solve(UnivariateRealFunction, double, double)} or
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * method. */
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected UnivariateRealFunction f;
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a solver with given iteration count and accuracy.
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param f the function to solve.
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param defaultAbsoluteAccuracy maximum absolute error
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param defaultMaximalIterationCount maximum number of iterations
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if f is null or the
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * defaultAbsoluteAccuracy is not valid
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated as of 2.0 the function to solve is passed as an argument
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * to the {@link #solve(UnivariateRealFunction, double, double)} or
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * method.
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected UnivariateRealSolverImpl(final UnivariateRealFunction f,
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                       final int defaultMaximalIterationCount,
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                       final double defaultAbsoluteAccuracy) {
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        super(defaultMaximalIterationCount, defaultAbsoluteAccuracy);
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (f == null) {
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw new NullArgumentException(LocalizedFormats.FUNCTION);
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.f = f;
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.defaultFunctionValueAccuracy = 1.0e-15;
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.functionValueAccuracy = defaultFunctionValueAccuracy;
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a solver with given iteration count and accuracy.
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param defaultAbsoluteAccuracy maximum absolute error
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param defaultMaximalIterationCount maximum number of iterations
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if f is null or the
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * defaultAbsoluteAccuracy is not valid
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected UnivariateRealSolverImpl(final int defaultMaximalIterationCount,
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                       final double defaultAbsoluteAccuracy) {
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        super(defaultMaximalIterationCount, defaultAbsoluteAccuracy);
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.defaultFunctionValueAccuracy = 1.0e-15;
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.functionValueAccuracy = defaultFunctionValueAccuracy;
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Check if a result has been computed.
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalStateException if no result has been computed
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected void checkResultComputed() throws IllegalStateException {
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (!resultComputed) {
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE);
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getResult() {
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkResultComputed();
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return result;
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getFunctionValue() {
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkResultComputed();
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return functionValue;
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setFunctionValueAccuracy(final double accuracy) {
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        functionValueAccuracy = accuracy;
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getFunctionValueAccuracy() {
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return functionValueAccuracy;
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void resetFunctionValueAccuracy() {
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        functionValueAccuracy = defaultFunctionValueAccuracy;
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Solve for a zero root in the given interval.
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>A solver may require that the interval brackets a single zero root.
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Solvers that do require bracketing should be able to handle the case
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * where one of the endpoints is itself a root.</p>
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param function the function to solve.
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param min the lower bound for the interval.
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param max the upper bound for the interval.
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param maxEval Maximum number of evaluations.
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a value where the function is zero
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws ConvergenceException if the maximum iteration count is exceeded
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * or the solver detects convergence problems otherwise.
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws FunctionEvaluationException if an error occurs evaluating the function
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if min > max or the endpoints do not
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * satisfy the requirements specified by the solver
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.2
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double solve(int maxEval, UnivariateRealFunction function, double min, double max)
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws ConvergenceException, FunctionEvaluationException {
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN);
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Solve for a zero in the given interval, start at startValue.
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>A solver may require that the interval brackets a single zero root.
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Solvers that do require bracketing should be able to handle the case
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * where one of the endpoints is itself a root.</p>
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param function the function to solve.
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param min the lower bound for the interval.
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param max the upper bound for the interval.
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param startValue the start value to use
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param maxEval Maximum number of evaluations.
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a value where the function is zero
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws ConvergenceException if the maximum iteration count is exceeded
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * or the solver detects convergence problems otherwise.
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws FunctionEvaluationException if an error occurs evaluating the function
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if min > max or the arguments do not
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * satisfy the requirements specified by the solver
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.2
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double solve(int maxEval, UnivariateRealFunction function, double min, double max, double startValue)
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException {
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN);
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Convenience function for implementations.
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param newResult the result to set
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param iterationCount the iteration count to set
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected final void setResult(final double newResult, final int iterationCount) {
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.result         = newResult;
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.iterationCount = iterationCount;
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.resultComputed = true;
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Convenience function for implementations.
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x the result to set
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param fx the result to set
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param iterationCount the iteration count to set
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected final void setResult(final double x, final double fx,
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                   final int iterationCount) {
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.result         = x;
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.functionValue  = fx;
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.iterationCount = iterationCount;
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.resultComputed = true;
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Convenience function for implementations.
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected final void clearResult() {
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.iterationCount = 0;
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.resultComputed = false;
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns true iff the function takes opposite signs at the endpoints.
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param lower  the lower endpoint
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param upper  the upper endpoint
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param function the function
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return true if f(lower) * f(upper) < 0
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected boolean isBracketing(final double lower, final double upper,
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                   final UnivariateRealFunction function)
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws FunctionEvaluationException {
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final double f1 = function.value(lower);
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final double f2 = function.value(upper);
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (f1 > 0 && f2 < 0) || (f1 < 0 && f2 > 0);
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns true if the arguments form a (strictly) increasing sequence
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param start  first number
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param mid   second number
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param end  third number
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return true if the arguments form an increasing sequence
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected boolean isSequence(final double start, final double mid, final double end) {
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (start < mid) && (mid < end);
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Verifies that the endpoints specify an interval,
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * throws IllegalArgumentException if not
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param lower  lower endpoint
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param upper upper endpoint
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected void verifyInterval(final double lower, final double upper) {
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (lower >= upper) {
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    lower, upper);
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Verifies that <code>lower < initial < upper</code>
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * throws IllegalArgumentException if not
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param lower  lower endpoint
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param initial initial value
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param upper upper endpoint
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected void verifySequence(final double lower, final double initial, final double upper) {
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (!isSequence(lower, initial, upper)) {
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    LocalizedFormats.INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS,
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    lower, initial, upper);
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Verifies that the endpoints specify an interval and the function takes
285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * opposite signs at the endpoints, throws IllegalArgumentException if not
286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param lower  lower endpoint
288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param upper upper endpoint
289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param function function
290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException
291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints
292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected void verifyBracketing(final double lower, final double upper,
294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                    final UnivariateRealFunction function)
295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws FunctionEvaluationException {
296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        verifyInterval(lower, upper);
298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (!isBracketing(lower, upper, function)) {
299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    LocalizedFormats.SAME_SIGN_AT_ENDPOINTS,
301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    lower, upper, function.value(lower), function.value(upper));
302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
305