realroot_doc 0.1.1
|
00001 /********************************************************************* 00002 * This file is part of the source code of realroot kernel. 00003 * Author(s): B. Mourrain, GALAAD, INRIA 00004 * 00005 * Modification: et@di.uoa.gr 00006 * Add lcoeff, tcoeff functions 00007 * Add diff function that returns the derivative 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 // {degree_=this->size_-1;checkdegree(*this);} 00075 monomials(const monomials<C> & p); 00076 // {}//{cout <<"copy rep"<<endl;} 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 // No test {if(i<size_) return tab_[i]; else return C(0);} 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 // std::cout <<"(Using default degree) "<<p<<std::endl; 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 // if(i != degree(p) && with_plus_sign(p[i])) os<<"+"; 00392 if(i>0) 00393 { 00394 // if(p[i] == (coeff_t)(-1)) os<<"-"; 00395 // else 00396 if(not_one) 00397 os<<"*"; 00398 os<<"x"; 00399 if(i !=1) 00400 {os<<'^'; os<<i;} 00401 } 00402 // else 00403 // os<<p[0]; 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 // for(; it !=p.rend(); ++it) {r*=c; assign(cf,*it); r+=cf;} 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 // for(; it !=p.rend(); ++it) {r*=c; assign(cf,*it); r+=cf;} 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) // version + simple 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 // ancienne version 00615 // template <class R> inline 00616 // void diff(R & r, const R & p) 00617 // { 00618 // if(degree(p)>0)// assert(degree(p)>0); 00619 // { 00620 // for(unsigned i=1;i<p.size();++i) 00621 // r[i-1] =p[i]*i; 00622 // r.resize(degree(p)); 00623 // } else r.resize(0); 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 // ancienne version 00637 // template <class R> inline 00638 // R diff(const R & p) 00639 // { 00640 // R r(p); 00641 // if(degree(p)>0) { 00642 // for(unsigned i = 1; i < p.size(); ++i) 00643 // r[i-1] = p[i] * i; 00644 // r.resize(degree(p)); 00645 // } else r.resize(0); 00646 // return r; 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 // il me semble que tout ca c'est la meme chose que p.resize(e) 00699 T temp(e); 00700 for (typename T::size_type i = 0; i < e; i++) temp[i]=p[i]; 00701 p.resize(e); 00702 // p.degree()=e-1; 00703 for (typename T::size_type i = 0; i < e; i++) p[i]=temp[i]; 00704 } 00705 //------------------------------------------------------------------------- 00715 template <class T> // version + simple 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 // template <class T> // ancienne version 00720 // inline void reverse(T & p,typename T::size_type n) 00721 // { 00722 // for (typename T::size_type i = 0, j=n-1; i<j; i++, j--) 00723 // { 00724 // swap(p[i],p[j]); 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 // wrap sur eval 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 // template <class R> // ancienne version 00763 // inline typename R::value_type 00764 // derive(const R p, typename R::value_type x) 00765 // { 00766 // typename R::size_type degree = p.degree(); 00767 // typename R::value_type deriv(0); 00768 // for (typename R::size_type j=1; j<=p.degree();j++) 00769 // deriv+=p[j]*j*pow(x,j-1); 00770 // return (typename R::value_type) deriv; 00771 // } 00772 00773 //-------------------------------------------------------------------- 00777 template< class R,class C> // version + simple 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 // ancienne version 00796 // { 00797 // R dp(p); 00798 // r[0]=eval_horner(dp,x0); 00799 // for(unsigned i=1; i< p.size();i++){ 00800 // diff(dp,dp); 00801 // array::div(dp,i); 00802 // r[i]=eval_horner(dp,x0); 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 } //namespace univariate 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 // static inline void 00960 // rem (Polynomial &r, const Polynomial &a, const Polynomial &b) { 00961 // univariate::rem (r, b, a); 00962 // } 00963 }; 00964 # undef Polynomial 00965 # undef TMPL 00966 //==================================================================== 00967 } //namespace mmx 00968 //====================================================================== 00969 # undef TMPL 00970 # undef TMPLX 00971 # undef Polynomial 00972 #endif // realroot_univariate_hpp 00973