Basic Polynomial Algebra Subprograms (BPAS)  v. 1.700
BigPrimeField.hpp
1 
2 #ifndef _BIG_PRIME_FIELD_H_
3 #define _BIG_PRIME_FIELD_H_
4 
5 #include "BPASFiniteField.hpp"
6 #include <iostream>
7 #include <string>
8 
9 using std::endl;
10 using std::cout;
11 
12 //forward declarations
13 class Integer;
14 class RationalNumber;
16 class SmallPrimeField;
20 template <class Ring>
22 
23 // prime field with big number, using GMP functions
24 /**
25  * A prime field whose prime can be arbitrarily large.
26  */
27 class BigPrimeField : public BPASFiniteField<BigPrimeField> {
28 
29 private:
30 
31  static mpz_class prime;
32  mpz_class a;
33 
34 public:
35 
36  static mpz_class characteristic;
37  static RingProperties properties;
38  // static bool isPrimeField;
39  // static bool isSmallPrimeField;
40  // static bool isComplexField;
41 
42  BigPrimeField ();
43 
44  BigPrimeField (mpz_class _a);
45 
46  BigPrimeField (long int _a);
47 
48  BigPrimeField (const BigPrimeField& c);
49 
50  explicit BigPrimeField (const Integer& c);
51 
52  explicit BigPrimeField (const RationalNumber& c);
53 
54  explicit BigPrimeField (const ComplexRationalNumber& c);
55 
56  explicit BigPrimeField (const SmallPrimeField& c); //? NOT SURE
57 
58  explicit BigPrimeField (const GeneralizedFermatPrimeField& c);
59 
61 
63 
65 
67 
69 
70  template <class Ring>
72 
73  BigPrimeField* BPFpointer(BigPrimeField* b);
74 
75  BigPrimeField* BPFpointer(RationalNumber* a);
76 
77  BigPrimeField* BPFpointer(SmallPrimeField* a);
78 
80 
81  static void setPrime(mpz_class p){
82  prime = p;
83  // characteristic = p;
84  }
85 
86  mpz_class Prime() const;
87 
88  mpz_class number() const;
89 
90  void whichprimefield();
91 
92  BigPrimeField findPrimitiveRootOfUnity(long int n) const {
93  return BigPrimeField::findPrimitiveRootofUnity(mpz_class(n));
94  }
95 
96 
97  static BigPrimeField findPrimitiveRootofUnity(mpz_class n){
98  if ( ((prime - 1) % n != 0)){
99  cout << "ERROR: n does not divide prime - 1." << endl;
100  return -1;
101  }
102  bool flag = false;
103  mpz_class q = (prime - 1) / n;
104  BigPrimeField p1 (prime - 1);
105  BigPrimeField c;
106  int i = 0;
107  mpz_class test = q * n / 2;
108  srand (time(NULL));
109  while(i < 20){
110  c = rand();
111  if ((c^test) == p1) {
112  flag = true;
113  return (c^q);
114  }
115  i++;
116  }
117  if (!flag ){
118  cout << "No primitive root found!"<< endl;
119  return 0;
120  }
121  // If no primitive root found
122  return 0;
123  }
124 
125  BigPrimeField unitCanonical(BigPrimeField* u = NULL, BigPrimeField* v = NULL) const;
126 
128 
129  BigPrimeField& operator= (long int k);
130 
131  BigPrimeField& operator= (const mpz_class& k);
132 
133  inline bool isZero() const {
134  return (a == 0);
135  }
136 
137  inline void zero() {
138  a = 0;
139  }
140 
141  inline bool isOne() const {
142  return (a == 1);
143  }
144 
145  inline void one() {
146  a = 1;
147  }
148 
149  inline bool isNegativeOne() const {
150  return (a == (prime - 1));
151  }
152 
153  inline void negativeOne() {
154  a = prime - 1;
155  }
156 
157  inline int isConstant() const {
158  if (a >= 0)
159  return 1;
160  else { return -1; }
161  }
162 
163  inline bool operator== (const BigPrimeField& c) const {
164  if (a == c.a)
165  return 1;
166  else { return 0; }
167  }
168 
169  inline bool operator== (const mpz_class& k) const {
170  BigPrimeField r (*this);
171  BigPrimeField b (k);
172  if (b == r){
173  return 1;
174  }
175  else {
176  return 0;
177  }
178  }
179 
180  inline bool operator== (long int k) const {
181  BigPrimeField r (*this);
182  BigPrimeField b (k);
183  if (b == r){
184  return 1;
185  }
186  else {
187  return 0;
188  }
189  }
190 
191  inline bool operator!= (const BigPrimeField& c) const {
192  if (a == c.a)
193  return 0;
194  else { return 1; }
195  }
196 
197  inline bool operator!= (const mpz_class& k) const {
198  BigPrimeField r (*this);
199  BigPrimeField b (k);
200  if (b == r){
201  return 0;
202  }
203  else {
204  return 1;
205  }
206  }
207 
208  inline bool operator!= (long int k) const {
209  BigPrimeField r (*this);
210  BigPrimeField b (k);
211  if (b == r){
212  return 0;
213  }
214  else {
215  return 1;
216  }
217  }
218 
219  inline BigPrimeField operator+ (const BigPrimeField& c) const {
220  BigPrimeField r (*this);
221  return (r += c);
222  }
223 
224  inline BigPrimeField operator+ (long int c) const {
225  BigPrimeField r (*this);
226  BigPrimeField b (c);
227  return (r += b);
228  }
229 
230  inline BigPrimeField operator+ (const mpz_class& c) const {
231  BigPrimeField r (*this);
232  BigPrimeField b(c);
233  return (r += b);
234  }
235 
237  a = (a + c.a);
238  if(a>prime)
239  a -= prime;
240  return *this;
241  }
242 
243  inline BigPrimeField operator+= (long int c) {
244  BigPrimeField r (*this);
245  BigPrimeField b (c);
246  return (r += b);
247  }
248 
249  inline BigPrimeField operator+= (const mpz_class& c) {
250  BigPrimeField r (*this);
251  BigPrimeField b(c);
252  return (r += b);
253  }
254 
255  inline BigPrimeField operator- (const BigPrimeField& c) const {
256  BigPrimeField r (*this);
257  return (r -= c);
258  }
259 
260  inline BigPrimeField operator- (long int c) const {
261  BigPrimeField r (*this);
262  BigPrimeField b (c);
263  return (r += b);
264  }
265 
266  inline BigPrimeField operator- (const mpz_class& c) const {
267  BigPrimeField r (*this);
268  BigPrimeField b(c);
269  return (r += b);
270  }
271 
273  if ((a - c.a)<0){
274  a = prime+(a - c.a);
275  }
276  else{
277  a = a - c.a;
278  }
279  return *this;
280  }
281 
282  inline BigPrimeField operator-= (long int c) {
283  BigPrimeField r (*this);
284  BigPrimeField b (c);
285  return (r += b);
286  }
287 
288  inline BigPrimeField operator-= (const mpz_class& c) {
289  BigPrimeField r (*this);
290  BigPrimeField b(c);
291  return (r += b);
292  }
293 
294  inline BigPrimeField operator- () const {
295  BigPrimeField ret = *this;
296  ret.a = prime - a;
297  return ret;
298  }
299 
300  inline BigPrimeField operator* (const BigPrimeField& c) const {
301  BigPrimeField r (*this);
302  return (r *= c);
303  }
304 
305  inline BigPrimeField operator* (const mpz_class& c) const {
306  BigPrimeField r (*this);
307  return (r *= c);
308  }
309 
310  inline BigPrimeField operator* (long int c) const {
311  BigPrimeField r (*this);
312  return (r *= c);
313  }
314 
316  a = (a * c.a)%prime;
317  return *this;
318  }
319 
320  inline BigPrimeField& operator*= (const mpz_class& m) {
321  mpz_class c(m);
322  while(c<0){
323  c=c+prime;
324  }
325  a = (a * c)%prime;
326  return *this;
327  }
328 
329  inline BigPrimeField& operator*= (long int c) {
330  mpz_class b = c;
331  while(b<0){
332  b=b+prime;
333  }
334  a = (a * b)%prime;
335  return *this;
336  }
337 
338  inline BigPrimeField operator^ (long long int c) const {
339  BigPrimeField r (*this);
340  mpz_class b(std::to_string(c), 10);
341  return (r ^ b);
342  }
343 
344  inline BigPrimeField operator^ (const mpz_class& exp) const {
345  BigPrimeField r;
346  mpz_class e = exp;
347  if (isZero() || isOne() || e == 1)
348  r = *this;
349  else if (e == 2) {
350  r = *this * *this;
351  }
352  else if (e > 2) {
353  BigPrimeField x (*this);
354  r.one();
355 
356  while (e != 0) {
357  if ((e % 2) == 1)
358  r *= x;
359  x = x * x;
360  e >>= 1;
361  }
362  }
363  else if (e == 0) {
364  r.one();
365  }
366  else {
367  r = *this ^ (-e);
368  r=r.inverse();
369  }
370  return r;
371  }
372 
373  inline BigPrimeField& operator^= (long long int c) {
374  *this = *this ^ c;
375  return *this;
376  }
377 
378  inline BigPrimeField& operator^= (const mpz_class& e) {
379  *this = *this ^ e;
380  return *this;
381  }
382 
384  return ExpressionTree(new ExprTreeNode(a));
385  }
386 
387  inline BigPrimeField operator/ (const BigPrimeField& c) const {
388  BigPrimeField r (*this);
389  return (r /= c);
390  }
391 
392  inline BigPrimeField operator/ (long int c) const {
393  BigPrimeField r (*this);
394  BigPrimeField b (c);
395  return (r /= b);
396  }
397 
398  inline BigPrimeField operator/ (const mpz_class& c) const {
399  BigPrimeField r (*this);
400  BigPrimeField b (c);
401  return (r /= b);
402  }
403 
405  if (c.isZero()) {
406  std::cout << "BPAS: error, dividend is zero from SmallPrimeField."<< std::endl;
407  exit(1);
408  }
409  BigPrimeField inv = c.inverse();
410  *this *= inv;
411  return *this;
412  }
413 
414  inline BigPrimeField& operator/= (long int c) {
415  BigPrimeField b (c);
416  return (*this /= b);
417  }
418 
419  inline BigPrimeField& operator/= (const mpz_class& c) {
420  BigPrimeField b (c);
421  return (*this /= b);
422  }
423 
424  inline BigPrimeField operator% (const BigPrimeField& c) const {
425  return 0;
426  }
427 
429  *this = 0;
430  return *this;
431  }
432 
433  inline BigPrimeField gcd (const BigPrimeField& other) const {
434  BigPrimeField q (0);
435  BigPrimeField r (0);
436  BigPrimeField c (other);
437  BigPrimeField b (*this);
438  if(b.a < c.a){
439  return c.gcd(b);
440  }
441  while (c.a > 0) {
442  q.a = b.a / c.a;
443  r.a = b.a % c.a;
444  b = c;
445  c = r;
446  }
447  return b;
448  }
449 
450  inline BigPrimeField gcd (long int c){
451  BigPrimeField r (*this);
452  BigPrimeField b (c);
453  return r.gcd(b);
454  }
455 
456  inline BigPrimeField gcd (const mpz_class& c) const {
457  BigPrimeField r (*this);
458  BigPrimeField b (c);
459  return r.gcd(b);
460  }
461 
462  /**
463  * Compute squarefree factorization of *this
464  */
466  std::vector<BigPrimeField> ret;
467  ret.push_back(*this);
468  return ret;
469  }
470 
471  /**
472  * Get the euclidean size of *this.
473  */
474  inline BigPrimeField euclideanSize() const {
475  return (*this).number();
476  }
477 
478  /**
479  * Perform the eucldiean division of *this and b. Returns the
480  * remainder. If q is not NULL, then returns the quotient in q.
481  */
482  BigPrimeField euclideanDivision(const BigPrimeField& b, BigPrimeField* q = NULL) const;
483 
484  /**
485  * Perform the extended euclidean division on *this and b.
486  * Returns the GCD. If s and t are not NULL, returns the bezout coefficients in them.
487  */
488  BigPrimeField extendedEuclidean(const BigPrimeField& b, BigPrimeField* s = NULL, BigPrimeField* t = NULL) const;
489 
490  /**
491  * Get the quotient of *this and b.
492  */
493  BigPrimeField quotient(const BigPrimeField& b) const;
494 
495  /**
496  * Get the remainder of *this and b.
497  */
498  BigPrimeField remainder(const BigPrimeField& b) const;
499 
500  inline BigPrimeField inverse() const {
501  BigPrimeField r(0);
502  mpz_t temp;
503  mpz_init(temp);
504  if (!mpz_invert(temp, a.get_mpz_t(), prime.get_mpz_t()))
505  mpz_set_si(temp, 0);
506  mpz_class temp_class(temp);
507  mpz_clear(temp);
508  r = temp_class;
509  return r;
510  }
511 
512 };
513 
514 #endif
ExpressionTree convertToExpressionTree() const
Convert this to an expression tree.
Definition: BigPrimeField.hpp:383
BigPrimeField quotient(const BigPrimeField &b) const
Get the quotient of *this and b.
BigPrimeField remainder(const BigPrimeField &b) const
Get the remainder of *this and b.
BigPrimeField euclideanSize() const
Get the euclidean size of *this.
Definition: BigPrimeField.hpp:474
BigPrimeField & operator^=(long long int c)
Exponentiation assignment.
Definition: BigPrimeField.hpp:373
A univariate polynomial over an arbitrary BPASRing represented sparsely.
Definition: BigPrimeField.hpp:21
bool isZero() const
Determine if *this ring element is zero, that is the additive identity.
Definition: BigPrimeField.hpp:133
An arbitrary-precision complex rational number.
Definition: ComplexRationalNumber.hpp:23
void one()
Make *this ring element one.
Definition: BigPrimeField.hpp:145
BigPrimeField operator*(const BigPrimeField &c) const
Multiplication.
Definition: BigPrimeField.hpp:300
BigPrimeField & operator+=(const BigPrimeField &c)
Addition assignment.
Definition: BigPrimeField.hpp:236
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
BigPrimeField gcd(const BigPrimeField &other) const
Get GCD of *this and other.
Definition: BigPrimeField.hpp:433
A finite field whose prime should be a generalized fermat number.
Definition: GeneralizedFermatPrimeField.hpp:36
BigPrimeField & operator/=(const BigPrimeField &c)
Exact division assignment.
Definition: BigPrimeField.hpp:404
BigPrimeField unitCanonical(BigPrimeField *u=NULL, BigPrimeField *v=NULL) const
Obtain the unit normal (a.k.a canonical associate) of an element.
A prime field whose prime is 32 bits or less.
Definition: SmallPrimeField.hpp:449
BigPrimeField extendedEuclidean(const BigPrimeField &b, BigPrimeField *s=NULL, BigPrimeField *t=NULL) const
Perform the extended euclidean division on *this and b.
A univariate polynomial with Integer coefficients using a dense representation.
Definition: uzpolynomial.h:13
bool operator!=(const BigPrimeField &c) const
Inequality test,.
Definition: BigPrimeField.hpp:191
BigPrimeField operator^(long long int c) const
Exponentiation.
Definition: BigPrimeField.hpp:338
BigPrimeField & operator*=(const BigPrimeField &c)
Multiplication assignment.
Definition: BigPrimeField.hpp:315
bool operator==(const BigPrimeField &c) const
Equality test,.
Definition: BigPrimeField.hpp:163
A univariate polynomial with RationalNumber coefficients represented densely.
Definition: urpolynomial.h:15
A prime field whose prime can be arbitrarily large.
Definition: BigPrimeField.hpp:27
BigPrimeField operator%(const BigPrimeField &c) const
Get the remainder of *this and b;.
Definition: BigPrimeField.hpp:424
BigPrimeField operator-() const
Negation.
Definition: BigPrimeField.hpp:294
BigPrimeField & operator-=(const BigPrimeField &c)
Subtraction assignment.
Definition: BigPrimeField.hpp:272
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
BigPrimeField & operator%=(const BigPrimeField &c)
Assign *this to be the remainder of *this and b.
Definition: BigPrimeField.hpp:428
An arbitrary-precision Integer.
Definition: Integer.hpp:22
bool isOne() const
Determine if *this ring element is one, that is the multiplication identity.
Definition: BigPrimeField.hpp:141
void zero()
Make *this ring element zero.
Definition: BigPrimeField.hpp:137
BigPrimeField operator/(const BigPrimeField &c) const
Exact division.
Definition: BigPrimeField.hpp:387
An arbitrary-precision rational number.
Definition: RationalNumber.hpp:24
BigPrimeField operator+(const BigPrimeField &c) const
Addition.
Definition: BigPrimeField.hpp:219
virtual mpz_class characteristic()
The characteristic of this ring class.
Definition: BPASRing.hpp:88
Factors< BigPrimeField > squareFree() const
Compute squarefree factorization of *this.
Definition: BigPrimeField.hpp:465
BigPrimeField euclideanDivision(const BigPrimeField &b, BigPrimeField *q=NULL) const
Perform the eucldiean division of *this and b.
BigPrimeField & operator=(const BigPrimeField &c)
Copy assignment.
BigPrimeField inverse() const
Get the inverse of *this.
Definition: BigPrimeField.hpp:500
ExprTreeNode is a single node in the bianry tree of an ExpressionTree.
Definition: ExprTreeNode.hpp:76
An abstract class defining the interface of a prime field.
Definition: BPASFiniteField.hpp:12