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