realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/sparse_dual.hpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *      This file is part of the source code of the realroot library.
00003 *      Author(s): B. Mourrain, GALAAD, INRIA                 
00004 **********************************************************************/
00005 
00006 #ifndef realroot_sparse_dual_hpp
00007 #define realroot_sparse_dual_hpp
00008 
00009 #include <realroot/sparse_monomials.hpp>
00010 
00011 //--------------------------------------------------------------------
00012 namespace mmx {
00013   namespace sparse {
00014 //----------------------------------------------------------------------
00015 template <class C,
00016           class O=DegRevLex>
00017 struct dual: public monomial_seq<C,O> {
00018 
00019   // Types
00020     
00021   typedef monomial_seq<C,O>                  R;
00022   typedef monomial_seq<C,O>                  base_t;
00023 
00024   typedef typename R::monom_t                monom_t;
00025   typedef C                                  coeff_t;
00026   typedef O                                  order_t;
00027   typedef typename R::iterator               iterator;
00028   typedef typename R::const_iterator         const_iterator;
00029   typedef typename R::reverse_iterator       reverse_iterator;
00030   typedef typename R::const_reverse_iterator const_reverse_iterator;
00031   typedef monomial_seq<C,O>                  poly_t;
00032   typedef dual<C,O>                          self_t;
00033 
00034   // Constructors
00035   dual(): poly_t() {}
00036   dual(const coeff_t & c): poly_t(c) {}
00037   dual(const coeff_t & c, int d, int v): poly_t(c,-d,v) {}
00038   dual(const monom_t & m):  poly_t(m) {neg_exponent(*this);}
00039   //  dual(int n, const monom_t * t): poly_t(n,t) {neg_exponent(*this);}
00040 
00041   dual(const self_t & P): poly_t(P){}
00042   dual(const char * s, variables& vars = variables::default_): 
00043     poly_t(s,vars) {neg_exponent(*this);}
00044   dual(const char * s, const variables& vars):
00045     poly_t(s,vars) {neg_exponent(*this);}
00046 
00047   template<class Q>
00048   dual(const dual<C,Q>& p) : poly_t(p) {}
00049   
00050   // Destructor
00051   // no dynamic allocation at this level.
00052 
00053   //  static Variable var;
00054 
00055   // Assignment operators
00056   self_t & operator =(const self_t & x)  
00057   { 
00058     this->base_t::operator=(x); return *this;
00059   }
00060   self_t & operator =(const coeff_t & c) {*this=self_t(c); return *this;}
00061   self_t & operator =(int n)             {*this=self_t(n); return *this;}
00062   self_t & operator =(const monom_t & m) {*this=self_t(m); return *this;}
00063 
00064   C operator()(const poly_t& p);
00065 
00066 };
00067 
00068 
00069 template<class C, class O>
00070 void neg_exponent(dual<C,O>& p)
00071 {
00072   typedef typename dual<C,O>::iterator iterator;
00073   for(iterator it=p.begin();it != p.end();it++)
00074     {
00075       for(int j=0;j<(it->nvars()+1);j++)
00076         {
00077           it->set_expt(j,-(*it)[j]);
00078         }
00079     }
00080 }
00081 //--------------------------------------------------------------------
00086 template<class C, class O>
00087 C dual<C,O>::operator()(const monomial_seq<C,O>& p)
00088 {
00089   monomial_seq<C,O> t= ((monomial_seq<C,O>)(*this))*p;
00090   typedef typename monomial_seq<C,O>::reverse_iterator iterator;
00091   iterator it;
00092   for(it=t.rbegin(); it != t.rend();it++)
00093     {
00094       bool nul=true;
00095       for(unsigned j=0;j<(it->nvars()+1) && nul;j++)  
00096         {
00097           if((*it)[j]!=0) nul=false;
00098         }
00099       if(nul) return it->coeff();
00100     }
00101   return C(0);
00102 }
00103 //--------------------------------------------------------------------
00104 template<class C, class O> inline void
00105 add(dual<C,O>& res, const dual<C,O>& a, const dual<C,O>& b) {
00106   add((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,(const monomial_seq<C,O>&)b);
00107 } 
00108 //--------------------------------------------------------------------
00109 template<class C, class O> inline void
00110 add(dual<C,O>& res, const dual<C,O>& a, const C& b) {
00111   add((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,b);
00112 }
00113 //--------------------------------------------------------------------
00114 template<class C, class O> inline void
00115 add(dual<C,O>& res, const C& b , const dual<C,O>& a) {
00116   add((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,b);
00117 }
00118 //--------------------------------------------------------------------
00119 template<class C, class O> inline void
00120 sub(dual<C,O>& res, const dual<C,O>& a, const dual<C,O>& b) {
00121   sub((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,(const monomial_seq<C,O>&)b);
00122 } 
00123 //--------------------------------------------------------------------
00124 template<class C, class O> inline void
00125 sub(dual<C,O>& res, const dual<C,O>& a, const C& b) {
00126   sub((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,b);
00127 }
00128 //--------------------------------------------------------------------
00129 template<class C, class O> inline void
00130 sub(dual<C,O>& res, const C& a, const dual<C,O>& b) {
00131   sub((monomial_seq<C,O>&)res,a,(const monomial_seq<C,O>&)b);
00132 } 
00133 //--------------------------------------------------------------------
00134 template<class C, class O> inline void
00135 mul(dual<C,O>& res, const dual<C,O>& a, const dual<C,O>& b) {
00136   mul((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,(const monomial_seq<C,O>&)b);
00137 }
00138 //--------------------------------------------------------------------
00139 template<class C, class O> inline void
00140 mul(dual<C,O>& res, const dual<C,O>& a, const C& b) {
00141   mul((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,b);
00142 } 
00143 //--------------------------------------------------------------------
00144 template<class C, class O> inline void
00145 mul(dual<C,O>& res, const C& b, const dual<C,O>& a) {
00146   mul((monomial_seq<C,O>&)res,(const monomial_seq<C,O>&)a,b);
00147 } 
00148 //--------------------------------------------------------------------
00154 template<class C, class O> void
00155 mul(dual<C,O>& res, const monomial_seq<C,O>& p, const dual<C,O>& l) {
00156   monomial_seq<C,O> t;
00157   mul(t,p,(monomial_seq<C,O>)l);
00158   typedef typename dual<C,O>::const_iterator iterator;
00159   for(iterator it=t.begin();it != t.end();it++)
00160     {
00161       bool neg=true;
00162       for(unsigned j=0;j<it->size() && neg;j++) {
00163         if((*it)[j]>0) neg=false;
00164       }
00165       if(neg) res.push_back(*it);
00166     }
00167 }
00168 
00169 // template<class C, class O> Seq<polynom< monomial_seq<C,O> >
00170 // coefficients(const Polynomial & f, const int & v ) {
00171 //     unsigned N = degree(f,v)+1;
00172 //     Seq<Polynomial> r(N);
00173 //     typename Polynomial::Monomial m;
00174 //     for(typename Polynomial::const_iterator it=f.begin(); it != f.end(); it++) {
00175 //       m=*it;
00176 //       if (v<(int)m.size()) m.set_expt(v,0);
00177 //       r[(*it)[v]]+= Polynomial(m);
00178 //     }
00179 //     return r;
00180 //   }
00181 
00182 
00183 //--------------------------------------------------------------------
00188 template<class C, class O> void
00189 mul(monomial_seq<C,O>& res, const dual<C,O>& l, const monomial_seq<C,O>& p) {
00190   monomial_seq<C,O> t;
00191   mul(t,(monomial_seq<C,O>)l,p);
00192   typedef typename dual<C,O>::const_iterator iterator;
00193   for(iterator it=t.begin();it != t.end();it++)
00194     {
00195       bool pos=true;
00196       for(unsigned j=0;j<it->size() && pos;j++) {
00197         if((*it)[j]<0) pos=false;
00198       }
00199       if(pos) res.push_back(*it);
00200     }
00201 }
00202 
00203 //----------------------------------------------------------------------    
00204 template<class C, class O> inline void 
00205 div(dual<C,O> &f, const C& c) {
00206   for(typename dual<C,O>::iterator it=f.begin(); it != f.end(); it++) 
00207     it->coeff()/=c;
00208 }
00209 
00210 //----------------------------------------------------------------------
00211 template<class C, class O> void 
00212 div(dual<C,O> &r, const dual<C,O>& p, const C & c) {
00213   r = p; div(r,c);
00214 }
00215 
00216 //--------------------------------------------------------------------
00217 #ifndef MMX_WITH_PLUS_SIGN
00218 #define MMX_WITH_PLUS_SIGN
00219   template<class X> bool with_plus_sign(const X& x) {return x>0;}
00220 #endif  //MMX_WITH_PLUS_SIGN
00221 
00222 template <class OSTREAM, class C> inline OSTREAM & 
00223 print_dual (OSTREAM & os, const monom<C>& m, const variables& V) { 
00224   if (m.coeff() ==0 ) {
00225     os<<"0"; return os;
00226   }
00227   int i=m.size()-1;
00228   while(i> -1 && m[i]==0) i--;
00229   if(i<0)
00230     os <<m.coeff();
00231   else {
00232     if(m.coeff() != 1) {
00233       if(m.coeff()==-1) 
00234          os << "-"; 
00235       else {  
00236         os << m.coeff(); os <<"*"; 
00237       }
00238     }
00239   }
00240   bool first=true;
00241   for (unsigned i = 0; i < m.size(); ++i) {
00242     if (m[i] !=0) {
00243       if(first)
00244         first =false;
00245       else
00246         os<<'*';
00247       os << 'd'<<V[i];
00248       if (m[i] != -1)
00249         os << '^' <<(-m[i]);
00250     }
00251   }
00252   return os;
00253 }
00254 //--------------------------------------------------------------------
00256 
00259 template <class OSTREAM, class C, class O> OSTREAM & 
00260 print(OSTREAM & os, const dual<C,O> & P, const variables& V ) {
00261  if ( P.begin() == P.end() ) {
00262    os << '0';
00263    return os;
00264  }
00265  typename dual<C,O>::const_iterator i = P.begin();
00266  while ( i != P.end() ) {
00267    if ( with_plus_sign(i->coeff()) && i !=P.begin())
00268      os <<'+';
00269    print_dual(os,*i++,V);
00270  }
00271  return os;
00272 }
00273 //--------------------------------------------------------------------__
00274 } //namespace sparse
00275 
00276 //======================================================================
00277 # define Polynomial sparse::dual<C,O>
00278 # define TMPL template<class C, class O>
00279 
00280 template<class A, class B> struct use;
00281 struct operators_of;
00282 
00283 TMPL struct use<operators_of,Polynomial> {
00284 
00285     static inline void 
00286     add (Polynomial &r, const Polynomial &a ) { 
00287       sparse::add (r, a); 
00288     }
00289     static inline void 
00290     add (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00291       sparse::add (r, a, b); 
00292     }
00293     static inline void
00294     add (Polynomial &r, const Polynomial &a, const C & b) {
00295       sparse::add (r, a, b); 
00296     }
00297     static inline void
00298     add (Polynomial &r, const C & a, const Polynomial &b) {
00299       sparse::add (r, b, a); 
00300     }
00301     static inline void
00302     sub (Polynomial &r, const Polynomial &a ) {
00303       sparse::sub (r, a ); 
00304     }
00305     static inline void
00306     sub (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00307       sparse::sub (r, a, b); 
00308     }
00309     static inline void
00310     sub (Polynomial &r, const C & a, const Polynomial &b) {
00311       sparse::sub (r, a, b); 
00312     }
00313     static inline void
00314     sub (Polynomial &r, const Polynomial &a, const C & b) {
00315       sparse::sub (r, a, b); 
00316     }
00317     static inline void
00318     mul (Polynomial &r, const Polynomial &a ) {
00319       sparse::mul (r, a ); 
00320     }
00321     static inline void
00322     mul (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00323       sparse::mul (r, a, b); 
00324 }
00325     static inline void
00326     mul (Polynomial &r, const Polynomial &a, const C & b) {
00327       sparse::mul (r, a, b); }
00328     static inline void
00329     mul (Polynomial &r, const C & a, const Polynomial &b) {
00330       sparse::mul (r, b, a); 
00331     }
00332     static inline void
00333     div (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00334       sparse::div (r, a, b); 
00335     }
00336     static inline void
00337     div (Polynomial &r, const Polynomial &a, const C & b) {
00338       sparse::div (r, a, b); 
00339     }
00340     static inline void
00341     rem (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00342       sparse::rem (r, b, a); 
00343     }
00344 };
00345 # undef Polynomial
00346 # undef TMPL
00347 //====================================================================
00348 } //namespace mmx
00349 #endif // realroot_sparse_dual_hpp
00350