Basic Polynomial Algebra Subprograms (BPAS)  v. 1.791
mrpolynomial.h
1 #ifndef _SMQPALTARRAY_H_
2 #define _SMQPALTARRAY_H_
3 
4 #include "../Polynomial/BPASRecursivePolynomial.hpp"
5 #include "../Interval/interval.h"
6 #include "urpolynomial.h"
7 #include "../IntegerPolynomial/mzpolynomial.hpp"
8 #include "../RingPolynomial/upolynomial.h"
9 #include "SMQP_CppSupport-AA.hpp"
10 #include "SMQP_Support-AA.h"
11 #include "SMQP_Support_Test-AA.h"
12 #include "SMQP_Support_Recursive-AA.h"
13 #include <gmpxx.h>
14 #include "../ExpressionTree/ExpressionTree.hpp"
15 #include "../DataStructures/Factors.hpp"
16 #include "../TriangularSet/triangularset.hpp"
17 #include "../IntegerPolynomial/DUZP_Support.h"
18 #include "../ModularPolynomial/DUSP_Parallel.hpp"
19 #include "../Parser/bpas_parser.h"
20 
22 
23 /**
24  * An element of the SLP of a rational number polynomial.
25  */
27 
28  public:
29  union CoefOrInt {
30  RationalNumber* c;
31  int i;
32  };
33 
34  int op; // 0: '+'; 1: '*'.
35  int type; // 0: coef & variate;
36  // 1: coef & result;
37  // 2: variate & result;
38  // 3: result & result;
39  // 4: coef (constant);
40  CoefOrInt a; // variate or result or coef position
41  int b; // variate or result or coef position
42  Interval res; // Storing the result
43 
45  a.c = NULL;
46  }
47 
49  op = r.op;
50  type = r.type;
51  b = r.b;
52  res = r.res;
53  if (type == 0 || type == 1 || type == 4) {
54  a.c = new RationalNumber(*(r.a.c));
55  } else {
56  a.i = r.a.i;
57  }
58  }
59 
61  if (type == 0 || type == 1) {
62  delete a.c;
63  }
64  }
65 };
66 
67 /**
68  * A multivariate polynomial with RationalNumber coefficients represented sparely.
69  * Only non-zero coefficients are encoded.
70  */
71 class SparseMultivariateRationalPolynomial: public BPASRecursivelyViewedPolynomial<RationalNumber,SparseMultivariateRationalPolynomial> {
72 
73  private:
74  mutable AltArr_t* poly;
75  int nvar; //number of variables
76  Symbol* names; //list of strings representing the variables.
77  //names[0] is 1 if "system-generated" variables
78  //names[0] is 9 if "user-specified" variables;
79 
80 
82 
83  /**
84  * Determine if *this and b have compatible variable orderings.
85  * xs returns the mapping of both *this and b to the compatible superset
86  * returns true iff compatible.
87  */
88  bool isOrderedRing(const SparseMultivariateRationalPolynomial& b, std::vector<int>& xs) const;
89 
90  /**
91  * Rearrange exponent vectors in place and then re-sort the polynomial.
92  */
93  void reorderVarsInPlace(int varmap[]);
94 
95  /**
96  * Rearrange exponent vectors, expanding as needed, and then re-sort the polynomial.
97  */
98  void expandVarsInPlace(int vars, Symbol* newvars, int varmap[]);
99 
100  /**
101  * Returns a copy of *this under the new variable ordering supplied.
102  * varmap is such that this.names[i] = newvars[varmap[i]]
103  * Returns an SMQP equal to *this but expended to newvars.
104  */
105  SparseMultivariateRationalPolynomial expandVariables(int vars, Symbol* newvars, int varmap[]) const;
106 
107  void preparePolysForSRC(const SparseMultivariateRationalPolynomial& q, const Symbol& v, std::vector<Symbol>& superRing, bool sameRing, int* varMap, int& swapIdx, AltArrZ_t** ppZ, AltArrZ_t** qqZ) const;
108 
109  public:
110 
111 
113 
114  std::vector<SLPRepresentation> slp;
115 
116  /* Constructors */
117 
118  /**
119  * Construct a multivariate polynomial
120  *
121  **/
123 
124  /**
125  * Construct a multivariate polynomial with specific number of variables
126  *
127  * @param v: Number of variables
128  **/
130 
131  /**
132  * Construct with a variable name such that f(x) = x;
133  *
134  * @param x: The variable name
135  **/
137 
138  /**
139  * Construct a polynomial by parsing the string str.
140  */
141  SparseMultivariateRationalPolynomial (const std::string& str);
142 
143  /**
144  * Construct an SMQP given the head Node*. The SMQP takes ownership
145  * of the Node list.
146  */
147  SparseMultivariateRationalPolynomial(AltArr_t* aa, int vars, Symbol* varNames);
148 
149  /**
150  * Copy Constructor.
151  *
152  * Does not reuse underlying memory allocated by b.
153  *
154  * @param b: A sparse multivariate polynomial
155  **/
157 
158  /**
159  * Move Constructor.
160  *
161  * @params b: The r-value reference polynomial.
162  */
164 
165  /**
166  * Create a SMZP from an SMQP.
167  */
169 
170  /**
171  * Create a SMQP from an Integer.
172  */
173  SparseMultivariateRationalPolynomial(const Integer& r, int nvar = 0);
174 
175  /**
176  * Create a SMQP from a RationalNumber.
177  */
179 
180  /**
181  * Create a SMQP from a univariate rational polynomial.
182  *
183  * @param p: A SUQP polynomial.
184  **/
186 
187  /**
188  * Construct from a SUP<SMQP> polynomial such that the resulting SMQP
189  * has main variable equal to the variable of s.
190  *
191  * @param s: The SUP<SMQP> polynomial
192  **/
194 
195  /**
196  * Destroy the polynomial and underlying node memory.
197  **/
199 
200 
201  /* BPASRing interface */
202  // static bool isPrimeField;
203  // static bool isSmallPrimeField;
204  // static bool isComplexField;
205 
206  /**
207  * Is this polynomial zero.
208  * returns true iff this polynomial encodes 0.
209  */
210  bool isZero() const;
211 
212  /**
213  * Set this polynomial to zero. Maintains existing variable ordering.
214  */
215  void zero();
216 
217  /**
218  * Is this polynomial one.
219  * return true iff this polynomial encodes 1.
220  */
221  bool isOne() const;
222 
223  /**
224  * Sets this polynomial to one. Maintains existing variable ordering.
225  */
226  void one();
227 
228  /**
229  * Is this polynomial negative one.
230  * returns true iff this polynomial encodes -1.
231  */
232  bool isNegativeOne() const;
233 
234  /**
235  * Sets this polynomial to -1. Maintains existing variable ordering.
236  */
237  void negativeOne();
238 
239  /**
240  * Determine if this polynomial encodes a constant.
241  * returns 0 if not a constant, 1 if a constant >= 0, -1 if a negative contstant.
242  */
243  int isConstant() const;
244 
245  /**
246  * Obtain the unit normal (a.k.a canonical associate) of an element.
247  * If either parameters u, v, are non-NULL then the units are returned such that
248  * b = ua, v = u^-1. Where b is the unit normal of a, and is the returned value.
249  */
252  RationalNumber leadInv = lead.inverse();
253  if (u != NULL) {
254  *u = leadInv;
255  }
256  if (v != NULL) {
257  *v = lead;
258  }
259  return (*this * leadInv);
260  }
261 
262  /* BPASPolynomial interface */
263 
264  /**
265  * Assign this polynomail to equal the specified.
266  */
268 
269  /**
270  * Movement assignment: move b to be this polynomail.
271  */
273 
274  /**
275  * Assign this polynomial to be equal to the constant ring element.
276  */
278 
279  /**
280  * Add two SMQP polynomials together, *this and the specified.
281  */
284 
285  // /**
286  // * Add the polynomails a and b and return the sum.
287  // */
288  // friend SparseMultivariateRationalPolynomial operator+ (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
289 
290  /**
291  * Update *this by adding the specified polynomail to it.
292  */
294 
295  /**
296  * Subtract the specified polynomail from *this
297  */
300 
301  // /**
302  // * Subtract the polynomial b from a and return the difference.
303  // */
304  // friend SparseMultivariateRationalPolynomial operator- (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
305 
306  /**
307  * Unary operation, return *this * -1.
308  */
310 
311  /**
312  * Update *this by subtracting the specified polynomial from it.
313  */
315 
316  /**
317  * Multiply *this by the specified polynomail.
318  */
321 
322  // /**
323  // * Multiply the polynomials a and b, returning their product.
324  // */
325  // friend SparseMultivariateRationalPolynomial operator* (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
326 
327  /**
328  * Update this by multiplying by the specified polynomail.
329  */
331 
332  /**
333  * Divide *this by the specified polynomial.
334  */
337 
338  // friend SparseMultivariateRationalPolynomial operator/ (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
339 
340  /**
341  * Update *this by dividing by the specified polynomial.
342  */
344 
345  /**
346  * Exponentiate *this by the input exponent integer.
347  * Treats negative exponents as positive.
348  */
349  SparseMultivariateRationalPolynomial operator^ (long long int e) const;
350 
351  /**
352  * Update *this by exponentiating this to the input integer.
353  * Treats negative exponents as positive.
354  */
356 
357  /**
358  * Determine if *this is equal to the specified polynomial.
359  * This takes into account the variable ordering on both poylnomials
360  * in such a way that the same polynomial under different variable orderings
361  * are NOT equal.
362  */
364 
365  /**
366  * Determine if *this is not equal to the specified polynomial.
367  * This takes into account the variable ordering on both poylnomials
368  * in such a way that the same polynomial under different variable orderings
369  * are NOT equal.
370  */
372 
373  /**
374  * Output the string representation of *this to the input ostream.
375  */
376  void print(std::ostream& os) const;
377 
378  /**
379  * Parse polynomial from in stream. Exactly one line is parsed.
380  */
381  friend std::istream& operator>>(std::istream& in, SparseMultivariateRationalPolynomial& p);
382 
383  /**
384  * Parse a polynomial from string str and place in *this.
385  */
386  void fromString(const std::string& str);
387 
388  /**
389  * Given a polynomial q, compute the subresultant chain between this and q, viewing both polynomial
390  * recursively with main variable v.
391  *
392  * @note, if this and q do not exist in the same ambient space, the space of p will define the ordering of the subresultants.
393  *
394  * @param q: the other polynomial for which to compute the subresultant chain.
395  * @param v: the main variable to be used when computing the subresultant chain.
396  * @param filled: if false, degenerative cases are not returned and so indices in the returned chain do not necessarily match subresultant degrees
397  *
398  * @return a vector containing the subresultant chain whereby index 0 is resultant and subresultant degrees increase with index.
399  *
400  */
401  std::vector<SparseMultivariateRationalPolynomial> subresultantChain(const SparseMultivariateRationalPolynomial& q, const Symbol& v, bool filled = 1) const;
402 
403  /**
404  * Subresultant Chain with respect to the leaving variable of this.
405  * Return the list of subresultants
406  **/
407  std::vector<SparseMultivariateRationalPolynomial> subresultantChain (const SparseMultivariateRationalPolynomial& q, int filled = 1) const;
408 
409  /**
410  * Given a polynomial q, compute the subresultant of index idx between this and q, viewing both polynomial
411  * recursively with main variable v. This function in fact computes the subresultant of index idx and idx+1
412  * and so both are returned, unless idx+1 does not exist (e.g. idx = this->degree(v)).
413  *
414  * Optionally, this function also returns the principleCoefs of the subresultants of index i to this->degree(v).
415  *
416  * @note, if the subresultant of index idx+1 is degenerative then many subresultants will be returned until the first non-degenerative one is found.
417  * @note, if this and q do not exist in the same ambient space, the space of p will define the ordering of the subresultants.
418  *
419  * @param q: the other polynomial for which to compute the subresultant chain.subresultantInit
420  * @param v: the main variable to be used when computing the subresultant chain.
421  *
422  * @return two successive subresultants: S_{i}, S_{i+1} s.t. deg(S_{i}) <= idx and deg(S_{i+1} > idx
423  *
424  */
425  std::vector<SparseMultivariateRationalPolynomial> subresultantAtIdx (const SparseMultivariateRationalPolynomial& q, const Symbol& v, int idx = 0, specSRC_AAZ **lazyInfo = NULL) const;
426 
427  /**
428  * Compute the initials of two successive subresultants: S_{i}, S_{i+1} s.t. deg(S_{i}) <= idx and deg(S_{i+1} > idx.
429  * This returns init(S_{i},v) and init(S_{i+1}, v) as a vector.
430  * The degrees degree(S_{i},v) and degree(S_{i+1}, v) are returned in mdegIdx and mdegIdx1, respectively.
431  * These degrees can be used to determine if certain subresultants are defective, i.e. degree(S_{i}, v) != i.
432  */
433  std::vector<SparseMultivariateRationalPolynomial> subresultantInitialAtIdx (const SparseMultivariateRationalPolynomial& q, const Symbol& v, int idx, Integer& mdegIdx, Integer& mdegIdx1, specSRC_AAZ **lazyInfo = NULL) const;
434 
435  /**
436  * Compute the initials of two successive subresultants: S_{i}, S_{i+1} s.t. deg(S_{i}) <= idx and deg(S_{i+1} > idx.
437  * This returns init(S_{i},v) and init(S_{i+1}, v) as a vector.
438  */
439  std::vector<SparseMultivariateRationalPolynomial> subresultantInitialAtIdx (const SparseMultivariateRationalPolynomial& q, const Symbol& v, int idx = 0, specSRC_AAZ **lazyInfo = NULL) const {
440  Integer d1, d2;
441  return this->subresultantInitialAtIdx(q, v, idx, d1, d2, lazyInfo);
442  }
443 
444  /**
445  * Extended Subresultant Chain
446  * Return the list of subresultants with Besout Coefficients
447  */
448  std::vector<std::vector<SparseMultivariateRationalPolynomial>> exSubresultantChain (const SparseMultivariateRationalPolynomial& q, const Symbol& v) const;
449 
451 
452  /**
453  * Get GCD between *this and b.
454  */
456 
457  /**
458  * Get the GCD between *this and b as a primitive polynomial.
459  */
461 
462  /**
463  * Compute squarefree factorization of *this with respect to all of its variables.
464  */
466 
467  /**
468  * Compute squarefree factorization of *this with respect to the list of variables, vars.
469  */
470  Factors<SparseMultivariateRationalPolynomial> squareFree(const std::vector<Symbol>& vars) const;
471 
472  /**
473  * Computes the square free part of this polynomail. That is, the polynomial of this
474  * divided by all square factors. This is with respect to all variables.
475  */
477 
478  /**
479  * Computes the square free part of this polynomail. That is, the polynomial of this
480  * divided by all square factors. This is with respect to all variables.
481  */
482  SparseMultivariateRationalPolynomial squareFreePart(std::vector<Symbol>& vars) const;
483 
484  /**
485  * Get the content with respect to all variables. That is, a single
486  * rational number. The content here is one such that this/content is
487  * an integer polynomial with content of 1.
488  *
489  * Moreover, the content is one such that the leading coefficient
490  * of the corresponding primitive part is positive.
491  */
492  RationalNumber content() const;
493 
494  /**
495  * Get the content of this polynomial with respect to the variables in
496  * the input vector v.
497  *
498  * Moreover, the content is one such that the leading coefficient
499  * of the corresponding primitive part is positive.
500  */
501  SparseMultivariateRationalPolynomial content(const std::vector<Symbol>& v) const;
502 
503  /**
504  * Get the primitive part with respect to all variables, returned as an SMZP.
505  * This is equivalent to this / content();
506  */
507  SparseMultivariateIntegerPolynomial primitivePartSMZP() const;
508 
509  /**
510  * Get the primitive part with respect to all variables, returned as an SMZP.
511  * This is equivalent to this / content();
512  *
513  * Simultaneously returns the rational number content in the parameter content.
514  */
515  SparseMultivariateIntegerPolynomial primitivePartSMZP(RationalNumber& content) const;
516 
517  /**
518  * Get the primitive part with respect to all variables.
519  * This is equivalent to this / content().
520  */
522 
523  /**
524  * Get the primitive part with respect to the variable s.
525  * This is equivalent to this / content(s).
526  */
528 
529  /**
530  * Get the primitive part with respect to all variables.
531  * This is equivalent to this / content().
532  *
533  * Simultaneously returns the rational number content in the parameter content.
534  */
536 
537  /**
538  * Get the primitive part with respect to the variables in the vector v.
539  *
540  * returns the primitive part.
541  */
542  SparseMultivariateRationalPolynomial primitivePart(const std::vector<Symbol>& v) const;
543 
544  /**
545  * Get the primitive part with respect to the variables in the vector v.
546  * Returns the corresponding content in the content reference.
547  * returns the primitive part.
548  */
550 
551  SparseMultivariateRationalPolynomial mainPrimitivePart() const;
552 
554 
555  /**
556  * Get the leading coefficient of *this with respect to the main variable.
557  *
558  * returns the initial.
559  */
561 
562  /**
563  * Get the main variable. That is, the highest-ordered variable with
564  * positive degree.
565  *
566  * returns the main variable.
567  */
568  inline Symbol mainVariable() const {
569  return leadingVariable();
570  }
571 
572  /**
573  * Get the degree of the main variable.
574  *
575  * returns the degree.
576  */
577  int mainDegree() const;
578 
579  /**
580  * Get the rank of this polynomial.
581  * That is, the main variable raised to the main degree.
582  *
583  * returns the rank.
584  */
586 
587  /**
588  * Get the head of this polynomial. That is, the initial multiplied
589  * by the rank.
590  *
591  * returns the head.
592  */
594 
595  /**
596  * Get the tail of this polynomial. That is, This - this.head().
597  *
598  * returns the tail.
599  */
601 
603 
604  /* BPASMultivariatePolynomial interface */
605 
606  /**
607  * Get the number of variables in this polynomial.
608  */
609  int numberOfVariables() const;
610 
611  /**
612  * Get the number of variables in this polynomial ring.
613  */
614  inline int numberOfRingVariables() const {
615  return ringVariables().size();
616  }
617 
618  /**
619  * Get the number of non-zero terms
620  */
621  Integer numberOfTerms() const;
622 
623  /**
624  * Total degree.
625  */
626  Integer degree() const;
627 
628  /**
629  * Get the degree of a variable
630  */
631  Integer degree(const Symbol&) const;
632 
633  /**
634  * Get the leading coefficient
635  */
637 
638  /**
639  * Get the trailing coefficient.
640  */
642 
643  /**
644  * Get a coefficient, given the exponent of each variable
645  */
646  RationalNumber coefficient(int, const int*) const;
647 
648  inline RationalNumber coefficient(const std::vector<int>& v) const {
649  return coefficient(v.size(), v.data());
650  }
651 
652  /**
653  * Set a coefficient, given the exponent of each variable
654  */
655  void setCoefficient(int, const int*, const RationalNumber&);
656 
657  inline void setCoefficient(const std::vector<int>& v, const RationalNumber& r) {
658  setCoefficient(v.size(), v.data(), r);
659  }
660 
661 
662  /**
663  * Set variables' names.
664  *
665  * This method can be used to shrink, expand, re-order, and re-name the variables
666  * of the polynomial ring in which this polynomial belongs.
667  *
668  * Any symbol in the input vector that matches the current variables
669  * is considered a re-order. Non-matching symbols are considered a re-name
670  * and this renames is done in the order they appear by increasing index.
671  * For example: Q[x,y,z] -> Q[y,s,t] will have y reordered to be the
672  * first variable, x renamed to s, and z renamed to t.
673  *
674  * If the size of the input vector is greater than the current number of variables
675  * then the polynomial ring is being expanded. Matching variables from this
676  * polynomial are re-ordered as they appear in the input vector. Current variables
677  * that have no match in the input vector are re-named in order of increasing index
678  * of unused variables from the input vector.
679  * For example: Q[x,y,z] -> Q[s,t,z,x] will have y named to s, t a new variable,
680  * and z and x re-ordered accordingly.
681  *
682  * If the size of the input vector is less than the current number of variables
683  * then the polynomial ring is shrink to remove variables. Variables in the
684  * input vector that are also found to be in the current polynomial ring
685  * are matched and re-ordered as necessary.
686  *
687  * It is invalid to remove a variable which is non-zero in this polynomial.
688  */
689  void setRingVariables (const std::vector<Symbol>&);
690 
691  /**
692  * Get variable names of all variables available to this polynomial,
693  * even those that have zero degree.
694  */
695  std::vector<Symbol> ringVariables() const;
696 
697  /**
698  * Get variable names of variables with non-zero degree;
699  */
700  std::vector<Symbol> variables() const;
701 
702 
703  /* SMQP-specific */
704 
705  /**
706  * Determine if *this is equal to b.
707  * This takes into account the variable ordering on both poylnomials
708  * in such a way that the same polynomial under different variable orderings
709  * are NOT equal.
710  */
711  bool isEqual(const SparseMultivariateRationalPolynomial& b) const;
712 
713  /**
714  * Convert current object to its k-th derivative
715  *
716  * @param s: Symbol to differentiate with respect to
717  * @param k: Order of the derivative, k > 0
718  **/
719  inline void differentiate(const Symbol& s, int k) {
720  *this = this->derivative(s, k);
721  }
722 
723  /**
724  * Convert current object to its derivative
725  *
726  * @param s: Symbol to differentiate with respect to
727  **/
728  inline void differentiate(const Symbol& s) {
729  this->differentiate(s,1);
730  }
731 
732  /**
733  * Return k-th derivative
734  *
735  * @param s: Symbol to differentiate with respect to
736  * @param k: Order of the k-th derivative, k > 0
737  **/
739 
740  /**
741  * Compute derivative
742  *
743  * @param s: Symbol to differentiate with respect to
744  **/
746  return this->derivative(s,1);
747  }
748 
749  /**
750  * Convert current object to its k-th integral
751  *
752  * @param s: Symbol to differentiate with respect to
753  * @param k: Order of the derivative, k > 0
754  **/
755  inline void integrate(const Symbol& s, int k) {
756  *this = this->integral(s, k);
757  }
758 
759  /**
760  * Convert current object to its derivative
761  *
762  * @param s: Symbol to differentiate with respect to
763  **/
764  inline void integrate(const Symbol& s) {
765  this->integrate(s,1);
766  }
767 
768  /**
769  * Return k-th integral. If Symbol s is not a symbol contained in this
770  * polynomial then it becomes the main variable of the result and
771  * integration proceeds as expected.
772  *
773  * @param s: Symbol to differentiate with respect to
774  * @param k: Order of the k-th derivative, k > 0
775  **/
777 
778  /**
779  * Compute integral
780  *
781  * @param s: Symbol to differentiate with respect to
782  **/
784  return this->integral(s,1);
785  }
786 
787  /**
788  * Evaluate f(x)
789  *
790  * @param syms: Array of Symbols to evaluate at corresponding xs
791  * @param xs: Evaluation points
792  **/
793  inline SparseMultivariateRationalPolynomial evaluate(int n, const Symbol* syms, const RationalNumber* xs) const {
794  std::vector<Symbol> vecSyms;
795  std::vector<RationalNumber> vecRats;
796  vecSyms.reserve(n);
797  vecRats.reserve(n);
798  for (int i = 0; i < n; ++i) {
799  vecSyms.push_back(syms[i]);
800  vecRats.push_back(xs[i]);
801  }
802  return evaluate(vecSyms, vecRats);
803  }
804 
805  /**
806  * Evaluate *this polynomial given the variables and their values in vars, and values.
807  * vars must be a list of variables which are a (not necessarily proper) subset.
808  * vars and values should have matching indices. i.e. the values of vars[i] is values[i].
809  *
810  * returns a new SMQP where all variables in vars have been evaluated using the values given.
811  */
812  SparseMultivariateRationalPolynomial evaluate(const std::vector<Symbol>& vars, const std::vector<RationalNumber>& values) const;
813 
814  /**
815  * Find the interpolating polynomial for the points and values specified by each vector, respectively.
816  * The points vector is a vector of vectors, where each element of the outer vector represents a multi-dimensional point.
817  * Each multi-dimensional point should have the same number of dimensions and in the same order.
818  *
819  * returns the interpolating polynomial.
820  */
821  static SparseMultivariateRationalPolynomial interpolate(const std::vector<std::vector<RationalNumber>>& points, const std::vector<RationalNumber>& vals);
822 
823  /**
824  * Divide this by polynomial b, returning the quotient and remainder in q and r, respectively.
825  *
826  * returns a boolean indicating if the division was exact.
827  */
829 
830  /**
831  * Get the remainder of *this divided by b.
832  */
834 
835  /**
836  * Update *this by setting it to the remainder of *this divided by b.
837  */
839 
840 
843  ret %= i;
844  return ret;
845  }
846 
848  if (!this->isZero()) {
849  applyModuloSymmetricPrimPart_AA_inp(this->poly, i.get_mpz_t());
850  }
851  return *this;
852  }
853 
854  /**
855  * Pseudo divide this by b. The remainder is returned.
856  * if parameter quo is not null then the quotient is returned in quo.
857  * if parameter mult is not null then the multiplier is set to the initial of b
858  * raised to the power of degree(c, mvar(c)) - degree(b, mvar(c)) + 1.
859  *
860  * returns the pseudo remainder.
861  */
863 
864  /**
865  * Pseudo divide this by b. The remainder is returned.
866  * This function assumes that both this and b are primitive, and thus
867  * can be viewed as integer polynomials. The psuedo-division is then performed
868  * over the integers and the quotient and remainder returned also so they are primitive.
869  *
870  * If parameter quo is not null then the quotient is returned in quo.
871  * If parameter mult is not null then the multiplier is set to the initial of b
872  * raised to the power of degree(c, mvar(c)) - degree(b, mvar(c)) + 1.
873  *
874  * @return the pseudo remainder.
875  */
877 
878 
879  /**
880  * Add *this and a ratNum_t.
881  */
882  inline SparseMultivariateRationalPolynomial operator+ (const ratNum_t& r) const {
883  return (*this + RationalNumber(r));
884  }
885 
886  /**
887  * Add *this and the RationalNumber r.
888  */
890 
891  /**
892  * Add ratNum_t r and SMQP b.
893  */
895  return (b + r);
896  }
897 
898  /**
899  * Update *this by adding r
900  */
902  return (*this += RationalNumber(r));
903  }
904 
905  /**
906  * Add RationalNumber r and SMQP b.
907  */
909  return (b + r);
910  }
911 
912  /**
913  * Update *this by adding the RationalNumber r to it.
914  */
916 
917  /**
918  * Subtract the ratNum_t r from *this.
919  */
920  inline SparseMultivariateRationalPolynomial operator- (const ratNum_t& r) const {
921  return (*this - RationalNumber(r));
922  }
923 
924  /**
925  * Subtract the RationalNumber r from *this.
926  */
928 
929  /**
930  * Subtract SMQP b from ratNum_t r.
931  */
933  return (-b + r);
934  }
935 
936  /**
937  * Subtract SMQP b from ratNum_t r.
938  */
940  return (-b + r);
941  }
942 
943  /**
944  * Update *this by subtracting ratNum_t r.
945  */
947  return (*this -= RationalNumber(r));
948  }
949 
950  /**
951  * Update *this by subtracting RationalNumber r.
952  */
954 
955  /**
956  * Multiply *this by ratNum_t r.
957  */
958  inline SparseMultivariateRationalPolynomial operator* (const ratNum_t& r) const {
959  return (*this * RationalNumber(r));
960  }
961 
962  /**
963  * Multiply *this by RationalNumber r.
964  */
966 
967  /**
968  * Multiply ratNum_t r and SMQP b.
969  */
971  return (b * r);
972  }
973 
974  /**
975  * Update *this by multiplying by ratNum_t r.
976  */
978  return (*this *= RationalNumber(r));
979  }
980 
981  /**
982  * Multiply RationalNumber r and SMQP b.
983  */
985  return (b * r);
986  }
987 
988  /**
989  * Update *this by multiplying by RationalNumber r.
990  */
992 
993  /**
994  * Divide *this by ratNum_t r.
995  */
996  inline SparseMultivariateRationalPolynomial operator/ (const ratNum_t& r) const {
997  return (*this / RationalNumber(r));
998  }
999 
1000  /**
1001  * Divide *this by RationalNumber r.
1002  */
1004 
1005  /**
1006  * Divide ratNum_t r by SMQP b.
1007  */
1009 
1010  /**
1011  * Update *this by dividing by ratNum_t r.
1012  */
1014  return (*this /= RationalNumber(r));
1015  }
1016  /**
1017  * Divide RationalNumber r by SMQP b.
1018  */
1020  ratNum_t t;
1021  mpq_init(t);
1022  mpq_set(t, r.get_mpq_t());
1024  mpq_clear(t);
1025  return ret;
1026  }
1027 
1028  /**
1029  * Update *this by dividing by RationalNumber r.
1030  */
1032 
1033  /**
1034  * Get the polynomial term at index. Returns 0 if index is beyond the
1035  * number of terms in this polynomial.
1036  */
1038 
1039  /**
1040  * Get the leading variable, that is, the highest-order variable with positive degree
1041  * of this polynomial.
1042  * returns the leading variable or the empty string if this polynomial has zero variables.
1043  */
1044  Symbol leadingVariable() const;
1045 
1046  /**
1047  * Get the degree of this polynomial w.r.t the leading variable.
1048  */
1050 
1051  /**
1052  * Is the contant term zero.
1053  */
1054  bool isConstantTermZero() const;
1055 
1056  /**
1057  * Get the leading coefficient w.r.t the input variable 'x'.
1058  * Returns the leading exponent as e.
1059  *
1060  * returns the coefficient as a new SMQP.
1061  */
1063 
1064  /**
1065  * Convert to a SUP<SMQP> given the variable 'x'.
1066  *
1067  * returns the SUP<SMQP>.
1068  */
1070 
1071  /**
1072  * Negate all the coefficients of *this. Note, that due to the
1073  * sharing nature of underling nodes, this may alter the Nodes of
1074  * other SMQP.
1075  */
1076  void negate();
1077 
1078  /**
1079  * Get a copy of this such that all underlying memory is NOT shared.
1080  * Note, any following arithmetic operations on the returned result
1081  * will result in possibly making the underlying memory shared again.
1082  */
1084 
1085  /**
1086  * Factors this polynomial into irreducible factors.
1087  * The Factors may include a common numerical (rational) factor.
1088  * See also, Factors.
1089  */
1091 
1092  /**
1093  * SLP representation of the polynomial
1094  **/
1095  void straightLineProgram();
1096 
1097  /**
1098  * Print SLP representation
1099  **/
1100  void printSLP(std::ostream& out = std::cout) const;
1101 
1102  /* Real Root Isolation */
1103  private:
1105  int refineSleeveUnivariateIntervals(Intervals*, Intervals*, Intervals*, DenseUnivariateRationalPolynomial*, DenseUnivariateRationalPolynomial*, lfixq);
1106  void sleeveBoundURPolynomials(DenseUnivariateRationalPolynomial*, DenseUnivariateRationalPolynomial*, Intervals&, int, int);
1107  public:
1108  /**
1109  * Given one real root for x_1, .., x_{n-1},
1110  * isolate positive roots for x_n
1111  *
1112  * @param mpIs: Roots of x_n (Output)
1113  * @param apIs: A root of previous polynomials
1114  * @param s: deal with 0: positive roots; 1: negative roots
1115  * @param check: 1: check the leading or tail coefficient; 0: do not
1116  * @param width: Interval's right - left < width
1117  * @param ts: Taylor Shift option
1118  *
1119  * Return
1120  * 1: Need to refine preious polynomials
1121  * 0: Found positive real roots
1122  **/
1123  int positiveRealRootIsolation(Intervals* pIs, Intervals& apIs, mpq_class width, int ts=-1, bool s=0, bool check=1);
1124 
1125  /**
1126  * Change *this to be a random non-zero polynomial.
1127  * numvar: number of variables
1128  * nterms: number of terms
1129  * coefBound: limit on the number of bits encoding the coefficients.
1130  * sparsity: succesive terms are at most sparsity away from each other
1131  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1132  */
1133  void randomPolynomial(int numvar, int nterms, unsigned long int coefBound, degree_t sparsity, bool includeNeg);
1134 
1135  /**
1136  * Change *this to be a random non-zero polynomial. The number of variables will
1137  * be equal to the size of the maxDegs vector. The term whose monomial
1138  * has exponents equal to those in maxDegs is guaranteed to exist in the
1139  * resulting polynomial.
1140  * A sparsity of 0 produces a dense polynomial. A sparsity of 1 produces only
1141  * one term; one whose monomial has exponents equal to maxDegs.
1142  *
1143  * coefBound: limit on the number of bits encoding the coefficients.
1144  * sparsity: a percentage of zero-terms between term with maxDegs and the constant term.
1145  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1146  */
1147  void randomPolynomial(std::vector<int> maxDegs, unsigned long int coefBound, float sparsity, bool includeNeg);
1148 
1149  /**
1150  * Convert *this to an ExpressionTree.
1151  *
1152  * returns the new ExpressionTree.
1153  */
1155 
1156 
1157 /****************
1158 * Multi-Divisor Division
1159 *****************/
1160 
1161 /**
1162  * Normal Form (or Multi-Divisor Division (MDD))
1163  * Given the dividend, f, and a divisor-set of polynomials of size s,
1164  * G[s] = {g_0, ..., g_{s-1}} to compute the reduce polynomial (remainder) r with respect to the G[s],
1165  * Return (by reference) the remainder and the quotient set Q[s] = {q_0, ..., q_{s-1}},
1166  * such that f = q_0*g_0 + ... + q_{s-1}*g_{s-1} + r.
1167  */
1168  SparseMultivariateRationalPolynomial lexNormalForm(const std::vector<Symbol>& superNames,
1169  const std::vector<SparseMultivariateRationalPolynomial>& ts, std::vector<SparseMultivariateRationalPolynomial>* quoSet = NULL) const;
1170 
1171  SparseMultivariateRationalPolynomial lexNormalizeDim0 (const std::vector<Symbol>& superNames,
1172  const std::vector<SparseMultivariateRationalPolynomial>& ts, SparseMultivariateRationalPolynomial* A) const;
1173 
1174  /**
1175  * Multi-Divisor Division (MDD) where the divisor-set is a Triangular Set
1176  * Given the dividend, f, and a divisor-set of polynomials of size s,
1177  * G[s] = {g_0, ..., g_{s-1}} to compute the reduce polynomial (remainder) r with respect to the G[s],
1178  * Return (by reference) the remainder and the quotient set Q[s] = {q_0, ..., q_{s-1}}.
1179  */
1180  SparseMultivariateRationalPolynomial triangularSetNormalForm(const TriangularSet<RationalNumber,SparseMultivariateRationalPolynomial>& ts, std::vector<SparseMultivariateRationalPolynomial>* quoSet) const;
1181 
1182 /**
1183  * Do the pseudo division of c by the triangular-set (divisor set) of B in the naive principle
1184  * such that hPow*f = quoSet_0 * B_0 + ... + quoSet_{nSet-1} * B_{nSet-1} + rem.
1185  * Quotients are returned in quoSet, and remainder in rem.
1186  * If hPow is not NULL then *hPow is set to the initial of b to the power of
1187  * the exact number of division steps which occurred..
1188  * nvar : size of exponent vectors
1189  * nSet : the size of the divisor set
1190  */
1192  std::vector<SparseMultivariateRationalPolynomial>* quoSet, SparseMultivariateRationalPolynomial* h) const;
1193 
1194 /**
1195  * Specialized Normal Form where the divisor-set is a Triangular Set
1196  * Given the dividend, f, and a divisor-set of polynomials of size s,
1197  * G[s] = {g_0, ..., g_{s-1}} to compute the reduce polynomial (remainder) r with respect to the G[s].
1198  */
1200 
1201 
1202 
1203 
1204 
1205 
1206 
1207 
1208 /*
1209 
1210 ***/
1211 
1214 
1215 
1216 };
1217 
1218 
1219 
1220 
1221 
1222 #endif //_SMQPLINKEDLIST_H_
bool isOne() const
Is this polynomial one.
A multivariate polynomial with Integer coefficients using a sparse representation.
Definition: mzpolynomial.hpp:75
A triangular set templated by a multivariate polynomial over a field.
Definition: triangularset.hpp:44
SparseMultivariateRationalPolynomial evaluate(int n, const Symbol *syms, const RationalNumber *xs) const
Evaluate f(x)
Definition: mrpolynomial.h:793
void differentiate(const Symbol &s)
Convert current object to its derivative.
Definition: mrpolynomial.h:728
A sparsely represented univariate polynomial over an arbitrary ring.
Definition: BigPrimeField.hpp:21
int mainDegree() const
Get the degree of the main variable.
SparseMultivariateIntegerPolynomial & operator+=(const SparseMultivariateIntegerPolynomial &b)
Add the polynomails a and b and return the sum.
SparseMultivariateIntegerPolynomial pseudoDivide(const SparseMultivariateIntegerPolynomial &b, SparseMultivariateIntegerPolynomial *quo=NULL, SparseMultivariateIntegerPolynomial *mult=NULL, bool lazy=0) const
Pseudo divide this by b.
SparseMultivariateIntegerPolynomial separant() const
Get the separant of this polynomial, that is, its derivative with respect to the main variable...
void print(std::ostream &os) const
Output the string representation of *this to the input ostream.
A multivariate polynomial with RationalNumber coefficients represented sparely.
Definition: mrpolynomial.h:71
SparseMultivariateRationalPolynomial derivative(const Symbol &s) const
Compute derivative.
Definition: mrpolynomial.h:745
Integer leadingCoefficient() const
Get the leading coefficient.
Symbol mainVariable() const
Get the main variable.
Definition: mrpolynomial.h:568
SparseMultivariateIntegerPolynomial & operator%=(const SparseMultivariateIntegerPolynomial &b)
Update *this by setting it to the remainder of *this divided by b.
bool isZero() const
Is this polynomial zero.
SparseMultivariateIntegerPolynomial operator[](int index) const
Get the polynomial term at index.
void randomPolynomial(int numvar, int nterms, unsigned long int coefBound, degree_t sparsity, bool includeNeg)
Change *this to be a random non-zero polynomial.
SparseMultivariateIntegerPolynomial & operator/=(const SparseMultivariateIntegerPolynomial &b)
Update *this by dividing by the specified polynomial.
int numberOfVariables() const
Get the number of variables in this polynomial.
SparseUnivariatePolynomial< SparseMultivariateIntegerPolynomial > convertToSUP(const Symbol &x) const
Convert to a SUP<SMQP> given the variable &#39;x&#39;.
int isConstant() const
Determine if this polynomial encodes a constant.
std::vector< Symbol > ringVariables() const
Get variable names of all variables available to this polynomial, even those that have zero degree...
void integrate(const Symbol &s)
Convert current object to its derivative.
Definition: mrpolynomial.h:764
SparseMultivariateIntegerPolynomial evaluate(int n, const Symbol *syms, const Integer *xs) const
Evaluate f(x)
Definition: mzpolynomial.hpp:760
SparseMultivariateIntegerPolynomial tail() const
Get the tail of this polynomial.
static SparseMultivariateIntegerPolynomial interpolate(const std::vector< std::vector< Integer >> &points, const std::vector< Integer > &vals)
Find the interpolating polynomial for the integer points and values specified by each vector...
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
SparseMultivariateIntegerPolynomial primitiveGCD(const SparseMultivariateIntegerPolynomial &b) const
Get the GCD between *this and b as a primitive polynomial.
void negate()
Negate all the coefficients of *this.
SparseMultivariateIntegerPolynomial & operator=(const SparseMultivariateIntegerPolynomial &b)
Assign this polynomail to equal the specified.
SparseMultivariateIntegerPolynomial operator-() const
Subtract the polynomial b from a and return the difference.
Data Structure for interval [a, b].
Definition: interval.h:11
SparseMultivariateIntegerPolynomial & operator*=(const SparseMultivariateIntegerPolynomial &b)
Multiply the polynomials a and b, returning their product.
SparseMultivariateIntegerPolynomial integral(const Symbol &s, int k) const
Return k-th integral.
SparseMultivariateIntegerPolynomial initial() const
Get the leading coefficient of *this with respect to the main variable.
void straightLineProgram()
SLP representation of the polynomial.
std::vector< Symbol > variables() const
Get variable names of variables with non-zero degree;.
void printSLP(std::ostream &out=std::cout) const
Print SLP representation.
void setCoefficient(int, const int *, const Integer &)
Set a coefficient, given the exponent of each variable.
SparseMultivariateIntegerPolynomial & operator^=(long long int e)
Update *this by exponentiating this to the input integer.
int numberOfRingVariables() const
Get the number of variables in this polynomial ring.
Definition: mrpolynomial.h:614
bool divide(const SparseMultivariateIntegerPolynomial &b, SparseMultivariateIntegerPolynomial &q, SparseMultivariateIntegerPolynomial &r) const
Divide this by polynomial b, returning the quotient and remainder in q and r, respectively.
A univariate polynomial with RationalNumber coefficients represented densely.
Definition: urpolynomial.h:16
bool isEqual(const SparseMultivariateIntegerPolynomial &b) const
Determine if *this is equal to b.
Integer leadingVariableDegree() const
Get the degree of this polynomial w.r.t the leading variable.
void differentiate(const Symbol &s, int k)
Convert current object to its k-th derivative.
Definition: mzpolynomial.hpp:662
Integer coefficient(int, const int *) const
Get a coefficient, given the exponent of each variable.
friend std::istream & operator>>(std::istream &in, SparseMultivariateIntegerPolynomial &p)
Parse a polynomial from the in stream.
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
SparseMultivariateIntegerPolynomial deepCopy() const
Get a copy of this such that all underlying memory is NOT shared.
Definition: mrpolynomial.h:29
bool isNegativeOne() const
Is this polynomial negative one.
Integer trailingCoefficient() const
Get the trailing coefficient.
SparseMultivariateIntegerPolynomial operator/(const SparseMultivariateIntegerPolynomial &b) const
Divide *this by the specified polynomial.
SparseMultivariateIntegerPolynomial rank() const
Get the rank of this polynomial.
Integer content() const
Get the content with respect to all variables.
An arbitrary-precision Integer.
Definition: Integer.hpp:22
void fromString(const std::string &str)
Parse a polynomial from the string str and place it in *this.
RationalNumber coefficient(const std::vector< int > &v) const
Get the coefficient of this polynomial with respect to the monomial defined by exponent vector exps...
Definition: mrpolynomial.h:648
SparseMultivariateIntegerPolynomial operator*(const SparseMultivariateIntegerPolynomial &b) const
Multiply *this by the specified polynomail.
void integrate(const Symbol &s, int k)
Convert current object to its k-th integral.
Definition: mrpolynomial.h:755
std::vector< SparseMultivariateRationalPolynomial > subresultantInitialAtIdx(const SparseMultivariateRationalPolynomial &q, const Symbol &v, int idx=0, specSRC_AAZ **lazyInfo=NULL) const
Compute the initials of two successive subresultants: S_{i}, S_{i+1} s.t.
Definition: mrpolynomial.h:439
SparseMultivariateIntegerPolynomial squareFreePart() const
Computes the square free part of this polynomail.
void setCoefficient(const std::vector< int > &v, const RationalNumber &r)
Set the coefficient of this polynomial for the monomial defined by exponent vector exps to r...
Definition: mrpolynomial.h:657
SparseMultivariateIntegerPolynomial & operator-=(const SparseMultivariateIntegerPolynomial &b)
Update *this by subtracting the specified polynomial from it.
ExpressionTree convertToExpressionTree() const
Convert *this to an ExpressionTree.
SparseMultivariateIntegerPolynomial operator+(const SparseMultivariateIntegerPolynomial &b) const
Add two SMQP polynomials together, *this and the specified.
bool isConstantTermZero() const
Is the contant term zero.
void zero()
Set this polynomial to zero.
Integer numberOfTerms() const
Get the number of non-zero terms.
SparseMultivariateIntegerPolynomial derivative(const Symbol &s, int k) const
Return k-th derivative.
void setRingVariables(const std::vector< Symbol > &)
Set variables&#39; names.
SparseMultivariateIntegerPolynomial leadingCoefficientInVariable(const Symbol &x, int *e=NULL) const
Get the leading coefficient w.r.t the input variable &#39;x&#39;.
SparseMultivariateIntegerPolynomial head() const
Get the head of this polynomial.
Factors< SparseMultivariateIntegerPolynomial > factor() const
Factors this polynomial into irreducible factors.
SparseMultivariateIntegerPolynomial gcd(const SparseMultivariateIntegerPolynomial &b) const
Get GCD between *this and b.
void negativeOne()
Sets this polynomial to -1.
bool operator!=(const SparseMultivariateIntegerPolynomial &b) const
Determine if *this is not equal to the specified polynomial.
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
An arbitrary-precision rational number.
Definition: RationalNumber.hpp:24
void one()
Sets this polynomial to one.
An element of the SLP of a rational number polynomial.
Definition: mrpolynomial.h:26
SparseMultivariateIntegerPolynomial primitivePart() const
Get the primitive part with respect to all variables.
SparseMultivariateIntegerPolynomial operator%(const SparseMultivariateIntegerPolynomial &b) const
Get the remainder of *this divided by b.
RationalNumber inverse() const
Get the inverse of *this.
Definition: RationalNumber.hpp:388
SparseMultivariateRationalPolynomial unitCanonical(SparseMultivariateRationalPolynomial *u, SparseMultivariateRationalPolynomial *v) const
Obtain the unit normal (a.k.a canonical associate) of an element.
Definition: mrpolynomial.h:250
void integrate(const Symbol &s, int k)
Convert current object to its k-th integral.
Definition: mzpolynomial.hpp:698
Factors< SparseMultivariateIntegerPolynomial > squareFree() const
Compute squarefree factorization of *this with respect to all of its variables.
SparseMultivariateIntegerPolynomial operator^(long long int e) const
Exponentiate *this by the input exponent integer.
Interval lists for real roots of multivariate polynomials.
Definition: interval.h:35
Symbol leadingVariable() const
Get the leading variable, that is, the highest-order variable with positive degree of this polynomial...
Integer degree() const
Total degree.
SparseMultivariateRationalPolynomial integral(const Symbol &s) const
Compute integral.
Definition: mrpolynomial.h:783
void differentiate(const Symbol &s, int k)
Convert current object to its k-th derivative.
Definition: mrpolynomial.h:719
An abstract class defining the interface of a multivariate polynomial that can be viewed recursively...
Definition: BPASRecursivePolynomial.hpp:12
bool operator==(const SparseMultivariateIntegerPolynomial &b) const
Determine if *this is equal to the specified polynomial.