All Classes Functions Friends
ring.h
1 #ifndef _RING_H_
2 #define _RING_H_
3 
4 #include "global.h"
5 
6 class Integer;
7 class RationalNumber;
11 template <class Ring>
13 
14 class BPASRing {
15  public:
16  static int characteristic;
17  virtual bool isZero() = 0;
18  virtual void zero() = 0;
19  virtual bool isOne() = 0;
20  virtual void one() = 0;
21  virtual bool isNegativeOne() = 0;
22  virtual void negativeOne() = 0;
23  virtual int isConstant() = 0;
24  static bool isPrimeField;
25  static bool isComplexField;
26 };
27 
28 class BPASField : public BPASRing {
29  public:
30  BPASField & operator= (BPASField&);
31  BPASField& operator+ (BPASField&);
32  BPASField& operator+= (BPASField&);
33  BPASField& operator- (BPASField&);
34  BPASField& operator- ();
35  BPASField& operator-= (BPASField&);
36  BPASField& operator* (BPASField&);
37  BPASField& operator*= (BPASField&);
38  BPASField& operator/ (BPASField&);
39  BPASField& operator/= (BPASField&);
40  BPASField& inverse();
41  BPASField& operator^ (int);
42  bool operator== (BPASField&);
43  bool operator!= (BPASField&);
44  friend std::ostream& operator<< (std::ostream&, BPASField&);
45 };
46 
47 
48 class Integer : public mpz_class, public BPASRing {
49  public:
50  static int characteristic;
51  static bool isPrimeField;
52  static bool isComplexField;
53  Integer () { *this = 0; }
54  Integer (int a) {
55  *this = mpz_class(a);
56  }
57  Integer (mpz_class a) {
58  *this = a;
59  }
60  Integer (const Integer& a) {
61  *this = mpz_class(a.get_mpz_t());
62  }
63 
71  template <class Ring>
73  using mpz_class::operator=;
74  Integer& operator= (const Integer& a) {
75  if (this != &a)
76  *this = mpz_class(a.get_mpz_t());
77  return *this;
78  }
79 
80  inline mpz_class get_mpz () {
81  return mpz_class(get_mpz_t());
82  }
83 
84  /**
85  * Is a zero
86  *
87  * @param
88  **/
89  inline bool isZero() {
90  return (*this == 0);
91  }
92  /**
93  * Assign to zero
94  *
95  * @param
96  **/
97  inline void zero() {
98  *this = 0;
99  }
100  /**
101  * Is a 1
102  *
103  * @param
104  **/
105  inline bool isOne() {
106  return (*this == 1);
107  }
108  /**
109  * Assign to one
110  *
111  * @param
112  **/
113  inline void one() {
114  *this = 1;
115  }
116  /**
117  * Is a -1
118  *
119  * @param
120  **/
121  inline bool isNegativeOne() {
122  return (*this == -1);
123  }
124  /**
125  * Assign to negative one
126  *
127  * @param
128  **/
129  inline void negativeOne() {
130  *this = -1;
131  }
132  /**
133  * Is a constant
134  *
135  * @param
136  **/
137  inline int isConstant() {
138  if (*this >= 0)
139  return 1;
140  else { return -1; }
141  }
142 
143  /**
144  * GCD (a, b)
145  *
146  * @param b: The other integer
147  **/
148  inline Integer gcd (Integer b) {
149  Integer c;
150  mpz_gcd(c.get_mpz_t(), this->get_mpz_t(), b.get_mpz_t());
151  return c;
152  }
153  /**
154  * Overload operator ^
155  * replace xor operation by exponentiation
156  *
157  * @param e: The exponentiation
158  **/
159  inline Integer operator^ (int e) {
160  Integer r;
161  mpz_pow_ui(r.get_mpz_t(), this->get_mpz_t(), (unsigned long int) e);
162  return r;
163  }
164 };
165 
166 class RationalNumber : public mpq_class, public BPASRing {
167  public:
168  static int characteristic;
169  static bool isPrimeField;
170  static bool isComplexField;
171  RationalNumber () { *this = 0; }
172  RationalNumber (mpq_class a) {
173  *this = a;
174  }
175  RationalNumber (const RationalNumber& a) {
176  *this = mpq_class(a.get_mpq_t());
177  }
185  template <class Ring>
187 
188  RationalNumber (int a, int b) {
189  *this = a;
190  *this /= b;
191  }
192  RationalNumber& set (int a, int b) {
193  *this = a;
194  *this /= b;
195  return *this;
196  }
197  using mpq_class::operator=;
198  RationalNumber& operator= (const RationalNumber& a) {
199  if (this != &a)
200  *this = mpq_class(a.get_mpq_t());
201  return *this;
202  }
203 
204  /**
205  * Is a zero
206  *
207  * @param
208  **/
209  inline bool isZero() {
210  return (*this == 0);
211  }
212  /**
213  * Assign to zero
214  *
215  * @param
216  **/
217  inline void zero() {
218  *this = 0;
219  }
220  /**
221  * Is a 1
222  *
223  * @param
224  **/
225  inline bool isOne() {
226  return (*this == 1);
227  }
228  /**
229  * Assign to one
230  *
231  * @param
232  **/
233  inline void one() {
234  *this = 1;
235  }
236  /**
237  * Is a -1
238  *
239  * @param
240  **/
241  inline bool isNegativeOne() {
242  return (*this == -1);
243  }
244  /**
245  * Assign to negative one
246  *
247  * @param
248  **/
249  inline void negativeOne() {
250  *this = -1;
251  }
252  /**
253  * Is a constant
254  *
255  * @param
256  **/
257  inline int isConstant() {
258  if (*this >= 0)
259  return 1;
260  else { return -1; }
261  }
262  /**
263  * GCD(a, b)
264  *
265  * @param b: The other rational number
266  **/
268  RationalNumber c;
269  if (*this == 0 && b == 0)
270  c = 0;
271  else
272  c = 1;
273  return c;
274  }
275  /**
276  * Overload operator ^
277  * replace xor operation by exponentiation
278  *
279  * @param e: The exponentiation
280  **/
281  inline RationalNumber operator^ (int e) {
282  RationalNumber r;
283  mpz_pow_ui(r.get_num_mpz_t(), this->get_num_mpz_t(), (unsigned long int) e);
284  mpz_pow_ui(r.get_den_mpz_t(), this->get_den_mpz_t(), (unsigned long int) e);
285  return r;
286  }
287 
288 };
289 
291  private:
292  // a + i * b
293  mpq_class a;
294  mpq_class b;
295  public:
296  static int characteristic;
297  static bool isPrimeField;
298  static bool isComplexField;
299  ComplexRationalNumber () : a(0), b(0) {}
300  ComplexRationalNumber (mpq_class _a, mpq_class _b) {
301  a = _a;
302  b = _b;
303  }
305  a = c.a;
306  b = c.b;
307  }
315  template <class Ring>
318  if (this != &c) {
319  a = c.a;
320  b = c.b;
321  }
322  return *this;
323  }
324  ComplexRationalNumber& operator= (mpq_class k) {
325  a = k;
326  b = 0;
327  return *this;
328  }
329  ComplexRationalNumber& operator= (int k) {
330  a = k;
331  b = 0;
332  return *this;
333  }
334  ComplexRationalNumber& setRealPart (mpq_class k) {
335  a = k;
336  return *this;
337  }
338  ComplexRationalNumber& setRealPart (int k) {
339  a = k;
340  return *this;
341  }
342  ComplexRationalNumber& setImaginaryPart (mpq_class k) {
343  b = k;
344  return *this;
345  }
346  ComplexRationalNumber& setImaginaryPart (int k) {
347  b = k;
348  return *this;
349  }
350  ComplexRationalNumber& set (mpq_class ka, mpq_class kb) {
351  a = ka;
352  b = kb;
353  return *this;
354  }
355  ComplexRationalNumber& set (mpq_class ka, int kb) {
356  a = ka;
357  b = kb;
358  return *this;
359  }
360  ComplexRationalNumber& set (int ka, mpq_class kb) {
361  a = ka;
362  b = kb;
363  return *this;
364  }
365  ComplexRationalNumber& set (int ka, int kb) {
366  a = ka;
367  b = kb;
368  return *this;
369  }
370 
371  /**
372  * Is a zero
373  *
374  * @param
375  **/
376  inline bool isZero() {
377  return (a == 0 && b == 0);
378  }
379  /**
380  * Assign to zero
381  *
382  * @param
383  **/
384  inline void zero() {
385  a = 0;
386  b = 0;
387  }
388  /**
389  * Is a 1
390  *
391  * @param
392  **/
393  inline bool isOne() {
394  return (a == 1 && b == 0);
395  }
396  /**
397  * Assign to one
398  *
399  * @param
400  **/
401  inline void one() {
402  a = 1;
403  b = 0;
404  }
405  /**
406  * Is a -1
407  *
408  * @param
409  **/
410  inline bool isNegativeOne() {
411  return (a == -1 && b == 0);
412  }
413  /**
414  * Assign to negative one
415  *
416  * @param
417  **/
418  inline void negativeOne() {
419  a = -1;
420  b = 0;
421  }
422  /**
423  * Is a constant
424  *
425  * @param
426  **/
427  inline int isConstant() {
428  if (a >= 0)
429  return 1;
430  else { return -1; }
431  }
432  /**
433  * GCD(a, b)
434  *
435  * @param b: The other rational number
436  **/
439  if (isZero() && c.isZero())
440  e.zero();
441  else
442  e.one();
443  return e;
444  }
445 
446  inline bool operator== (ComplexRationalNumber& c) {
447  if (a == c.a && b == c.b)
448  return 1;
449  else { return 0; }
450  }
451 
452  inline bool operator== (mpq_class k) {
453  if (a == k && b == 0)
454  return 1;
455  else { return 0; }
456  }
457 
458  inline bool operator== (int k) {
459  if (a == k && b == 0)
460  return 1;
461  else { return 0; }
462  }
463  inline bool operator!= (ComplexRationalNumber& c) {
464  if (a == c.a && b == c.b)
465  return 0;
466  else { return 1; }
467  }
468  inline bool operator!= (mpq_class k) {
469  if (a == k && b == 0)
470  return 1;
471  else { return 0; }
472  }
473  inline bool operator!= (int k) {
474  if (a == k && b == 0)
475  return 1;
476  else { return 0; }
477  }
478 
479  inline ComplexRationalNumber operator+ (ComplexRationalNumber& c) {
480  ComplexRationalNumber r (*this);
481  return (r += c);
482  }
483  inline ComplexRationalNumber& operator+= (ComplexRationalNumber c) {
484  a += c.a;
485  b += c.b;
486  return *this;
487  }
488 
489  inline ComplexRationalNumber operator- (ComplexRationalNumber& c) {
490  ComplexRationalNumber r (*this);
491  return (r -= c);
492  }
493  inline ComplexRationalNumber& operator-= (ComplexRationalNumber c) {
494  a -= c.a;
495  b -= c.b;
496  return *this;
497  }
498 
499  inline ComplexRationalNumber operator- () {
500  ComplexRationalNumber r (-a, -b);
501  return r;
502  }
503  inline ComplexRationalNumber operator* (ComplexRationalNumber& c) {
504  ComplexRationalNumber r (*this);
505  return (r *= c);
506  }
507  inline ComplexRationalNumber& operator*= (ComplexRationalNumber c) {
508  mpq_class t = a*c.a - b*c.b;
509  mpq_class e = a*c.b + c.a*b;
510  a = t;
511  b = e;
512  return *this;
513  }
514  inline ComplexRationalNumber& operator*= (mpq_class c) {
515  a *= c;
516  b *= c;
517  return *this;
518  }
519  inline ComplexRationalNumber& operator*= (int c) {
520  a *= c;
521  b *= c;
522  return *this;
523  }
524  inline ComplexRationalNumber operator/ (ComplexRationalNumber& c) {
525  ComplexRationalNumber r (*this);
526  return (r /= c);
527  }
528  inline ComplexRationalNumber& operator/= (ComplexRationalNumber c) {
529  if (c.isZero()) {
530  std::cout << "BPAS: error, dividend is zero from ComplexRationalNumber."<< std::endl;
531  exit(1);
532  }
533  mpq_class r = c.a*c.a + c.b*c.b;
534  mpq_class t = (a*c.a+b*c.b)/r;
535  mpq_class e = (b*c.a-c.b*a)/r;
536  a = t;
537  b = e;
538  return *this;
539  }
540 
541  /**
542  * Overload operator ^
543  * replace xor operation by exponentiation
544  *
545  * @param e: The exponentiation
546  **/
549  if (isZero() || isOne() || e == 1)
550  r = *this;
551  else if (e == 2) {
552  r = *this * *this;
553  }
554  else if (e > 2) {
555  ComplexRationalNumber x (*this);
556  r.one();
557 
558  while (e != 0) {
559  if (e % 2)
560  r *= x;
561  x = x * x;
562  e >>= 1;
563  }
564  }
565  else if (e == 0) {
566  r.one();
567  }
568  else {
569  r = *this ^ (-e);
570  r.inverse();
571  }
572  return r;
573  }
574 
575  inline ComplexRationalNumber inverse() {
577  mpq_class e = a * a + b * b;
578  r.a = a/e;
579  r.b = -b/e;
580  return r;
581  }
582 
583  inline mpq_class realPart() {
584  return a;
585  }
586  inline mpq_class imaginaryPart() {
587  return b;
588  }
589  inline ComplexRationalNumber conjugate() {
590  ComplexRationalNumber r(a, -b);
591  return r;
592  }
593 
594  /**
595  * Overload stream operator <<
596  *
597  * @param out: Stream object
598  * @param b: The univariate polynomial
599  **/
600  inline friend std::ostream& operator<< (std::ostream &out, ComplexRationalNumber c){
601  if (c.b == 0) {
602  out << c.a;
603  }
604  else if (c.a == 0) {
605  if (abs(c.b) == 1) {
606  if (c.b == 1)
607  out << "I";
608  else
609  out << "-I";
610  }
611  else {
612  if (c.b < 0)
613  out << "-I*" << abs(c.b);
614  else
615  out << "I*" << c.b;
616  }
617  }
618  else {
619  out << "(" << c.a;
620  if (abs(c.b) == 1) {
621  if (c.b == 1)
622  out << "+I";
623  else
624  out << "-I";
625  }
626  else {
627  if (c.b < 0)
628  out << "-I*" << abs(c.b);
629  else
630  out << "+I*" << c.b;
631  }
632  out << ")";
633  }
634  return out;
635  }
636 };
637 
638 
639 #endif
640 /* This file is part of the BPAS library http://www.bpaslib.org
641 
642  BPAS is free software: you can redistribute it and/or modify
643  it under the terms of the GNU General Public License as published by
644  the Free Software Foundation, either version 3 of the License, or
645  (at your option) any later version.
646 
647  BPAS is distributed in the hope that it will be useful,
648  but WITHOUT ANY WARRANTY; without even the implied warranty of
649  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
650  GNU General Public License for more details.
651 
652  You should have received a copy of the GNU General Public License
653  along with BPAS. If not, see <http://www.gnu.org/licenses/>.
654 
655  Copyright: Changbo Chen <changbo.chen@hotmail.com>
656  Farnam Mansouri <mansouri.farnam@gmail.com>
657  Marc Moreno Maza <moreno@csd.uwo.ca>
658  Ning Xie <nxie6@csd.uwo.ca>
659  Yuzhen Xie <yuzhenxie@yahoo.ca>
660 
661 */
662 
663 
Definition: ring.h:14
Definition: upolynomial.h:10
void negativeOne()
Definition: ring.h:129
bool isNegativeOne()
Definition: ring.h:410
RationalNumber operator^(int e)
Definition: ring.h:281
void negativeOne()
Definition: ring.h:249
void zero()
Definition: ring.h:217
Definition: ring.h:290
ComplexRationalNumber gcd(ComplexRationalNumber c)
Definition: ring.h:437
RationalNumber gcd(RationalNumber b)
Definition: ring.h:267
void one()
Definition: ring.h:233
bool isNegativeOne()
Definition: ring.h:241
friend std::ostream & operator<<(std::ostream &out, ComplexRationalNumber c)
Definition: ring.h:600
Integer operator^(int e)
Definition: ring.h:159
void zero()
Definition: ring.h:384
Definition: uzpolynomial.h:12
bool isOne()
Definition: ring.h:393
void negativeOne()
Definition: ring.h:418
int isConstant()
Definition: ring.h:257
Definition: urpolynomial.h:16
bool isNegativeOne()
Definition: ring.h:121
int isConstant()
Definition: ring.h:137
int isConstant()
Definition: ring.h:427
Definition: ring.h:48
bool isZero()
Definition: ring.h:209
bool isZero()
Definition: ring.h:89
bool isOne()
Definition: ring.h:225
ComplexRationalNumber operator^(int e)
Definition: ring.h:547
Definition: ring.h:166
bool isOne()
Definition: ring.h:105
Definition: ring.h:28
void zero()
Definition: ring.h:97
void one()
Definition: ring.h:113
Integer gcd(Integer b)
Definition: ring.h:148
bool isZero()
Definition: ring.h:376
void one()
Definition: ring.h:401