@@ -44,38 +44,50 @@ _field_absorb(::UFD, ::Field) = Field()
44
44
_field_absorb (:: Field , :: UFD ) = Field ()
45
45
_field_absorb (:: Field , :: Field ) = Field ()
46
46
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))
54
64
end
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)))
57
67
end
58
- function _div (f:: APL , g:: APL )
68
+ function div_multiple (f:: APL , g:: APL , mf = MA . IsNotMutable () )
59
69
lt = leadingterm (g)
60
- rf = MA . copy_if_mutable (f )
70
+ rf = _copy (f, mf )
61
71
rg = removeleadingterm (g)
62
72
q = zero (rf)
63
73
while ! iszero (rf)
64
74
ltf = leadingterm (rf)
65
75
if ! divides (lt, ltf)
66
76
# In floating point arithmetics, it may happen
67
77
# 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
69
79
# `rf` is approximately zero anyway.
70
80
break
71
81
end
72
- qt = _div (ltf, lt)
82
+ qt = div_multiple (ltf, lt)
73
83
q = MA. add!! (q, qt)
74
84
rf = MA. operate!! (removeleadingterm, rf)
75
85
rf = MA. operate!! (MA. sub_mul, rf, qt, rg)
76
86
end
77
87
return q
78
88
end
89
+ # 2-arguments useful to be used with `Base.Fix2`
90
+ _div_multiple! (a, b) = div_multiple (a, b, MA. IsMutable ())
79
91
80
92
Base. div (f:: APL , g:: Union{APL, AbstractVector{<:APL}} ; kwargs... ) = divrem (f, g; kwargs... )[1 ]
81
93
Base. 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)
98
110
else
99
111
st = constantterm (coefficient (ltg), f)
100
112
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)))
102
114
new_g = qt * rg
103
115
# Check with `::` that we don't have any type unstability on this variable.
104
116
return convert (typeof (f), st), convert (typeof (f), qt), (new_f - new_g):: typeof (f)
@@ -136,11 +148,11 @@ end
136
148
137
149
function _prepare_s_poly! (:: typeof (pseudo_rem), f, ltf, ltg)
138
150
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)))
140
152
end
141
153
142
154
function _prepare_s_poly! (:: typeof (rem), :: APL , ltf, ltg)
143
- return _div (ltf, ltg)
155
+ return div_multiple (ltf, ltg)
144
156
end
145
157
146
158
function 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}
255
267
if isapproxzero (ltf; kwargs... )
256
268
rf = MA. operate!! (removeleadingterm, rf)
257
269
elseif divides (lm, ltf)
258
- qt = _div (ltf, lt)
270
+ qt = div_multiple (ltf, lt)
259
271
q = MA. add!! (q, qt)
260
272
rf = MA. operate!! (removeleadingterm, rf)
261
273
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
291
303
divisionoccured = false
292
304
for i in useful
293
305
if divides (lm[i], ltf)
294
- qt = _div (ltf, lt[i])
306
+ qt = div_multiple (ltf, lt[i])
295
307
q[i] = MA. add!! (q[i], qt)
296
308
rf = MA. operate!! (removeleadingterm, rf)
297
309
rf = MA. operate!! (MA. sub_mul, rf, qt, rg[i])
0 commit comments