realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/sparse_monomials.hpp
Go to the documentation of this file.
00001 #ifndef  realroot_sparse_monomials_hpp
00002 #define  realroot_sparse_monomials_hpp
00003 # include <list>
00004 # include <vector>
00005 # include <algorithm>
00006 # include <realroot/binomials.hpp>
00007 # include <realroot/Seq.hpp>
00008 # include <realroot/monomial.hpp>
00009 # include <realroot/monomial_ordering.hpp>
00010 # define TMPL  template<class C, class O, class MONOM, class REP>
00011 # define TMPLX template<class C, class O, class MONOM, class REP, class X>
00012 # define Polynomial monomial_seq<C,O,MONOM,REP>
00013 # define CLASS      monomial_seq
00014 # define sparse_monomials  sparse::monomial_seq
00015 //======================================================================
00016 namespace mmx {
00017 
00018 
00019 //--------------------------------------------------------------------
00020 
00022 namespace sparse {
00023 
00024   template<class C, class O = DegRevLex, 
00025            class MONOM=monom<C>, 
00026            class REP=std::list<MONOM> >
00027   struct CLASS : public REP {
00028 
00029     typedef C                                       coeff_t;
00030     typedef C                                       Scalar;
00031     typedef C                                       value_type;
00032     typedef O                                       Order;
00033     typedef REP                                     base_t;
00034     typedef typename base_t::value_type             monom_t;
00035     typedef typename base_t::value_type             Monomial;
00036     typedef typename base_t::iterator               iterator;
00037     typedef typename base_t::const_iterator         const_iterator;
00038     typedef typename base_t::reverse_iterator       reverse_iterator;
00039     typedef typename base_t::const_reverse_iterator const_reverse_iterator;
00040     typedef Polynomial                              self_t;
00041     
00042     Polynomial(): base_t() {}
00043     Polynomial(const C& c):base_t() {
00044       if (c!=(coeff_t)0)
00045         this ->push_back(monom_t(c));
00046     }
00047 
00048 
00049     Polynomial(const C& c, int d, unsigned v);
00050     Polynomial(const monom_t& m): base_t() { this->push_back(m);};
00051 
00052     bool operator==( const Polynomial& p ) const;
00053     bool operator!=( const Polynomial& p ) const { return !(*this==p); }
00054     bool operator==( const C& c ) const;
00055     bool operator!=( const C& c ) const { return !(*this==c); }
00056 
00057     int nbvar() const;
00058 
00059     static MonomialOrdering * m_order;
00060     static MonomialOrdering * order() {return m_order;}
00061     static bool 
00062     less (const monom_t & m1, const monom_t & m2) {
00063       //      std::cout<<"less "<< m1<< " "<< m2<<std::endl;
00064       return m_order->less(m1.begin(),m1.size(), 
00065                            m2.begin(),m2.size());
00066     }
00067   }; 
00068 }//namespace sparse
00069 
00070 // #ifndef MMX_WITH_PLUS_SIGN
00071 // #define MMX_WITH_PLUS_SIGN
00072 //   template<class X> bool with_plus_sign(const X& x) {return true;}//x>0;}
00073 // #endif  //MMX_WITH_PLUS_SIGN
00074 //   TMPL bool with_plus_sign(const SparsePolynomial& x) {return true;}
00075 
00076 
00077   namespace sparse {
00078   
00079   TMPL MonomialOrdering* Polynomial::m_order = (MonomialOrdering*)new O; //DegreeLex;
00080 
00081 
00082   TMPL inline
00083   Polynomial::CLASS(const C& c, int d, unsigned v):base_t() {
00084       this ->push_back(monom_t(c,d,v));}
00085 
00087   TMPL int 
00088   Polynomial::nbvar() const{
00089     int v = 0;
00090     for (const_iterator it = this->begin(); it != this->end(); ++it)
00091       v = std::max(v,it->l_variable()+1);
00092     return v;
00093   }
00094 
00095 
00096   TMPL bool 
00097   Polynomial::operator== (const Polynomial& p) const {
00098     return ((base_t)*this==(base_t)p);
00099   }
00100 
00101   TMPL bool 
00102   Polynomial::operator== (const C& c) const {
00103     if(c==0)
00104       return (this->size()==0);
00105     else
00106       return(this->size()==1 && (this->begin()->coeff() == c) && degree(*this->begin())== 0);
00107   }
00108 
00109   
00110   //====================================================================  
00111   TMPL void 
00112   add(Polynomial & result, const Polynomial& p1, const Polynomial& p2)
00113   {
00114     assert(&result != &p1); assert(&result != &p2);
00115     
00116     typedef typename Polynomial::const_iterator  const_iterator;
00117     typedef typename Polynomial::iterator        iterator;
00118     typedef typename Polynomial::value_type      coeff_type;
00119     typedef typename Polynomial::Scalar          Scalar;
00120 
00121     const_iterator
00122       b1=p1.begin(),
00123       e1=p1.end(),
00124       b2=p2.begin(),
00125       e2=p2.end();
00126     result.resize(p1.size()+p2.size());
00127     iterator i=result.begin();
00128     while (b1!=e1 && b2!=e2) {
00129       if(Polynomial::less(*b2,*b1))
00130         *i++=*b1++;
00131       else if(Polynomial::less(*b1,*b2))
00132         *i++=*b2++;
00133       else {
00134         coeff_type c=b1->coeff()+ b2->coeff();
00135         if (c !=(Scalar)0) {
00136           *i =*b1;
00137           i->set_coeff(c);
00138           ++i;
00139         }
00140         ++b1;++b2;
00141       }
00142     }
00143     while (b1!=e1) *i++=*b1++;
00144     while (b2!=e2) *i++=*b2++;
00145     
00146     int m=std::distance(result.begin(),i);
00147     assert(m>=0);
00148     result.resize(m);
00149   }
00150   //----------------------------------------------------------------------
00152   TMPL void 
00153   add(Polynomial & p1, const Polynomial& p2) {
00154     
00155     assert(&p1 != &p2);
00156     typedef typename Polynomial::const_iterator  const_iterator;
00157     typedef typename Polynomial::iterator        iterator;
00158     typedef typename Polynomial::value_type      coeff_type;
00159     
00160     //    reserve(p1,p1.size()+p2.size());
00161     iterator        b1=p1.begin();
00162     const_iterator  b2=p2.begin();
00163     while (b1!=p1.end() && b2!=p2.end()) {
00164       if(Polynomial::less(*b2,*b1))
00165         b1++;
00166       else if(Polynomial::less(*b1,*b2))
00167         {
00168           b1 = p1.insert(b1,*b2); b1++; b2++;
00169         }
00170       else
00171         {
00172           coeff_type c=b1->coeff() + b2->coeff();
00173           if (c != (typename Polynomial::Scalar)0) {
00174             b1->set_coeff(c); ++b1;
00175           }else{
00176             b1 = p1.erase(b1);
00177           }
00178           ++b2;
00179         }
00180     }
00181     p1.insert(b1,b2,p2.end());
00182   }
00183   //----------------------------------------------------------------------
00184     template<class C, class O, class MONOM, class REP, class I, class J, class M>
00185   I add(Polynomial & p1, I b1, J e1, const M & m2) {
00186     typedef typename Polynomial::value_type::coeff_t coeff_type;
00187     
00188     while (b1!=e1) {
00189       if(Polynomial::less(m2,*b1))
00190         {
00191           b1++; //COUNT<M>('i');
00192         }
00193       else if(Polynomial::less(*b1,m2))
00194         {
00195           b1=p1.insert(b1,m2);
00196           return b1;
00197         }
00198       else
00199         {
00200           coeff_type c=b1->coeff() + m2.coeff();
00201           if (c !=0) {
00202             b1->set_coeff(c);
00203           }else
00204             b1 = p1.erase(b1);
00205           return(b1);
00206         }
00207     }
00208     b1 = p1.insert(b1,m2);
00209     return b1;
00210   }
00211   //----------------------------------------------------------------------
00212   TMPL void
00213   add(Polynomial & p, const typename Polynomial::monom_t& m) {
00214     Polynomial q(m); add(p,q);
00215   }
00216 
00217   TMPL void
00218   add(Polynomial & p, const C& c) {
00219     Polynomial m(c); add(p,m);
00220   }
00221   //----------------------------------------------------------------------
00222   TMPLX void
00223   add(Polynomial & r, const Polynomial& q, const X& c) {
00224     Polynomial m(c); add(r,q,m);
00225   } 
00226   //----------------------------------------------------------------------
00227   TMPL void
00228   add(Polynomial & r, const C& c, const Polynomial& q) {
00229     Polynomial m(c); add(r,q,m);
00230   }
00231   //----------------------------------------------------------------------
00232   TMPL void 
00233   sub(Polynomial & result, const Polynomial& p1, const Polynomial& p2)
00234   {
00235     assert(&result != &p1); assert(&result != &p2);
00236     typedef typename Polynomial::const_iterator  const_iterator;
00237     typedef typename Polynomial::iterator        iterator;
00238     typedef typename Polynomial::value_type      coeff_type;
00239     const_iterator
00240       b1=p1.begin(),
00241       e1=p1.end(),
00242       b2=p2.begin(),
00243       e2=p2.end();
00244     result.resize(p1.size()+p2.size());
00245     iterator i=result.begin();
00246     while (b1!=e1 && b2!=e2) {
00247       if(Polynomial::less(*b2,*b1))
00248         *i++=*b1++;
00249       else if(Polynomial::less(*b1,*b2))
00250         {
00251           *i=*b2++; i->coeff()*= -1; i++;
00252         }
00253       else {
00254         coeff_type c=b1->coeff()- b2->coeff();
00255         if (c !=0) {
00256           *i =*b1;
00257           i->set_coeff(c);
00258           ++i;
00259         }
00260         ++b1;++b2;
00261       }
00262     }
00263     while (b1!=e1) *i++=*b1++;
00264     while (b2!=e2) {*i=*b2++;i->coeff()*=-1;i++;}
00265     
00266     int m=std::distance(result.begin(),i);
00267     assert(m>=0);
00268     result.resize(m);
00269   }
00270   //--------------------------------------------------------------------  
00271   TMPL void
00272   sub(Polynomial & p, const Polynomial& q) {
00273     Polynomial m(q); mul(m,(C)-1);
00274     add(p,m);
00275   }
00276   //--------------------------------------------------------------------
00277   TMPLX void
00278   sub(Polynomial & r, const Polynomial& q, const X& c) {
00279     Polynomial m(C(-c)); add(r,q,m);
00280   }
00281   //--------------------------------------------------------------------    
00282   TMPLX void
00283   sub(Polynomial & r, const X& c, const Polynomial& q) {
00284     Polynomial m(c); sub(r,m,q);
00285   }
00286   //----------------------------------------------------------------------
00288   TMPL void 
00289   mul(Polynomial &r, const C & c) {
00290     for(typename Polynomial::iterator it=r.begin(); it!=r.end(); ++it) {
00291       it->coeff()*=c;
00292     }
00293   }
00294   //----------------------------------------------------------------------
00295   TMPL void 
00296   mul(Polynomial &r, const Polynomial& p, const C & c) {
00297     r = p; mul(r,c);
00298   }
00299 
00300   //----------------------------------------------------------------------
00301   TMPLX void 
00302   mul(Polynomial &r, const X & c, const Polynomial& p) {
00303     r = p; mul(r,c);
00304   }
00305   //----------------------------------------------------------------------
00307   template <class C, class O, class MONOM, class REP, class M> inline  void 
00308   mul_ext(Polynomial &r, const Polynomial& a, const M & m) {
00309     r.resize(a.size());
00310     typename Polynomial::const_iterator b=a.begin(); 
00311     typename Polynomial::iterator i=r.begin();
00312     for(; b!=a.end(); ++i, ++b) *i = (*b) * m; 
00313      //    VECTOR::apply_mult(r, a, m);
00314   }
00315   //----------------------------------------------------------------------
00317   TMPL inline  void 
00318   mul(Polynomial &r, const Polynomial& a, const typename Polynomial::monom_t & m) {
00319     mul_ext(r,a,m);
00320   }
00321   //----------------------------------------------------------------------
00323   TMPL inline  void 
00324   mul(Polynomial &r, const typename Polynomial::monom_t & m) {
00325     typename Polynomial::iterator i=r.begin();
00326     for(; i!=r.end(); ++i) *i *= m; 
00327   }
00328   //----------------------------------------------------------------------
00329   template<class C, class O, class MONOM, class REP, class M> inline  void 
00330   mul_ext_e(Polynomial &result, const Polynomial& a, const M & m)
00331   {
00332     typedef typename Polynomial::const_iterator  const_iterator;
00333     typedef typename Polynomial::iterator        iterator;
00334     typedef typename Polynomial::monom_t         R;
00335 
00336     result.resize(0);
00337     iterator i=result.begin();
00338     R tmp;
00339     for(const_iterator b=a.begin();b!=a.end(); ++b)
00340       {
00341         tmp = (*b) * m;
00342         (i=result.insert(i,tmp))++;
00343       }
00344   }
00345 //----------------------------------------------------------------------
00347   TMPL inline void 
00348   mul(Polynomial &r, const Polynomial& a, const Polynomial& b)
00349   {
00350     if (a.size()==0) return;
00351     if (b.size()==0) return;
00352     if (a.size()<b.size())
00353       mul(r,a.begin(),a.end(),b);
00354     else
00355       mul(r,b.begin(),b.end(),a);
00356   }
00357 
00359   TMPLX inline void 
00360   mul(Polynomial &r, 
00361       const Polynomial& a, 
00362       const Polynomial& b, const X & o)
00363   {
00364     typedef typename Polynomial::const_iterator const_iterator;
00365     typedef typename Polynomial::iterator       iterator;
00366     typedef typename Polynomial::monomt_t       M;
00367 
00368     r.resize(0);
00369     M m;
00370     for(const_iterator i=b.begin();i !=b.end();i++)
00371       {
00372         if(r.size())
00373           {
00374             iterator ip = r.begin();
00375             for(const_iterator j=a.begin();j != a.end();j++) { 
00376               m  = *j * *i;
00377               ip = add(r,ip,r.end(),m);//,O()); 
00378             }
00379             //MPOLDST::mul_ext(tmp,a,*i);
00380             //MPOLDST::add<list<M>,vector<M>,O>(r,tmp);
00381           }
00382         else
00383           mul_ext(r,a,*i);
00384       }
00385   }
00386 
00387   //----------------------------------------------------------------------
00388   TMPL inline void 
00389   mul(Polynomial &r,
00390       typename Polynomial::const_iterator b,
00391       typename Polynomial::const_iterator e, 
00392       const Polynomial& p) {
00393 
00394     
00395     typedef typename Polynomial::const_iterator  const_iterator;
00396     int n=std::distance(b,e);
00397     assert(n>=0);
00398     if (n==0) r.resize(0);
00399     if (n==1) 
00400       mul_ext(r,p,*b);
00401     else {
00402       const_iterator med=b; // b+(n/2);
00403       for(int i=0; i<n/2 && med !=e;i++,med++) {}
00404 
00405       Polynomial tmp0((C)0), tmp1((C)0);
00406       mul(tmp0,b,med,p);
00407       mul(tmp1,med,e,p);
00408       add(r,tmp0,tmp1);
00409     }
00410 
00411   }
00412   TMPL inline void 
00413   mul(Polynomial &r, const Polynomial& p)
00414   {
00415     Polynomial s(r); mul(r,s,p); 
00416   }
00417   //----------------------------------------------------------------------
00418   TMPL inline void 
00419   div(Polynomial &q, const Polynomial& a, const Polynomial& b)
00420   {
00421     Polynomial r(a);
00422     div_rem(q,r,b);
00423   }
00424 
00425   TMPL inline void 
00426   div(Polynomial &r, const Polynomial& b)
00427   {
00428     Polynomial a(r);
00429     div(r,a,b);
00430   }
00431 
00432   TMPL inline void 
00433   div(Polynomial &f, const typename Polynomial::Scalar& c)
00434   {
00435     for(typename Polynomial::iterator it=f.begin(); it != f.end(); it++) 
00436       it->coeff()/=c;
00437   }
00438 
00439   //----------------------------------------------------------------------
00440   TMPL void 
00441   div(Polynomial &r, const Polynomial& p, const C & c) {
00442     r = p; div(r,c);
00443   }
00444 
00445   //----------------------------------------------------------------------
00446   TMPL inline void 
00447   rem(Polynomial &r, const Polynomial& a, const Polynomial& b)
00448   {
00449     Polynomial q; r=a;
00450     div_rem(q,r,b);
00451   }
00452  
00453   //----------------------------------------------------------------------
00454     template<class C, class O, class MONOM, class REP, class U> void
00455   coefficients(Seq<U>& r,const Polynomial& f,int v) {
00456     unsigned N = degree(f,v)+1;
00457     r=Seq<U>(N);
00458     typename Polynomial::monom_t m;
00459     for(typename Polynomial::const_iterator it=f.begin(); it != f.end(); it++) {
00460       m=*it;
00461       if (v<(int)m.size()) m.set_expt(v,0);
00462       r[(*it)[v]]+= U(m);
00463     }
00464   }
00465 
00466   TMPL void
00467   coefficients(Seq<C>& r, const Polynomial& f) {
00468     for(typename Polynomial::const_iterator it=f.begin(); it != f.end(); it++) {
00469       r<<it->coeff();
00470     }
00471   }
00472   //----------------------------------------------------------------------
00474   template <class R>  int lvar (const R & p) {
00475   int v = -1;
00476   for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00477     v = std::max(v,it->l_variable());
00478   return v;
00479   }
00480   //--------------------------------------------------------------------
00482   template <class R>  unsigned nbvar (const R & p) {
00483     return p.nbvar();
00484   }
00485   //----------------------------------------------------------------------
00487   template <class R>  int 
00488   degree (const R & p) {
00489     if(!p.size())
00490       return -1;
00491     else
00492       {
00493         int d = 0;
00494         for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00495           d = std::max(d,degree(*it));
00496         return d;
00497       }
00498   }
00499 
00501   template <class R>  int 
00502   degree (const R & p, int i) {
00503     if(!p.size())
00504       return -1;
00505     else
00506       {
00507         int d=0;
00508         for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00509           {
00510             if(i<=it->nvars()) d = std::max(d,(int)(*it)[i]);
00511           }
00512         return d;
00513       }
00514   }
00515   //----------------------------------------------------------------------
00516   template<class R> typename R::coeff_t& 
00517   leadingcoeff(R & a)       {return a.begin()->coeff();}
00518   //----------------------------------------------------------------------
00519   template<class R> typename R::coeff_t   
00520   leadingcoeff(const R & a) {return a.begin()->coeff();}
00521   //----------------------------------------------------------------------
00526   template<class POL> typename POL::coeff_t 
00527   coeffof(const POL & p,
00528           const typename POL::monom_t & mono)
00529   {
00530     typedef typename POL::coeff_t coeff_t;
00531     typename POL::const_iterator m;
00532     for(m = p.begin();  m!= p.end() && !IsComparable((*m),mono); m++) {}
00533     if(m != p.end())
00534       {
00535         return m->coeff();
00536       }
00537     else
00538       {
00539         return  coeff_t(0);
00540       }
00541   }
00542 
00543   template<class POL> typename POL::const_iterator 
00544   last_term(const POL& p) {
00545     assert(p.size()>0);
00546     typename POL::const_iterator it=p.end();
00547     it--;
00548     return it;
00549   }
00550 
00551 
00552   //----------------------------------------------------------------------
00554   template<class R> void 
00555   div_rem(R & q, R & a, const R & b0) {
00556     //    std::cout <<"---- Begin div-rem sparse -----"<<std::endl;
00557     typedef typename R::monom_t       monom_t;
00558     typedef typename monom_t::coeff_t coeff_t;
00559     q= R((coeff_t)0);
00560 
00561     if(a==0) return;
00562     
00563     R b(b0);
00564     //coeff_t cb =b0.begin()->coeff();
00565     //  b/=cb;
00566     monom_t mb = (*b.begin()), m;
00567     R t;
00568     while( a != (coeff_t)0 && divide(*a.begin(), mb, m) )
00569       {
00570         mul(t,b,m);
00571         sub(a,t);
00572         if ( m != 0 )  add(q,m);
00573         //      print(std::cout,a); std::cout<<std::endl;
00574       }
00575     //    std::cout <<"---- End div-rem sparse -----"<<std::endl;
00576   }
00577   
00578   //----------------------------------------------------------------------
00580   TMPL void 
00581   diff(Polynomial & r, const Polynomial & p, int i)
00582   {
00583     typedef typename Polynomial::Monomial Monomial;
00584     typedef typename Polynomial::Scalar   Scalar;
00585 
00586     assert(&r != &p);
00587     r= Polynomial((Scalar)0);
00588     for (typename Polynomial::const_iterator it = p.begin(); it != p.end(); ++it) {
00589       if((*it)[i]>0){
00590         Monomial m(*it);
00591         m*=(typename Polynomial::coeff_t)(*it)[i];
00592         m.set_expt(i,(*it)[i]-1);
00593         add(r,m);
00594       }
00595     }
00596   }
00597 
00598   //----------------------------------------------------------------------
00600   TMPL void 
00601   shift(Polynomial & r, const Polynomial & p, const typename Polynomial::monom_t& m)
00602   {
00603     assert(&r != &p);
00604     typedef typename Polynomial::monom_t Monomial;
00605     r= Polynomial(0);
00606     for (typename Polynomial::const_iterator it = p.begin(); it != p.end(); ++it) {
00607       add(r,*it*m);
00608     }
00609   }
00610 
00611   //----------------------------------------------------------------------
00613   TMPL void 
00614   copy(Polynomial& r, const Polynomial& a)
00615   {
00616     //to be modified when bug fixed in gcc
00617     //    using dense::reserve;
00618     reserve(r,a.size());
00619     std::copy(a.begin(),a.end(),r.begin());
00620   }
00621   //----------------------------------------------------------------------
00623   TMPL typename Polynomial::coeff_t 
00624   eval(const Polynomial& p,
00625        const typename Polynomial::coeff_t &x,
00626        const typename Polynomial::coeff_t &y) {
00627     typename Polynomial::coeff_t r(0);
00628     for(typename Polynomial::const_iterator it=p.begin(); it!=p.end(); ++it)
00629       {
00630         typename Polynomial::coeff_t c(it->coeff());
00631         //for(unsigned int i=0;i<2;++i)
00632         for(int k=0;k<(int)(*it)[0];k++)
00633           c*=x;
00634         for(int k=0;k<(int)(*it)[1];k++)
00635           c*=y;
00636         r+=c;
00637       }
00638     return r;
00639   }
00640 
00641   //--------------------------------------------------------------------
00642   template<class C,class O, class MONOM, class REP, class R, class VCT>  void
00643   eval_at(R& r,
00644           const Polynomial& p,
00645           const VCT &x) {
00646     r=R(0);
00647     for(typename Polynomial::const_iterator it=p.begin(); it!=p.end(); ++it)
00648       {
00649         R c(it->coeff());
00650         for(unsigned int j=0;j<x.size()&& j<it->nvars();++j)
00651           for(int k=0;k<(int)(*it)[j];k++)
00652             c*=x[j];
00653         r+=c;
00654       }
00655     return r;
00656   }
00657 
00658   //--------------------------------------------------------------------
00660     template<class R, class C, class O, class MONOM, class REP, class X> inline void
00661   eval(R& r, const Polynomial& p, const X& x) {
00662     r=(R)0;
00663     for(typename Polynomial::const_iterator it=p.begin(); it!=p.end(); ++it)
00664       {
00665         R c(it->coeff());
00666         for(int k=0;k<(int)(*it)[0];k++)
00667           c*=x;
00668         r+=(R)c;
00669       }
00670   }
00671 
00672   //----------------------------------------------------------------------
00673   TMPL inline void
00674   homogenize(Polynomial& r, const Polynomial& p, const Polynomial& v) {
00675     Polynomial t;
00676     int d = sparse::degree(p);
00677     for(typename Polynomial::const_iterator it=p.begin();it != p.end();it++) {
00678       t=*it;
00679       for (int i=0;i<d-degree(*it);i++) mul(t,v);
00680       add(r,t);
00681     }
00682   }
00683 
00684   //--------------------------------------------------------------------
00685   TMPL inline void
00686   homogenize(Polynomial& r, const Polynomial& p, int n, const Polynomial& v) {
00687     Polynomial t;
00688     int d = degree(p,n);
00689     for(typename Polynomial::const_iterator it=p.begin();it != p.end();it++) {
00690       t=*it;
00691       for (int i=0;i<d-(*it)[n];i++) mul(t,v);
00692       add(r,t);
00693     }
00694   }
00695   //----------------------------------------------------------------------
00696   
00699   template <class MP> MP 
00700   convert(const MP & P,typename MP::coeff_t x,typename MP::coeff_t y,int ind) {
00701     typedef typename MP::const_iterator  const_iterator;
00702     typedef typename MP::coeff_t coeff_t;
00703     typedef typename MP::monom_t monom_t;
00704     MP  res;
00705     int ind1=0;
00706     int ind2=0;
00707     for(int i=0;i<=2;i++)
00708       {
00709         if(ind!=i) {ind1=i;break;}
00710       }
00711     for(int i=0;i<=2;i++)
00712       {
00713         if(ind!=i && ind1!=i) {ind2=i;break;}
00714       }
00715     for(const_iterator i = P.begin(); i != P.end(); ++i)
00716       {
00717         coeff_t  k=i->coeff();
00718         int puissx=(*i)[ind1];
00719         int puissy=(*i)[ind2];
00720         int d=(*i)[ind];
00721         coeff_t coeff1=pow(x,puissx);
00722         coeff_t coeff2=pow(y,puissy);
00723         k*=coeff1;k*=coeff2;
00724         MP P1=monom_t(k,ind,d);
00725         res=res+P1;
00726       }
00727     return res;
00728   }
00729   
00730   //--------------------------------------------------------------------
00731     template <class OS, class C, class O, class MONOM, class REP, class VARIABLES> OS& 
00732   print(OS & os, const Polynomial & P, const VARIABLES & V) {
00733     if ( P.begin() == P.end() )
00734       {
00735         os << '0';
00736         return os;
00737       }
00738     for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) {
00739       std::ostringstream sm;
00740       print(sm,*i,V);
00741       if(sm.str()[0] != '-' && sm.str()[0] != '+' && i != P.begin())
00742         os <<'+';
00743       os<<sm.str();
00744     }
00745     return os;
00746   }
00747 
00748 
00749     template <class OS, class C, class O, class MONOM, class REP, class VARIABLES> OS& 
00750   print_as_double(OS & os, const Polynomial & P, const VARIABLES & V) {
00751     if ( P.begin() == P.end() )
00752       {
00753         os << '0';
00754         return os;
00755       }
00756     for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) {
00757       std::ostringstream sm;
00758       print_as_double(sm,*i,V);
00759       if(sm.str()[0] != '-' && sm.str()[0] != '+' && i != P.begin())
00760         os <<'+';
00761       os<<sm.str();
00762     }
00763     return os;
00764   }
00765   //--------------------------------------------------------------------
00766   template <class OS, class C, class O, class MONOM, class REP> OS& 
00767   print(OS & os, const Polynomial & P)
00768   {
00769     return print(os,P,variables::default_);
00770   }
00771 
00772  
00773   //----------------------------------------------------------------------
00774   template <class OS, class C, class O, class MONOM, class REP> OS& 
00775   print_verbatim(OS & os, const Polynomial & P)
00776   {
00777     if ( P.begin() == P.end() )
00778       {
00779         os << '0';
00780         return os;
00781       }
00782     for( typename Polynomial::const_iterator i=P.begin(); i != P.end();++i)
00783       {
00784         os<<" "<<i->coeff()<<" [";
00785         for(int l=0;l<i->size();l++) os<<(*i)[l]<<" ";
00786         os<<"]";
00787       }
00788     return os;
00789   }
00790   //----------------------------------------------------------------------
00794   template <class POL, class C> POL 
00795   shift(typename POL::const_iterator monom, const C& a, int i) {
00796     
00797     POL polynom;
00798     // Definition du type monome.
00799     typedef typename POL::monom_t monomial;
00800     // monomiale temporaire.
00801     monomial tmpmonomial;
00802     
00803     int i0 = i;
00804     int i1 = (i + 1) % 3;
00805     int i2 = (i + 2) % 3;
00806     
00807     // Si la variable est presente dans le monome.
00808     if ( (a!=0) && ( monom->operator[](i0) !=0 ) )
00809       {
00810         polynom = binomial< POL >(C(1.), i0, monom->operator[](i0), a);
00811         int expt[3];
00812         expt[i0] = 0;
00813         expt[i1] = monom->operator[](i1);
00814         expt[i2] = monom->operator[](i2);
00815         
00816         if ( ( expt[i0] == 0 ) && ( expt[i1] == 0 ) && ( expt[i2] == 0 ) )
00817           tmpmonomial = monomial( monom->coeff(), 0, 0 );
00818         else   tmpmonomial = monomial( monom->coeff(), 3, expt );
00819         
00820         polynom *= tmpmonomial;
00821       }
00822     // Si a = 0 alors le monome reste inchange.
00823     else polynom = ( *monom );
00824     
00825     return polynom;
00826     
00827   }
00828   //----------------------------------------------------------------------
00831   template < class POL, class C > POL 
00832   scale( const POL &p, C a, int v) {
00833     
00834     typedef typename POL::monom_t monomial;
00835     
00836     POL  np(p);
00837     
00838     for ( typename POL::const_iterator i = np.begin(); i != np.end(); ++i ) {
00839       i->coeff()*= pow( a, int( i->operator[]( v ) ) );
00840     }
00841     return np;
00842     
00843   }
00844   //----------------------------------------------------------------------
00845   template<class T, class MP, class V> T 
00846   eval(const MP& p, const V& v) {
00847     T r(0);
00848     for(typename MP::const_iterator it=p.begin(); it!=p.end(); ++it)
00849       {
00850         T c; let::assign(c,it->coeff());
00851         for(unsigned i=0;i< it->size()&&i<v.size();++i)
00852           for(int k=0;k<(*it)[i];k++)
00853             {
00854               c*=v[i];
00855             }
00856         r+=c;
00857       }
00858     return r;
00859   }
00860 
00861 
00862   //----------------------------------------------------------------------
00863   template<class R, class MP, class V> void 
00864   eval(R& r, const MP& p, const V& v, unsigned n) {
00865     r=R(0);
00866     for(typename MP::const_iterator it=p.begin(); it!=p.end(); ++it)
00867       {
00868         R c; 
00869         let::assign(c,it->coeff());
00870         for(unsigned i=0;i< it->size()&&i<n;++i)
00871           for(int k=0;k<(*it)[i];k++) {
00872             c*=v[i];
00873           }
00874         r+=c;
00875       }
00876   }
00877 
00878   //----------------------------------------------------------------------
00880   template<class MP,class X> MP 
00881   subs( unsigned  var, const X& val, const MP & P)
00882   {
00883     MP Result;//("0");
00884     typedef typename MP::coeff_t coeff_t;
00885     typedef typename MP::Monomial monom_t;
00886     
00887     for( typename MP::const_iterator it = P.begin(); it != P.end(); ++it )
00888       {
00889         if ( it->size() > var )
00890           {
00891             monom_t m (*it);
00892             X tmp = pow(val,m[var]);
00893             m.rep()[var] = 0; 
00894             Result += tmp*m;
00895           }
00896         else 
00897           Result += *it;
00898         
00899       }
00900     return Result;
00901   }
00902   //----------------------------------------------------------------------
00904   template<class MP> MP 
00905   subs(const MP & P, int var, typename MP::coeff_t val)
00906   {
00907     MP Result;//("0");
00908     typedef typename MP::coeff_t coeff_t;
00909     typedef typename MP::Monomial monom_t;
00910         //  std::cout<<"Begin subs!!"<<endl;
00911     coeff_t C=0;
00912     for ( typename MP::const_iterator it = P.begin();
00913           it != P.end(); ++it )
00914       {
00915         monom_t m(it->coeff());
00916         for(int ind=0; ind<(lvar(P)+1); ++ind)
00917           {
00918             if (ind == var)
00919               {
00920                 for(int k=0;k<(int)(*it)[ind];k++)
00921                   m*=val;
00922               }
00923             else
00924               {
00925                 if ((*it)[ind] != 0)
00926                   {
00927                     monom_t mon(ind,(*it)[ind]);
00928                     m*= mon;
00929                   }
00930               }
00931           }
00932         if (m.nvars() == -1)
00933           {
00934             C += m.coeff();
00935           }
00936         else if (m != 0)
00937           Result+= m;
00938       }
00939     if (C != 0)
00940       Result += monom_t(C);
00941           //std::cout<<"End subs!!"<<endl;
00942     return Result;
00943   }
00944 
00945   //----------------------------------------------------------------------
00947   template<class MP> MP 
00948   subs(const MP & P, char* x, typename MP::coeff_t val) {
00949     int xi = MP::var(x);
00950     if (xi<0)
00951       return P;
00952     else
00953       return subs(P,xi,val);
00954   }
00955   
00956   //----------------------------------------------------------------------
00957   template<class T> void print(const T & x) {std::cout<<x<<std::endl;}
00958   //----------------------------------------------------------------------
00960   template<class MP> MP 
00961   swap(const MP & P, int var_i, int var_j)
00962   {
00963     MP Result;//("0");
00964     typedef typename MP::monom_t monom_t;
00965     for ( typename MP::const_iterator it = P.begin();
00966           it != P.end(); ++it )
00967       {
00968         monom_t m(it->coeff());
00969         for(int ind=0; ind<(lvar(P)+1); ++ind)
00970           {
00971             if((*it)[ind] !=0 ) {
00972               if (ind == var_i) {
00973                 m*=monom_t(var_j,(*it)[ind]);
00974               } else { 
00975                 if (ind == var_j)
00976                   m*=monom_t(var_i,(*it)[ind]);
00977                 else
00978                   m*= monom_t(ind,(*it)[ind]);
00979               }
00980             }
00981           }
00982         Result+=m;
00983       }
00984     return Result;
00985   }
00986 
00987   //----------------------------------------------------------------------
00989   template<class MP> MP 
00990   swap(const MP & P, char* x_i, char* x_j)
00991   {
00992     typedef typename MP::monom_t monom_t;
00993     int xi = monom_t::index_of_var(x_i);
00994     int xj = monom_t::index_of_var(x_j);
00995     return swap(P,xi,xj);
00996   }
00997    
00998   //--------------------------------------------------------------------
00999   template <class C, class O, class MONOM, class REP> C
01000   content(const Polynomial & P)
01001   {
01002     C d=0;
01003     for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) {
01004       d= gcd(d,i->coeff());
01005     }
01006     return d;
01007   }
01008 
01009 } //namespace sparse
01010 
01011 //====================================================================
01012 namespace let {
01013 
01014   TMPL void
01015   assign(sparse::monomial_seq<C,O,MONOM,REP>& p, const C&c) {
01016     p = sparse::monomial_seq<C,O,MONOM,REP>(); p.push_back(c);
01017   }
01018 
01019   template<class U, class V, class O, class UMONOM, class UREP, class VMONOM, class VREP> void
01020   assign(sparse::monomial_seq<U,O,UMONOM,UREP>& p, 
01021          const sparse::monomial_seq<V,O,VMONOM,VREP>& q) {
01022 
01023     typedef typename sparse::monomial_seq<U,O,UMONOM,UREP>::Monomial MonomialU;
01024     typedef typename sparse::monomial_seq<V,O,VMONOM,VREP>::Monomial MonomialV;
01025 
01026     for ( typename  sparse::monomial_seq<V,O,VMONOM,VREP>::const_iterator it = q.begin(); 
01027           it != q.end(); ++it ) {
01028       U c; assign(c,it->coeff());
01029       MonomialU m(c,it->rep());
01030       p.push_back(m);
01031     }
01032   }
01033 
01034 }
01035 //======================================================================
01036 # define SparsePolynomial  sparse:: monomial_seq<C,O,MONOM,REP>
01037 
01038 template<class A, class B> struct use;
01039 struct operators_of;
01040 
01041 TMPL struct use<operators_of,SparsePolynomial> {
01042 
01043     static inline void 
01044     add (SparsePolynomial &r, const SparsePolynomial &a ) { 
01045       sparse::add (r, a); 
01046     }
01047     static inline void 
01048     add (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01049       sparse::add (r, a, b); 
01050     }
01051     static inline void
01052     add (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01053       sparse::add (r, a, b); 
01054     }
01055     static inline void
01056     add (SparsePolynomial &r, const C & a, const SparsePolynomial &b) {
01057       sparse::add (r, b, a); 
01058     }
01059     static inline void
01060     sub (SparsePolynomial &r, const SparsePolynomial &a ) {
01061       sparse::sub (r, a ); 
01062     }
01063     static inline void
01064     sub (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01065       sparse::sub (r, a, b); 
01066     }
01067     static inline void
01068     sub (SparsePolynomial &r, const C & a, const SparsePolynomial &b) {
01069       sparse::sub (r, a, b); 
01070     }
01071     static inline void
01072     sub (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01073       sparse::sub (r, a, b); 
01074     }
01075     static inline void
01076     mul (SparsePolynomial &r, const SparsePolynomial &a ) {
01077       sparse::mul (r, a ); 
01078     }
01079     static inline void
01080     mul (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01081       sparse::mul (r, a, b); 
01082     }
01083     static inline void
01084     mul (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01085       sparse::mul (r, a, b); }
01086     static inline void
01087     mul (SparsePolynomial &r, const C & a, const SparsePolynomial &b) {
01088       sparse::mul (r, b, a); 
01089     }
01090     static inline void
01091     div (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01092       sparse::div (r, a, b); 
01093     }
01094     static inline void
01095     div (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01096       sparse::div (r, a, b); 
01097     } 
01098     static inline void
01099     div (SparsePolynomial &a, const SparsePolynomial& b) {
01100       sparse::div (a, b); 
01101     } 
01102     static inline void
01103     div (SparsePolynomial &a, const C & c) {
01104       sparse::div (a, c); 
01105     }
01106     static inline void
01107     rem (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01108       sparse::rem (r, b, a); 
01109     }
01110 };
01111 #undef SparsePolynomial
01112 //====================================================================
01113 }//  namespace mmx 
01114 #undef TMPL
01115 #undef TMPLX
01116 #undef CLASS
01117 #undef Polynomial
01118 #endif // realroot_sparse_monomial_hpp
01119