View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math.analysis;
18  
19  import org.apache.commons.math.ConvergenceException;
20  import org.apache.commons.math.FunctionEvaluationException;
21  
22  
23  /**
24   * Interface for (univariate real) rootfinding algorithms.
25   * <p>
26   * Implementations will search for only one zero in the given interval.</p>
27   *  
28   * @version $Revision: 615734 $ $Date: 2008-01-27 23:10:03 -0700 (Sun, 27 Jan 2008) $
29   */
30  public interface UnivariateRealSolver {
31  
32      /**
33       * Set the upper limit for the number of iterations.
34       * <p>
35       * Usually a high iteration count indicates convergence problems. However,
36       * the "reasonable value" varies widely for different solvers.  Users are
37       * advised to use the default value supplied by the solver.</p>
38       * <p>
39       * A <code>ConvergenceException</code> will be thrown if this number
40       * is exceeded.</p>
41       *  
42       * @param count maximum number of iterations
43       */
44      void setMaximalIterationCount(int count);
45  
46      /**
47       * Get the upper limit for the number of iterations.
48       * 
49       * @return the actual upper limit
50       */
51      int getMaximalIterationCount();
52  
53      /**
54       * Reset the upper limit for the number of iterations to the default.
55       * <p>
56       * The default value is supplied by the solver implementation.</p>
57       * 
58       * @see #setMaximalIterationCount(int)
59       */
60      void resetMaximalIterationCount();
61  
62      /**
63       * Set the absolute accuracy.
64       * <p>
65       * The default is usually choosen so that roots in the interval
66       * -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the
67       * expected absolute value of your roots is of much smaller magnitude, set
68       * this to a smaller value.</p>
69       * <p>
70       * Solvers are advised to do a plausibility check with the relative
71       * accuracy, but clients should not rely on this.</p>
72       *  
73       * @param accuracy the accuracy.
74       * @throws IllegalArgumentException if the accuracy can't be achieved by
75       * the solver or is otherwise deemed unreasonable. 
76       */
77      void setAbsoluteAccuracy(double accuracy);
78  
79      /**
80       * Get the actual absolute accuracy.
81       * 
82       * @return the accuracy
83       */
84      double getAbsoluteAccuracy();
85  
86      /**
87       * Reset the absolute accuracy to the default.
88       * <p>
89       * The default value is provided by the solver implementation.</p>
90       */
91      void resetAbsoluteAccuracy();
92  
93      /**
94       * Set the relative accuracy.
95       * <p>
96       * This is used to stop iterations if the absolute accuracy can't be
97       * achieved due to large values or short mantissa length.</p>
98       * <p>
99       * If this should be the primary criterion for convergence rather then a
100      * safety measure, set the absolute accuracy to a ridiculously small value,
101      * like 1E-1000.</p>
102      * 
103      * @param accuracy the relative accuracy.
104      * @throws IllegalArgumentException if the accuracy can't be achieved by
105      *  the solver or is otherwise deemed unreasonable. 
106      */
107     void setRelativeAccuracy(double accuracy);
108 
109     /**
110      * Get the actual relative accuracy.
111      * @return the accuracy
112      */
113     double getRelativeAccuracy();
114 
115     /**
116      * Reset the relative accuracy to the default.
117      * The default value is provided by the solver implementation.
118      */
119     void resetRelativeAccuracy();
120 
121     /**
122      * Set the function value accuracy.
123      * <p>
124      * This is used to determine when an evaluated function value or some other
125      * value which is used as divisor is zero.</p>
126      * <p>
127      * This is a safety guard and it shouldn't be necessary to change this in
128      * general.</p>
129      * 
130      * @param accuracy the accuracy.
131      * @throws IllegalArgumentException if the accuracy can't be achieved by
132      * the solver or is otherwise deemed unreasonable. 
133      */
134     void setFunctionValueAccuracy(double accuracy);
135 
136     /**
137      * Get the actual function value accuracy.
138      * @return the accuracy
139      */
140     double getFunctionValueAccuracy();
141 
142     /**
143      * Reset the actual function accuracy to the default.
144      * The default value is provided by the solver implementation.
145      */
146     void resetFunctionValueAccuracy();
147 
148     /**
149      * Solve for a zero root in the given interval.
150      * A solver may require that the interval brackets a single zero root.
151      * 
152      * @param min the lower bound for the interval.
153      * @param max the upper bound for the interval.
154      * @return a value where the function is zero
155      * @throws ConvergenceException if the maximum iteration count is exceeded
156      * or the solver detects convergence problems otherwise.
157      * @throws FunctionEvaluationException if an error occurs evaluating the
158      * function
159      * @throws IllegalArgumentException if min > max or the endpoints do not
160      * satisfy the requirements specified by the solver
161      */
162     double solve(double min, double max) throws ConvergenceException, 
163         FunctionEvaluationException;
164 
165     /**
166      * Solve for a zero in the given interval, start at startValue.
167      * A solver may require that the interval brackets a single zero root.
168      * 
169      * @param min the lower bound for the interval.
170      * @param max the upper bound for the interval.
171      * @param startValue the start value to use
172      * @return a value where the function is zero
173      * @throws ConvergenceException if the maximum iteration count is exceeded
174      * or the solver detects convergence problems otherwise.
175      * @throws FunctionEvaluationException if an error occurs evaluating the
176      * function
177      * @throws IllegalArgumentException if min > max or the arguments do not
178      * satisfy the requirements specified by the solver
179      */
180     double solve(double min, double max, double startValue)
181         throws ConvergenceException, FunctionEvaluationException;
182 
183     /**
184      * Get the result of the last run of the solver.
185      * 
186      * @return the last result.
187      * @throws IllegalStateException if there is no result available, either
188      * because no result was yet computed or the last attempt failed.
189      */
190     double getResult();
191 
192     /**
193      * Get the number of iterations in the last run of the solver.
194      * <p>
195      * This is mainly meant for testing purposes. It may occasionally
196      * help track down performance problems: if the iteration count
197      * is notoriously high, check whether the function is evaluated
198      * properly, and whether another solver is more amenable to the
199      * problem.</p>
200      * 
201      * @return the last iteration count.
202      * @throws IllegalStateException if there is no result available, either
203      * because no result was yet computed or the last attempt failed.
204      */
205     int getIterationCount();
206 }