Basic Polynomial Algebra Subprograms (BPAS)  v. 1.700
mzpolynomial.hpp
1 #ifndef _SMZPALTARRAY_H_
2 #define _SMZPALTARRAY_H_
3 
4 #include "../Ring/Integer.hpp"
5 #include "../polynomial.h"
6 #include "uzpolynomial.h"
7 #include "../RingPolynomial/upolynomial.h"
8 #include "../RationalNumberPolynomial/mrpolynomial.h"
9 #include "SMZP_CppSupport.hpp"
10 #include "SMZP_Support.h"
11 #include "SMZP_Support_Test.h"
12 #include "SMZP_Support_Recursive.h"
13 #include <gmpxx.h>
14 #include "../ExpressionTree/ExpressionTree.hpp"
15 #include "../DataStructures/Factors.hpp"
16 
17 #if defined(WITH_BLAD) && WITH_BLAD
18 #include "../BLADInterface/bladinterface.h"
19 #endif
20 
21 #if defined(WITH_MAPLE) && WITH_MAPLE
22 #include "../MapleInterface/MapleInterfaceStream.hpp"
23 #endif
24 
26 
27 /**
28  * An element of the SLP of an integer polynomial.
29  */
31 
32  public:
33  union CoefOrInt {
34  Integer* c;
35  int i;
36  };
37 
38  int op; // 0: '+'; 1: '*'.
39  int type; // 0: coef & variate;
40  // 1: coef & result;
41  // 2: variate & result;
42  // 3: result & result;
43  // 4: coef (constant);
44  CoefOrInt a; // variate or result or coef position
45  int b; // variate or result or coef position
46  Interval res; // Storing the result
47 
49  a.c = NULL;
50  }
51 
53  op = r.op;
54  type = r.type;
55  b = r.b;
56  res = r.res;
57  if (type == 0 || type == 1 || type == 4) {
58  a.c = new Integer(*(r.a.c));
59  } else {
60  a.i = r.a.i;
61  }
62  }
63 
65  if (type == 0 || type == 1) {
66  delete a.c;
67  }
68  }
69 };
70 
71 /**
72  * A multivariate polynomial with Integer coefficients using a
73  * sparse representation. Only non-zero coefficients are encoded.
74  */
75 class SparseMultivariateIntegerPolynomial: public BPASRecursivelyViewedPolynomial<Integer,SparseMultivariateIntegerPolynomial> {
76 
77  private:
78  mutable AltArrZ_t* poly;
79  int nvar; //number of variables
80  Symbol* names; //list of strings representing the variables.
81  //names[0] is 1 if "system-generated" variables
82  //names[0] is 9 if "user-specified" variables
83 
85  friend class MapleInterface;
86 
87  /**
88  * Construct an SMZP given the alternating array.
89  */
90  SparseMultivariateIntegerPolynomial(AltArrZ_t* aa, int vars, Symbol* varNames);
91 
92  /**
93  * Attempt to construct an SMZP given the rational number alternating array.
94  */
95  SparseMultivariateIntegerPolynomial(const RationalNumber& r, AltArr_t* aa, int vars, Symbol* varNames);
96 
97  /**
98  * Determine if *this and b have compatible variable orderings.
99  * xs returns the mapping of both *this and b to the compatible superset
100  * returns true iff compatible.
101  */
102  bool isOrderedRing(const SparseMultivariateIntegerPolynomial& b, std::vector<int>& xs) const;
103 
104  /**
105  * Rearrange exponent vectors in place and then re-sort the polynomial.
106  */
107  void reorderVarsInPlace(int varmap[]);
108 
109  /**
110  * Rearrange exponent vectors, expanding as needed, and then re-sort the polynomial.
111  */
112  void expandVarsInPlace(int vars, Symbol* newvars, int varmap[]);
113 
114  /**
115  * Returns a copy of *this under the new variable ordering supplied.
116  * varmap is such that this.names[i] = newvars[varmap[i]]
117  * Returns an SMQP equal to *this but expended to newvars.
118  */
119  SparseMultivariateIntegerPolynomial expandVariables(int vars, Symbol* newvars, int varmap[]) const;
120 
121  public:
122 
124 
125  std::vector<SparseMultivariateIntegerPolynomial> subresultantChain (const SparseMultivariateIntegerPolynomial& q, int filled = 0) const;
126 
128 
129  std::vector<SLPZRepresentation> slp;
130 
131  /* Constructors */
132 
133  /**
134  * Construct a multivariate polynomial
135  *
136  **/
138 
139  /**
140  * Construct a multivariate polynomial with specific number of variables
141  *
142  * @param v: Number of variables
143  **/
145 
146  /**htop
147 
148  * Construct with a variable name such that f(x) = x;
149  *
150  * @param x: The variable name
151  **/
153 
154  /**
155  * Construct a polynomial by parsing the string str.
156  */
157  SparseMultivariateIntegerPolynomial (const std::string& str);
158 
159  /**
160  * Copy Constructor.
161  *
162  * Does not reuse underlying memory allocated by b.
163  *
164  * @param b: A sparse multivariate polynomial
165  **/
167 
168  /**
169  * Move Constructor.
170  *
171  * @params b: The r-value reference polynomial.
172  */
174 
175  /**
176  * Create a SMZP from an SMQP.
177  */
179 
180  /**
181  * Create a SMZP from an Integer.
182  */
183  SparseMultivariateIntegerPolynomial(const Integer& r, int nvar = 0);
184 
185  /**
186  * Create a SMZP from a RationalNumber.
187  */
188  SparseMultivariateIntegerPolynomial(const RationalNumber& r, int nvar = 0);
189 
190  /**
191  * Create a SMZP from a univariate rational polynomial.
192  *
193  * @param p: A SUZP polynomial.
194  **/
196 
197  /**
198  * Construct from a SUP<SMZP> polynomial such that the resulting SMZP
199  * has main variable equal to the variable of s.
200  *
201  * @param s: The SUP<SMZP> polynomial
202  **/
204 
205  /**
206  * Destroy the polynomial and underlying node memory.
207  **/
209 
210 
211  /* BPASRing interface */
212  static mpz_class characteristic;
213  static RingProperties properties;
214  // static bool isPrimeField;
215  // static bool isSmallPrimeField;
216  // static bool isComplexField;
217 
218  /**
219  * Is this polynomial zero.
220  * returns true iff this polynomial encodes 0.
221  */
222  bool isZero() const;
223 
224  /**
225  * Set this polynomial to zero. Maintains existing variable ordering.
226  */
227  void zero();
228 
229  /**
230  * Is this polynomial one.
231  * return true iff this polynomial encodes 1.
232  */
233  bool isOne() const;
234 
235  /**
236  * Sets this polynomial to one. Maintains existing variable ordering.
237  */
238  void one();
239 
240  /**
241  * Is this polynomial negative one.
242  * returns true iff this polynomial encodes -1.
243  */
244  bool isNegativeOne() const;
245 
246  /**
247  * Sets this polynomial to -1. Maintains existing variable ordering.
248  */
249  void negativeOne();
250 
251  /**
252  * Determine if this polynomial encodes a constant.
253  * returns 0 if not a constant, 1 if a constant >= 0, -1 if a negative contstant.
254  */
255  int isConstant() const;
256 
257  /**
258  * Obtain the unit normal (a.k.a canonical associate) of an element.
259  * If either parameters u, v, are non-NULL then the units are returned such that
260  * b = ua, v = u^-1. Where b is the unit normal of a, and is the returned value.
261  */
263  if (isZero()) {
264  return *this;
265  }
266 
267  if (mpz_cmp_si(this->poly->elems->coef, 0l) < 0) {
269  if (u != NULL) {
271  }
272  if (v != NULL) {
273  *v = *u;
274  }
275  return ret;
276  }
277 
278  if (u != NULL) {
279  (*u).one();
280  }
281  if (v != NULL) {
282  (*v).one();
283  }
284  return *this;
285  }
286 
287  /* BPASPolynomial interface */
288 
289  /**
290  * Assign this polynomail to equal the specified.
291  */
293 
294  /**
295  * Movement assignment: move b to be this polynomail.
296  */
298 
299  /**
300  * Assign this polynomial to be equal to the constant ring element.
301  */
302  SparseMultivariateIntegerPolynomial& operator= (const Integer& r);
303 
304  /**
305  * Add two SMQP polynomials together, *this and the specified.
306  */
309 
310  /**
311  * Add the polynomails a and b and return the sum.
312  */
313  // friend SparseMultivariateIntegerPolynomial operator+ (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
314 
315  /**
316  * Update *this by adding the specified polynomail to it.
317  */
319 
320  /**
321  * Subtract the specified polynomail from *this
322  */
325 
326  /**
327  * Subtract the polynomial b from a and return the difference.
328  */
329  // friend SparseMultivariateIntegerPolynomial operator- (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
330 
331  /**
332  * Unary operation, return *this * -1.
333  */
334  SparseMultivariateIntegerPolynomial operator- () const;
335 
336  /**
337  * Update *this by subtracting the specified polynomial from it.
338  */
340 
341  /**
342  * Multiply *this by the specified polynomail.
343  */
346 
347  /**
348  * Multiply the polynomials a and b, returning their product.
349  */
350  // friend SparseMultivariateIntegerPolynomial operator* (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
351 
352  /**
353  * Update this by multiplying by the specified polynomail.
354  */
356 
357  /**
358  * Divide *this by the specified polynomial.
359  */
362 
363  // friend SparseMultivariateIntegerPolynomial operator/ (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
364 
365  /**
366  * Update *this by dividing by the specified polynomial.
367  */
369 
370  /**
371  * Exponentiate *this by the input exponent integer.
372  * Treats negative exponents as positive.
373  */
374  SparseMultivariateIntegerPolynomial operator^ (long long int e) const;
375 
376  /**
377  * Update *this by exponentiating this to the input integer.
378  * Treats negative exponents as positive.
379  */
380  SparseMultivariateIntegerPolynomial& operator^= (long long int e);
381 
382  /**
383  * Determine if *this is equal to the specified polynomial.
384  * This takes into account the variable ordering on both poylnomials
385  * in such a way that the same polynomial under different variable orderings
386  * are NOT equal.
387  */
388  bool operator== (const SparseMultivariateIntegerPolynomial& b) const;
389 
390  /**
391  * Determine if *this is not equal to the specified polynomial.
392  * This takes into account the variable ordering on both poylnomials
393  * in such a way that the same polynomial under different variable orderings
394  * are NOT equal.
395  */
396  bool operator!= (const SparseMultivariateIntegerPolynomial& b) const;
397 
398  /**
399  * Output the string representation of *this to the input ostream.
400  */
401  void print(std::ostream& os) const;
402 
403  /**
404  * Parse a polynomial from the in stream. Exactly one line is parsed.
405  */
406  friend std::istream& operator>>(std::istream& in, SparseMultivariateIntegerPolynomial& p);
407 
408  /**
409  * Parse a polynomial from the string str and place it in *this.
410  */
411  void fromString(const std::string& str);
412 
413  /**
414  * Get GCD between *this and b.
415  */
417 
418  /**
419  * Get the GCD between *this and b as a primitive polynomial.
420  */
422 
423  /**
424  * Compute squarefree factorization of *this with respect to all of its variables.
425  */
427 
428  /**
429  * Compute squarefree factorization of *this with respect to the list of variables, vars.
430  */
431  Factors<SparseMultivariateIntegerPolynomial> squareFree(const std::vector<Symbol>& vars) const;
432 
433  /**
434  * Computes the square free part of this polynomail. That is, the polynomial of this
435  * divided by all square factors. This is with respect to all variables.
436  */
437  SparseMultivariateIntegerPolynomial squareFreePart() const;
438 
439  /**
440  * Computes the square free part of this polynomail. That is, the polynomial of this
441  * divided by all square factors. This is with respect to all variables.
442  */
443  SparseMultivariateIntegerPolynomial squareFreePart(std::vector<Symbol>& vars) const;
444 
445  /**
446  * Get the content with respect to all variables. That is, a single
447  * rational number. The content here is one such that this/content is
448  * an integer polynomial with content of 1.
449  *
450  * Moreover, the content is one such that the leading coefficient
451  * of the corresponding primitive part is positive.
452  */
453  Integer content() const;
454 
455  /**
456  * Get the content of this polynomial with respect to the variables in
457  * the input vector v.
458  *
459  * Moreover, the content is one such that the leading coefficient
460  * of the corresponding primitive part is positive.
461  */
462  SparseMultivariateIntegerPolynomial content(const std::vector<Symbol>& v) const;
463 
464  /**
465  * Get the primitive part with respect to all variables.
466  * This is equivalent to this / content().
467  */
468  SparseMultivariateIntegerPolynomial primitivePart() const;
469 
470  /**
471  * Get the primitive part with respect to all variables.
472  * This is equivalent to this / content().
473  *
474  * Simultaneously returns the rational number content in the parameter content.
475  */
476  SparseMultivariateIntegerPolynomial primitivePart(Integer& content) const;
477 
478  /**
479  * Get the primitive part with respect to the variables in the vector v.
480  *
481  * returns the primitive part.
482  */
483  SparseMultivariateIntegerPolynomial primitivePart(const std::vector<Symbol>& v) const;
484 
485  /**
486  * Get the primitive part with respect to the variables in the vector v.
487  * Returns the corresponding content in the content reference.
488  * returns the primitive part.
489  */
490  SparseMultivariateIntegerPolynomial primitivePart(const std::vector<Symbol>& v, SparseMultivariateIntegerPolynomial& content) const;
491 
492  /**
493  * Get the leading coefficient of *this with respect to the main variable.
494  *
495  * returns the initial.
496  */
497  SparseMultivariateIntegerPolynomial initial() const;
498 
499  /**
500  * Get the main variable. That is, the highest-ordered variable with
501  * positive degree.
502  *
503  * returns the main variable.
504  */
505  inline Symbol mainVariable() const {
506  return leadingVariable();
507  }
508 
509  /**
510  * Get the degree of the main variable.
511  *
512  * returns the degree.
513  */
514  int mainDegree() const;
515 
516  /**
517  * Get the rank of this polynomial.
518  * That is, the main variable raised to the main degree.
519  *
520  * returns the rank.
521  */
523 
524  /**
525  * Get the head of this polynomial. That is, the initial multiplied
526  * by the rank.
527  *
528  * returns the head.
529  */
531 
532  /**
533  * Get the tail of this polynomial. That is, This - this.head().
534  *
535  * returns the tail.
536  */
538 
539  SparseMultivariateIntegerPolynomial separant() const;
540 
541  /* BPASMultivariatePolynomial interface */
542 
543  /**
544  * Get the number of variables in this polynomial.
545  */
546  int numberOfVariables() const;
547 
548  /**
549  * Get the number of variables in this polynomial ring.
550  */
551  inline int numberOfRingVariables() const {
552  return ringVariables().size();
553  }
554 
555  /**
556  * Get the number of non-zero terms
557  */
558  Integer numberOfTerms() const;
559 
560  /**
561  * Total degree.
562  */
563  Integer degree() const;
564 
565  /**
566  * Get the degree of a variable
567  */
568  Integer degree(const Symbol&) const;
569 
570  /**
571  * Get the leading coefficient
572  */
573  Integer leadingCoefficient() const;
574 
575  /**
576  * Set the leading coefficient.
577  */
578  void setLeadingCoefficient(const Integer& it);
579 
580  /**
581  * Get the trailing coefficient.
582  */
583  Integer trailingCoefficient() const;
584 
585  /**
586  * Get a coefficient, given the exponent of each variable
587  */
588  Integer coefficient(int, const int*) const;
589 
590  inline Integer coefficient(const std::vector<int>& v) const {
591  return coefficient(v.size(), v.data());
592  }
593 
594  /**
595  * Set a coefficient, given the exponent of each variable
596  */
597  void setCoefficient(int, const int*, const Integer&);
598 
599  inline void setCoefficient(const std::vector<int>& v, const Integer& r) {
600  setCoefficient(v.size(), v.data(), r);
601  }
602 
603 
604  /**
605  * Set variables' names.
606  *
607  * This method can be used to shrink, expand, re-order, and re-name the variables
608  * of the polynomial ring in which this polynomial belongs.
609  *
610  * Any symbol in the input vector that matches the current variables
611  * is considered a re-order. Non-matching symbols are considered a re-name
612  * and this renames is done in the order they appear by increasing index.
613  * For example: Q[x,y,z] -> Q[y,s,t] will have y reordered to be the
614  * first variable, x renamed to s, and z renamed to t.
615  *
616  * If the size of the input vector is greater than the current number of variables
617  * then the polynomial ring is being expanded. Matching variables from this
618  * polynomial are re-ordered as they appear in the input vector. Current variables
619  * that have no match in the input vector are re-named in order of increasing index
620  * of unused variables from the input vector.
621  * For example: Q[x,y,z] -> Q[s,t,z,x] will have y named to s, t a new variable,
622  * and z and x re-ordered accordingly.
623  *
624  * If the size of the input vector is less than the current number of variables
625  * then the polynomial ring is shrink to remove variables. Variables in the
626  * input vector that are also found to be in the current polynomial ring
627  * are matched and re-ordered as necessary.
628  *
629  * It is invalid to remove a variable which is non-zero in this polynomial.
630  */
631  void setRingVariables (const std::vector<Symbol>&);
632 
633  /**
634  * Get variable names of all variables available to this polynomial,
635  * even those that have zero degree.
636  */
637  std::vector<Symbol> ringVariables() const;
638 
639  /**
640  * Get variable names of variables with non-zero degree;
641  */
642  std::vector<Symbol> variables() const;
643 
644 
645  /* SMQP-specific */
646 
647  /**
648  * Determine if *this is equal to b.
649  * This takes into account the variable ordering on both poylnomials
650  * in such a way that the same polynomial under different variable orderings
651  * are NOT equal.
652  */
653  bool isEqual(const SparseMultivariateIntegerPolynomial& b) const;
654 
655  /**
656  * Convert current object to its k-th derivative
657  *
658  * @param s: Symbol to differentiate with respect to
659  * @param k: Order of the derivative, k > 0
660  **/
661  inline void differentiate(const Symbol& s, int k) {
662  *this = this->derivative(s, k);
663  }
664 
665  /**
666  * Convert current object to its derivative
667  *
668  * @param s: Symbol to differentiate with respect to
669  **/
670  inline void differentiate(const Symbol& s) {
671  this->differentiate(s,1);
672  }
673 
674  /**
675  * Return k-th derivative
676  *
677  * @param s: Symbol to differentiate with respect to
678  * @param k: Order of the k-th derivative, k > 0
679  **/
680  SparseMultivariateIntegerPolynomial derivative(const Symbol& s, int k) const;
681 
682  /**
683  * Compute derivative
684  *
685  * @param s: Symbol to differentiate with respect to
686  **/
688  return this->derivative(s,1);
689  }
690 
691  /**
692  * Convert current object to its k-th integral
693  *
694  * @param s: Symbol to differentiate with respect to
695  * @param k: Order of the derivative, k > 0
696  **/
697  inline void integrate(const Symbol& s, int k) {
698  *this = this->integral(s, k);
699  }
700 
701  /**
702  * Convert current object to its derivative
703  *
704  * @param s: Symbol to differentiate with respect to
705  **/
706  inline void integrate(const Symbol& s) {
707  this->integrate(s,1);
708  }
709 
710  /**
711  * Return k-th integral. If Symbol s is not a symbol contained in this
712  * polynomial then it becomes the main variable of the result and
713  * integration proceeds as expected.
714  *
715  * If the integral of this polynomial cannot be represented as an integer
716  * polynomial then an error occurs. See rationalIntegral().
717  *
718  * @param s: Symbol to differentiate with respect to
719  * @param k: Order of the k-th derivative, k > 0
720  **/
721  SparseMultivariateIntegerPolynomial integral(const Symbol& s, int k) const;
722 
723  /**
724  * Return k-th integral. If Symbol s is not a symbol contained in this
725  * polynomial then it becomes the main variable of the result and
726  * integration proceeds as expected.
727  *
728  * This method returns a rational number polynomial and therefore works
729  * regardless of the coefficients of this polynomial.
730  *
731  * @param s: Symbol to differentiate with respect to
732  * @param k: Order of the k-th derivative, k > 0
733  **/
734  SparseMultivariateRationalPolynomial rationalIntegral(const Symbol& s, int k) const;
735 
736  /**
737  * Compute integral
738  *
739  * @param s: Symbol to differentiate with respect to
740  **/
742  return this->integral(s,1);
743  }
744 
745  /**
746  * Return the integral of this, with respect to Symbol s, as a rational number polynomial.
747  *
748  * @param s: the symbol to integrate with respect to
749  * returns the integral
750  */
751  SparseMultivariateRationalPolynomial rationalIntegral(const Symbol& s) const;
752 
753  /**
754  * Evaluate f(x)
755  *
756  * @param syms: Array of Symbols to evaluate at corresponding xs
757  * @param xs: Evaluation points
758  **/
759  inline SparseMultivariateIntegerPolynomial evaluate(int n, const Symbol* syms, const Integer* xs) const {
760  std::vector<Symbol> vecSyms;
761  std::vector<Integer> vecRats;
762  vecSyms.reserve(n);
763  vecRats.reserve(n);
764  for (int i = 0; i < n; ++i) {
765  vecSyms.push_back(syms[i]);
766  vecRats.push_back(xs[i]);
767  }
768  return evaluate(vecSyms, vecRats);
769  }
770 
771  /**
772  * Evaluate *this polynomial given the variables and their values in vars, and values.
773  * vars must be a list of variables which are a (not necessarily proper) subset.
774  * vars and values should have matching indices. i.e. the values of vars[i] is values[i].
775  *
776  * returns a new SMQP where all variables in vars have been evaluated using the values given.
777  */
778  SparseMultivariateIntegerPolynomial evaluate(const std::vector<Symbol>& vars, const std::vector<Integer>& values) const;
779 
780  /**
781  * Find the interpolating polynomial for the integer points and values specified by each vector, respectively.
782  * The points vector is a vector of vectors, where each element of the outer vector represents a multi-dimensional point.
783  * Each multi-dimensional point should have the same number of dimensions and in the same order.
784  *
785  * An error will occur if the resulting interpolating polynomial cannot be represented as an integer polynomial.
786  *
787  * returns the interpolating polynomial.
788  */
789  static SparseMultivariateIntegerPolynomial interpolate(const std::vector<std::vector<Integer>>& points, const std::vector<Integer>& vals);
790 
791  /**
792  * Find the interpolating polynomial for the rational number points and values specified by each vector, respectively.
793  * The points vector is a vector of vectors, where each element of the outer vector represents a multi-dimensional point.
794  * Each multi-dimensional point should have the same number of dimensions and in the same order.
795  *
796  * An error will occur if the resulting interpolating polynomial cannot be represented as an integer polynomial.
797  *
798  * returns the interpolating polynomial.
799  */
800  static SparseMultivariateIntegerPolynomial interpolate(const std::vector<std::vector<RationalNumber>>& points, const std::vector<RationalNumber>& vals);
801 
802 
803  /**
804  * Divide this by polynomial b, returning the quotient and remainder in q and r, respectively.
805  *
806  * returns a boolean indicating if the division was exact.
807  */
809 
810  /**
811  * Divide this by polynomial b, return the quotient and remainder in q and r as rational number polynomials.
812  * This differs from the normal divide function where divisibility of coefficients does not matter as the result
813  * belongs to the polynomial ring over the rational numbers.
814  *
815  * returns a boolean indicating if the division was exact.
816  */
818 
819  /**
820  * Get the remainder of *this divided by b.
821  */
823 
824  /**
825  * Update *this by setting it to the remainder of *this divided by b.
826  */
828 
829  /**
830  * Pseudo divide this by b. The remainder is returned.
831  * if parameter quo is not null then the quotient is returned in quo.
832  * if parameter mult is not null then the multiplier is set to the initial of b
833  * raised to the power of degree(c, mvar(c)) - degree(b, mvar(c)) + 1.
834  *
835  * returns the pseudo remainder.
836  */
838 
839 
840  /**
841  * Add *this and a mpz_t.
842  */
843  inline SparseMultivariateIntegerPolynomial operator+ (const mpz_t r) const {
844  return (*this + mpz_class(r));
845  }
846 
847  /**
848  * Add *this and the mpz_class r.
849  */
850  SparseMultivariateIntegerPolynomial operator+ (const mpz_class& r) const;
851 
852  inline SparseMultivariateIntegerPolynomial operator+ (const Integer& r) const {
853  return (*this + r.get_mpz());
854  }
855 
856  /**
857  * Add mpz_t r and SMQP b.
858  */
859  inline friend SparseMultivariateIntegerPolynomial operator+ (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) {
860  return (b + r);
861  }
862 
863  /**
864  * Update *this by adding r
865  */
866  inline SparseMultivariateIntegerPolynomial& operator+= (const mpz_t r) {
867  return (*this += mpz_class(r));
868  }
869 
870 
871  /**
872  * Add mpz_class r and SMQP b.
873  */
874  inline friend SparseMultivariateIntegerPolynomial operator+ (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
875  return (b + r);
876  }
877 
878  /**
879  * Update *this by adding the mpz_class r to it.
880  */
881  SparseMultivariateIntegerPolynomial& operator+= (const mpz_class& r);
882 
883  /**
884  * Update *this by adding the Integer r to it.
885  */
886  inline SparseMultivariateIntegerPolynomial& operator+= (const Integer& r) {
887  *this += r.get_mpz();
888  return *this;
889  }
890 
891  /**
892  * Subtract the mpz_t r from *this.
893  */
894  inline SparseMultivariateIntegerPolynomial operator- (const mpz_t r) const {
895  return (*this - mpz_class(r));
896  }
897 
898  /**
899  * Subtract the mpz_class r from *this.
900  */
901  SparseMultivariateIntegerPolynomial operator- (const mpz_class& r) const;
902 
903  /**
904  * Subtract the Integer r from *this.
905  */
906  inline SparseMultivariateIntegerPolynomial operator- (const Integer& r) const {
907  return (*this - r.get_mpz());
908  }
909 
910  /**
911  * Subtract SMQP b from mpz_t r.
912  */
913  inline friend SparseMultivariateIntegerPolynomial operator- (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) {
914  return (-b + r);
915  }
916 
917  /**
918  * Update *this by subtracting mpz_t r.
919  */
920  inline SparseMultivariateIntegerPolynomial& operator-= (const mpz_t r) {
921  return (*this -= mpz_class(r));
922  }
923 
924 
925  /**
926  * Subtract SMQP b from mpz_class r.
927  */
928  inline friend SparseMultivariateIntegerPolynomial operator- (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
929  return (-b + r);
930  }
931 
932  /**
933  * Update *this by subtracting mpz_class r.
934  */
935  SparseMultivariateIntegerPolynomial& operator-= (const mpz_class& r);
936 
937  /**
938  * Update *this by subtracting Integer r.
939  */
940  inline SparseMultivariateIntegerPolynomial& operator-= (const Integer& r) {
941  *this -= r.get_mpz();
942  return *this;
943  }
944 
945  /**
946  * Multiply *this by mpz_t r.
947  */
948  inline SparseMultivariateIntegerPolynomial operator* (const mpz_t r) const {
949  return (*this * mpz_class(r));
950  }
951 
952  /**
953  * Multiply *this by mpz_class r.
954  */
955  SparseMultivariateIntegerPolynomial operator* (const mpz_class& r) const;
956 
957  /**
958  * Multiply *this by Integer r.
959  */
960  inline SparseMultivariateIntegerPolynomial operator* (const Integer& r) const {
961  return (*this * r.get_mpz());
962  }
963 
964  /**
965  * Multiply mpz_t r and SMQP b.
966  */
967  inline friend SparseMultivariateIntegerPolynomial operator* (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) {
968  return (b * r);
969  }
970 
971  /**
972  * Update *this by multiplying by mpz_t r.
973  */
974  inline SparseMultivariateIntegerPolynomial& operator*= (const mpz_t r) {
975  return (*this *= mpz_class(r));
976  }
977 
978  /**
979  * Multiply mpz_class r and SMQP b.
980  */
981  inline friend SparseMultivariateIntegerPolynomial operator* (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
982  return (b * r);
983  }
984 
985  /**
986  * Update *this by multiplying by mpz_class r.
987  */
988  SparseMultivariateIntegerPolynomial& operator*= (const mpz_class& r);
989 
990  /**
991  * Update *this by multiplying by Integer r.
992  */
993  inline SparseMultivariateIntegerPolynomial& operator*= (const Integer& r) {
994  *this *= r.get_mpz();
995  return *this;
996  }
997 
998  /**
999  * Divide *this by mpz_t r.
1000  */
1001  inline SparseMultivariateIntegerPolynomial operator/ (const mpz_t r) const {
1002  return (*this / mpz_class(r));
1003  }
1004 
1005  /**
1006  * Divide *this by mpz_class r.
1007  */
1008  SparseMultivariateIntegerPolynomial operator/ (const mpz_class& r) const;
1009 
1010  /**
1011  * Divide *this by Integer r.
1012  */
1013  inline SparseMultivariateIntegerPolynomial operator/ (const Integer& r) const {
1014  return (*this / r.get_mpz());
1015  }
1016 
1017  /**
1018  * Divide mpz_t r by SMQP b.
1019  */
1020  friend SparseMultivariateIntegerPolynomial operator/ (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) ;
1021 
1022  /**
1023  * Update *this by dividing by mpz_t r.
1024  */
1025  inline SparseMultivariateIntegerPolynomial& operator/= (const mpz_t r) {
1026  return (*this /= mpz_class(r));
1027  }
1028  /**
1029  * Divide mpz_class r by SMQP b.
1030  */
1031  inline friend SparseMultivariateIntegerPolynomial operator/ (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
1032  mpz_t t;
1033  mpz_init(t);
1034  mpz_set(t, r.get_mpz_t());
1036  mpz_clear(t);
1037  return ret;
1038  }
1039 
1040  /**
1041  * Update *this by dividing by mpz_class r.
1042  */
1043  SparseMultivariateIntegerPolynomial& operator/= (const mpz_class& r);
1044  /**
1045  * Update *this by dividing by Integer r.
1046  */
1047  inline SparseMultivariateIntegerPolynomial& operator/= (const Integer& r) {
1048  *this /= r.get_mpz();
1049  return *this;
1050  }
1051 
1052  /**
1053  * Get the polynomial term at index. Returns 0 if index is beyond the
1054  * number of terms in this polynomial.
1055  */
1056  SparseMultivariateIntegerPolynomial operator[] (int index) const;
1057 
1058  /**
1059  * Get the leading variable, that is, the highest-order variable with positive degree
1060  * of this polynomial.
1061  * returns the leading variable or the empty string if this polynomial has zero variables.
1062  */
1063  Symbol leadingVariable() const;
1064 
1065  /**
1066  * Get the degree of this polynomial w.r.t the leading variable.
1067  */
1068  Integer leadingVariableDegree() const;
1069 
1070  /**
1071  * Is the contant term zero.
1072  */
1073  bool isConstantTermZero() const;
1074 
1075  /**
1076  * Get the leading coefficient w.r.t the input variable 'x'.
1077  * Returns the leading exponent as e.
1078  *
1079  * returns the coefficient as a new SMQP.
1080  */
1081  SparseMultivariateIntegerPolynomial leadingCoefficientInVariable (const Symbol& x, int* e = NULL) const;
1082 
1083  /**
1084  * Convert to a SUP<SMQP> given the variable 'x'.
1085  *
1086  * returns the SUP<SMQP>.
1087  */
1089 
1090  /**
1091  * Negate all the coefficients of *this. Note, that due to the
1092  * sharing nature of underling nodes, this may alter the Nodes of
1093  * other SMQP.
1094  */
1095  void negate();
1096 
1097  /**
1098  * Get a copy of this such that all underlying memory is NOT shared.
1099  * Note, any following arithmetic operations on the returned result
1100  * will result in possibly making the underlying memory shared again.
1101  */
1102  SparseMultivariateIntegerPolynomial deepCopy() const;
1103 
1104  /**
1105  * Factors this polynomial into irreducible factors.
1106  * The Factors may include a common numerical (integer) factor.
1107  * See also, Factors.
1108  */
1110 
1111  /**
1112  * SLP representation of the polynomial
1113  **/
1114  void straightLineProgram();
1115 
1116  /**
1117  * Print SLP representation
1118  **/
1119  void printSLP(std::ostream& out = std::cout) const;
1120 
1121  /**
1122  * Change *this to be a random non-zero polynomial.
1123  * numvar: number of variables
1124  * nterms: number of terms
1125  * coefBound: limit on the number of bits encoding the coefficients.
1126  * sparsity: succesive terms are at most sparsity away from each other
1127  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1128  */
1129  void randomPolynomial(int numvar, int nterms, unsigned long int coefBound, degree_t sparsity, bool includeNeg);
1130 
1131  /**
1132  * Change *this to be a random non-zero polynomial. The number of variables will
1133  * be equal to the size of the maxDegs vector. The term whose monomial
1134  * has exponents equal to those in maxDegs is guaranteed to exist in the
1135  * resulting polynomial.
1136  * A sparsity of 0 produces a dense polynomial. A sparsity of 1 produces only
1137  * one term; one whose monomial has exponents equal to maxDegs.
1138  *
1139  * coefBound: limit on the number of bits encoding the coefficients.
1140  * sparsity: a percentage of zero-terms between term with maxDegs and the constant term.
1141  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1142  */
1143  void randomPolynomial(std::vector<int> maxDegs, unsigned long int coefBound, float sparsity, bool includeNeg);
1144 
1145  /**
1146  * Convert *this to an ExpressionTree.
1147  *
1148  * returns the new ExpressionTree.
1149  */
1150  ExpressionTree convertToExpressionTree() const;
1151 };
1152 
1153 
1154 
1155 
1156 
1157 #endif //_SMQPLINKEDLIST_H_
A multivariate polynomial with Integer coefficients using a sparse representation.
Definition: mzpolynomial.hpp:75
A univariate polynomial over an arbitrary BPASRing represented sparsely.
Definition: BigPrimeField.hpp:21
A multivariate polynomial with RationalNumber coefficients represented sparely.
Definition: mrpolynomial.h:70
int numberOfRingVariables() const
Get the number of variables in this polynomial ring.
Definition: mzpolynomial.hpp:551
Definition: mzpolynomial.hpp:33
SparseMultivariateIntegerPolynomial evaluate(int n, const Symbol *syms, const Integer *xs) const
Evaluate f(x)
Definition: mzpolynomial.hpp:759
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
Data Structure for interval [a, b].
Definition: interval.h:9
SparseMultivariateIntegerPolynomial unitCanonical(SparseMultivariateIntegerPolynomial *u, SparseMultivariateIntegerPolynomial *v) const
Obtain the unit normal (a.k.a canonical associate) of an element.
Definition: mzpolynomial.hpp:262
A univariate polynomial with Integer coefficients using a dense representation.
Definition: uzpolynomial.h:13
Symbol mainVariable() const
Get the main variable.
Definition: mzpolynomial.hpp:505
SparseMultivariateIntegerPolynomial integral(const Symbol &s) const
Compute integral.
Definition: mzpolynomial.hpp:741
void differentiate(const Symbol &s, int k)
Convert current object to its k-th derivative.
Definition: mzpolynomial.hpp:661
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
An arbitrary-precision Integer.
Definition: Integer.hpp:22
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
An arbitrary-precision rational number.
Definition: RationalNumber.hpp:24
An element of the SLP of an integer polynomial.
Definition: mzpolynomial.hpp:30
void one()
Sets this polynomial to one.
void integrate(const Symbol &s)
Convert current object to its derivative.
Definition: mzpolynomial.hpp:706
SparseMultivariateIntegerPolynomial derivative(const Symbol &s) const
Compute derivative.
Definition: mzpolynomial.hpp:687
void integrate(const Symbol &s, int k)
Convert current object to its k-th integral.
Definition: mzpolynomial.hpp:697
void differentiate(const Symbol &s)
Convert current object to its derivative.
Definition: mzpolynomial.hpp:670
An abstract class defining the interface of a multivariate polynomial that can be viewed recursively...
Definition: polynomial.h:166