00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef realroot_univariate_hpp
00010 #define realroot_univariate_hpp
00011
00012 #include <iostream>
00013 #include <math.h>
00014 #include <realroot/assign.hpp>
00015 #include <realroot/array.hpp>
00016 # define TMPL template<class C>
00017 # define TMPLX template<class C, class X>
00018 # define Polynomial monomials<C>
00019
00020
00021 namespace mmx {
00022
00023 #ifndef MMX_WITH_PLUS_SIGN
00024 #define MMX_WITH_PLUS_SIGN
00025 template<class X> bool with_plus_sign(const X& x) {return x>0;}
00026 #endif //MMX_WITH_PLUS_SIGN
00027
00028 struct AsSize;
00029
00030
00032
00047 namespace univariate {
00048
00053 template <class C>
00054 struct monomials {
00055
00056 typedef C value_type;
00057 typedef unsigned int size_type;
00058 typedef C* iterator;
00059 typedef iterator const_iterator;
00060 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00061 typedef std::reverse_iterator<iterator> reverse_iterator;
00062 typedef C coeff_t;
00063
00064 C * tab_;
00065 size_type size_;
00066 int degree_;
00067
00068 monomials(): tab_(0), size_(0), degree_(-1) {}
00069 monomials(const C& c);
00070 monomials(const C& c, size_type d, int v=0);
00071 monomials(const size_type& s, C *t);
00072 monomials(const size_type& s, const char* t);
00073 monomials(C* b, C *e);
00074
00075 monomials(const monomials<C> & p);
00076
00077 ~monomials () { delete[] tab_;}
00078
00079 iterator begin() {return iterator(tab_); }
00080 const_iterator begin() const {return const_iterator(tab_); }
00081 iterator end() {return iterator(this->tab_+degree_+1); }
00082 const_iterator end() const {return const_iterator(this->tab_+degree_+1); }
00083
00084 reverse_iterator rend() {return reverse_iterator(tab_); }
00085 const_reverse_iterator rend() const {return reverse_iterator(tab_); }
00086
00087 reverse_iterator rbegin() {
00088 return reverse_iterator(this->tab_+degree_+1);
00089 }
00090 const_reverse_iterator rbegin() const {
00091 return const_reverse_iterator(this->tab_+degree_+1);
00092 }
00093
00094 unsigned size() const { return size_;}
00095 unsigned degree() const { return degree_;}
00096
00097 monomials& operator= (const monomials<C> & v);
00098
00099 inline C & operator[] (size_type i) {return tab_[i];}
00100 inline const C & operator[] (size_type i) const {return tab_[i];}
00101
00102
00103 bool operator==( const C& c ) const;
00104
00105 void resize(const size_type& n);
00106
00107 };
00108
00109 TMPL
00110 Polynomial::monomials(const Polynomial & v) : size_(v.size_), degree_(v.degree_) {
00111 tab_ = new C[v.size_];
00112 for(size_type i=0;i<v.size_;i++) {tab_[i] = v[i];}
00113 }
00114
00115 TMPL
00116 Polynomial::monomials(const C& c): size_(1), degree_(0) {
00117 tab_ = new C[1];
00118 tab_[0]=c;
00119 }
00120 TMPL
00121 Polynomial::monomials(const C& c, size_type l, int v): size_(l+1), degree_(l) {
00122 tab_ = new C[l+1];
00123 for (size_type i = 0; i < l; i++) tab_[i]=C(0);
00124 tab_[l]=c;
00125 }
00126
00127 TMPL
00128 Polynomial::monomials(const size_type& i, C* t): size_(i), degree_(i-1) {
00129 tab_ = new C[i];
00130 for(size_type l=0;l<i;l++) tab_[l] = t[l];
00131 check_degree(*this);
00132 }
00133
00134 TMPL
00135 Polynomial::monomials(C* b, C* e) {
00136 size_=0; C* p;
00137 for(p=b;p!=e;p++,size_++) ;
00138 tab_ = new C[size_];
00139 degree_=0;
00140 for(p=b; p!=e; p++,degree_++) {tab_[degree_]=(*p);}
00141 check_degree(*this);
00142 }
00143
00144
00145 TMPL
00146 Polynomial::monomials(const size_type& l, const char * nm) {
00147 std::istringstream ins(nm);
00148 size_=l;
00149 tab_ = new C[size_];
00150 for(size_type i=0; i< size_; i++) ins >>tab_[i];
00151 degree_=l-1;
00152 check_degree(*this);
00153 }
00154
00155 TMPL void
00156 Polynomial::resize(const size_type & i) {
00157 if(size_!=i){
00158 if (size_ != 0) {
00159 C* tmp = tab_;
00160 tab_ = new C[i];
00161 for(size_type j=0;j<std::min(i,size_);j++) tab_[j]=tmp[j];
00162 for(size_type j=std::min(i,size_);j<i;j++) tab_[j]=value_type();
00163 size_=i;
00164 delete [] tmp;
00165 } else {
00166 size_=i; tab_= new C[i];
00167 for(size_type j=0;j<size_;j++) tab_[j]=value_type();
00168 }
00169 }
00170 degree_=i-1;
00171 }
00172
00173 TMPL Polynomial&
00174 Polynomial::operator=(const Polynomial & v) {
00175 if (size_ != v.size_) {
00176 if (size_ !=0) delete [] tab_;
00177 tab_ = new C[v.size_];
00178 size_ = v.size_;
00179 }
00180 degree_=v.degree_;
00181 for(size_type i=0;i<size_;i++) tab_[i] = v[i];
00182 return *this;
00183 }
00184
00185 TMPL bool
00186 Polynomial::operator== (const C& c) const {
00187 if(c==0)
00188 return (this->degree()<0);
00189 else
00190 return (this->degree()==0 && tab_[0]== c);
00191 }
00192
00193 template <class R>
00194 int degree(const R & p) {
00195
00196 int i = p.size()-1;
00197 while(i>-1 && p[i]==(typename R::value_type)0) i--;
00198 return i;
00199 }
00200
00201 TMPL inline int degree(const Polynomial& a) { return a.degree_;}
00202
00203
00204
00205
00206 TMPL inline int
00207 check_degree(Polynomial& a) {
00208 int l = a.degree_;
00209 while(l >=0 && (a.tab_[l]==0)) {l--;}
00210 a.degree_=l;
00211 return a.degree_;
00212 }
00213
00214
00215 TMPL void inline
00216 add(Polynomial &r, const Polynomial& a, const Polynomial & b) {
00217 array::add(r,a,b);
00218 check_degree(r);
00219 }
00220
00221
00222 TMPL void inline
00223 add(Polynomial &r, const Polynomial& a, const C& c) {
00224 if(degree(a)>-1) {
00225 r=a; r[0]+=c;
00226 }
00227 else
00228 r= Polynomial(c,0);
00229 check_degree(r);
00230 }
00231
00232
00233 TMPL void inline
00234 add(Polynomial &r, const C& c) {
00235 if(degree(r)>-1) {
00236 r[0]+=c;
00237 }
00238 else
00239 r= Polynomial(c,0);
00240 check_degree(r);
00241 }
00242
00243 TMPL void inline
00244 add(Polynomial &r, const Polynomial& a) {
00245 array::add(r,a);
00246 check_degree(r);
00247 }
00248
00249 TMPL void inline
00250 sub(Polynomial &r, const Polynomial& a, const Polynomial & b) {
00251 array::sub(r,a,b);
00252 check_degree(r);
00253 }
00254
00255 TMPL void inline
00256 sub(Polynomial &r, const Polynomial& a) {
00257 array::sub(r,a);
00258 check_degree(r);
00259 }
00260
00261 TMPL void inline
00262 sub(Polynomial &r, const Polynomial& a, const C& c) {
00263 if(degree(a)>-1) {
00264 r=a; r[0]-=c;
00265 }
00266 else
00267 r= Polynomial(-c,0);
00268 check_degree(r);
00269 }
00270
00271 TMPLX void inline
00272 sub(Polynomial &r, const Polynomial& a, const X& x) {
00273 sub(r,a,(C)x);
00274 }
00275
00276 TMPL void inline
00277 sub(Polynomial &r, const C& c) {
00278 if(degree(r)>-1) {
00279 r[0]-=c;
00280 }
00281 else
00282 r= Polynomial(-c,0);
00283 check_degree(r);
00284 }
00285
00286 TMPL void inline
00287 mul(Polynomial &r, const Polynomial& a, const Polynomial & b) {
00288 assert(&r!=&a);
00289
00290 r.resize(std::max(degree(a)+degree(b)+1,0));
00291 array::set_cst(r,(C)0);
00292 mul_index(r,a,b);
00293 check_degree(r);
00294 }
00295
00296
00298 TMPL void inline
00299 mul(Polynomial &r, const C & c) {
00300 array::mul_ext(r,c);
00301 }
00302
00303
00305 TMPL void inline
00306 mul(Polynomial &a, const Polynomial & b) {
00307 Polynomial r; mul(r,a,b); a=r;
00308 }
00309
00310 TMPL void inline
00311 mul(Polynomial &r, const Polynomial& p, const C & c) {
00312 r=p; mul(r,c); check_degree(r);
00313 }
00314
00315
00316
00317 TMPL void inline
00318 shift(Polynomial &r, const Polynomial& p, int d, int v=0) {
00319 if(d>=0) {
00320 r.resize(degree(p)+d+1);
00321 for(int i=0; i<d;i++)
00322 r[i]= (typename Polynomial::coeff_t)0;
00323 for(int i=0; i<=degree(p);i++)
00324 r[i+d]=p[i];
00325 }
00326 }
00327
00328
00329 TMPL void inline
00330 div(Polynomial &r, const Polynomial& a, const Polynomial & b) {
00331 assert(&r!=&a);
00332 Polynomial tmp(a);
00333 r = Polynomial(0);
00334 div_rem(r,tmp,b);
00335 check_degree(r);
00336 }
00337
00338
00339 TMPL void inline
00340 div(Polynomial &r, const Polynomial& b) {
00341 Polynomial tmp(r);
00342 r = Polynomial(0);
00343 div_rem(r,tmp,b);
00344 check_degree(r);
00345 }
00346
00347
00348 TMPL void inline
00349 div(Polynomial &r, const C & c) {
00350 array::div_ext(r,c);
00351 check_degree(r);
00352 }
00353
00354
00356 template< class R > inline typename R::value_type
00357 lcoeff(const R& p) {
00358 return p[degree(p)];
00359 }
00360
00362 template< class R > inline typename R::value_type
00363 tcoeff(const R& p) { return p[0]; }
00364
00365
00366 template <class OSTREAM, class C> OSTREAM&
00367 print_as_coeff(OSTREAM & os, const C & c, bool plus)
00368 {
00369 if(plus)
00370 os <<"+";
00371 os<<"("<<c<<")";
00372 return os;
00373 }
00374
00375 template <class OSTREAM, class C, class VAR> inline OSTREAM&
00376 print(OSTREAM& os, const Polynomial& p, const VAR& var)
00377 {
00378 typedef typename Polynomial::value_type coeff_t;
00379 bool plus=false, not_one;
00380 if ( degree(p)<0)
00381 os << coeff_t(0) ;
00382 else {
00383 for(int i= 0; i<=degree(p); i++)
00384 {
00385 if(p[i]!= (coeff_t)0)
00386 {
00387 not_one = (p[i] != (coeff_t)1);
00388 if(not_one || i==0)
00389 print_as_coeff(os,p[i],plus);
00390 plus=true;
00391
00392 if(i>0)
00393 {
00394
00395
00396 if(not_one)
00397 os<<"*";
00398 os<<"x";
00399 if(i !=1)
00400 {os<<'^'; os<<i;}
00401 }
00402
00403
00404 }
00405 }
00406 if(!plus) os << 0 ;
00407 }
00408 return os;
00409 }
00410
00411 template <class OSTREAM, class C> inline OSTREAM&
00412 print(OSTREAM& os, const Polynomial& p) {
00413 return print(os,p, "x");
00414 }
00415
00416
00417 template <class R, class C>
00418 inline void set_monomial(R & x, const C & c, unsigned n)
00419 {
00420
00421 x.resize(n+1);
00422 array::set_cst(x,(typename R::value_type)0);
00423 x[n]=c;
00424 checkdegree(x);
00425
00426 }
00427
00428 template <class R, class S>
00429 inline void add_cst(R & r, const S & c) { r[0]+=c; }
00430
00431 template <class R, class S>
00432 inline void sub_cst(R & r, const S & c) { r[0]-=c;}
00433
00434 template <class R>
00435 inline void mul_index(R & r, const R & a, const R & b)
00436 {
00437 typedef typename R::coeff_t Scalar;
00438 int da=degree(a), db=degree(b),i,j;
00439 for (i=0;i<=db;i++) {
00440 if (b[i] == 0) continue;
00441 for (j=0;j<=da;j++) r[i+j] += a[j]*b[i];
00442 }
00443 }
00444
00445 template <class R> inline
00446 void mul_index_it(R & r, const R & a, const R & b)
00447 {
00448 typename R::const_iterator ia, ib;
00449 typename R::iterator ir, it;
00450 ir=r.begin();
00451 for (ib=b.begin();ib !=b.end()&& ir != r.end();++ib) {
00452 typename R::value_type c = *ib;
00453 it=ir;
00454 if (c==0) {++ir;continue;}
00455 for (ia=a.begin();ia!=a.end();++ia,++it) {
00456 (*it)+=(*ia)*c;
00457 }
00458 ++ir;
00459 }
00460 }
00461
00462 template <class R> inline
00463 void mul(R & a, const R & b)
00464 {
00465 if(degree(a)>=0 && degree(b)>=0)
00466 {
00467 R ta(a);
00468 a.resize(degree(a)+degree(b)+1);
00469 array::set_cst(a,0);
00470 mul_index(a,ta,b);
00471 }
00472 else
00473 array::set_cst(a,0);
00474 }
00475
00476 template <class R> inline
00477 void mul_index(R & a, const R & b)
00478 {
00479 R ta(a);
00480 a.resize(degree(a)+degree(b)+1);
00481 array::set_cst(a,0);
00482 mul_index(a,ta,b);
00483 }
00484
00485 template <class C, class R>
00486 inline C eval_horner(const R & p, const C & c)
00487 {
00488 using namespace let;
00489 C r,cf;
00490 if(degree(p)>0) {
00491 typedef typename R::const_reverse_iterator const_reverse_iterator;
00492 const_reverse_iterator it=p.rbegin();
00493 assign(r,*it); it++;
00494
00495 for(; it !=p.rend(); ++it) {r=r*c; assign(cf,*it); r=r+cf;}
00496 return r;
00497 } else if(degree(p)>-1)
00498 {
00499 assign(r,p[0]); return r;
00500 }
00501 else
00502 return C(0);
00503 }
00504
00505 template <class C, class R>
00506 inline C eval_horner_idx(const R & p, const C & c)
00507 {
00508 if(degree(p)>0) {
00509 int d=degree(p);
00510 C r=p[d];
00511 for(int i=d-1; i>-1; --i) {r*=c; r+= p[i];}
00512 return r;
00513 } else if(degree(p)>-1)
00514 return p[0];
00515 else
00516 return C(0);
00517 }
00518
00519 template <class C, class R>
00520 inline C eval(const R & p, const C & c)
00521 {
00522 return eval_horner(p,c);
00523 }
00524
00525 template <class C, class R>
00526 inline C eval_homogeneous(const R & p, const C & a, const C& b)
00527 {
00528 using namespace let;
00529 C r,y=1,cf;
00530 if(degree(p)>0) {
00531 typedef typename R::const_reverse_iterator const_reverse_iterator;
00532 const_reverse_iterator it=p.rbegin();
00533 assign(r,*it); it++;
00534
00535 for(; it !=p.rend(); ++it) {r*=a; y *=b; assign(cf,*it); r=r+cf*y;}
00536 return r;
00537 } else if(degree(p)==0)
00538 {
00539 assign(r,p[0]); return r;
00540 }
00541 else
00542 return C(0);
00543 }
00544
00545
00546 template<typename POL, typename X> inline
00547 int sign_at(const POL & p, const X& x)
00548 {
00549 X v= eval_horner(p,x);
00550 return sign(v);
00551 }
00552
00558 template<class R>
00559 void div_rem(R & q, R & a, const R & b)
00560 {
00561 typedef typename R::iterator iterator;
00562 int da = degree(a), db=degree(b);
00563 typename R::value_type lb=b[db];
00564 R t;
00565 q=(R)0;
00566 while (da>=db) {
00567 while(a[da]==0 && da>=db) da--;
00568 if(da>=db) {
00569 R m( a[da]/lb, da-db );
00570 mul(t,b,m);
00571 t[da]=a[da];
00572 sub(a,t);
00573 add(q,m);
00574 }
00575 }
00576 }
00577
00578
00579 template<class R> inline void checkdegree(R & p) {
00580 int d = p.size()-1;
00581 if ( d < 0 ) return;
00582 while ( p[d] == 0 ) d--;
00583 p.resize(d+1);
00584 }
00585
00586 template <class R> inline R diff(const R & p);
00587
00588 template<class R> void reciprocal(R & w,const R & p);
00589
00590 template<class R> void reverse(R & p, typename R::size_type n)
00591 {
00592 int l=n-1;
00593 for(typename R::size_type i=0;i<n/2;i++)
00594 std::swap(p[i],p[l-i]);
00595 }
00596
00597 template<class R>
00598 typename R::value_type derive(const R p,typename R::value_type x);
00599
00600 template<class R> void reduce(R & p, const typename R::size_type & e);
00601
00602 template<class R, class C>
00603 void scale(R & t,const R & p,const C & l);
00604
00607 template<class R> inline
00608 void diff(R & r, const R & p)
00609 {
00610 int n,i;
00611 r.resize(n=degree(p));
00612 for( i = 1; i < n+1; ++i) r[i-1] =p[i]*i;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00629 template <class R> inline
00630 R diff(const R & p)
00631 {
00632 R r(p);
00633 diff(r,p);
00634 return r;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00659 template <class R>
00660 void reciprocal(R & w, const R & p)
00661 {
00662 typedef typename R::size_type size_type;
00663 typedef typename R::value_type C;
00664
00665 const size_type deg = univariate::degree(p)+1;
00666 R w0(deg),v(deg),xp(p);
00667 size_type K = (size_type) (std::log(p.degree()+1)/std::log(2)),j=1;
00668 C p0 = xp[deg-1];
00669
00670 xp /= p0;
00671 w0 =xp/xp[0];
00672 v = w0;
00673 v *= C(-1.0);
00674 v[0]+=C(2);
00675 w=v/xp[0];
00676 w0=w;
00677 while (j <= K) {
00678 univariate::reduce(w0,pow(2,j+1));
00679 w=xp*w0;
00680 v =w;
00681 v*=C(-1.0);
00682 v[0]+=C(2);
00683 univariate::reduce(v,pow(2,j+1));
00684 w=w0*v;
00685 w0=w;
00686 j++;
00687 }
00688 univariate::reduce(w,deg);
00689 w/=p0;
00690 }
00691
00695 template <class T>
00696 inline void reduce(T & p, const typename T::size_type & e)
00697 {
00698
00699 T temp(e);
00700 for (typename T::size_type i = 0; i < e; i++) temp[i]=p[i];
00701 p.resize(e);
00702
00703 for (typename T::size_type i = 0; i < e; i++) p[i]=temp[i];
00704 }
00705
00715 template <class T>
00716 inline void reverse(T & p, int n)
00717 { for ( int i = 0; i < n/2; i++ ) std::swap(p[i],p[n-i]) ; }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00737 template<class O, class R, class I> inline
00738 void eval( O& p, O& dp, const R& Pol, const I& x )
00739 {
00740 int n = p.size()-1;
00741 p = Pol[n];
00742 dp = O(0);
00743 for ( int j = n-1; j >= 0; dp = dp*x + p, p =p*x + Pol[j], j-- ) ;
00744 };
00745
00754 template <class R> inline
00755 typename R::value_type derive( const R& Pol, const typename R::value_type& x )
00756 {
00757 typename R::value_type p,res;
00758 eval(p,res,Pol,x);
00759 return res;
00760 };
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00777 template< class R,class C>
00778 void shift( R& p, const C& c )
00779 {
00780 int j,k,s;
00781 for ( s = p.size(), j = 0; j <= s-2; j++ )
00782 for( k = s-2; k >= j; p[k] += c*p[k+1], k-- ) ;
00783 };
00784
00789 template<class R, class C>
00790 void shift(R & r,const R & p,const C& x0)
00791 {
00792 r=p; shift(r,x0);
00793 }
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00811 template<class R, class C>
00812 void scale(R & r, const R & p, const C & l)
00813 {
00814 r=p;
00815 C s(l);
00816 for(unsigned i=1; i< p.size();i++){
00817 r[i]*=s;
00818 s *=l;
00819 }
00820 }
00821
00822
00827 template<class R, class C>
00828 void inv_scale(R & r, const R & p, const C & l)
00829 {
00830 int sz=p.size();
00831 r.resize(sz);
00832 sz--;
00833 r[sz]=p[sz];
00834 typename R::value_type s=l;
00835 for(int i=sz-1; i>=0;i--){
00836 r[i]=p[i]*s;
00837 s *=l;
00838 }
00839 }
00840
00841
00846 template<class T,class P, class C> void
00847 convertm2b(T& bz, const P& p, unsigned size, const C& a, const C& b) {
00848 typedef typename T::value_type coeff_t;
00849 T pps(p.size());
00850 array::assign(pps,p);
00851
00852 if(a !=0)
00853 shift(pps,pps,a);
00854
00855 scale(pps, pps, C(b-a));
00856
00857 array::set_cst(bz,pps[0]);
00858 int dn=1, nm=1;
00859
00860 for(unsigned j=1; j<size; j++) {
00861 dn *= (size-j); dn/= j;
00862 nm=1;
00863 bz[j] += pps[j]/dn;
00864 for(unsigned i=j+1; i<size; i++) {
00865 nm *= i; nm/= (i-j);
00866 bz[i] += pps[j]*nm/dn;
00867 }
00868 }
00869 }
00870
00871
00872 template<class R>
00873 void coeff_modulo( R & r, const typename R::value_type & x ) {
00874 for ( typename R::iterator i = r.begin(); i != r.end(); *i %= x, ++i ) ;
00875 };
00876
00877 template<class S, class R>
00878 S numer(const R & f) {
00879 S p(0,degree(f));
00880 typename S::value_type d=1;
00881 for(int i=0;i<degree(f)+1;i++) {
00882 if (f[i] !=0) d=lcm(d,denominator(f[i]));
00883 }
00884 for(int i=0;i<degree(f)+1;i++)
00885 p[i]=numerator(f[i])* (d/denominator(f[i]));
00886 return p;
00887 }
00888
00889 }
00890
00891 # undef Polynomial
00892 # define Polynomial univariate::monomials<C>
00893 # define TMPL template<class C>
00894
00895 template<class A, class B> struct use;
00896 struct operators_of;
00897
00898 TMPL struct use<operators_of,Polynomial> {
00899
00900 static inline void
00901 add (Polynomial &r, const Polynomial &a ) {
00902 univariate::add (r, a);
00903 }
00904 static inline void
00905 add (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00906 univariate::add (r, a, b);
00907 }
00908 static inline void
00909 add (Polynomial &r, const Polynomial &a, const C & b) {
00910 univariate::add (r, a, b);
00911 }
00912 static inline void
00913 add (Polynomial &r, const C & a, const Polynomial &b) {
00914 univariate::add (r, b, a);
00915 }
00916 static inline void
00917 sub (Polynomial &r, const Polynomial &a ) {
00918 univariate::sub (r, a );
00919 }
00920 static inline void
00921 sub (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00922 univariate::sub (r, a, b);
00923 }
00924 static inline void
00925 sub (Polynomial &r, const C & a, const Polynomial &b) {
00926 univariate::sub (r, a, b);
00927 }
00928 static inline void
00929 sub (Polynomial &r, const Polynomial &a, const C & b) {
00930 univariate::sub (r, a, b);
00931 }
00932 static inline void
00933 mul (Polynomial &r, const Polynomial &a ) {
00934 univariate::mul (r, a );
00935 }
00936 static inline void
00937 mul (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00938 univariate::mul (r, a, b);
00939 }
00940 static inline void
00941 mul (Polynomial &r, const Polynomial &a, const C & b) {
00942 univariate::mul (r, a, b); }
00943 static inline void
00944 mul (Polynomial &r, const C & a, const Polynomial &b) {
00945 univariate::mul (r, b, a);
00946 }
00947 static inline void
00948 div (Polynomial &r, const Polynomial &a, const Polynomial &b) {
00949 univariate::div (r, a, b);
00950 }
00951 static inline void
00952 div (Polynomial &r, const Polynomial &a, const C & b) {
00953 univariate::div (r, a, b);
00954 }
00955 static inline void
00956 div (Polynomial &a, const C & c) {
00957 univariate::div (a, c);
00958 }
00959
00960
00961
00962
00963 };
00964 # undef Polynomial
00965 # undef TMPL
00966
00967 }
00968
00969 # undef TMPL
00970 # undef TMPLX
00971 # undef Polynomial
00972 #endif // realroot_univariate_hpp
00973