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