Developer documentation

univariate.hpp
Go to the documentation of this file.
1 /*********************************************************************
2 * This file is part of the source code of realroot kernel.
3 * Author(s): B. Mourrain, GALAAD, INRIA
4 *
5 * Modification: et@di.uoa.gr
6 * Add lcoeff, tcoeff functions
7 * Add diff function that returns the derivative
8 **********************************************************************/
9 #ifndef realroot_univariate_hpp
10 #define realroot_univariate_hpp
11 //--------------------------------------------------------------------
12 #include <iostream>
13 #include <math.h>
14 #include <realroot/assign.hpp>
15 #include <realroot/array.hpp>
16 # define TMPL template<class C>
17 # define TMPLX template<class C, class X>
18 # define Polynomial monomials<C>
19 
20 //====================================================================
21 namespace mmx {
22 //--------------------------------------------------------------------
23 #ifndef MMX_WITH_PLUS_SIGN
24 #define MMX_WITH_PLUS_SIGN
25  template<class X> bool with_plus_sign(const X& x) {return x>0;}
26 #endif //MMX_WITH_PLUS_SIGN
27 //--------------------------------------------------------------------
28  struct AsSize;
29 
30  //====================================================================
32 
47 namespace univariate {
48 
53  template <class C>
54  struct monomials {
55 
56  typedef C value_type;
57  typedef unsigned int size_type;
58  typedef C* iterator;
59  typedef iterator const_iterator;
60  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
61  typedef std::reverse_iterator<iterator> reverse_iterator;
62  typedef C coeff_t;
63 
64  C * tab_;
65  size_type size_;
66  int degree_;
67 
68  monomials(): tab_(0), size_(0), degree_(-1) {}
69  monomials(const C& c);
70  monomials(const C& c, size_type d, int v=0);
71  monomials(const size_type& s, C *t);
72  monomials(const size_type& s, const char* t);
73  monomials(C* b, C *e);
74  // {degree_=this->size_-1;checkdegree(*this);}
75  monomials(const monomials<C> & p);
76  // {}//{cout <<"copy rep"<<endl;}
77  ~monomials () { delete[] tab_;}
78 
79  iterator begin() {return iterator(tab_); }
80  const_iterator begin() const {return const_iterator(tab_); }
81  iterator end() {return iterator(this->tab_+degree_+1); }
82  const_iterator end() const {return const_iterator(this->tab_+degree_+1); }
83 
84  reverse_iterator rend() {return reverse_iterator(tab_); }
85  const_reverse_iterator rend() const {return reverse_iterator(tab_); }
86 
87  reverse_iterator rbegin() {
88  return reverse_iterator(this->tab_+degree_+1);
89  }
90  const_reverse_iterator rbegin() const {
91  return const_reverse_iterator(this->tab_+degree_+1);
92  }
93 
94  unsigned size() const { return size_;}
95  unsigned degree() const { return degree_;}
96 
97  monomials& operator= (const monomials<C> & v);
98 
99  inline C & operator[] (size_type i) {return tab_[i];}
100  inline const C & operator[] (size_type i) const {return tab_[i];}
101  // No test {if(i<size_) return tab_[i]; else return C(0);}
102 
103  bool operator==( const C& c ) const;
104 
105  void resize(const size_type& n);
106 
107  };
108 
109  TMPL
110  Polynomial::monomials(const Polynomial & v) : size_(v.size_), degree_(v.degree_) {
111  tab_ = new C[v.size_];
112  for(size_type i=0;i<v.size_;i++) {tab_[i] = v[i];}
113  }
114 
115  TMPL
116  Polynomial::monomials(const C& c): size_(1), degree_(0) {
117  tab_ = new C[1];
118  tab_[0]=c;
119  }
120  TMPL
121  Polynomial::monomials(const C& c, size_type l, int v): size_(l+1), degree_(l) {
122  tab_ = new C[l+1];
123  for (size_type i = 0; i < l; i++) tab_[i]=C(0);
124  tab_[l]=c;
125  }
126 
127  TMPL
128  Polynomial::monomials(const size_type& i, C* t): size_(i), degree_(i-1) {
129  tab_ = new C[i];
130  for(size_type l=0;l<i;l++) tab_[l] = t[l];
131  check_degree(*this);
132  }
133 
134  TMPL
135  Polynomial::monomials(C* b, C* e) {
136  size_=0; C* p;
137  for(p=b;p!=e;p++,size_++) ;
138  tab_ = new C[size_];
139  degree_=0;
140  for(p=b; p!=e; p++,degree_++) {tab_[degree_]=(*p);}
141  check_degree(*this);
142  }
143 
144 
145  TMPL
146  Polynomial::monomials(const size_type& l, const char * nm) {
147  std::istringstream ins(nm);
148  size_=l;
149  tab_ = new C[size_];
150  for(size_type i=0; i< size_; i++) ins >>tab_[i];
151  degree_=l-1;
152  check_degree(*this);
153  }
154  //----------------------------------------------------------------------
155  TMPL void
156  Polynomial::resize(const size_type & i) {
157  if(size_!=i){
158  if (size_ != 0) {
159  C* tmp = tab_;
160  tab_ = new C[i];
161  for(size_type j=0;j<std::min(i,size_);j++) tab_[j]=tmp[j];
162  for(size_type j=std::min(i,size_);j<i;j++) tab_[j]=value_type();
163  size_=i;
164  delete [] tmp;
165  } else {
166  size_=i; tab_= new C[i];
167  for(size_type j=0;j<size_;j++) tab_[j]=value_type();
168  }
169  }
170  degree_=i-1;
171  }
172 
173  TMPL Polynomial&
174  Polynomial::operator=(const Polynomial & v) {
175  if (size_ != v.size_) {
176  if (size_ !=0) delete [] tab_;
177  tab_ = new C[v.size_];
178  size_ = v.size_;
179  }
180  degree_=v.degree_;
181  for(size_type i=0;i<size_;i++) tab_[i] = v[i];
182  return *this;
183  }
184 
185  TMPL bool
186  Polynomial::operator== (const C& c) const {
187  if(c==0)
188  return (this->degree()<0);
189  else
190  return (this->degree()==0 && tab_[0]== c);
191  }
192  //--------------------------------------------------------------------
193  template <class R>
194  int degree(const R & p) {
195  // std::cout <<"(Using default degree) "<<p<<std::endl;
196  int i = p.size()-1;
197  while(i>-1 && p[i]==(typename R::value_type)0) i--;
198  return i;
199  }
200 
201  TMPL inline int degree(const Polynomial& a) { return a.degree_;}
202 
203 
204  //-------------------------------------------------------------------
205 
206  TMPL inline int
208  int l = a.degree_;
209  while(l >=0 && (a.tab_[l]==0)) {l--;}
210  a.degree_=l;
211  return a.degree_;
212  }
213 
214  //----------------------------------------------------------------------
215  TMPL void inline
216  add(Polynomial &r, const Polynomial& a, const Polynomial & b) {
217  array::add(r,a,b);
218  check_degree(r);
219  }
220 
221  //----------------------------------------------------------------------
222  TMPL void inline
223  add(Polynomial &r, const Polynomial& a, const C& c) {
224  if(degree(a)>-1) {
225  r=a; r[0]+=c;
226  }
227  else
228  r= Polynomial(c,0);
229  check_degree(r);
230  }
231 
232  //----------------------------------------------------------------------
233  TMPL void inline
234  add(Polynomial &r, const C& c) {
235  if(degree(r)>-1) {
236  r[0]+=c;
237  }
238  else
239  r= Polynomial(c,0);
240  check_degree(r);
241  }
242  //----------------------------------------------------------------------
243  TMPL void inline
244  add(Polynomial &r, const Polynomial& a) {
245  array::add(r,a);
246  check_degree(r);
247  }
248  //----------------------------------------------------------------------
249  TMPL void inline
250  sub(Polynomial &r, const Polynomial& a, const Polynomial & b) {
251  array::sub(r,a,b);
252  check_degree(r);
253  }
254  //----------------------------------------------------------------------
255  TMPL void inline
256  sub(Polynomial &r, const Polynomial& a) {
257  array::sub(r,a);
258  check_degree(r);
259  }
260  //----------------------------------------------------------------------
261  TMPL void inline
262  sub(Polynomial &r, const Polynomial& a, const C& c) {
263  if(degree(a)>-1) {
264  r=a; r[0]-=c;
265  }
266  else
267  r= Polynomial(-c,0);
268  check_degree(r);
269  }
270  //----------------------------------------------------------------------
271  TMPLX void inline
272  sub(Polynomial &r, const Polynomial& a, const X& x) {
273  sub(r,a,(C)x);
274  }
275  //--------------------------------------------------------------------
276  TMPL void inline
277  sub(Polynomial &r, const C& c) {
278  if(degree(r)>-1) {
279  r[0]-=c;
280  }
281  else
282  r= Polynomial(-c,0);
283  check_degree(r);
284  }
285  //----------------------------------------------------------------------
286  TMPL void inline
287  mul(Polynomial &r, const Polynomial& a, const Polynomial & b) {
288  assert(&r!=&a);
289 
290  r.resize(std::max(degree(a)+degree(b)+1,0));
291  array::set_cst(r,(C)0);
292  mul_index(r,a,b);
293  check_degree(r);
294  }
295 
296  //--------------------------------------------------------------------
298  TMPL void inline
299  mul(Polynomial &r, const C & c) {
300  array::mul_ext(r,c);
301  }
302 
303  //--------------------------------------------------------------------
305  TMPL void inline
306  mul(Polynomial &a, const Polynomial & b) {
307  Polynomial r; mul(r,a,b); a=r;
308  }
309  //----------------------------------------------------------------------
310  TMPL void inline
311  mul(Polynomial &r, const Polynomial& p, const C & c) {
312  r=p; mul(r,c); check_degree(r);
313  }
314 
315 
316  //----------------------------------------------------------------------
317  TMPL void inline
318  shift(Polynomial &r, const Polynomial& p, int d, int v=0) {
319  if(d>=0) {
320  r.resize(degree(p)+d+1);
321  for(int i=0; i<d;i++)
322  r[i]= (typename Polynomial::coeff_t)0;
323  for(int i=0; i<=degree(p);i++)
324  r[i+d]=p[i];
325  }
326  }
327 
328  //----------------------------------------------------------------------
329  TMPL void inline
330  div(Polynomial &r, const Polynomial& a, const Polynomial & b) {
331  assert(&r!=&a);
332  Polynomial tmp(a);
333  r = Polynomial(0);
334  div_rem(r,tmp,b);
335  check_degree(r);
336  }
337 
338  //----------------------------------------------------------------------
339  TMPL void inline
340  div(Polynomial &r, const Polynomial& b) {
341  Polynomial tmp(r);
342  r = Polynomial(0);
343  div_rem(r,tmp,b);
344  check_degree(r);
345  }
346 
347  //--------------------------------------------------------------------
348  TMPL void inline
349  div(Polynomial &r, const C & c) {
350  array::div_ext(r,c);
351  check_degree(r);
352  }
353 
354  //-------------------------------------------------------------------
356  template< class R > inline typename R::value_type
357  lcoeff(const R& p) {
358  return p[degree(p)];
359  }
360  //-------------------------------------------------------------------
362  template< class R > inline typename R::value_type
363  tcoeff(const R& p) { return p[0]; }
364 
365  //-------------------------------------------------------------------
366  template <class OSTREAM, class C> OSTREAM&
367  print_as_coeff(OSTREAM & os, const C & c, bool plus)
368  {
369  if(plus)
370  os <<"+";
371  os<<"("<<c<<")";
372  return os;
373  }
374 
375  template <class OSTREAM, class C, class VAR> inline OSTREAM&
376  print(OSTREAM& os, const Polynomial& p, const VAR& var)
377  {
378  typedef typename Polynomial::value_type coeff_t;
379  bool plus=false, not_one;
380  if ( degree(p)<0)
381  os << coeff_t(0) ;
382  else {
383  for(int i= 0; i<=degree(p); i++)
384  {
385  if(p[i]!= (coeff_t)0)
386  {
387  not_one = (p[i] != (coeff_t)1);
388  if(not_one || i==0)
389  print_as_coeff(os,p[i],plus);
390  plus=true;
391  // if(i != degree(p) && with_plus_sign(p[i])) os<<"+";
392  if(i>0)
393  {
394  // if(p[i] == (coeff_t)(-1)) os<<"-";
395  // else
396  if(not_one)
397  os<<"*";
398  os<<"x";
399  if(i !=1)
400  {os<<'^'; os<<i;}
401  }
402 // else
403 // os<<p[0];
404  }
405  }
406  if(!plus) os << 0 ;
407  }
408  return os;
409  }
410 
411  template <class OSTREAM, class C> inline OSTREAM&
412  print(OSTREAM& os, const Polynomial& p) {
413  return print(os,p, "x");
414  }
415 
416  //--------------------------------------------------------------------
417  template <class R, class C>
418  inline void set_monomial(R & x, const C & c, unsigned n)
419  {
420 
421  x.resize(n+1);
422  array::set_cst(x,(typename R::value_type)0);
423  x[n]=c;
424  checkdegree(x);
425 
426  }
427  //--------------------------------------------------------------------
428  template <class R, class S>
429  inline void add_cst(R & r, const S & c) { r[0]+=c; }
430 
431  template <class R, class S>
432  inline void sub_cst(R & r, const S & c) { r[0]-=c;}
433  //-------------------------------------------------------------------
434  template <class R>
435  inline void mul_index(R & r, const R & a, const R & b)
436  {
437  //typedef typename R::coeff_t Scalar;
438  int da=degree(a), db=degree(b),i,j;
439  for (i=0;i<=db;i++) {
440  if (b[i] == 0) continue;
441  for (j=0;j<=da;j++) r[i+j] += a[j]*b[i];
442  }
443  }
444  //-------------------------------------------------------------------
445  template <class R> inline
446  void mul_index_it(R & r, const R & a, const R & b)
447  {
448  typename R::const_iterator ia, ib;
449  typename R::iterator ir, it;
450  ir=r.begin();
451  for (ib=b.begin();ib !=b.end()&& ir != r.end();++ib) {
452  typename R::value_type c = *ib;
453  it=ir;
454  if (c==0) {++ir;continue;}
455  for (ia=a.begin();ia!=a.end();++ia,++it) {
456  (*it)+=(*ia)*c;
457  }
458  ++ir;
459  }
460  }
461  //-------------------------------------------------------------------
462  template <class R> inline
463  void mul(R & a, const R & b)
464  {
465  if(degree(a)>=0 && degree(b)>=0)
466  {
467  R ta(a);
468  a.resize(degree(a)+degree(b)+1);
469  array::set_cst(a,0);
470  mul_index(a,ta,b);
471  }
472  else
473  array::set_cst(a,0);
474  }
475  //--------------------------------------------------------------------
476  template <class R> inline
477  void mul_index(R & a, const R & b)
478  {
479  R ta(a);
480  a.resize(degree(a)+degree(b)+1);
481  array::set_cst(a,0);
482  mul_index(a,ta,b);
483  }
484  //----------------------------------------------------------------------
485  template <class C, class R>
486  inline C eval_horner(const R & p, const C & c)
487  {
488  using namespace let;
489  C r,cf;
490  if(degree(p)>0) {
491  typedef typename R::const_reverse_iterator const_reverse_iterator;
492  const_reverse_iterator it=p.rbegin();
493  assign(r,*it); it++;
494  // for(; it !=p.rend(); ++it) {r*=c; assign(cf,*it); r+=cf;}
495  for(; it !=p.rend(); ++it) {r=r*c; assign(cf,*it); r=r+cf;}
496  return r;
497  } else if(degree(p)>-1)
498  {
499  assign(r,p[0]); return r;
500  }
501  else
502  return C(0);
503  }
504  //----------------------------------------------------------------------
505  template <class C, class R>
506  inline C eval_horner_idx(const R & p, const C & c)
507  {
508  if(degree(p)>0) {
509  int d=degree(p);
510  C r=p[d];
511  for(int i=d-1; i>-1; --i) {r*=c; r+= p[i];}
512  return r;
513  } else if(degree(p)>-1)
514  return p[0];
515  else
516  return C(0);
517  }
518  //--------------------------------------------------------------------
519  template <class C, class R>
520  inline C eval(const R & p, const C & c)
521  {
522  return eval_horner(p,c);
523  }
524  //----------------------------------------------------------------------
525  template <class C, class R>
526  inline C eval_homogeneous(const R & p, const C & a, const C& b)
527  {
528  using namespace let;
529  C r,y=1,cf;
530  if(degree(p)>0) {
531  typedef typename R::const_reverse_iterator const_reverse_iterator;
532  const_reverse_iterator it=p.rbegin();
533  assign(r,*it); it++;
534  // for(; it !=p.rend(); ++it) {r*=c; assign(cf,*it); r+=cf;}
535  for(; it !=p.rend(); ++it) {r*=a; y *=b; assign(cf,*it); r=r+cf*y;}
536  return r;
537  } else if(degree(p)==0)
538  {
539  assign(r,p[0]); return r;
540  }
541  else
542  return C(0);
543  }
544 
545  //--------------------------------------------------------------------
546  template<typename POL, typename X> inline
547  int sign_at(const POL & p, const X& x)
548  {
549  X v= eval_horner(p,x);
550  return sign(v);
551  }
552 
558  template<class R>
559  void div_rem(R & q, R & a, const R & b)
560  {
561  //typedef typename R::iterator iterator;
562  int da = degree(a), db=degree(b);
563  typename R::value_type lb=b[db];
564  R t;
565  q=(R)0;
566  while (da>=db) {
567  while(a[da]==0 && da>=db) da--;
568  if(da>=db) {
569  R m( a[da]/lb, da-db );
570  mul(t,b,m);
571  t[da]=a[da];
572  sub(a,t);
573  add(q,m);
574  }
575  }
576  }
577 
578 //----------------------------------------------------------------------
579 template<class R> inline void checkdegree(R & p) {
580  int d = p.size()-1;
581  if ( d < 0 ) return;
582  while ( p[d] == 0 ) d--;
583  p.resize(d+1);
584 }
585 //----------------------------------------------------------------------
586 template <class R> inline R diff(const R & p);
587 //----------------------------------------------------------------------
588 template<class R> void reciprocal(R & w,const R & p);
589 //----------------------------------------------------------------------
590 template<class R> void reverse(R & p, typename R::size_type n)
591 {
592  int l=n-1;
593  for(typename R::size_type i=0;i<n/2;i++)
594  std::swap(p[i],p[l-i]);
595 }
596 //----------------------------------------------------------------------
597 template<class R>
598 typename R::value_type derive(const R p,typename R::value_type x);
599 //----------------------------------------------------------------------
600 template<class R> void reduce(R & p, const typename R::size_type & e);
601 //----------------------------------------------------------------------
602 template<class R, class C>
603  void scale(R & t,const R & p,const C & l);
604 //----------------------------------------------------------------------
607 template<class R> inline
608 void diff(R & r, const R & p) // version + simple
609 {
610  int n,i;
611  r.resize(n=degree(p));
612  for( i = 1; i < n+1; ++i) r[i-1] =p[i]*i;
613 }
614  // ancienne version
615  // template <class R> inline
616  // void diff(R & r, const R & p)
617  // {
618  // if(degree(p)>0)// assert(degree(p)>0);
619  // {
620  // for(unsigned i=1;i<p.size();++i)
621  // r[i-1] =p[i]*i;
622  // r.resize(degree(p));
623  // } else r.resize(0);
624  // }
625 
626 //---------------------------------------------------------------------
629 template <class R> inline
630 R diff(const R & p)
631 {
632  R r(p);
633  diff(r,p);
634  return r;
635 }
636 // ancienne version
637 // template <class R> inline
638 // R diff(const R & p)
639 // {
640 // R r(p);
641 // if(degree(p)>0) {
642 // for(unsigned i = 1; i < p.size(); ++i)
643 // r[i-1] = p[i] * i;
644 // r.resize(degree(p));
645 // } else r.resize(0);
646 // return r;
647 // }
648 //---------------------------------------------------------------------
659 template <class R>
660 void reciprocal(R & w, const R & p)
661 {
662  typedef typename R::size_type size_type;
663  typedef typename R::value_type C;
664 
665  const size_type deg = univariate::degree(p)+1;
666  R w0(deg),v(deg),xp(p);
667  size_type K = (size_type) (std::log(p.degree()+1)/std::log(2)),j=1;
668  C p0 = xp[deg-1];
669 
670  xp /= p0;
671  w0 =xp/xp[0];
672  v = w0;
673  v *= C(-1.0);
674  v[0]+=C(2);
675  w=v/xp[0];
676  w0=w;
677  while (j <= K) {
678  univariate::reduce(w0,pow(2,j+1));
679  w=xp*w0;
680  v =w;
681  v*=C(-1.0);
682  v[0]+=C(2);
683  univariate::reduce(v,pow(2,j+1));
684  w=w0*v;
685  w0=w;
686  j++;
687  }
688  univariate::reduce(w,deg);
689  w/=p0;
690 }
691 //-------------------------------------------------------------------------
695 template <class T>
696 inline void reduce(T & p, const typename T::size_type & e)
697 {
698  // il me semble que tout ca c'est la meme chose que p.resize(e)
699  T temp(e);
700  for (typename T::size_type i = 0; i < e; i++) temp[i]=p[i];
701  p.resize(e);
702  // p.degree()=e-1;
703  for (typename T::size_type i = 0; i < e; i++) p[i]=temp[i];
704 }
705 //-------------------------------------------------------------------------
715 template <class T> // version + simple
716 inline void reverse(T & p, int n)
717 { for ( int i = 0; i < n/2; i++ ) std::swap(p[i],p[n-i]) ; }
718 
719 // template <class T> // ancienne version
720 // inline void reverse(T & p,typename T::size_type n)
721 // {
722 // for (typename T::size_type i = 0, j=n-1; i<j; i++, j--)
723 // {
724 // swap(p[i],p[j]);
725 // }
726 // }
727 
728 //----------------------------------------------------------------------------
737 template<class O, class R, class I> inline
738 void eval( O& p, O& dp, const R& Pol, const I& x )
739 {
740  int n = p.size()-1;
741  p = Pol[n];
742  dp = O(0);
743  for ( int j = n-1; j >= 0; dp = dp*x + p, p =p*x + Pol[j], j-- ) ;
744 };
745 
754 template <class R> inline // wrap sur eval
755 typename R::value_type derive( const R& Pol, const typename R::value_type& x )
756 {
757  typename R::value_type p,res;
758  eval(p,res,Pol,x);
759  return res;
760 };
761 
762 // template <class R> // ancienne version
763 // inline typename R::value_type
764 // derive(const R p, typename R::value_type x)
765 // {
766 // typename R::size_type degree = p.degree();
767 // typename R::value_type deriv(0);
768 // for (typename R::size_type j=1; j<=p.degree();j++)
769 // deriv+=p[j]*j*pow(x,j-1);
770 // return (typename R::value_type) deriv;
771 // }
772 
773 //--------------------------------------------------------------------
777 template< class R,class C> // version + simple
778 void shift( R& p, const C& c )
779 {
780  int j,k,s;
781  for ( s = p.size(), j = 0; j <= s-2; j++ )
782  for( k = s-2; k >= j; p[k] += c*p[k+1], k-- ) ;
783 };
784 //--------------------------------------------------------------------
789 template<class R, class C>
790 void shift(R & r,const R & p,const C& x0)
791 {
792  r=p; shift(r,x0);
793 }
794 
795 // ancienne version
796 // {
797 // R dp(p);
798 // r[0]=eval_horner(dp,x0);
799 // for(unsigned i=1; i< p.size();i++){
800 // diff(dp,dp);
801 // array::div(dp,i);
802 // r[i]=eval_horner(dp,x0);
803 // }
804 // }
805 //--------------------------------------------------------------------
806 
811 template<class R, class C>
812 void scale(R & r, const R & p, const C & l)
813 {
814  r=p;
815  C s(l);
816  for(unsigned i=1; i< p.size();i++){
817  r[i]*=s;
818  s *=l;
819  }
820 }
821 //--------------------------------------------------------------------
822 
827 template<class R, class C>
828 void inv_scale(R & r, const R & p, const C & l)
829 {
830  int sz=p.size();
831  r.resize(sz);
832  sz--;
833  r[sz]=p[sz];
834  typename R::value_type s=l;
835  for(int i=sz-1; i>=0;i--){
836  r[i]=p[i]*s;
837  s *=l;
838  }
839 }
840 
841 //--------------------------------------------------------------------
846 template<class T,class P, class C> void
847 convertm2b(T& bz, const P& p, unsigned size, const C& a, const C& b) {
848  //typedef typename T::value_type coeff_t;
849  T pps(p.size());
850  array::assign(pps,p);
851 
852  if(a !=0)
853  shift(pps,pps,a);
854 
855  scale(pps, pps, C(b-a));
856 
857  array::set_cst(bz,pps[0]);
858  int dn=1, nm=1;
859 
860  for(unsigned j=1; j<size; j++) {
861  dn *= (size-j); dn/= j;
862  nm=1;
863  bz[j] += pps[j]/dn;
864  for(unsigned i=j+1; i<size; i++) {
865  nm *= i; nm/= (i-j);
866  bz[i] += pps[j]*nm/dn;
867  }
868  }
869 }
870 //--------------------------------------------------------------------
871 
872 template<class R>
873 void coeff_modulo( R & r, const typename R::value_type & x ) {
874  for ( typename R::iterator i = r.begin(); i != r.end(); *i %= x, ++i ) ;
875 };
876 //--------------------------------------------------------------------
877 template<class S, class R>
878 S numer(const R & f) {
879  S p(0,degree(f));
880  typename S::value_type d=1;
881  for(int i=0;i<degree(f)+1;i++) {
882  if (f[i] !=0) d=lcm(d,denominator(f[i]));
883  }
884  for(int i=0;i<degree(f)+1;i++)
885  p[i]=numerator(f[i])* (d/denominator(f[i]));
886  return p;
887 }
888 //--------------------------------------------------------------------
889 } //namespace univariate
890 //======================================================================
891 # undef Polynomial
892 # define Polynomial univariate::monomials<C>
893 # define TMPL template<class C>
894 
895 template<class A, class B> struct use;
896 struct operators_of;
897 
898 TMPL struct use<operators_of,Polynomial> {
899 
900  static inline void
901  add (Polynomial &r, const Polynomial &a ) {
902  univariate::add (r, a);
903  }
904  static inline void
905  add (Polynomial &r, const Polynomial &a, const Polynomial &b) {
906  univariate::add (r, a, b);
907  }
908  static inline void
909  add (Polynomial &r, const Polynomial &a, const C & b) {
910  univariate::add (r, a, b);
911  }
912  static inline void
913  add (Polynomial &r, const C & a, const Polynomial &b) {
914  univariate::add (r, b, a);
915  }
916  static inline void
917  sub (Polynomial &r, const Polynomial &a ) {
918  univariate::sub (r, a );
919  }
920  static inline void
921  sub (Polynomial &r, const Polynomial &a, const Polynomial &b) {
922  univariate::sub (r, a, b);
923  }
924  static inline void
925  sub (Polynomial &r, const C & a, const Polynomial &b) {
926  univariate::sub (r, a, b);
927  }
928  static inline void
929  sub (Polynomial &r, const Polynomial &a, const C & b) {
930  univariate::sub (r, a, b);
931  }
932  static inline void
933  mul (Polynomial &r, const Polynomial &a ) {
934  univariate::mul (r, a );
935  }
936  static inline void
937  mul (Polynomial &r, const Polynomial &a, const Polynomial &b) {
938  univariate::mul (r, a, b);
939 }
940  static inline void
941  mul (Polynomial &r, const Polynomial &a, const C & b) {
942  univariate::mul (r, a, b); }
943  static inline void
944  mul (Polynomial &r, const C & a, const Polynomial &b) {
945  univariate::mul (r, b, a);
946  }
947  static inline void
948  div (Polynomial &r, const Polynomial &a, const Polynomial &b) {
949  univariate::div (r, a, b);
950  }
951  static inline void
952  div (Polynomial &r, const Polynomial &a, const C & b) {
953  univariate::div (r, a, b);
954  }
955  static inline void
956  div (Polynomial &a, const C & c) {
957  univariate::div (a, c);
958  }
959 // static inline void
960 // rem (Polynomial &r, const Polynomial &a, const Polynomial &b) {
961 // univariate::rem (r, b, a);
962 // }
963 };
964 # undef Polynomial
965 # undef TMPL
966 //====================================================================
967 } //namespace mmx
968 //======================================================================
969 # undef TMPL
970 # undef TMPLX
971 # undef Polynomial
972 #endif // realroot_univariate_hpp
973 
R::value_type tcoeff(const R &p)
Definition: univariate.hpp:363
void set_cst(V &a, const C &v)
Set all the entries of a to the values v.
Definition: array.hpp:99
bool operator==(const extended< NT > &lhs, const extended< NT > &rhs)
Definition: extended.hpp:88
C & operator[](size_type i)
Definition: univariate.hpp:99
C eval_homogeneous(const R &p, const C &a, const C &b)
Definition: univariate.hpp:526
T pow(const T &a, int i)
Definition: binomials.hpp:12
const C & b
Definition: Interval_glue.hpp:25
const_iterator begin() const
Definition: univariate.hpp:80
TMPL X
Definition: polynomial_operators.hpp:148
R::value_type lcoeff(const R &p)
Definition: univariate.hpp:357
C eval(const R &p, const C &c)
Definition: univariate.hpp:520
void div_rem(R &q, R &a, const R &b)
Definition: univariate.hpp:559
void mul_ext(V &a, const V &b, const W &c)
Scalar multiplication.
Definition: array.hpp:291
const Interval & I
Definition: Interval_glue.hpp:49
int degree(const R &p)
Definition: univariate.hpp:194
MP swap(const MP &P, int var_i, int var_j)
Definition: sparse_monomials.hpp:988
bool with_plus_sign(const ZZ &c)
Definition: GMP.hpp:62
static void sub(Polynomial &r, const Polynomial &a, const C &b)
Definition: univariate.hpp:929
unsigned size() const
Definition: univariate.hpp:94
TMPL void add(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:216
monomials()
Definition: univariate.hpp:68
OSTREAM & print_as_coeff(OSTREAM &os, const C &c, bool plus)
Definition: univariate.hpp:367
static void add(Polynomial &r, const C &a, const Polynomial &b)
Definition: univariate.hpp:913
reverse_iterator rbegin()
Definition: univariate.hpp:87
R diff(const R &p)
Definition: univariate.hpp:630
C coeff_t
Definition: univariate.hpp:62
static void mul(Polynomial &r, const C &a, const Polynomial &b)
Definition: univariate.hpp:944
static void sub(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:921
TMPL void shift(Polynomial &r, const Polynomial &p, int d, int v=0)
Definition: univariate.hpp:318
S numer(const R &f)
Definition: univariate.hpp:878
static void sub(Polynomial &r, const Polynomial &a)
Definition: univariate.hpp:917
C * tab_
Definition: univariate.hpp:64
static void sub(Polynomial &r, const C &a, const Polynomial &b)
Definition: univariate.hpp:925
void mul_index(R &r, const R &a, const R &b)
Definition: univariate.hpp:435
void reverse(R &p, typename R::size_type n)
Definition: univariate.hpp:590
static void div(Polynomial &r, const Polynomial &a, const C &b)
Definition: univariate.hpp:952
R::value_type derive(const R p, typename R::value_type x)
void set_monomial(R &x, const C &c, unsigned n)
Definition: univariate.hpp:418
void coeff_modulo(R &r, const typename R::value_type &x)
Definition: univariate.hpp:873
OSTREAM & print(OSTREAM &os, const Polynomial &p, const VAR &var)
Definition: univariate.hpp:376
static void div(Polynomial &a, const C &c)
Definition: univariate.hpp:956
void reduce(R &p, const typename R::size_type &e)
unsigned degree() const
Definition: univariate.hpp:95
polynomial< COEFF, with< MonomialTensor > > Polynomial
Definition: solver_mv_cf.cpp:23
TMPL void mul(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:287
iterator end()
Definition: univariate.hpp:81
const_reverse_iterator rend() const
Definition: univariate.hpp:85
monomials & operator=(const monomials< C > &v)
static void add(Polynomial &r, const Polynomial &a, const C &b)
Definition: univariate.hpp:909
void assign(double &r, const scalar< MPF > &z)
Definition: scalar_floating.hpp:537
void sub_cst(R &r, const S &c)
Definition: univariate.hpp:432
ZZ numerator(const QQ &a)
Definition: GMPXX.hpp:95
void add_cst(R &r, const S &c)
Definition: univariate.hpp:429
void resize(const size_type &n)
TMPL void div(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:330
#define min(a, b)
Definition: parser_def.c:475
size_type size_
Definition: univariate.hpp:65
void scale(R &t, const R &p, const C &l)
Definition: univariate.hpp:812
#define TMPLX
Definition: univariate.hpp:17
Definition: polynomial.hpp:37
static void mul(Polynomial &r, const Polynomial &a, const C &b)
Definition: univariate.hpp:941
ZZ size(const ZZ &z)
Definition: GMPXX.hpp:67
static void mul(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:937
void sub(V &a, const W &b)
Substraction of two vectors.
Definition: array.hpp:221
TMPL POL
Definition: polynomial_dual.hpp:74
void mul_index_it(R &r, const R &a, const R &b)
Definition: univariate.hpp:446
const_reverse_iterator rbegin() const
Definition: univariate.hpp:90
reverse_iterator rend()
Definition: univariate.hpp:84
C eval_horner_idx(const R &p, const C &c)
Definition: univariate.hpp:506
void add(V &a, const W &b)
Addition of two vectors.
Definition: array.hpp:154
C * iterator
Definition: univariate.hpp:58
ZZ denominator(const QQ &a)
Definition: GMPXX.hpp:96
void reciprocal(R &w, const R &p)
Definition: univariate.hpp:660
int degree_
Definition: univariate.hpp:66
TMPL int check_degree(Polynomial &a)
Definition: univariate.hpp:207
Polynomial P
Definition: solver_mv_cf.cpp:24
unsigned int size_type
Definition: univariate.hpp:57
static void div(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:948
void checkdegree(R &p)
Definition: univariate.hpp:579
bool operator==(const C &c) const
const C & c
Definition: Interval_glue.hpp:45
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: univariate.hpp:60
static void mul(Polynomial &r, const Polynomial &a)
Definition: univariate.hpp:933
double C
Definition: solver_mv_fatarcs.cpp:16
~monomials()
Definition: univariate.hpp:77
int sign(const QQ &a)
Definition: GMP.hpp:60
void convertm2b(T &bz, const P &p, unsigned size, const C &a, const C &b)
Definition: univariate.hpp:847
int sign_at(const POL &p, const X &x)
Definition: univariate.hpp:547
iterator begin()
Definition: univariate.hpp:79
Definition: univariate.hpp:54
TMPL void sub(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:250
static void add(Polynomial &r, const Polynomial &a, const Polynomial &b)
Definition: univariate.hpp:905
#define Polynomial
Definition: univariate.hpp:892
Interval< T, r > max(const Interval< T, r > &a, const Interval< T, r > &b)
Definition: Interval_fcts.hpp:135
Definition: array.hpp:12
const_iterator end() const
Definition: univariate.hpp:82
iterator const_iterator
Definition: univariate.hpp:59
C eval_horner(const R &p, const C &c)
Definition: univariate.hpp:486
size_t log(const scalar< MPF > &b)
Definition: scalar_floating.hpp:506
C value_type
Definition: univariate.hpp:56
static void add(Polynomial &r, const Polynomial &a)
Definition: univariate.hpp:901
void inv_scale(R &r, const R &p, const C &l)
Definition: univariate.hpp:828
#define TMPL
Definition: univariate.hpp:893
ZZ lcm(const ZZ &a, const ZZ &b)
Definition: GMPXX.hpp:58
std::reverse_iterator< iterator > reverse_iterator
Definition: univariate.hpp:61
void assign(Ra &a, const Rb &b)
Definition: array.hpp:425
#define assert(expr, msg)
Definition: shared_object.hpp:57
void div_ext(V &a, const V &b, const SC &sc)
Scalar division.
Definition: array.hpp:319
Home