synaps/mpol/MPol.h

00001 /*********************************************************************
00002 *      This file is part of the source code of the SYNAPS library.
00003 *      Author(s): B. Mourrain, GALAAD, INRIA                 
00004 **********************************************************************
00005 History:
00006     03/03/00 by bm, update for the new version
00007     02/03/99 by dbondy,
00008                   - modification of the operator *=. "p*=p;" fonctionne.
00009     24/02/99 by dbondy,
00010         - add a constructor for the MPol class form a char *.
00011         - add a typedef for the arithmetic coefficient.
00012     12/12/98 by bm, change p in rep, add size method.
00013     1/12/98  by dbondy modified the structure of the file for a better
00014     documentation.
00015 $Id: MPol.H,v 1.1 2005/07/11 11:17:56 mourrain Exp $
00016 **********************************************************************/
00017 #ifndef SYNAPS_MPOL_MPOL_H
00018 #define SYNAPS_MPOL_MPOL_H
00019 
00020 #include <stdlib.h>
00021 #include <string>
00022 #include <list>
00023 #include <synaps/init.h>
00024 #include "synaps/base/shared_object.h"
00025 #include "synaps/base/parser.h"
00026 #include "synaps/base/COUNT.h"
00027 #include "synaps/arithm/REF.h"
00028 #include "synaps/arithm/let.h"
00029 #include "synaps/upol/UPolDse.h"
00030 #include "synaps/mpol/Variables.h"
00031 #include "synaps/mpol/dynamicexp.h"
00032 #include "synaps/mpol/DegLex.h"
00033 #include "synaps/mpol/Monom.h"
00034 #include "synaps/mpol/MPOLDST.m"
00035 
00036 //--------------------------------------------------------------------
00037 __BEGIN_NAMESPACE_SYNAPS
00038 //----------------------------------------------------------------------
00039 namespace linalg { template<class C> struct rep1d; }
00040 //----------------------------------------------------------------------
00042 
00047 template <class C,
00048           class O=DegLex,
00049           class R=std::list<Monom<C,dynamicexp<unsigned> > > >
00050 struct MPol {
00051 
00052   shared_object<R>  data;
00053   R &       rep()       {return (*data);}
00054   const R & rep() const {return (*data);}
00055 
00056   // Types
00057   typedef typename R::value_type             monom_t;
00058   typedef C                                  coeff_t;
00059   typedef O                                  order_t;
00060   typedef typename R::iterator               iterator;
00061   typedef typename R::const_iterator         const_iterator;
00062   typedef typename R::reverse_iterator       reverse_iterator;
00063   typedef typename R::const_reverse_iterator const_reverse_iterator;
00064   typedef MPol<C,O,R>                        self_t;
00065 
00066   // Constructors
00067   MPol():data() {rep().resize(0);}
00068   MPol(const monom_t & m): data()
00069     {
00070       rep().resize(0); rep().insert(rep().begin(),m);
00071     }
00072 
00073   MPol(const coeff_t & c):data()
00074     {
00075       if(c !=0) {
00076         rep().resize(0); rep().insert(rep().begin(),monom_t(c));
00077       }else
00078         rep().resize(0);
00079     }
00080 
00081   MPol(const int & i): data()
00082     {
00083       if(i !=0)
00084         { rep().resize(0);rep().insert(rep().begin(),monom_t(i));}
00085       else
00086         { rep().resize(0);}
00087     }
00088 
00089   MPol(int, const monom_t *);
00090   MPol(const self_t & P): data(P.data) {}
00091   MPol(const char *, Variables& vars = Variables::default_);
00092   MPol(const char *, const Variables& vars);
00093 
00094   template<class S>
00095   MPol(const VAL<S>& M) {using let::assign; assign(*this,M.rep());}
00096 
00097 
00098   template<class Q>
00099   MPol(const MPol<C,Q,R>& p) : data()
00100   {
00101     for(const_iterator it=p.begin();it != p.end(); it++)
00102       (*this) += *it;
00103   }
00104   
00105   // Destructor
00106   // no dynamic allocation at this level.
00107 
00108   //  static Variable var;
00109   static int index(const std::string & s)     { return monom_t::var[s]; }
00110   static std::string var(int i)               { return monom_t::var[i]; }
00111   static void var(int i, const std::string& s){ monom_t::var.let(i,s); }
00112   static int  var(char* s)                    { monom_t::var=s; return monom_t::var[s]; }
00113 
00114 
00115   // Assignment operators
00116   self_t & operator =(const self_t & x)  {data=x.data; return *this;}
00117   self_t & operator =(const coeff_t & c) {*this=self_t(c); return *this;}
00118   self_t & operator =(int n)             {*this=self_t(n); return *this;}
00119   self_t & operator =(const monom_t & m) {*this=self_t(m); return *this;}
00120   template<class S>
00121   self_t & operator =(const VAL<S> & M)  {assign(*this,M.rep());return *this;}
00122 
00123   self_t & operator*=(const coeff_t &);
00124   self_t & operator/=(const coeff_t &);
00125 
00126   self_t & operator*=(const monom_t &);
00127   self_t & operator/=(const monom_t &);
00128   //  self_t & operator+=( const monom_t & m );
00129   
00130   self_t & operator+=(const self_t &);
00131   self_t & operator-=(const self_t &);
00132   self_t & operator*=(const self_t &);
00133   self_t & operator/=(const self_t & Q);
00134 
00135   // Boolean operators and functions
00136   bool operator==(int n) const;
00137   bool operator!=(int n) const {return !(*this==n);}
00138 
00139   // Iterator functions
00140   iterator                begin ()       {return rep().begin(); }
00141   const_iterator          begin () const {return rep().begin(); }
00142   reverse_iterator       rbegin ()       {return rep().rbegin();}
00143   const_reverse_iterator rbegin () const {return rep().rbegin();}
00144 
00145   iterator                  end ()       {return rep().end(); }
00146   const_iterator            end () const {return rep().end(); }
00147   reverse_iterator         rend ()       {return rep().rend();}
00148   const_reverse_iterator   rend () const {return rep().rend();}
00149 
00151   int size()  const {return rep().size();}
00153   int nbvar() const {return MPOLDST::nbvar(*this);}
00154 
00156   template<class T>
00157   coeff_t operator()(const T & p) const;
00158 
00159 };
00160 //======================================================================
00161 // template<class C, class O, class R> Variable MPol<C,O,R>::var;
00162 //======================================================================
00163 // Input/Output operator
00164 template<class C, class O, class R>
00165 std::istream & operator >>(std::istream &, MPol<C,O,R> &);
00166 template<class C, class O, class R>
00167 std::ostream & operator <<(std::ostream &, const MPol<C,O,R> &);
00168 template<class C, class O, class R>
00169 bool operator == (const MPol<C,O,R> &, const MPol<C,O,R> &);
00170 template<class C, class O, class R>
00171 bool operator != (const MPol<C,O,R> &, const MPol<C,O,R> &);
00172 template<class C, class O, class R>
00173 bool operator < (const MPol<C,O,R> &, const MPol<C,O,R> &);
00174 template<class C, class O, class R>
00175 bool operator <= (const MPol<C,O,R> &, const MPol<C,O,R> &);
00176 template<class C, class O, class R>
00177 bool operator > (const MPol<C,O,R> &, const MPol<C,O,R> &);
00178 template<class C, class O, class R>
00179 bool operator >= (const MPol<C,O,R> &, const MPol<C,O,R> &);
00180 //======================================================================
00181 // ARITHMETIC OPERATIONS.
00182 //======================================================================
00183 #ifdef WITH_TEMPLATE_EXP
00184         #include <synaps/MPol_with_texp.h>
00185 #else
00186 //======================================================================
00187 template <class C, class O, class R>
00188 MPol<C,O,R> operator+(const MPol<C,O,R> & a, const MPol<C,O,R> & b);
00189 //----------------------------------------------------------------------
00190 template <class C, class O, class R>
00191 MPol<C,O,R> operator+(const MPol<C,O,R> & a,
00192                       const typename MPol<C,O,R>::coeff_t & c);
00193 //----------------------------------------------------------------------
00194 template <class C, class O, class R>
00195 MPol<C,O,R> operator+(const MPol<C,O,R> & a,
00196                       const typename MPol<C,O,R>::monom_t & c);
00197 //----------------------------------------------------------------------
00198 template <class C, class O, class R>
00199 MPol<C,O,R> operator+(const typename MPol<C,O,R>::coeff_t & c,const MPol<C,O,R> & a);
00200 //----------------------------------------------------------------------
00201 template <class C, class O, class R>
00202 MPol<C,O,R> operator-(const MPol<C,O,R> & a, const MPol<C,O,R> & b);
00203 //----------------------------------------------------------------------
00204 template <class C, class O, class R> inline
00205 MPol<C,O,R> operator-(const MPol<C,O,R> & a,const typename MPol<C,O,R>::coeff_t & c);
00206 //----------------------------------------------------------------------
00207 template <class C, class O, class R> inline
00208 MPol<C,O,R> operator-(const typename MPol<C,O,R>::coeff_t & c,const MPol<C,O,R> & a);
00209 //----------------------------------------------------------------------
00210 template <class C, class O, class R> inline
00211 MPol<C,O,R> operator-(const MPol<C,O,R> & a);
00212 //----------------------------------------------------------------------
00213 template <class C, class O, class R>
00214 MPol<C,O,R> operator*(const MPol<C,O,R> & a, const MPol<C,O,R> & b);
00215 //----------------------------------------------------------------------
00216 template <class C, class O, class R>
00217 MPol<C,O,R> operator*(const MPol<C,O,R> & a, const C & c);
00218 //----------------------------------------------------------------------
00219 template <class C, class O, class R> inline
00220 MPol<C,O,R> operator*(const typename MPol<C,O,R>::coeff_t & c,
00221                       const MPol<C,O,R> & a);
00222 //----------------------------------------------------------------------
00223 template <class C, class O, class R> inline
00224 MPol<C,O,R> operator*(int c,const MPol<C,O,R> & a);
00225 //----------------------------------------------------------------------
00226 template <class C, class O, class R> inline
00227 MPol<C,O,R> operator*(const MPol<C,O,R> & a,
00228                       const typename MPol<C,O,R>::monom_t & m);
00229 //----------------------------------------------------------------------
00230 template <class C, class O, class R> inline
00231 MPol<C,O,R> operator*(const typename MPol<C,O,R>::monom_t & m,
00232                       const MPol<C,O,R> & a);
00233 //----------------------------------------------------------------------
00234 template <class C, class O, class R> inline
00235 MPol<C,O,R> operator/(const MPol<C,O,R> & a, const MPol<C,O,R> & b) ;
00236 //----------------------------------------------------------------------
00237 template <class C, class O, class R> inline
00238 MPol<C,O,R> operator%(const MPol<C,O,R> & a, const MPol<C,O,R> & b) ;
00239 //----------------------------------------------------------------------
00240 template <class C, class O, class R>
00241 MPol<C,O,R> operator^(const MPol<C,O,R> & a, unsigned int n);
00242 #endif
00243 //----------------------------------------------------------------------
00245 template <class C, class O, class R>
00246 int NbVar(const MPol<C,O,R> & p)
00247 {
00248   return MPOLDST::nbvar(p);
00249 }
00250 
00252 template <class C, class O, class R>
00253 int LastVar(const MPol<C,O,R> & p)
00254 {
00255   return MPOLDST::lvar(p);
00256 }
00257 
00258 
00259 //====================================================================
00261 template <class C, class O, class R> inline
00262 int degree (const MPol<C,O,R> & p)
00263 {
00264   return MPOLDST::degree(p.rep());
00265 }
00267 template <class C, class O, class R> inline
00268 int degree (const MPol<C,O,R> & p, unsigned int i)
00269 {
00270   return MPOLDST::degree(p.rep(),i);
00271 }
00272 //====================================================================
00274 template <class C, class O, class R> inline
00275 MPol<C,O,R> diff(const MPol<C,O,R> & p, unsigned i)
00276 {
00277   MPol<C,O,R> r;
00278   MPOLDST::diff(r,p,i);
00279   return r;
00280 }
00281 //----------------------------------------------------------------------
00285 template <class C, class O, class R> inline
00286 MPol<C,O,R> diff(const MPol<C,O,R> & p, char* x, Variables& vars = Variables::default_ )
00287 {
00288   typedef typename MPol<C,O,R>::monom_t monom_t;
00289   int i = vars[x];
00290   if(i<0)
00291     return MPol<C,O,R>(0);
00292   else
00293     {
00294       MPol<C,O,R> r;
00295       MPOLDST::diff(r,p,i);
00296       return r;
00297     }
00298 }
00299 //====================================================================
00300 namespace let 
00301 {
00305   template<class P,class S, class C, class O, class R>
00306   void assign(MPol<double,P,S>& r, const MPol<C,O,R> & p)
00307   {
00308     typedef typename MPol<double,P,S>::monom_t monom_t;
00309     double c;
00310     for(typename MPol<C,O,R>::const_iterator it=p.begin(); it !=p.end(); ++it)
00311       {
00312         let::assign<double,C>(c,it->coeff());
00313         monom_t m(c,it->rep());
00314         r+=m;
00315       }
00316   }
00317 
00320   template<class Ca, class Ra,
00321            class Cb, class Ob, class Rb >
00322   void convert( UPolDse<Ca,Ra> & p, const MPol<Cb,Ob,Rb> & mp, int v )
00323   {
00324     int dv;
00325     p.resize( (dv = degree(mp,v))+1 );
00326     std::fill( p.begin(), p.end(), 0);
00327         
00328     typedef typename MPol<Cb,Ob,Rb>::const_iterator pmit;
00329     typedef typename MPol<Cb,Ob,Rb>::monom_t monom;
00330     using namespace let;
00331     for ( pmit it = mp.begin(); it != mp.end(); it ++ )
00332       {
00333         monom m(*it);
00334         if ( m.size() > v ) m.rep()[v] = 0;
00335         p[ (*it)[v] ] += convert(m,type::As<Ca>());
00336       };
00337   };
00338   
00339   template<class Ca, class Ra,
00340            class Cb, class Ob, class Rb,
00341            class Rp, class Ru>
00342   void convert( UPolDse< UPolDse<Ca,Ra>, Rp >& p, 
00343                 const UPolDse< MPol<Cb,Ob,Rb>, Ru >&  ump, int v )
00344   {
00345     p.resize( ump.size() );
00346     for ( int i = 0; i < ump.size(); i++ ) convert(p[i],ump[i],v);
00347   };
00348   
00350   template<class Ca, class Ra, 
00351            class Rp, 
00352            class Cb, class Ob, class Rb >
00353 
00354   void convert( UPolDse< UPolDse<Ca,Ra>, Rp >& p, 
00355                 const MPol<Cb,Ob,Rb> & mp, int a, int b )
00356   {
00357     UPolDse< MPol<Cb,Ob,Rb> > tmp;
00358     convert( tmp, mp, a );
00359     convert( p,  tmp, b );
00360   };
00361   
00362   template<class C, class O, class Ra, class Rb, class Rc>
00363   void convert( UPolDse< UPolDse<C,Ra>, Rb >& p, 
00364                 const MPol<C,O,Rc> & mp, 
00365                 const char * a, const char * b, 
00366                 const Variables & vars = Variables::default_  )
00367   {
00368     convert( p, mp, vars[a], vars[b] );
00369   };
00370 
00371   template<class C, class O, class Rm, class Ru> inline
00372   void convert( MPol<C,O,Rm> & result, const UPolDse< MPol<C,O,Rm> , Ru >  & p, int v )  
00373   {
00374     int nvar = NbVar(p);
00375     int tmp[ nvar + 1 ];
00376 //     MPol<C,O,Rm> result;
00377     for ( int i = 0; i < p.size(); i ++ ) 
00378       for ( typename MPol<C,O,Rm>::coeff_t::const_iterator itc = p[i].begin(); itc != p[i].end(); itc++ )
00379         {
00380           typename MPol<C,O,Rm>::monom_t tmp = *itc;
00381           if ( tmp.rep.size() <= v ) tmp.rep().resize( v+1 );
00382           tmp.rep()[v] = i;
00383           result += tmp;
00384         };
00385   };
00386 }
00387 //====================================================================
00388 namespace UPOLDAR 
00389 {
00390   template <class C, class O, class R>
00391   std::ostream & print_as_coeff(std::ostream & os, const MPol<C,O,R> & p)
00392   {
00393     return os<<"+("<<p<<")";;
00394   }
00395 }
00396 //----------------------------------------------------------------------
00397 // Constructors
00398 //----------------------------------------------------------------------
00399 template <class C,class O, class R>
00400 inline MPol<C,O,R>::MPol (int s, const monom_t *t)
00401 {
00402         for (int i = 0; i<s; i++) *this += t[i];
00403 }
00404 
00405 extern "C" char *synaps_inputptr;
00406 template <class C,class O, class R>
00407 inline MPol<C,O,R>::MPol (const char * s, Variables&  vars ): data() {
00408   rep().resize(0);
00409   int n = strlen(s);
00410   if (s[n-1]=='\n') {n--;}
00411   if(s[n-1]==';')
00412     {
00413       synaps_input = new char[n+1];
00414       memcpy(synaps_input,s,n); synaps_input[n]='\0';
00415       synaps_inputlim = synaps_input + n;
00416     }
00417   else
00418     {
00419       synaps_input = new char[n+2];
00420       memcpy(synaps_input,s,n); 
00421       synaps_input[n]=';'; synaps_input[n+1]='\0';
00422       synaps_inputlim = synaps_input + n+1;
00423     }
00424   synaps_inputptr=synaps_input;
00425   monom_t m(1);
00426   bool sign = true;
00427   bool first = true;
00428   int Ask;
00429 
00430   for (;;) {
00431     Ask = yylex();
00432     if (Ask == COEF) { /* Monome constant */
00433       coeff_t c;
00434       let::assign(c,yylval);
00435       free(yylval);
00436       m *= c;
00437     }
00438     else if (Ask == XID) {
00439       char* p = strchr(yylval,'^');
00440       if (p == NULL)
00441         {
00442           m *= monom_t(vars[std::string(yylval)],1);
00443         }
00444       else {
00445         p++;
00446         m *= monom_t(vars[std::string(yylval,p-1)], atoi(p));
00447       }
00448       free(yylval);
00449     }
00450     else if (Ask == MULT);
00451     else if (Ask == SUM) {
00452       if (sign) {
00453         if(m!=0) *this += m;
00454         m = monom_t(1);
00455       } else {
00456         if(m!=0) *this -= m;
00457         sign = true;
00458         m = monom_t(1);
00459       }
00460     }
00461     else if (Ask == MINUS) {
00462       if (first)
00463         sign = false;
00464       else if (sign) {
00465         if(m!=0) *this += m;
00466         sign = false;
00467         m = monom_t(1);
00468       }
00469       else {
00470         if(m!=0) *this -= m;
00471         m = monom_t(1);
00472       }
00473     }
00474     else if (Ask == TERMINATOR) {
00475       if (sign){
00476         if(m!=0) *this += m;
00477       }else{
00478         if(m!=0) *this -= m;
00479       }
00480       break;
00481     }
00482     first = false;
00483   }
00484   delete[] synaps_input;
00485 }
00486 //----------------------------------------------------------------------
00487 template <class C,class O, class R>
00488   inline MPol<C,O,R>::MPol (const char * s, const Variables&  vars )
00489 {
00490   Variables V(vars);
00491   *this= MPol<C,O,R>(s,V);
00492 }
00493 //----------------------------------------------------------------------
00494 // template <class C,class O, class R>
00495 // inline MPol<C,O,R> & MPol<C,O,R>::operator += (const typename MPol<C,O,R>::monom_t & m){
00496 //   if (m.coeff()!=0)
00497 //     MPOLDST::insert<C,O,R>(rep(), rep().begin(), m);
00498 //   return *this;
00499 // }
00500 //----------------------------------------------------------------------
00501 template <class C,class O, class R>
00502 inline MPol<C,O,R> & MPol<C,O,R>::operator+= (const MPol<C,O,R> & P)
00503 {
00504   if (P==0) return *this;
00505   if (*this==0)
00506     {*this = P; return *this;}
00507   else
00508     MPOLDST::add<O,R>(rep(),P.rep());
00509   return *this;
00510 }
00511 //----------------------------------------------------------------------
00512 template <class C,class O, class R>
00513 inline MPol<C,O,R> & MPol<C,O,R>::operator-= (const MPol<C,O,R> & P){
00514   if (P==0) return *this;
00515   if (*this==0) {*this = -P; return *this;}
00516   *this += (-P);
00517   return *this;
00518 }
00519 //----------------------------------------------------------------------
00520 template <class C,class O, class R>
00521 inline MPol<C,O,R> & MPol<C,O,R>::operator*= (const typename MPol<C,O,R>::coeff_t & c){
00522   MPol<C,O,R> P;
00523   for (iterator i = begin(); i != end(); i++) {
00524     (*i)*= c;
00525   }
00526   return *this;
00527 }
00528 //----------------------------------------------------------------------
00529 template <class C,class O, class R>
00530 inline MPol<C,O,R> & MPol<C,O,R>::operator/= (const typename MPol<C,O,R>::coeff_t & c){
00531   MPol<C,O,R> P;
00532   for (iterator i = begin(); i != end(); i++) { (*i)/= c;
00533   }
00534   return *this;
00535 }
00536 //----------------------------------------------------------------------
00537 template <class C,class O, class R>
00538 inline MPol<C,O,R> & MPol<C,O,R>::operator/= (const typename MPol<C,O,R>::monom_t & m){
00539 
00540   if ( (*this!=0)  && (m.coeff() !=0) ) {
00541     MPol<C,O,R> P(*this);
00542     for (iterator i = P.begin(); i != P.end(); i++) {
00543       int n=m.nvars();
00544       if (n<=(*i).nvars())
00545         while (((*i)[n] >= m[n] ) && ( n >= 0)) n--;
00546       if (n<0)
00547         *i=div(*i,m);
00548       else return *this;
00549     }
00550     (rep()=P.rep());
00551   }
00552   return *this;
00553 }
00554 //----------------------------------------------------------------------
00555 template <class C,class O, class R>
00556 inline MPol<C,O,R> & MPol<C,O,R>::operator*= (const typename MPol<C,O,R>::monom_t & m){
00557  if(m !=0)
00558    {
00559      MPol<C,O,R> P;
00560      for (iterator i = begin(); i != end(); i++) {
00561        (*i)*= m;
00562      }
00563    }
00564  else
00565    *this=0;
00566  return *this;
00567 }
00568 //----------------------------------------------------------------------
00569 template <class C,class O, class R>
00570 inline  MPol<C,O,R> & MPol<C,O,R>::operator*= (const MPol<C,O,R> & b)
00571 {
00572   assert(&rep() != &b.rep());
00573   if(*this !=0)
00574     if(b!=0)
00575       {
00576         const self_t a(*this);
00577         *this=0;
00578         MPOLDST::mul(rep(),a.rep(),b.rep(),O());
00579       }else
00580         (*this)= self_t(0);
00581   return *this;
00582 }
00583 //----------------------------------------------------------------------
00584 template <class C,class O, class R>
00585 inline  MPol<C,O,R> & MPol<C,O,R>::operator/= (const MPol<C,O,R> & Q){
00586   assert(Q != 0);
00587   MPol<C,O,R> P(*this), quo;
00588   MPOLDST::div_rem_x(quo,P,Q);
00589   *this=quo;
00590   return *this;
00591 }
00592 //----------------------------------------------------------------------
00593 template <class C,class O, class R>
00594 template<class T>
00595 typename MPol<C,O,R>::coeff_t
00596 MPol<C,O,R>::operator()(const T & p) const
00597 {
00598   coeff_t r(0);
00599   for(const_iterator it=begin(); it!=end(); ++it)
00600     {
00601       coeff_t s(it->coeff());
00602       for(unsigned int i=0;i<(*it).rep().size();++i)
00603         s*=pow(p[i],(int)(*it)[i]);
00604       r+=s;
00605     }
00606   return r;
00607 }
00608 //----------------------------------------------------------------------
00609 // Boolean operators and functions
00610 //----------------------------------------------------------------------
00611 template <class C,class O, class R> inline
00612 bool MPol<C,O,R>::operator ==(int n) const
00613 {
00614   if(n==0)
00615     if (rep().size()==0)
00616       return true;
00617     else
00618       return false;
00619   else
00620     if (rep().size() ==0)
00621       return false;
00622     else
00623       return(rep().size()==1 && (rep().begin()->coeff() ==n));
00625  /* if ( n==0 && rep().size() == 0 ) 
00626     return true;
00627   if (rep().size() == 0 )   return false;
00628   return(rep().size()==1 && (rep().begin()->coeff() ==n));
00629  */
00630 }
00631 //----------------------------------------------------------------------
00632 template <class C,class O, class R>
00633 bool operator== (const MPol<C,O,R> & P, const MPol<C,O,R> & Q)
00634 {
00635         return P.rep() == Q.rep();
00636 }
00637 //----------------------------------------------------------------------
00638 template <class C,class O, class R>
00639 bool operator!= (const MPol<C,O,R> & P, const MPol<C,O,R> & Q)
00640 {
00641         return !(P.rep() == Q.rep());
00642 }
00643 //----------------------------------------------------------------------
00644 template <class C,class O, class R>
00645 bool operator< (const MPol<C,O,R> & P, const MPol<C,O,R> & Q)
00646 {
00647         typename MPol<C,O,R>::const_iterator iP = P.begin();
00648         typename MPol<C,O,R>::const_iterator iQ = Q.begin();
00649         while (iP != P.end() && iQ != Q.end() && IsComparable(*iP,*iQ)) {
00650                 ++iP;
00651                 ++iQ;
00652         }
00653         if (iQ == Q.end())
00654                 return false;
00655         if (iP == P.end())
00656                 return true;
00657         return O::less(*iP,*iQ);
00658 }
00659 //----------------------------------------------------------------------
00660 template <class C,class O, class R>
00661 bool operator> (const MPol<C,O,R> & P, const MPol<C,O,R> & Q){
00662         return Q < P;
00663 }
00664 //----------------------------------------------------------------------
00665 template <class C,class O, class R>
00666 bool operator>= (const MPol<C,O,R> & P, const MPol<C,O,R> & Q){
00667         return !(P < Q);
00668 }
00669 //----------------------------------------------------------------------
00670 template <class C,class O, class R>
00671 bool operator<= (const MPol<C,O,R> & P, const MPol<C,O,R> & Q){
00672         return !(Q < P);
00673 }
00674 //======================================================================
00675 // Input/putput operators
00676 //======================================================================
00678 template <class C,class O, class R>
00679 std::istream & operator>> (std::istream & is, MPol<C,O,R> & P)
00680 {
00681         std::string s,ss = "";
00682         int p;
00683         for (;;) {
00684                 is >> s;
00685                 p = s.find(';');
00686                 if (p== -1) s.find(':');
00687                 if (p== -1) s.find(',');
00688                 if (p== -1)
00689                         ss += s;
00690                 else {
00691                         ss += s.substr(0,p+1);
00692                         break;
00693                 }
00694         }
00695         P = MPol<C,O,R>(ss.c_str());
00696         return is;
00697 }
00698 //----------------------------------------------------------------------
00700 template <class C, class O, class R>
00701 std::ostream & operator<< (std::ostream & os, const MPol<C,O,R> & P)
00702 {
00703   MPOLDST::print(os,P); return os;
00704 }
00705 
00707 template <class C, class O, class R>
00708 std::ostream & print (std::ostream & os, const MPol<C,O,R> & P, const Variables& V=Variables::default_)
00709 {
00710   MPOLDST::print(os,P,V); return os;
00711 }
00712 //----------------------------------------------------------------------
00714 template <class C, class O, class R>
00715 MPol<C,O,R> operator+(const MPol<C,O,R> & a, const MPol<C,O,R> & b)
00716 {
00717   MPol<C,O,R> p;
00718   if(&p == &a && &p == &b)
00719     MPOLDST::add<O,R>(p.rep(),MPol<C,O,R>(b).rep());
00720   else if(&p == &a)
00721     MPOLDST::add<O,R>(p.rep(),b.rep());
00722   else if(&p == &b)
00723     MPOLDST::add<O,R>(p.rep(),a.rep());
00724   else
00725     MPOLDST::add<O,R>(p.rep(),a.rep(),b.rep());
00726   return p;
00727 }
00728 //----------------------------------------------------------------------
00730 template <class C, class O, class R>
00731 MPol<C,O,R> operator+(const MPol<C,O,R> & a,
00732                       const typename MPol<C,O,R>::coeff_t & c)
00733 {
00734   return a + MPol<C,O,R>(c);
00735 }
00736 //--------------------------------------------------------------------
00738 template <class C, class O, class R>
00739 MPol<C,O,R> operator+(const MPol<C,O,R> & a,
00740                       const typename MPol<C,O,R>::monom_t & m)
00741 {
00742   return a + MPol<C,O,R>(m);
00743 }
00744 //----------------------------------------------------------------------
00746 template <class C, class O, class R>
00747 MPol<C,O,R> operator+(const typename MPol<C,O,R>::coeff_t & c,
00748                       const MPol<C,O,R> & a)
00749 {
00750   return a + MPol<C,O,R>(c);
00751 }
00752 //----------------------------------------------------------------------
00753 // operator -
00754 template <class C, class O, class R>
00755 MPol<C,O,R> operator-(const MPol<C,O,R> & a, const MPol<C,O,R> & b)
00756 {
00757   return (a + (-b));
00758 }
00759 template <class C, class O, class R> inline
00760 MPol<C,O,R> operator-(const MPol<C,O,R> & a,
00761                       const typename MPol<C,O,R>::coeff_t & c)
00762 {
00763   return a - MPol<C,O,R>(c);
00764 }
00765 template <class C, class O, class R> inline
00766 MPol<C,O,R> operator-(const typename MPol<C,O,R>::coeff_t & c,
00767                       const MPol<C,O,R> & a)
00768 {
00769   return MPol<C,O,R>(c) - a;
00770 }
00771 //--------------------------------------------------------------------
00772 template <class C, class O, class R> inline
00773 MPol<C,O,R> operator-(const MPol<C,O,R> & a,
00774                       const typename MPol<C,O,R>::monom_t & m)
00775 {
00776   return a - MPol<C,O,R>(m);
00777 }
00778 template <class C, class O, class R> inline
00779 MPol<C,O,R> operator-(const typename MPol<C,O,R>::monom_t & m,
00780                       const MPol<C,O,R> & a)
00781 {
00782   return MPol<C,O,R>(m) - a;
00783 }
00784 //----------------------------------------------------------------------
00785 // Unary operator -
00786 template <class C, class O, class R> inline
00787 MPol<C,O,R> operator-(const MPol<C,O,R> & a)
00788 {
00789   return a*((typename MPol<C,O,R>::coeff_t)-1);
00790 }
00791 //----------------------------------------------------------------------
00792 // Product of polynomials
00793 template <class C, class O, class R>
00794 MPol<C,O,R> operator*(const MPol<C,O,R> & a, const MPol<C,O,R> & b)
00795 {
00796   MPol<C,O,R> p;
00797   if(a !=0 && b !=0)
00798     MPOLDST::mul(p.rep(),a.rep(),b.rep(),O());
00799   else
00800     p= MPol<C,O,R>(0);
00801   return p;
00802 }
00803 //----------------------------------------------------------------------
00804 // Product of a polynomial by a "scalar"
00805 template <class C, class O, class R>
00806 MPol<C,O,R> operator*(const MPol<C,O,R> & a, const C & c)
00807 {
00808   MPol<C,O,R> p;
00809   if(a!=0 && c!=0)
00810     MPOLDST::mul_ext(p.rep(),a.rep(),c);
00811  else
00812     p= MPol<C,O,R>(0);
00813   return p;
00814 }
00815 //----------------------------------------------------------------------
00816 template <class C, class O, class R> inline
00817 MPol<C,O,R> operator*(const typename MPol<C,O,R>::coeff_t & c,
00818                      const MPol<C,O,R> & a)
00819 {
00820   return a*c;
00821 }
00822 //----------------------------------------------------------------------
00823 template <class C, class O, class R> inline
00824 MPol<C,O,R> operator*(int c,const MPol<C,O,R> & a)
00825 {
00826   return a*MPol<C,O,R>::coeff_t(c);
00827 }
00828 //----------------------------------------------------------------------
00829 template <class C, class O, class R> inline
00830 MPol<C,O,R> operator*(const MPol<C,O,R> & a,
00831                       const typename MPol<C,O,R>::monom_t & m)
00832 {
00833   MPol<C,O,R> p;
00834   if(a!=0)
00835     MPOLDST::mul_ext(p.rep(),a.rep(),m);
00836   else
00837     p= MPol<C,O,R>(0);
00838   return p;
00839 }
00840 //----------------------------------------------------------------------
00841 template <class C, class O, class R> inline
00842 MPol<C,O,R> operator*(const typename MPol<C,O,R>::monom_t & m,
00843                      const MPol<C,O,R> & a)
00844 {
00845   return a*m;
00846 }
00847 //----------------------------------------------------------------------
00848 template <class C, class O, class R> inline
00849 MPol<C,O,R> operator/(const MPol<C,O,R> & A, const MPol<C,O,R> & B)
00850 {
00851   MPol<C,O,R> x=A; x/=B; return x;
00852 }
00853 //----------------------------------------------------------------------
00854 template <class C, class O, class R> inline
00855 MPol<C,O,R> operator%(const MPol<C,O,R> & a, const MPol<C,O,R> & b)
00856 {
00857   assert(b != 0);
00858   MPol<C,O,R> r(a), quo;
00859   MPOLDST::div_rem_x(quo,r,b);
00860   return r;
00861 }
00862 //----------------------------------------------------------------------
00863 template <class C, class O, class R>
00864 MPol<C,O,R> operator^(const MPol<C,O,R> & a, unsigned int n)
00865 {
00866   MPol<C,O,R> p;
00867   if(n ==0) p = 1;
00868   else {
00869     p=1;
00870     unsigned N = n;
00871     while(N>0) {p*=a; N--;}
00872   }
00873   return p;
00874 }
00875 
00876 
00877 // //--------------------------------------------------------------------
00878 // /** This function let the variable of index \c i appear as the string
00879 //     \c s. This association is also used, when a polynomial is parsed.
00880 //     In other words, if the variable \c s is parsed, then its index is
00881 //     \c i.
00882 // **/
00883 // template<class T> void Variable(unsigned i, const std::string & s)
00884 // {
00885 //   T::monom_t::_var_of_index[i+1]=s;
00886 //   T::monom_t::_index_of_var[s]=i+1;
00887 // }
00888 // //----------------------------------------------------------------------
00889 // /**  Return the variable of index \c i **/
00890 // template<class T> std::string Variable(unsigned i)
00891 // {
00892 //   return T::monom_t::var_of_index(i);
00893 // }
00894 // //----------------------------------------------------------------------
00895 // /**  Return the index of a variable \c s **/
00896 // template<class T> unsigned IndexOf(const std::string & s)
00897 // {
00898 //   return T::monom_t::index_of_var(s);
00899 // }
00900 //--------------------------------------------------------------------
00901 template<class C, class O, class R, class X>
00902 MPol<C,O,R> subs( int variable, const X & value, class MPol<C,O,R> & polynom )
00903 {
00904   //  using namespace MPOLDST;
00905   return MPOLDST::subs( variable, value, polynom );
00906 };
00907 __END_NAMESPACE_SYNAPS
00908 //======================================================================
00909 #endif // SYNAPS_MPOL_MPOL_H
00910 

SYNAPS DOCUMENTATION
logo