numeric::realroot
-- numerical
search for a real root of a real univariate functionnumeric::realroot
(f(x), x=a..b, ..)
computes a numerical real root of f(x) in the interval
[a,b].
numeric::realroot(f(x), x = a..b <, SearchLevel = s>)
f(x) |
- | an arithmetical expression in one unknown
x . Alternatively, an equation f1(x)=f2(x)
equivalent to the expression f1(x)-f2(x) . |
x |
- | an identifier or an indexed identifier |
a, b |
- | finite real numerical values |
SearchLevel =
s |
- | s is a small non-zero integer. It
controls the internal refinement of the search. |
a single numerical real root of domain type DOM_FLOAT
. If no solution is found, then
FAIL
is returned.
The function is sensitive to the environment variable DIGITS
, which determines the
numerical working precision.
numeric::fsolve
,
numeric::polyroots
,
numeric::realroots
,
polylib::realroots
,
solve
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
PI
or sqrt(2)
etc. are accepted. The same
holds true for the boundaries a,b
of the search
interval.float(f(x))
does not yield real floating point numbers for all real floating point
numbers x
from the interval [a,b]
, then
internal problems may occur. Cf. 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. Cf. example 5.DIGITS
significant
decimal places. Roots of smaller absolute size are computed to an
absolute precision of 10^(-2*DIGITS). These precision goals
are not achieved, if significant round-off occurs in the numerical
evaluation of f(x).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 [a,b]
.numeric::realroot
approximates a point
where f(x)
changes its sign. This is a root only if the
function f
is continuous. Cf. example 3.
setuserinfo(numeric::realroot,1)
provides information on the internal search.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.polylib::realroots
rather than
numeric::realroot
.s
FAIL
is returned, if no real root is found. For
this reason we recommend to restrict s to small values
(s<=5, say).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)
2.718281829
>> numeric::realroot(exp(-x[1]) = x[1], x[1] = 0..1)
0.5671432904
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)
0.1118325592
>> delete f:
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)
1.0
>> delete f:
The following function does not have a real root.
Consequently, numeric::realroot
fails:
>> numeric::realroot(x^2 + 1, x = -2..2)
FAIL
The following function does not have a real root in the search interval:
>> numeric::realroot(x^2 - 1, x = 2..3)
FAIL
The following function is complex valued for x^2 <3.5. An error occurs, when the internal search hits such a point:
>> numeric::realroot(ln(x^2 - 3.5), x = -2..3)
Error: Complex arguments are not allowed in comparisons; during evaluation of 'numeric::BrentFindRoot'
The singularity at x=2 does not cause any problem in the following call:
>> numeric::realroot((x-1)/(x-2), x = -10..PI)
1.0
However, the singularity may be hit accidentally in the internal search:
>> numeric::realroot((x-1)/(x-2), x = -10..14)
Error: Division by zero [_power]; during evaluation of '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)
FAIL
The root is detected with an increased search level:
>> numeric::realroot(f, x = 0..5, SearchLevel = 3)
1.0
>> delete f:
numeric::realroot
.