how to bracket function zeros



On Dec. 11, 2012, I wrote
-----------------------------------------
>I am interested in bracketing the first zero
>(starting somewhere) of an arbitrarily
>complicated function as a preliminary to
>using find_root or bf_find_root.
>......
>......
>This approach will not work at bracketing
> a root of a function which has, for example,
> f(x1) = 0, f'(x1) = 0,  and f''(x1) > 0
>(for example, concave upwards at x = 1,
> zero slope at x = 1, and having a local
> minimum at x = 1) such as f(x) = (x - 1)^2 . 
>
>Another example which will not work with the
>above approach is f(x) = 10/cos(10*x)^2
........................................
  The second example SHOULD have been
       f(x) = cos(10*x)^2/10 .
  
I have constructed bracket(e,x,x1,x2,num)
 which starts with the structure of zbrak;
   if the function does NOT have opposite 
   signs at the ends of the subinterval 
   [xa,xb], check to see if the first derivative
   of the given function has opposite signs at
   the ends of the subinterval; if so, then 
   use find_root to solve for the location xr
   where the slope is zero, and evaluate the 
   function at xr. If f(xr) is "close" to 0,
   then return the list [xa,xb] as a bracket
   to use in checking integrability.
   
   To check integrability I do not need the
   exact location of the zero of the inverse
   of the first derivative of the integrand,
   only bracket limits.

--------------------------------------
Maxima 5.28.0-2 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.8 (a.k.a. GCL)

(%i1) opp_sign (o1,o2) :=
(if o1 < 0 and o2 > 0 then true
 else if o1 > 0 and o2 < 0 then true
 else false)$
 
(%i2) bracket(ze,zx,zx1,zx2,zn) :=
block([zdx,zfp,zxp,zfc,zr:[],zxr,zsmall:1.0e-12 ],local(zf,dzf),
    define(zf(zx),ze),
    define(dzf(zx),diff(ze,zx)),   
    zxp : zx1,
    zdx : (zx2-zx1)/zn,
    zfp : zf(zxp),
    dzfp : dzf(zxp),
    for zi:1 thru zn do
         (zxp : zxp + zdx,
          zfc : zf(zxp),
          dzfc : dzf(zxp),
          
          if opp_sign (zfp,zfc) then 
              (zr : [zxp - zdx,zxp],
               return())
          else if opp_sign (dzfp,dzfc) then
                  (zxr : find_root(dzf,zxp - zdx,zxp),
                   if abs (zf(zxr)) < zsmall then
                       (zr : [zxp - zdx,zxp],
                        return())),
          zfp : zfc,
          dzfp : dzfc),
    zr)$
    
(%i3) bracket(x^2,x,-1,1,11);
(%o3) [-1/11,1/11]

(%i4) bracket((x-1)^2,x,0,2,11);
(%o4) [10/11,12/11]

(%i5) bracket(cos(10*x)^2/10,x,0,1,11);
(%o5) [1/11,2/11]

(%i6) bracket(cos(10*x)^2/10,x,0,1,21);
(%o6) [1/7,4/21]

(%i7) bracket(1+x^2,x,-1,1,11);
(%o7) []

(%i8) bracket(sin(x),x,-1,1,21);
(%o8) [-1/21,1/21]

(%i9) bracket(cos(x),x,-1,1,21);
(%o9) []
---------------------------------------
Ted Woollett