@@ -141,41 +141,42 @@ function Base.gcd(t1::AbstractTermLike{T}, t2::AbstractTermLike{S}, algo::Abstra
141141 return term (_coefficient_gcd (coefficient (t1), coefficient (t2)), gcd (monomial (t1), monomial (t2)))
142142end
143143
144+ function shift_deflation (p:: AbstractPolynomialLike , v:: AbstractVariable )
145+ shift = - 1
146+ defl = 0
147+ for mono in monomials (p)
148+ exp = degree (mono, v)
149+ if shift == - 1
150+ shift = exp
151+ elseif exp < shift
152+ # There are two cases:
153+ # 1) If `defl[i]` is zero then it means all previous monomials
154+ # had degree `shift[i]` so we just set `defl[i]` to
155+ # `shift[i] - exp` or equivalently `gcd(0, shift[i] - exp)`.
156+ # 2) If `defl[i]` is positive then we have some monomials with
157+ # degree `shift[i]` and some with degree
158+ # `shift[i] + k * defl[i]` for some `k > 0`. We have
159+ # `gcd(shift[i] - exp, shift[i] + k1 * defl[i] - exp, shift[i] + k2 * defl[i] - exp, ...) =`
160+ # `gcd(shift[i] - exp, k1 * defl[i], k2 * defl[i], ...)`
161+ # Since `gcd(k1, k2, ...) = 1`, this is equal to
162+ # `gcd(shift[i] - exp, defl[i])`
163+ defl = gcd (defl, shift - exp)
164+ shift = exp
165+ else
166+ defl = gcd (defl, exp - shift)
167+ end
168+ end
169+ return shift, defl
170+ end
171+
144172# Inspired from to `AbstractAlgebra.deflation`
145173function deflation (p:: AbstractPolynomialLike )
146174 if iszero (p)
147175 return constantmonomial (p), constantmonomial (p)
148176 end
149- shift = fill (- 1 , nvariables (p))
150- defl = zeros (Int, nvariables (p))
151- for mono in monomials (p)
152- exps = exponents (mono)
153- for i in eachindex (exps)
154- exp = exps[i]
155- @assert exp >= 0
156- if shift[i] == - 1
157- shift[i] = exp
158- elseif exp < shift[i]
159- # There are two cases:
160- # 1) If `defl[i]` is zero then it means all previous monomials
161- # had degree `shift[i]` so we just set `defl[i]` to
162- # `shift[i] - exp` or equivalently `gcd(0, shift[i] - exp)`.
163- # 2) If `defl[i]` is positive then we have some monomials with
164- # degree `shift[i]` and some with degree
165- # `shift[i] + k * defl[i]` for some `k > 0`. We have
166- # `gcd(shift[i] - exp, shift[i] + k1 * defl[i] - exp, shift[i] + k2 * defl[i] - exp, ...) =`
167- # `gcd(shift[i] - exp, k1 * defl[i], k2 * defl[i], ...)`
168- # Since `gcd(k1, k2, ...) = 1`, this is equal to
169- # `gcd(shift[i] - exp, defl[i])`
170- defl[i] = gcd (defl[i], shift[i] - exp)
171- shift[i] = exp
172- else
173- defl[i] = gcd (defl[i], exp - shift[i])
174- end
175- end
176- end
177- @assert all (d -> d >= 0 , shift)
178- @assert all (d -> d >= 0 , defl)
177+ shift_defl = shift_deflation .(p, variables (p))
178+ shift = getindex .(shift_defl, 1 )
179+ defl = getindex .(shift_defl, 2 )
179180 s = prod (variables (p).^ shift; init = constantmonomial (p)):: monomialtype (p)
180181 d = prod (variables (p).^ defl; init = constantmonomial (p)):: monomialtype (p)
181182 return s, d
0 commit comments