@@ -141,41 +141,42 @@ function Base.gcd(t1::AbstractTermLike{T}, t2::AbstractTermLike{S}, algo::Abstra
141
141
return term (_coefficient_gcd (coefficient (t1), coefficient (t2)), gcd (monomial (t1), monomial (t2)))
142
142
end
143
143
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
+
144
172
# Inspired from to `AbstractAlgebra.deflation`
145
173
function deflation (p:: AbstractPolynomialLike )
146
174
if iszero (p)
147
175
return constantmonomial (p), constantmonomial (p)
148
176
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 )
179
180
s = prod (variables (p).^ shift; init = constantmonomial (p)):: monomialtype (p)
180
181
d = prod (variables (p).^ defl; init = constantmonomial (p)):: monomialtype (p)
181
182
return s, d
0 commit comments