# Given a real polynomial p(x) and lower and upper bounds 
# of the desiredc real root.
#
# NewtonItern(p) returns a zero of p(x).
#
#                                        Ren-Cang Li, June 1, 1996
#                                        na.rcli@na-net.ornl.gov

NewtonItern:=proc(p:polynom, LowB, UpB)
      local f, df, x0, x1, temp, fL, fU, Lb, Ub, nt, unknset, unkn, eps;
      unknset:=indets(p); eps:=10^(-Digits+5);
      if nops(unknset)=0 then # Test if the polynomial is a constant.
	 print(`Error: the polynomialis a constant!`);
      elif nops(unknset)>1 then
	 print(`Error: handle univariate polynomial ONLY!`);
      else # The univariate polynomial is at least of degree 1.
	 unkn:=unknset[1]; f:=convert(expand(p),horner); 
	 df:=convert(diff(expand(p),unkn),horner); 
	 Lb:=evalf(convert(evalf(LowB),fraction)); 
	 Ub:=evalf(convert(evalf(UpB),fraction)); 
	 fL:=subs(unkn=Lb,f); fU:=subs(unkn=Ub,f); 
	 if fL*fU>=0 then 
	    print(`Warning: there may be two zeros.`);
	 fi;
	 x0:=(Lb+Ub)/2; temp:=subs(unkn=x0,f);
	 x1:=x0-temp/subs(unkn=x0,df);
	 if temp*fL>0 then 
	    Lb:=x0; fL:=temp;
	 else
	    Ub:=x0; fU:=temp;
	 fi;
	 if x1<Lb or x1>Ub then 
	    x1:=(Lb+Ub)/2;   
	 fi;
	 nt:=1;
	 while abs(x1-x0)>eps*abs(x1) and nt<101 do  
	   nt:=nt+1;
	   x0:=x1; temp:=subs(unkn=x0,f); 
	   x1:=x0-temp/subs(unkn=x0,df); 
	   if temp*fL>0 then 
	      Lb:=x0; fL:=temp;
	   else
	      Ub:=x0; fU:=temp;
	   fi;
	   if x1<Lb or x1>Ub then 
	      x1:=(Lb+Ub)/2; 
	   fi;
	 od;    
      fi;
      if nt=101 or nt>101 then 
	 print(`over 101 iterations`);
      fi;
      x1;
      end:
