realroot_doc 0.1.1
|
00001 00002 #ifndef _synaps_usolve_contfrac_lower_bound_h_ 00003 #define _synaps_usolve_contfrac_lower_bound_h_ 00004 00005 #include <realroot/univariate_bounds.hpp> 00006 #include <realroot/tensor_bernstein.hpp> 00007 00008 namespace mmx { 00009 // #define bit_size(a) mpz_sizeinbase(a.get_mpz_t(),2) 00010 00011 //-------------------------------------------------------------------- 00019 struct BezierBound 00020 { 00021 template < typename Poly > 00022 typename Poly::value_type lower_bound( const Poly& f) 00023 { 00024 //std::cout <<"Bezier"<<std::endl; 00025 typedef typename Poly::value_type RT; 00026 unsigned deg = degree(f); 00027 tensor::bernstein<RT> bz(deg+1); 00028 let::assign(bz, f); 00029 // The Bernstein form of f w.r.t. the interval [0,\infinity] 00030 00031 int sn = sign(bz[0]); 00032 if(sn == 0) return 0;// That is, zero is a root, this should not be the case 00033 00034 //std::cout << "bz[0] = "<< bz[0] << std::endl; 00035 00036 RT lowerBoundN =-1, lowerBoundD=1;// Numerator and denominator of lower bound 00037 //Now we find the least positive intersection of the convex hull. 00038 for(int i=1; i <= deg; i++){ 00039 if(sn * sign(bz[i]) < 0){ 00040 /* 00041 std::cout << "bz["<<i<<"] = "<< bz[i] << std::endl; 00042 std::cout << "bz[0]*i "<< bz[0] * i << std::endl; 00043 std::cout << "(deg*(bz[0]-bz[i]))" << (deg*(bz[0]-bz[i])) << std::endl; 00044 */ 00045 if(lowerBoundN * deg *(bz[0]-bz[i]) > bz[0]*i*lowerBoundD 00046 || lowerBoundN == -1){ 00047 lowerBoundN = bz[0]*i; 00048 lowerBoundD = deg*(bz[0]-bz[i]); 00049 } 00050 } 00051 } 00052 lowerBoundD -= lowerBoundN;// Have to scale back the result to the orignial setting of [0, B] 00053 long K = bit_size(lowerBoundN)- bit_size(lowerBoundD) -1; 00054 if(K < 0) 00055 return RT(0); 00056 else if(lowerBoundN == lowerBoundD) 00057 return 1; 00058 else{// K > 0 00059 return pow( RT(2), K); 00060 } 00061 } 00062 }; 00063 00064 00065 00066 } //namespace mmx 00067 #endif //_synaps_usolve_contfrac_lower_bound_h_