266 lines
14 KiB
XML
266 lines
14 KiB
XML
<?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>
|