BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/poly/Sturm.h
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Core Library Version 1.7, August 2004
00003  * Copyright (c) 1995-2004 Exact Computation Project
00004  * All rights reserved.
00005  *
00006  * This file is part of CORE (http://cs.nyu.edu/exact/core/); you may
00007  * redistribute it under the terms of the Q Public License version 1.0.
00008  * See the file LICENSE.QPL distributed with CORE.
00009  *
00010  * Licensees holding a valid commercial license may use this file in
00011  * accordance with the commercial license agreement provided with the
00012  * software.
00013  *
00014  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00015  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00016  *
00017  *
00018  *  File: Sturm.h
00019  * 
00020  *  Description: 
00021  *  The templated class Sturm implements Sturm sequences.
00022  *  Basic capabilities include:
00023  *     counting number of roots in an interval, 
00024  *     isolating all roots in an interval
00025  *     isolating the i-th largest (or smallest) root in interval
00026  *  It is based on the Polynomial class.
00027  * 
00028  *   BigFloat intervals are used for this (new) version.
00029  *   It is very important that the BigFloats used in these intervals
00030  *   have no error at the beginning, and this is maintained
00031  *   by refinement.  Note that if x, y are error-free BigFloats,
00032  *   then (x+y)/2 may not be error-free (in current implementaion.
00033  *   We have to call a special "exact divide by 2" method,
00034  *   (x+y).div2() for this purpose.
00035  *
00036  *   CONVENTION: an interval defined by a pair of BigFloats x, y
00037  *   has this interpretation:
00038  *       (1) if x>y,  it represents an invalid interval.
00039  *       (2) if x=y,  it represents a unique point x.
00040  *       (3) if x<y,  it represents the open interval (x,y).
00041  *           In this case, we always may sure that x, y are not zeros.
00042  * 
00043  *   TODO LIST and Potential Bugs:
00044  *   (1) Split an isolating interval to give definite sign (done)
00045  *   (2) Should have a test for square-free polynomials (done)
00046  * 
00047  *  Author:  Chee Yap and Sylvain Pion, Vikram Sharma
00048  *  Date:    July 20, 2002
00049  *
00050  * WWW URL: http://cs.nyu.edu/exact/
00051  * Email: exact@cs.nyu.edu
00052  *
00053  * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/poly/Sturm.h $
00054  * $Id: Sturm.h 43611 2008-06-15 16:21:29Z spion $
00055  ***************************************************************************/
00056 
00057 
00058 #ifndef CORE_STURM_H
00059 #define CORE_STURM_H
00060 
00061 #include "CGAL/CORE/BigFloat.h"
00062 #include "CGAL/CORE/Expr.h"
00063 #include "CGAL/CORE/poly/Poly.h"
00064 
00065 CORE_BEGIN_NAMESPACE
00066 
00067 // ==================================================
00068 // Sturm Class
00069 // ==================================================
00070 
00071 template < class NT >
00072 class Sturm {
00073 public:
00074   int len;      // len is 1 less than the number of non-zero entries in array seq.
00075                 //     I.e., len + 1 = length of the Sturm Sequence
00076                 // N.B. When len = -1 or len = 0 are special,
00077                 //     the array seq is not used!
00078                 //     Hence, one must test these special cases
00079   Polynomial<NT> * seq;      // array of polynomials of length "len+1"
00080   Polynomial<NT> g;//GCD of input polynomial P and it's derivative P'
00081   NT cont;//Content of the square-free part of input polynomial P
00082   //Thus P = g * cont * seq[0]
00083   static int N_STOP_ITER;    // Stop IterE after this many iterations. This
00084   // is initialized below, outside the Newton class
00085   bool NEWTON_DIV_BY_ZERO;   // This is set to true when there is divide by
00086   // zero in Newton iteration (at critical value)
00087   // User is responsible to check this and to reset.
00088   typedef Polynomial<NT> PolyNT;
00089 
00090   // ===============================================================
00091   // CONSTRUCTORS
00092   // ===============================================================
00093   // Null Constructor
00094   Sturm() : len(0), NEWTON_DIV_BY_ZERO(false) {}
00095 
00096   // Constructor from a polynomial
00097   Sturm(Polynomial<NT> pp) : NEWTON_DIV_BY_ZERO(false) {
00098     len = pp.getTrueDegree();
00099     if (len <= 0) return; // hence, seq is not defined in these cases
00100     seq = new Polynomial<NT> [len+1];
00101     seq[0] = pp;
00102     g = seq[0].sqFreePart();
00103     cont = content(seq[0]);
00104     seq[0].primPart();
00105     seq[1] = differentiate(seq[0]);
00106     int i;
00107     for (i=2; i <= len; i++) {
00108       seq[i] = seq[i-2];
00109       seq[i].negPseudoRemainder(seq[i-1]);
00110       if (zeroP(seq[i])){
00111         len = i-1;//Since len is one less than the number of non-zero entries.
00112         break;
00113       }
00114       seq[i].primPart(); // Primitive part is important to speed
00115       // up large polynomials! However, for first 2 polymials,
00116       // we MUST NOT take primitive part, because we
00117       // want to use them in Newton Iteration
00118     }
00119   }
00120 
00121   // Chee: 7/31/04
00122   //    We need BigFloat version of Sturm(Polynomial<NT>pp) because
00123   //    of curve verticalIntersection() ... .  We also introduce
00124   //    various support methods in BigFloat.h (exact_div, gcd, etc).
00125   // Constructor from a BigFloat polynomial 
00126   //    Need the fake argument to avoid compiler overloading errors
00127   Sturm(Polynomial<BigFloat> pp, bool fake) : NEWTON_DIV_BY_ZERO(false) {
00128     len = pp.getTrueDegree();
00129     if (len <= 0) return; // hence, seq is not defined in these cases
00130     seq = new Polynomial<NT> [len+1];
00131     seq[0] = pp;
00132     g = seq[0].sqFreePart();
00133     cont = content(seq[0]);
00134     seq[0].primPart();
00135     seq[1] = differentiate(seq[0]);
00136     int i;
00137     for (i=2; i <= len; i++) {
00138       seq[i] = seq[i-2];
00139       seq[i].negPseudoRemainder(seq[i-1]);
00140       if (zeroP(seq[i])){
00141         len = i-1;//Since len is one less than the number of non-zero entries.
00142         //len = i;
00143         break;
00144       }
00145       seq[i].primPart(); // Primitive part is important to speed
00146       // up large polynomials! However, for first 2 polymials,
00147       // we DO NOT take primitive part, because we
00148       // want to use them in Newton Iteration
00149     }
00150   }
00151 
00152   // Constructor from an array of NT's
00153   //   -- this code is identical to constructing from a polynomial...
00154   Sturm(int n, NT * c) : NEWTON_DIV_BY_ZERO(false) {
00155     Polynomial<NT> pp(n, c); // create the polynomial pp first and call the
00156     (*this) = Sturm<NT>(pp);//constructor from a polynomial
00157   }
00158 
00159   // copy constructor
00160   Sturm(const Sturm&s) : len(s.len), NEWTON_DIV_BY_ZERO(s.NEWTON_DIV_BY_ZERO) {
00161     if (len <= 0) return;
00162     seq = new Polynomial<NT> [len+1];
00163     for (int i=0; i<=len; i++)
00164       seq[i] = s.seq[i];
00165   }
00166 
00167   // assignment operator
00168   const Sturm& operator=(const Sturm& o) {
00169     if (this == &o)
00170       return *this;
00171     if (len > 0)
00172       delete[] seq;
00173     NEWTON_DIV_BY_ZERO = o.NEWTON_DIV_BY_ZERO;
00174     len = o.len;
00175     if (len > 0) {
00176       seq = new Polynomial<NT>[len+1];
00177       for (int i=0; i<=len; i++)
00178         seq[i] = o.seq[i];
00179     }
00180     return *this;
00181   }
00182 
00183   // destructor
00184   ~Sturm() {
00185     if (len != 0)
00186       delete[] seq;
00187   }
00188 
00189   // METHODS
00190 
00191   // dump functions
00192   void dump(std::string msg) const {
00193     std::cerr << msg << std::endl;
00194     if (len <= 0) std::cerr << " len = " << len << std::endl;
00195     else
00196        for (int i=0; i<=len; i++)
00197          std::cerr << " seq[" << i << "] = " << seq[i] << std::endl;
00198   }
00199   void dump() const {
00200     dump("");
00201   }
00202 
00203   // signVariations(x, sx)
00204   //   where sx = sign of evaluating seq[0] at x
00205   //   PRE-CONDITION: sx != 0  and len > 0
00206   int signVariations(const BigFloat & x, int sx) const {
00207     assert((sx != 0) && (len >0));
00208     int cnt = 0;
00209     int last_sign = sx;
00210     for (int i=1; i<=len; i++) {// Chee (4/29/04): Bug fix,
00211         // should start iteration at i=1, not i=0.  Potential error
00212         // if seq[0].eval(x)=0 (though not in our usage).
00213       int sgn = sign(seq[i].evalExactSign(x));
00214       if (sgn*last_sign < 0) {
00215         cnt++;
00216         last_sign *= -1;
00217       }
00218     }
00219     return cnt;
00220   }
00221 
00222   // signVariations(x)
00223   //   --the first polynomial eval is not yet done
00224   //   --special return value of -1, indicating x is root!
00225   int signVariations(const BigFloat & x) const {
00226     if (len <= 0) return len; 
00227     int signx = sign(seq[0].evalExactSign(x));
00228     if (signx == 0)
00229       return (-1);    // THIS indicates that x is a root...
00230                       // REMARK: in our usage, this case does not arise
00231     return signVariations(x, signx);
00232   }//signVariations(x)
00233 
00234   // signVariation at +Infinity
00235   int signVariationsAtPosInfty() const {
00236     if (len <= 0) return len;
00237     int cnt = 0;
00238     int last_sign = sign(seq[0].coeff[seq[0].getTrueDegree()]);
00239     assert(last_sign != 0);
00240     for (int i=1; i<=len; i++) {
00241       int sgn = sign(seq[i].coeff[seq[i].getTrueDegree()]);
00242       if (sgn*last_sign < 0)
00243         cnt++;
00244       if (sgn != 0)
00245         last_sign = sgn;
00246     }
00247     return cnt;
00248   }
00249 
00250   // signVariation at -Infinity
00251   int signVariationsAtNegInfty() const {
00252     if (len <= 0) return len;
00253     int cnt = 0;
00254     int last_sign = sign(seq[0].coeff[seq[0].getTrueDegree()]);
00255     if (seq[0].getTrueDegree() % 2 != 0)
00256       last_sign *= -1;
00257     assert(last_sign != 0);
00258     for (int i=1; i<=len; i++) {
00259       int parity = (seq[i].getTrueDegree() % 2 == 0) ? 1 : -1;
00260       int sgn = parity * sign(seq[i].coeff[seq[i].getTrueDegree()]);
00261       if (sgn*last_sign < 0)
00262         cnt++;
00263       if (sgn != 0)
00264         last_sign = sgn;
00265     }
00266     return cnt;
00267   }
00268 
00269   // numberOfRoots(x,y):
00270   //   COUNT NUMBER OF ROOTS in the close interval [x,y]
00271   //   IMPORTANT: Must get it right even if x, y are roots
00272   //   Assert("x and y are exact")
00273   //       [If the user is unsure of this assertion, do
00274   //        "x.makeExact(); y.makeExact()" before calling].
00276   int numberOfRoots(const BigFloat &x, const BigFloat &y) const {
00277     assert(x <= y);   // we allow x=y
00278     if (len <= 0) return len;  // return of -1 means infinity of roots!
00279     int signx = sign(seq[0].evalExactSign(x));
00280     if (x == y) return ((signx == 0) ? 1 : 0);
00281     int signy = sign(seq[0].evalExactSign(y));
00282     // easy case: THIS SHOULD BE THE OVERWHELMING MAJORITY
00283 
00284     if (signx != 0 && signy != 0)
00285       return (signVariations(x, signx) - signVariations(y, signy));
00286     // harder case: THIS SHOULD BE VERY INFREQUENT
00287     BigFloat sep = (seq[0].sepBound()).div2();
00288     BigFloat newx, newy;
00289     if (signx == 0)
00290       newx = x - sep;
00291     else
00292       newx = x;
00293     if (signy == 0)
00294       newy = y + sep;
00295     else
00296       newy = y;
00297     return (signVariations(newx, sign(seq[0].evalExactSign(newx)))
00298             - signVariations(newy, sign(seq[0].evalExactSign(newy))) );
00299   }//numberOfRoots
00300 
00301   // numberOfRoots():
00302   //   Counts the number of real roots of a polynomial
00304   int numberOfRoots() const {
00305     if (len <= 0) return len;  // return of -1 means infinity of roots!
00306     //    BigFloat bd = seq[0].CauchyUpperBound();
00307     //    return numberOfRoots(-bd, bd);
00308     return signVariationsAtNegInfty() - signVariationsAtPosInfty();
00309   }
00310 
00311   // numberOfRoots above or equal to x:
00312   //   Default value x=0 (i.e., number of positive roots)
00313   //   assert(len >= 0)
00315   int numberOfRootsAbove(const BigFloat &x = 0) const {
00316     if (len <= 0) return len;  // return of -1 means infinity of roots!
00317     int signx = sign(seq[0].evalExactSign(x));
00318     if (signx != 0)
00319       return signVariations(x, signx) - signVariationsAtPosInfty();
00320     BigFloat newx = x - (seq[0].sepBound()).div2();
00321     return signVariations(newx, sign(seq[0].evalExactSign(newx)))
00322            - signVariationsAtPosInfty();
00323   }
00324 
00325   // numberOfRoots below or equal to x:
00326   //   Default value x=0 (i.e., number of negative roots)
00327   //   assert(len >= 0)
00329   int numberOfRootsBelow(const BigFloat &x = 0) const {
00330     if (len <= 0) return len;  // return of -1 means infinity of roots!
00331     int signx = sign(seq[0].evalExactSign(x));
00332     if (signx != 0)
00333       return signVariationsAtNegInfty() - signVariations(x, signx);
00334     BigFloat newx = x + (seq[0].sepBound()).div2();
00335     return signVariationsAtNegInfty()
00336            - signVariations(newx, sign(seq[0].evalExactSign(newx)));
00337   }
00338 
00339 
00343 
00354   void isolateRoots(const BigFloat &x, const BigFloat &y,
00355                     BFVecInterval &v) const {
00356     assert(x<=y);
00357 
00358     int n = numberOfRoots(x,y);
00359     if (n == 0) return;
00360     if (n == 1) {
00361       if ((x > 0) || (y < 0)) // usual case: 0 is not in interval
00362         v.push_back(std::make_pair(x, y));
00363       else { // if 0 is inside our interval (this extra
00364              // service is not strictly necessary!)
00365         if (seq[0].coeff[0] == 0)
00366           v.push_back(std::make_pair(BigFloat(0), BigFloat(0)));
00367         else if (numberOfRoots(0,y) == 0)
00368           v.push_back(std::make_pair(x, BigFloat(0)));
00369         else
00370           v.push_back(std::make_pair(BigFloat(0), y));
00371       }
00372     } else { // n > 1
00373       BigFloat mid = (x+y).div2(); // So mid is exact.
00374       if (sign(seq[0].evalExactSign(mid)) != 0)  { // usual case: mid is non-root
00375         isolateRoots(x, mid, v);
00376         isolateRoots(mid, y, v); 
00377       } else { // special case: mid is a root
00378         BigFloat tmpEps = (seq[0].sepBound()).div2();  // this is exact!
00379         if(mid-tmpEps > x )//Since otherwise there are no roots in (x,mid)
00380           isolateRoots(x, (mid-tmpEps).makeCeilExact(), v);
00381         v.push_back(std::make_pair(mid, mid));
00382         if(mid+tmpEps < y)//Since otherwise there are no roots in (mid,y)
00383           isolateRoots((mid+tmpEps).makeFloorExact(), y, v);
00384       }
00385     }
00386   }//isolateRoots(x,y,v)
00387 
00388   // isolateRoots(v)
00390 
00392   void isolateRoots(BFVecInterval &v) const {
00393     if (len <= 0) {
00394        v.clear(); return;
00395     }
00396     BigFloat bd = seq[0].CauchyUpperBound();
00397     // Note: bd is an exact BigFloat (this is important)
00398     isolateRoots(-bd, bd, v);
00399   }
00400 
00401   // isolateRoot(i)
00405   BFInterval isolateRoot(int i = 0) const {
00406     if (len <= 0) 
00407        return BFInterval(1,0);   // ERROR CONDITION
00408     if (i == 0)
00409       return mainRoot();
00410     BigFloat bd = seq[0].CauchyUpperBound();
00411     return isolateRoot(i, -bd, bd);
00412   }
00413 
00414   // isolateRoot(i, x, y)
00416 
00419   BFInterval isolateRoot(int i, BigFloat x, BigFloat y) const {
00420     int n = numberOfRoots(x,y);
00421     if (i < 0) {//then we want the n-i+1 root
00422       i += n+1;
00423       if (i <= 0)
00424         return BFInterval(1,0); // ERROR CONDITION
00425     }
00426     if (n < i)
00427       return BFInterval(1,0);  // ERROR CONDITION INDICATED
00428     //Now 0< i <= n
00429     if (n == 1) {
00430       if ((x>0) || (y<0)) return BFInterval(x, y);
00431       if (seq[0].coeff[0] == NT(0)) return BFInterval(0,0);
00432       if (numberOfRoots(0, y)==0) return BFInterval(x,0);
00433       return BFInterval(0,y);
00434     }
00435     BigFloat m = (x+y).div2();
00436     n = numberOfRoots(x, m);
00437     if (n >= i)
00438             return isolateRoot(i, x, m);
00439     // Now (n < i) but we have to be careful if m is a root
00440     if (sign(seq[0].evalExactSign(m)) != 0)   // usual case
00441       return isolateRoot(i-n, m, y);
00442     else
00443       return isolateRoot(i-n+1, m, y);
00444   }
00445 
00446   // same as isolateRoot(i).
00447   BFInterval diamond(int i) const {
00448     return isolateRoot(i);
00449   }
00450 
00451   // First root above
00452   BFInterval firstRootAbove(const BigFloat &e) const {
00453     if (len <= 0)
00454        return BFInterval(1,0);   // ERROR CONDITION
00455     return isolateRoot(1, e, seq[0].CauchyUpperBound());
00456   }
00457 
00458   // Main root (i.e., first root above 0)
00459   BFInterval mainRoot() const {
00460     if (len <= 0)
00461        return BFInterval(1,0);   // ERROR CONDITION
00462     return isolateRoot(1, 0, seq[0].CauchyUpperBound());
00463   }
00464 
00465   // First root below
00466   BFInterval firstRootBelow(const BigFloat &e) const {
00467     if (len <= 0)
00468        return BFInterval(1,0);   // ERROR CONDITION
00469     BigFloat bd = seq[0].CauchyUpperBound(); // bd is exact
00470     int n = numberOfRoots(-bd, e);
00471     if (n <= 0)
00472       return BFInterval(1,0);
00473     BigFloat bdBF = BigFloat(ceil(bd));
00474     if (n == 1)
00475       return BFInterval(-bdBF, e);
00476     return isolateRoot(n, -bdBF, e);
00477   }
00478 
00479   // Refine an interval I to absolute precision 2^{-aprec}
00480   //   THIS USES bisection only!  Use only for debugging (it is too slow)
00481   //
00482   BFInterval refine(const BFInterval& I, int aprec) const {
00483     // assert( There is a unique root in I )
00484     // We repeat binary search till the following holds
00485     //      width/2^n <= eps             (eps = 2^(-aprec))
00486     //   => log(width/eps) <= n
00487     //   => n = ceil(log(width/eps)) this many steps of binary search
00488     //   will work.
00489     // At each step we verify
00490     //   seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) < 0
00491 
00492     BigFloat width = I.second - I.first;
00493     if (width <= 0) return I;  // Nothing to do if the
00494                                //   interval I is exact or inconsistent
00495     BigFloat eps = BigFloat::exp2(-aprec);   //  eps = 2^{-aprec}
00496     extLong n =  width.uMSB() + (extLong)aprec;
00497 
00498 
00499     BFInterval J = I;           // Return value is the Interval J
00500     BigFloat midpoint;
00501     while(n >= 0) {
00502       midpoint = (J.second + J.first).div2();
00503       BigFloat m = seq[0].evalExactSign(midpoint);
00504       if (m == 0) {
00505         J.first = J.second = midpoint;
00506         return J;
00507       }
00508       if (seq[0].evalExactSign(J.first) * m < 0) {
00509         J.second = midpoint;
00510       } else {
00511         J.first = midpoint;
00512       }
00513 
00514       n--;
00515     }
00516 
00517     return J;
00518   }//End Refine
00519 
00520   // Refine First root above
00521   BFInterval refinefirstRootAbove(const BigFloat &e, int aprec) const {
00522     BFInterval I = firstRootAbove(e);
00523     return refine(I,aprec);
00524   }
00525 
00526   // Refine First root below
00527   BFInterval refinefirstRootBelow(const BigFloat &e, int aprec) const {
00528     BFInterval I = firstRootBelow(e);
00529     return refine(I,aprec);
00530   }
00531 
00532   // refineAllRoots(v, aprec)
00533   //     will modify v so that v is a list of isolating intervals for
00534   //     the roots of the polynomial in *this.  The size of these intervals
00535   //     are at most 2^{-aprec}.
00536   // If v is non-null, we assume it is a list of initial isolating intervals.
00537   // If v is null, we will first call isolateRoots(v) to set this up.
00538   void refineAllRoots( BFVecInterval &v, int aprec) {
00539     BFVecInterval v1;
00540     BFInterval  J;
00541     if (v.empty())
00542       isolateRoots(v);
00543 
00544     for (BFVecInterval::const_iterator it = v.begin();
00545          it != v.end(); ++it) {        // Iterate through all the intervals
00546       //refine them to the given precision aprec
00547       J = refine(BFInterval(it->first, it->second), aprec);
00548       v1.push_back(std::make_pair(J.first, J.second));
00549     }
00550     v.swap(v1);
00551   }//End of refineAllRoots
00552 
00553   // This is the new version of "refineAllRoots"
00554   //            based on Newton iteration
00555   // It should be used instead of refineAllRoots!
00556   void newtonRefineAllRoots( BFVecInterval &v, int aprec) {
00557 
00558     BFVecInterval v1;
00559     BFInterval  J;
00560 
00561     if (v.empty())
00562       isolateRoots(v);
00563     for (BFVecInterval::iterator it = v.begin();
00564          it != v.end(); ++it) {        // Iterate through all the intervals
00565       //refine them to the given precision aprec
00566       J = newtonRefine(*it, aprec);
00567 
00568       if (NEWTON_DIV_BY_ZERO) {
00569         J.first = 1;
00570         J.second = 0;   // indicating divide by zero
00571       }
00572       v1.push_back(std::make_pair(J.first, J.second));
00573     }
00574     v.swap(v1);
00575   }//End of newtonRefineAllRoots
00576 
00599   BigFloat newtonIterN(long n, const BigFloat& bf, BigFloat& del,
00600         unsigned long & err, extLong& fuMSB, extLong& ffuMSB) {
00601     if (len <= 0) return bf;   // Nothing to do!  User must
00602                                // check this possibility!
00603     BigFloat val = bf;  
00604     // val.makeExact();    // val is exact
00605 
00606     // newton iteration
00607     for (int i=0; i<n; i++) {
00609       // Filtered Eval
00611       BigFloat ff = seq[1].evalExactSign(val, 3*ffuMSB); //3 is a slight hack
00612       ffuMSB = ff.uMSB();
00613       //ff is guaranteed to have the correct sign as the exact evaluation.
00615 
00616       if (ff == 0) {
00617         NEWTON_DIV_BY_ZERO = true;
00618         del = 0;
00619         core_error("Zero divisor in Newton Iteration",
00620                 __FILE__, __LINE__, false);
00621         return 0;
00622       }
00623 
00625       // Filtered Eval
00627       BigFloat f= seq[0].evalExactSign(val, 3*fuMSB); //3 is a slight hack
00628       fuMSB = f.uMSB();
00630 
00631       if (f == 0) {
00632         NEWTON_DIV_BY_ZERO = false;
00633         del = 0;    // Indicates that we have reached the exact root
00634                     //    This is because eval(val) is exact!!!
00635         return val; // val is the exact root, before the last iteration
00636       }
00637       del = f/ff; // But the accuracy of "f/ff" must be controllable
00638                     // by the caller...
00639       err = del.err();
00640       del.makeExact(); // makeExact() is necessary
00641       val -= del;
00642       // val.makeExact();  // -- unnecessary...
00643     }
00644     return val;
00645   }//newtonIterN
00646 
00647   //Another version of newtonIterN which does not return the error 
00648   //and passing the uMSB as arguments; it is easier for the user to call
00649   //this.
00650   BigFloat newtonIterN(long n, const BigFloat& bf, BigFloat& del){
00651     unsigned long err;
00652     extLong fuMSB=0, ffuMSB=0;
00653     return newtonIterN(n, bf, del, err, fuMSB, ffuMSB);
00654   }
00655 
00656   // v = newtonIterE(prec, bf, del, fuMSB, ffuMSB)
00657   //
00658   //    return the value v which is obtained by Newton iteration
00659   //    until del.uMSB < -prec, starting from initial value of bf.
00660   //    Returned value is an exact BigFloat.
00661   //    We guarantee at least one Newton step (so del is defined).
00662   //
00663   //       The parameters fuMSB and ffuMSB are precision parameters for
00664   //       evaluating coefficients of f(x) and f'(x), used similarly
00665   //       as described above for newtonIterN(....)
00666   //
00667   //    Return by reference "del" (difference between returned val and value
00668   //       in the previous Newton iteration).  This "del" is an upper bound
00669   //       on the last (f/f')-value in Newton iteration.
00670   //
00671   //    IN particular, if v is in the Newton zone of a root z^*, then z^* is
00672   //       guaranteed to lie inside [v-del, v+del].
00673   //
00674   //    Note that this is dangerous unless you know that bf is already
00675   //       in the Newton zone.  So we use the global N_STOP_ITER to
00676   //       prevent infinite loop.
00677 
00678   BigFloat newtonIterE(int prec, const BigFloat& bf, BigFloat& del, 
00679         extLong& fuMSB, extLong& ffuMSB) {
00680     // usually, prec is positive
00681     int count = N_STOP_ITER; // upper bound on number of iterations
00682     int stepsize = 1;
00683     BigFloat val = bf;
00684     unsigned long err = 0;
00685 
00686     do {
00687       val = newtonIterN(stepsize, val, del, err, fuMSB, ffuMSB);
00688       count -= stepsize;
00689       stepsize++; // heuristic
00690     } while ((del != 0) && ((del.uMSB() >= -prec) && (count >0))) ;
00691 
00692     if (count == 0) core_error("newtonIterE: reached count=0",
00693                         __FILE__, __LINE__, true);
00694     del = BigFloat(core_abs(del.m()), err, del.exp() );
00695     del.makeCeilExact();
00696     return val;
00697   }
00698 
00699   //Another version of newtonIterE which avoids passing the uMSB's.
00700   BigFloat newtonIterE(int prec, const BigFloat& bf, BigFloat& del){
00701     extLong fuMSB=0, ffuMSB=0;
00702     return newtonIterE(prec, bf, del, fuMSB, ffuMSB);
00703   }
00704   // A Smale bound which is an \'a posteriori condition. Applying 
00705   // Newton iteration to any point z satisfying this condition we are 
00706   // sure to converge to the nearest root in a certain interval of z.
00707   // The condition is for all k >= 2,
00708   //    | \frac{p^(k)(z)}{k!p'(z)} |^{1\(k-1)} < 1/8 * |\frac{p'(z)}{p(z)}|
00709   // Note: code below has been streamlined (Chee)
00710   /*
00711     bool smaleBound(const Polynomial<NT> * p, BigFloat z){
00712     int deg = p[0].getTrueDegree();
00713     BigFloat max, temp, temp1, temp2;
00714     temp2 = p[1].eval(z);
00715     temp = core_abs(temp2/p[0].eval(z))/8;
00716     BigInt fact_k = 2;
00717     for(int k = 2; k <= deg; k++){
00718       temp1 = core_abs(p[k].eval(z)/(fact_k*temp2)); 
00719       if(k-1 == 2)
00720         temp1 = sqrt(temp1);
00721       else
00722         temp1 = root(temp1, k-1);
00723       if(temp1 >= temp) return false; 
00724     }
00725     return true;
00726     }
00727    */
00728 
00729   //An easily computable Smale's point estimate for Newton as compared to the
00730   //one above. The criterion is
00731   //
00732   // ||f||_{\infty} * \frac{|f(z)|}{|f'(z)|^2} 
00733   //                * \frac{\phi'(|z|)^2}{\phi(|z|)}  < 0.03
00734   // where
00735   //           \phi(r) = \sum_{i=0}{m}r^i,
00736   //           m = deg(f)
00737   //
00738   //It is given as Theorem B in [Smale86].
00739   //Reference:- Chapter 8 in Complexity and Real Computation, by
00740   //            Blum, Cucker, Shub and Smale
00741   //
00742   //For our implementation we calculate an upper bound on
00743   //the second fraction in the inequality above.  For r>0,
00744   //
00745   //    \phi'(r)^2     m^2 (r^m + 1)^2
00746   //     ---------  <  -------------------          (1)
00747   //    \phi(r)        (r-1) (r^{m+1} - 1)
00748   //
00749   // Alternatively, we have
00750   // 
00751   //    \phi'(r)^2     (mr^{m+1} + 1)^2
00752   //     ---------  <  -------------------          (2)
00753   //    \phi(r)        (r-1)^3 (r^{m+1} - 1)
00754   //
00755   // The first bound is better when r > 1.
00756   // The second bound is better when r << 1.
00757   // Both bounds (1) and (2) assumes r is not equal to 1.
00758   // When r=1, the exact value is
00759   //
00760   //    \phi'(r)^2     m^2 (m + 1)
00761   //     ---------  =  -----------                  (3)
00762   //    \phi(r)            4
00763   // 
00764   // REMARK: smaleBoundTest(z) actually computes an upper bound
00765   //    on alpha(f,z), and compares it to 0.02 (then our theory
00766   //    says that z is a robust approximate zero).
00767   //
00768   bool smaleBoundTest(const BigFloat& z){
00769     assert(z.isExact());   // the bound only makes sense for exact z
00770 
00771 #ifdef CORE_DEBUG
00772     std::cout <<"Computing Smale's bound = " <<  std::endl;
00773 #endif
00774 
00775     if(seq[0].evalExactSign(z) == 0)// Reached the exact root.
00776       return true;
00777 
00778     BigFloat fprime = core_abs(seq[1].evalExactSign(z));
00779     fprime.makeFloorExact();
00780     if (fprime == 0) return false;  // z is a critical value!
00781     BigFloat temp =        // evalExactSign(z) may have error.
00782       core_abs(seq[0].evalExactSign(z));
00783     temp = (temp.makeCeilExact()/power(fprime, 2)).makeCeilExact();
00784     temp = temp*seq[0].height();  // remains exact
00785     //Thus, temp >=  ||f||_{\infty} |\frac{f(z)}{f'(z)^2}|
00786 
00787     int m = seq[0].getTrueDegree();    
00788     BigFloat x = core_abs(z);
00789     if (x==1)   // special case, using (3)
00790             return (temp * BigFloat(m*m*(m+1)).div2().div2() < 0.02);
00791 
00792     BigFloat temp1;
00793     if (x>1) { // use formula (1)
00794       temp1 = power(m* (power(x, m)+1), 2);          // m^2*(x^m + 1)^2
00795       temp1 /= ((x - 1)*(power(x, m+1) - 1));        // formula (1)
00796     } else {  // use formula (2)
00797       temp1 = power(m*(power(x, m+1) +1), 2);        // (m*x^{m+1} + 1)^2
00798       temp1 /= (power(x - 1,3)*(power(x, m+1) -1));  // formula (2)
00799     }
00800 
00801 #ifdef CORE_DEBUG
00802     std::cout <<"Value returned by Smale bound = " << temp * temp1.makeCeilExact() << std::endl;
00803 #endif
00804 
00805     if(temp * temp1.makeCeilExact() < 0.03)          // make temp1 exact!
00806       return true;
00807     else
00808       return false;
00809   }//smaleBoundTest
00810 
00811 
00812   // yapsBound(p)
00813   //    returns a bound on size of isolating interval of polynomial p
00814   //    which is guaranteed to be in the Newton Zone.
00815   //    N.B. p MUST be square-free
00816   //
00817   //   Reference: Theorem 6.37, p.184 of Yap's book
00818   //       [Fundamental Problems of Algorithmic Algebra]
00819 
00820   BigFloat yapsBound(const Polynomial<NT> & p) const {
00821     int deg = p.getTrueDegree();
00822     return  1/(1 + pow(BigFloat(deg), 3*deg+9)
00823                *pow(BigFloat(2+p.height()),6*deg));
00824   }
00825 
00826   //newtonRefine(J, a) 
00827   //
00828   //    ASSERT(J is an isolating interval for some root x^*)
00829   //
00830   //    ASSERT(J.first and J.second are exact BigFloats)
00831   //
00832   //    Otherwise, the boundaries of the interval are not well defined.
00833   //    We will return a refined interval with exact endpoints,
00834   //    still called J, containing x^* and
00835   //
00836   //                    |J| < 2^{-a}.
00837   //
00838   //    TO DO: write a version of newtonRefine(J, a, sign) where
00839   //    sign=J.first.sign(), since you may already know the sign
00840   //    of J.first.  This will skip the preliminary stuff in the
00841   //    current version.
00842   //
00843   BFInterval newtonRefine(BFInterval &J, int aprec) {
00844 
00845 #ifdef CORE_DEBUG_NEWTON
00846 std::cout << "In newtonRefine, input J=" << J.first
00847         << ", " << J.second << " precision = " << aprec << std::endl;
00848 #endif
00849 
00850     if (len <= 0) return J;   // Nothing to do!  User must
00851                                // check this possibility!
00852       
00853 
00854     if((J.second - J.first).uMSB() < -aprec){
00855       return (J);
00856     }
00857     int xSign, leftSign, rightSign;
00858 
00859     leftSign = sign(seq[0].evalExactSign(J.first));
00860     if (leftSign == 0) {
00861       J.second = J.first;
00862       return J;
00863     }
00864 
00865     rightSign = sign(seq[0].evalExactSign(J.second));
00866     if (rightSign == 0) {
00867       J.first = J.second;
00868       return J;
00869     }
00870 
00871     assert( leftSign * rightSign < 0 );
00872 
00873     //N is number of times Newton is called without checking
00874     // whether the result is still in the interval or not
00875     #define NO_STEPS 2
00876     // REMARK: NO_STEPS=1 is incorrect, as it may lead to
00877     //      linear convergence (it is somewhat similar to Dekker-Brent's
00878     //      idea of guaranteeing that bisection does not
00879     //      destroy the superlinear convergence of Newton.
00880     int N = NO_STEPS;
00881 
00882     BigFloat x, del, olddel, temp;
00883     unsigned long err;
00884     BigFloat yap = yapsBound(seq[0]);
00885 
00886     BigFloat old_width = J.second - J.first;
00887     x = (J.second + J.first).div2();
00888 
00889     // initial estimate for the evaluation of filter to floating point precision
00890     extLong fuMSB=54, ffuMSB=54;
00891 
00892     //MAIN WHILE LOOP. We ensure that J always contains the root
00893 
00894     while ( !smaleBoundTest(x) && 
00895             (J.second - J.first) > yap &&
00896            (J.second - J.first).uMSB() >= -aprec) {
00897       x = newtonIterN(N, x, del, err, fuMSB, ffuMSB);
00898       if ((del == 0)&&(NEWTON_DIV_BY_ZERO == false)) {  // reached exact root!
00899         J.first = J.second = x;
00900         return J;
00901       }
00902 
00903       BigFloat left(x), right(x);
00904       if (del>0) {
00905         left -= del; right += del;
00906       } else {
00907         left += del; right -= del;
00908       }
00909 
00910       // update interval
00911       if ((left > J.first)&&(left <J.second)) {
00912           int lSign = sign(seq[0].evalExactSign(left));
00913           if (lSign == leftSign)  // leftSign=sign of J.first
00914             J.first = left;
00915           else if (lSign == 0) {
00916             J.first = J.second = left;
00917             return J;
00918           } else {
00919             J.second = left;
00920           }     
00921       }
00922       if ((right < J.second)&&(right >J.first)) {
00923           int rSign = sign(seq[0].evalExactSign(right));
00924           if (rSign == rightSign)
00925             J.second = right;
00926           else if (rSign == 0) {
00927             J.first = J.second = right;
00928             return J;
00929           } else {
00930             J.first = right;
00931           }
00932       }
00933       BigFloat width = J.second - J.first;
00934 
00935       //left and right are exact, since x is exact.
00936       if (width*2 <= old_width && !NEWTON_DIV_BY_ZERO) {
00937                                   // we can get a better root:
00938 
00939         // No, it is not necessary to update x to
00940         // the midpoint of the new interval J.
00941         // REASON: basically, it is hard to be smarter than Newton's method!
00942         // Newton might bring x very close to one endpoint, but it can be
00943         // because the root is near there!  In any case,
00944         // by setting x to the center of J, you only gain at most
00945         // one bit of accuracy, but you stand to loose an
00946         // arbitrary amount of bits of accuracy if you are unlucky!
00947         // So I will comment out the next line.  --Chee (Aug 9, 2004).
00948         // 
00949         // x = (J.second + J.first).div2();
00950         if (J.first > x || J.second < x)
00951           x = (J.second + J.first).div2();
00952 
00953         old_width = width; // update width
00954 
00955         N ++;      // be more confident or aggressive
00956                    //  (perhaps we should double N)
00957                    //
00958       } else {// Either NEWTON_DIV_BY_ZERO=true
00959               // Or width has not decreased sufficiently
00960         x = (J.second + J.first).div2();//Reset x to midpoint since it was the
00961                                         //value from a failed Newton step
00962         xSign = sign(seq[0].evalExactSign(x));
00963         if (xSign == rightSign) {
00964           J.second = x;
00965         } else if (xSign == leftSign) {
00966           J.first = x;
00967         } else { // xSign must be 0
00968           J.first = J.second = x; return J;
00969         }
00970         x = (J.second + J.first).div2();
00971 
00972         old_width = old_width.div2(); // update width
00973         
00974         // reduce value of N:
00975         N = core_max(N-1, NO_STEPS);   // N must be at least NO_STEPS
00976       }
00977     }//MAIN WHILE LOOP
00978 
00979     if((J.second - J.first).uMSB() >= -aprec){ // The interval J
00980                     //still hasn't reached the required precision.
00981                     //But we know the current value of x (call it x_0)
00982                     //is in the strong Newton basin of the
00983                     //root x^* (because it passes Smale's bound)
00985       //Both x_0 and the root x^* are in the interval J.
00986       //Let NB(x^*) be the strong Newton basin of x^*.  By definition,
00987       //x_0 is in NB(x^*) means that:
00988       //
00989       //    x_0 is in NB(x^*) iff |x_n-x^*| \le 2^{-2^{n}+1} |x_0-x^*|
00990       //    
00991       // where x_n is the n-th iterate of Newton.  
00992       //    
00993       //  LEMMA 1: if x_0  \in NB(x^*) then 
00994       //               |x_0 - x^*| <= 2|del|      (*)
00995       //  and
00996       //               |x_1 - x^*| <= |del|       (**)
00997       //
00998       //  where del = -f(x_0)/f'(x_0) and x_1 = x_0 + del
00999       //Proof:
01000       //Since x_0 is in the strong Newton basin, we have
01001       //         |x_1-x^*| <= |x_0-x^*|/2.        (***)
01002       //The bound (*) is equivalent to
01003       //         |x_0-x^*|/2 <= |del|.
01004       //This is equivalent to
01005       //         |x_0-x^*| - |del| <= |x_0-x^*|/2,
01006       //which follows from
01007       //         |x_0-x^* + del| <= |x_0-x^*|/2,
01008       //which is equivalent to (***).  
01009       //The bound (**) follows from (*) and (***).
01010       //QED
01011       //
01012       //  COMMENT: the above derivation refers to the exact values,
01013       //  but what we compute is X_1 where X_1 is an approximation to
01014       //  x_1.  However, let us write X_1 = x_0 - DEL, where DEL is
01015       //  an approximation to del.  
01016       //
01017       //  LEMMA 2:  If |DEL| >= |del|,
01018       //  then (**) holds with X_1 and DEL in place of x_1 and del.
01019       //  
01020       //  NOTE: We implemented this DEL in newtonIterE.   
01021 
01022 #ifdef CORE_DEBUG
01023       std::cout << "Inside Newton Refine: Refining Part " << std::endl;
01024 
01025       if((J.second - J.first) > yap)
01026         std::cout << "Smales Bound satisfied " << std::endl;
01027       else
01028         std::cout << "Chees Bound satisfied " << std::endl;
01029 #endif
01030       xSign = sign(seq[0].evalExactSign(x));
01031       if(xSign == 0){
01032         J.first = J.second = x; 
01033         return J; // missing before!
01034       }
01035 
01036       //int k = clLg((-(J.second - J.first).lMSB() + aprec).asLong());
01037       x = newtonIterE(aprec, x, del, fuMSB, ffuMSB);
01038       xSign = sign(seq[0].evalExactSign(x));
01039 
01040       if(xSign == leftSign){//Root is greater than x
01041         J.first = x;
01042         J.second = x + del;  // justified by Lemma 2 above
01043       }else if(xSign == rightSign){//Root is less than x
01044         J.first = x - del;   // justified by Lemma 2 above
01045         J.second = x ;
01046       }else{//x is the root
01047         J.first = J.second = x;
01048       }
01049     }
01050 
01051 
01052 
01053 #ifdef CORE_DEBUG
01054     std::cout << " Returning from Newton Refine: J.first = " << J.first
01055               << " J.second = " << J.second << " aprec = " << aprec
01056               << " Sign at the interval endpoints = " 
01057               << sign(seq[0].evalExactSign(J.first))
01058               << " : " << sign(seq[0].evalExactSign(J.second)) << " Err at starting = " 
01059               << J.first.err() << " Err at end = " << J.second.err() << std::endl;
01060 #endif
01061 
01062     assert( (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) <= 0) );
01063 
01064 #ifdef CORE_DEBUG_NEWTON
01065     if (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) > 0)
01066       std::cout <<" ERROR! Root is not in the Interval " << std::endl;
01067     if(J.second - J.first >  BigFloat(1).exp2(-aprec))
01068       std::cout << "ERROR! Newton Refine failed to achieve the desired precision" << std::endl;
01069 #endif
01070 
01071       return(J);
01072  }//End of newton refine
01073 
01074 };// Sturm class
01075 
01076 // ==================================================
01077 // Static initialization
01078 // ==================================================
01079 template <class NT>
01080 int Sturm<NT>:: N_STOP_ITER = 10000;   // stop IterE after this many loops
01081 // Reset this as needed
01082 
01083 // ==================================================
01084 // Helper Functions 
01085 // ==================================================
01086 
01087 // isZeroIn(I):
01088 //          returns true iff 0 is in the closed interval I
01089 CORE_INLINE bool isZeroIn(BFInterval I) {
01090         return ((I.first <= 0.0) && (I.second >= 0.0));
01091 }
01092 
01094 //  DIAGNOSTIC TOOLS
01096 // Polynomial tester:   P is polynomial to be tested
01097 //          prec is the bit precision for root isolation
01098 //          n is the number of roots predicted
01099 
01100 template<class NT>
01101 CORE_INLINE void testSturm(const Polynomial<NT>&P, int prec, int n = -1) {
01102   Sturm<NT> Ss (P);
01103   BFVecInterval v;
01104   Ss.refineAllRoots(v, prec);
01105   std::cout << "   Number of roots is " << v.size() <<std::endl;
01106   if ((n >= 0) & (v.size() == (unsigned)n))
01107     std::cout << " (CORRECT!)" << std::endl;
01108   else
01109     std::cout << " (ERROR!) " << std::endl;
01110   int i = 0;
01111   for (BFVecInterval::const_iterator it = v.begin();
01112        it != v.end(); ++it) {
01113     std::cout << ++i << "th Root is in ["
01114     << it->first << " ; " << it->second << "]" << std::endl;
01115   }
01116 }// testSturm
01117 
01118 // testNewtonSturm( Poly, aprec, n)
01119 //   will run the Newton-Sturm refinement to isolate the roots of Poly
01120 //         until absolute precision aprec.
01121 //   n is the predicated number of roots
01122 //      (will print an error message if n is wrong)
01123 template<class NT>
01124 CORE_INLINE void testNewtonSturm(const Polynomial<NT>&P, int prec, int n = -1) {
01125   Sturm<NT> Ss (P);
01126   BFVecInterval v;
01127   Ss.newtonRefineAllRoots(v, prec);
01128   std::cout << "   Number of roots is " << v.size();
01129   if ((n >= 0) & (v.size() == (unsigned)n))
01130     std::cout << " (CORRECT!)" << std::endl;
01131   else
01132     std::cout << " (ERROR!) " << std::endl;
01133 
01134   int i = 0;
01135   for (BFVecInterval::iterator it = v.begin();
01136        it != v.end(); ++it) {
01137     std::cout << ++i << "th Root is in ["
01138     << it->first << " ; " << it->second << "]" << std::endl;
01139     if(it->second - it->first <= (1/power(BigFloat(2), prec)))
01140       std::cout << " (CORRECT!) Precision attained" << std::endl;
01141     else
01142       std::cout << " (ERROR!) Precision not attained" << std::endl;
01143   }
01144 }// testNewtonSturm
01145 
01146 CORE_END_NAMESPACE
01147 
01148 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines