Function: math[fnull] 4.0 - determines all zeros of an expression in one real
Calling Sequence:
fnull(f, x);
fnull(f, x, options);
fnull(f, x=a .. b);
fnull(f, x=a .. b, options);
Parameters:
f -
either any algebraic expression or an equation
x -
name of the indeterminate
a, b -
interval [a, b] to be searched for roots, including a and b
Options:
alg - Algorithm used to compute the roots if a change of sign of the
function has been found. Possible settings:
1) 'rf' - Newton's Regula falsi
2) 'nr' or 'raphson' - Newton-Raphson method using derivative and
bisection if Newton-Raphson would take the solution out of bounds
or if Newton-Raphson is not reducing the size of the brackets rapidly
enough. This algortihm was taken from: W. H. Press, S. A.
Teukolsky, W. T. Vetterling, B. P. Flannery: 'Numerical Recipes
in FORTRAN', 2nd Ed., Cambridge University Press, p. 355ff.
Newton-Raphson, as implemeted here, does not work well with
polynomials.
3) 'fs' or 'fsolve' - fsolve with option fulldigits (default)
The default for option alg can be changed by assigning the global variable
fnullAlg
one of the the above settings ('rf', 'nr, 'raphson', 'fs', or 'fsolve').
approx - If set true then approximations are (also) returned, if false only
those solutions where f(solution) = 0 are returned. Default is true,
syntax is: approx=<Boolean>.
The default for option approx can be changed by assigning the global variable
fnullApprox
either 'true' or 'false'.
check - Check the domain of f. The range passed to fnull will be changed if appropriate
which often speeds up computation. Default is 'true'.
The default for option check can be changed by assigning the global variable
fnullCheckDomain
either 'true' or 'false'.
eps - the stop value (difference between the positive and negative value
of the function around a zero), the smaller the value of eps
(abs(eps)->0) the more accurate the calculation of the zero;
eps should be less then 0.1. Default is 1e-8. syntax is: eps=<value>.
NOTE: You may have to increase eps in order to find more or all
roots of a function depending on its 'complexity'.
The default for option eps can be changed by assigning the global variable
fnullEps
a value of type numeric.
numerator-if a fraction is passed only evaluate its numerator; default is
true, syntax is: numer=<Boolean>.
Changing the default to false may cause division by zero.
The default for option numer can be changed by assigning the global variable
fnullNumerator
either 'true' or 'false'.
step - the length of the interval where the function is examined for a
change in sign, the smaller the value of step the more zeros may be
found (try f:=x->exp(x)*sin(x)). Default is 0.1, syntax is:
step=<value>.
The default for option step can be changed by assigning the global variable
fnullStep
a value of type numeric.
Description:
fnull evaluates all real solutions of any algebraic or transcendental expression or equation in one indeterminate on a specified interval.
In the first and second form, fnull determines the roots on the interval defined by the global variable _MathDomain which by default is assigned the range -10 .. 10. _MathDomain can be set according to the user's needs, see math/init for further details.
In the third and fourth form, fnull determines the roots on the interval [a, b].
The return is a sequence of results or if no solution was found the NULL sequence. Wrong options are ignored and defaults used instead.
If an algebraic expression f is specified then the equation f = 0 is understood.
If the expression f evaluates to zero the equation x=x is returned.
Wrong options are ignored, if you specify a wrong option to alg, Regula falsi is used.
Please note that fnull uses numerical algorithms, so in some cases a returned value is only an approximation. A value v is an approximation, if f(v) <> 0 but abs(f(v)) <= eps, where eps is the stop value. If approx is set true (default) then the global variable _A is assigned a list containing that value v or a list of values if more than one approximation is returned. So by evaluating _A you know which returned value is not an exact solution of the expression passed. See below for an example. (The global variable _A and the return of approximations have been introduced in version 3.2.)
The algorithm of this procedure is based on the combination of interval subdivision, looking for change of sign, and if there is a change applying function fsolve (default), the regula falsi or Newton-Raphson method (see option alg).
Since there is not necessarily a change of sign of the function over a subinterval but nevertheless a local extremum may exist and the root does not coincide with either the left nor right border of the respective subinterval evaluated by bisection, the first derivative of the function passed is determined and bisection and regula falsi also applied to it.
Internally the procedure only uses an algebraic expression for evaluation, so in case an equation is passed all terms of its right-hand side are moved to the left and the procedure called again with the resulting algebraic expression.
Beginning with fnull v 4.0 the function by default compares the range passed as the second argument with the domain of the expression f using math/domain . If parts of the range passed by the user are not included in the domain of f, those parts are ignored to speed up computation.
User information will be displayed during the computation if infolevel[`math/fnull`] or infolevel[fnull] is assigned value 1. The verbose option has been deleted with version 3.3.
fnull has option remember.
The core of this routine was adapted from a calculus program I wrote for the Sinclair ZX Spectrum home computer.
This function is part of the math package, and so can be used only after performing the command with(math) or with(math, fnull).
Examples:
> restart:
> with(math, fnull):
> f := x -> 1/4*x^3-4*x:
> _MathDomain;
> fnull(f(x), x);
> fnull(f(x), x=0 .. 5);
> fnull(sin(x), x=-10 .. 10, eps=1e-5, step=0.25);
> _A; # find out whether the return contains approximations.
> fnull(sin(x)=cos(x), x=-2 .. 2);
> infolevel[fnull] := 1:
> fnull(x/(x-1), x=-5 .. 5);
Warning, discontinuities found: {1}
fnull: Fraction found, now proceeding with numerator: x
fnull: using fsolve to determine roots
fnull: Searching for roots in expression x
fnull: Searching for roots in derivative 1
fnull: Roots found in original function: 0
fnull: Possible roots found in derivative: none
> infolevel[fnull] := 0:
> fnull((x-4.11)^4, x=-10 .. 10, alg='rf');
> _A;
> (_A[1]-4.11)^4;
> f := x -> ln(x):
> math[domain](f(x));
> infolevel[fnull] := 1:
> fnull(f(x), x);
fnull: using default domain (_MathDomain): -10 .. 10
fnull: domain changed to 0 .. 10
fnull: using fsolve to determine roots
fnull: Searching for roots in expression ln(x)
fnull: Searching for roots in derivative 1/x
fnull: Roots found in original function: 1.
fnull: Possible roots found in derivative: none
See Also:
math/init .
Known Bugs:
When assigning a value >= 0.1 to eps zeros may be printed multiple times.
Credits:
Dr. Ing. habil. Erhard Pross, pross@leipzig.ifag.de for giving fnull a proper test.
Joe Riel, jsr@sparc.sandiegoca.ncr.com, for advising me how to parse optional arguments of the form var=value.
Version History:
Version 2.0 current as of February 23, 1996
Version 2.1 current as of May 24, 1996
Version 2.2 current as of June 17, 1996
Version 2.3 current as of July 25, 1996
Version 2.3a current as of August 13, 1996
Version 3.0 current as of January 13, 1997
Version 3.0a current as of January 15, 1997
Version 3.1 current as of March 25, 1997 (not published)
Version 3.2 current as of April 11, 1997
Version 3.3 current as of May 28, 1997
Version 3.4 current as of May 29, 1997
Version 4.0 current as of December 29, 1997
Version 4.0.1 current as of October 31, 1997 (R5)