realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/scalar_rational.hpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *      This file is part of the source code of realroot software.         *
00003 *      (C) B. Mourrain, GALAAD, INRIA                                *
00004 **********************************************************************
00005 History: 
00006 **********************************************************************/
00007 #ifndef _SCL_MPQ_H_
00008 #define _SCL_MPQ_H_
00009 //----------------------------------------------------------------------
00010 #include <string>
00011 #include <iostream>
00012 #include <realroot/scalar.hpp>
00013 //======================================================================
00014 namespace mmx {
00015 //----------------------------------------------------------------------
00016 typedef MP_INT  MPZ;
00017 typedef MP_RAT  MPQ;
00018 //----------------------------------------------------------------------
00019 std::ostream& operator << (std::ostream& os, const scalar<MPQ>& b);
00020 //----------------------------------------------------------------------
00021 template<> inline
00022 void scalar<MPQ>::init ( )                   {mpq_init(&rep());}
00023 //------------------- scalar<T> (...) -------------------------------------
00024 template<> inline
00025 scalar<MPQ>::scalar ( )                    {mpq_init(&rep());}
00026 //----------------------------------------------------------------------
00027 template<> inline scalar<MPQ>::~scalar ( )   {mpq_clear(&rep());}
00028 //----------------------------------------------------------------------
00029 template<> inline
00030 scalar<MPQ>::scalar (int si)               
00031      {mpq_init(&rep());mpq_set_si(&rep(),si,1);}
00032 //----------------------------------------------------------------------
00033 template<> inline
00034 scalar<MPQ>::scalar (unsigned si)               
00035      {mpq_init(&rep());mpq_set_ui(&rep(),si,1);}
00036 //----------------------------------------------------------------------
00037 template<> inline
00038 scalar<MPQ>::scalar (const char *string, unsigned int base)
00039 {
00040   MP_INT tmp;
00041   mpz_init_set_str(&tmp, string, base);
00042   mpq_init(&rep());
00043   mpq_set_z(&rep(),&tmp);      
00044 }
00045 //----------------------------------------------------------------------
00046 template<> inline
00047 scalar<MPQ>::scalar (signed long int sl)   
00048      {mpq_init(&rep());mpq_set_si(&rep(),sl,1);}
00049 //----------------------------------------------------------------------
00050 template<> inline
00051 scalar<MPQ>::scalar (unsigned long int ul) 
00052      {mpq_init(&rep());mpq_set_ui(&rep(),ul,1);}
00053 //----------------------------------------------------------------------
00054 template<> inline 
00055 scalar<MPQ>::scalar(const scalar<MPQ>& rhs) 
00056 {
00057   mpz_init_set(&rep()._mp_num, &rhs.rep()._mp_num); 
00058   mpz_init_set(&rep()._mp_den, &rhs.rep()._mp_den); 
00059 }
00060 //----------------------------------------------------------------------
00061 template<> inline 
00062 scalar<MPQ>::scalar(double rhs) 
00063 {
00064   mpq_init(&rep());
00065   mpq_set_d(&rep(), rhs); 
00066 }
00067 //----------------------------------------------------------------------
00068 template<> inline 
00069 scalar<MPQ>& scalar<MPQ>::operator =  (const scalar<MPQ>& rhs)
00070 {
00071   // COUNT<MPQ>('=');
00072   //if (this != &rhs) 
00073   //mpq_clear(&rep());
00074   //mpq_init(&rep());
00075   mpq_set(&rep(), &rhs.rep()); 
00076   return *this;
00077 }
00078 //----------------------------------------------------------------------
00079 template<> inline 
00080 bool scalar<MPQ>::operator == (const scalar<MPQ>& rhs) const
00081 {
00082   return mpq_cmp(&rep(), &rhs.rep()) == 0;
00083 }
00084 
00085 template<> inline 
00086 bool scalar<MPQ>::operator == (long sl) const {
00087   assert(sl>0);
00088   return mpq_cmp_ui(&rep(), sl, 1) == 0;
00089   
00090 }
00091 
00092 template<> inline 
00093 bool scalar<MPQ>::operator == (int si) const {
00094   return mpq_cmp_ui(&rep(), (long) si, 1) == 0;
00095 }
00096 
00097 template<> inline 
00098 bool scalar<MPQ>::operator == (unsigned long ul) const
00099 {
00100   return mpq_cmp_ui(&rep(), ul, 1) == 0;
00101 }
00102 
00103 // != ------------------------------------------------------------------
00104 template<> inline 
00105 bool scalar<MPQ>::operator != (const scalar<MPQ>& rhs) const
00106 {
00107   return mpq_cmp(&rep(), &rhs.rep()) != 0;
00108 }
00109 
00110 template<> inline 
00111 bool scalar<MPQ>::operator != (long sl) const {
00112   assert(sl>=0);
00113   return mpq_cmp_ui(&rep(), sl,1) != 0;
00114 }
00115 
00116 template<> inline
00117 bool scalar<MPQ>::operator != (int si) const {
00118   assert(si>=0);
00119   return mpq_cmp_ui(&rep(), (long) si,1) != 0;
00120 }
00121 
00122 template<> inline 
00123 bool scalar<MPQ>::operator != (unsigned long ul) const
00124 {
00125   return mpq_cmp_ui(&rep(), ul,1) != 0;
00126 }
00127 // > -------------------------------------------------------------------
00128 template<> inline 
00129 bool scalar<MPQ>::operator > (const scalar<MPQ>& rhs) const
00130 {
00131   return mpq_cmp(&rep(), &rhs.rep()) > 0;
00132 }
00133 
00134 template<> inline 
00135 bool scalar<MPQ>::operator > (long sl) const {
00136   assert(sl>=0);
00137   return mpq_cmp_ui(&rep(), sl, 1) > 0;
00138 }
00139 
00140 template<> inline 
00141 bool scalar<MPQ>::operator > (int si) const {
00142   assert(si>=0);
00143   return mpq_cmp_ui(&rep(), (long) si, 1) > 0;
00144 }
00145 
00146 template<> inline 
00147 bool scalar<MPQ>::operator > (unsigned long ul) const
00148 {
00149   return mpq_cmp_ui(&rep(), ul,1) > 0;
00150 }
00151 // <= --------------------------------------------------------------------
00152 template<> inline 
00153 bool scalar<MPQ>::operator >= (const scalar<MPQ>& rhs) const
00154 {
00155   return mpq_cmp(&rep(), &rhs.rep()) >= 0;
00156 }
00157 
00158 template<> inline 
00159 bool scalar<MPQ>::operator >= (long sl) const {
00160   assert(sl>=0);
00161   return mpq_cmp_ui(&rep(), sl, 1) >= 0;
00162 }
00163 
00164 template<> inline 
00165 bool scalar<MPQ>::operator >= (int si) const
00166 {
00167   assert(si>=0);
00168   return mpq_cmp_ui(&rep(), (long) si, 1) >= 0;
00169 }
00170 
00171 template<> inline 
00172 bool scalar<MPQ>::operator >= (unsigned long ul) const
00173 {
00174   return mpq_cmp_ui(&rep(), ul, 1) >= 0;
00175 }
00176 
00177 // < -------------------------------------------------------------------
00178 template<> inline 
00179 bool scalar<MPQ>::operator < (const scalar<MPQ>& rhs) const
00180 {
00181   return mpq_cmp(&rep(), &rhs.rep()) < 0;
00182 }
00183 
00184 template<> inline 
00185 bool scalar<MPQ>::operator < (long sl) const {
00186   return mpq_cmp_ui(&rep(), sl, 1) < 0;
00187 }
00188 
00189 template<> inline 
00190 bool scalar<MPQ>::operator < (int si) const
00191 {
00192   assert(si>=0);
00193   return mpq_cmp_ui(&rep(), (long) si, 1) < 0;
00194 }
00195 
00196 template<> inline 
00197 bool scalar<MPQ>::operator < (unsigned long ul) const
00198 {
00199   return mpq_cmp_ui(&rep(), ul, 1) < 0;
00200 }
00201 
00202 // <= ------------------------------------------------------------------
00203 
00204 template<> inline 
00205 bool scalar<MPQ>::operator <= (const scalar<MPQ>& rhs) const
00206 {
00207   return mpq_cmp(&rep(), &rhs.rep()) <= 0;
00208 }
00209 
00210 template<> inline 
00211 bool scalar<MPQ>::operator <= (long sl) const {
00212   assert(sl>=0);
00213   return mpq_cmp_ui(&rep(), sl,1) <= 0;
00214 }
00215 
00216 template<> inline 
00217 bool scalar<MPQ>::operator <= (int si) const
00218 {
00219   assert(si>=0);
00220   return mpq_cmp_ui(&rep(), (long) si, 1) <= 0;
00221 }
00222 
00223 template<> inline 
00224 bool scalar<MPQ>::operator <= (unsigned long ul) const
00225 {
00226   return mpq_cmp_ui(&rep(), ul, 1) <= 0;
00227 }
00228 
00229 // = -------------------------------------------------------------------
00230 template<> inline 
00231 scalar<MPQ>&  scalar<MPQ>::operator =  (unsigned long ul)
00232 {
00233   mpq_set_ui(&rep(), ul, 1); return *this;
00234 }
00235 
00236 template<> inline 
00237 scalar<MPQ>& scalar<MPQ>::operator =  (long sl)
00238 {
00239   mpq_set_si(&rep(), sl, 1);  return *this;
00240 }
00241 
00242 template<> inline 
00243 scalar<MPQ>& scalar<MPQ>::operator = (int ul)
00244 {
00245   mpq_set_si(&rep(), ul, 1);  return *this;
00246 }
00247 // += -------------------------------------------------------------------
00248 template<> inline 
00249 scalar<MPQ>& scalar<MPQ>::operator += (const scalar<MPQ>& rhs)
00250 {
00251   scalar<MPQ> tmp;
00252   mpq_add(&tmp.rep(), &rep(), &rhs.rep());  
00253   mpq_swap(&tmp.rep(),&rep());
00254   //  mpq_canonicalize(&rep());
00255   return *this;
00256 }
00257 
00258 template<> inline 
00259 scalar<MPQ>& scalar<MPQ>::operator += (unsigned long ul)
00260 {
00261   mpq_add(&rep(), &rep(), &scalar<MPQ>(ul).rep());
00262   //  mpq_canonicalize(&rep());
00263   return *this;
00264 }
00265 
00266 template<> inline 
00267 scalar<MPQ>& scalar<MPQ>::operator += (long sl)
00268 {
00269   mpq_add(&rep(), &rep(), &scalar<MPQ>(sl).rep());
00270   //mpq_canonicalize(&rep());
00271   return *this;
00272 }
00273 
00274 template<> inline 
00275 scalar<MPQ>& scalar<MPQ>::operator += (int ul)
00276 {
00277   scalar<MPQ> tmp(ul);
00278   *this += tmp;  
00279   //mpq_canonicalize(&rep());
00280   return *this;
00281 }
00282 
00283 // -= -------------------------------------------------------------------
00284 template<> inline 
00285 scalar<MPQ>& scalar<MPQ>::operator -= (const scalar<MPQ>& rhs)
00286 {
00287   mpq_sub(&rep(), &rep(), &rhs.rep()); 
00288   //mpq_canonicalize(&rep());
00289   return *this;
00290 }
00291 
00292 template<> inline 
00293 scalar<MPQ>& scalar<MPQ>::operator -= (unsigned long ul)
00294 {
00295   mpq_sub(&rep(), &rep(), &scalar<MPQ>(ul).rep()); 
00296   //mpq_canonicalize(&rep());
00297   return *this;
00298 }
00299 
00300 template<> inline 
00301 scalar<MPQ>& scalar<MPQ>::operator -= (long sl)
00302 {
00303   mpq_sub(&rep(), &rep(), &scalar<MPQ>(sl).rep());
00304   //mpq_canonicalize(&rep());
00305   return *this;
00306 }
00307 
00308 template<> inline 
00309 scalar<MPQ>& scalar<MPQ>::operator -= (int ul)
00310 {
00311   *this -= scalar<MPQ>(ul); 
00312   //mpq_canonicalize(&rep());
00313   return *this;
00314 }
00315 // *= -----------------------------------------------------------------
00316 template<> inline 
00317 scalar<MPQ>& scalar<MPQ>::operator *= (const scalar<MPQ>& rhs)
00318 {
00319   mpq_mul(&rep(), &rep(), &rhs.rep()); 
00320   return *this;
00321 }
00322 
00323 template<> inline 
00324 scalar<MPQ>& scalar<MPQ>::operator *= (int ul)
00325 {
00326   mpq_mul(&rep(), &rep(), &scalar<MPQ>(ul).rep()); 
00327   return *this;
00328 }
00329 template<> inline 
00330 scalar<MPQ>& scalar<MPQ>::operator *= (unsigned long ul)
00331 {
00332   mpq_mul(&rep(), &rep(), &scalar<MPQ>(ul).rep()); 
00333   return *this;
00334 }
00335 template<> inline 
00336 scalar<MPQ>& scalar<MPQ>::operator *= (long sl)
00337 {
00338   mpq_mul(&rep(), &rep(), &scalar<MPQ>(sl).rep());
00339   //mpq_canonicalize(&rep());
00340   return *this; 
00341 }
00342 
00343 // /= ------------------------------------------------------------------
00344 template<> inline 
00345 scalar<MPQ>& scalar<MPQ>::operator /= (const scalar<MPQ>& rhs)
00346 {
00347   mpq_div(&rep(), &rep(), &rhs.rep());
00348   return *this;
00349 }
00350 
00351 template<> inline 
00352 scalar<MPQ>& scalar<MPQ>::operator /= (unsigned sl)
00353 {
00354   mpq_div(&rep(), &rep(),  &scalar<MPQ>(sl).rep());
00355   return *this;
00356 }
00357 
00358 template<> inline 
00359 scalar<MPQ>& scalar<MPQ>::operator /= (int sl)
00360 {
00361   mpq_div(&rep(), &rep(),  &scalar<MPQ>(sl).rep());
00362   return *this;
00363 }
00364 
00365 template<> inline 
00366 scalar<MPQ>& scalar<MPQ>::operator /= (unsigned long ul)
00367 {
00368   mpq_div(&rep(), &rep(), &scalar<MPQ>(ul).rep()); 
00369   return *this;
00370 }
00371 
00372 template<> inline 
00373 scalar<MPQ>& scalar<MPQ>::operator /= (long int sl)
00374 {
00375   
00376   mpq_div(&rep(), &rep(),  &scalar<MPQ>(sl).rep());
00377   //mpq_canonicalize(&rep());
00378   return *this;
00379 }
00380 
00381 //======================================================================
00382 // ARITHMETIC OPERATORS
00383 //======================================================================
00384 inline  
00385 scalar<MPQ> operator +(const scalar<MPQ>& a1, const scalar<MPQ>& a2) 
00386 {
00387   scalar<MPQ> result;
00388   mpq_add(&result.rep(), &a1.rep(), &a2.rep());
00389   //mpq_canonicalize(&result.rep());
00390   return result;
00391 }
00392 //----------------------------------------------------------------------
00393 inline
00394 scalar<MPQ> operator -(const scalar<MPQ>& a1, const scalar<MPQ>& a2) 
00395 {
00396   scalar<MPQ> result;
00397   mpq_sub(&result.rep(), &a1.rep(), &a2.rep());
00398   //mpq_canonicalize(&result.rep());
00399   return result;
00400 }
00401 inline
00402 scalar<MPQ> operator -(const scalar<MPQ>& a1) 
00403 {
00404   scalar<MPQ> r;  mpq_neg(&r.rep(), &a1.rep()); return r;
00405 }
00406 //----------------------------------------------------------------------
00407 inline
00408 scalar<MPQ> operator *(const scalar<MPQ>& a1, const scalar<MPQ>& a2) 
00409 {
00410   //   static 
00411   scalar<MPQ> result;
00412   // if(mpq_cmp_ui(&a1.rep(),0ul,1ul) && mpq_cmp_ui(&a2.rep(),0ul,1ul))
00413   mpq_mul(&result.rep(), &a1.rep(), &a2.rep());
00414   return result;
00415 }
00416 
00417 inline 
00418 scalar<MPQ> operator *(const scalar<MPQ>& a1, const scalar<MPZ>& a2) 
00419 {
00420   return a1*scalar<MPQ>(a2);
00421 }
00422 
00423 inline scalar<MPQ> operator *(const scalar<MPZ>& a1, const scalar<MPQ>& a2) 
00424 {
00425   return a2*scalar<MPQ>(a1);
00426 }
00427 //--------------------------------------------------------------------
00428 inline
00429 scalar<MPQ> operator *(const scalar<MPQ>& a2, int a1) 
00430 {
00431   return a2 * scalar<MPQ>(a1);
00432 }
00433 
00434 inline
00435 scalar<MPQ> operator *(int a1, const scalar<MPQ>& a2) 
00436 {
00437   return a2 * scalar<MPQ>(a1);
00438 }
00439 
00440 inline
00441 scalar<MPQ> operator /(const scalar<MPQ>& a1, const scalar<MPQ>& a2) 
00442 {
00443   scalar<MPQ> result;
00444   mpq_div(&result.rep(), &a1.rep(), &a2.rep());
00445   return result;
00446 }
00447 
00448 inline 
00449 scalar<MPQ> operator /(const scalar<MPQ>& a1, const scalar<MPZ>& a2) 
00450 {
00451   return a1/scalar<MPQ>(a2);
00452 }
00453 //======================================================================
00455 template<> inline 
00456 void scalar<MPQ>::operator ++ ( )
00457 {
00458   mpq_add(&rep(), &rep(), &scalar<MPQ>(1).rep());
00459   //mpq_canonicalize(&rep());
00460 }
00461 //----------------------------------------------------------------------
00463 template<> inline 
00464 void scalar<MPQ>::operator -- ( )
00465 {
00466   mpq_sub(&rep(), &rep(), &scalar<MPQ>(1).rep());
00467   //mpq_canonicalize(&rep());
00468 }
00469 //======================================================================
00470 // INPUT OUTPUT
00471 //======================================================================
00472 inline
00473 std::ostream& operator << (std::ostream& os, const scalar<MPQ>& b)
00474 {
00475   mpq_out_str(stdout, 10, &b.rep());  //MP_INT tmp; //mpz_init(&tmp);
00476   return os;       
00477 }
00478 
00479 inline char* as_charp( const scalar<MPQ>& b) {
00480   return mpq_get_str(NULL,10,&b.rep());
00481 }
00482 
00483 template<class OSTREAM> inline void 
00484 print(OSTREAM& os, const scalar<MPQ>& b) {
00485   os<<as_charp(b);
00486 }
00487 //----------------------------------------------------------------------
00488 inline
00489 std::istream& operator >> (std::istream& is, scalar<MPQ>& b)
00490 {
00491   std::string s;is >> s;
00492   MP_INT tmp;
00493   mpz_init_set_str(&tmp,s.c_str(), 10);
00494   mpq_init(&b.rep());
00495   mpq_set_z(&b.rep(),&tmp);
00496     return is;          
00497 }
00498 //======================================================================
00499 // SPECIAL FUNCTIONS
00500 //======================================================================
00501 template<> inline void
00502 scalar<MPQ>::abs ( )
00503 {
00504   if (rep()._mp_num._mp_size < 0) rep()._mp_num._mp_size = - rep()._mp_num._mp_size;
00505 }
00506 
00507 template<> inline 
00508 scalar<MPQ>& scalar<MPQ>::negate ( )
00509 {
00510   rep()._mp_num._mp_size = - rep()._mp_num._mp_size; return *this;
00511 }
00512 
00513 inline scalar<MPZ> numerator(const scalar<MPQ>& q)   { scalar<MPZ> r; mpq_get_num(&r.rep(),&q.rep()); return r;}
00514 inline scalar<MPZ> denominator(const scalar<MPQ>& q) { scalar<MPZ> r; mpq_get_den(&r.rep(),&q.rep()); return r;}
00515 inline scalar<MPZ> rfloor (const scalar<MPQ>& q) { scalar<MPZ> r=numerator(q); r/=denominator(q); return r; }
00516 inline scalar<MPZ> rceil  (const scalar<MPQ>& q) { return rfloor(q)+1; }
00517 //-------------------------- compare (...) ------------------------------------
00518 inline int compare (const scalar<MPQ>& b1, const scalar<MPQ>& b2)
00519 {
00520   return mpq_cmp(&b1.rep(), &b2.rep());
00521 }
00522 
00523 inline int compare (const scalar<MPQ>& b, unsigned long ul)
00524 {
00525   return mpq_cmp_ui(&b.rep(), ul, 1);
00526 }
00527 
00528 inline int compare (const scalar<MPQ>& b, long sl)
00529 {
00530   assert(sl>=0);
00531   return mpq_cmp_ui(&b.rep(), sl, 1);
00532 }
00533 
00534 inline scalar<MPQ> min(const scalar<MPQ>& a1, const scalar<MPQ>& a2) {return (a1<a2?a1:a2);}
00535 inline scalar<MPQ> max(const scalar<MPQ>& a1, const scalar<MPQ>& a2) {return (a1>a2?a1:a2);}
00536 
00537 //----------------------------------------------------------------------
00538 inline void convert (scalar<MPQ>& dd, char *s)
00539 {
00540   mpq_clear(&dd.rep());
00541   mpq_init(&dd.rep());
00542   mpz_set_str(mpq_numref(&dd.rep()),s,10);
00543 }
00544 //----------------------------------------------------------------------
00545 inline scalar<MPQ> Size(const scalar<MPQ> & r) { return abs(r); };
00546 
00547 namespace let
00548 {
00549   inline void assign(scalar<MPQ> & x, char *s) { mpq_set_str(&x.rep(), s, 10);}
00550   inline void assign(scalar<MPQ> & q, double d ) { mpq_set_d(&q.rep(),d); }
00551   inline void assign(double & d, const scalar<MPQ>& x ) 
00552   {
00553     d = mpq_get_d(&x.rep());
00554   } 
00555 }
00556 //--------------------------------------------------------------------
00557   
00558 inline double to_double(const scalar<MPQ>& a)   { return mpq_get_d(&a.rep()); }
00559 
00560 template<typename T,typename F> struct as_helper;
00561 
00562 template<> struct as_helper<double,scalar<MPQ> > { 
00563   static inline double cv(const scalar<MPQ>& x) {double r; let::assign(r,x); return r;}
00564 };
00565 
00566 } //namespace mmx
00567 //======================================================================
00568 #endif // //SCL_MPQ_H