+/** Compute GCD of polynomials in Q[X] using the Euclidean algorithm (not
+ * really suited for multivariate GCDs). This function is only provided for
+ * testing purposes.
+ *
+ * @param a first multivariate polynomial
+ * @param b second multivariate polynomial
+ * @param x pointer to symbol (main variable) in which to compute the GCD in
+ * @return the GCD as a new expression
+ * @see gcd */
+
+static ex eu_gcd(const ex &a, const ex &b, const symbol *x)
+{
+//std::clog << "eu_gcd(" << a << "," << b << ")\n";
+
+ // Sort c and d so that c has higher degree
+ ex c, d;
+ int adeg = a.degree(*x), bdeg = b.degree(*x);
+ if (adeg >= bdeg) {
+ c = a;
+ d = b;
+ } else {
+ c = b;
+ d = a;
+ }
+
+ // Normalize in Q[x]
+ c = c / c.lcoeff(*x);
+ d = d / d.lcoeff(*x);
+
+ // Euclidean algorithm
+ ex r;
+ for (;;) {
+//std::clog << " d = " << d << endl;
+ r = rem(c, d, *x, false);
+ if (r.is_zero())
+ return d / d.lcoeff(*x);
+ c = d;
+ d = r;
+ }
+}
+
+
+/** Compute GCD of multivariate polynomials using the Euclidean PRS algorithm
+ * with pseudo-remainders ("World's Worst GCD Algorithm", staying in Z[X]).
+ * This function is only provided for testing purposes.
+ *
+ * @param a first multivariate polynomial
+ * @param b second multivariate polynomial
+ * @param x pointer to symbol (main variable) in which to compute the GCD in
+ * @return the GCD as a new expression
+ * @see gcd */
+
+static ex euprem_gcd(const ex &a, const ex &b, const symbol *x)
+{
+//std::clog << "euprem_gcd(" << a << "," << b << ")\n";
+
+ // Sort c and d so that c has higher degree
+ ex c, d;
+ int adeg = a.degree(*x), bdeg = b.degree(*x);
+ if (adeg >= bdeg) {
+ c = a;
+ d = b;
+ } else {
+ c = b;
+ d = a;
+ }
+
+ // Calculate GCD of contents
+ ex gamma = gcd(c.content(*x), d.content(*x), NULL, NULL, false);
+
+ // Euclidean algorithm with pseudo-remainders
+ ex r;
+ for (;;) {
+//std::clog << " d = " << d << endl;
+ r = prem(c, d, *x, false);
+ if (r.is_zero())
+ return d.primpart(*x) * gamma;
+ c = d;
+ d = r;
+ }
+}
+
+
+/** Compute GCD of multivariate polynomials using the primitive Euclidean
+ * PRS algorithm (complete content removal at each step). This function is
+ * only provided for testing purposes.
+ *
+ * @param a first multivariate polynomial
+ * @param b second multivariate polynomial
+ * @param x pointer to symbol (main variable) in which to compute the GCD in
+ * @return the GCD as a new expression
+ * @see gcd */
+
+static ex peu_gcd(const ex &a, const ex &b, const symbol *x)
+{
+//std::clog << "peu_gcd(" << a << "," << b << ")\n";
+
+ // Sort c and d so that c has higher degree
+ ex c, d;
+ int adeg = a.degree(*x), bdeg = b.degree(*x);
+ int ddeg;
+ if (adeg >= bdeg) {
+ c = a;
+ d = b;
+ ddeg = bdeg;
+ } else {
+ c = b;
+ d = a;
+ ddeg = adeg;
+ }
+
+ // Remove content from c and d, to be attached to GCD later
+ ex cont_c = c.content(*x);
+ ex cont_d = d.content(*x);
+ ex gamma = gcd(cont_c, cont_d, NULL, NULL, false);
+ if (ddeg == 0)
+ return gamma;
+ c = c.primpart(*x, cont_c);
+ d = d.primpart(*x, cont_d);
+
+ // Euclidean algorithm with content removal
+ ex r;
+ for (;;) {
+//std::clog << " d = " << d << endl;
+ r = prem(c, d, *x, false);
+ if (r.is_zero())
+ return gamma * d;
+ c = d;
+ d = r.primpart(*x);
+ }
+}
+
+
+/** Compute GCD of multivariate polynomials using the reduced PRS algorithm.
+ * This function is only provided for testing purposes.