Developer documentation

subresultant.hpp
Go to the documentation of this file.
1 #ifndef subdivix_subresultant_hpp
2 #define subdivix_subresultant_hpp
3 /********************************************************************/
4 #include <realroot/Seq.hpp>
6 namespace mmx {
7 struct euclidean {
8 
9 
10  template<class R> static
11  void pseudo_div(R& q, R& a, const R& b)
12  {
13  //typedef typename R::iterator iterator;
14  R t;//(degree(b)+1, AsSize());
15  typename R::value_type lb=b[degree(b)];
16  q=R(0);
17  int c=0, da = degree(a), db = degree(b), dab =da-db+1;
18  while (da>=db) {
19  R m(a[da],da-db);
20  shift(t,b,da-db); t*=a[da]; // t=b*m;
21  c++;
22  a*=lb;
23  t[da]=a[da];
24  a-=t;
25  q+=m;
26  da=degree(a);
27  }
28  a *= pow(lb, dab-c);
29  }
30 
31  template<class Polynomial> static inline
33  {
34  Polynomial r=a,q;
35  pseudo_div(q, r, b);
36  return r;
37  }
38 
39  template<class Polynomial> static inline
41  {
42  Polynomial r=a, q;
43  pseudo_div(q, r, b);
44  return q;
45  }
46 
47 };
48 
49 
50 
51 template<class PREM>
52 struct sub_resultant {
53 
54  template<class Pol>
55  static Seq<Pol> sequence(const Pol & p, const Pol & q) {
56 
57  typedef typename Pol::value_type coeff_type;
58  assert(degree(p) >=0 && degree(q) >= 0);
59  int n1 = degree(p), n2= degree(q);
60  coeff_type lp = p[n1], lq = q[n2];
61 
62  Seq<Pol> tab;
63  unsigned N = std::min(n1,n2);
64  tab.resize(N);
65  for(unsigned i=0;i<N;i++) tab[i]=Pol(0);
66  int d,da,db;
67  coeff_type la;
68  Pol a, b, Sr;
69 
70  if (n1>=n2) {
71  a=q;
72  b=PREM::prem(p,q);
73  d=n1-n2-1;
74  la=pow(lq,n1-n2);
75  } else {
76  a=p;
77  b=PREM::prem(q,p);
78  d=n2-n1-1;
79  la=pow(lp,n2-n1);
80  }
81 
82  if (d!=0) {
83  a*=(coeff_type)pow<int>(-1,d*(d+1)/2);
84  b*=(coeff_type)pow<int>(-1,(d+2)*(d+3)/2);
85  }
86  da=degree(a);
87  db=degree(b);
88  if(db>=0) tab[db]=b;
89 
90  while (db>=0) {
91  Sr =PREM::prem(a,b);
92  Sr/=(coeff_type)(pow(la,da-db)*a[da]);
93  Sr*=(coeff_type)pow<int>(-1,((da-db+1)*(da-db+2))/2);
94  a = b;
95  a *=(coeff_type)pow(b[db],da-db-1);
96  a /=(coeff_type)pow(la,da-db-1);
97  da=degree(a);
98  b=Sr;
99  la=a[da];
100  db=degree(b);
101  if (db>=0) tab[db]=b;
102  }
103  return tab;
104  }
105 
106  template<class Polynomial>
107  static Seq<Seq<Polynomial> > sequence(const Polynomial & p, const Polynomial & q, int v) {
108 
110  sp= coefficients(p,v),
111  sq= coefficients(q,v);
112 
113  typedef polynomial< Polynomial, with<Univariate> > upolmpol_t;
114  upolmpol_t
115  P(1,sp.size()-1),
116  Q(1,sq.size()-1);
117 
118  for (unsigned i=0;i<sp.size();i++) P[i]= sp[i];
119  for (unsigned i=0;i<sq.size();i++) Q[i]= sq[i];
120 
122 
123  Seq< Seq<Polynomial> > res(s.size());
124  for(unsigned i=0;i<s.size();i++)
125  for(int j=0; j<=degree(s[i]);j++)
126  res[i]<<s[i][j];
127 
128  return res;
129  }
130 
131  template<class Pol> static typename Pol::value_type
132  resultant(const Pol & p, const Pol & q) {
133  Seq<Pol> s= sequence(p,q);
134  if(s.size()>0)
135  return s[0][0];
136  else return 0;
137  }
138 
139  template<class Pol> static Pol
140  resultant(const Pol & p, const Pol & q, int v) {
141  Seq< Seq<Pol> > s = sequence(p,q,v);
142  if(s.size()>0) return s[0][0];
143  else return 0;
144  }
145 
146  template<class Pol> static bool
147  is_zero_seq(const Seq<Pol> & s) {
148  for (unsigned i=0;i<s.size() ;i++)
149  if(s[i]!=0) return false;
150  return true;
151  }
152 
153  template<class Polynomial> static Polynomial
154  subres_gcd(const Polynomial & p, const Polynomial & q, int v) {
155  typedef typename Polynomial::Monomial Monomial;
156  if(p==0) return q;
157  if(q==0) return p;
158  if(v==-1) return gcd(content(p),content(q));
159 
160  if(nbvar(p)==v+1 && nbvar(q)<= v) {
162  Polynomial d=q;
163  for (unsigned i=0;i<s.size();i++)
164  d = subres_gcd(d,s[i]);
165  return d;
166  }
167 
168  if(nbvar(p)<=v && nbvar(q)== v+1) {
170  Polynomial d=p;
171  for (unsigned i=0;i<s.size();i++)
172  d = subres_gcd(d,s[i]);
173  return d;
174  }
175 
176 
177  // Remove content of p
178  Polynomial dp=0;
179  Seq<Polynomial> sp = coefficients(p,v);
180  for(unsigned i=0;i< sp.size();i++) dp= subres_gcd(dp,sp[i]);
181  Polynomial P= p/dp;
182 
183  // Remove content of q
184  Polynomial dq=0;
185  Seq<Polynomial> sq = coefficients(q,v);
186  for(unsigned i=0;i< sq.size();i++) dq= subres_gcd(dq,sq[i]);
187  Polynomial Q= q/dq;
188 
189  // Take gcd of contents
190  Polynomial C= subres_gcd(dp,dq);
191 
192  // Subresultant sequence
194  = (degree(P)>=degree(Q)?sequence(P,Q,v):sequence(Q,P,v));
195 
196  unsigned i;
197  for (i=0;i<s.size() && is_zero_seq(s[i]);i++) ;
198 
199  if(i==s.size()) return (degree(P)>=degree(Q)?Q*C:P*C);
200 
201  // Take last non-zero term
202  Seq<Polynomial> D = s[i];
203 
204  // Remove content of last non-zero term.
205  Polynomial d=0;
206  for (i=0;i<D.size();i++) d = subres_gcd(d,D[i]);
207  // d/=content(d);
208  for (i=0;i<D.size();i++) D[i]/=d;
209 
210  // Reconstruct the multivariate polynomial
211  Polynomial r=0;
212  for (i=0;i<D.size();i++)
213  r+= D[i]*Polynomial(Monomial(1,i,v));
214  r/=content(r);
215  r *= C;
216  return r;
217  }
218 
219  template<class Polynomial> static Polynomial
220  subres_gcd(const Polynomial & p, const Polynomial & q) {
221  int v = std::max(nbvar(p)-1,nbvar(q)-1);
222  return subres_gcd(p,q,v);
223  }
224 };
225 
226  template<class C, class V> inline polynomial<C,V>
227  sr_gcd (const polynomial<C,V> & p, const polynomial<C,V> & q) {
229  }
230 }// namespace mmx
231 #endif //subdivix_subresultant_hpp
polynomial< C, V > sr_gcd(const polynomial< C, V > &p, const polynomial< C, V > &q)
Definition: subresultant.hpp:227
Sequence of terms with reference counter.
Definition: Seq.hpp:28
void resize(size_type i)
Definition: Seq.hpp:169
T pow(const T &a, int i)
Definition: binomials.hpp:12
const C & b
Definition: Interval_glue.hpp:25
dynamic_exp< E >::degree_t degree(const dynamic_exp< E > &t)
Definition: dynamicexp.hpp:191
void shift(IntervalData< RT, Poly > &ID, const RT &a)
Definition: contfrac_intervaldata.hpp:257
static Polynomial prem(const Polynomial &a, const Polynomial &b)
Definition: subresultant.hpp:32
double gcd(const double &, const double &)
Definition: GMP.hpp:90
static void pseudo_div(R &q, R &a, const R &b)
Definition: subresultant.hpp:11
#define Monomial
Definition: monomial.hpp:56
static Polynomial pquo(const Polynomial &a, const Polynomial &b)
Definition: subresultant.hpp:40
TMPL int N(const MONOMIAL &v)
Definition: monomial_glue.hpp:60
Definition: subresultant.hpp:52
polynomial< COEFF, with< MonomialTensor > > Polynomial
Definition: solver_mv_cf.cpp:23
size_type size() const
Definition: Seq.hpp:166
#define min(a, b)
Definition: parser_def.c:475
Definition: polynomial.hpp:37
Definition: subresultant.hpp:7
static Pol resultant(const Pol &p, const Pol &q, int v)
Definition: subresultant.hpp:140
Polynomial P
Definition: solver_mv_cf.cpp:24
static Seq< Pol > sequence(const Pol &p, const Pol &q)
Definition: subresultant.hpp:55
const C & c
Definition: Interval_glue.hpp:45
static Polynomial subres_gcd(const Polynomial &p, const Polynomial &q, int v)
Definition: subresultant.hpp:154
static Polynomial subres_gcd(const Polynomial &p, const Polynomial &q)
Definition: subresultant.hpp:220
double C
Definition: solver_mv_fatarcs.cpp:16
TMPL Polynomial::Scalar content(const Polynomial &p)
Definition: polynomial_fcts.hpp:240
TMPL int nbvar(const Polynomial &mp)
Definition: polynomial_fcts.hpp:43
static Pol::value_type resultant(const Pol &p, const Pol &q)
Definition: subresultant.hpp:132
static Seq< Seq< Polynomial > > sequence(const Polynomial &p, const Polynomial &q, int v)
Definition: subresultant.hpp:107
Interval< T, r > max(const Interval< T, r > &a, const Interval< T, r > &b)
Definition: Interval_fcts.hpp:135
Definition: array.hpp:12
TMPL Seq< typename ring< C, Bernstein >::Polynomial > coefficients(const typename ring< C, Bernstein >::Polynomial &pol, int v)
Definition: polynomial_bernstein.hpp:74
static bool is_zero_seq(const Seq< Pol > &s)
Definition: subresultant.hpp:147
#define assert(expr, msg)
Definition: shared_object.hpp:57
Home