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
00064 return m_order->less(m1.begin(),m1.size(),
00065 m2.begin(),m2.size());
00066 }
00067 };
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 namespace sparse {
00078
00079 TMPL MonomialOrdering* Polynomial::m_order = (MonomialOrdering*)new O;
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
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++;
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
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);
00378 }
00379
00380
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;
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
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
00565
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
00574 }
00575
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
00617
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
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 j=0; j< (unsigned)x.size() && j< (unsigned)it->nvars();++j)
00651 for(int k=0;k<(int)(*it)[j];k++)
00652 c*=x[j];
00653 r+=c;
00654 }
00655
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().c_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().c_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
00799 typedef typename POL::monom_t monomial;
00800
00801 monomial tmpmonomial;
00802
00803 int i0 = i;
00804 int i1 = (i + 1) % 3;
00805 int i2 = (i + 2) % 3;
00806
00807
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
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;
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
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(coeff_t(1),(*it)[ind],ind);
00928 m*= mon;
00929 }
00930 }
00931 }
00932 if (m.nvars() == -1)
00933 {
00934 C += m.coeff();
00935 }
00936 else if (m != 0)
00937 {
00938 Result+= m;
00939 }
00940 }
00941 if (C != 0)
00942 Result += monom_t(C);
00943
00944 return Result;
00945 }
00946
00947
00949 template<class MP> MP
00950 subs(const MP & P, char* x, typename MP::coeff_t val) {
00951 int xi = MP::var(x);
00952 if (xi<0)
00953 return P;
00954 else
00955 return subs(P,xi,val);
00956 }
00957
00958
00959 template<class T> void print(const T & x) {std::cout<<x<<std::endl;}
00960
00962 template<class MP> MP
00963 swap(const MP & P, int var_i, int var_j)
00964 {
00965 MP Result;
00966 typedef typename MP::monom_t monom_t;
00967 for ( typename MP::const_iterator it = P.begin();
00968 it != P.end(); ++it )
00969 {
00970 monom_t m(it->coeff());
00971 for(int ind=0; ind<(lvar(P)+1); ++ind)
00972 {
00973 if((*it)[ind] !=0 ) {
00974 if (ind == var_i) {
00975 m*=monom_t(var_j,(*it)[ind]);
00976 } else {
00977 if (ind == var_j)
00978 m*=monom_t(var_i,(*it)[ind]);
00979 else
00980 m*= monom_t(ind,(*it)[ind]);
00981 }
00982 }
00983 }
00984 Result+=m;
00985 }
00986 return Result;
00987 }
00988
00989
00991 template<class MP> MP
00992 swap(const MP & P, char* x_i, char* x_j)
00993 {
00994 typedef typename MP::monom_t monom_t;
00995 int xi = monom_t::index_of_var(x_i);
00996 int xj = monom_t::index_of_var(x_j);
00997 return swap(P,xi,xj);
00998 }
00999
01000
01001 template <class C, class O, class MONOM, class REP> C
01002 content(const Polynomial & P)
01003 {
01004 C d=0;
01005 for(typename Polynomial::const_iterator i = P.begin(); i != P.end();i++ ) {
01006 d= gcd(d,i->coeff());
01007 }
01008 return d;
01009 }
01010
01011 }
01012
01013
01014 namespace let {
01015
01016 TMPL void
01017 assign(sparse::monomial_seq<C,O,MONOM,REP>& p, const C&c) {
01018 p = sparse::monomial_seq<C,O,MONOM,REP>(); p.push_back(c);
01019 }
01020
01021 template<class U, class V, class O, class UMONOM, class UREP, class VMONOM, class VREP> void
01022 assign(sparse::monomial_seq<U,O,UMONOM,UREP>& p,
01023 const sparse::monomial_seq<V,O,VMONOM,VREP>& q) {
01024
01025 typedef typename sparse::monomial_seq<U,O,UMONOM,UREP>::Monomial MonomialU;
01026 typedef typename sparse::monomial_seq<V,O,VMONOM,VREP>::Monomial MonomialV;
01027
01028 for ( typename sparse::monomial_seq<V,O,VMONOM,VREP>::const_iterator it = q.begin();
01029 it != q.end(); ++it ) {
01030 U c; assign(c,it->coeff());
01031 MonomialU m(c,it->rep());
01032 p.push_back(m);
01033 }
01034 }
01035
01036 }
01037
01038 # define SparsePolynomial sparse:: monomial_seq<C,O,MONOM,REP>
01039
01040 template<class A, class B> struct use;
01041 struct operators_of;
01042
01043 TMPL struct use<operators_of,SparsePolynomial> {
01044
01045 static inline void
01046 add (SparsePolynomial &r, const SparsePolynomial &a ) {
01047 sparse::add (r, a);
01048 }
01049 static inline void
01050 add (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01051 sparse::add (r, a, b);
01052 }
01053 static inline void
01054 add (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01055 sparse::add (r, a, b);
01056 }
01057 static inline void
01058 add (SparsePolynomial &r, const C & a, const SparsePolynomial &b) {
01059 sparse::add (r, b, a);
01060 }
01061 static inline void
01062 sub (SparsePolynomial &r, const SparsePolynomial &a ) {
01063 sparse::sub (r, a );
01064 }
01065 static inline void
01066 sub (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01067 sparse::sub (r, a, b);
01068 }
01069 static inline void
01070 sub (SparsePolynomial &r, const C & a, const SparsePolynomial &b) {
01071 sparse::sub (r, a, b);
01072 }
01073 static inline void
01074 sub (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01075 sparse::sub (r, a, b);
01076 }
01077 static inline void
01078 mul (SparsePolynomial &r, const SparsePolynomial &a ) {
01079 sparse::mul (r, a );
01080 }
01081 static inline void
01082 mul (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01083 sparse::mul (r, a, b);
01084 }
01085 static inline void
01086 mul (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01087 sparse::mul (r, a, b); }
01088 static inline void
01089 mul (SparsePolynomial &r, const C & a, const SparsePolynomial &b) {
01090 sparse::mul (r, b, a);
01091 }
01092 static inline void
01093 div (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01094 sparse::div (r, a, b);
01095 }
01096 static inline void
01097 div (SparsePolynomial &r, const SparsePolynomial &a, const C & b) {
01098 sparse::div (r, a, b);
01099 }
01100 static inline void
01101 div (SparsePolynomial &a, const SparsePolynomial& b) {
01102 sparse::div (a, b);
01103 }
01104 static inline void
01105 div (SparsePolynomial &a, const C & c) {
01106 sparse::div (a, c);
01107 }
01108 static inline void
01109 rem (SparsePolynomial &r, const SparsePolynomial &a, const SparsePolynomial &b) {
01110 sparse::rem (r, b, a);
01111 }
01112 };
01113 #undef SparsePolynomial
01114
01115 }
01116 #undef TMPL
01117 #undef TMPLX
01118 #undef CLASS
01119 #undef Polynomial
01120 #endif // realroot_sparse_monomial_hpp
01121