realroot_doc 0.1.1
|
00001 #ifndef synaps_usolve_contfrac_IntervalData_h 00002 #define synaps_usolve_contfrac_IntervalData_h 00003 00004 #include <realroot/Interval.hpp> 00005 #include <realroot/univariate.hpp> 00006 namespace mmx { 00007 00008 template<class POL> void div_x(POL& p, int k) 00009 { 00010 for(int i=0;i< int(p.size()-k);i++) 00011 p[i]=p[i+k]; 00012 for(int i=p.size()-k; i<(int)p.size();i++) 00013 p[i]=0; 00014 } 00015 00016 template < typename RT, typename Poly > 00017 struct IntervalData 00018 { 00019 RT a, b, c, d; 00020 Poly p; 00021 unsigned long s; 00022 00023 IntervalData( const RT& a_, const RT& b_, const RT& c_, const RT& d_, 00024 const Poly& p_, unsigned long s_) 00025 : a(a_), b(b_), c(c_), d(d_), p(p_), s(s_) {} 00026 00027 IntervalData() {} 00028 00029 }; 00030 00031 template < typename FT > inline 00032 Interval< FT > as_interval( const FT& a, const FT& b) 00033 { 00034 if ( a <= b ) 00035 return Interval<FT>( a, b); 00036 return Interval<FT>( b, a); 00037 } 00038 00039 template < typename RT, typename Poly > 00040 IntervalData<RT,Poly> as_interval_data(const RT& a, const RT& b, const RT&c, const RT&d, 00041 const Poly& f) 00042 { 00043 00044 Poly X = Poly("x")*a+Poly(b), Y=Poly("x")*c+Poly(d); 00045 00046 Poly F = univariate::eval_homogeneous(f,X,Y); 00047 return IntervalData<RT,Poly> (a,b,c,d,F,degree(f)); 00048 } 00049 00050 #ifndef WITH_AS 00051 #define WITH_AS 00052 template<typename T,typename F> 00053 struct as_helper { 00054 static inline T cv (const F& x) { return x; } 00055 }; 00056 00057 template<typename T,typename F> inline T 00058 as (const F& x) { return as_helper<T,F>::cv (x); } 00059 #endif 00060 00061 template<typename FT, typename RT, typename Poly> 00062 struct as_helper<Interval<FT>,IntervalData<RT,Poly> > { 00063 static inline Interval<FT> 00064 cv (const IntervalData<RT,Poly>& I) { 00065 FT left, right; 00066 if ( I.c == RT(0)) 00067 left = sign(I.a) * bound_root( I.p, Cauchy<FT>()); 00068 else 00069 left = FT(I.a)/I.c; 00070 00071 if ( I.d == RT(0)) 00072 right = sign(I.b) * bound_root( I.p, Cauchy<FT>()); 00073 else 00074 right = FT(I.b)/I.d; 00075 // std::cout << I.a<<"/"<<I.c<<", "<<I.b<<"/"<<I.d<<std::endl; 00076 return Interval<FT>(left, right); 00077 } 00078 }; 00079 00080 00081 00082 00083 00084 00085 // template <> inline rational as<rational>(const integer& a, const integer& b) 00086 // { 00087 // return rational(a)/b; 00088 // } 00089 00090 template<class C> typename texp::rationalof<C>::T to_FT(const C& a, const C& b) 00091 { 00092 typedef typename texp::rationalof<C>::T rational; 00093 return (rational(a)/b); 00094 } 00095 00096 00097 00098 template < typename FT > 00099 Interval< FT > inline 00100 to_FIT( const FT& a, const FT& b) 00101 { 00102 if ( a <= b ) 00103 return Interval<FT>( a, b); 00104 return Interval<FT>( b, a); 00105 } 00106 00107 00108 template < typename K > 00109 typename K::FIT 00110 to_FIT( const typename K::RT& a, const typename K::RT& b, 00111 const typename K::RT& c, const typename K::RT& d, 00112 const typename K::FT& B) 00113 { 00114 typedef typename K::RT RT; 00115 typedef typename K::FT FT; 00116 typedef typename K::FIT FIT; 00117 00118 00119 FT left; 00120 FT right; 00121 00122 if ( c == RT(0)) left = sign(a) * B; 00123 // else left = as<FT>(a, c); 00124 else left = to_FT(a,c); 00125 00126 if ( d == RT(0)) right = sign(b) * B; 00127 // else right = as<FT>(b, d); 00128 else right = to_FT(b,d); 00129 00130 return to_FIT( left, right); 00131 } 00132 00133 00134 template < typename Poly> inline 00135 void 00136 reverse(Poly & R, const Poly& P) { 00137 R=P; reverse(R); 00138 } 00139 00140 /* Replace R by its reverse */ 00141 template < typename Poly> inline 00142 void 00143 reverse(Poly & R) 00144 { 00145 int deg = degree(R); 00146 Poly temp(R); 00147 for (int i = 0; i <= deg; ++i) 00148 R[i] = temp[deg-i]; 00149 } 00150 00151 /* Replaces P by the polynomial P(X+1) */ 00152 template < typename RT, typename Poly > inline 00153 void reverse( IntervalData<RT,Poly>& I1) 00154 { 00155 reverse(I1.p); 00156 std::swap(I1.a,I1.b); 00157 std::swap(I1.c,I1.d); 00158 return; 00159 } 00160 00161 00162 00163 /* Replaces P by the polynomial P(X+1) */ 00164 template < typename Poly > inline 00165 void shift_by_1( Poly& R, const Poly& P) 00166 { 00167 R=P; 00168 int deg = degree(P); 00169 for (int j = deg-1; j >= 0; j--) { 00170 for (int i = j; i < deg; i++) { 00171 R[i] += R[i+1]; 00172 } 00173 00174 } 00175 00176 return; 00177 } 00178 00179 /* Replaces P by the polynomial P(X+1) */ 00180 template < typename RT, typename Poly > inline 00181 void shift_by_1( IntervalData<RT,Poly>& I1, const IntervalData<RT,Poly>& I2) 00182 { 00183 shift_by_1(I1.p,I2.p); 00184 I1.a = I2.a; 00185 I1.b = I2.a + I2.b; 00186 I1.c = I2.c; 00187 I1.d = I2.c + I2.d; 00188 I1.s = sign_variation(I1.p); 00189 return; 00190 } 00191 00192 /* Replaces P by the polynomial P(X+1) */ 00193 template < typename RT, typename Poly > inline 00194 void shift_by_1( IntervalData<RT,Poly>& I1) 00195 { 00196 shift_by_1(I1.p); 00197 I1.b += I1.a; 00198 I1.d += I1.c; 00199 I1.s = sign_variation(I1.p); 00200 } 00201 00202 /* Replaces P by the polynomial P(X+1) */ 00203 template < typename Poly > inline 00204 void shift_by_1(Poly& R) 00205 00206 { 00207 long deg = degree( R); 00208 for (int j = deg-1; j >= 0; j--) { 00209 for (int i = j; i < deg; i++) { 00210 R[i] += R[i+1]; 00211 } 00212 } 00213 return; 00214 } 00215 00216 00217 template < typename RT, typename Poly > inline 00218 void scale( IntervalData<RT,Poly>& ID, const RT& a) 00219 { 00220 univariate::scale( ID.p, ID.p, a); 00221 ID.a *= a; 00222 ID.c *= a; 00223 } 00224 00225 00226 template < typename RT, typename Poly > inline 00227 void scale( IntervalData<RT,Poly>& ID, long k) 00228 { 00229 RT a = pow( RT( 2), k); 00230 00231 univariate::scale( ID.p, ID.p, a); 00232 ID.a *= a; 00233 ID.c *= a; 00234 } 00235 00236 00237 template < typename RT, typename Poly > inline 00238 void inv_scale( IntervalData<RT,Poly>& ID, const RT& a) 00239 { 00240 univariate::inv_scale( ID.p, ID.p, a); 00241 ID.b *= a; 00242 ID.d *= a; 00243 } 00244 00245 00246 template < typename RT, typename Poly > inline 00247 void shift( IntervalData<RT,Poly>& ID, const RT& a) 00248 { 00249 univariate::shift( ID.p, ID.p, a); 00250 ID.s = sign_variation(ID.p); 00251 ID.b += a * ID.a; 00252 ID.d += ID.c * a; 00253 } 00254 00255 00256 /* Replaces P by the polynomial (X+1)^d*P(1/(X+1)) */ 00257 template < typename RT, typename Poly > inline 00258 void reverse_shift_homography( IntervalData<RT,Poly>& I2, const IntervalData<RT,Poly>& ID) 00259 { 00260 I2.a = ID.b; 00261 I2.b = ID.a + ID.b; 00262 I2.c = ID.d; 00263 I2.d = ID.c + ID.d; 00264 } 00265 00266 /* Replaces P by the polynomial (X+1)^d*P(1/(X+1)) */ 00267 template < typename RT, typename Poly > inline 00268 void reverse_shift( IntervalData<RT,Poly>& I2, const IntervalData<RT,Poly>& ID) 00269 { 00270 I2.a = ID.b; 00271 I2.b = ID.a + ID.b; 00272 I2.c = ID.d; 00273 I2.d = ID.c + ID.d; 00274 I2.p= ID.p; 00275 reverse(I2); 00276 shift_by_1(I2); 00277 I2.s = sign_variation(I2.p); 00278 } 00279 00280 } //namespace mmx 00281 #endif //synaps_usolve_contfrac_IntervalData_h