carl  24.04
Computer ARithmetic Library
GCD_univariate.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Division.h"
4 #include "Remainder.h"
5 
6 #include "../UnivariatePolynomial.h"
8 
9 namespace carl {
10 
11 template<typename Coeff>
13  assert(!carl::is_zero(a));
14  assert(carl::is_zero(b) || b.degree() <= a.degree());
15 
16  if(carl::is_zero(b)) {
17  return a;
18  }
19 // if(is_field_type<Coeff>::value)
20 // {
21 // if(b.is_constant()) return b;
22 // }
23  else {
24  return gcd_recursive(b, remainder(a, b));
25  }
26 }
27 
28 /**
29  * Calculates the extended greatest common divisor `g` of two polynomials.
30  * The output polynomials `s` and `t` are computed such that \f$g = s \cdot a + t \cdot b\f$.
31  * @param a First polynomial.
32  * @param b Second polynomial.
33  * @param s First output polynomial.
34  * @param t Second output polynomial.
35  * @see @cite GCL92, Algorithm 2.2
36  * @return `gcd(a,b)`
37  */
38 template<typename Coeff>
41  assert(a.main_var() == b.main_var());
42  assert(a.main_var() == s.main_var());
43  assert(a.main_var() == t.main_var());
44  assert(!is_zero(a));
45  assert(!is_zero(b));
46 
47  CARL_LOG_DEBUG("carl.core", "UnivEEA: a=" << a << ", b=" << b );
48  Variable x = a.main_var();
53  c = c.normalized();
54  d = d.normalized();
55 
58 
61 
62  while(!is_zero(d))
63  {
65  assert(divres.remainder == c - divres.quotient * d);
66  UnivariatePolynomial r1 = c1 - divres.quotient*d1;
67  UnivariatePolynomial r2 = c2 - divres.quotient*d2;
68  CARL_LOG_TRACE("carl.core", "UnivEEA: q=" << divres.quotient << ", r=" << divres.remainder);
69  CARL_LOG_TRACE("carl.core", "UnivEEA: r1=" << c1 << "-" << divres.quotient << "*" << d1 << "==" << c1 - divres.quotient * d1 );
70  CARL_LOG_TRACE("carl.core", "UnivEEA: r2=" << c2 << "-" << divres.quotient << "*" << d2 << "==" << c2 - divres.quotient * d2 );
71  c = d;
72  c1 = d1;
73  c2 = d2;
74  d = divres.remainder;
75  d1 = r1;
76  d2 = r2;
79 
80  CARL_LOG_TRACE("carl.core", "UnivEEA: c=" << c << ", d=" << d );
81  CARL_LOG_TRACE("carl.core", "UnivEEA: c1=" << c1 << ", c2=" << c2 );
82  CARL_LOG_TRACE("carl.core", "UnivEEA: d1=" << d1 << ", d2=" << d2 );
83  }
84  assert(!is_zero(c));
85  s = c1 / (a.lcoeff() * c.lcoeff());
86  t = c2 / (b.lcoeff() * c.lcoeff());
87  c = c.normalized();
91  CARL_LOG_DEBUG("carl.core", "UnivEEA: g=" << c << ", s=" << s << ", t=" << t );
92  CARL_LOG_TRACE("carl.core", "UnivEEA: " << c << "==" << s*a + t*b << "==" << s*a << " + " << t*b );
93  assert(c == s*a + t*b);
94  return c;
95 }
96 
97 /**
98  * Calculates the greatest common divisor of two polynomials.
99  * @param a First polynomial.
100  * @param b Second polynomial.
101  * @return `gcd(a,b)`
102  */
103 template<typename Coeff>
105  // We want degree(b) <= degree(a).
106  assert(!carl::is_zero(a));
107  assert(!carl::is_zero(b));
108  assert(a.main_var() == b.main_var());
109  if(a.degree() < b.degree()) {
110  return gcd_recursive(b.normalized(),a.normalized()).normalized();
111  } else {
112  return gcd_recursive(a.normalized(),b.normalized()).normalized();
113  }
114 }
115 
116 }
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
#define CARL_LOG_DEBUG(channel, msg)
Definition: carl-logging.h:43
carl is the main namespace for the library.
UnivariatePolynomial< Coeff > extended_gcd(const UnivariatePolynomial< Coeff > &a, const UnivariatePolynomial< Coeff > &b, UnivariatePolynomial< Coeff > &s, UnivariatePolynomial< Coeff > &t)
Calculates the extended greatest common divisor g of two polynomials.
cln::cl_I gcd(const cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
Definition: operations.h:310
UnivariatePolynomial< Coeff > gcd_recursive(const UnivariatePolynomial< Coeff > &a, const UnivariatePolynomial< Coeff > &b)
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
void divide(const cln::cl_I &dividend, const cln::cl_I &divisor, cln::cl_I &quotient, cln::cl_I &remainder)
Definition: operations.h:326
cln::cl_I remainder(const cln::cl_I &a, const cln::cl_I &b)
Calculate the remainder of the integer division.
Definition: operations.h:526
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
This class represents a univariate polynomial with coefficients of an arbitrary type.
UnivariatePolynomial one() const
Creates a polynomial of value one with the same main variable.
Variable main_var() const
Retrieves the main variable of this polynomial.
const Coefficient & lcoeff() const
Returns the leading coefficient.
UnivariatePolynomial & normalizeCoefficients()
uint degree() const
Get the maximal exponent of the main variable.
UnivariatePolynomial normalized() const
The normal part of a polynomial is the polynomial divided by the unit part.
A strongly typed pair encoding the result of a division, being a quotient and a remainder.
Definition: Division.h:16