synaps/mpol/MPOLDST.m

00001 /*********************************************************************
00002 *   This file is part of the source code of the SYNAPS.       *
00003 *   Author(s): B. Mourrain, GALAAD, INRIA                            *
00004 **********************************************************************
00005 $Id: MPOLDST.h,v 1.2 2005/09/28 06:40:50 mourrain Exp $
00006 **********************************************************************/
00007 #ifndef SYNAPS_MPOL_MPOLDST_H
00008 #define SYNAPS_MPOL_MPOLDST_H
00009 
00010 #include <list>
00011 #include <vector>
00012 #include <algorithm>
00013 #include <synaps/init.h>
00014 #include <synaps/linalg/VECTOR.m>
00015 #include <synaps/arithm/let.h>
00016 #include <synaps/arithm/binomial.h>
00017 #include <synaps/arithm/sign.h>
00018 #include <synaps/mpol/Variables.h>
00019 #include <synaps/mpol/binomial.h>
00020 #include <synaps/mpol/Monom.h>
00021 #include <synaps/mpol/MONOMIAL.m>
00022 #include <synaps/arithm/pow.h>
00023 
00024 
00025 __BEGIN_NAMESPACE_SYNAPS
00026 
00028 namespace MPOLDST
00029 {
00030   template<class O, class R>
00031   void add(R & result, const R& p1, const R& p2)
00032   {
00033     assert(&result != &p1); assert(&result != &p2);
00034 
00035     typedef typename R::const_iterator  const_iterator;
00036     typedef typename R::iterator iterator;
00037     typedef typename R::value_type::coeff_t coeff_type;
00038     const_iterator
00039       b1=p1.begin(),
00040       e1=p1.end(),
00041       b2=p2.begin(),
00042       e2=p2.end();
00043     result.resize(p1.size()+p2.size());
00044     iterator i=result.begin();
00045     while (b1!=e1 && b2!=e2) {
00046       if(O::less(*b2,*b1))
00047         *i++=*b1++;
00048       else if(O::less(*b1,*b2))
00049         *i++=*b2++;
00050       else {
00051           coeff_type c=b1->coeff()+ b2->coeff();
00052           if (c !=0) {
00053                 *i =*b1;
00054                 i->setcoeff(c);
00055                 ++i;
00056           }
00057           ++b1;++b2;
00058         }
00059     }
00060     while (b1!=e1) *i++=*b1++;
00061     while (b2!=e2) *i++=*b2++;
00062 
00063     int m=std::distance(result.begin(),i);
00064     assert(m>=0);
00065     result.resize(m);
00066   }
00067 
00068   template<class R, class O>
00069   void sub(R & result, const R& p1, const R& p2)
00070   {
00071     assert(&result != &p1); assert(&result != &p2);
00072     typedef typename R::const_iterator  const_iterator;
00073     typedef typename R::iterator iterator;
00074     typedef typename R::value_type::coeff_t coeff_type;
00075     const_iterator
00076       b1=p1.begin(),
00077       e1=p1.end(),
00078       b2=p2.begin(),
00079       e2=p2.end();
00080     result.resize(p1.size()+p2.size());
00081     iterator i=result.begin();
00082     while (b1!=e1 && b2!=e2) {
00083       if(O::less(*b2,*b1))
00084         *i++=*b1++;
00085       else if(O::less(*b1,*b2))
00086         {
00087           *i=*b2++; i->coeff()*= -1; i++;
00088         }
00089       else {
00090           coeff_type c=b1->coeff()- b2->coeff();
00091           if (c !=0) {
00092                 *i =*b1;
00093                 i->setcoeff(c);
00094                 ++i;
00095           }
00096           ++b1;++b2;
00097         }
00098     }
00099     while (b1!=e1) *i++=*b1++;
00100     while (b2!=e2) {*i=*b2++;i->coeff()*=-1;i++;}
00101 
00102     int m=std::distance(result.begin(),i);
00103     assert(m>=0);
00104     result.resize(m);
00105   }
00106 
00108   template<class O, class R>
00109   void add(R & p1, const R& p2)
00110   {
00111     assert(&p1 != &p2);
00112     typedef typename R::const_iterator  const_iterator;
00113     typedef typename R::iterator iterator;
00114     typedef typename R::value_type::coeff_t coeff_type;
00115 
00116     //    reserve(p1,p1.size()+p2.size());
00117     iterator        b1=p1.begin();
00118     const_iterator  b2=p2.begin();
00119     while (b1!=p1.end() && b2!=p2.end()) {
00120       if(O::less(*b2,*b1))
00121         b1++;
00122        else if(O::less(*b1,*b2))
00123         {
00124           b1 = p1.insert(b1,*b2); b1++; b2++;
00125         }
00126       else
00127         {
00128           coeff_type c=b1->coeff() + b2->coeff();
00129           if (c !=0) {
00130             b1->setcoeff(c); ++b1;
00131           }else{
00132             b1 = p1.erase(b1);
00133           }
00134           ++b2;
00135         }
00136     }
00137     p1.insert(b1,b2,p2.end());
00138   }
00139 //----------------------------------------------------------------------
00140  template<class R, class I, class J, class M, class O>
00141  I add(R & p1, I b1, J e1, const M & m2, const O & o)
00142   {
00143     typedef typename R::value_type::coeff_t coeff_type;
00144 
00145     while (b1!=e1) {
00146       if(O::less(m2,*b1))
00147         {
00148           b1++; //COUNT<M>('i');
00149         }
00150       else if(O::less(*b1,m2))
00151         {
00152           b1=p1.insert(b1,m2);
00153           return b1;
00154         }
00155       else
00156         {
00157           coeff_type c=b1->coeff() + m2.coeff();
00158           if (c !=0) {
00159                 b1->setcoeff(c);
00160           }else
00161             b1 = p1.erase(b1);
00162           return(b1);
00163         }
00164     }
00165     b1 = p1.insert(b1,m2);
00166     return b1;
00167   }
00168 //----------------------------------------------------------------------
00170   template <class R, class S, class C> inline
00171   void mul_ext(R &result, const S& a, const C & m)
00172   {
00173     VECTOR::apply_mult(result, a, typename R::value_type(m));
00174   }
00175 //----------------------------------------------------------------------
00176   template <class R,class C> inline
00177   void mul_ext_e(std::list<R> &result, const std::list<R>& a, const C & m)
00178   {
00179     typedef typename std::list<R>::const_iterator  const_iterator;
00180     typedef typename std::list<R>::iterator iterator;
00181 
00182     result.resize(0);
00183     iterator i=result.begin();
00184     R tmp;
00185     for(const_iterator b=a.begin();b!=a.end(); ++b)
00186       {
00187         tmp = (*b) * m;
00188         (i=result.insert(i,tmp))++;
00189       }
00190   }
00191 //----------------------------------------------------------------------
00193   template<class R, class O> inline
00194   void mul(R &r, const R& a, const R& b, const O & o)
00195   {
00196     if (a.size()<b.size())
00197       MPOLDST::mul<R,O>(r,a.begin(),a.end(),b);
00198     else
00199       MPOLDST::mul<R,O>(r,b.begin(),b.end(),a);
00200   }
00201 
00203   template <class M, class O> inline
00204   void mul(std::list<M> &r, const std::list<M>& a, const std::list<M>& b, const O & o)
00205   {
00206     typedef typename std::list<M>::const_iterator const_iterator;
00207     typedef typename std::list<M>::iterator       iterator;
00208 
00209     r.resize(0);
00210     M m;
00211     for(const_iterator i=b.begin();i !=b.end();i++)
00212       {
00213         if(r.size())
00214           {
00215             iterator ip = r.begin();
00216             for(const_iterator j=a.begin();j != a.end();j++)
00217               { m = *j * *i;ip = MPOLDST::add(r,ip,r.end(),m,O()); }
00218             //MPOLDST::mul_ext(tmp,a,*i);
00219             //MPOLDST::add<list<M>,vector<M>,O>(r,tmp);
00220           }
00221         else
00222           MPOLDST::mul_ext(r,a,*i);
00223       }
00224   }
00225 
00226 //----------------------------------------------------------------------
00227 template <class R, class O> inline
00228 void mul(R &r,
00229           typename R::const_iterator b,
00230           typename R::const_iterator e, const R& p)
00231 {
00232     typedef typename R::const_iterator  const_iterator;
00233     long int n=std::distance(b,e);
00234 
00235     assert(n>=0);
00236     if (n==0) r.resize(0);
00237     if (n==1) MPOLDST::mul_ext(r,p,*b);
00238     else {
00239 
00240       const_iterator med=b+(n/2);
00241       R tmp(0), tmp1(0);
00242       MPOLDST::mul<R,O>(tmp,b,med,p);
00243       MPOLDST::mul<R,O>(tmp1,med,e,p);
00244       MPOLDST::add<R,O>(r,tmp,tmp1);
00245     }
00246 
00247 }
00248 
00249 //----------------------------------------------------------------------
00251 template <class R>  int lvar (const R & p)
00252 {
00253   unsigned v = 0;
00254   for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00255     v = std::max(v,it->size());
00256   return (v-1);
00257 }
00258 //--------------------------------------------------------------------
00260 template <class R>  unsigned nbvar (const R & p)
00261 {
00262   return lvar(p)+1;
00263 }
00264 //----------------------------------------------------------------------
00266 template <class R>  int degree (const R & p)
00267 {
00268     if(!p.size())
00269       return -1;
00270     else
00271       {
00272         int d = 0;
00273         for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00274           d = std::max(d,degree(*it));
00275         return d;
00276       }
00277 }
00278 
00280 template <class R>  int degree (const R & p, int i)
00281 {
00282     if(!p.size())
00283       return -1;
00284     else
00285       {
00286         int d=0;
00287         for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00288           {
00289             if(i<=it->nvars()) d = std::max(d,(int)(*it)[i]);
00290           }
00291         return d;
00292       }
00293 }
00294 //----------------------------------------------------------------------
00295 template<class R>
00296 typename R::coeff_t & leadingcoeff(R & a)       {return a.begin()->coeff();}
00297 //----------------------------------------------------------------------
00298 template<class R>
00299 typename R::coeff_t   leadingcoeff(const R & a) {return a.begin()->coeff();}
00300 //----------------------------------------------------------------------
00302 template<class R>
00303 void div_rem(R & q, R & a, const R & b)
00304 {
00305 
00306   typedef typename R::monom_t monom_t;
00307 
00308   q= R(0);
00309   if(a!=0)
00310     {
00311       typename R::monom_t mb = (*b.begin());
00312       typename R::monom_t m = (*a.begin())/mb;
00313       R t;
00314       while( a !=0 && m != 0) {
00315         t=b*m;
00316         a-=t;
00317         q+=m;
00318         if(a !=0) m =(*a.begin())/mb;
00319       }
00320     }
00321 }
00322 //----------------------------------------------------------------------
00327 template<class POL>
00328 typename POL::coeff_t coeffof(const POL & p,
00329                               const typename POL::monom_t & mono)
00330 {
00331   typedef typename POL::coeff_t coeff_t;
00332   typename POL::const_iterator m;
00333   for(m = p.begin();  m!= p.end() && !IsComparable((*m),mono); m++);
00334   if(m != p.end())
00335     {
00336       return m->coeff();
00337     }
00338   else
00339     {
00340       return  coeff_t(0);
00341     }
00342 }
00343 //----------------------------------------------------------------------
00345 template<class R>
00346 void div_rem_x(R & q, R & a, const R & b0)
00347 {
00348   //  cout <<"-------------------------------------------------------------"<<endl;
00349   typedef typename R::monom_t       monom_t;
00350   typedef typename monom_t::coeff_t coeff_t;
00351   q= R(0);
00352   if(a==0) return;
00353 
00354   R b(b0), a0(a);
00355   coeff_t cb =b0.begin()->coeff();
00356   //  b/=cb;
00357   monom_t mb = (*b.begin()),
00358           m  = (*a.begin())/mb,
00359           null =  monom_t(0);
00360   R t;
00361   //  cout <<">>> "<<a<<"\n||| "<<b<<endl;
00362   while(m != null && a !=0)
00363     {
00364       typename R::const_iterator ia =a.begin();
00365       while(ia !=a.end() && (m =(*ia/mb))== null ) ia++;
00366       t=b*m;
00367       a-= t;
00368       if ( (m) != 0 )
00369         q+= (m);
00370   }
00371 //   cout <<"============================================================="<<endl;
00372 //   cout <<q<<endl;
00373 //   cout <<"============================================================="<<endl;
00374 }
00375 
00376 //----------------------------------------------------------------------
00378 template<class R>
00379 void diff(R & r, const R & p, int i)
00380 {
00381     assert(&r != &p);
00382     typedef typename R::monom_t monom_t;
00383     r= R(0);
00384     for (typename R::const_iterator it = p.begin(); it != p.end(); ++it)
00385       {
00386         if((*it)[i]>1){
00387           monom_t m(*it);
00388           m*=(typename R::coeff_t)(*it);
00389           m.setexpt(i,(*it)[i]-1);
00390           r+=m;
00391         }
00392         else if ((*it)[i]==1)
00393           {
00394             monom_t m(it->coeff());
00395             for( int ind=0; ind<(it->nvars()+1); ++ind)
00396               {
00397                 if( ((*it)[ind] !=0) && (ind != i) )
00398                   m*=monom_t(ind,(*it)[ind]);
00399               }
00400             r+=m;
00401           }
00402       }
00403 }
00404 
00405 //----------------------------------------------------------------------
00407 template <class R>
00408 void copy(R& r, const R& a)
00409 {
00410   //to nbe modified when bug fixed in gcc
00411   //  using VECTOR::reserve;
00412   using namespace VECTOR;
00413   reserve(r,a.size());
00414   std::copy(a.begin(),a.end(),r.begin());
00415 }
00416 //----------------------------------------------------------------------
00418 template <class R>
00419 typename R::coeff_t eval(const R& p,
00420                          const typename R::coeff_t &x,
00421                          const typename R::coeff_t &y)
00422 {
00423   typename R::coeff_t r(0);
00424   for(typename R::const_iterator it=p.begin(); it!=p.end(); ++it)
00425     {
00426       typename R::coeff_t c(it->coeff());
00427       //for(unsigned int i=0;i<2;++i)
00428       for(int k=0;k<(int)(*it)[0];k++)
00429         c*=x;
00430       for(int k=0;k<(int)(*it)[1];k++)
00431         c*=y;
00432       r+=c;
00433     }
00434   return r;
00435 }
00438 template <class MP>
00439 MP convert(const MP & P,typename MP::coeff_t x,typename MP::coeff_t y,int ind)
00440 {
00441   typedef typename MP::const_iterator  const_iterator;
00442   typedef typename MP::coeff_t coeff_t;
00443   typedef typename MP::monom_t monom_t;
00444   MP  res;
00445   int ind1=0;
00446   int ind2=0;
00447   for(int i=0;i<=2;i++)
00448     {
00449       if(ind!=i) {ind1=i;break;}
00450     }
00451   for(int i=0;i<=2;i++)
00452     {
00453       if(ind!=i && ind1!=i) {ind2=i;break;}
00454     }
00455   for(const_iterator i = P.begin(); i != P.end(); ++i)
00456     {
00457       coeff_t  k=i->coeff();
00458       int puissx=(*i);
00459       int puissy=(*i);
00460       int d=(*i);
00461       coeff_t coeff1=pow(x,puissx);
00462       coeff_t coeff2=pow(y,puissy);
00463       k*=coeff1;k*=coeff2;
00464       MP P1=monom_t(k,ind,d);
00465       res=res+P1;
00466     }
00467   return res;
00468 }
00469 
00470 //--------------------------------------------------------------------
00471 template <class OS,class R, class VARIABLES>
00472 OS & print(OS & os, const R & P, const VARIABLES & V)
00473 {
00474   if ( P.begin() == P.end() )
00475     {
00476       os << '0';
00477       return os;
00478     }
00479  typename R::const_iterator i = P.begin();
00480  while ( i != P.end() )
00481    {
00482      if ( with_plus_sign(i->coeff()) && i !=P.begin())
00483        os <<'+';
00484      MONOMIAL::print(os,*i++,V);
00485    }
00486  return os;
00487 }
00488 //--------------------------------------------------------------------
00489 template <class OS,class R>
00490 OS & print(OS & os, const R & P)
00491 {
00492   return print(os,P,Variables::default_);
00493 }
00494 //----------------------------------------------------------------------
00495 template <class OS,class R>
00496 OS & print_verbatim(OS & os, const R & P)
00497 {
00498   if ( P.begin() == P.end() )
00499     {
00500       os << '0';
00501       return os;
00502     }
00503  for( typename R::const_iterator i=P.begin(); i != P.end();++i)
00504    {
00505      os<<" "<<i->coeff()<<" [";
00506      for(int l=0;l<i->size();l++) os<<(*i)<<" ";
00507      os<<"]";
00508    }
00509  return os;
00510 }
00511 //----------------------------------------------------------------------
00518 template<class MP>
00519 MP Rotate_yz(const MP & P,typename MP::coeff_t t)
00520 {
00521   typedef typename MP::const_iterator  const_iterator;
00522   typedef typename MP::coeff_t coeff_t;
00523 
00524   coeff_t cos_teta = (1-pow<coeff_t>(t,2))/(1+pow<coeff_t>(t,2));
00525   coeff_t sin_teta = 2*t/(1+pow<coeff_t>(t,2));
00526   coeff_t coeff;
00527 
00528   MP pi1,pi2,pi3,P5;
00529 
00530   for(const_iterator i = P.begin(); i != P.end(); ++i)
00531     {
00532       int puiss1=(*i);
00533       int puiss2=(*i);
00534       int puiss3=(*i);
00535 
00536       coeff = i->coeff();
00537       MP P1,P2,P3;
00538 
00539       if (puiss1)
00540         {
00541           pi1 = Monom<coeff_t,dynamicexp<unsigned> >(1,0,puiss1);
00542           if ( Degree(pi1) > 0 )
00543             P1+=pi1;
00544         }
00545 
00546       for(int j=0;j<=puiss2;j++)
00547         {
00548           int puiss_j = puiss2-j;
00549           coeff_t coeffB=binomial<coeff_t>(puiss2,j);
00550           coeff_t k=pow<coeff_t>(cos_teta,j);
00551           pi2 = Monom<coeff_t,dynamicexp<unsigned> >(coeffB*k,1,j);
00552           k=pow<coeff_t>(-sin_teta,puiss_j);
00553           pi3 = Monom<coeff_t,dynamicexp<unsigned> >(k,2,puiss_j);
00554           if ( Degree(pi2*pi3) > 0 )
00555             P2 += (pi2*pi3);
00556         }
00557 
00558       for(int j=0;j<=puiss3;j++)
00559         {
00560           int puiss_j = puiss3-j;
00561           coeff_t coeffB=binomial<coeff_t>(puiss3,j);
00562           coeff_t k=pow<coeff_t>(sin_teta,j);
00563           pi2 = Monom<coeff_t,dynamicexp<unsigned> >(coeffB*k,1,j);
00564           k=pow<coeff_t>(cos_teta,puiss_j);
00565           pi3 = Monom<coeff_t,dynamicexp<unsigned> >(k,2,puiss_j);
00566           if ( Degree(pi2*pi3) > 0)
00567             P3 += (pi2*pi3);
00568         }
00569 
00570       MP P4("0;");
00571       if (coeff != 0)
00572         P4 += coeff;
00573       if (puiss1)
00574         P4 *= P1;
00575       if (puiss2)
00576         P4 *= P2;
00577       if (puiss3)
00578         P4 *= P3;
00579 
00580       if (P4 != MP("0;"))
00581         P5 += P4;
00582     }
00583   return P5;
00584 }
00585 
00586 //----------------------------------------------------------------------
00593 template<class MP>
00594 MP Rotate_xz(const MP & P,typename MP::coeff_t t)
00595 {
00596   typedef typename MP::const_iterator  const_iterator;
00597   typedef typename MP::coeff_t coeff_t;
00598 
00599   coeff_t cos_teta = (1-pow<coeff_t>(t,2))/(1+pow<coeff_t>(t,2));
00600   coeff_t sin_teta = 2*t/(1+pow<coeff_t>(t,2));
00601   coeff_t coeff;
00602 
00603   MP pi1,pi2,pi3,P5;
00604 
00605   for(const_iterator i = P.begin(); i != P.end(); ++i)
00606     {
00607       int puiss1=(*i);
00608       int puiss2=(*i);
00609       int puiss3=(*i);
00610 
00611       coeff = i->coeff();
00612       MP P1,P2,P3;
00613 
00614       for(int j=0;j<=puiss1;j++)
00615         {
00616           int puiss_j = puiss1-j;
00617           coeff_t coeffB=binomial<coeff_t>(puiss1,j);
00618           coeff_t k=pow<coeff_t>(cos_teta,j);
00619           pi1 = Monom<coeff_t,dynamicexp<unsigned> >(coeffB*k,0,j);
00620           k=pow<coeff_t>(-sin_teta,puiss_j);
00621           pi3 = Monom<coeff_t,dynamicexp<unsigned> >(k,2,puiss_j);
00622           if ( Degree(pi1*pi3) > 0)
00623             P1 += (pi1*pi3);
00624         }
00625 
00626       if (puiss2)
00627         {
00628           pi2 = Monom<coeff_t,dynamicexp<unsigned> >(1,1,puiss2);
00629           if ( Degree(pi2) > 0 )
00630             P2+=pi2;
00631         }
00632 
00633       for(int j=0;j<=puiss3;j++)
00634         {
00635           int puiss_j = puiss3-j;
00636           coeff_t coeffB=binomial<coeff_t>(puiss3,j);
00637           coeff_t k=pow<coeff_t>(sin_teta,j);
00638           pi1 = Monom<coeff_t,dynamicexp<unsigned> >(coeffB*k,0,j);
00639           k=pow<coeff_t>(cos_teta,puiss_j);
00640           pi3 = Monom<coeff_t,dynamicexp<unsigned> >(k,2,puiss_j);
00641           if ( Degree(pi1*pi3) > 0)
00642             P3 += (pi1*pi3);
00643         }
00644 
00645       MP P4("0;");
00646       if (coeff != 0)
00647         P4 += coeff;
00648       if (puiss1)
00649         P4 *= P1;
00650       if (puiss2)
00651         P4 *= P2;
00652       if (puiss3)
00653         P4 *= P3;
00654 
00655       if (P4 != MP("0;"))
00656         P5 += P4;
00657     }
00658   return P5;
00659 }
00660 
00661 //----------------------------------------------------------------------
00668 template<class MP>
00669 MP Rotate_xy(const MP & P,typename MP::coeff_t t)
00670 {
00671   typedef typename MP::const_iterator  const_iterator;
00672   typedef typename MP::coeff_t coeff_t;
00673 
00674   coeff_t cos_teta = (1-pow<coeff_t>(t,2))/(1+pow<coeff_t>(t,2));
00675   coeff_t sin_teta = 2*t/(1+pow<coeff_t>(t,2));
00676   coeff_t coeff;
00677 
00678   MP pi1,pi2,pi3,P5;
00679 
00680   for(const_iterator i = P.begin(); i != P.end(); ++i)
00681     {
00682       int puiss1=(*i);
00683       int puiss2=(*i);
00684       int puiss3=(*i);
00685 
00686       coeff = i->coeff();
00687       MP P1,P2,P3;
00688 
00689       for(int j=0;j<=puiss1;j++)
00690         {
00691           int puiss_j = puiss1-j;
00692           coeff_t coeffB=binomial<coeff_t>(puiss1,j);
00693           coeff_t k=pow<coeff_t>(cos_teta,j);
00694           pi1 = Monom<coeff_t,dynamicexp<unsigned> >(coeffB*k,0,j);
00695           k=pow<coeff_t>(-sin_teta,puiss_j);
00696           pi2 = Monom<coeff_t,dynamicexp<unsigned> >(k,1,puiss_j);
00697           if ( Degree(pi1*pi2) > 0)
00698             P1 += (pi1*pi2);
00699         }
00700 
00701       for(int j=0;j<=puiss2;j++)
00702         {
00703           int puiss_j = puiss2-j;
00704           coeff_t coeffB=binomial<coeff_t>(puiss2,j);
00705           coeff_t k=pow<coeff_t>(sin_teta,j);
00706           pi1 = Monom<coeff_t,dynamicexp<unsigned> >(coeffB*k,0,j);
00707           k=pow<coeff_t>(cos_teta,puiss_j);
00708           pi2 = Monom<coeff_t,dynamicexp<unsigned> >(k,1,puiss_j);
00709           if ( Degree(pi1*pi2) > 0)
00710             P2 += (pi1*pi2);
00711         }
00712 
00713       if (puiss3)
00714         {
00715           pi3 = Monom<coeff_t,dynamicexp<unsigned> >(1,2,puiss3);
00716           if ( Degree(pi3) > 0 )
00717             P3+=pi3;
00718         }
00719 
00720       MP P4("0;");
00721       if (coeff != 0)
00722         P4 += coeff;
00723       if (puiss1)
00724         P4 *= P1;
00725       if (puiss2)
00726         P4 *= P2;
00727       if (puiss3)
00728         P4 *= P3;
00729 
00730       if (P4 != MP("0;"))
00731         P5 += P4;
00732     }
00733   return P5;
00734 }
00735 
00736 //----------------------------------------------------------------------
00743 template<class MP>
00744 MP Rotate_xyz(const MP & P,typename MP::coeff_t t)
00745 {
00746   typedef typename MP::const_iterator  const_iterator;
00747   typedef typename MP::coeff_t coeff_t;
00748 
00749   MP P1,P2,P3;
00750 
00751   P1 = Rotate_xy(P,t);
00752   P2 = Rotate_xz(P1,t);
00753   P3 = Rotate_yz(P2,t);
00754   return P3;
00755 }
00756 
00757 //----------------------------------------------------------------------
00761 template <class POL, class C>
00762 POL shift(typename POL::const_iterator monom, C a, int i)
00763 {
00764 
00765   POL polynom;
00766   // Definition du type monome.
00767   typedef typename POL::monom_t Monom;
00768   // Monome temporaire.
00769   Monom tmpMonom;
00770 
00771   int i0 = i;
00772   int i1 = (i + 1) % 3;
00773   int i2 = (i + 2) % 3;
00774 
00775   // Si la variable est presente dans le monome.
00776   if ( (a!=0) && ( monom->operator[](i0) !=0 ) )
00777     {
00778       polynom = binomial< POL >(C(1.), i0, monom->operator(i0), a);
00779       int expt;
00780       expt = 0;
00781       expt = monom->operator(i1);
00782       expt = monom->operator(i2);
00783 
00784       if ( ( expt[i0] == 0 ) && ( expt[i1] == 0 ) && ( expt[i2] == 0 ) )
00785         tmpMonom = Monom( monom->coeff(), 0, 0 );
00786       else   tmpMonom = Monom( monom->coeff(), 3, expt );
00787 
00788       polynom *= tmpMonom;
00789     }
00790   // Si a = 0 alors le monome reste inchange.
00791   else polynom = ( *monom );
00792 
00793   return polynom;
00794 
00795 }
00796 //---------------------------------------------------------------------
00798 template < class POL, class C>
00799 POL shift(const POL &polynom, C x0, C y0, C z0 ) {
00800 
00801   // Definition du type monome.
00802   typedef typename POL::monom_t Monom;
00803 
00804   // Les polynomes temporaires.
00805   POL tmpPolynom1, tmpPolynom2, tmpPolynom3;
00806 
00807   // L'iterateur va pointer sur le monome courrant.
00808   typename POL::const_iterator currentMonom = polynom.begin();
00809 
00810   if ( currentMonom == polynom.end() ) {
00811     std::cerr << "Error : empty polynom ... in Shift ";
00812     exit(1);
00813   }
00814 
00815   // Pour la premiere variable.
00816   while ( currentMonom != polynom.end() ) {
00817     // Changement de variable sur le monome courant.
00818     tmpPolynom1 += MPOLDST::shift<POL,C>(currentMonom, x0, 0);
00819 
00820     // Le prochain Monome.
00821     ( *currentMonom++ );
00822   }
00823 
00824   if ( tmpPolynom1 == 0 ) tmpPolynom1= polynom ;
00825 
00826   currentMonom = tmpPolynom1.begin();
00827 
00828   // Pour la seconde variable.
00829   while ( currentMonom != tmpPolynom1.end() ) {
00830     tmpPolynom2 += shift<POL,C>(currentMonom, y0, 1);
00831     ( *currentMonom++ );
00832   }
00833 
00834   if ( tmpPolynom2 == 0 ) tmpPolynom2 =polynom;
00835   currentMonom = tmpPolynom2.begin();
00836 
00837   // Pour la 3ieme variable.
00838   while ( currentMonom != tmpPolynom2.end() ) {
00839     tmpPolynom3 += shift<POL,C>(currentMonom, z0, 2);
00840     ( *currentMonom++ );
00841   }
00842 
00843   return  tmpPolynom3;
00844 }
00845 
00846 //----------------------------------------------------------------------
00849 template < class POL, class C >
00850 POL scale( const POL &polynom, C a, C b, C c ) {
00851 
00852   typedef typename POL::monom_t Monom;
00853 
00854   C newCoeff;
00855   POL  newPolynom;
00856 
00857   for ( typename POL::const_iterator i = polynom.begin();
00858         i != polynom.end(); ++i ) {
00859 
00860     Monom tmpMonom;
00861 
00862     newCoeff = i->coeff()
00863       * pow( a, int( i->operator[]( 0 ) ) )
00864       * pow( b, int( i->operator[]( 1 ) ) )
00865       * pow( c, int( i->operator[]( 2 ) ) );
00866 
00867     int expt;
00868     expt = i->operator(0);
00869     expt = i->operator(1);
00870     expt = i->operator(2);
00871 
00872     if ( ( expt[0] == 0 ) && ( expt[1] == 0 ) && ( expt[2] == 0 ) )
00873       tmpMonom = Monom( i->coeff(), 0, 0 );
00874     else   tmpMonom = Monom( newCoeff, 3, expt );
00875 
00876     newPolynom += tmpMonom;
00877   }
00878   return newPolynom;
00879 
00880 }
00881 
00882 //----------------------------------------------------------------------
00884 template<class MP,class X>
00885 MP subs( unsigned  var, const X& val, const MP & P)
00886 {
00887   MP Result("0");
00888   typedef typename MP::coeff_t coeff_t;
00889   typedef typename MP::monom_t monom_t;
00890   
00891   for( typename MP::const_iterator it = P.begin(); it != P.end(); ++it )
00892     {
00893       if ( it->size() > var )
00894         {
00895           monom_t m (*it);
00896           X tmp = pow(val,m[var]);
00897           m.rep() = 0; 
00898           Result += tmp*m;
00899         }
00900       else 
00901         Result += *it;
00902 
00903     }
00904   return Result;
00905 }
00906 //----------------------------------------------------------------------
00908 template<class MP>
00909 MP subs(const MP & P, int var, typename MP::coeff_t val)
00910 {
00911   MP Result("0");
00912   typedef typename MP::coeff_t coeff_t;
00913   typedef typename MP::monom_t monom_t;
00914   coeff_t C=0;
00915   for ( typename MP::const_iterator it = P.begin();
00916         it != P.end(); ++it )
00917     {
00918       monom_t m(it->coeff());
00919       for(int ind=0; ind<(lvar(P)+1); ++ind)
00920         {
00921           if (ind == var)
00922             {
00923               for(int k=0;k<(int)(*it)[ind];k++)
00924                 m*=val;
00925             }
00926           else
00927             {
00928               if ((*it)[ind] != 0)
00929                 {
00930                   monom_t mon(ind,(*it)[ind]);
00931                   m*= mon;
00932                 }
00933             }
00934         }
00935       if (m.nvars() == -1)
00936         {
00937           C += m.coeff();
00938         }
00939       else if (m != 0)
00940           Result+= m;
00941     }
00942   if (C != 0)
00943     Result += monom_t(C);
00944   return Result;
00945 }
00946 
00947 //----------------------------------------------------------------------
00949 template<class MP>
00950 MP subs(const MP & P, char* x, typename MP::coeff_t val)
00951 {
00952   int xi = MP::var(x);
00953   if (xi<0)
00954     return P;
00955   else
00956     return subs(P,xi,val);
00957 }
00958 
00959 //----------------------------------------------------------------------
00960 template<class T> void print(const T & x) {std::cout<<x<<std::endl;}
00961 //----------------------------------------------------------------------
00963 template<class MP>
00964 MP swap(const MP & P, int var_i, int var_j)
00965 {
00966   MP Result("0");
00967   typedef typename MP::monom_t monom_t;
00968   for ( typename MP::const_iterator it = P.begin();
00969         it != P.end(); ++it )
00970     {
00971       monom_t m(it->coeff());
00972       for(int ind=0; ind<(lvar(P)+1); ++ind)
00973         {
00974           if((*it)[ind] !=0 )
00975             if (ind == var_i)
00976               m*=monom_t(var_j,(*it)[ind]);
00977             else if (ind == var_j)
00978               m*=monom_t(var_i,(*it)[ind]);
00979             else
00980               m*= monom_t(ind,(*it)[ind]);
00981         }
00982       Result+=m;
00983     }
00984   return Result;
00985 }
00986 
00987 //----------------------------------------------------------------------
00989 template<class MP>
00990 MP 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 T, class MP, class V>
01000 T eval(const MP& p, const V& v)
01001 {
01002   T r(0);
01003   for(typename MP::const_iterator it=p.begin(); it!=p.end(); ++it)
01004     {
01005       T c; let::assign(c,it->coeff());
01006       for(unsigned i=0;i< it->size();++i)
01007         for(unsigned  k=0;k<(*it);k++)
01008           {
01009             c*=v[i];
01010           }
01011       r+=c;
01012     }
01013   return r;
01014 }
01015 
01016 //======================================================================
01017 } //CLOSE MPOLDST
01018 __END_NAMESPACE_SYNAPS
01019 
01020 #endif // SYNAPS_MPOL_MPOLDST_H
01021 

SYNAPS DOCUMENTATION
logo