#include <univariate_bounds.hpp>
A 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.
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 }