AkritasBound< RT > Struct Template Reference

#include <univariate_bounds.hpp>

List of all members.

Static Public Member Functions


Detailed Description

template<class RT>
struct mmx::AkritasBound< RT >

A $\Theta(n)$ time algorithm for computing a lower bound. It is based upon an upper bound by Akritas et al. that returns a value some what better than Kioustelidis' bound, but is not better than the bound by Hong. The idea is to pair the positive and negative coefficients in a certain manner. Assume the constant coefficient is not zero and there is at least one sign variation in the coefficients.

Definition at line 407 of file univariate_bounds.hpp.


Member Function Documentation

static RT lower_bound ( const Poly &  f  )  [inline, static]

Definition at line 411 of file univariate_bounds.hpp.

References mmx::abs(), mmx::bit_size(), mmx::degree(), mmx::univariate::degree(), and mmx::sign().

Referenced by solver_cffirst< Real, POL >::all_roots(), and solver_cffirst< Real, POL >::first_root().

00412     {
00413       using univariate::degree;
00414 
00415       //    std::cout <<"Poly is " << f << std::endl;
00416       typedef std::pair<RT, int>        Coeff_deg;
00417       Coeff_deg T1, T2;
00418 
00419       unsigned deg=degree(f);
00420       int s=sign(f[0]);//, len;
00421       long B=0;// The logarithm of the bound to be returned
00422       bool boundSet=false;// The bound is not set initially
00423       long temp,q;
00424       int posCounter=0, negCounter=0, nPosCounter=0;
00425       // The coefficients from posCounter to negCounter-1 have the same sign
00426       // as f[0]; the coefficients from negCounter to nPosCounter-1 have the
00427       // opposite sign of f[0].
00428       std::queue< Coeff_deg > Neg;// Queue that stores the negative (between
00429       // negCounter and nPosCounter) coefficients.
00430       std::stack< Coeff_deg > Pos; // Stack that stores the positive (between
00431       // posCounter and negCounter) coefficients.
00432 
00433       int l1, l2;// size of the above two queues
00434 
00435       while(posCounter != int(deg+1)){
00436         // Find the first change in sign larger than posCounter and assign negCounter
00437         // to this value. If no such sign variation occurs then
00438         // set negCounter to -1.
00439         negCounter = -1;// By default there is no such coefficient
00440         //Pos.push(Coeff_deg(RT(f[posCounter]), posCounter));// Push the first "positive" coefficient
00441         Pos.push(Coeff_deg(RT(f[posCounter]), posCounter));// Push the first "positive" coefficient
00442         for(unsigned i=posCounter + 1;i <= deg; i++){
00443           if(sign(f[i]) * s < 0){
00444             negCounter=i; break;
00445           }
00446           if(sign(f[i]) *s > 0){// Store the list of "positive" coefficients
00447             //Pos.push(Coeff_deg(RT(f[i]), i));// Note the actual degree is deg-i, but
00448             // later we subtract degrees so we store only i
00449             Pos.push(Coeff_deg(RT(f[i]), i));
00450           }
00451         }
00452         if(negCounter == -1){
00453           //    std::cout <<"Returning the lower bound " << B << std::endl;
00454           if ( B < 0 )
00455             return pow2<RT>( abs(B) );
00456           else
00457             return 0;
00458         }
00459         // Now find the next coefficient that has the same sign as f[0].
00460         nPosCounter = deg+1;// By default this is deg+1
00461         Neg.push(Coeff_deg(RT(f[negCounter]), negCounter));
00462         for(unsigned i=negCounter + 1;i <= deg; i++){
00463           if(sign(f[i]) * s > 0){
00464             nPosCounter=i; break;
00465           }
00466           if(sign(f[i]) *s < 0)// Store the list of "negative" coefficients
00467             Neg.push(Coeff_deg(RT(f[i]), i));
00468         }
00469 
00470         //      std::cout <<" Assigning to the queues done" << std::endl;
00471         // Start computing the bound
00472         // If the number of "positive" terms from posCounter to negCounter -1 are
00473         // greater or equal to  the number of "negative" terms from negCounter to
00474         // nPosCounter -1 then we have the straightforward matching of "negative"
00475         // coefficients with the "positive" ones.
00476         l1 = Neg.size(); l2 = Pos.size();
00477         if(l2 >= l1){
00478           //    std::cout <<"Pos length " << l2 << " greater than Neg length "
00479           //              << l1 << std::endl;
00480           // or equally negCounter - posCounter >= nPosCounter - negCounter
00481           for(int i=0; i < l1; i++){
00482             T1= Neg.front(); Neg.pop();
00483             //T2= Pos.front(); Pos.pop();
00484             T2=Pos.top();Pos.pop();
00485             //    std::cout <<"Neg coeff " << T1.first << " Pos coeff " << T2.first
00486             //              << " Deg difference " << T1.second - T2.second
00487             //              << std::endl;
00488             temp = bit_size( T1.first ) - bit_size( T2.first ) - 1;
00489             q = temp/(T1.second - T2.second);
00490             //    std::cout << "Difference between logs " << temp
00491             //              << " temporary bound value " << B << std::endl;
00492             if(!boundSet || B < q + 2){// Choose the maximum
00493               boundSet = true;
00494               B = q+2;
00495             }
00496           }
00497         }else{//Else split the coefficient f[posCounter] to compensate for
00498           // the paucity of "positive" terms and then do the matching.
00499           //    std::cout <<" Pos length "<< l2 << " smaller than Neg length "
00500           //              << l1 << std::endl;
00501 
00502           //T2=Pos.front(); Pos.pop();
00503           T2= Pos.top();Pos.pop();
00504           for(int i=0; i <= l1-l2; i++){
00505             T1= Neg.front(); Neg.pop();
00506             temp = bit_size( T1.first ) - bit_size( T2.first ) + bit_size(RT(l1-l2+1)) - 1;
00507             q = temp/(T1.second-T2.second);
00508             if(!boundSet || B < q + 2){// Choose the maximum
00509               boundSet = true;
00510               B = q+2;
00511             }
00512           }
00513           //    std::cout <<" Splitting the leading coefficient done" << std::endl;
00514           l1 = Neg.size();// Now the size of Neg and Pos should be the same
00515           for(int i=0; i < l1; i++){
00516             T1= Neg.front(); Neg.pop();
00517             //T2= Pos.front(); Pos.pop();
00518             Pos.pop();
00519             temp = bit_size( T1.first ) - bit_size( T2.first ) - 1;
00520             q = temp/(T1.second - T2.second);
00521             if(!boundSet || B < q + 2){// Choose the maximum
00522               boundSet = true;
00523               B = q+2;
00524             }
00525           }
00526         }// end else
00527         //      std::cout <<" Matching the coefficients done" << std::endl;
00528         posCounter = nPosCounter; Neg.empty(); Pos.empty();
00529       }//end while
00530       //    std::cout <<"Returning the lower bound " << B << std::endl;
00531       if ( B < 0 ) return pow2<RT>( abs(B) );
00532       return 0;
00533     }

