synaps/mpol/Monom.h

Go to the documentation of this file.
00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS kernel.        *
00003 *      Author(s): B. Mourrain, GALAAD, INRIA                         *
00004 **********************************************************************
00005 $Id: Monom.h,v 1.1 2005/07/11 11:17:56 mourrain Exp $
00006 **********************************************************************/
00007 #ifndef SYNAPS_MPOL_MONOM_H
00008 #define SYNAPS_MPOL_MONOM_H
00009 //--------------------------------------------------------------------
00010 #include <assert.h>
00011 #include <map>
00012 #include <string>
00013 #include <synaps/init.h>
00014 #include <synaps/base/COUNT.h>
00015 #include <synaps/base/shared_object.h>
00016 #include <synaps/base/type.h>
00017 #include <synaps/linalg/VECTOR.m>
00018 #include <synaps/arithm/REF.h>
00019 #include <synaps/mpol/MONOMIAL.m>
00020 #include <synaps/mpol/dynamicexp.h>
00021 #include <synaps/mpol/Variables.h>
00022 
00023 __BEGIN_NAMESPACE_SYNAPS
00024 //--------------------------------------------------------------------
00026 //--------------------------------------------------------------------
00032 template <class C, class R=dynamicexp<unsigned> >
00033 struct Monom {
00034 
00035   //data
00036   C                 _coef;
00037 #ifdef SHARED_MONOM
00038   shared_object<R>  _expt;
00039   R &       rep()       {return (*_expt);}
00040   const R & rep() const {return (*_expt);}
00041   typedef  shared_object<R> exp_t;
00042 #else
00043   R  _expt;
00044   R &       rep()       {return (_expt);}
00045   const R & rep() const {return (_expt);}
00046   typedef  R exp_t;
00047 #endif
00048 
00049   static Variables var;
00050   //   //  unsigned                  _number_var;
00051   //   //  static std::map<std::string,int> _index_of_var;
00052   //   //  static std::map<int,std::string> _var_of_index;
00053   //   static  int index_of_var(const std::string & s) { return var[s]; }
00054   //   static std::string var_of_index(int i)          { return var[i]; }
00055 
00056   // Type definitions
00057   typedef int                    index_t;
00058   typedef R                      container_t;
00059   typedef typename R::exponent_t exponent_t; //typename R::coeff_t exponent_t;
00060   typedef typename R::size_type  size_type;
00061   typedef C                      coeff_t;
00062   typedef Monom<C,R>             self_t;
00063 
00064   // Constructors
00065   Monom(): _coef(),_expt()
00066     {
00067       rep().resize(0); //COUNT<self_t>(' ');
00068     }
00069   Monom(const C & c, const exp_t & r):_coef(c), _expt(r){}
00070   Monom(const C & c): _coef(c),_expt()
00071     {
00072       rep().resize(0);
00073     } // monome constant
00074   Monom(int i):_coef(i), _expt()
00075     {
00076       rep().resize(0);
00077     }
00078   Monom(int i, int d);                 // monome x[i]**d
00079   Monom(const std::string & s, int d, Variables& vars = Variables::default_ );                // monome x[i]**d
00080   Monom(const C & c, unsigned s, const type::AsSize & S):_coef(c),_expt(s){}
00081   Monom(const C & c, int i, int d =1); // monome c*x[i]**d
00082   Monom(const C & c, int s, int *t):_coef(c), _expt(s){
00083     for(int i=0;i<s;i++) rep()[i]= t[i];
00084   }
00085 
00086   //Copy constructor
00087   Monom(const Monom & m):_coef(m._coef),_expt(m._expt)
00088     {
00089       // COUNT<self_t>('c');
00090     }
00091 
00092   template<class S>
00093   Monom(const VAL<S> & M)
00094     {
00095       assign(*this,M.rep());
00096     }
00097 
00098   // Destructor
00099   // not dynamic allocation at this level
00100 
00101   // Assignement
00102   self_t & operator = (const self_t & m)
00103     {
00104       //      COUNT<self_t>('=');
00105       _coef = m.coeff(); 
00106       _expt = m._expt; 
00107       return *this;
00108     };
00109   template<class S>
00110   self_t & operator = (const VAL<S> & M)
00111     {
00112       assign(*this,M.rep()); return *this;
00113     }
00114 
00115   // Accessors
00116   const C & coeff () const { return _coef; }
00117   C& coeff ()       { return _coef; }
00118 
00119   void setcoeff (const C & c) { _coef = c; }
00120 
00121   unsigned size() const     { return rep().size(); }
00122   int      nvars() const    { return lvar(rep()); }
00123   int      nbvar() const    { return lvar(rep())+1; }
00124 
00125   exponent_t operator[] (size_type i) const { return rep()[i]; }
00126 
00127   self_t & setexpt (size_type i, exponent_t d)
00128     {rep().setExponent(i,d);return *this; }
00129 
00130   // boolean operators and functions
00131   bool operator==(int n) const;
00132   bool operator!=(int n) const {return !(*this==n);}
00133 
00134 
00135   friend bool operator == (const self_t & m1, const self_t & m2) {
00136     return m1._coef == m2._coef && m1.rep() == m2.rep();
00137   }
00138 
00139   friend bool  operator != (const self_t & m1, const self_t & m2) {
00140     return !(m1 == m2);
00141   }
00142 
00143   friend bool IsComparable (const self_t & m1, const self_t & m2){
00144     return m1.rep() == m2.rep();
00145   }
00146 
00147   // Arithmetic operators
00148   self_t   operator  - () const {return self_t(-_coef,rep());}
00149   self_t & operator += (const self_t &);
00150   self_t & operator -= (const self_t &);
00151   self_t & operator *= (const self_t &);
00152   self_t & operator *= (const C &);
00153   self_t & operator /= (const C &);
00154 
00155 };
00156 //======================================================================
00157 template<class R,class O> Variables Monom<R,O>::var;
00158 //----------------------------------------------------------------------//
00159 // template<class R,class O> unsigned Monom<R,O>::_number_var=1;
00160 // template<class R,class O> std::map<std::string,int> Monom<R,O>::_index_of_var;
00161 // template<class R,class O> std::map<int,std::string> Monom<R,O>::_var_of_index;
00162 //----------------------------------------------------------------------//
00163 template <class R,class O>
00164 inline VAL<OP<'*',Monom<R,O>,Monom<R,O> > >
00165   operator*(const Monom<R,O> & a, const Monom<R,O> & b)
00166 {
00167   return VAL<OP<'*',Monom<R,O>,Monom<R,O> > >
00168    (OP<'*',Monom<R,O>,Monom<R,O> >(a,b));
00169 }
00170 //----------------------------------------------------------------------//
00171 template <class R,class O>
00172 inline VAL<OP<'/',Monom<R,O>,Monom<R,O> > >
00173   operator/(const Monom<R,O> & a, const Monom<R,O> & b)
00174 {
00175   return VAL<OP<'/',Monom<R,O>,Monom<R,O> > >
00176    (OP<'/',Monom<R,O>,Monom<R,O> >(a,b));
00177 }
00178 
00179 //----------------------------------------------------------------------//
00180 namespace let 
00181 {
00182   template<class C, class R> inline
00183   void assign( C & r, const Monom<C,R>& m )
00184   {
00185     r = m.coeff();
00186   };
00187   template<class C, class R> inline
00188   const C&  convert( const Monom<C,R> & m, const type::As<C>& ) { return m.coeff(); };
00189 };
00190 //----------------------------------------------------------------------//
00191 template <class C,class R> inline
00192 void assign(Monom<C,R> & a, const OP<'*',Monom<C,R>,Monom<C,R> > & M)
00193 {
00194   a.coeff() = (M.op1.coeff()*M.op2.coeff());
00195   if (a.coeff() !=0)
00196     {
00197       a.rep().reserve(std::max(M.op1.rep().size(),M.op2.rep().size()));
00198       using namespace VECTOR; add(a.rep(),M.op1.rep(),M.op2.rep());
00199     }
00200   else
00201     {
00202       erase(a.rep());
00203     }
00204 }
00205 //----------------------------------------------------------------------//
00206 template <class R,class O> inline
00207 void assign(Monom<R,O> & res, const OP<'/',Monom<R,O>,Monom<R,O> > & M)
00208 {
00209   typedef typename Monom<R,O>::exponent_t exponent_t;
00210   if(M.op1.nvars()< M.op2.nvars())
00211     res= Monom<R,O>(0);
00212   else {
00213     res= Monom<R,O>(M.op1);
00214     res.coeff() /=M.op2.coeff();
00215     for (int i = 0; i <= M.op1.nvars() && res.coeff() !=0 ; ++i)
00216       if(M.op1[i] <M.op2[i])
00217         {
00218           res= Monom<R,O>(0);
00219         }
00220       else
00221         res.rep().setExponent(i,exponent_t(M.op1[i] - M.op2[i]));
00222   }
00223 }
00224 //----------------------------------------------------------------------
00225 template <class C, class R> inline
00226 typename R::degree_t degree(const Monom<C,R> & m)
00227 {
00228   return degree(m.rep());
00229 }
00230 //----------------------------------------------------------------------//
00231 template<class M>
00232 M MGcd(const M & m1, const M & m2) {
00233   int d = Gcd(m1.coeff(),m2.coeff());
00234   M res(d);
00235   int v = Min(m1.nvars(),m2.nvars());
00236   for (int i = 0; i <= v; ++i)
00237     res.rep().setExponent(i, Min(m1[i],m2[i]));
00238   return res;
00239 }
00240 
00241 template <class M>
00242 M div(const M & m1, const M & m2) {
00243   M res(1); res*=(m1.coeff()/m2.coeff());
00244   for (int i = 0; i <= m1.nvars(); ++i)
00245     res.rep().setExponent(i,m1[i] - m2[i]);
00246   return res;
00247 }
00248 
00249 template <class M>
00250 M div_quo(const M & m1, const M & m2) {
00251   M res(1); res*=(m1.coeff()/m2.coeff());
00252   for (int i = 0; i <= m1.nvars(); ++i)
00253     res.rep().setExponent(i,m1[i] - m2[i]);
00254   return res;
00255 }
00256 
00257 
00258 
00260 template <class C, class R>
00261 Monom<C,R>::Monom(int i, int d):_coef(1)
00262 {
00263   if(d == 0)
00264     rep().resize(0);
00265   else
00266     {
00267       rep().reserve(i+1);
00268       for(int j=0;j<i;j++) rep().setExponent(j,0);
00269       rep().setExponent(i,d);
00270     }
00271 }
00272 //----------------------------------------------------------------------
00273 
00275 template <class C, class R>
00276 Monom<C,R>::Monom(const std::string & s, int d, 
00277                   Variables& vars                 ):_coef(1)
00278 {
00279   if(d == 0)
00280     rep().resize(0);
00281  else
00282      {
00283        int i=vars[s];
00284        //  std::cout <<":: "<<s<<" "<<i<<std::endl;
00285        rep().reserve(i+1);
00286        for(int j=0;j<i;j++) rep().setExponent(j,0);
00287        rep().setExponent(i,d);
00288      }
00289  }
00290 
00291 //----------------------------------------------------------------------
00293 template <class C, class R>
00294 Monom<C,R>::Monom(const C & c, int i, int d ):_coef(c)
00295 {
00296   if(d == 0)
00297     rep().resize(0);
00298   else
00299     {
00300       rep().reserve(i+1);
00301       for(int j=0;j<i;j++) rep().setExponent(j,0);
00302       rep().setExponent(i,d);
00303     }
00304 }
00305 //----------------------------------------------------------------------
00306 // arithemtic operators
00307 //----------------------------------------------------------------------
00308 template <class C, class R> inline
00309 bool Monom<C,R>::operator== (int n) const
00310 {
00311   return (coeff()==n);
00312 }
00313 //----------------------------------------------------------------------
00314 // template <class C, class R> inline
00315 // int Monom<C,R>::index_of_var(const std::string & s)
00316 // {
00317 //   //cout <<">> "<<s<<endl;
00318 //   if(s[0]=='x' && s.size()>1 )
00319 //     {
00320 //       const char* var=s.data()+1;
00321 //       return atoi(var);
00322 //     }
00323 //   else
00324 //     {
00325 //       int i=_index_of_var[s]-1;
00326 //       if(i<0)
00327 //      {
00328 //        while(_var_of_index[_number_var]!="")
00329 //          {
00330 //            _number_var++;
00331 //          }
00332 //        i=_number_var-1;
00333 //        _index_of_var[s]=_number_var;
00334 //        _var_of_index[_number_var]=s;
00335 //      }
00336 //       return i;
00337 //     }
00338 // }
00339 // //----------------------------------------------------------------------
00340 // template <class C, class R> inline
00341 // std::string Monom<C,R>::var_of_index(int i)
00342 // {
00343 //   if(_var_of_index[i+1]!="")
00344 //     return _var_of_index[i+1];
00345 //   else
00346 //     {
00347 //       int sz=1,m=1;
00348 //       while(m<i) {m*=10; sz++;}
00349 //       char str[sz];
00350 //       sprintf(str,"%d",i);
00351 //       return std::string("x")+str;
00352 //     }
00353 // }
00354 //----------------------------------------------------------------------
00355 // arithemtic operators
00356 //----------------------------------------------------------------------
00357 template <class C, class R> inline
00358 Monom<C,R> & Monom<C,R>::operator += (const Monom<C,R> & m)
00359 {
00360   coeff() += m.coeff();
00361   if (coeff()==0) erase(rep());
00362   return *this;
00363 }
00364 
00365 template <class C, class R> inline
00366 Monom<C,R> & Monom<C,R>::operator -= (const Monom<C,R> & m)
00367 {
00368   coeff() -= m.coeff();
00369   if (coeff()==0) erase(rep());
00370   return *this;
00371 }
00372 
00373 template <class C, class R> inline
00374 Monom<C,R>  operator +  (const Monom<C,R> & m1, const Monom<C,R> & m2)
00375 {
00376   Monom<C,R> res(m1);
00377   res.coeff() += m2.coeff();
00378   return (*res);
00379 }
00380 
00381 template <class C, class R> inline
00382 Monom<C,R> operator - (const Monom<C,R> & m1, const Monom<C,R> & m2)
00383 {
00384         Monom<C,R> res(m1);
00385         res.coeff() -= m2.coeff();
00386         return (res);
00387 }
00388 
00389 template <class C, class R> inline
00390 Monom<C,R> & Monom<C,R>::operator *= (const Monom<C,R> & m)
00391 {
00392   using namespace VECTOR;
00393   coeff() *= m.coeff();
00394   if (coeff()!=0)
00395     add(rep(),m.rep());
00396   else
00397     erase(rep());
00398   return *this;
00399 }
00400 
00401 template <class C, class R> inline
00402 Monom<C,R> & Monom<C,R>::operator *= (const C & c)
00403 {
00404   coeff() *= c;
00405   if (coeff()==0) erase(rep());
00406   return *this;
00407 }
00408 
00409 template <class C, class R> inline
00410 Monom<C,R> & Monom<C,R>::operator /= (const C & c)
00411 {
00412   assert(c !=0);
00413   coeff() /= c;
00414   if (coeff()==0) erase(rep());
00415   return *this;
00416 }
00417 
00418 template <class C, class R> inline
00419 Monom<C,R> operator * (const Monom<C,R> & m1, const C & c2)
00420 {
00421   Monom<C,R> res(m1);
00422   res.coeff() *= c2;
00423   if (res.coeff() ==0) erase(res.rep());
00424   return (res);
00425 }
00426 template <class C, class R> inline
00427 Monom<C,R> operator * (const C & c2, const Monom<C,R> & m1)
00428 {
00429   return(m1*c2);
00430 }
00431 
00432 template <class C, class R> inline
00433 Monom<C,R> operator / (const Monom<C,R> & m1, const C & c2)
00434 {
00435   Monom<C,R> res(m1);
00436   res.coeff() /= c2;
00437   if (res.coeff() ==0) erase(res.rep());
00438   return (res);
00439 }
00440 
00441 
00442 //----------------------------------------------------------------------
00443 // operateurs d'entrees/sorties
00444 //----------------------------------------------------------------------
00446 template <class C, class R> inline
00447 std::ostream & operator << (std::ostream & os, const Monom <C,R> & m)
00448 {
00449   if (m.coeff() ==0 )    os<<"(0)";
00450   else {
00451     MONOMIAL::print(os,m);
00452   }
00453   return os;
00454 }
00455 //----------------------------------------------------------------------
00456 __END_NAMESPACE_SYNAPS
00457 //----------------------------------------------------------------------
00458 #endif // SYNAPS_MPOL_MONOM_H
00459 

SYNAPS DOCUMENTATION
logo