synaps/upol/UPolDse.h

00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS library.       *
00003 *      Author(s): B. Mourrain, GALAAD, INRIA                         *
00004 **********************************************************************
00005 $Id: UPolDse.h,v 1.2 2005/08/29 14:30:17 mourrain Exp $
00006 **********************************************************************/
00007 #ifndef SYNAPS_UPOL_UPOLDSE_H
00008 #define SYNAPS_UPOL_UPOLDSE_H
00009 #include <synaps/init.h>
00010 #include <synaps/base/parser.h>
00011 #include <stdlib.h>
00012 #include <string>
00013 #include <synaps/arithm/let.h>
00014 #include <synaps/arithm/REF.h>
00015 #include <synaps/linalg/VECTOR.m>
00016 #include <synaps/upol/UPOLDAR.m>
00017 #include <synaps/upol/rep.h>
00018 #include <synaps/upol/EUCLIDIAN.h>
00019 #include <synaps/base/shared_object.h>
00020 #include <synaps/base/type.h>
00021 
00022 __BEGIN_NAMESPACE_SYNAPS
00023 
00025 
00061 template<class C, class R=upol::rep<C> >
00062 struct UPolDse {
00063 
00064 #ifdef NOREFCOUNT
00065   R data;
00066   R &       rep()       {return data;}
00067   const R & rep() const {return data;}
00068 #else
00069   shared_object<R> data;
00070   R &       rep()       {return *data;}
00071   const R & rep() const {return *data;}
00072 #endif
00073   typedef C                            value_type;
00074   typedef C                            coeff_t;
00075   typedef typename R::size_type        size_type;
00076   typedef R                            rep_type;
00077   typedef typename R::iterator         iterator;
00078   typedef typename R::const_iterator   const_iterator;
00079   typedef typename R::reverse_iterator reverse_iterator;
00080   typedef typename R::const_reverse_iterator const_reverse_iterator;
00081   typedef UPolDse<C,R>                self_t;
00082 
00083   static char* var_;
00084   
00085   UPolDse() : data() {}
00086   UPolDse(const R & r) {data(r);}
00087   UPolDse(const int n);
00088   //  UPolDse( const coeff_t & c );
00089   UPolDse(size_type n, type::AsSize A)
00090     {rep().resize(n);VECTOR::init(rep(),(value_type)0);}
00091   UPolDse(value_type c, size_type n = 0 );
00092   UPolDse(size_type n, value_type * t);
00093   UPolDse(iterator b, iterator e);
00094 
00095   UPolDse(const char *);
00096   UPolDse(const self_t & P) {data=P.data;} //COUNT<self_t>('c');}
00097 
00098   template<class S>
00099   UPolDse(const VAL<S> & P) {let::assign(*this,P.rep());}
00100 
00101   iterator               begin()        {return rep().begin();}
00102   const_iterator         begin()  const {return rep().begin();}
00103   iterator               end()          {return rep().end();}
00104   const_iterator         end()    const {return rep().end();}
00105   reverse_iterator       rbegin()       {return rep().rbegin();}
00106   const_reverse_iterator rbegin() const {return rep().rbegin();}
00107   reverse_iterator       rend()         {return rep().rend();}
00108   const_reverse_iterator rend()   const {return rep().rend();}
00109 
00110   self_t & operator=(const self_t & P)
00111     {
00112       data=P.data;
00113       //  COUNT<self_t>('=');
00114       return *this;
00115     }
00116 
00117   template<class S>
00118   self_t & operator =(const VAL<S> & M)
00119   {let::assign(*this,M.rep());return *this;}
00120 
00121   bool operator==(int n) const;
00122   bool operator!=(int n) const {return !(*this==n);}
00123 
00124   bool operator==(const self_t & p) const;
00125   bool operator!=(const self_t & p) const {return !(*this==p);}
00126 
00127   self_t & operator+= (const self_t  & P);
00128   self_t & operator+= (const value_type & c);
00129 
00130   self_t & operator-= (const self_t  & P);
00131   self_t & operator-= (const value_type & c);
00132 
00133   self_t & operator*= (const self_t  & P);
00134   self_t & operator*= (const value_type & c);
00135 
00136   self_t & operator/= (const self_t  & Q);
00137   self_t & operator/= (const value_type & c);
00138 
00139   self_t & operator%= (const self_t  & Q);
00140   self_t & operator%= ( const value_type & x );
00141   int get_degree() const 
00142   { 
00143     using UPOLDAR::degree; return degree(rep());
00144   }
00145   size_type   size() const { return (rep().size()); }
00146   void resize(size_type i) { rep().resize(i); }
00147 
00148   inline  value_type &  operator[] (size_type i)
00149   {
00150     assert(i<size()); return (rep())[i];
00151   }
00152   inline  value_type    operator[] (size_type i) const
00153   {
00154     if(i< std::max((size_type)(this->get_degree()+1),(size_type)0))
00155       return (rep())[i]; else return 0;
00156   }
00157 
00158   template<class T> T operator()(const T & c) const;
00159   
00160   bool operator<( const value_type & c ) { return false; };
00161 };
00162 template<class C, class R> inline bool adjust_denum( const UPolDse<C,R> &  ) { return false; };
00163 //======================================================================
00164 template<class C,class R> char* UPolDse<C,R>::var_="x";
00168 template<class P> char*& Variable(void) {return P::var_;}
00169 //======================================================================
00172 template <class C, class R>  inline
00173 int degree(const UPolDse<C,R>& p)
00174 {
00175   using UPOLDAR::degree;  return degree(p.rep());
00176 }
00177 //----------------------------------------------------------------------
00179 template <class C, class R>  inline
00180 UPolDse<C,R> const diff(const UPolDse<C,R>& p)
00181 {
00182   if(degree(p)>0)
00183     {
00184       UPolDse<C,R> r(degree(p),type::AsSize());
00185       using UPOLDAR::diff; diff(r.rep(),p.rep());
00186       return r;
00187     }
00188   else
00189     return 0;
00190 }
00191 //----------------------------------------------------------------------
00193 template <class C, class R>  inline
00194 UPolDse<C,R> const diff(const UPolDse<C,R>& p, unsigned int k)
00195 {
00196   if(degree(p)>(int)k-1)
00197     {
00198       UPolDse<C,R> r(p);
00199       using UPOLDAR::diff;
00200       for(unsigned i=0; i<k;++i) diff(r.rep(),r.rep());
00201       return r;
00202     }
00203   else
00204     return 0;
00205 }
00206 //======================================================================
00207 // THE ARITHMETIC OPERATORS
00208 //======================================================================
00209 #ifndef UPOL_WITH_TEMP_EXP
00210 //----------------------------------------------------------------------
00212 template <class C, class R> inline
00213 UPolDse<C,R> operator+(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00214 {
00215   UPolDse<C,R> result(std::max(degree(a),degree(b))+1, type::AsSize());
00216   using UPOLDAR::add; add(result.rep(),a.rep(),b.rep());
00217   using UPOLDAR::checkdegree; checkdegree(result.rep());
00218   return result;
00219 }
00220 //----------------------------------------------------------------------
00222 template <class C, class R>
00223 inline UPolDse<C,R>
00224   operator-(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00225 {
00226 
00227   UPolDse<C,R> result(std::max(degree(a),degree(b))+1,type::AsSize());
00228   using UPOLDAR::sub; sub(result.rep(),a.rep(),b.rep());
00229   using UPOLDAR::checkdegree; checkdegree(result.rep());
00230   return result;
00231 }
00232 //----------------------------------------------------------------------}
00234 template <class C, class R>
00235 inline UPolDse<C,R> operator-(const UPolDse<C,R> & a)
00236 {
00237   UPolDse<C,R> result(degree(a)+1,type::AsSize());
00238   using UPOLDAR::mul_ext; mul_ext(result.rep(),a.rep(),-1);
00239   return result;
00240 }
00241 //----------------------------------------------------------------------
00243 template <class C, class R> inline
00244 UPolDse<C,R> operator*(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00245 {
00246   UPolDse<C,R> result(std::max(degree(a)+degree(b)+1,0),type::AsSize());
00247   using UPOLDAR::mul;         mul(result.rep(),a.rep(),b.rep());
00248   using UPOLDAR::checkdegree; checkdegree(result.rep());
00249   return result;
00250 }
00251 //----------------------------------------------------------------------
00253 template <class C, class R> inline
00254 UPolDse<C,R> operator+(const UPolDse<C,R> & a,
00255                        const typename UPolDse<C,R>::value_type & c)
00256 {
00257   if(degree(a) >= 0)
00258     {
00259       UPolDse<C,R> r(a);
00260       using UPOLDAR::add_cst; add_cst(r.rep(),c);
00261       return r;
00262     }
00263   else
00264     return UPolDse<C,R>(c,1);
00265 }
00266 //----------------------------------------------------------------------
00268 template <class C, class R> inline
00269 UPolDse<C,R> operator+(const typename UPolDse<C,R>::value_type & c,
00270                        const UPolDse<C,R> & a)
00271 {
00272   return a+c;  
00273 }
00274 //----------------------------------------------------------------------
00276 template <class C, class R> inline
00277 UPolDse<C,R> operator-(const UPolDse<C,R> & a,
00278                        const typename UPolDse<C,R>::value_type & c)
00279 {
00280   if(degree(a) >= 0)
00281     {
00282       UPolDse<C,R> r(a);
00283       using UPOLDAR::add_cst; add_cst(r.rep(),-c);
00284       return r;
00285     }
00286   else
00287     return UPolDse<C,R>(-c,1);
00288 }
00289 //----------------------------------------------------------------------
00291 template <class C, class R> inline
00292 UPolDse<C,R> operator-(const typename UPolDse<C,R>::value_type & c,
00293                         const UPolDse<C,R> & a)
00294 {
00295   return  (-a)+c;   
00296 }
00297 //----------------------------------------------------------------------
00299 template <class C, class R> inline
00300 UPolDse<C,R> operator*(const UPolDse<C,R> & a,
00301                        const typename UPolDse<C,R>::value_type & c)
00302 {
00303   //  std::cout<<"Mult ext a*c: "<<a<<" "<<c<<std::endl;
00304   UPolDse<C,R> result(degree(a)+1,type::AsSize());
00305   using UPOLDAR::mul_ext;
00306   mul_ext(result.rep(),a.rep(),c);
00307   checkdegree(result.rep());
00308   return result;
00309 }
00310 
00311 //----------------------------------------------------------------------
00313 template <class C, class R> inline
00314 UPolDse<C,R> operator*(const typename UPolDse<C,R>::value_type & c,
00315                        const UPolDse<C,R> & a)
00316 {
00317   //  std::cout<<"Mult ext c*a:"<<c<<" "<<a<<std::endl;
00318   return a*c;
00319 }
00320 
00321 
00322 //----------------------------------------------------------------------
00324 template <class C, class R>  inline
00325 UPolDse<C,R> operator/(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00326 {
00327   assert(b!=0);
00328   UPolDse<C,R> result(0), tmp(a);
00329   EUCLIDIAN::div_rem(result,tmp,b);
00330   return result;
00331 }//----------------------------------------------------------------------
00333 template <class C, class R>  inline
00334 UPolDse<C,R> operator/(const UPolDse<C,R> & a,
00335                        const typename UPolDse<C,R>::value_type &  c)
00336 {
00337   assert(c!=0);
00338   UPolDse<C,R> result(degree(a)+1,type::AsSize());
00339   using namespace UPOLDAR;
00340   div_ext(result.rep(),a.rep(),c);
00341   checkdegree(result.rep());
00342   return result;
00343 
00344 }
00345 
00346 //----------------------------------------------------------------------
00348 template <class C, class R>  inline
00349 UPolDse<C,R> operator%(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00350 {
00351   assert(b!=0);
00352   UPolDse<C,R> result(a);
00353   result %= b;
00354   return result;
00355 }
00356 
00357 template <class C, class R>  inline
00358 UPolDse<C,R> operator%(const UPolDse<C,R> & a, const C & b)
00359 {
00360   assert(b!=0);
00361   UPolDse<C,R> result(a);
00362   result %= b;
00363   return result;
00364 }
00365 //----------------------------------------------------------------------
00367 template <class C, class R>  inline
00368 UPolDse<C,R> prem(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00369 {
00370   assert(b!=0);
00371   UPolDse<C,R> r(a), q;
00372   EUCLIDIAN::pseudo_div_rem(q,r,b);
00373   return r;
00374 }
00375 //----------------------------------------------------------------------
00377 template <class C, class R>  inline
00378 UPolDse<C,R> operator^(const UPolDse<C,R> & a, const unsigned int & n)
00379 {
00380   UPolDse<C,R> result(1);
00381   //  ALGEBRA::power(result,a,n);
00382   for(unsigned int i=0; i< n; i++) result *= a;
00383   return result;
00384 }
00385 #else
00386 //======================================================================
00388 template <class C, class R>
00389 inline VAL<OP<'+',UPolDse<C,R>,UPolDse<C,R> > >
00390   operator+(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00391 {
00392   return VAL<OP<'+',UPolDse<C,R>,UPolDse<C,R> > >
00393     (OP<'+',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00394 }
00395 //----------------------------------------------------------------------
00397 template <class C, class R>
00398 inline VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00399   operator-(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00400 {
00401   return VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00402     (OP<'-',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00403 }
00404 //----------------------------------------------------------------------}
00406 template <class C, class R>
00407 inline VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00408   operator-(const UPolDse<C,R> & a)
00409 {
00410   return VAL<OP<'-',UPolDse<C,R>,UPolDse<C,R> > >
00411     (OP<'-',UPolDse<C,R>,UPolDse<C,R> >(UPolDse<C,R>(0),a));
00412 }
00413 //----------------------------------------------------------------------
00415 template <class C, class R>  inline
00416 VAL<OP<'*',UPolDse<C,R>,UPolDse<C,R> > >
00417   operator*(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00418 {
00419   return VAL<OP<'*',UPolDse<C,R>,UPolDse<C,R> > >
00420    (OP<'*',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00421 }
00422 //----------------------------------------------------------------------
00424 template <class C, class R> inline
00425 VAL<OP<'.',UPolDse<C,R>,typename UPolDse<C,R>::value_type> >
00426   operator*(const UPolDse<C,R> & a, const typename UPolDse<C,R>::value_type & c)
00427 {
00428   typedef typename UPolDse<C,R>::value_type C;
00429   return VAL<OP<'.',UPolDse<C,R>,C> >(OP<'.',UPolDse<C,R>,C>(a,c));
00430 }
00431 //----------------------------------------------------------------------
00433 template <class C, class R>  inline
00434 VAL<OP<'/',UPolDse<C,R>,UPolDse<C,R> > >
00435   operator/(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00436 {
00437   return VAL<OP<'/',UPolDse<C,R>,UPolDse<C,R> > >
00438    (OP<'/',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00439 }
00440 //----------------------------------------------------------------------
00442 template <class C, class R>  inline
00443 VAL<OP<'%',UPolDse<C,R>,UPolDse<C,R> > >
00444   operator%(const UPolDse<C,R> & a, const UPolDse<C,R> & b)
00445 {
00446   return VAL<OP<'%',UPolDse<C,R>,UPolDse<C,R> > >
00447    (OP<'%',UPolDse<C,R>,UPolDse<C,R> >(a,b));
00448 }
00449 //----------------------------------------------------------------------
00451 template <class C, class R>  inline
00452 VAL<OP<'^',UPolDse<C,R>,unsigned int> >
00453   operator^(const UPolDse<C,R> & a, const unsigned int & n)
00454 {
00455   return VAL<OP<'^',UPolDse<C,R>,unsigned int> >
00456    (OP<'^',UPolDse<C,R>,unsigned int>(a,n));
00457 }
00458 //======================================================================
00459 // ASSIGNEMENTS
00460 //======================================================================
00461 namespace let {
00462   template<class C, class R> inline
00463   void assign(UPolDse<C,R> & p,
00464               const OP<'+',UPolDse<C,R>, UPolDse<C,R> >& M)
00465   {
00466     assert(&(p.rep())!=&(M.op1.rep())); 
00467     assert(&(p.rep())!=&(M.op2.rep()));
00468     p.rep().resize(std::max(degree(M.op1),degree(M.op2))+1);
00469     using namespace UPOLDAR;
00470     init(p.rep(),0);
00471     add(p.rep(),M.op1.rep(),M.op2.rep());
00472     checkdegree(p.rep());
00473   }
00474 
00475 
00476   template<class C, class R,class X> inline
00477   void assign(UPolDse<C,R> & p,
00478               const OP<'+',UPolDse<C,R>, VAL<X> >& M)
00479   {
00480     assert(&(p.rep())!=&(M.op1.rep())); 
00481     // assert(&(p.rep())!=&(M.op2.rep()));
00482     UPolDse<C,R> tmp=M.op2;
00483     p.rep().resize(std::max(degree(M.op1),degree(tmp))+1);
00484     using namespace UPOLDAR;
00485     init(p.rep(),0);
00486     add(p.rep(),M.op1.rep(),tmp);
00487     checkdegree(p.rep());
00488   }
00489 
00490   template<class C, class R,class X> inline
00491   void assign(UPolDse<C,R> & p,
00492               const OP<'+',VAL<X>,UPolDse<C,R> >& M)
00493   {
00494     assert(&(p.rep())!=&(M.op2.rep())); 
00495     UPolDse<C,R> tmp=M.op2;
00496     p.rep().resize(std::max(degree(M.op2),degree(tmp))+1);
00497     using UPOLDAR::init;  init(p.rep(),0);
00498     using UPOLDAR::add;   add(p.rep(),tmp,M.op2.rep());
00499     using UPOLDAR::checkdegree; checkdegree(p.rep());
00500   }
00501   //----------------------------------------------------------------------
00502   template<class C, class R> inline
00503   void assign(UPolDse<C,R> & p,
00504               const OP<'-',UPolDse<C,R>, UPolDse<C,R> >& M)
00505   {
00506     assert(&(p.rep())!=&(M.op1.rep())); assert(&(p.rep())!=&(M.op2.rep()));
00507     p.rep().resize(std::max(degree(M.op1),degree(M.op2))+1);
00508     using namespace UPOLDAR;
00509     init(p.rep(),0);
00510     sub(p.rep(),M.op1.rep(),M.op2.rep());
00511     checkdegree(p.rep());
00512   }
00513   //----------------------------------------------------------------------
00514   template<class C, class R> inline
00515   void assign(UPolDse<C,R> & p,
00516               const OP<'*',UPolDse<C,R>, UPolDse<C,R> >& M)
00517   {
00518     using namespace UPOLDAR;
00519     if( &(p.rep())==&(M.op1.rep()) || &(p.rep())==&(M.op2.rep()) )
00520       {
00521         UPolDse<C,R> tmp;
00522         tmp.rep().resize(std::max(degree(M.op1)+degree(M.op2)+1,0));
00523         init(tmp.rep(),0);
00524         mul(tmp.rep(),M.op1.rep(),M.op2.rep());
00525         p=tmp;
00526       }
00527     else
00528       {
00529         p.rep().resize(std::max(degree(M.op1)+degree(M.op2)+1,0));
00530         init(p.rep(),0);
00531         mul(p.rep(),M.op1.rep(),M.op2.rep());
00532       }
00533   }
00534   //----------------------------------------------------------------------
00535   template<class C, class R> inline
00536   void assign(UPolDse<C,R> & p,
00537               const OP<'.',UPolDse<C,R>,typename R::value_type>& M)
00538   {
00539     p.rep().resize(degree(M.op1)+1);
00540     using namespace UPOLDAR;
00541     mul_scalar(p.rep(),M.op1.rep(),M.op2);
00542   }
00543   //----------------------------------------------------------------------
00544   template<class C, class R> inline
00545   void assign(UPolDse<C,R> & p,
00546               const OP<'/',UPolDse<C,R>,UPolDse<C,R> >& M)
00547   {
00548     assert(M.op2!=0);
00549     UPolDse<C,R> top1(M.op1);
00550     using namespace EUCLIDIAN; div_rem(p,top1,M.op2);
00551   }
00552   //----------------------------------------------------------------------
00553   template<class C, class R> inline
00554   void assign(UPolDse<C,R> & r,
00555               const OP<'%',UPolDse<C,R>,UPolDse<C,R> >& M)
00556   {
00557     assert(M.op2!=0);
00558     r= M.op1;
00559     UPolDse<C,R> tmp;
00560     using namespace EUCLIDIAN; div_rem(tmp,r,M.op2);
00561   }
00562   //--------------------------------------------------------------------
00563   template<class C, class R> inline
00564   void assign(UPolDse<C,R> & r,
00565               const OP<'^',UPolDse<C,R>,unsigned int> M)
00566   {
00567     r=M.op1;
00568     for(unsigned int i=1;i<M.op2;i++) r*=M.op1;
00569   }
00570   
00571 } // namespace let
00572 //======================================================================
00573 #endif //UPOL_WITH_TEMP_EXP
00574 //======================================================================
00575 namespace let 
00576 {
00577   //--------------------------------------------------------------------
00582   template<class C, class R, class D, class S>  inline
00583   void assign(UPolDse<C,R> & u, const UPolDse<D,S> & P)
00584   {
00585     //    using let::assign_x;
00586     u.resize(degree(P)+1);
00587     for(int k=0; k< u.size();++k) let::assign(u[k],P[k]);
00588   }
00589   //--------------------------------------------------------------------
00593   template<class POL, class C, class S>
00594     POL convert(const UPolDse<C,S> & P, type::As<POL>)
00595   {
00596     using let::assign;
00597     POL u(degree(P)+1, type::AsSize());
00598     assign(u,P);
00599     return u;
00600   }
00601 }
00602 //======================================================================
00603 // INPUT OUTPUT
00604 //======================================================================
00606 template <class C, class R> inline
00607 std::ostream & operator<<(std::ostream & os, const UPolDse<C,R> & p)
00608 {
00609   using UPOLDAR::print;
00610   return print(os,p.rep(),UPolDse<C,R>::var_);
00611 }
00612 //----------------------------------------------------------------------
00614 template <class C, class R>
00615 std::istream & operator>>(std::istream & is, UPolDse<C,R> & P);
00616 //====================================================================
00617 template <class C, class R, class X>
00618 int SignAt(const UPolDse<C,R>& p, const X& x)
00619 {
00620   return sign(p(x));
00621 }
00622 //====================================================================
00623 template<class C, class R>
00624 UPolDse<C,R>::UPolDse(int n)
00625 {
00626   if(n==0)
00627     resize(0);
00628   else
00629     {
00630       rep().resize(1);
00631       rep()[0]=n;
00632       checkdegree(rep());
00633     }
00634 }
00635 //----------------------------------------------------------------------
00637 template<class C, class R>
00638 UPolDse<C,R>::UPolDse(value_type c, size_type n)
00639 {
00640   using UPOLDAR::set_monomial;  set_monomial(rep(),c,n);
00641 }
00642 //----------------------------------------------------------------------
00646 template<class C, class R>
00647 UPolDse<C,R>::UPolDse(size_type n, value_type * v)
00648 {
00649   rep().resize(n);
00650   iterator it=rep().begin(), iv=v;
00651   for(unsigned int i=0;i<n;i++) *it++=*iv++;
00652   using UPOLDAR::checkdegree;  checkdegree(rep());
00653 }
00654 //----------------------------------------------------------------------
00658 template<class C, class R>
00659 UPolDse<C,R>::UPolDse(iterator b, iterator e)
00660 {
00661   rep().resize(std::distance(b,e));
00662   iterator it=rep().begin(), iv=b;
00663   while(iv != e) *it++=*iv++;
00664   using UPOLDAR::checkdegree;  checkdegree(rep());
00665 }
00666 //----------------------------------------------------------------------
00670 template <class C, class R>
00671 UPolDse<C,R>::UPolDse(const char * s) {
00672   rep().resize(0);
00673   VECTOR::init(rep(),0);
00674   int n = strlen(s);
00675   if(s[n-1]==';')
00676     {
00677       synaps_input = new char[n+1];
00678       memcpy(synaps_input,s,n); synaps_input[n]='\0';
00679       synaps_inputlim = synaps_input + n;
00680     }
00681   else
00682     {
00683       synaps_input = new char[n+2];
00684       memcpy(synaps_input,s,n); synaps_input[n]=';'; synaps_input[n+1]='\0';
00685       synaps_inputlim = synaps_input + n+1;
00686     }
00687   synaps_inputptr = synaps_input;
00688 
00689   self_t m(1);
00690   bool sign  = true;
00691   bool first = true;
00692   int Ask=0;
00693   for (;;) {
00694     Ask = yylex();
00695     if (Ask == COEF) { /* Monome constant */
00696       value_type c;//(yylval);
00697       let::assign(c,yylval);
00698       m *= c;
00699     }
00700     else if (Ask == XID) { /* Variable */
00701       char * p = strchr(yylval,'^');
00702       if (p == NULL){
00703         m *= self_t(value_type(1),1);
00704       } else {
00705         p++;
00706         m *= self_t(value_type(1),atoi(p));
00707       }
00708     }
00709     else if (Ask == MULT); /* Multiplication */
00710     else if (Ask == SUM) { /* Addition */
00711       if (sign) {
00712         *this += m;
00713         m = self_t(1);
00714       }
00715       else {
00716         *this -= m;
00717         sign = true;
00718         m = self_t(1);
00719       }
00720     }
00721     else if (Ask == MINUS) { /* Soustraction */
00722       if (first)
00723         sign = false;
00724       else if (sign) {
00725         *this += m;
00726         sign = false;
00727         m = self_t(1);
00728       }
00729       else {
00730         *this -= m;
00731         m = self_t(1);
00732       }
00733     }
00734     else if (Ask == TERMINATOR) { /* ; */
00735       if (sign)
00736         *this += m;
00737       else
00738         *this -= m;
00739       break;
00740     }
00741     first = false;
00742   }
00743   delete[] synaps_input;
00744 }
00745 //----------------------------------------------------------------------
00747 template<class C, class R> inline
00748 bool UPolDse<C,R>::operator==(int n) const
00749 {
00750   if(n==0 && degree(*this)<0)
00751     return(true);
00752   else{
00753     return( (degree(*this)==0) && ((*this)[0]==n) );
00754   }
00755 }
00756 //----------------------------------------------------------------------
00758 template<class C, class R> inline
00759 bool UPolDse<C,R>::operator==(const UPolDse<C,R> & p) const
00760 {
00761   return &(rep())== &p.rep();
00762 }
00763 //----------------------------------------------------------------------
00764 template<class C, class R> inline
00765 UPolDse<C,R> & UPolDse<C,R>::operator+= (const UPolDse<C,R> & P)
00766 {
00767   using UPOLDAR::add; add(rep(),P.rep());
00768   using UPOLDAR::checkdegree; checkdegree(rep());
00769   return *this;
00770 }
00771 //--------------------------------------------------------------------
00772 template<class C, class R> inline
00773 UPolDse<C,R>& UPolDse<C,R>::operator+=(const C& c)
00774 {
00775   if(degree(*this) >= 0)
00776     {
00777       using UPOLDAR::add_cst; add_cst(rep(),c);
00778     }
00779   else
00780     *this=UPolDse<C,R>(c,1);
00781   return *this;
00782 }
00783 //----------------------------------------------------------------------
00784 template<class C, class R> inline
00785 UPolDse<C,R> & UPolDse<C,R>::operator-= (const UPolDse<C,R> & P)
00786 {
00787   rep().resize(std::max(degree(*this),degree(P))+1);
00788   using UPOLDAR::sub; sub(rep(),P.rep());
00789   using UPOLDAR::checkdegree; checkdegree(rep());
00790   return *this;
00791 }
00792 //--------------------------------------------------------------------
00793 template<class C, class R> inline
00794 UPolDse<C,R>& UPolDse<C,R>::operator-=(const C& c)
00795 {
00796   if(degree(*this) >= 0)
00797     {
00798       using UPOLDAR::add_cst; add_cst(rep(),-c);
00799     }
00800   else
00801     *this=UPolDse<C,R>(c,1);
00802   return *this;
00803 }
00804 //----------------------------------------------------------------------
00805 template<class C, class R> inline
00806 UPolDse<C,R> & UPolDse<C,R>::operator*= (const UPolDse<C,R> & P)
00807 {
00808   //  using namespace UPOLDAR;  mul(rep(),P.rep());
00809   (*this)= (*this) * P;
00810   return (*this);
00811 }
00812 //----------------------------------------------------------------------
00813 template<class C, class R> inline
00814 UPolDse<C,R> & UPolDse<C,R>::operator*= (const typename UPolDse<C,R>::value_type & c)
00815 {
00816   if (c != 0)
00817     {
00818       using UPOLDAR::mul_ext; mul_ext(rep(),rep(),c);
00819     }
00820   else 
00821     {
00822       rep().resize(0);// rep()[0]=0;
00823     }
00824   return *this;
00825 }
00826 //----------------------------------------------------------------------
00828 template<class C, class R> inline
00829 UPolDse<C,R> & UPolDse<C,R>::operator/= (const typename UPolDse<C,R>::value_type & c)
00830 {
00831   using namespace VECTOR; div_ext(rep(),rep(),c);
00832   return *this;
00833 }
00834 //----------------------------------------------------------------------
00836 template <class C, class R> inline
00837 UPolDse<C,R> & UPolDse<C,R>::operator/= (const UPolDse<C,R> & Q) {
00838   using namespace UPOLDAR;
00839   assert(Q!=0);
00840   if (*this ==0) return *this;
00841   if (&rep()==&Q.rep()) {*this=1;return *this;}
00842   UPolDse<C,R> quo(0);
00843   div_rem(quo,*this,Q);
00844   *this=quo;
00845   return *this;
00846 }
00847 //-----------------------------------------------------------------------------
00849 template <class C, class R> inline
00850 UPolDse<C,R> & UPolDse<C,R>::operator%= (const UPolDse<C,R> & Q)
00851 {
00852   assert(Q!=0);
00853   if (*this ==0) return *this;
00854   if (&rep()==&Q.rep()) {*this=0;return *this;}
00855   UPolDse<C,R> quo;
00856   EUCLIDIAN::div_rem(quo,*this,Q);
00857   return *this;
00858 }
00859 
00860 template<class C, class R> inline 
00861 UPolDse<C,R> & UPolDse<C,R>::operator%=( const C & c )
00862 {
00863   using namespace UPOLDAR;
00864   coeff_modulo(rep(),c);
00865   checkdegree(rep());
00866   return *this;
00867 };
00868 
00869 //-----------------------------------------------------------------------------
00872 template <class C, class R> template<class T> inline
00873 T UPolDse<C,R>::operator()(const T & c) const
00874 {
00875   using UPOLDAR::eval;
00876   return eval(rep(),c);
00877 }
00878 //----------------------------------------------------------------------
00879 // Input operator. The variable is @x@ or @x0@. Ended by a @;@.
00880 template <class C, class R> inline
00881 std::istream & operator>>(std::istream & is, UPolDse<C,R> & P)
00882 {
00883   std::string s, ss = "";
00884   int p;
00885   for (;;) {
00886     is >> s;
00887     p = s.find(';');
00888     if (p == -1)
00889       ss += s;
00890     else {
00891       ss += s.substr(0,p+1);
00892       break;
00893     }
00894   }
00895   P = UPolDse<C,R>(ss.c_str());
00896   return is;
00897 }
00898 
00899   template <class C, class R>
00900   std::ostream & print_as_coeff(std::ostream & os, const UPolDse<C,R> & p)
00901   {
00902     return os<<"+("<<p<<")";
00903   }
00904 
00905 template<class C, class R>
00906 void checkdegree( UPolDse<C,R> & p )
00907 {
00908   using namespace UPOLDAR;
00909   checkdegree(p);
00910 };
00911 
00912 //template<class C, class R> 
00913 //UPolDse<C,R> abs( const UPolDse<C,R> & p ) { if ( p[degree(p)] < 0 ) return -p; };
00914 
00915 __END_NAMESPACE_SYNAPS
00916 
00917 #include "traits.h"
00918 
00919 //====================================================================
00920 #endif // SYNAPS_UPOL_UPOLDSE_H
00921 

SYNAPS DOCUMENTATION
logo