@@ -44,38 +44,50 @@ _field_absorb(::UFD, ::Field) = Field()
4444_field_absorb (:: Field , :: UFD ) = Field ()
4545_field_absorb (:: Field , :: Field ) = Field ()
4646
47- # _div(a, b) assumes that b divides a
48- _div (:: Field , a, b) = a / b
49- _div (:: UFD , a, b) = div (a, b)
50- _div (a, b) = _div (algebraic_structure (promote_type (typeof (a), typeof (b))), a, b)
51- _div (m1:: AbstractMonomialLike , m2:: AbstractMonomialLike ) = mapexponents (- , m1, m2)
52- function _div (t:: AbstractTerm , m:: AbstractMonomial )
53- term (coefficient (t), _div (monomial (t), m))
47+ """
48+ div_multiple(a, b, ma::MA.MutableTrait)
49+
50+ Return the division of `a` by `b` assuming that `a` is a multiple of `b`.
51+ If `a` is not a multiple of `b` then this function may return anything.
52+ """
53+ div_multiple (:: Field , a, b, ma:: MA.MutableTrait ) = a / b
54+ div_multiple (:: UFD , a, b, ma:: MA.IsMutable ) = MA. operate!! (div, a, b)
55+ div_multiple (:: UFD , a, b, ma:: MA.IsNotMutable ) = div (a, b)
56+ function div_multiple (a, b, ma:: MA.MutableTrait = MA. IsNotMutable ())
57+ return div_multiple (algebraic_structure (promote_type (typeof (a), typeof (b))), a, b, ma)
58+ end
59+ function div_multiple (m1:: AbstractMonomialLike , m2:: AbstractMonomialLike , :: MA.MutableTrait )
60+ return mapexponents (- , m1, m2)
61+ end
62+ function div_multiple (t:: AbstractTerm , m:: AbstractMonomial , mt:: MA.MutableTrait = MA. IsNotMutable ())
63+ term (_copy (coefficient (t), mt), div_multiple (monomial (t), m))
5464end
55- function _div (t1:: AbstractTermLike , t2:: AbstractTermLike )
56- term (_div (coefficient (t1), coefficient (t2)), _div (monomial (t1), monomial (t2)))
65+ function div_multiple (t1:: AbstractTermLike , t2:: AbstractTermLike , m1 :: MA.MutableTrait = MA . IsNotMutable () )
66+ term (div_multiple (coefficient (t1), coefficient (t2), m1 ), div_multiple (monomial (t1), monomial (t2)))
5767end
58- function _div (f:: APL , g:: APL )
68+ function div_multiple (f:: APL , g:: APL , mf = MA . IsNotMutable () )
5969 lt = leadingterm (g)
60- rf = MA . copy_if_mutable (f )
70+ rf = _copy (f, mf )
6171 rg = removeleadingterm (g)
6272 q = zero (rf)
6373 while ! iszero (rf)
6474 ltf = leadingterm (rf)
6575 if ! divides (lt, ltf)
6676 # In floating point arithmetics, it may happen
6777 # that `rf` is not zero even if it cannot be reduced further.
68- # As `_div ` assumes that `g` divides `f`, we know that
78+ # As `div_multiple ` assumes that `g` divides `f`, we know that
6979 # `rf` is approximately zero anyway.
7080 break
7181 end
72- qt = _div (ltf, lt)
82+ qt = div_multiple (ltf, lt)
7383 q = MA. add!! (q, qt)
7484 rf = MA. operate!! (removeleadingterm, rf)
7585 rf = MA. operate!! (MA. sub_mul, rf, qt, rg)
7686 end
7787 return q
7888end
89+ # 2-arguments useful to be used with `Base.Fix2`
90+ _div_multiple! (a, b) = div_multiple (a, b, MA. IsMutable ())
7991
8092Base. div (f:: APL , g:: Union{APL, AbstractVector{<:APL}} ; kwargs... ) = divrem (f, g; kwargs... )[1 ]
8193Base. rem (f:: APL , g:: Union{APL, AbstractVector{<:APL}} ; kwargs... ) = divrem (f, g; kwargs... )[2 ]
@@ -98,7 +110,7 @@ function _pseudo_divrem(::UFD, f::APL, g::APL, algo)
98110 else
99111 st = constantterm (coefficient (ltg), f)
100112 new_f = st * removeleadingterm (f)
101- qt = term (coefficient (ltf), _div (monomial (ltf), monomial (ltg)))
113+ qt = term (coefficient (ltf), div_multiple (monomial (ltf), monomial (ltg)))
102114 new_g = qt * rg
103115 # Check with `::` that we don't have any type unstability on this variable.
104116 return convert (typeof (f), st), convert (typeof (f), qt), (new_f - new_g):: typeof (f)
@@ -136,11 +148,11 @@ end
136148
137149function _prepare_s_poly! (:: typeof (pseudo_rem), f, ltf, ltg)
138150 MA. operate! (right_constant_mult, f, coefficient (ltg))
139- return term (coefficient (ltf), _div (monomial (ltf), monomial (ltg)))
151+ return term (coefficient (ltf), div_multiple (monomial (ltf), monomial (ltg)))
140152end
141153
142154function _prepare_s_poly! (:: typeof (rem), :: APL , ltf, ltg)
143- return _div (ltf, ltg)
155+ return div_multiple (ltf, ltg)
144156end
145157
146158function MA. operate! (op:: Union{typeof(rem), typeof(pseudo_rem)} , f:: APL , g:: APL , algo)
@@ -255,7 +267,7 @@ function Base.divrem(f::APL{T}, g::APL{S}; kwargs...) where {T, S}
255267 if isapproxzero (ltf; kwargs... )
256268 rf = MA. operate!! (removeleadingterm, rf)
257269 elseif divides (lm, ltf)
258- qt = _div (ltf, lt)
270+ qt = div_multiple (ltf, lt)
259271 q = MA. add!! (q, qt)
260272 rf = MA. operate!! (removeleadingterm, rf)
261273 rf = MA. operate!! (MA. sub_mul, rf, qt, rg)
@@ -291,7 +303,7 @@ function Base.divrem(f::APL{T}, g::AbstractVector{<:APL{S}}; kwargs...) where {T
291303 divisionoccured = false
292304 for i in useful
293305 if divides (lm[i], ltf)
294- qt = _div (ltf, lt[i])
306+ qt = div_multiple (ltf, lt[i])
295307 q[i] = MA. add!! (q[i], qt)
296308 rf = MA. operate!! (removeleadingterm, rf)
297309 rf = MA. operate!! (MA. sub_mul, rf, qt, rg[i])
0 commit comments