realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/contfrac_intervaldata.hpp
Go to the documentation of this file.
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