public class ZerosFunction extends Object implements Serializable, Cloneable
ZerosFunction
computes n real zeros of
a real, continuous, univariate function f. The search for the zeros
of the function can be limited to a specified interval, or extended over
the entire real line. The algorithm is generally more efficient if an interval
is specified. The user supplied function, f(x), must return valid
results for all values in the specified interval. If no interval is given,
the user-supplied function must return valid results for all real numbers.
The function has two convergence criteria. The first criterion accepts a
root, x, if $$\left| f\left(x\right) \right|\le \tau$$
where \(\tau\) = error
, see method
setError
.
The second criterion accepts a root if it is known to be inside of an
interval of length at most errorAbsolute
, see method
setAbsoluteError
.
A root is accepted if it satisfies either criteria and is not within
minSeparation
of another accepted root, see method
setMinimumSeparation
.
If initial guesses for the roots are given, Müller's method (Müller 1956) is used for each of these guesses. For each guess, the Müller iteration is stopped if the next step would be outside of the bound, if given. The iteration is also stopped if the algorithm cannot make further progress in finding a root.
If no guesses for the zeros were given, or if Müller's method with the guesses did not find the requested number of roots, a meta-algorithm, combining Müller's and Brent's methods, is used. Müller's method is used primarily to find the roots of functions, such as \(f(x) = x^2\), where the function does not cross the y=0 line. Brent's method is used to find other types of roots.
The meta-algorithm successively refines the interval using a
one-dimensional Faure low-discrepancy sequence. The Faure sequence may be
scaled by setting the bound interval [a,b] using the setBounds
method. The Faure sequence will be scaled from (0,1) to (a,b).
If no bound on the function's domain is given, the entire real line must
be searched for roots. In this case the Faure sequence is scaled from
(0, 1) to \(\left( -\infty, +\infty \right)\) using the mapping
$$h(u) = \mbox{xScale} \cdot{\tan{(\pi( u - 1/2))}}$$
where xScale
is set by the setXScale
method.
At each step of the iteration, the next point in the Faure sequence is added to the list of breakpoints defining the subintervals. Call the points \(x_0=a, x_1=b, x_2, x_3, \ldots\). The new point, \(x_s\) splits an existing subinterval, \([x_p, x_q]\).
The function is evaluated at \(x_s\). If its value is small enough, specifically if $$\left|f\left(x_s\right)\right|\lt \hbox{mullerTolerance}$$ then Müller's method is used with \(x_p\), \(x_q\) and \(x_s\) as starting values. If a root is found, it is added to the list of roots. If more roots are required, the new Faure point is used.
If Müller's method did not find a root using the new point, the function value at the point is compared with the function values at the endpoints of the subinterval it divides. If \(f\left(x_p\right)f\left(x_s\right) \lt 0 \) and no root has previously been found in \([x_p,x_s]\), then Brent's method is used to find a root in this interval. Similarly, if the function changes sign over the interval \([x_s,x_q]\), and a root has not already been found in the subinterval, Brent's method is used.
Modifier and Type | Class and Description |
---|---|
static interface |
ZerosFunction.Function
Public interface for the user supplied function to
ZerosFunction . |
Constructor and Description |
---|
ZerosFunction()
Creates an instance of the solver.
|
Modifier and Type | Method and Description |
---|---|
boolean |
allConverged()
Returns true if the iterations for all of the roots have converged.
|
double[] |
computeZeros(ZerosFunction.Function objectF)
Returns the zeros of a univariate function.
|
int |
getMaxEvaluations()
Returns the maximum number of function evaluations allowed.
|
int |
getNumberOfEvaluations()
Returns the actual number of function evaluations performed.
|
int |
getNumberOfRoots()
Returns the requested number of roots to be found.
|
int |
getNumberOfRootsFound()
Returns the number of zeros found.
|
void |
setAbsoluteError(double errorAbsolute)
Sets the second convergence criterion.
|
void |
setBounds(double lowerBound,
double upperBound)
Sets the closed interval in which to search for the roots.
|
void |
setError(double error)
Sets the first convergence criterion.
|
void |
setGuess(double[] guess)
Sets the initial guess for the zeros.
|
void |
setMaxEvaluations(int maxEvaluations)
Sets the maximum number of function evaluations allowed.
|
void |
setMinimumSeparation(double minSeparation)
Sets the minimum separation between accepted roots.
|
void |
setMullerTolerance(double mullerTolerance)
Sets the tolerance used during refinement to determine if Müllers method is
started.
|
void |
setNumberOfRoots(int numRoots)
Sets the number of roots to be found.
|
void |
setXScale(double xScale)
Sets the scaling in the x-coordinate.
|
public void setBounds(double lowerBound, double upperBound)
lowerBound
- a double
containing the lower interval
bound. lowerBound
cannot be greater than
or equal to upperBound
.upperBound
- a double
containing the upper interval bound.
By default the search for the roots is not bounded.
public void setXScale(double xScale)
If no bound on the function's domain is given, the entire real line must be searched for roots. In this case the Faure sequence is scaled from (0, 1) to \(\left( -\infty, \infty \right)\) using the mapping $$h(u) = \mbox{xScale} \cdot{\tan{(\pi( u - 1/2))}}.$$
xScale
- a double
containing the scaling in the
x-coordinate. The absolute value of the roots divided by
xScale
should be about one. xScale
must be greater than 0.0. By default, xScale
=1.0.public void setNumberOfRoots(int numRoots)
numRoots
- an int
containing the number of roots to be
found. numRoots
must be greater than or
equal to zero. By default, numRoots
=1.public int getNumberOfRoots()
int
containing the requested number of roots to be foundpublic int getNumberOfRootsFound()
int
containing the number of roots foundpublic void setMaxEvaluations(int maxEvaluations)
Methods allConverged
and
getNumberOfRootsFound
can be used to confirm
whether or not the number of roots requested were found
within the maximum evaluations specified.
maxEvaluations
must be greater than or
equal to 0.0.
maxEvaluations
- an int
containing the maximum number of
function evaluations allowed. Once this limit is
reached, the roots found are returned.public int getMaxEvaluations()
int
containing the maximum number of
function evaluations allowedpublic void setAbsoluteError(double errorAbsolute)
The second criterion accepts a root if the root is known to be inside
an interval of length at most errorAbsolute
.
errorAbsolute
- a double
value specifying the second
convergence criterion. A root is accepted if the
absolute value of the function at the point is
less than or equal to errorAbsolute
.
errorAbsolute
must be greater than
or equal to 0.0.
Default: errorAbsolute
= 2.22e-14public void setGuess(double[] guess)
guess
- a double
array containing the initial guesses
for the number of zeros to be found. If a bound on the
zeros is also given, the guesses must satisfy the bound
condition.public void setMinimumSeparation(double minSeparation)
minSeparation
- a double
containing the minimum
separation between accepted roots. If two points
satisfy the convergence criteria, but are within
minSeparation
of each other, only one
of the roots is accepted. minSeparation
must be greater than or equal to 0.0.
By default, minSeparation
=
1.0e-8/xScale
.
public void setError(double error)
A root is accepted if it is bracketed within an interval of
length error
.
$$\left| f\left(x\right) \right|\le \tau$$
where \(\tau\) = error
.
error
- a double
containing the first convergence
criterion. error
must be greater than or
equal to 0.0. By default,
error
= 2.0e-8/xScale
.public void setMullerTolerance(double mullerTolerance)
Müller's method is started if, during refinement, a point is found for
which the absolute value of the function is less than mullerTolerance
and the point is not near an already discovered root. If mullerTolerance
is less than or equal to zero, Müller's method is never used.
mullerTolerance
- a double
containing the tolerance used
during refinement to determine when the Müller's method is used.
By default, mullerTolerance
= 1.0e-8/errorAbsolute
public int getNumberOfEvaluations()
int
containing the actual number of
function evaluations performedpublic double[] computeZeros(ZerosFunction.Function objectF)
objectF
- contains the function for which the zeros will be founddouble
array containing the zerso of the
univariate function.public boolean allConverged()
Copyright © 2020 Rogue Wave Software. All rights reserved.