Developer documentation

monomial.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 $Id: monomial.hpp,v 1.1 2005/07/11 11:17:56 mourrain Exp $
6 **********************************************************************/
7 #ifndef realroot_monomial_hpp
8 #define realroot_monomial_hpp
9 //======================================================================
42 //======================================================================
43 #include <assert.h>
44 #include <map>
45 #include <string>
46 #include <cstring>
48 #include <realroot/parser.hpp>
49 #include <realroot/array.hpp>
50 #include <realroot/dynamicexp.hpp>
51 #include <realroot/variables.hpp>
52 #include <realroot/print.hpp>
53 //======================================================================
54 
55 #define TMPL template<class C, class E>
56 #define Monomial monom<C,E>
57 
58 namespace mmx {
59 
61 template <class C, class E=dynamic_exp<int> >
62 struct monom {
63 
64  //data
66 #ifdef SHARED_MONOM
68  E & rep() {return (*_expt);}
69  const E & rep() const {return (*_expt);}
70  typedef shared_object<E> exp_t;
71 #else
72  E _expt;
73  E & rep() {return (_expt);}
74  const E & rep() const {return (_expt);}
75  typedef E exp_t;
76 #endif
77 
78  static variables var;
79 
80  // Type definitions
81  typedef int index_t;
82  typedef E container_t;
83  typedef typename E::exponent_t exponent_t;
84  //typename E::coeff_t exponent_t;
85  typedef typename E::size_type size_type;
86  typedef C coeff_t;
87  typedef C Scalar;
88  typedef Monomial self_t;
89 
90  // Constructors
91  monom(): _coef(),_expt() {
92  rep().resize(0); //COUNT<self_t>(' ');
93  }
94 
95  monom(const C & c, const exp_t & r):_coef(c), _expt(r){}
96  monom(const C & c): _coef(c),_expt() {
97  rep().resize(0);
98  }
99  monom(int i):_coef(i), _expt() {
100  rep().resize(0);
101  }
103  monom(const std::string & s, int d, const variables& vars);
104  monom(const C & c, unsigned s, const AsSize & ):_coef(c),_expt(s){}
105 
107  monom(const C & c, int d, unsigned i);
108  monom(const C & c, int s, int *t):_coef(c), _expt(s){
109  for(int i=0;i<s;i++) rep()[i]= t[i];
110  }
111  monom(const char *, variables& vars = monom::var);
112 
113  //Copy constructor
114  monom(const monom & m):_coef(m._coef),_expt(m._expt) {}
115 
116  // Destructor
117  // no dynamic allocation at this level
118 
119  // Assignement
120  self_t & operator = (const self_t & m)
121  {
122  _coef = m.coeff();
123  _expt = m._expt;
124  return *this;
125  };
126 
127  // Accessors
128  const C & coeff () const { return _coef; }
129  C& coeff () { return _coef; }
130  void set_coeff (const C & c){ _coef = c; }
131 
132  int* begin() { return rep().begin(); }
133  int* begin() const { return rep().begin(); }
134 
135  unsigned size() const { return rep().size(); }
136  int nvars() const { return lvar(rep()); }
137  int l_variable() const { return lvar(rep()); }
138  unsigned nbvar() const { return lvar(rep())+1; }
139 
140  exponent_t operator[] (size_type i) const { return rep()[i]; }
141  exponent_t expt (size_type i) const { return rep()[i]; }
142  exponent_t exponent (size_type i) const { return rep()[i]; }
143 
144  self_t & set_expt (size_type i, exponent_t d)
145  {rep().set_expt(i,d);return *this; }
146 
147  // boolean operators and functions
148  bool operator==(int n) const;
149  bool operator!=(int n) const {return !(*this==n);}
150 
151 
152  friend bool operator == (const self_t & m1, const self_t & m2)
153  {
154  return m1._coef == m2._coef && m1.rep() == m2.rep();
155  }
156 
157  friend bool operator != (const self_t & m1, const self_t & m2)
158  {
159  return !(m1 == m2);
160  }
161 
162  friend bool IsComparable (const self_t & m1, const self_t & m2)
163  {
164  return m1.rep() == m2.rep();
165  }
166 
167  // Arithmetic operators
168  self_t operator - () const {return self_t(-_coef,rep());}
169  self_t & operator += (const self_t &);
170  self_t & operator -= (const self_t &);
171  self_t & operator *= (const self_t &);
172  self_t & operator *= (const C &);
173  self_t & operator /= (const C &);
174 
175 };
176 
177 //======================================================================
178 template<class C,class E> variables Monomial::var;
179 //----------------------------------------------------------------------//
180 // template<class R,class O> unsigned Monomial::_number_var=1;
181 // template<class R,class O> std::map<std::string,int> Monomial::_index_of_var;
182 // template<class R,class O> std::map<int,std::string> Monomial::_var_of_index;
183 //----------------------------------------------------------------------//
184 namespace let
185 {
186 TMPL inline void
187 assign( C & r, const Monomial& m ) { r = m.coeff(); };
188 // TMPL inline const C&
189 // convert( const Monomial & m, const meta::As<C>& ) { return m.coeff(); };
190 };
191 //----------------------------------------------------------------------//
192 //#define MONOM Monomial
193 // declare_binary_operator(TMPL,MONOM,MONOM,meta::_mul_,operator*);
194 // declare_binary_operator(TMPL,MONOM,MONOM,meta::_div_,operator/);
195 //#undef MONOM
196 TMPL inline Monomial
197 operator* (const Monomial& m1, const Monomial& m2) {
198  Monomial r; mul(r,m1,m2); return r;
199 }
200 
201 TMPL inline Monomial
202 operator/ (const Monomial& m1, const Monomial& m2) {
203  Monomial r; div(r,m1,m2); return r;
204 }
205 
206 TMPL inline bool
207 divide(const Monomial& m1, const Monomial& m2, Monomial& r) {
208  div(r,m1,m2);
209  for (int i = 0; i <= r.nvars(); ++i)
210  if(r[i]<0) return false;
211  return true;
212 }
213 //----------------------------------------------------------------------//
214 TMPL inline void
215 mul(Monomial & a, const Monomial& m1, const Monomial& m2) {
216  a.coeff() = (m1.coeff()*m2.coeff());
217  if (a.coeff() !=(typename Monomial::Scalar)0)
218  {
219  a.rep().reserve(std::max(m1.rep().size(),m2.rep().size()));
220  array::add(a.rep(),m1.rep(),m2.rep());
221  }
222  else
223  {
224  erase(a.rep());
225  }
226 }
227 //----------------------------------------------------------------------//
228 TMPL inline void
229 div(Monomial & a, const Monomial& m1, const Monomial& m2) {
230  a.coeff() = (m1.coeff()/m2.coeff());
231  if (a.coeff() !=0)
232  {
233  a.rep().reserve(std::max(m1.rep().size(),m2.rep().size()));
234  array::sub(a.rep(),m1.rep(),m2.rep());
235  }
236  else
237  {
238  erase(a.rep());
239  }
240 }
241 //----------------------------------------------------------------------
242 TMPL inline Monomial
243 div(const Monomial & m1, const Monomial & m2) {
244  Monomial res(1); res*=(m1.coeff()/m2.coeff());
245  for (int i = 0; i <= m1.nvars(); ++i)
246  res.set_expt(i,m1[i] - m2[i]);
247  return res;
248 }
249 //----------------------------------------------------------------------
250 TMPL inline Monomial
251 div_quo(const Monomial & m1, const Monomial & m2) {
252  Monomial res(1); res*=(m1.coeff()/m2.coeff());
253  for (int i = 0; i <= m1.nvars(); ++i)
254  res.set_expt(i,m1[i] - m2[i]);
255  return res;
256 }
257 //----------------------------------------------------------------------
258 template <class C, class E> inline
259 typename E::degree_t degree(const Monomial & m) {
260  return degree(m.rep());
261 }
262 //----------------------------------------------------------------------//
264 MGcd(const Monomial & m1, const Monomial & m2) {
265  int d = Gcd(m1.coeff(),m2.coeff());
266  Monomial res(d);
267  int v = Min(m1.nvars(),m2.nvars());
268  for (int i = 0; i <= v; ++i)
269  res.set_expt(i, Min(m1[i],m2[i]));
270  return res;
271 }
272 
273 
274 TMPL inline Monomial
275 pow(const Monomial& m1, int n) {
276  Monomial res(m1);
277  for (int i = 0; i <= m1.nvars(); ++i)
278  res.set_expt(i,m1[i]*n);
279  return res;
280 }
281 //----------------------------------------------------------------------
283 template <class C, class E>
284 Monomial::monom(const std::string & s, int d,
285  const variables& vars ):_coef(1) {
286  if(d == 0)
287  rep().resize(0);
288  else
289  {
290  int i=vars[s];
291  rep().reserve(i+1);
292  for(int j=0;j<i;j++) rep().set_expt(j,0);
293  rep().set_expt(i,d);
294  }
295 }
296 //----------------------------------------------------------------------
298 template <class C, class E>
299 Monomial::monom(const C & c, int d, unsigned v):_coef(c) {
300  if(d == 0)
301  rep().resize(0);
302  else
303  {
304  rep().reserve(v+1);
305  for(unsigned j=0;j<v;j++) rep().set_expt(j,0);
306  rep().set_expt(v,d);
307  }
308 }
309 //----------------------------------------------------------------------
310 extern "C" char *synaps_inputptr;
311 template <class C, class E>
312 Monomial::monom(const char * s, variables& vars ) {
313  int n = strlen(s);
314  if (s[n-1]=='\n') {n--;}
315  if(s[n-1]==';')
316  {
317  synaps_input = new char[n+1];
318  memcpy(synaps_input,s,n); synaps_input[n]='\0';
320  }
321  else
322  {
323  synaps_input = new char[n+2];
324  memcpy(synaps_input,s,n);
325  synaps_input[n]=';'; synaps_input[n+1]='\0';
327  }
328  synaps_inputptr=synaps_input;
329  *this = Monomial((C)1);
330  int Ask;
331 
332  for (;;) {
333  Ask = yylex();
334  if (Ask == COEF) { /* monome constant */
335  C c;
336  let::assign(c,yylval);
337  free(yylval);
338  *this *= c;
339  }
340  else if (Ask == XID) {
341  char* p = strchr(yylval,'^');
342  if (p == NULL)
343  {
344  *this *= Monomial(vars[std::string(yylval)],1);
345  }
346  else {
347  p++;
348  *this *= Monomial(vars[std::string(yylval,p-1)], atoi(p));
349  }
350  free(yylval);
351  }
352  else if (Ask == TERMINATE) {
353  break;
354  }
355  }
356  delete[] synaps_input;
357 }
358 //----------------------------------------------------------------------
359 template <class C, class E> inline bool
360 Monomial::operator== (int n) const {
361  return (coeff()==n);
362 }
363 //----------------------------------------------------------------------
364 // arithemtic operators
365 //----------------------------------------------------------------------
366 template <class C, class E> inline Monomial &
367 Monomial::operator += (const Monomial & m) {
368  coeff() += m.coeff();
369  if (coeff()==0) erase(rep());
370  return *this;
371 }
372 
373 template <class C, class E> inline Monomial &
374 Monomial::operator -= (const Monomial & m) {
375  coeff() -= m.coeff();
376  if (coeff()==0) erase(rep());
377  return *this;
378 }
379 
380 template <class C, class E> inline Monomial
381 operator + (const Monomial & m1, const Monomial & m2) {
382  Monomial res(m1);
383  res.coeff() += m2.coeff();
384  return (*res);
385 }
386 
387 template <class C, class E> inline Monomial
388 operator - (const Monomial & m1, const Monomial & m2) {
389  Monomial res(m1);
390  res.coeff() -= m2.coeff();
391  return (res);
392 }
393 
394 template <class C, class E> inline Monomial &
395 Monomial::operator *= (const Monomial & m) {
396  coeff() *= m.coeff();
397  if (coeff()!=0)
398  array::add(rep(),m.rep());
399  else
400  erase(rep());
401  return *this;
402 }
403 
404 template <class C, class E> inline Monomial &
405 Monomial::operator *= (const C & c) {
406  coeff() *= c;
407  if (coeff()==0) erase(rep());
408  return *this;
409 }
410 
411 template <class C, class E> inline Monomial &
412 Monomial::operator /= (const C & c) {
413  assert(c !=0);
414  coeff() /= c;
415  if (coeff()==0) erase(rep());
416  return *this;
417 }
418 
419 template <class C, class E> inline Monomial
420 operator * (const Monomial & m1, const C & c2) {
421  Monomial res(m1);
422  res.coeff() *= c2;
423  if (res.coeff() ==0) erase(res.rep());
424  return (res);
425 }
426 template <class C, class E> inline Monomial
427 operator * (const C & c2, const Monomial & m1) {
428  return(m1*c2);
429 }
430 
431 template <class C, class E> inline Monomial
432 operator / (const Monomial & m1, const C & c2) {
433  Monomial res(m1);
434  res.coeff() /= c2;
435  if (res.coeff() ==0) erase(res.rep());
436  return (res);
437 }
438 
439 
440 //----------------------------------------------------------------------
441 // operateurs d'entrees/sorties
442 //----------------------------------------------------------------------
443 inline bool is_polynomial(const std::ostringstream& sm){
444  for(unsigned i=1; i<sm.str().length();i++)
445  if(sm.str()[i]=='+' || (sm.str()[i]=='-' && (i>0 && sm.str()[i-1]=='e'))) return true;
446  return false;
447 }
448 
449 
450 template <class OSTREAM, class C, class E> inline OSTREAM &
451 print (OSTREAM & os, const Monomial & m,
452  const variables& V) {
453  if (m.coeff() == C(0) )
454  os<<"0";
455  else {
456  int i=m.nvars();
457  while(i> -1 && m[i]==0) i--;
458  if(i<0)
459  print(os,m.coeff());
460  else {
461  if(m.coeff() != (C)1) {
462  if(m.coeff()==(C)-1)
463  { os << "-"; }
464  else
465  {
466  std::ostringstream sm;
467  print(sm,m.coeff());
468  bool is_pol = is_polynomial(sm);
469  if (is_pol) os <<"+(";
470  os<<sm.str();
471  if (is_pol) os <<")";
472  os <<"*";
473  }
474  }
475  //print_pp(os,m,V);
476  }
477  }
478  return os;
479 }
480 
481 //--------------------------------------------------------------------
482 template <class C, class E> std::string
483 to_string_pp (const Monomial & m, const variables& V) {
484  std::string s;
485  bool first=true;
486  for (unsigned i = 0; i < (unsigned)m.rep().size(); i++) {
487  if (m[i] !=0) {
488  if(first) {
489  first =false;
490  } else {
491  s+="*";
492  }
493  //s += "x"; s+= to_string(i);
494  //std::cout<<":: "<<i<<" "<< V[i]<<std::endl;
495  s += V[i];
496 
497  if (m[i] != 1) {
498  s+= "^";
499  s+= to_string(m[i]);
500  }
501  }
502  }
503  return s;
504 }
505 //--------------------------------------------------------------------
506 template <class C, class E> inline std::string
507 to_string (const Monomial& m, const variables& V) {
508  std::string s;
509  if (m.coeff() == C(0) )
510  s+="0";
511  else {
512  int i=m.nvars();
513  while(i> -1 && m[i]==0) i--;
514  if(i<0)
515  s += to_string(m.coeff());
516  else {
517  if(m.coeff() != (C)1) {
518  if(m.coeff()==(C)-1)
519  { s += "-"; }
520  else
521  {
522  std::string sm;
523  sm = to_string(m.coeff());
524  //bool is_pol = is_polynomial(sm);
525  //if (is_pol)
526  //s +="+(";
527  s+=sm;
528  //if (is_pol)
529  //s +=")";
530  s +="*";
531  }
532  }
533  s += to_string_pp(m,V);
534  }
535  }
536  return s;
537 }
538 
539 
540 template <class OSTREAM, class C, class E> inline OSTREAM &
541 print_as_double (OSTREAM & os, const Monomial & m,
542  const variables& V) {
543  if (m.coeff() == C(0) )
544  os<<"0";
545  else {
546  int i=m.nvars();
547  while(i> -1 && m[i]==0) i--;
548  if(i<0)
549  print(os,as_double(m.coeff()));
550  else {
551  if(m.coeff() != (C)1) {
552  if(m.coeff()==(C)-1)
553  { os << "-"; }
554  else
555  {
556  std::ostringstream sm;
557  print(sm,as_double(m.coeff()));
558  bool is_pol = is_polynomial(sm);
559  if (is_pol) os <<"+(";
560  os<<sm.str();
561  if (is_pol) os <<")";
562  os <<"*";
563  }
564  }
565  print_pp(os,m,V);
566  }
567  }
568  return os;
569 }
570 
571 
572 
573 
575 template <class C, class E> inline
576 std::ostream & operator << (std::ostream & os, const monom <C,E> & m)
577 {
578  if (m.coeff() ==0 ) os<<"(0)";
579  else
580  print(os,m,variables());
581 
582  return os;
583 }
584 
585 //--------------------------------------------------------------------
586 } // namespace mmx
587 //======================================================================
588 #undef TMPL
589 #undef Monomial
590 #endif // realroot_monom_hpp
591 
extended< NT > & operator+=(extended< NT > &x, const extended< NT > &other)
Definition: extended.hpp:158
bool operator==(const extended< NT > &lhs, const extended< NT > &rhs)
Definition: extended.hpp:88
C Scalar
Definition: monomial.hpp:87
int lvar(const dynamic_exp< E > &A)
Definition: dynamicexp.hpp:262
T pow(const T &a, int i)
Definition: binomials.hpp:12
OSTREAM & print(OSTREAM &os, const Monomial &m, const variables &V)
Definition: monomial.hpp:451
std::string to_string_pp(const Monomial &m, const variables &V)
Definition: monomial.hpp:483
dynamic_exp< E >::degree_t degree(const dynamic_exp< E > &t)
Definition: dynamicexp.hpp:191
self_t & operator/=(const C &)
int yylex(void)
monom(const C &c, int s, int *t)
Definition: monomial.hpp:108
static variables var
Definition: monomial.hpp:78
monom(const C &c)
Definition: monomial.hpp:96
unsigned size() const
Definition: monomial.hpp:135
char * yylval
Definition: parser.hpp:31
E::exponent_t exponent_t
Definition: monomial.hpp:83
R & rep(R &r)
Definition: shared_object.hpp:180
extended< NT > operator/(const extended< NT > &lhs, const extended< NT > &rhs)
Definition: extended.hpp:111
int l_variable() const
Definition: monomial.hpp:137
self_t & set_expt(size_type i, exponent_t d)
Definition: monomial.hpp:144
#define Monomial
Definition: monomial.hpp:56
monom(const C &c, const exp_t &r)
Definition: monomial.hpp:95
self_t operator-() const
Definition: monomial.hpp:168
self_t & operator*=(const self_t &)
C coeff_t
Definition: monomial.hpp:86
self_t & operator=(const self_t &m)
Definition: monomial.hpp:120
#define COEF
Definition: parser.hpp:16
char * synaps_inputlim
Definition: parser.hpp:37
extended< NT > & operator/=(extended< NT > &x, const extended< NT > &other)
Definition: extended.hpp:179
bool is_polynomial(const std::ostringstream &sm)
Definition: monomial.hpp:443
void mul(Interval< C, r > &a, const C &x)
Definition: Interval_fcts.hpp:259
void set_coeff(const C &c)
Definition: monomial.hpp:130
self_t & operator-=(const self_t &)
Definition: shared_object.hpp:64
Monomial operator*(const C &c2, const Monomial &m1)
Definition: monomial.hpp:427
exponent_t exponent(size_type i) const
Definition: monomial.hpp:142
monom(const C &c, unsigned s, const AsSize &)
Definition: monomial.hpp:104
E _expt
Definition: monomial.hpp:72
char * synaps_input
Definition: parser.hpp:34
TMPL bool divide(const Monomial &m1, const Monomial &m2, Monomial &r)
Definition: monomial.hpp:207
E container_t
Definition: monomial.hpp:82
monom()
Definition: monomial.hpp:91
Monomial operator-(const Monomial &m1, const Monomial &m2)
Definition: monomial.hpp:388
TMPL Monomial div_quo(const Monomial &m1, const Monomial &m2)
Definition: monomial.hpp:251
Monomial operator/(const Monomial &m1, const C &c2)
Definition: monomial.hpp:432
extended< NT > & operator*=(extended< NT > &x, const extended< NT > &other)
Definition: extended.hpp:172
bool operator==(int n) const
monom(int i)
Definition: monomial.hpp:99
Definition: shared_object.hpp:61
monom(const monom &m)
Definition: monomial.hpp:114
friend bool IsComparable(const self_t &m1, const self_t &m2)
Definition: monomial.hpp:162
char * synaps_inputptr
Definition: monomial.hpp:310
Monomial operator+(const Monomial &m1, const Monomial &m2)
Definition: monomial.hpp:381
E exp_t
Definition: monomial.hpp:75
E & rep()
Definition: monomial.hpp:73
void sub(V &a, const W &b)
Substraction of two vectors.
Definition: array.hpp:221
int index_t
Definition: monomial.hpp:81
#define XID
Definition: parser.hpp:17
void add(V &a, const W &b)
Addition of two vectors.
Definition: array.hpp:154
exponent_t operator[](size_type i) const
Definition: monomial.hpp:140
int nvars() const
Definition: monomial.hpp:136
#define Scalar
Definition: polynomial_operators.hpp:12
const C & coeff() const
Definition: monomial.hpp:128
TMPL Monomial MGcd(const Monomial &m1, const Monomial &m2)
Definition: monomial.hpp:264
int * begin() const
Definition: monomial.hpp:133
std::string to_string(const Monomial &m, const variables &V)
Definition: monomial.hpp:507
const C & c
Definition: Interval_glue.hpp:45
#define TMPL
Definition: monomial.hpp:55
int * begin()
Definition: monomial.hpp:132
double C
Definition: solver_mv_fatarcs.cpp:16
Monomial self_t
Definition: monomial.hpp:88
OSTREAM & print_as_double(OSTREAM &os, const Monomial &m, const variables &V)
Definition: monomial.hpp:541
bool operator!=(int n) const
Definition: monomial.hpp:149
void assign(A &a, const B &b)
Generic definition of the assignement function.
Definition: assign.hpp:97
Monomial class.
Definition: monomial.hpp:62
const E & rep() const
Definition: monomial.hpp:74
E::size_type size_type
Definition: monomial.hpp:85
TMPL void assign(C &r, const Monomial &m)
Definition: monomial.hpp:187
C & coeff()
Definition: monomial.hpp:129
C _coef
Definition: monomial.hpp:65
exponent_t expt(size_type i) const
Definition: monomial.hpp:141
Interval< T, r > max(const Interval< T, r > &a, const Interval< T, r > &b)
Definition: Interval_fcts.hpp:135
Definition: array.hpp:12
void div(Interval< C, r > &a, const C &x)
Definition: Interval_fcts.hpp:430
Definition: variables.hpp:65
extended< NT > & operator-=(extended< NT > &x, const extended< NT > &other)
Definition: extended.hpp:165
extended< NT > operator*(const extended< NT > &lhs, const extended< NT > &rhs)
Definition: extended.hpp:101
unsigned nbvar() const
Definition: monomial.hpp:138
double as_double(const RR &a)
Definition: GMP.hpp:67
#define TERMINATE
Definition: parser.hpp:21
self_t & operator+=(const self_t &)
#define assert(expr, msg)
Definition: shared_object.hpp:57
void erase(dynamic_exp< E > &A)
Definition: dynamicexp.hpp:269
Home