Numerical search for a real root of a real univariate function
This functionality does not run in MATLAB.
numeric::realroot(f(x), x = a .. b, <SearchLevel = s>)
numeric::realroot(f(x), x = a..b) computes a numerical real root of f(x) in the interval [a, b].
The expression f(x) must not contain symbolic objects other than the indeterminate x that cannot be converted to numerical values via float. Symbolic objects such as π or etc. are accepted. The same holds true for the boundaries a, b of the search interval.
The function must produce real values. If float(f(x)) does not yield real floating-point numbers for all real floating-point numbers x from the interval , internal problems may occur. See Example 5.
numeric::realroot never tries to evaluate f(x) outside the search interval. Consequently, singularities outside the interval do not cause any problems. In many cases also singularities inside the interval do not affect the numerical search. However, numeric::realroot is not guaranteed to work in such a case. An error may occur, if the internal search accidentally hits a singularity. See Example 5.
Up to roundoff effects numerical roots r with are computed to a relative precision of DIGITS significant decimal places. Roots of smaller absolute size are computed to an absolute precision of . These precision goals are not achieved, if significant roundoff occurs in the numerical evaluation of f(x).
If f takes opposite signs at the endpoints a, b of the search interval and does not have zero-crossing singularities, then numeric::realroot is bound to find a root in the interval .
User defined functions can be handled. See Example 2.
Note: numeric::realroot approximates a point where f(x) changes its sign. This is a root only if the function f is continuous. See Example 3.
Note that numeric::realroots may be used to isolate all real roots. However, this function is much slower than numeric::realroot, if f is not a polynomial.
The function is sensitive to the environment variable DIGITS, which determines the numerical working precision.
The following functions assume different signs at the boundaries, so the searches are bound to succeed:
numeric::realroot(x^3 - exp(3), x = -PI..10)
numeric::realroot(exp(-x) = x, x = 0..1)
The following function cannot be evaluated for non-numerical x. So one has to delay evaluation via hold:
f := proc(x) begin if x<0 then 1 - x else exp(x) - 10*x end_if end_proc: numeric::realroot(hold(f)(x), x = -10..10)
numeric::realroot approximates a point, where f(x) changes its sign. For the following function this happens at the discontinuity x = 1:
f := proc(x) begin if x<1 then -1 else x end_if end_proc: numeric::realroot(hold(f)(x), x = 0..3)
The following function does not have a real root. Consequently, numeric::realroot fails:
numeric::realroot(x^2 + 1, x = -2..2)
The following function does not have a real root in the search interval:
numeric::realroot(x^2 - 1, x = 2..3)
The following function is complex valued for x2 < 3.5. An error occurs, when the internal search hits such a point:
numeric::realroot(ln(x^2 - 3.5), x = -2..3)
Error: Cannot evaluate to Boolean. [_less] Evaluating: numeric::BrentFindRoot
The singularity at x = 1 does not cause any problem in the following call:
numeric::realroot((x-2)/(x-1), x = -10..10)
However, the singularity may be hit accidentally in the internal search:
numeric::realroot((x-2)/(x-1), x = 0..3)
Error: Division by zero. [_power] Evaluating: f
The following function has a root close to 1.0, which is difficult to detect. With the default search level s = 1, this root is not found:
f := 2 - exp(-100*(x - 2)^2) - 2*exp(-1000*(x - 1)^2): numeric::realroot(f, x = 0..5)
The root is detected with an increased search level:
numeric::realroot(f, x = 0..5, SearchLevel = 3)
An arithmetical expression in one unknown x or a list, set, array, or matrix (Cat::Matrix) of expressions. Alternatively, equations in the form f1(x) = f2(x) equivalent to the expressions f1(x) - f2(x).
An identifier or an indexed identifier
Finite real numerical values
Option, specified as SearchLevel = s
The nonnegative integer s controls the internal refinement of the search. The default value is s = 1. Increasing s increases the chance of finding roots that are difficult to detect numerically. See Example 6.
Note that increasing s by 1 may quadruple the time before FAIL is returned, if no real root is found. For this reason we recommend to restrict s to small values (s ≤ 5, say).
A mixture of bisectioning, secant steps and quadratic interpolation is used by numeric::realroot.