1 #ifndef GINAC_UPOLY_SR_GCD_TCC
2 #define GINAC_UPOLY_SR_GCD_TCC
4 #include "ring_traits.hpp"
5 #include "normalize.tcc"
12 /// Calculate GCD of two univariate polynomials @a a and @a b using
13 /// subresultant pseudo-remainder sequence method
14 template<typename T> static bool
15 sr_gcd_priv(T& g, T a, T b,
16 unsigned tries = std::numeric_limits<unsigned>::max())
18 // handle zero polynomials
28 typedef typename T::value_type ring_t;
29 if (degree(a) < degree(b))
32 normalize_in_ring(a, &acont);
33 normalize_in_ring(b, &bcont);
35 const ring_t one = get_ring_elt(b[0], 1);
37 const ring_t gamma = gcd(acont, bcont);
44 T r(std::min(degree(a), degree(b)));
46 ring_t ri = one, psi = one;
49 std::size_t delta = degree(a) - degree(b);
50 pseudoremainder(r, a, b);
59 ring_t ri_psi_delta = delta > 0 ? ri*expt_pos(psi, delta) : ri;
61 bool divisible_p = divide(b, r, ri_psi_delta);
62 bug_on(!divisible_p, "division failed: r = " << r <<
63 ", ri = " << ri << ", psi = " << psi);
65 if ((degree(b) == 0) && (degree(r) == 0)) {
81 const ring_t ri_delta = expt_pos(ri, delta);
82 const ring_t psi_delta_1 = expt_pos(psi, delta - 1);
83 bool sanity_check = div(psi, ri_delta, psi_delta_1);
84 bug_on(!sanity_check, "division failed: ri = " << ri
85 << ", psi = " << psi << ", delta = " << delta);
94 #endif // GINAC_UPOLY_SR_GCD_TCC