8 #ifndef realroot_UPOL_BOUND_H
9 #define realroot_UPOL_BOUND_H
26 template<
typename T>
inline T
abs(
const T& x) {
return (x < 0 ? -x : x); }
57 template<
class C>
struct NISP
67 template <
typename POLY>
static
76 unsigned n = p.size();
80 while ( p[--i] == 0 );
85 while ( p[i] > 0 && i < n ) i++;
86 if ( i == n )
return 0;
88 for (
unsigned k = i+1; k < n; k ++ )
89 if ( p[k] > 0 ) sum += p[k];
91 for (
unsigned k = i; k < n; k ++ )
94 { rational tmp = -p[k]/
sum;
if ( tmp >
max )
max = tmp; }
102 while ( p[i] < 0 && i < n ) i++;
103 if ( i == n )
return 0;
104 for (
unsigned k = i+1; k < n; k ++ )
105 if ( p[k] < 0 ) sum += p[k];
106 for (
unsigned k = i; k < n; k ++ )
107 if ( p[k] > 0 ) { rational tmp = -p[k]/
sum;
if ( tmp >
max )
max = tmp; }
115 template <
typename POLY>
static
138 template <
typename POLY>
static
142 for (
unsigned i = 1; i < p.size(); i += 2 )
149 template <
typename T >
150 struct abs_max :
public std::unary_function<T, void>
157 if (temp >
max)
max = temp;
187 template<
class Poly>
static
191 typedef typename Poly::value_type RT;
199 C res=
C(M.
max/an) +
C(1);
219 for (
int i = 1; i <= deg; ++i) {
220 if (
sign( f[i]) *
sign( f[0]) < 0 ) {
226 bool bound_set =
false;
229 for (
int i = 1; i <= deg; ++i) {
230 if (
sign( f[i]) *
sign( f[0]) < 0 ) {
231 long bai =
bit_size( RT( l * f[i])) - 1;
232 long p = bai - ba0 - 1 ;
244 if ( (bound_set ==
false) || (K < rq) ) {
250 if ( K < 0 ) {
return pow2<RT>(
abs( K) );}
261 typedef typename Poly::value_type RT;
266 for (
int i = 1; i <= deg; ++i) {
267 if (
sign( f[i]) *
sign( f[0]) < 0 ) {
273 bool bound_set =
false;
276 for (
int i = 1; i <= deg; ++i) {
277 if (
sign( f[i]) *
sign( f[0]) < 0 ) {
278 long bai =
bit_size( RT( l * f[i])) - 1;
279 long p = bai - ba0 - 1 ;
291 if ( (bound_set ==
false) || (K < rq) ) {
297 if ( K < 0 ) {
abs( K);}
308 typedef typename Poly::value_type coeff_t;
312 for(
unsigned i=0;i< p.size(); i++) M =
std::max(M, coeff_t(
abs(p[i])));
318 double res=as<double>(coeff_t(M/an)) + 1;
324 template <
typename FT,
typename POLY>
331 template <
typename FT,
typename POLY>
337 template <
typename FT,
typename POLY>
361 template <
typename Poly >
static
369 bool localBoundSet =
false, globalBoundSet =
false;
373 for(
int i= deg; i > 0; i--){
375 if(
sign(f[i]) * s < 0){
376 for(
int k=i-1; k >= 0; k--){
377 if(
sign(f[k]) * s > 0){
380 if(!localBoundSet || lB > q + 2){
381 localBoundSet =
true;
386 localBoundSet =
false;
387 if(!globalBoundSet || gB < lB){
388 globalBoundSet =
true;
394 if ( gB+1 < 0 )
return pow2<RT>(
abs( gB+1) );
412 template <
typename Poly >
static
418 typedef std::pair<RT, int> Coeff_deg;
426 int posCounter=0, negCounter=0, nPosCounter=0;
430 std::queue< Coeff_deg > Neg;
432 std::stack< Coeff_deg > Pos;
437 while(posCounter !=
int(deg+1)){
443 Pos.push(Coeff_deg(RT(f[posCounter]), posCounter));
444 for(
unsigned i=posCounter + 1;i <= deg; i++){
445 if(
sign(f[i]) * s < 0){
448 if(
sign(f[i]) *s > 0){
451 Pos.push(Coeff_deg(RT(f[i]), i));
454 if(negCounter == -1){
457 return pow2<RT>(
abs(B) );
463 Neg.push(Coeff_deg(RT(f[negCounter]), negCounter));
464 for(
unsigned i=negCounter + 1;i <= deg; i++){
465 if(
sign(f[i]) * s > 0){
466 nPosCounter=i;
break;
468 if(
sign(f[i]) *s < 0)
469 Neg.push(Coeff_deg(RT(f[i]), i));
478 l1 = Neg.size(); l2 = Pos.size();
483 for(
int i=0; i < l1; i++){
484 T1= Neg.front(); Neg.pop();
486 T2=Pos.top();Pos.pop();
491 q = temp/(T1.second - T2.second);
494 if(!boundSet || B < q + 2){
505 T2= Pos.top();Pos.pop();
506 for(
int i=0; i <= l1-l2; i++){
507 T1= Neg.front(); Neg.pop();
509 q = temp/(T1.second-T2.second);
510 if(!boundSet || B < q + 2){
517 for(
int i=0; i < l1; i++){
518 T1= Neg.front(); Neg.pop();
522 q = temp/(T1.second - T2.second);
523 if(!boundSet || B < q + 2){
530 posCounter = nPosCounter; Neg.empty(); Pos.empty();
533 if ( B < 0 )
return pow2<RT>(
abs(B) );
538 template <
typename Poly >
static
544 typedef std::pair<RT, int> Coeff_deg;
552 int posCounter=0, negCounter=0, nPosCounter=0;
556 std::queue< Coeff_deg > Neg;
558 std::stack< Coeff_deg > Pos;
563 while(posCounter !=
int(deg+1)){
569 Pos.push(Coeff_deg(RT(f[posCounter]), posCounter));
570 for(
unsigned i=posCounter + 1;i <= deg; i++){
571 if(
sign(f[i]) * s < 0){
574 if(
sign(f[i]) *s > 0){
577 Pos.push(Coeff_deg(RT(f[i]), i));
580 if(negCounter == -1){
582 if ( B < 0 )
return abs( B);
587 Neg.push(Coeff_deg(RT(f[negCounter]), negCounter));
588 for(
unsigned i=negCounter + 1;i <= deg; i++){
589 if(
sign(f[i]) * s > 0){
590 nPosCounter=i;
break;
592 if(
sign(f[i]) *s < 0)
593 Neg.push(Coeff_deg(RT(f[i]), i));
602 l1 = Neg.size(); l2 = Pos.size();
607 for(
int i=0; i < l1; i++){
608 T1= Neg.front(); Neg.pop();
610 T2=Pos.top();Pos.pop();
615 q = temp/(T1.second - T2.second);
618 if(!boundSet || B < q + 2){
629 T2= Pos.top();Pos.pop();
630 for(
int i=0; i <= l1-l2; i++){
631 T1= Neg.front(); Neg.pop();
633 q = temp/(T1.second-T2.second);
634 if(!boundSet || B < q + 2){
641 for(
int i=0; i < l1; i++){
642 T1= Neg.front(); Neg.pop();
646 q = temp/(T1.second - T2.second);
647 if(!boundSet || B < q + 2){
654 posCounter = nPosCounter; Neg.empty(); Pos.empty();
657 if ( B < 0 )
return abs( B);
666 #endif // realroot_UPOL_BOUND_H
T pow2(int i)
Definition: univariate_bounds.hpp:31
Cauchy bound.
Definition: univariate_bounds.hpp:163
static C lower_bound(const POLY &p)
Definition: univariate_bounds.hpp:116
Definition: univariate_bounds.hpp:409
dynamic_exp< E >::degree_t degree(const dynamic_exp< E > &t)
Definition: dynamicexp.hpp:191
R::value_type lcoeff(const R &p)
Definition: univariate.hpp:357
int degree(const R &p)
Definition: univariate.hpp:194
FT bound_root(const POLY &p, const Cauchy< FT > &m)
Definition: univariate_bounds.hpp:325
abs_max()
Definition: univariate_bounds.hpp:152
T max
Definition: univariate_bounds.hpp:159
Definition: univariate_bounds.hpp:359
void reverse(Poly &R, const Poly &P)
Definition: contfrac_intervaldata.hpp:139
static C upper_bound(const POLY &p)
Computes the "Negative Inverse Sum" bound for the positive roots.
Definition: univariate_bounds.hpp:68
C lower_bound(const Poly &f) const
Computes the Cauchy lower bound on the first positive root as a power of 2.
Definition: univariate_bounds.hpp:211
void reverse(R &p, typename R::size_type n)
Definition: univariate.hpp:590
kernel_rationalof< typename kernelof< X >::T, _X, typename is_extended< X >::T >::T T
Definition: texp_rationalof.hpp:21
Definition: rounding_mode.hpp:71
static RT lower_bound(const Poly &f)
Definition: univariate_bounds.hpp:413
Definition: univariate_bounds.hpp:150
real_t sum(real_t const *const src, unsigned sz, int st=1)
Definition: loops_vctops.hpp:197
ZZ numerator(const QQ &a)
Definition: GMPXX.hpp:95
long int bit_size(const ZZ &z)
Definition: GMPXX.hpp:32
void operator()(const T &x)
Definition: univariate_bounds.hpp:153
FT min_bound(const POLY &p, Cauchy< FT >)
Definition: univariate_bounds.hpp:339
Negative Inverse Sum bound for negative roots.
Definition: univariate_bounds.hpp:129
void abs(Interval< C, r > &x, const Interval< C, r > &a)
Definition: Interval_fcts.hpp:185
long lower_power_2(const Poly &f) const
Definition: univariate_bounds.hpp:257
static long lower_power_2(const Poly &f)
Definition: univariate_bounds.hpp:539
ZZ denominator(const QQ &a)
Definition: GMPXX.hpp:96
static FT upper_bound(const POLY &p)
Definition: univariate_bounds.hpp:139
FT max_bound(const POLY &p, const Cauchy< FT > &m)
Definition: univariate_bounds.hpp:332
static C upper_bound(const Poly &p)
Computes the Cauchy root bound.
Definition: univariate_bounds.hpp:188
double C
Definition: solver_mv_fatarcs.cpp:16
int sign(const QQ &a)
Definition: GMP.hpp:60
Interval< T, r > max(const Interval< T, r > &a, const Interval< T, r > &b)
Definition: Interval_fcts.hpp:135
Negative Inverse Sum bound for positive roots.
Definition: univariate_bounds.hpp:57
static RT lower_bound(const Poly &f)
Definition: univariate_bounds.hpp:362
#define assert(expr, msg)
Definition: shared_object.hpp:57