realroot_doc 0.1.1
|
00001 #ifndef realroot_sparse_monomials_hpp 00002 #define realroot_sparse_monomials_hpp 00003 # include <list> 00004 # include <vector> 00005 # include <algorithm> 00006 # include <realroot/binomials.hpp> 00007 # include <realroot/Seq.hpp> 00008 # include <realroot/monomial.hpp> 00009 # include <realroot/monomial_ordering.hpp> 00010 # define TMPL template<class C, class O, class MONOM, class REP> 00011 # define TMPLX template<class C, class O, class MONOM, class REP, class X> 00012 # define Polynomial monomial_seq<C,O,MONOM,REP> 00013 # define CLASS monomial_seq 00014 # define sparse_monomials sparse::monomial_seq 00015 //====================================================================== 00016 namespace mmx { 00017 00018 00019 //-------------------------------------------------------------------- 00020 00022 namespace sparse { 00023 00024 template<class C, class O = DegRevLex, 00025 class MONOM=monom<C>, 00026 class REP=std::list<MONOM> > 00027 struct CLASS : public REP { 00028 00029 typedef C coeff_t; 00030 typedef C Scalar; 00031 typedef C value_type; 00032 typedef O Order; 00033 typedef REP base_t; 00034 typedef typename base_t::value_type monom_t; 00035 typedef typename base_t::value_type Monomial; 00036 typedef typename base_t::iterator iterator; 00037 typedef typename base_t::const_iterator const_iterator; 00038 typedef typename base_t::reverse_iterator reverse_iterator; 00039 typedef typename base_t::const_reverse_iterator const_reverse_iterator; 00040 typedef Polynomial self_t; 00041 00042 Polynomial(): base_t() {} 00043 Polynomial(const C& c):base_t() { 00044 if (c!=(coeff_t)0) 00045 this ->push_back(monom_t(c)); 00046 } 00047 00048 00049 Polynomial(const C& c, int d, unsigned v); 00050 Polynomial(const monom_t& m): base_t() { this->push_back(m);}; 00051 00052 bool operator==( const Polynomial& p ) const; 00053 bool operator!=( const Polynomial& p ) const { return !(*this==p); } 00054 bool operator==( const C& c ) const; 00055 bool operator!=( const C& c ) const { return !(*this==c); } 00056 00057 int nbvar() const; 00058 00059 static MonomialOrdering * m_order; 00060 static MonomialOrdering * order() {return m_order;} 00061 static bool 00062 less (const monom_t & m1, const monom_t & m2) { 00063 // std::cout<<"less "<< m1<< " "<< m2<<std::endl; 00064 return m_order->less(m1.begin(),m1.size(), 00065 m2.begin(),m2.size()); 00066 } 00067 }; 00068 }//namespace sparse 00069 00070 // #ifndef MMX_WITH_PLUS_SIGN 00071 // #define MMX_WITH_PLUS_SIGN 00072 // template<class X> bool with_plus_sign(const X& x) {return true;}//x>0;} 00073 // #endif //MMX_WITH_PLUS_SIGN 00074 // TMPL bool with_plus_sign(const SparsePolynomial& x) {return true;} 00075 00076 00077 namespace sparse { 00078 00079 TMPL MonomialOrdering* Polynomial::m_order = (MonomialOrdering*)new O; //DegreeLex; 00080 00081 00082 TMPL inline 00083 Polynomial::CLASS(const C& c, int d, unsigned v):base_t() { 00084 this ->push_back(monom_t(c,d,v));} 00085 00087 TMPL int 00088 Polynomial::nbvar() const{ 00089 int v = 0; 00090 for (const_iterator it = this->begin(); it != this->end(); ++it) 00091 v = std::max(v,it->l_variable()+1); 00092 return v; 00093 } 00094 00095 00096 TMPL bool 00097 Polynomial::operator== (const Polynomial& p) const { 00098 return ((base_t)*this==(base_t)p); 00099 } 00100 00101 TMPL bool 00102 Polynomial::operator== (const C& c) const { 00103 if(c==0) 00104 return (this->size()==0); 00105 else 00106 return(this->size()==1 && (this->begin()->coeff() == c) && degree(*this->begin())== 0); 00107 } 00108 00109 00110 //==================================================================== 00111 TMPL void 00112 add(Polynomial & result, const Polynomial& p1, const Polynomial& p2) 00113 { 00114 assert(&result != &p1); assert(&result != &p2); 00115 00116 typedef typename Polynomial::const_iterator const_iterator; 00117 typedef typename Polynomial::iterator iterator; 00118 typedef typename Polynomial::value_type coeff_type; 00119 typedef typename Polynomial::Scalar Scalar; 00120 00121 const_iterator 00122 b1=p1.begin(), 00123 e1=p1.end(), 00124 b2=p2.begin(), 00125 e2=p2.end(); 00126 result.resize(p1.size()+p2.size()); 00127 iterator i=result.begin(); 00128 while (b1!=e1 && b2!=e2) { 00129 if(Polynomial::less(*b2,*b1)) 00130 *i++=*b1++; 00131 else if(Polynomial::less(*b1,*b2)) 00132 *i++=*b2++; 00133 else { 00134 coeff_type c=b1->coeff()+ b2->coeff(); 00135 if (c !=(Scalar)0) { 00136 *i =*b1; 00137 i->set_coeff(c); 00138 ++i; 00139 } 00140 ++b1;++b2; 00141 } 00142 } 00143 while (b1!=e1) *i++=*b1++; 00144 while (b2!=e2) *i++=*b2++; 00145 00146 int m=std::distance(result.begin(),i); 00147 assert(m>=0); 00148 result.resize(m); 00149 } 00150 //---------------------------------------------------------------------- 00152 TMPL void 00153 add(Polynomial & p1, const Polynomial& p2) { 00154 00155 assert(&p1 != &p2); 00156 typedef typename Polynomial::const_iterator const_iterator; 00157 typedef typename Polynomial::iterator iterator; 00158 typedef typename Polynomial::value_type coeff_type; 00159 00160 // reserve(p1,p1.size()+p2.size()); 00161 iterator b1=p1.begin(); 00162 const_iterator b2=p2.begin(); 00163 while (b1!=p1.end() && b2!=p2.end()) { 00164 if(Polynomial::less(*b2,*b1)) 00165 b1++; 00166 else if(Polynomial::less(*b1,*b2)) 00167 { 00168 b1 = p1.insert(b1,*b2); b1++; b2++; 00169 } 00170 else 00171 { 00172 coeff_type c=b1->coeff() + b2->coeff(); 00173 if (c != (typename Polynomial::Scalar)0) { 00174 b1->set_coeff(c); ++b1; 00175 }else{ 00176 b1 = p1.erase(b1); 00177 } 00178 ++b2; 00179 } 00180 } 00181 p1.insert(b1,b2,p2.end()); 00182 } 00183 //---------------------------------------------------------------------- 00184 template<class C, class O, class MONOM, class REP, class I, class J, class M> 00185 I add(Polynomial & p1, I b1, J e1, const M & m2) { 00186 typedef typename Polynomial::value_type::coeff_t coeff_type; 00187 00188 while (b1!=e1) { 00189 if(Polynomial::less(m2,*b1)) 00190 { 00191 b1++; //COUNT<M>('i'); 00192 } 00193 else if(Polynomial::less(*b1,m2)) 00194 { 00195 b1=p1.insert(b1,m2); 00196 return b1; 00197 } 00198 else 00199 { 00200 coeff_type c=b1->coeff() + m2.coeff(); 00201 if (c !=0) { 00202 b1->set_coeff(c); 00203 }else 00204 b1 = p1.erase(b1); 00205 return(b1); 00206 } 00207 } 00208 b1 = p1.insert(b1,m2); 00209 return b1; 00210 } 00211 //---------------------------------------------------------------------- 00212 TMPL void 00213 add(Polynomial & p, const typename Polynomial::monom_t& m) { 00214 Polynomial q(m); add(p,q); 00215 } 00216 00217 TMPL void 00218 add(Polynomial & p, const C& c) { 00219 Polynomial m(c); add(p,m); 00220 } 00221 //---------------------------------------------------------------------- 00222 TMPLX void 00223 add(Polynomial & r, const Polynomial& q, const X& c) { 00224 Polynomial m(c); add(r,q,m); 00225 } 00226 //---------------------------------------------------------------------- 00227 TMPL void 00228 add(Polynomial & r, const C& c, const Polynomial& q) { 00229 Polynomial m(c); add(r,q,m); 00230 } 00231 //---------------------------------------------------------------------- 00232 TMPL void 00233 sub(Polynomial & result, const Polynomial& p1, const Polynomial& p2) 00234 { 00235 assert(&result != &p1); assert(&result != &p2); 00236 typedef typename Polynomial::const_iterator const_iterator; 00237 typedef typename Polynomial::iterator iterator; 00238 typedef typename Polynomial::value_type coeff_type; 00239 const_iterator 00240 b1=p1.begin(), 00241 e1=p1.end(), 00242 b2=p2.begin(), 00243 e2=p2.end(); 00244 result.resize(p1.size()+p2.size()); 00245 iterator i=result.begin(); 00246 while (b1!=e1 && b2!=e2) { 00247 if(Polynomial::less(*b2,*b1)) 00248 *i++=*b1++; 00249 else if(Polynomial::less(*b1,*b2)) 00250 { 00251 *i=*b2++; i->coeff()*= -1; i++; 00252 } 00253 else { 00254 coeff_type c=b1->coeff()- b2->coeff(); 00255 if (c !=0) { 00256 *i =*b1; 00257 i->set_coeff(c); 00258 ++i; 00259 } 00260 ++b1;++b2; 00261 } 00262 } 00263 while (b1!=e1) *i++=*b1++; 00264 while (b2!=e2) {*i=*b2++;i->coeff()*=-1;i++;} 00265 00266 int m=std::distance(result.begin(),i); 00267 assert(m>=0); 00268 result.resize(m); 00269 } 00270 //-------------------------------------------------------------------- 00271 TMPL void 00272 sub(Polynomial & p, const Polynomial& q) { 00273 Polynomial m(q); mul(m,(C)-1); 00274 add(p,m); 00275 } 00276 //-------------------------------------------------------------------- 00277 TMPLX void 00278 sub(Polynomial & r, const Polynomial& q, const X& c) { 00279 Polynomial m(C(-c)); add(r,q,m); 00280 } 00281 //-------------------------------------------------------------------- 00282 TMPLX void 00283 sub(Polynomial & r, const X& c, const Polynomial& q) { 00284 Polynomial m(c); sub(r,m,q); 00285 } 00286 //---------------------------------------------------------------------- 00288 TMPL void 00289 mul(Polynomial &r, const C & c) { 00290 for(typename Polynomial::iterator it=r.begin(); it!=r.end(); ++it) { 00291 it->coeff()*=c; 00292 } 00293 } 00294 //---------------------------------------------------------------------- 00295 TMPL void 00296 mul(Polynomial &r, const Polynomial& p, const C & c) { 00297 r = p; mul(r,c); 00298 } 00299 00300 //---------------------------------------------------------------------- 00301 TMPLX void 00302 mul(Polynomial &r, const X & c, const Polynomial& p) { 00303 r = p; mul(r,c); 00304 } 00305 //---------------------------------------------------------------------- 00307 template <class C, class O, class MONOM, class REP, class M> inline void 00308 mul_ext(Polynomial &r, const Polynomial& a, const M & m) { 00309 r.resize(a.size()); 00310 typename Polynomial::const_iterator b=a.begin(); 00311 typename Polynomial::iterator i=r.begin(); 00312 for(; b!=a.end(); ++i, ++b) *i = (*b) * m; 00313 // VECTOR::apply_mult(r, a, m); 00314 } 00315 //---------------------------------------------------------------------- 00317 TMPL inline void 00318 mul(Polynomial &r, const Polynomial& a, const typename Polynomial::monom_t & m) { 00319 mul_ext(r,a,m); 00320 } 00321 //---------------------------------------------------------------------- 00323 TMPL inline void 00324 mul(Polynomial &r, const typename Polynomial::monom_t & m) { 00325 typename Polynomial::iterator i=r.begin(); 00326 for(; i!=r.end(); ++i) *i *= m; 00327 } 00328 //---------------------------------------------------------------------- 00329 template<class C, class O, class MONOM, class REP, class M> inline void 00330 mul_ext_e(Polynomial &result, const Polynomial& a, const M & m) 00331 { 00332 typedef typename Polynomial::const_iterator const_iterator; 00333 typedef typename Polynomial::iterator iterator; 00334 typedef typename Polynomial::monom_t R; 00335 00336 result.resize(0); 00337 iterator i=result.begin(); 00338 R tmp; 00339 for(const_iterator b=a.begin();b!=a.end(); ++b) 00340 { 00341 tmp = (*b) * m; 00342 (i=result.insert(i,tmp))++; 00343 } 00344 } 00345 //---------------------------------------------------------------------- 00347 TMPL inline void 00348 mul(Polynomial &r, const Polynomial& a, const Polynomial& b) 00349 { 00350 if (a.size()==0) return; 00351 if (b.size()==0) return; 00352 if (a.size()<b.size()) 00353 mul(r,a.begin(),a.end(),b); 00354 else 00355 mul(r,b.begin(),b.end(),a); 00356 } 00357 00359 TMPLX inline void 00360 mul(Polynomial &r, 00361 const Polynomial& a, 00362 const Polynomial& b, const X & o) 00363 { 00364 typedef typename Polynomial::const_iterator const_iterator; 00365 typedef typename Polynomial::iterator iterator; 00366 typedef typename Polynomial::monomt_t M; 00367 00368 r.resize(0); 00369 M m; 00370 for(const_iterator i=b.begin();i !=b.end();i++) 00371 { 00372 if(r.size()) 00373 { 00374 iterator ip = r.begin(); 00375 for(const_iterator j=a.begin();j != a.end();j++) { 00376 m = *j * *i; 00377 ip = add(r,ip,r.end(),m);//,O()); 00378 } 00379 //MPOLDST::mul_ext(tmp,a,*i); 00380 //MPOLDST::add<list<M>,vector<M>,O>(r,tmp); 00381 } 00382 else 00383 mul_ext(r,a,*i); 00384 } 00385 } 00386 00387 //---------------------------------------------------------------------- 00388 TMPL inline void 00389 mul(Polynomial &r, 00390 typename Polynomial::const_iterator b, 00391 typename Polynomial::const_iterator e, 00392 const Polynomial& p) { 00393 00394 00395 typedef typename Polynomial::const_iterator const_iterator; 00396 int n=std::distance(b,e); 00397 assert(n>=0); 00398 if (n==0) r.resize(0); 00399 if (n==1) 00400 mul_ext(r,p,*b); 00401 else { 00402 const_iterator med=b; // b+(n/2); 00403 for(int i=0; i<n/2 && med !=e;i++,med++) {} 00404 00405 Polynomial tmp0((C)0), tmp1((C)0); 00406 mul(tmp0,b,med,p); 00407 mul(tmp1,med,e,p); 00408 add(r,tmp0,tmp1); 00409 } 00410 00411 } 00412 TMPL inline void 00413 mul(Polynomial &r, const Polynomial& p) 00414 { 00415 Polynomial s(r); mul(r,s,p); 00416 } 00417 //---------------------------------------------------------------------- 00418 TMPL inline void 00419 div(Polynomial &q, const Polynomial& a, const Polynomial& b) 00420 { 00421 Polynomial r(a); 00422 div_rem(q,r,b); 00423 } 00424 00425 TMPL inline void 00426 div(Polynomial &r, const Polynomial& b) 00427 { 00428 Polynomial a(r); 00429 div(r,a,b); 00430 } 00431 00432 TMPL inline void 00433 div(Polynomial &f, const typename Polynomial::Scalar& c) 00434 { 00435 for(typename Polynomial::iterator it=f.begin(); it != f.end(); it++) 00436 it->coeff()/=c; 00437 } 00438 00439 //---------------------------------------------------------------------- 00440 TMPL void 00441 div(Polynomial &r, const Polynomial& p, const C & c) { 00442 r = p; div(r,c); 00443 } 00444 00445 //---------------------------------------------------------------------- 00446 TMPL inline void 00447 rem(Polynomial &r, const Polynomial& a, const Polynomial& b) 00448 { 00449 Polynomial q; r=a; 00450 div_rem(q,r,b); 00451 } 00452 00453 //---------------------------------------------------------------------- 00454 template<class C, class O, class MONOM, class REP, class U> void 00455 coefficients(Seq<U>& r,const Polynomial& f,int v) { 00456 unsigned N = degree(f,v)+1; 00457 r=Seq<U>(N); 00458 typename Polynomial::monom_t m; 00459 for(typename Polynomial::const_iterator it=f.begin(); it != f.end(); it++) { 00460 m=*it; 00461 if (v<(int)m.size()) m.set_expt(v,0); 00462 r[(*it)[v]]+= U(m); 00463 } 00464 } 00465 00466 TMPL void 00467 coefficients(Seq<C>& r, const Polynomial& f) { 00468 for(typename Polynomial::const_iterator it=f.begin(); it != f.end(); it++) { 00469 r<<it->coeff(); 00470 } 00471 } 00472 //---------------------------------------------------------------------- 00474 template <class R> int lvar (const R & p) { 00475 int v = -1; 00476 for (typename R::const_iterator it = p.begin(); it != p.end(); ++it) 00477 v = std::max(v,it->l_variable()); 00478 return v; 00479 } 00480 //-------------------------------------------------------------------- 00482 template <class R> unsigned nbvar (const R & p) { 00483 return p.nbvar(); 00484 } 00485 //---------------------------------------------------------------------- 00487 template <class R> int 00488 degree (const R & p) { 00489 if(!p.size()) 00490 return -1; 00491 else 00492 { 00493 int d = 0; 00494 for (typename R::const_iterator it = p.begin(); it != p.end(); ++it) 00495 d = std::max(d,degree(*it)); 00496 return d; 00497 } 00498 } 00499 00501 template <class R> int 00502 degree (const R & p, int i) { 00503 if(!p.size()) 00504 return -1; 00505 else 00506 { 00507 int d=0; 00508 for (typename R::const_iterator it = p.begin(); it != p.end(); ++it) 00509 { 00510 if(i<=it->nvars()) d = std::max(d,(int)(*it)[i]); 00511 } 00512 return d; 00513 } 00514 } 00515 //---------------------------------------------------------------------- 00516 template<class R> typename R::coeff_t& 00517 leadingcoeff(R & a) {return a.begin()->coeff();} 00518 //---------------------------------------------------------------------- 00519 template<class R> typename R::coeff_t 00520 leadingcoeff(const R & a) {return a.begin()->coeff();} 00521 //---------------------------------------------------------------------- 00526 template<class POL> typename POL::coeff_t 00527 coeffof(const POL & p, 00528 const typename POL::monom_t & mono) 00529 { 00530 typedef typename POL::coeff_t coeff_t; 00531 typename POL::const_iterator m; 00532 for(m = p.begin(); m!= p.end() && !IsComparable((*m),mono); m++) {} 00533 if(m != p.end()) 00534 { 00535 return m->coeff(); 00536 } 00537 else 00538 { 00539 return coeff_t(0); 00540 } 00541 } 00542 00543 template<class POL> typename POL::const_iterator 00544 last_term(const POL& p) { 00545 assert(p.size()>0); 00546 typename POL::const_iterator it=p.end(); 00547 it--; 00548 return it; 00549 } 00550 00551 00552 //---------------------------------------------------------------------- 00554 template<class R> void 00555 div_rem(R & q, R & a, const R & b0) { 00556 // std::cout <<"---- Begin div-rem sparse -----"<<std::endl; 00557 typedef typename R::monom_t monom_t; 00558 typedef typename monom_t::coeff_t coeff_t; 00559 q= R((coeff_t)0); 00560 00561 if(a==0) return; 00562 00563 R b(b0); 00564 //coeff_t cb =b0.begin()->coeff(); 00565 // b/=cb; 00566 monom_t mb = (*b.begin()), m; 00567 R t; 00568 while( a != (coeff_t)0 && divide(*a.begin(), mb, m) ) 00569 { 00570 mul(t,b,m); 00571 sub(a,t); 00572 if ( m != 0 ) add(q,m); 00573 // print(std::cout,a); std::cout<<std::endl; 00574 } 00575 // std::cout <<"---- End div-rem sparse -----"<<std::endl; 00576 } 00577 00578 //---------------------------------------------------------------------- 00580 TMPL void 00581 diff(Polynomial & r, const Polynomial & p, int i) 00582 { 00583 typedef typename Polynomial::Monomial Monomial; 00584 typedef typename Polynomial::Scalar Scalar; 00585 00586 assert(&r != &p); 00587 r= Polynomial((Scalar)0); 00588 for (typename Polynomial::const_iterator it = p.begin(); it != p.end(); ++it) { 00589 if((*it)[i]>0){ 00590 Monomial m(*it); 00591 m*=(typename Polynomial::coeff_t)(*it)[i]; 00592 m.set_expt(i,(*it)[i]-1); 00593 add(r,m); 00594 } 00595 } 00596 } 00597 00598 //---------------------------------------------------------------------- 00600 TMPL void 00601 shift(Polynomial & r, const Polynomial & p, const typename Polynomial::monom_t& m) 00602 { 00603 assert(&r != &p); 00604 typedef typename Polynomial::monom_t Monomial; 00605 r= Polynomial(0); 00606 for (typename Polynomial::const_iterator it = p.begin(); it != p.end(); ++it) { 00607 add(r,*it*m); 00608 } 00609 } 00610 00611 //---------------------------------------------------------------------- 00613 TMPL void 00614 copy(Polynomial& r, const Polynomial& a) 00615 { 00616 //to be modified when bug fixed in gcc 00617 // using dense::reserve; 00618 reserve(r,a.size()); 00619 std::copy(a.begin(),a.end(),r.begin()); 00620 } 00621 //---------------------------------------------------------------------- 00623 TMPL typename Polynomial::coeff_t 00624 eval(const Polynomial& p, 00625 const typename Polynomial::coeff_t &x, 00626 const typename Polynomial::coeff_t &y) { 00627 typename Polynomial::coeff_t r(0); 00628 for(typename Polynomial::const_iterator it=p.begin(); it!=p.end(); ++it) 00629 { 00630 typename Polynomial::coeff_t c(it->coeff()); 00631 //for(unsigned int i=0;i<2;++i) 00632 for(int k=0;k<(int)(*it)[0];k++) 00633 c*=x; 00634 for(int k=0;k<(int)(*it)[1];k++) 00635 c*=y; 00636 r+=c; 00637 } 00638 return r; 00639 } 00640 00641 //-------------------------------------------------------------------- 00642 template<class C,class O, class MONOM, class REP, class R, class VCT> void 00643 eval_at(R& r, 00644 const Polynomial& p, 00645 const VCT &x) { 00646 r=R(0); 00647 for(typename Polynomial::const_iterator it=p.begin(); it!=p.end(); ++it) 00648 { 00649 R c(it->coeff()); 00650 for(unsigned int j=0;j<x.size()&& j<it->nvars();++j) 00651 for(int k=0;k<(int)(*it)[j];k++) 00652 c*=x[j]; 00653 r+=c; 00654 } 00655 return r; 00656 } 00657 00658 //-------------------------------------------------------------------- 00660 template<class R, class C, class O, class MONOM, class REP, class X> inline void 00661 eval(R& r, const Polynomial& p, const X& x) { 00662 r=(R)0; 00663 for(typename Polynomial::const_iterator it=p.begin(); it!=p.end(); ++it) 00664 { 00665 R c(it->coeff()); 00666 for(int k=0;k<(int)(*it)[0];k++) 00667 c*=x; 00668 r+=(R)c; 00669 } 00670 } 00671 00672 //---------------------------------------------------------------------- 00673 TMPL inline void 00674 homogenize(Polynomial& r, const Polynomial& p, const Polynomial& v) { 00675 Polynomial t; 00676 int d = sparse::degree(p); 00677 for(typename Polynomial::const_iterator it=p.begin();it != p.end();it++) { 00678 t=*it; 00679 for (int i=0;i<d-degree(*it);i++) mul(t,v); 00680 add(r,t); 00681 } 00682 } 00683 00684 //-------------------------------------------------------------------- 00685 TMPL inline void 00686 homogenize(Polynomial& r, const Polynomial& p, int n, const Polynomial& v) { 00687 Polynomial t; 00688 int d = degree(p,n); 00689 for(typename Polynomial::const_iterator it=p.begin();it != p.end();it++) { 00690 t=*it; 00691 for (int i=0;i<d-(*it)[n];i++) mul(t,v); 00692 add(r,t); 00693 } 00694 } 00695 //---------------------------------------------------------------------- 00696 00699 template <class MP> MP 00700 convert(const MP & P,typename MP::coeff_t x,typename MP::coeff_t y,int ind) { 00701 typedef typename MP::const_iterator const_iterator; 00702 typedef typename MP::coeff_t coeff_t; 00703 typedef typename MP::monom_t monom_t; 00704 MP res; 00705 int ind1=0; 00706 int ind2=0; 00707 for(int i=0;i<=2;i++) 00708 { 00709 if(ind!=i) {ind1=i;break;} 00710 } 00711 for(int i=0;i<=2;i++) 00712 { 00713 if(ind!=i && ind1!=i) {ind2=i;break;} 00714 } 00715 for(const_iterator i = P.begin(); i != P.end(); ++i) 00716 { 00717 coeff_t k=i->coeff(); 00718 int puissx=(*i)[ind1]; 00719 int puissy=(*i)[ind2]; 00720 int d=(*i)[ind]; 00721 coeff_t coeff1=pow(x,puissx); 00722 coeff_t coeff2=pow(y,puissy); 00723 k*=coeff1;k*=coeff2; 00724 MP P1=monom_t(k,ind,d); 00725 res=res+P1; 00726 } 00727 return res; 00728 } 00729 00730 //-------------------------------------------------------------------- 00731 template <class OS, class C, class O, class MONOM, class REP, class VARIABLES> OS& 00732 print(OS & os, const Polynomial & P, const VARIABLES & V) { 00733 if ( P.begin() == P.end() ) 00734 { 00735 os << '0'; 00736 return os; 00737 } 00738 for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) { 00739 std::ostringstream sm; 00740 print(sm,*i,V); 00741 if(sm.str()[0] != '-' && sm.str()[0] != '+' && i != P.begin()) 00742 os <<'+'; 00743 os<<sm.str(); 00744 } 00745 return os; 00746 } 00747 00748 00749 template <class OS, class C, class O, class MONOM, class REP, class VARIABLES> OS& 00750 print_as_double(OS & os, const Polynomial & P, const VARIABLES & V) { 00751 if ( P.begin() == P.end() ) 00752 { 00753 os << '0'; 00754 return os; 00755 } 00756 for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) { 00757 std::ostringstream sm; 00758 print_as_double(sm,*i,V); 00759 if(sm.str()[0] != '-' && sm.str()[0] != '+' && i != P.begin()) 00760 os <<'+'; 00761 os<<sm.str(); 00762 } 00763 return os; 00764 } 00765 //-------------------------------------------------------------------- 00766 template <class OS, class C, class O, class MONOM, class REP> OS& 00767 print(OS & os, const Polynomial & P) 00768 { 00769 return print(os,P,variables::default_); 00770 } 00771 00772 00773 //---------------------------------------------------------------------- 00774 template <class OS, class C, class O, class MONOM, class REP> OS& 00775 print_verbatim(OS & os, const Polynomial & P) 00776 { 00777 if ( P.begin() == P.end() ) 00778 { 00779 os << '0'; 00780 return os; 00781 } 00782 for( typename Polynomial::const_iterator i=P.begin(); i != P.end();++i) 00783 { 00784 os<<" "<<i->coeff()<<" ["; 00785 for(int l=0;l<i->size();l++) os<<(*i)[l]<<" "; 00786 os<<"]"; 00787 } 00788 return os; 00789 } 00790 //---------------------------------------------------------------------- 00794 template <class POL, class C> POL 00795 shift(typename POL::const_iterator monom, const C& a, int i) { 00796 00797 POL polynom; 00798 // Definition du type monome. 00799 typedef typename POL::monom_t monomial; 00800 // monomiale temporaire. 00801 monomial tmpmonomial; 00802 00803 int i0 = i; 00804 int i1 = (i + 1) % 3; 00805 int i2 = (i + 2) % 3; 00806 00807 // Si la variable est presente dans le monome. 00808 if ( (a!=0) && ( monom->operator[](i0) !=0 ) ) 00809 { 00810 polynom = binomial< POL >(C(1.), i0, monom->operator[](i0), a); 00811 int expt[3]; 00812 expt[i0] = 0; 00813 expt[i1] = monom->operator[](i1); 00814 expt[i2] = monom->operator[](i2); 00815 00816 if ( ( expt[i0] == 0 ) && ( expt[i1] == 0 ) && ( expt[i2] == 0 ) ) 00817 tmpmonomial = monomial( monom->coeff(), 0, 0 ); 00818 else tmpmonomial = monomial( monom->coeff(), 3, expt ); 00819 00820 polynom *= tmpmonomial; 00821 } 00822 // Si a = 0 alors le monome reste inchange. 00823 else polynom = ( *monom ); 00824 00825 return polynom; 00826 00827 } 00828 //---------------------------------------------------------------------- 00831 template < class POL, class C > POL 00832 scale( const POL &p, C a, int v) { 00833 00834 typedef typename POL::monom_t monomial; 00835 00836 POL np(p); 00837 00838 for ( typename POL::const_iterator i = np.begin(); i != np.end(); ++i ) { 00839 i->coeff()*= pow( a, int( i->operator[]( v ) ) ); 00840 } 00841 return np; 00842 00843 } 00844 //---------------------------------------------------------------------- 00845 template<class T, class MP, class V> T 00846 eval(const MP& p, const V& v) { 00847 T r(0); 00848 for(typename MP::const_iterator it=p.begin(); it!=p.end(); ++it) 00849 { 00850 T c; let::assign(c,it->coeff()); 00851 for(unsigned i=0;i< it->size()&&i<v.size();++i) 00852 for(int k=0;k<(*it)[i];k++) 00853 { 00854 c*=v[i]; 00855 } 00856 r+=c; 00857 } 00858 return r; 00859 } 00860 00861 00862 //---------------------------------------------------------------------- 00863 template<class R, class MP, class V> void 00864 eval(R& r, const MP& p, const V& v, unsigned n) { 00865 r=R(0); 00866 for(typename MP::const_iterator it=p.begin(); it!=p.end(); ++it) 00867 { 00868 R c; 00869 let::assign(c,it->coeff()); 00870 for(unsigned i=0;i< it->size()&&i<n;++i) 00871 for(int k=0;k<(*it)[i];k++) { 00872 c*=v[i]; 00873 } 00874 r+=c; 00875 } 00876 } 00877 00878 //---------------------------------------------------------------------- 00880 template<class MP,class X> MP 00881 subs( unsigned var, const X& val, const MP & P) 00882 { 00883 MP Result;//("0"); 00884 typedef typename MP::coeff_t coeff_t; 00885 typedef typename MP::Monomial monom_t; 00886 00887 for( typename MP::const_iterator it = P.begin(); it != P.end(); ++it ) 00888 { 00889 if ( it->size() > var ) 00890 { 00891 monom_t m (*it); 00892 X tmp = pow(val,m[var]); 00893 m.rep()[var] = 0; 00894 Result += tmp*m; 00895 } 00896 else 00897 Result += *it; 00898 00899 } 00900 return Result; 00901 } 00902 //---------------------------------------------------------------------- 00904 template<class MP> MP 00905 subs(const MP & P, int var, typename MP::coeff_t val) 00906 { 00907 MP Result;//("0"); 00908 typedef typename MP::coeff_t coeff_t; 00909 typedef typename MP::Monomial monom_t; 00910 // std::cout<<"Begin subs!!"<<endl; 00911 coeff_t C=0; 00912 for ( typename MP::const_iterator it = P.begin(); 00913 it != P.end(); ++it ) 00914 { 00915 monom_t m(it->coeff()); 00916 for(int ind=0; ind<(lvar(P)+1); ++ind) 00917 { 00918 if (ind == var) 00919 { 00920 for(int k=0;k<(int)(*it)[ind];k++) 00921 m*=val; 00922 } 00923 else 00924 { 00925 if ((*it)[ind] != 0) 00926 { 00927 monom_t mon(ind,(*it)[ind]); 00928 m*= mon; 00929 } 00930 } 00931 } 00932 if (m.nvars() == -1) 00933 { 00934 C += m.coeff(); 00935 } 00936 else if (m != 0) 00937 Result+= m; 00938 } 00939 if (C != 0) 00940 Result += monom_t(C); 00941 //std::cout<<"End subs!!"<<endl; 00942 return Result; 00943 } 00944 00945 //---------------------------------------------------------------------- 00947 template<class MP> MP 00948 subs(const MP & P, char* x, typename MP::coeff_t val) { 00949 int xi = MP::var(x); 00950 if (xi<0) 00951 return P; 00952 else 00953 return subs(P,xi,val); 00954 } 00955 00956 //---------------------------------------------------------------------- 00957 template<class T> void print(const T & x) {std::cout<<x<<std::endl;} 00958 //---------------------------------------------------------------------- 00960 template<class MP> MP 00961 swap(const MP & P, int var_i, int var_j) 00962 { 00963 MP Result;//("0"); 00964 typedef typename MP::monom_t monom_t; 00965 for ( typename MP::const_iterator it = P.begin(); 00966 it != P.end(); ++it ) 00967 { 00968 monom_t m(it->coeff()); 00969 for(int ind=0; ind<(lvar(P)+1); ++ind) 00970 { 00971 if((*it)[ind] !=0 ) { 00972 if (ind == var_i) { 00973 m*=monom_t(var_j,(*it)[ind]); 00974 } else { 00975 if (ind == var_j) 00976 m*=monom_t(var_i,(*it)[ind]); 00977 else 00978 m*= monom_t(ind,(*it)[ind]); 00979 } 00980 } 00981 } 00982 Result+=m; 00983 } 00984 return Result; 00985 } 00986 00987 //---------------------------------------------------------------------- 00989 template<class MP> MP 00990 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 C, class O, class MONOM, class REP> C 01000 content(const Polynomial & P) 01001 { 01002 C d=0; 01003 for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) { 01004 d= gcd(d,i->coeff()); 01005 } 01006 return d; 01007 } 01008 01009 } //namespace sparse 01010 01011 //==================================================================== 01012 namespace let { 01013 01014 TMPL void 01015 assign(sparse::monomial_seq<C,O,MONOM,REP>& p, const C&c) { 01016 p = sparse::monomial_seq<C,O,MONOM,REP>(); p.push_back(c); 01017 } 01018 01019 template<class U, class V, class O, class UMONOM, class UREP, class VMONOM, class VREP> void 01020 assign(sparse::monomial_seq<U,O,UMONOM,UREP>& p, 01021 const sparse::monomial_seq<V,O,VMONOM,VREP>& q) { 01022 01023 typedef typename sparse::monomial_seq<U,O,UMONOM,UREP>::Monomial MonomialU; 01024 typedef typename sparse::monomial_seq<V,O,VMONOM,VREP>::Monomial MonomialV; 01025 01026 for ( typename sparse::monomial_seq<V,O,VMONOM,VREP>::const_iterator it = q.begin(); 01027 it != q.end(); ++it ) { 01028 U c; assign(c,it->coeff()); 01029 MonomialU m(c,it->rep()); 01030 p.push_back(m); 01031 } 01032 } 01033 01034 } 01035 //====================================================================== 01036 # define SparsePolynomial sparse:: monomial_seq<C,O,MONOM,REP> 01037 01038 template<class A, class B> struct use; 01039 struct operators_of; 01040 01041 TMPL struct use<operators_of,SparsePolynomial> { 01042 01043 static inline void 01044 add (SparsePolynomial &r, const SparsePolynomial &a ) { 01045 sparse::add (r, a); 01046 } 01047 static inline void 01048 add (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) { 01049 sparse::add (r, a, b); 01050 } 01051 static inline void 01052 add (SparsePolynomial &r, const SparsePolynomial &a, const C & b) { 01053 sparse::add (r, a, b); 01054 } 01055 static inline void 01056 add (SparsePolynomial &r, const C & a, const SparsePolynomial &b) { 01057 sparse::add (r, b, a); 01058 } 01059 static inline void 01060 sub (SparsePolynomial &r, const SparsePolynomial &a ) { 01061 sparse::sub (r, a ); 01062 } 01063 static inline void 01064 sub (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) { 01065 sparse::sub (r, a, b); 01066 } 01067 static inline void 01068 sub (SparsePolynomial &r, const C & a, const SparsePolynomial &b) { 01069 sparse::sub (r, a, b); 01070 } 01071 static inline void 01072 sub (SparsePolynomial &r, const SparsePolynomial &a, const C & b) { 01073 sparse::sub (r, a, b); 01074 } 01075 static inline void 01076 mul (SparsePolynomial &r, const SparsePolynomial &a ) { 01077 sparse::mul (r, a ); 01078 } 01079 static inline void 01080 mul (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) { 01081 sparse::mul (r, a, b); 01082 } 01083 static inline void 01084 mul (SparsePolynomial &r, const SparsePolynomial &a, const C & b) { 01085 sparse::mul (r, a, b); } 01086 static inline void 01087 mul (SparsePolynomial &r, const C & a, const SparsePolynomial &b) { 01088 sparse::mul (r, b, a); 01089 } 01090 static inline void 01091 div (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) { 01092 sparse::div (r, a, b); 01093 } 01094 static inline void 01095 div (SparsePolynomial &r, const SparsePolynomial &a, const C & b) { 01096 sparse::div (r, a, b); 01097 } 01098 static inline void 01099 div (SparsePolynomial &a, const SparsePolynomial& b) { 01100 sparse::div (a, b); 01101 } 01102 static inline void 01103 div (SparsePolynomial &a, const C & c) { 01104 sparse::div (a, c); 01105 } 01106 static inline void 01107 rem (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) { 01108 sparse::rem (r, b, a); 01109 } 01110 }; 01111 #undef SparsePolynomial 01112 //==================================================================== 01113 }// namespace mmx 01114 #undef TMPL 01115 #undef TMPLX 01116 #undef CLASS 01117 #undef Polynomial 01118 #endif // realroot_sparse_monomial_hpp 01119