static long lower_power_2 ( const Poly &  f  )  [inline, static]

Definition at line 537 of file univariate_bounds.hpp.

References mmx::abs(), mmx::bit_size(), mmx::degree(), mmx::univariate::degree(), and mmx::sign().

00538       {
00539         using univariate::degree;
00540 
00541           //    std::cout <<"Poly is " << f << std::endl;
00542           typedef std::pair<RT, int>    Coeff_deg;
00543           Coeff_deg T1, T2;
00544 
00545           unsigned deg=degree(f);
00546           int s=sign(f[0]);//, len;
00547           long B=0;// The logarithm of the bound to be returned
00548           bool boundSet=false;// The bound is not set initially
00549           long temp,q;
00550           int posCounter=0, negCounter=0, nPosCounter=0;
00551           // The coefficients from posCounter to negCounter-1 have the same sign
00552           // as f[0]; the coefficients from negCounter to nPosCounter-1 have the
00553           // opposite sign of f[0].
00554           std::queue< Coeff_deg > Neg;// Queue that stores the negative (between
00555           // negCounter and nPosCounter) coefficients.
00556           std::stack< Coeff_deg > Pos; // Stack that stores the positive (between
00557           // posCounter and negCounter) coefficients.
00558 
00559           int l1, l2;// size of the above two queues
00560 
00561           while(posCounter != int(deg+1)){
00562               // Find the first change in sign larger than posCounter and assign negCounter
00563               // to this value. If no such sign variation occurs then
00564               // set negCounter to -1.
00565               negCounter = -1;// By default there is no such coefficient
00566               //Pos.push(Coeff_deg(RT(f[posCounter]), posCounter));// Push the first "positive" coefficient
00567               Pos.push(Coeff_deg(RT(f[posCounter]), posCounter));// Push the first "positive" coefficient
00568               for(unsigned i=posCounter + 1;i <= deg; i++){
00569                   if(sign(f[i]) * s < 0){
00570                       negCounter=i; break;
00571                   }
00572                   if(sign(f[i]) *s > 0){// Store the list of "positive" coefficients
00573                       //Pos.push(Coeff_deg(RT(f[i]), i));// Note the actual degree is deg-i, but
00574                       // later we subtract degrees so we store only i
00575                       Pos.push(Coeff_deg(RT(f[i]), i));
00576                   }
00577               }
00578               if(negCounter == -1){
00579                   //    std::cout <<"Returning the lower bound " << B << std::endl;
00580                   if ( B < 0 ) return abs( B);
00581                   else return -1;
00582               }
00583               // Now find the next coefficient that has the same sign as f[0].
00584               nPosCounter = deg+1;// By default this is deg+1
00585               Neg.push(Coeff_deg(RT(f[negCounter]), negCounter));
00586               for(unsigned i=negCounter + 1;i <= deg; i++){
00587                   if(sign(f[i]) * s > 0){
00588                       nPosCounter=i; break;
00589                   }
00590                   if(sign(f[i]) *s < 0)// Store the list of "negative" coefficients
00591                       Neg.push(Coeff_deg(RT(f[i]), i));
00592               }
00593 
00594               //      std::cout <<" Assigning to the queues done" << std::endl;
00595               // Start computing the bound
00596               // If the number of "positive" terms from posCounter to negCounter -1 are
00597               // greater or equal to  the number of "negative" terms from negCounter to
00598               // nPosCounter -1 then we have the straightforward matching of "negative"
00599               // coefficients with the "positive" ones.
00600               l1 = Neg.size(); l2 = Pos.size();
00601               if(l2 >= l1){
00602                   //    std::cout <<"Pos length " << l2 << " greater than Neg length "
00603                   //              << l1 << std::endl;
00604                   // or equally negCounter - posCounter >= nPosCounter - negCounter
00605                   for(int i=0; i < l1; i++){
00606                       T1= Neg.front(); Neg.pop();
00607                       //T2= Pos.front(); Pos.pop();
00608                       T2=Pos.top();Pos.pop();
00609                       //          std::cout <<"Neg coeff " << T1.first << " Pos coeff " << T2.first
00610                       //                    << " Deg difference " << T1.second - T2.second
00611                       //                    << std::endl;
00612                       temp = bit_size( T1.first ) - bit_size( T2.first ) - 1;
00613                       q = temp/(T1.second - T2.second);
00614                       //          std::cout << "Difference between logs " << temp
00615                       //                    << " temporary bound value " << B << std::endl;
00616                       if(!boundSet || B < q + 2){// Choose the maximum
00617                           boundSet = true;
00618                           B = q+2;
00619                       }
00620                   }
00621               }else{//Else split the coefficient f[posCounter] to compensate for
00622                   // the paucity of "positive" terms and then do the matching.
00623                   //    std::cout <<" Pos length "<< l2 << " smaller than Neg length "
00624                   //              << l1 << std::endl;
00625 
00626                   //T2=Pos.front(); Pos.pop();
00627                   T2= Pos.top();Pos.pop();
00628                   for(int i=0; i <= l1-l2; i++){
00629                       T1= Neg.front(); Neg.pop();
00630                       temp = bit_size( T1.first ) - bit_size( T2.first ) + bit_size(RT(l1-l2+1)) - 1;
00631                       q = temp/(T1.second-T2.second);
00632                       if(!boundSet || B < q + 2){// Choose the maximum
00633                           boundSet = true;
00634                           B = q+2;
00635                       }
00636                   }
00637                   //    std::cout <<" Splitting the leading coefficient done" << std::endl;
00638                   l1 = Neg.size();// Now the size of Neg and Pos should be the same
00639                   for(int i=0; i < l1; i++){
00640                       T1= Neg.front(); Neg.pop();
00641                       //T2= Pos.front(); Pos.pop();
00642                       Pos.pop();
00643                       temp = bit_size( T1.first ) - bit_size( T2.first ) - 1;
00644                       q = temp/(T1.second - T2.second);
00645                       if(!boundSet || B < q + 2){// Choose the maximum
00646                           boundSet = true;
00647                           B = q+2;
00648                       }
00649                   }
00650               }// end else
00651               //      std::cout <<" Matching the coefficients done" << std::endl;
00652               posCounter = nPosCounter; Neg.empty(); Pos.empty();
00653           }//end while
00654           //    std::cout <<"Returning the lower bound " << B << std::endl;
00655           if ( B < 0 ) return abs( B);
00656           else return -1;
00657 
00658       }


The documentation for this struct was generated from the following file:

Generated on 6 Dec 2012 for realroot by  doxygen 1.6.1