Skip to content

Commit 183972e

Browse files
authored
Use promote_operation for subs in isolate_variable (#218)
* Use promote_operation for subs in isolate_variable * Fix * Fix degree of constant monomial with no variable * Missing end
1 parent 22b468e commit 183972e

File tree

6 files changed

+35
-5
lines changed

6 files changed

+35
-5
lines changed

src/gcd.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ function deflation(p::AbstractPolynomialLike)
175175
end
176176
@assert all(d -> d >= 0, shift)
177177
@assert all(d -> d >= 0, defl)
178-
s = prod(variables(p).^shift)::monomialtype(p)
179-
d = prod(variables(p).^defl)::monomialtype(p)
178+
s = prod(variables(p).^shift; init = constantmonomial(p))::monomialtype(p)
179+
d = prod(variables(p).^defl; init = constantmonomial(p))::monomialtype(p)
180180
return s, d
181181
end
182182

@@ -357,7 +357,8 @@ The output can be mutated without affecting `poly` if `mutability` is
357357
"""
358358
function isolate_variable(poly::APL, var::AbstractVariable, mutability::MA.MutableTrait)
359359
old_terms = sort!(_vector(terms(_copy(poly, mutability))), by = Base.Fix2(degree, var), rev=true)
360-
T = termtype(var, typeof(substitute(Subs(), zero(poly), (var,) => (1,))))
360+
U = MA.promote_operation(substitute, Subs, typeof(poly), Pair{typeof(var),Int})
361+
T = termtype(var, U)
361362
new_terms = T[]
362363
i = firstindex(old_terms)
363364
while i <= lastindex(old_terms)

src/monomial.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Calling `degree(x^2*y)` should return 3 which is ``2 + 1``.
6969
Calling `degree(x^2*y, x)` should return 2 and calling `degree(x^2*y, y)` should return 1.
7070
7171
"""
72-
degree(t::AbstractTermLike) = sum(exponents(t))
72+
degree(t::AbstractTermLike) = sum(exponents(t); init = 0)
7373

7474
degree(t::AbstractTermLike, var::AbstractVariable) = degree(monomial(t), var)
7575
degree(v::AbstractVariable, var::AbstractVariable) = (v == var ? 1 : 0)

src/promote.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,9 @@ function MA.promote_operation(::typeof(*), PT::Type{<:APL{S}}, QT::Type{<:APL{T}
116116
U = MA.promote_operation(+, ST, ST)
117117
return polynomialtype(promote_type(monomialtype(PT), monomialtype(QT)), U)
118118
end
119+
function MA.promote_operation(::typeof(*), ::Type{T}, ::Type{P}) where {T, U, P<:APL{U}}
120+
return changecoefficienttype(P, MA.promote_operation(*, T, U))
121+
end
122+
function MA.promote_operation(::typeof(*), ::Type{P}, ::Type{T}) where {T, U, P<:APL{U}}
123+
return changecoefficienttype(P, MA.promote_operation(*, U, T))
124+
end

src/substitution.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ substitute(st::AST, m::AbstractMonomial, s::Substitutions) = powersubstitute(st,
5050
## Terms
5151
substitute(st::AST, t::AbstractTerm, s::Substitutions) = coefficient(t) * substitute(st, monomial(t), s)
5252

53+
function MA.promote_operation(::typeof(substitute), ::Type{Subs}, ::Type{T}, args::Vararg{Type,N}) where {T<:AbstractTerm,N}
54+
M = MA.promote_operation(substitute, Subs, monomialtype(T), args...)
55+
U = coefficienttype(T)
56+
return MA.promote_operation(*, U, M)
57+
end
58+
5359
## Polynomials
5460
_polynomial(α) = α
5561
_polynomial(p::APL) = polynomial(p)
@@ -59,7 +65,7 @@ function substitute(st::AST, p::AbstractPolynomial, s::Substitutions)
5965
else
6066
ts = terms(p)
6167
r1 = substitute(st, ts[1], s)
62-
R = Base.promote_op(+, typeof(r1), typeof(r1))
68+
R = MA.promote_operation(+, typeof(r1), typeof(r1))
6369
result::R = convert(R, r1)
6470
for i in 2:length(ts)
6571
result += substitute(st, ts[i], s)
@@ -68,6 +74,11 @@ function substitute(st::AST, p::AbstractPolynomial, s::Substitutions)
6874
end
6975
end
7076

77+
function MA.promote_operation(::typeof(substitute), ::Type{Subs}, ::Type{P}, args::Vararg{Type,N}) where {P<:AbstractPolynomial,N}
78+
T = MA.promote_operation(substitute, Subs, termtype(P), args...)
79+
return MA.promote_operation(+, T, T)
80+
end
81+
7182
## Fallbacks
7283
substitute(st::AST, p::APL, s::Substitutions) = substitute(st, polynomial(p), s)
7384
substitute(st::AST, q::RationalPoly, s::Substitutions) = substitute(st, q.num, s) / substitute(st, q.den, s)

test/allocations.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ function test_polynomial_merge()
3030
end
3131
end
3232

33+
34+
function test_promotion()
35+
@polyvar x y
36+
p = x * y + x + y + 1
37+
alloc_test(0) do
38+
promote_operation(MP.substitute, MP.Subs, typeof(p), Pair{typeof(x),Int})
39+
end
40+
end
41+
3342
function test_isapproxzero()
3443
@polyvar x y
3544
p = x * y + x + y + 1
@@ -57,6 +66,7 @@ end
5766

5867
function test_gcd()
5968
_test_gcd(Int)
69+
6070
end
6171

6272
end

test/promote.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,6 @@ Base.:+(::C, ::C) = C()
104104
@testset "promote_operation with tricky types" begin
105105
Mod.@polyvar x
106106
@test MA.promote_operation(*, polynomialtype(x, A), polynomialtype(x, A)) == polynomialtype(x, C)
107+
@test MA.promote_operation(*, polynomialtype(x, A), A) == polynomialtype(x, B)
108+
@test MA.promote_operation(*, A, polynomialtype(x, A)) == polynomialtype(x, B)
107109
end

0 commit comments

Comments
 (0)