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
00010
00011
00019 struct BezierBound
00020 {
00021 template < typename Poly >
00022 typename Poly::value_type lower_bound( const Poly& f)
00023 {
00024
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
00030
00031 int sn = sign(bz[0]);
00032 if(sn == 0) return 0;
00033
00034
00035
00036 RT lowerBoundN =-1, lowerBoundD=1;
00037
00038 for(int i=1; i <= deg; i++){
00039 if(sn * sign(bz[i]) < 0){
00040
00041
00042
00043
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;
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{
00059 return pow( RT(2), K);
00060 }
00061 }
00062 };
00063
00064
00065
00066 }
00067 #endif //_synaps_usolve_contfrac_lower_bound_h_