synaps/arithm/Scl.h

00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS kernel.        *
00003 *      Author(s): B. Mourrain, GALAAD, INRIA                         *
00004 **********************************************************************
00005 History: Initialized from the Posso file.
00006          Modified in order to handel different internal representation.
00007 $Id: Scl.h,v 1.1 2005/07/11 10:39:47 mourrain Exp $
00008 **********************************************************************/
00009 
00010 
00011 #ifndef SYNAPS_ARITHM_SCL_H
00012 #define SYNAPS_ARITHM_SCL_H
00013 
00014 #ifndef NDEBUG
00015         #include <cassert>
00016 #endif
00017 
00018 //----------------------------------------------------------------------
00019 #include <cstdio>
00020 #include <gmp.h>
00021 #include <synaps/init.h>
00022 #include <synaps/arithm/REF.h>
00023 #include <synaps/base/shared_object.h>
00024 //----------------------------------------------------------------------
00025 
00026 
00027 __BEGIN_NAMESPACE_SYNAPS
00028 
00029 #define WITH_TEMP_EXP
00030 
00033 template<class T> struct Scl
00034 {
00035 public:
00036 #ifdef WITH_TEMP_EXP
00037   T data;
00038   inline T &       rep()       {return (data);}
00039   inline const T & rep() const {return (data);}
00040 #else
00041   shared_object<T>  data; 
00042   T &       rep()       {return (*data);}
00043   const T & rep() const {return (*data);}
00044 #endif
00045   Scl ();
00046   Scl (const Scl<T>& b);    //{ data=b.data;}
00047   Scl (double d);
00048   Scl (signed long sl);
00049   Scl (unsigned long ul);
00050   Scl (int si);
00051   Scl (const char* string, unsigned int b=10);
00052   Scl (const T & r);
00053   
00054   template<class S>
00055   Scl(const VAL<S> & P) {this->init();let::assign(*this,P.rep());}
00056 
00057   ~Scl () {}
00058 
00059   bool                  operator == (const Scl<T>& rhs) const;
00060   bool                  operator != (const Scl<T>& rhs) const;
00061   bool                  operator >  (const Scl<T>& rhs) const;
00062   bool                  operator >= (const Scl<T>& rhs) const;
00063   bool                  operator <  (const Scl<T>& rhs) const;
00064   bool                  operator <= (const Scl<T>& rhs) const;
00065 
00066   bool                  operator == (long sl) const;
00067   bool                  operator != (long sl) const;
00068   bool                  operator >  (long sl) const;
00069   bool                  operator >= (long sl) const;
00070   bool                  operator <  (long sl) const;
00071   bool                  operator <= (long sl) const;
00072 
00073   bool                  operator == (int si) const;
00074   bool                  operator != (int si) const;
00075   bool                  operator >  (int si) const;
00076   bool                  operator >= (int si) const;
00077   bool                  operator <  (int si) const;
00078   bool                  operator <= (int si) const;
00079 
00080   bool                  operator == (unsigned long ul) const;
00081   bool                  operator != (unsigned long ul) const;
00082   bool                  operator >  (unsigned long ul) const;
00083   bool                  operator >= (unsigned long ul) const;
00084   bool                  operator <  (unsigned long ul) const;
00085   bool                  operator <= (unsigned long ul) const;
00086 
00087   // functions that modify at least one argument or `*this' 
00088 
00089   Scl<T>& operator  = (const Scl<T>& rhs);// {data=rhs.data; return *this;}
00090   Scl<T>& operator += (const Scl<T>& rhs);
00091   Scl<T>& operator -= (const Scl<T>& rhs);
00092   Scl<T>& operator *= (const Scl<T>& rhs);
00093   Scl<T>& operator /= (const Scl<T>& rhs);
00094   Scl<T>& operator %= (const Scl<T>& rhs);
00095   
00096   Scl<T>&               operator =  (int rhs);
00097   Scl<T>&               operator += (int rhs);
00098   Scl<T>&               operator -= (int rhs);
00099   Scl<T>&               operator *= (int rhs);
00100   Scl<T>&               operator /= (int rhs);
00101   Scl<T>&               operator %= (int rhs);
00102 
00103   Scl<T>&               operator =  (unsigned long rhs);
00104   Scl<T>&               operator += (unsigned long rhs);
00105   Scl<T>&               operator -= (unsigned long rhs);
00106   Scl<T>&               operator *= (unsigned long rhs);
00107   Scl<T>&               operator /= (unsigned long rhs);
00108   Scl<T>&               operator %= (unsigned long rhs);
00109 
00110   Scl<T>&               operator *= (double rhs);
00111   Scl<T>&               operator += (double rhs);
00112 
00113   Scl<T>&               operator =  (long rhs);
00114   Scl<T>&               operator += (long rhs);
00115   Scl<T>&               operator -= (long rhs);
00116   Scl<T>&               operator *= (long rhs);
00117   Scl<T>&               operator /= (long rhs);
00118 //   Scl<T>&               operator %= (long rhs);
00119 
00120   template<class S> 
00121   Scl<T>& operator   = (const VAL<S> & x) 
00122   {
00123     let::assign(*this,x.rep());return *this;
00124   }
00125   template<class S> 
00126   Scl<T>& operator  += (const VAL<S> & x) 
00127     {Scl<T> tmp(x);*this+=tmp;return *this;}
00128   template<class S> 
00129   Scl<T>& operator  -= (const VAL<S> & x) 
00130     {Scl<T> tmp(x); *this-=tmp;return *this;}
00131   template<class S> Scl<T>& operator  *= (const VAL<S> & x) 
00132     {Scl<T> tmp(x); *this*=tmp;return *this;}
00133   template<class S> Scl<T>& operator  /= (const VAL<S> & x) 
00134     {Scl<T> tmp(x); *this/=tmp;return *this;}
00135   template<class S> Scl<T>& operator  %= (const VAL<S> & x) 
00136     {Scl<T> tmp(x); *this%=tmp;return *this;}
00137 
00138   //-----------------------------------------------------------------
00139   void                  operator ++ ( );
00140   void                  operator -- ( );
00141   //-----------------------------------------------------------------
00142   void                  Div2Exp   (unsigned long exponent_of_2);
00143   void                  GCD       (const Scl<T>& b2);
00144   void                  Mod2Exp   (unsigned long exponent_of_2);
00145   void                  Mul2Exp   (unsigned long exponent_of_2);
00146   void                  PowMod    (const Scl<T>& exp, const Scl<T>& m);
00147   void                  PowMod    (unsigned long exp, const Scl<T>& m);
00148   void                  abs       ( );
00149   void                  factorial (unsigned long n);
00150   Scl<T>&               negate    ( );
00151   Scl<T>&               pow       (unsigned long exp);
00152   Scl<T>&               pow       (unsigned long base, unsigned long exp);
00153   void                  quo       (const Scl<T>& divisor);
00154   void                  quo       (unsigned long divisor);
00155   void                  rem       (const Scl<T>& divisor);
00156   unsigned long         rem       (unsigned long divisor);
00157   void                  sqrt      ( );
00158 
00159 private:
00160   void init();
00161 };
00162 
00163 //======================================================================
00164 // THE ARITHMETIC OPERATORS
00165 //======================================================================
00166 #ifdef WITH_TEMP_EXP
00167 template <class R> inline
00168 VAL<OP<'+',Scl<R>,Scl<R> > > operator+(const Scl<R> & a, const Scl<R> & b)
00169 {
00170   return VAL<OP<'+',Scl<R>,Scl<R> > >(OP<'+',Scl<R>,Scl<R> >(a,b));
00171 }
00172 //----------------------------------------------------------------------
00173 template <class R> inline 
00174 VAL<OP<'-',Scl<R>,Scl<R> > > operator-(const Scl<R> & a, const Scl<R> & b)
00175 {
00176   return VAL<OP<'-',Scl<R>,Scl<R> > >(OP<'-',Scl<R>,Scl<R> >(a,b));
00177 }
00178 //----------------------------------------------------------------------
00179 // Product of polynomials 
00180 template <class R>  inline 
00181 VAL<OP<'*',Scl<R>,Scl<R> > > operator*(const Scl<R> & a, const Scl<R> & b)
00182 {
00183   return VAL<OP<'*',Scl<R>,Scl<R> > >(OP<'*',Scl<R>,Scl<R> >(a,b));
00184 }
00185 //----------------------------------------------------------------------
00186 // Division of polynomials 
00187 template <class R>  inline 
00188 VAL<OP<'/',Scl<R>,Scl<R> > > operator/(const Scl<R> & a, const Scl<R> & b)
00189 {
00190   return VAL<OP<'/',Scl<R>,Scl<R> > >(OP<'/',Scl<R>,Scl<R> >(a,b));
00191 }
00192 //----------------------------------------------------------------------
00193 // Division of polynomials 
00194 template <class R>  inline 
00195 VAL<OP<'%',Scl<R>,Scl<R> > > operator%(const Scl<R> & a, const Scl<R> & b)
00196 {
00197   return VAL<OP<'%',Scl<R>,Scl<R> > >(OP<'%',Scl<R>,Scl<R> >(a,b));
00198 }
00199 //----------------------------------------------------------------------
00200 #endif
00201 //======================================================================
00202 template<class T> inline 
00203 Scl<T> operator - (const Scl<T>& b) 
00204 {
00205   Scl<T> r(b); return (r.negate());
00206 }
00207 //----------------------------------------------------------------------}
00208 template<class T> Scl<T>& operator + (const Scl<T>& b, unsigned long ul);
00209 template<class T> Scl<T>& operator - (const Scl<T>& b, unsigned long ul);
00210 template<class T> Scl<T>& operator * (const Scl<T>& b, unsigned long ul);
00211 template<class T> Scl<T>& operator / (const Scl<T>& b, unsigned long ul);
00212 template<class T> Scl<T>& operator % (const Scl<T>& b, unsigned long ul);
00213 template<class T> Scl<T>& operator + (unsigned long ul, const Scl<T>& b);
00214 template<class T> Scl<T>& operator * (unsigned long ul, const Scl<T>& b);
00215 template<class T> Scl<T>& operator + (const Scl<T>& b, long sl);
00216 template<class T> Scl<T>& operator - (const Scl<T>& b, long sl);
00217 template<class T> Scl<T>& operator * (const Scl<T>& b, long sl);
00218 template<class T> Scl<T>& operator / (const Scl<T>& b, long sl);
00219 template<class T> Scl<T>& operator % (const Scl<T>& b, long sl);
00220 template<class T> Scl<T>& operator + (long sl, const Scl<T>& b);
00221 template<class T> Scl<T>& operator * (long sl, const Scl<T>& b);
00222 template<class T> Scl<T>& operator * (double d, const Scl<T>& b);
00223 //----------------------------------------------------------------------
00224 template<class T> Scl<T>& Div2Exp (const Scl<T>& b, 
00225                                    unsigned long exponent_of_2);
00226 template<class T> Scl<T>& GCD     (const Scl<T>& b1, const Scl<T>& b2);
00227 template<class T> Scl<T>& gcd     (const Scl<T>& b1, const Scl<T>& b2);
00228 template<class T> Scl<T>& Mod2Exp (const Scl<T>& b, 
00229                                    unsigned long exponent_of_2);
00230 template<class T> Scl<T>& Mul2Exp (const Scl<T>& b, unsigned long exponent_of_2);
00231 template<class T> Scl<T>& PowMod  (const Scl<T>& b, const Scl<T>& exp, const Scl<T>& m);
00232 template<class T> Scl<T>& PowMod  (const Scl<T>& b, unsigned long exp, 
00233                                    const Scl<T>& m);
00234 template<class T> Scl<T> abs     (const Scl<T>& b);
00235 // template<class T> Scl<T>& negate  (const Scl<T>& b);
00236 template<class T> Scl<T> pow     (const Scl<T>& base, unsigned long exp);
00237 template<class T> Scl<T>& quo     (const Scl<T>& dividend, 
00238                                    const Scl<T>& divisor);
00239 template<class T> Scl<T>& quo     (const Scl<T>& dividend, 
00240                                    unsigned long divisor);
00241 template<class T> Scl<T>& rem     (const Scl<T>& dividend, 
00242                                    const Scl<T>& divisor);
00243 template<class T> Scl<T> sqrt    (const Scl<T>& b);
00244 template<class T> unsigned long rem (const Scl<T>& b, unsigned long divisor);
00245 
00246 template<class T> Scl<T>& BigIntFactorial (unsigned long n);
00247 
00248 //
00249 // -------- the corresponding `const' functions -----------------------------
00250 //
00251 
00252 #define NO_NRV 1
00253 #if defined(__GNUG__) && !defined(NO_NRV)
00254 #define NRVAL(name) return name
00255 #define NRCODE(code) code
00256 #define NONRCODE(code) 
00257 #else
00258 #define NRVAL(name) 
00259 #define NRCODE(code)
00260 #define NONRCODE(code) code
00261 #endif
00262 
00263 #define OPCODE(a, b, op) Scl<T>& r =*new Scl<T>(a); return (r op b);
00264 
00265 
00266 // template<class T> inline 
00267 // Scl<T>& operator + (const Scl<T>& b1, const Scl<T>& b2) 
00268 // {
00269 //   OPCODE(b1,b2,+=)
00270 // }
00271 
00272 // template<class T> inline 
00273 // Scl<T>& operator - (const Scl<T>& b1, const Scl<T>& b2) 
00274 // {
00275 //   OPCODE(b1,b2,-=)
00276 // }
00277 
00278 // template<class T> inline 
00279 // Scl<T>& operator * (const Scl<T>& b1, const Scl<T>& b2) 
00280 // {
00281 //   OPCODE(b1,b2,*=)
00282 // }
00283 
00284 // template<class T> inline 
00285 // Scl<T>& operator / (const Scl<T>& b1, const Scl<T>& b2) 
00286 // {
00287 //   OPCODE(b1,b2,/=)
00288 // }
00289 
00290 // template<class T> inline 
00291 // Scl<T>& operator % (const Scl<T>& b1, const Scl<T>& b2) 
00292 // {
00293 //   OPCODE(b1,b2,%=)
00294 // }
00295 
00296 //--------------------------
00297 template<class T> inline 
00298 Scl<T>& operator + (const Scl<T>& b, int ul) 
00299 {
00300   OPCODE(b,ul,+=)
00301 }
00302 template<class T> inline 
00303 Scl<T>& operator + (const Scl<T>& b, unsigned long ul) 
00304 {
00305   OPCODE(b,ul,+=)
00306 }
00307 
00308 template<class T> inline 
00309 Scl<T>& operator - (const Scl<T>& b, unsigned long ul) 
00310 {
00311   OPCODE(b,ul,-=)
00312 }
00313 
00314 template<class T> inline Scl<T>&
00315 operator * (const Scl<T>& b, unsigned long ul) 
00316 {
00317   OPCODE(b,ul,*=)
00318 }
00319 
00320 template<class T> inline Scl<T>&
00321 operator / (const Scl<T>& b, unsigned long ul) 
00322 {
00323   OPCODE(b,ul,/=)
00324 }
00325 
00326 template<class T> inline 
00327 Scl<T>& operator % (const Scl<T>& b, unsigned long ul) 
00328 {
00329   OPCODE(b,ul,%=)
00330 }
00331 
00332 //----------------------------------------------------------------------
00333 template<class T> inline 
00334 Scl<T>& operator + (unsigned long ul, const Scl<T>& b)
00335 {
00336   return b + ul;
00337 }
00338 //----------------------------------------------------------------------
00339 template<class T> inline 
00340 Scl<T>& operator * (unsigned long ul, const Scl<T>& b)
00341 {
00342   return b * ul;
00343 }
00344 //----------------------------------------------------------------------
00345 template<class T> inline 
00346 Scl<T>& operator + (const Scl<T>& b, long sl)  
00347 {
00348   OPCODE(b,sl,+=)
00349 }
00350 
00351 
00352 template<class T> inline 
00353 Scl<T>& operator - (const Scl<T>& b, long sl)  NRVAL(r(b))
00354 {
00355   OPCODE(b,sl,-=)
00356 }
00357 
00358 template<class T> inline 
00359 Scl<T>& operator * (const Scl<T>& b, int sl)  NRVAL(r(b))
00360 {
00361   OPCODE(b,sl,*=)
00362 }
00363 
00364 template<class T> inline 
00365 Scl<T>& operator * (const Scl<T>& b, long sl)  NRVAL(r(b))
00366 {
00367   OPCODE(b,sl,*=)
00368 }
00369 
00370 template<class T> inline
00371 Scl<T>& operator / (const Scl<T>& b, long sl)  NRVAL(r(b))
00372 {
00373   OPCODE(b,sl,/=)
00374 }
00375 
00376 template<class T> inline Scl<T>&
00377 operator % (const Scl<T>& b, long sl)  NRVAL(r(b))
00378 {
00379   OPCODE(b,sl,%=)
00380 }
00381 
00382 //--------------------------
00383 
00384 template<class T> inline 
00385 Scl<T>& operator + (long sl, const Scl<T>& b)
00386 {
00387   return b + sl;
00388 }
00389 
00390 template<class T> inline 
00391 Scl<T>& operator * (long sl, const Scl<T>& b)
00392 {
00393   return b * sl;
00394 }
00395 //--------------------------
00396 
00397 template<class T> inline 
00398 Scl<T>& Div2Exp (const Scl<T>& b, unsigned long exponent_of_2) NRVAL(r(b))
00399 {
00400   NRCODE(r.Div2Exp(exponent_of_2);)
00401   NONRCODE(Scl<T> r(b); r.Div2Exp(exponent_of_2); return r;)
00402 }
00403 
00404 template<class T> inline 
00405 Scl<T>& GCD (const Scl<T>& b1, const Scl<T>& b2) NRVAL(r(b1))
00406 {
00407   NRCODE(r.GCD(b2);)
00408   NONRCODE(Scl<T> r(b1); r.GCD(b2); return r;)
00409 }
00410 
00411 template<class T> inline 
00412 Scl<T>& gcd (const Scl<T>& b1, const Scl<T>& b2) NRVAL(r(b1))
00413 {
00414   NRCODE(r.GCD(b2);)
00415   NONRCODE(Scl<T> r(b1); r.GCD(b2); return r;)
00416 }
00417 
00418 template<class T> inline 
00419 Scl<T>& Mod2Exp (const Scl<T>& b, unsigned long exponent_of_2) NRVAL(r(b))
00420 {
00421   NRCODE(r.Mod2Exp(exponent_of_2);)
00422   NONRCODE(Scl<T> r(b); r.Mod2Exp(exponent_of_2); return r;)
00423 }
00424 
00425 template<class T> inline 
00426 Scl<T>& Mul2Exp (const Scl<T>& b, unsigned long exponent_of_2) NRVAL(r(b))
00427 {
00428   NRCODE(r.Mul2Exp(exponent_of_2);)
00429   NONRCODE(Scl<T> r(b); r.Mul2Exp(exponent_of_2); return r;)
00430 }
00431 
00432 template<class T> inline 
00433 Scl<T>& PowMod  (const Scl<T>& b, const Scl<T>& exp, const Scl<T>& m) NRVAL(r(b))
00434 {
00435   NRCODE(r.PowMod(exp, m);)
00436   NONRCODE(Scl<T> r(b); r.PowMod(exp,m); return r;)
00437 }
00438 
00439 template<class T> inline 
00440 Scl<T>& PowMod  (const Scl<T>& b, unsigned long exp, const Scl<T>& m) NRVAL(r(b))
00441 {
00442   NRCODE(r.PowMod(exp, m);)
00443   NONRCODE(Scl<T> r(b); r.PowMod(exp,m); return r;)
00444 }
00445 
00446 //template<class T> inline Scl<T>
00447 template <class T> inline 
00448 Scl<T> abs (const Scl<T>& b) NRVAL(r(b))
00449 {
00450   NRCODE(r.abs();)
00451   NONRCODE(Scl<T> r(b); r.abs(); return r;)
00452 }
00453 
00454 // template<class T> inline Scl<T>&
00455 // negate (const Scl<T>& b) NRVAL(r(b))
00456 // {
00457 //   NRCODE(r.negate();)
00458 //   NONRCODE(Scl<T> r(b); r.negate(); return r;)  
00459 // }
00460 
00461 template<class T> inline 
00462 Scl<T> pow (const Scl<T>& base, unsigned long exp) NRVAL(r(base))
00463 {
00464   NRCODE(r.pow(exp);)
00465   NONRCODE(Scl<T> r(base); r.pow(exp); return r;)
00466 }
00467 
00468 template<class T> inline 
00469 Scl<T>& quo (const Scl<T>& dividend, const Scl<T>& divisor) NRVAL(r(dividend))
00470 {
00471   NRCODE(r.quo(divisor);)
00472   NONRCODE(Scl<T> r(dividend); r.quo(divisor); return r;)
00473 }
00474 
00475 template<class T> inline 
00476 Scl<T>& quo (const Scl<T>& dividend, unsigned long divisor) NRVAL(r(dividend))
00477 {
00478   NRCODE(r.quo(divisor);)
00479   NONRCODE(Scl<T> r(dividend); r.quo(divisor); return r;)
00480 }
00481 
00482 template<class T> inline 
00483 Scl<T>& rem (const Scl<T>& dividend, const Scl<T>& divisor) NRVAL(r(dividend))
00484 {
00485   NRCODE(r.rem(divisor);)
00486   NONRCODE(Scl<T> r(dividend); r.rem(divisor); return r;)
00487 }
00488 
00489 template<class T> inline 
00490 Scl<T> sqrt (const Scl<T>& b) NRVAL(r(b))
00491 {
00492   NRCODE(r.sqrt();)
00493   NONRCODE(Scl<T> r(b); r.sqrt(); return r;)
00494 }
00495 
00496 template<class T> inline 
00497 unsigned long rem (const Scl<T>& b, unsigned long divisor)
00498 {
00499   Scl<T> r(b);
00500   return r.rem(divisor);
00501 }
00502 
00503 template<class T> inline 
00504 Scl<T>& BigIntFactorial (unsigned long n) NRVAL(r)
00505 {
00506   NRCODE(r.factorial(n);)
00507   NONRCODE(Scl<T> r; r.factorial(n); return r;)    
00508 }
00509 
00510 template<class T> inline 
00511 Scl<T>& BigIntPow (unsigned long base, unsigned long exp) NRVAL(r)
00512 {
00513   NRCODE(r.pow(base, exp);)
00514   NONRCODE(Scl<T> r; r.pow(base, exp); return r;)
00515 }
00516 
00517 template<class T>
00518  Scl<T> Size(const Scl<T> & r)
00519 {
00520   return abs(r);
00521 }
00522 
00523 #undef NRVAL
00524 #undef NRCODE
00525 #undef NONRCODE
00526 
00527 
00528 __END_NAMESPACE_SYNAPS
00529 
00530 #endif // SYNAPS_ARITHM_SCL_H
00531 
00532 

SYNAPS DOCUMENTATION
logo