realroot_doc 0.1.1
|
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