Skip to content

Commit f62d550

Browse files
authored
Merge pull request #145 from JuliaAlgebra/bl/MA_div
Exploit mutability in divrem with MutableArithmetics
2 parents e42986d + f48c71d commit f62d550

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
1111

1212
[compat]
1313
DataStructures = "0.17.7"
14+
DynamicPolynomials = "0.3.12"
1415
MutableArithmetics = "0.2"
16+
TypedPolynomials = "0.2.8"
1517
julia = "1"
1618

1719
[extras]

src/division.jl

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,37 @@ Base.rem(f::APL, g::Union{APL, AbstractVector{<:APL}}; kwargs...) = divrem(f, g;
3232

3333
proddiff(x, y) = x/y - x/y
3434
function Base.divrem(f::APL{T}, g::APL{S}; kwargs...) where {T, S}
35-
rf = convert(polynomialtype(f, Base.promote_op(proddiff, T, S)), f)
36-
q = r = zero(rf)
35+
# `promote_type(typeof(f), typeof(g))` is needed for TypedPolynomials in case they use different variables
36+
rf = convert(polynomialtype(promote_type(typeof(f), typeof(g)), Base.promote_op(proddiff, T, S)), MA.copy_if_mutable(f))
37+
q = zero(rf)
38+
r = zero(rf)
3739
lt = leadingterm(g)
3840
rg = removeleadingterm(g)
3941
lm = monomial(lt)
4042
while !iszero(rf)
4143
ltf = leadingterm(rf)
4244
if isapproxzero(ltf; kwargs...)
43-
rf = removeleadingterm(rf)
45+
rf = MA.operate!(removeleadingterm, rf)
4446
elseif divides(lm, ltf)
4547
qt = _div(ltf, lt)
46-
q += qt
47-
rf = removeleadingterm(rf) - qt * rg
48+
q = MA.add!(q, qt)
49+
rf = MA.operate!(removeleadingterm, rf)
50+
rf = MA.operate!(MA.sub_mul, rf, qt, rg)
4851
elseif lm > monomial(ltf)
4952
# Since the monomials are sorted in decreasing order,
5053
# lm is larger than all of them hence it cannot divide any of them
51-
r += rf
54+
r = MA.add!(r, rf)
5255
break
5356
else
54-
r += ltf
55-
rf = removeleadingterm(rf)
57+
r = MA.add!(r, ltf)
58+
rf = MA.operate!(removeleadingterm, rf)
5659
end
5760
end
5861
q, r
5962
end
6063
function Base.divrem(f::APL{T}, g::AbstractVector{<:APL{S}}; kwargs...) where {T, S}
61-
rf = convert(polynomialtype(f, Base.promote_op(proddiff, T, S)), f)
64+
# `promote_type(typeof(f), eltype(g))` is needed for TypedPolynomials in case they use different variables
65+
rf = convert(polynomialtype(promote_type(typeof(f), eltype(g)), Base.promote_op(proddiff, T, S)), MA.copy_if_mutable(f))
6266
r = zero(rf)
6367
q = similar(g, typeof(rf))
6468
for i in eachindex(q)
@@ -71,15 +75,16 @@ function Base.divrem(f::APL{T}, g::AbstractVector{<:APL{S}}; kwargs...) where {T
7175
while !iszero(rf)
7276
ltf = leadingterm(rf)
7377
if isapproxzero(ltf; kwargs...)
74-
rf = removeleadingterm(rf)
78+
rf = MA.operate!(removeleadingterm, rf)
7579
continue
7680
end
7781
divisionoccured = false
7882
for i in useful
7983
if divides(lm[i], ltf)
8084
qt = _div(ltf, lt[i])
81-
q[i] += qt
82-
rf = removeleadingterm(rf) - qt * rg[i]
85+
q[i] = MA.add!(q[i], qt)
86+
rf = MA.operate!(removeleadingterm, rf)
87+
rf = MA.operate!(MA.sub_mul, rf, qt, rg[i])
8388
divisionoccured = true
8489
break
8590
elseif lm[i] > monomial(ltf)
@@ -90,11 +95,11 @@ function Base.divrem(f::APL{T}, g::AbstractVector{<:APL{S}}; kwargs...) where {T
9095
end
9196
if !divisionoccured
9297
if isempty(useful)
93-
r += rf
98+
r = MA.add!(r, rf)
9499
break
95100
else
96-
r += ltf
97-
rf = removeleadingterm(rf)
101+
r = MA.add!(r, ltf)
102+
rf = MA.operate!(removeleadingterm, rf)
98103
end
99104
end
100105
end

test/division.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ const MP = MultivariatePolynomials
6969
@test q == [x, 0]
7070
@test r == 0
7171

72+
@testset "Issue DynamicPolynomials#62" begin
73+
p = x^2 + x + 1
74+
q = rem(p, [x^2-y])
75+
@test q == x + y + 1
76+
end
77+
7278
@test (@inferred rem(x^2*y + (1+1e-10)*x*y + 1, [x^2 + x, y + 1])) == 1
7379
@test (@inferred rem(x^2*y + (1+1e-10)*x*y + 1, [x^2 + x, y + 1]; ztol=1e-11)) == -((1+1e-10)-1)x + 1
7480
end

test/polynomial.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,11 @@ const MP = MultivariatePolynomials
173173
p = im * x + 2im * x^2
174174
@test p * p == -x^2 - 4x^4 - 4x^3
175175
end
176+
177+
@testset "$f is a mutable copy, see issue DynamicPolynomials#62" for f in [zero, one]
178+
p = 2x + 1
179+
q = f(p)
180+
q = MA.add!(q, 2y)
181+
@test p == 2x + 1
182+
end
176183
end

0 commit comments

Comments
 (0)