1 /** @file sr_gcd_uvar.h
3 * GCD function for univariate polynomials using PRS method. */
6 * GiNaC Copyright (C) 1999-2022 Johannes Gutenberg University Mainz, Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #ifndef GINAC_UPOLY_SR_GCD_H
24 #define GINAC_UPOLY_SR_GCD_H
27 #include "ring_traits.h"
28 #include "normalize.h"
29 #include "prem_uvar.h"
35 /// Calculate GCD of two univariate polynomials @a a and @a b using
36 /// subresultant pseudo-remainder sequence method
37 template<typename T> static bool
38 sr_gcd_priv(T& g, T a, T b,
39 unsigned tries = std::numeric_limits<unsigned>::max())
41 // handle zero polynomials
51 typedef typename T::value_type ring_t;
52 if (degree(a) < degree(b))
55 normalize_in_ring(a, &acont);
56 normalize_in_ring(b, &bcont);
58 const ring_t one = get_ring_elt(b[0], 1);
60 const ring_t gamma = gcd(acont, bcont);
67 T r(std::min(degree(a), degree(b)));
69 ring_t ri = one, psi = one;
72 std::size_t delta = degree(a) - degree(b);
73 pseudoremainder(r, a, b);
82 ring_t ri_psi_delta = delta > 0 ? ri*expt_pos(psi, delta) : ri;
84 bool divisible_p = divide(b, r, ri_psi_delta);
85 bug_on(!divisible_p, "division failed: r = " << r <<
86 ", ri = " << ri << ", psi = " << psi);
88 if ((degree(b) == 0) && (degree(r) == 0)) {
104 const ring_t ri_delta = expt_pos(ri, delta);
105 const ring_t psi_delta_1 = expt_pos(psi, delta - 1);
106 bool sanity_check = div(psi, ri_delta, psi_delta_1);
107 bug_on(!sanity_check, "division failed: ri = " << ri
108 << ", psi = " << psi << ", delta = " << delta);
117 #endif // GINAC_UPOLY_SR_GCD_H