Basic Polynomial Algebra Subprograms (BPAS)  v. 1.652
dmpolynomial.h
1 #ifndef _MMPolynomial_H_
2 #define _MMPolynomial_H_
3 
4 
5 #include "../polynomial.h"
6 #include "../Utils/TemplateHelpers.hpp"
7 #include "../Ring/BPASField.hpp"
8 
9 template <class Field>
10 inline void coef_add_mod(Field* c, Field a, Field b, Field p) {
11  *c = (a + b) % p;
12 }
13 template <class Field>
14 inline void coef_sub_mod(Field* c, Field a, Field b, Field p) {
15  *c = (a - b) % p;
16  if (*c < 0) { *c += p; }
17 }
18 template <class Field>
19 inline void coef_neg_mod(Field* c, Field a, Field p) {
20  *c = p - a;
21 }
22 template <class Field>
23 inline void coef_mul_mod(Field* c, Field a, Field b, Field p) {
24  *c = (a * b) % p;
25 }
26 
27 /**
28  * A multivariate polynomial with coefficients in an arbitrary finite field represented densely.
29  * The class is templated by a Field which should be a BPASField.
30  */
31 template <class Field>
32 class DistributedDenseMultivariateModularPolynomial : public BPASMultivariatePolynomial<Field,DistributedDenseMultivariateModularPolynomial<Field>>,
33  private Derived_from<Field, BPASField<Field>> {
34  private:
35  Symbol* names; // Variable names
36  int var; // Number of variables
37  int n; // Number of terms
38  Field* coefs; // Coefficients in Prime field
39  int* degs; // Partial size
40  Field p; // Prime
41 
42 
43  int* acc;
44 
45  inline void zeros() {
46  for (int i = 0; i < n; ++i)
47  coefs[i] = 0;
48  }
49 
50  inline bool isSameRing(const DistributedDenseMultivariateModularPolynomial& b) const {
51  if (var != b.var || names[0] != b.names[0])
52  return 0;
53  if (names[0] == "9") {
54  for (int i = 1; i <= var; ++i) {
55  if (names[i] != b.names[i])
56  return 0;
57  }
58  }
59  return 1;
60  }
61 
62  public:
63  static mpz_class characteristic;
64  // static bool isPrimeField;
65  // static bool isSmallPrimeField;
66  // static bool isComplexField;
67  /**
68  * Constructor using a default field
69  **/
71  coefs = new Field[1];
72  coefs[0] = 0;
73  degs = new int[1];
74  degs[0] = 0;
75  acc = new int[1];
76  acc[0] = 1;
77  names = new Symbol[1];
78  names[0] = "1";
79  }
80 
81  /**
82  * Constructor with the Field
83  *
84  * @param m: The prime
85  **/
86  DistributedDenseMultivariateModularPolynomial (const Field& m) : var(0), n(0), p(m) {
87  coefs = new Field[1];
88  coefs[0] = 0;
89  degs = new int[1];
90  degs[0] = 0;
91  acc = new int[1];
92  acc[0] = 1;
93  names = new Symbol[1];
94  names[0] = "1";
95  }
96 
97  /**
98  * Constructor with number of variables and terms
99  *
100  * @param v: Number of variables
101  * @param ds: Partial degrees
102  * @param m: The prime
103  **/
104  DistributedDenseMultivariateModularPolynomial(int v, int* ds, Field m) : var(v), p(m) {
105  degs = new int[var];
106  acc = new int[var];
107  acc[0] = 1;
108  for (int i = 0; i < var; ++i) {
109  degs[i] = ds[i];
110  if (i < var - 1)
111  acc[i+1] = acc[i] * (degs[i] + 1);
112  }
113  n = acc[var-1] * (degs[var-1] + 1);
114  coefs = new Field[n];
115  zeros();
116  //coefs[0] = 0;
117  names = new Symbol[var+1];
118  names[0] = "1";
119  for (int i = 1; i <= var; ++i) {
120  std::ostringstream convert;
121  convert << var - i + 1;
122  names[i] = "_";
123  names[i] += convert.str();
124  }
125  }
126 
127  /**
128  * Construct with a variable name
129  * such that f(x) = x;
130  *
131  * @param x: The variable name
132  * @param m: The prime
133  **/
134  DistributedDenseMultivariateModularPolynomial (const Symbol& x, const Field& m) : var(1), n(2), p(m) {
135  names = new Symbol[2];
136  names[0] = "9";
137  names[1] = x;
138  degs = new int[1];
139  degs[0] = 1;
140  acc = new int[1];
141  acc[0] = 1;
142  coefs = new Field[2];
143  coefs[0] = 0;
144  coefs[1] = 1;
145  }
146  /**
147  * Copy constructor
148  *
149  * @param b: A multivariate modular polynomial
150  **/
152  degs = new int[var];
153  std::copy(b.degs, b.degs+var, degs);
154  acc = new int[var];
155  std::copy(b.acc, b.acc+var, acc);
156  coefs = new Field[n];
157  std::copy(b.coefs, b.coefs+n, coefs);
158  names = new Symbol[var+1];
159  std::copy(b.names, b.names+var+1, names);
160  }
161  /**
162  * Deconstructor
163  *
164  * @param
165  **/
167  delete [] coefs;
168  delete [] degs;
169  delete [] names;
170  delete [] acc;
171  }
172  /**
173  * Overload operator =
174  *
175  * @param b: A multivariate modular polynomial
176  **/
178  if (this != &b) {
179  delete [] coefs;
180  delete [] degs;
181  delete [] names;
182  delete [] acc;
183 
184  var = b.var;
185  degs = new int[var];
186  std::copy(b.degs, b.degs+var, degs);
187  acc = new int[var];
188  std::copy(b.acc, b.acc+var, acc);
189  n = b.n;
190  coefs = new Field[n];
191  std::copy(b.coefs, b.coefs+n, coefs);
192  names = new Symbol[var+1];
193  std::copy(b.names, b.names+var+1, names);
194  p = b.p;
195  }
196  }
197 
198  /**
199  * Overload operator =. Assign this to a be a base Field element.
200  */
203  return *this;
204  }
205 
206  /**
207  * Is a zero polynomial
208  *
209  * @param
210  **/
211  inline bool isZero() const {
212  for (int i = 0; i < n; ++i) {
213  if (coefs[i] != 0)
214  return 0;
215  }
216  return 1;
217  }
218  /**
219  * Zero polynomial
220  *
221  * @param
222  **/
223  inline void zero() {
224  zeros();
225  }
226  /**
227  * Is polynomial 1
228  *
229  * @param
230  **/
231  inline bool isOne() const {
232  for (int i = 1; i < n; ++i) {
233  if (coefs[i] != 0)
234  return 0;
235  }
236  return (coefs[0] == 1);
237  }
238  /**
239  * Set polynomial to 1
240  *
241  * @param
242  **/
243  inline void one() {
244  coefs[0] = 1;
245  for (int i = 1; i < n; ++i)
246  coefs[i] = 0;
247  }
248  /**
249  * Is polynomial -1
250  *
251  * @param
252  **/
253  inline bool isNegativeOne() const {
254  for (int i = 1; i < n; ++i) {
255  if (coefs[i] != 0)
256  return 0;
257  }
258  return (coefs[0] == p - 1);
259  }
260  /**
261  * Set polynomial to -1
262  *
263  * @param
264  **/
265  inline void negativeOne() {
266  coefs[0] = p - 1;
267  for (int i = 1; i < n; ++i)
268  coefs[i] = 0;
269  }
270  /**
271  * Is a constant
272  *
273  * @param
274  **/
275  inline int isConstant() const {
276  for (int i = 1; i < n; ++i) {
277  if (coefs[i] != 0)
278  return 0;
279  }
280  if (coefs[0] < (p / 2)) { return 1; }
281  else { return -1; }
282  }
283  /**
284  * Get the number of variables
285  *
286  * @param
287  **/
288  inline int numberOfVariables() const {
289  return variables().size();
290  }
291 
292  /**
293  * Get the number of variables in this polynomial ring.
294  */
295  inline int numberOfRingVariables() const {
296  return ringVariables().size();
297  }
298 
299  /**
300  * Get the number of non-zero terms
301  *
302  * @param
303  **/
304  inline Integer numberOfTerms() const {
305  int k = 0;
306  for (int i = 0; i < n; ++i)
307  if (coefs[i] != 0) { k++; }
308  return k;
309  }
310  /**
311  * Get the size of the polynomial
312  *
313  * @param
314  **/
315  inline int size() const {
316  return n;
317  }
318 
319  /**
320  * Get the total degree.
321  */
322  inline Integer degree() const {
323  std::cerr << "DistributedDenseMultivariateModularPolynomial::degree() NOT YET IMPLEMENTED" << std::endl;
324  //TODO
325  return 0;
326  }
327 
328  /**
329  * Get a partial degree of variable x
330  *
331  * @param x: The variable name
332  **/
333  inline Integer degree(const Symbol& x) const {
334  int k = 0, d = 0;
335  for (int i = 1; i <= var; ++i) {
336  if (names[i] == x)
337  k = i;
338  }
339  if (k) {
340  k--;
341  for (int i = 0; i < n; ++i) {
342  int e = (i / acc[k]) % (degs[k] + 1);
343  if (coefs[i] != 0 && e > d)
344  d = e;
345  }
346  }
347  return d;
348  }
349 
350  /**
351  * Get the leading coefficient
352  *
353  * @param
354  **/
355  inline Field leadingCoefficient() const {
356  for (int i = n-1; i > -1; --i) {
357  if (coefs[i] != 0)
358  return coefs[i];
359  }
360  return 0;
361  }
362 
363  inline Field trailingCoefficient() const {
364  for (int i = 0; i < n; ++i) {
365  if (coefs[i] != 0) {
366  return coefs[i];
367  }
368  }
369  return 0;
370  }
371 
372  bool isConstantTermZero() const {
373  int d[var];
374  Field f = coefficient(var, d);
375  return (f == 0);
376  }
377 
380  Field lead = leadingCoefficient();
381  Field leadInv = lead.inverse();
382  DistributedDenseMultivariateModularPolynomial ret = *this * leadInv;
383  if (u != NULL) {
384  *u = lead;
385  }
386  if (v != NULL) {
387  *v = leadInv;
388  }
389  return ret;
390  }
391 
392  /**
393  * Get a coefficient
394  *
395  * @param v: Number of variables
396  * @param d: The exponent of each variable
397  **/
398  inline Field coefficient(int v, const int* d) const {
399  int k = 0;
400  for (int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
401  if (d[j] <= degs[i])
402  k += d[j] * acc[i];
403  else { return 0; }
404  }
405  for (int i = v-var-1; i > -1; --i)
406  if (d[i]) { return 0; }
407  return coefs[k];
408  }
409 
410  inline Field coefficient(const std::vector<int>& v) const {
411  return coefficient(v.size(), v.data());
412  }
413 
414  /**
415  * Set a coefficient
416  *
417  * @param v: Number of variables
418  * @param d: The exponent of each variable
419  * @param val: Value of the coefficient
420  **/
421  inline void setCoefficient(int v, const int* d, const Field& val) {
422  if (v != var) {
423  std::cout << "BPAS: error, DDMMP(" << var << "), but trying to setCoefficient with " << v << " variables." << std::endl;
424  exit(1);
425  }
426  int k = 0;
427  for (int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
428  if (d[j] <= degs[i])
429  k += d[j] * acc[i];
430  else {
431  std::cout << "BPAS: error, the degree of " << names[i+1] << " in DDMMP is " << degs[i] << "." << std::endl;
432  exit(1);
433  }
434  }
435  coefs[k] = val;
436  }
437 
438  inline void setCoefficient(const std::vector<int>& v, const Field& val) {
439  setCoefficient(v.size(), v.data(), val);
440  }
441 
442  /**
443  * Set a coefficient
444  *
445  * @param k: The offset in the coefficient array
446  * @param val: Value of the coefficient
447  **/
448  inline void setCoefficient(int k, const Field& val) {
449  if (k >= n || k < 0) {
450  std::cout << "BPAS: error, trying to access a non-exist coefficient in DDMMP<Field>." << std::endl;
451  exit(1);
452  }
453  coefs[k] = val;
454  }
455 
456  inline Field content() const {
457  //TODO
458  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::content() NOT YET IMPLEMENTED" << std::endl;
459  return Field(1);
460  }
461 
462  inline DistributedDenseMultivariateModularPolynomial primitivePart() const {
463  //TODO
464  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::primitivePart() NOT YET IMPLEMENTED" << std::endl;
465  return *this;
466  }
467 
468  /**
469  * Overload operator ==
470  *
471  * @param b: A multivariate modular polynomial
472  **/
474  if (var != b.var || p != b.p)
475  return 0;
476 
477  int prev = 0;
478  for (int i = 0; i < n; ++i) {
479  int k = 0;
480  for (int j = 0; j < var; ++j) {
481  int e = (i / acc[j]) % (degs[j] + 1);
482  if (e <= b.degs[j])
483  k += e * b.acc[j];
484  else if (coefs[i] != 0)
485  return 0;
486  }
487  for (int j = prev+1; j < k; ++j) {
488  if (b.coefs[j] != 0)
489  return 0;
490  }
491  if (coefs[i] != b.coefs[k])
492  return 0;
493  prev = k;
494  }
495  for (int i = n; i < b.n; ++i) {
496  if (b.coefs[i] != 0)
497  return 0;
498  }
499  return 1;
500  }
501  /**
502  * Overload operator !=
503  *
504  * @param b: A multivariate modular polynomial
505  **/
507  return !(*this == b);
508  }
509 
510  /**
511  * Overload operator +
512  *
513  * @param b: A multivariate modular polynomial
514  **/
516  if (p != b.p) {
517  std::cout << "BPAS: error, trying to add between Z/" << p << "Z and Z/" << b.p << "Z from DDMMP<Field>." << std::endl;
518  exit(1);
519  }
520  if (isConstant()) { return b + coefs[0]; }
521  if (b.isConstant()) { return *this + b.coefs[0]; }
522 
523  bool isSame = isSameRing(b);
524  if (!isSame) {
525  std::cout << "BPAS: error, trying to add between Z/" << p << "Z[";
526  for (int i = 1; i <= var; ++i) {
527  std::cout << names[i];
528  if (i < var)
529  std::cout << ", ";
530  }
531  std::cout << "] and Z/" << b.p << "Z[";
532  for (int i = 1; i <= b.var; ++i) {
533  std::cout << b.names[i];
534  if (i < b.var)
535  std::cout << ", ";
536  }
537  std::cout << "] from DDMMP<Field>." << std::endl;
538  exit(1);
539  }
540 
541  int* ds = new int[var];
542  for (int i = 0; i < var; ++i)
543  ds[i] = (degs[i] >= b.degs[i])? degs[i] : b.degs[i];
545  std::copy(names, names+var+1, res.names);
546 
547  //#pragma cilk_grainsize = 1024;
548  for (int i = 0; i < res.n; ++i) {
549  Field elem = 0;
550  int offseta = 0, offsetb = 0;
551  for (int j = 0; j < var; ++j) {
552  int k = (i / res.acc[j]) % (res.degs[j] + 1);
553  if (offseta >= 0 && k <= degs[j])
554  offseta += k * acc[j];
555  else
556  offseta = -1;
557  if (offsetb >= 0 && k <= b.degs[j])
558  offsetb += k * b.acc[j];
559  else
560  offsetb = -1;
561  }
562  if (offseta >= 0 && offsetb >= 0)
563  coef_add_mod(&elem, coefs[offseta], b.coefs[offsetb], p);
564  else if (offseta >= 0)
565  elem = coefs[offseta];
566  else if (offsetb >= 0)
567  elem = b.coefs[offsetb];
568  res.coefs[i] = elem;
569  }
570 
571  delete [] ds;
572  return res;
573  }
574 
575  /**
576  * Overload operator +=
577  *
578  * @param b: A multivariate modular polynomial
579  **/
581  *this = *this + b;
582  return *this;
583  }
584 
585  /**
586  * Overload operator +
587  *
588  * @param e: A constant
589  **/
592  return (r += e);
593  }
594 
596  return (f + e);
597  }
598 
599  /**
600  * Overload operator +=
601  *
602  * @param e: A constant
603  **/
605  coef_add_mod(&coefs[0], coefs[0], e, p);
606  return *this;
607  }
608 
609  /**
610  * Overload operator -
611  *
612  * @param b: A multivariate modular polynomial
613  **/
615  if (p != b.p) {
616  std::cout << "BPAS: error, trying to subtract between Z/" << p << "Z and Z/" << b.p << "Z from DDMMP<Field>." << std::endl;
617  exit(1);
618  }
619  if (isConstant()) { return -b + coefs[0]; }
620  if (b.isConstant()) { return *this - b.coefs[0]; }
621 
622  bool isSame = isSameRing(b);
623  if (!isSame) {
624  std::cout << "BPAS: error, trying to subtract between Z/" << p << "Z[";
625  for (int i = 1; i <= var; ++i) {
626  std::cout << names[i];
627  if (i < var)
628  std::cout << ", ";
629  }
630  std::cout << "] and Z/" << b.p << "Z[";
631  for (int i = 1; i <= b.var; ++i) {
632  std::cout << b.names[i];
633  if (i < b.var)
634  std::cout << ", ";
635  }
636  std::cout << "] from DDMMP<Field>." << std::endl;
637  exit(1);
638  }
639 
640  int* ds = new int[var];
641  for (int i = 0; i < var; ++i)
642  ds[i] = (degs[i] >= b.degs[i])? degs[i] : b.degs[i];
644  std::copy(names, names+var+1, res.names);
645 
646  for (int i = 0; i < res.n; ++i) {
647  Field elem = 0;
648  int offseta = 0, offsetb = 0;
649  for (int j = 0; j < var; ++j) {
650  int k = (i / res.acc[j]) % (res.degs[j] + 1);
651  if (offseta >= 0 && k <= degs[j])
652  offseta += k * acc[j];
653  else { offseta = -1; }
654  if (offsetb >= 0 && k <= b.degs[j])
655  offsetb += k * b.acc[j];
656  else { offsetb = -1; }
657  }
658  if (offseta >= 0 && offsetb >= 0)
659  coef_sub_mod(&elem, coefs[offseta], b.coefs[offsetb], p);
660  else if (offseta >= 0)
661  elem = coefs[offseta];
662  else if (offsetb >= 0)
663  coef_neg_mod(&elem, b.coefs[offsetb], p);
664  res.coefs[i] = elem;
665  }
666  delete [] ds;
667  return res;
668  }
669 
670  /**
671  * Overload operator -=
672  *
673  * @param b: A multivariate modular polynomial
674  **/
676  *this = *this - b;
677  return *this;
678  }
679 
680  /**
681  * Overload operator -, negate
682  *
683  * @param
684  **/
687  std::copy(names, names+var+1, res.names);
688  for (int i = 0; i < res.n; ++i)
689  coef_neg_mod(&res.coefs[i], coefs[i], p);
690  return res;
691  }
692 
693  /**
694  * Overload operator -
695  *
696  * @param e: A constant
697  **/
700  return (r -= e);
701  }
702 
704  return (-f + e);
705  }
706 
707  /**
708  * Overload operator -=
709  *
710  * @param e: A constant
711  **/
713  coef_sub_mod(&coefs[0], coefs[0], e, p);
714  return *this;
715  }
716 
717  /**
718  * Negate, f(-x)
719  *
720  * @param
721  **/
722  inline void negate() {
723  for (int i = 0; i < n; ++i)
724  coef_neg_mod(&coefs[i], coefs[i], p);
725  }
726 
727  /**
728  * Overload operator *
729  *
730  * @param b: A multivariate modular polynomial
731  **/
733  if (p != b.p) {
734  std::cout << "BPAS: error, trying to multiply between Z/" << p << "Z and Z/" << b.p << "Z from DDMMP<Field>." << std::endl;
735  exit(1);
736  }
737  if (isConstant()) { return b * coefs[0]; }
738  if (b.isConstant()) { return *this * b.coefs[0]; }
739 
740  bool isSame = isSameRing(b);
741  if (!isSame) {
742  std::cout << "BPAS: error, trying to multiply between Z/" << p << "Z[";
743  for (int i = 1; i <= var; ++i) {
744  std::cout << names[i];
745  if (i < var)
746  std::cout << ", ";
747  }
748  std::cout << "] and Z/" << b.p << "Z[";
749  for (int i = 1; i <= b.var; ++i) {
750  std::cout << b.names[i];
751  if (i < b.var)
752  std::cout << ", ";
753  }
754  std::cout << "] from DDMMP<Field>." << std::endl;
755  exit(1);
756  }
757 
758  int* ds = new int[var];
759  for (int i = 0; i < var; ++i)
760  ds[i] = degs[i] + b.degs[i];
762  std::copy(names, names+var+1, res.names);
763 
764  for (int i = 0; i < n; ++i) {
765  for (int v = 0; v < var; ++v)
766  ds[v] = (i / acc[v]) % (degs[v] + 1);
767  for (int j = 0; j < b.n; ++j) {
768  int k = 0;
769  for (int v = 0; v < b.var; ++v) {
770  int e = (j / b.acc[v]) % (b.degs[v] + 1);
771  if (v < var)
772  k += (ds[v] + e) * res.acc[v];
773  else
774  k += e * res.acc[v];
775  }
776  for (int v = b.var; v < var; ++v)
777  k += ds[v] * res.acc[v];
778  // res.coefs[k] += coefs[i] * b.coefs[j];
779  Field t;
780  coef_mul_mod(&t, coefs[i], b.coefs[j], p);
781  coef_add_mod(&res.coefs[k], res.coefs[k], t, p);
782  }
783  }
784 
785  delete [] ds;
786  return res;
787  }
788 
789  /**
790  * Overload operator *=
791  *
792  * @param b: A multivariate modular polynomial
793  **/
795  *this = *this * b;
796  return *this;
797  }
798 
799  /**
800  * Overload operator *
801  *
802  * @param e: A constant
803  **/
806  return (r *= e);
807  }
808 
810  return (f * e);
811  }
812 
813  /**
814  * Overload operator *=
815  *
816  * @param e: A constant
817  **/
819  if (f != 0 && f != 1) {
820  Field e(f);
821  if (e < 0) { e = e % p + p; }
822  for (int i = 0; i < n; ++i)
823  coef_mul_mod(&coefs[i], coefs[i], e, p);
824  }
825  else if (f == 0) { zero(); }
826  return *this;
827  }
828 
829  inline DistributedDenseMultivariateModularPolynomial<Field> operator^ (long long int e) const {
830  //TODO
831  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^ NOT YET IMPLEMENTED" << std::endl;
832  return *this;
833  }
834 
835  inline DistributedDenseMultivariateModularPolynomial<Field>& operator^= (long long int e) {
836  //TODO
837  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^= NOT YET IMPLEMENTED" << std::endl;
838  return *this;
839  }
840 
843  ret /= p;
844  return ret;
845  }
846 
848  //TODO
849  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/=(DistributedDenseMultivariateModularPolynomial) NOT YET IMPLEMENTED" << std::endl;
850  return *this;
851  }
852 
853  inline DistributedDenseMultivariateModularPolynomial<Field> operator/ (const Field& e) const {
855  ret /= e;
856  return ret;
857  }
858 
859  inline DistributedDenseMultivariateModularPolynomial<Field>& operator/= (const Field& e) {
860  //TODO
861  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/= NOT YET IMPLEMENTED" << std::endl;
862  return *this;
863  }
864 
865  /**
866  * Set variable names
867  *
868  * @param xs: Variable names
869  **/
870  inline void setRingVariables (const std::vector<Symbol>& xs) {
871  int ns = xs.size();
872  if (ns != var) {
873  std::cerr << "BPAS ERROR: DDMMP shrinking and expanding polynomial ring NOT YET IMPLEMENTED" << std::endl;
874  return;
875  }
876  names[0] = "9";
877  for (int i = var, j = 0; i > 0 && j < ns; --i, ++j)
878  names[i] = xs[j];
879  }
880 
881  /**
882  * Get variable names
883  *
884  * @param
885  **/
886  inline std::vector<Symbol> ringVariables() const {
887  std::vector<Symbol> xs;
888  for (int i = var; i > 0; --i)
889  xs.push_back(names[i]);
890  return xs;
891  }
892 
893  inline std::vector<Symbol> variables() const {
894  std::cerr << "BPAS ERROR: DDMMP::variables() NOT YET IMPLEMENTED" << std::endl;
895  return ringVariables();
896  }
897 
898 
899  /**
900  * Overload stream operator <<
901  *
902  * @param out: Stream object
903  * @param b: The multivariate modular polynomial
904  **/
905  inline void print(std::ostream &out) const {
906  bool isFirst = 0;
907  for (int i = 0; i < this->n; ++i) {
908  if (this->coefs[i] != 0) {
909  if (isFirst) {
910  if (this->coefs[i] >= 0)
911  out << "+";
912  else if (this->coefs[i] == -1)
913  out << "-";
914  if (this->coefs[i] != 1 && this->coefs[i] != -1)
915  out << this->coefs[i];
916  bool isIt = 1;
917  for (int j = 0; j < this->var; ++j) {
918  int exp = (i / this->acc[j]) % (this->degs[j] + 1);
919  if (exp) {
920  if ((this->coefs[i] != 1 && this->coefs[i] != -1 && isIt) || !isIt)
921  out << "*";
922  out << this->names[j+1];
923  if (exp > 1)
924  out << "^" << exp;
925  isIt = 0;
926  }
927  }
928  }
929  else { out << this->coefs[i]; }
930  isFirst = 1;
931  }
932  }
933  if (!isFirst) { out << "0"; }
934  }
935 
936  /**
937  * Convert *this to an expression tree
938  */
940  //TODO
941  std::cerr << "DistributedDenseMultivariateModularPolynomial::convertToExpressionTree() NOT YET IMPLEMENTED" << std::endl;
942  return ExpressionTree();
943  }
944 
945  inline void differentiate(const Symbol& s, int k) {
946  std::cerr << "DistributedDenseMultivariateModularPolynomial::differentiate NOT YET IMPLEMENTED" << std::endl;
947  //TODO
948  }
949 
950  inline void differentiate(const Symbol& s) {
951  differentiate(s, 1);
952  }
953 
954  inline DistributedDenseMultivariateModularPolynomial<Field> derivative(const Symbol& s, int k) const {
956  ret.differentiate(s, k);
957  return ret;
958  }
959 
960  inline DistributedDenseMultivariateModularPolynomial<Field> derivative(const Symbol& s) const {
961  return derivative(s, 1);
962  }
963 
964  inline DistributedDenseMultivariateModularPolynomial<Field> evaluate(const std::vector<Symbol>& syms, const std::vector<Field>& vals) const {
965  //TODO
966  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
967  return *this;
968  }
969 
970  inline DistributedDenseMultivariateModularPolynomial<Field> evaluate(int n, const Symbol* syms, const Field* vals) const {
971  //TODO
972  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
973  return *this;
974  }
975 
977  //TODO
978  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::gcd NOT YET IMPLEMENTED" << std::endl;
979  return *this;
980  }
981 
982  /**
983  * Compute squarefree factorization of *this
984  */
986  std::cerr << "DistributedDenseMultivariateModularPolynomial::squareFree NOT YET IMPLEMENTED" << std::endl;
987  //TODO
988  std::vector<DistributedDenseMultivariateModularPolynomial> ret;
989  ret.push_back(*this);
990  return ret;
991  }
992 
993 
994 
995 
996 
997 
998 
999 };
1000 
1001 #endif
DistributedDenseMultivariateModularPolynomial(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Copy constructor.
Definition: dmpolynomial.h:151
void negate()
Negate, f(-x)
Definition: dmpolynomial.h:722
ExpressionTree convertToExpressionTree() const
Convert *this to an expression tree.
Definition: dmpolynomial.h:939
DistributedDenseMultivariateModularPolynomial< Field > operator+(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator +.
Definition: dmpolynomial.h:515
Field leadingCoefficient() const
Get the leading coefficient.
Definition: dmpolynomial.h:355
int numberOfRingVariables() const
Get the number of variables in this polynomial ring.
Definition: dmpolynomial.h:295
Integer degree(const Symbol &x) const
Get a partial degree of variable x.
Definition: dmpolynomial.h:333
DistributedDenseMultivariateModularPolynomial< Field > & operator-=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator -=.
Definition: dmpolynomial.h:675
Integer numberOfTerms() const
Get the number of non-zero terms.
Definition: dmpolynomial.h:304
DistributedDenseMultivariateModularPolynomial(int v, int *ds, Field m)
Constructor with number of variables and terms.
Definition: dmpolynomial.h:104
void print(std::ostream &out) const
Overload stream operator <<.
Definition: dmpolynomial.h:905
DistributedDenseMultivariateModularPolynomial()
Constructor using a default field.
Definition: dmpolynomial.h:70
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
DistributedDenseMultivariateModularPolynomial< Field > operator*(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator *.
Definition: dmpolynomial.h:732
Factors< DistributedDenseMultivariateModularPolynomial > squareFree() const
Compute squarefree factorization of *this.
Definition: dmpolynomial.h:985
Integer degree() const
Get the total degree.
Definition: dmpolynomial.h:322
void negativeOne()
Set polynomial to -1.
Definition: dmpolynomial.h:265
std::vector< Symbol > ringVariables() const
Get variable names.
Definition: dmpolynomial.h:886
int size() const
Get the size of the polynomial.
Definition: dmpolynomial.h:315
bool isOne() const
Is polynomial 1.
Definition: dmpolynomial.h:231
Field coefficient(int v, const int *d) const
Get a coefficient.
Definition: dmpolynomial.h:398
DistributedDenseMultivariateModularPolynomial(const Symbol &x, const Field &m)
Construct with a variable name such that f(x) = x;.
Definition: dmpolynomial.h:134
DistributedDenseMultivariateModularPolynomial< Field > & operator=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator =.
Definition: dmpolynomial.h:177
An abstract class defining the interface of a multivariate polynomial over an arbitrary BPASRing...
Definition: polynomial.h:117
DistributedDenseMultivariateModularPolynomial(const Field &m)
Constructor with the Field.
Definition: dmpolynomial.h:86
bool isZero() const
Is a zero polynomial.
Definition: dmpolynomial.h:211
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
~DistributedDenseMultivariateModularPolynomial()
Deconstructor.
Definition: dmpolynomial.h:166
DistributedDenseMultivariateModularPolynomial< Field > operator-() const
Overload operator -, negate.
Definition: dmpolynomial.h:685
An arbitrary-precision Integer.
Definition: Integer.hpp:22
void zero()
Zero polynomial.
Definition: dmpolynomial.h:223
bool operator!=(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator !=.
Definition: dmpolynomial.h:506
void one()
Set polynomial to 1.
Definition: dmpolynomial.h:243
DistributedDenseMultivariateModularPolynomial< Field > & operator+=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator +=.
Definition: dmpolynomial.h:580
int numberOfVariables() const
Get the number of variables.
Definition: dmpolynomial.h:288
void setCoefficient(int v, const int *d, const Field &val)
Set a coefficient.
Definition: dmpolynomial.h:421
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
int isConstant() const
Is a constant.
Definition: dmpolynomial.h:275
A multivariate polynomial with coefficients in an arbitrary finite field represented densely...
Definition: dmpolynomial.h:32
DistributedDenseMultivariateModularPolynomial< Field > & operator*=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator *=.
Definition: dmpolynomial.h:794
bool operator==(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator ==.
Definition: dmpolynomial.h:473
void setRingVariables(const std::vector< Symbol > &xs)
Set variable names.
Definition: dmpolynomial.h:870
void setCoefficient(int k, const Field &val)
Set a coefficient.
Definition: dmpolynomial.h:448
bool isNegativeOne() const
Is polynomial -1.
Definition: dmpolynomial.h:253