| <?xml version="1.0"?> |
| |
| <!-- |
| Copyright 2003-2005 The Apache Software Foundation |
| |
| Licensed 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. |
| --> |
| |
| <?xml-stylesheet type="text/xsl" href="./xdoc.xsl"?> |
| <!-- $Revision$ $Date$ --> |
| <document url="analysis.html"> |
| <properties> |
| <title>The Commons Math User Guide - Numerical Analysis</title> |
| </properties> |
| <body> |
| <section name="4 Numerical Analysis"> |
| <subsection name="4.1 Overview" href="overview"> |
| <p> |
| The analysis package provides numerical root-finding and interpolation |
| implementations for real-valued functions of one real variable. |
| </p> |
| <p> |
| Possible future additions may include numerical differentation, |
| integration and optimization. |
| </p> |
| </subsection> |
| <subsection name="4.2 Root-finding" href="rootfinding"> |
| <p> |
| A <a href="../apidocs/org/apache/commons/math/analysis/UnivariateRealSolver.html"> |
| org.apache.commons.math.analysis.UnivariateRealSolver.</a> |
| provides the means to find roots of univariate real-valued functions. |
| A root is the value where the function takes the value 0. Commons-Math |
| includes implementations of the following root-finding algorithms: <ul> |
| <li><a href="../apidocs/org/apache/commons/math/analysis/BisectionSolver.html"> |
| Bisection</a></li> |
| <li><a href="../apidocs/org/apache/commons/math/analysis/BrentSolver.html"> |
| Brent-Dekker</a></li> |
| <li><a href="../apidocs/org/apache/commons/math/analysis/NewtonSolver.html"> |
| Newton's Method</a></li> |
| <li><a href="../apidocs/org/apache/commons/math/analysis/SecantSolver.html"> |
| Secant Method</a></li> |
| </ul> |
| </p> |
| <p> |
| There are numerous non-obvious traps and pitfalls in root finding. |
| First, the usual disclaimers due to the way real world computers |
| calculate values apply. If the computation of the function provides |
| numerical instabilities, for example due to bit cancellation, the root |
| finding algorithms may behave badly and fail to converge or even |
| return bogus values. There will not necessarily be an indication that |
| the computed root is way off the true value. Secondly, the root finding |
| problem itself may be inherently ill-conditioned. There is a |
| "domain of indeterminacy", the interval for which the function has |
| near zero absolute values around the true root, which may be large. |
| Even worse, small problems like roundoff error may cause the function |
| value to "numerically oscillate" between negative and positive values. |
| This may again result in roots way off the true value, without |
| indication. There is not much a generic algorithm can do if |
| ill-conditioned problems are met. A way around this is to transform |
| the problem in order to get a better conditioned function. Proper |
| selection of a root-finding algorithm and its configuration parameters |
| requires knowledge of the analytical properties of the function under |
| analysis and numerical analysis techniques. Users are encouraged |
| to consult a numerical analysis text (or a numerical analyst) when |
| selecting and configuring a solver. |
| </p> |
| <p> |
| In order to use the root-finding features, first a solver object must |
| be created. It is encouraged that all solver object creation occurs |
| via the <code>org.apache.commons.math.analysis.UnivariateRealSolverFactory</code> |
| class. <code>UnivariateRealSolverFactory</code> is a simple factory |
| used to create all of the solver objects supported by Commons-Math. |
| The typical usage of <code>UnivariateRealSolverFactory</code> |
| to create a solver object would be:</p> |
| <source>UnivariateRealFunction function = // some user defined function object |
| UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance(); |
| UnivariateRealSolver solver = factory.newDefaultSolver(function);</source> |
| <p> |
| The solvers that can be instantiated via the |
| <code>UnivariateRealSolverFactory</code> are detailed below: |
| <table> |
| <tr><th>Solver</th><th>Factory Method</th><th>Notes on Use</th></tr> |
| <tr><td>Bisection</td><td>newBisectionSolver</td><td><div>Root must be bracketted.</div><div>Linear, guaranteed convergence</div></td></tr> |
| <tr><td>Brent</td><td>newBrentSolver</td><td><div>Root must be bracketted.</div><div>Super-linear, guaranteed convergence</div></td></tr> |
| <tr><td>Newton</td><td>newNewtonSolver</td><td><div>Uses single value for initialization.</div><div>Super-linear, non-guaranteed convergence</div><div>Function must be differentiable</div></td></tr> |
| <tr><td>Secant</td><td>newSecantSolver</td><td><div>Root must be bracketted.</div><div>Super-linear, non-guaranteed convergence</div></td></tr> |
| </table> |
| </p> |
| <p> |
| Using a solver object, roots of functions are easily found using the <code>solve</code> |
| methods. For a function <code>f</code>, and two domain values, <code>min</code> and |
| <code>max</code>, <code>solve</code> computes a value <code>c</code> such that: |
| <ul> |
| <li><code>f(c) = 0.0</code> (see "function value accuracy")</li> |
| <li><code>min <= c <= max</code></li> |
| </ul> |
| </p> |
| <p> |
| Typical usage: |
| </p> |
| <source>UnivariateRealFunction function = // some user defined function object |
| UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance(); |
| UnivariateRealSolver solver = factory.newBisectionSolver(function); |
| double c = solver.solve(1.0, 5.0);</source> |
| <p> |
| The <code>BrentSolve</code> uses the Brent-Dekker algorithm which is |
| fast and robust. This algorithm is recommended for most users and the |
| <code>BrentSolver</code> is the default solver provided by the |
| <code>UnivariateRealSolverFactory</code>. If there are multiple roots |
| in the interval, or there is a large domain of indeterminacy, the |
| algorithm will converge to a random root in the interval without |
| indication that there are problems. Interestingly, the examined text |
| book implementations all disagree in details of the convergence |
| criteria. Also each implementation had problems for one of the test |
| cases, so the expressions had to be fudged further. Don't expect to |
| get exactly the same root values as for other implementations of this |
| algorithm. |
| </p> |
| <p> |
| The <code>SecantSolver</code> uses a variant of the well known secant |
| algorithm. It may be a bit faster than the Brent solver for a class |
| of well-behaved functions. |
| </p> |
| <p> |
| The <code>BisectionSolver</code> is included for completeness and for |
| establishing a fall back in cases of emergency. The algorithm is |
| simple, most likely bug free and guaranteed to converge even in very |
| adverse circumstances which might cause other algorithms to |
| malfunction. The drawback is of course that it is also guaranteed |
| to be slow. |
| </p> |
| <p> |
| The <code>UnivariateRealSolver</code> interface exposes many |
| properties to control the convergence of a solver. For the most part, |
| these properties should not have to change from their default values |
| to produce good results. In the circumstances where changing these |
| property values is needed, it is easily done through getter and setter |
| methods on <code>UnivariateRealSolver</code>: |
| <table> |
| <tr><th>Property</th><th>Methods</th><th>Purpose</th></tr> |
| <tr> |
| <td>Absolute accuracy</td> |
| <td> |
| <div>getAbsoluteAccuracy</div> |
| <div>resetAbsoluteAccuracy</div> |
| <div>setAbsoluteAccuracy</div> |
| </td> |
| <td> |
| The Absolute Accuracy is (estimated) maximal difference between |
| the computed root and the true root of the function. This is |
| what most people think of as "accuracy" intuitively. The default |
| value is choosen as a sane value for most real world problems, |
| for roots in the range from -100 to +100. For accurate |
| computation of roots near zero, in the range form -0.0001 to |
| +0.0001, the value may be decreased. For computing roots |
| much larger in absolute value than 100, the default absolute |
| accuracy may never be reached because the given relative |
| accuracy is reached first. |
| </td> |
| </tr> |
| <tr> |
| <td>Relative accuracy</td> |
| <td> |
| <div>getRelativeAccuracy</div> |
| <div>resetRelativeAccuracy</div> |
| <div>setRelativeAccuracy</div> |
| </td> |
| <td> |
| The Relative Accuracy is the maximal difference between the |
| computed root and the true root, divided by the maximum of the |
| absolute values of the numbers. This accuracy measurement is |
| better suited for numerical calculations with computers, due to |
| the way floating point numbers are represented. The default |
| value is choosen so that algorithms will get a result even for |
| roots with large absolute values, even while it may be |
| impossible to reach the given absolute accuracy. |
| </td> |
| </tr> |
| <tr> |
| <td>Function value accuracy</td> |
| <td> |
| <div>getFunctionValueAccuracy</div> |
| <div>resetFunctionValueAccuracy</div> |
| <div>setFunctionValueAccuracy</div> |
| </td> |
| <td> |
| This value is used by some algorithms in order to prevent |
| numerical instabilities. If the function is evaluated to an |
| absolute value smaller than the Function Value Accuracy, the |
| algorithms assume they hit a root and return the value |
| immediately. The default value is a "very small value". If the |
| goal is to get a near zero function value rather than an accurate |
| root, computation may be sped up by setting this value |
| appropriately. |
| </td> |
| </tr> |
| <tr> |
| <td>Maximum iteration count</td> |
| <td> |
| <div>getMaximumIterationCount</div> |
| <div>resetMaximumIterationCount</div> |
| <div>setMaximumIterationCount</div> |
| </td> |
| <td> |
| This is the maximal number of iterations the algorithm will try. |
| If this number is exceeded, non-convergence is assumed and a |
| <code>ConvergenceException</code> exception is thrown. The |
| default value is 100, which should be plenty, given that a |
| bisection algorithm can't get any more accurate after 52 |
| iterations because of the number of mantissa bits in a double |
| precision floating point number. If a number of ill-conditioned |
| problems is to be solved, this number can be decreased in order |
| to avoid wasting time. |
| </td> |
| </tr> |
| </table> |
| </p> |
| </subsection> |
| <subsection name="4.3 Interpolation" href="interpolation"> |
| <p> |
| A <a href="../apidocs/org/apache/commons/math/analysis/UnivariateRealInterpolator.html"> |
| org.apache.commons.math.analysis.UnivariateRealInterpolator</a> |
| is used to find a univariate real-valued function <code>f</code> which |
| for a given set of ordered pairs |
| (<code>x<sub>i</sub></code>,<code>y<sub>i</sub></code>) yields |
| <code>f(x<sub>i</sub>)=y<sub>i</sub></code> to the best accuracy possible. |
| Currently, only an interpolator for generating natural cubic splines is available. There is |
| no interpolator factory, mainly because the interpolation algorithm is more determined |
| by the kind of the interpolated function rather than the set of points to interpolate. |
| There aren't currently any accuracy controls either, as interpolation |
| accuracy is in general determined by the algorithm. |
| </p> |
| <p>Typical usage:</p> |
| <source>double x[]={ 0.0, 1.0, 2.0 }; |
| double y[]={ 1.0, -1.0, 2.0); |
| UnivariateRealInterpolator interpolator = SplineInterpolator(); |
| UnivariateRealFunction function = interpolator.interpolate(); |
| double x=0.5; |
| double y=function.evaluate(x); |
| System.out println("f("+x+")="+y);</source> |
| <p> |
| A natural cubic spline is a function consisting of a polynominal of |
| third degree for each subinterval determined by the x-coordinates of the |
| interpolated points. A function interpolating <code>N</code> |
| value pairs consists of <code>N-1</code> polynominals. The function |
| is continuous, smooth and can be differentiated twice. The second |
| derivative is continuous but not smooth. The x values passed to the |
| interpolator must be ordered in ascending order. It is not valid to |
| evaluate the function for values outside the range |
| <code>x<sub>0</sub></code>..<code>x<sub>N</sub></code>. |
| </p> |
| </subsection> |
| </section> |
| </body> |
| </document> |