00001
00002
00003
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
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
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
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
00051
00052
00053
00054
00055
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
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
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 }
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 }
00349 #endif // realroot_sparse_dual_hpp
00350