Skip to content

Commit 03aabb5

Browse files
authored
Merge pull request #142 from JuliaAlgebra/bl/promote
Simplify promotion
2 parents 29057a2 + 89553ce commit 03aabb5

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

src/conversion.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ end
4242
function Base.convert(TT::Type{<:AbstractTerm{T}}, t::AbstractTerm) where T
4343
return convert(TT, convert(T, coefficient(t)) * monomial(t))
4444
end
45-
function Base.convert(::Type{T}, t::T) where T <: AbstractTerm
45+
46+
# Base.convert(::Type{T}, t::T) where {T <: AbstractTerm} is ambiguous with above method.
47+
# we need the following:
48+
function Base.convert(::Type{TT}, t::TT) where {T, TT <: AbstractTerm{T}}
4649
return t
4750
end
4851

src/hash.jl

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
1-
_hashpowers(u::UInt) = u
2-
function _hashpowers(u::UInt, power::Tuple, powers...)
3-
if iszero(power[2])
4-
_hashpowers(u, powers...)
5-
else
6-
_hashpowers(hash(power, u), powers...)
7-
end
8-
end
91
function Base.hash(m::AbstractMonomial, u::UInt)
102
nnz = count(!iszero, exponents(m))
113
if iszero(nnz)
124
hash(1, u)
135
elseif isone(nnz) && isone(degree(m))
6+
# We want the has of `m` to match the hash of `variable(m)`
7+
# so we ignore the exponent one.
148
hash(variable(m), u)
159
else
16-
_hashpowers(u, powers(m)...)
10+
reduce((u, power) -> iszero(power[2]) ? u : hash(power, u), powers(m), init=u)
1711
end
1812
end
1913

2014
function Base.hash(t::AbstractTerm, u::UInt)
2115
if iszero(t)
2216
hash(0, u)
23-
elseif coefficient(t) == 1
17+
elseif isone(coefficient(t))
18+
# We want the has of `t` to match the hash of `monomial(t)`
19+
# so we ignore the coefficient one.
2420
hash(monomial(t), u)
2521
else
2622
hash(monomial(t), hash(coefficient(t), u))

src/promote.jl

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,37 @@
1-
Base.promote_rule(::Type{PT}, ::Type{PS}) where {PT<:APL, PS<:APL} = promote_type(polynomialtype(PT), polynomialtype(PS))
2-
Base.promote_rule(::Type{PT}, ::Type{PT}) where {PT<:APL} = PT
1+
# MonomialLike
2+
Base.promote_rule(::Type{M}, ::Type{M}) where {M<:AbstractMonomialLike} = M
3+
function Base.promote_rule(M1::Type{<:AbstractMonomialLike},
4+
M2::Type{<:AbstractMonomialLike})
5+
return promote_type(monomialtype(M1), monomialtype(M2))
6+
end
37

4-
promote_rule_constant(::Type{T}, ::Type{RationalPoly{NT, DT}}) where {T, NT, DT} = RationalPoly{promote_type(T, NT), promote_type(DT, termtype(DT))}
8+
# TermLike
9+
Base.promote_rule(::Type{T}, ::Type{T}) where {T<:AbstractTermLike} = T
10+
function Base.promote_rule(TS::Type{<:AbstractTermLike{S}}, TT::Type{<:AbstractTermLike{T}}) where {S, T}
11+
U = promote_type(S, T)
12+
M = promote_type(monomialtype(TS), monomialtype(TT))
13+
return termtype(M, U)
14+
end
15+
function promote_rule_constant(::Type{S}, TT::Type{<:AbstractTermLike{T}}) where {S, T}
16+
return termtype(TT, promote_type(S, T))
17+
end
18+
19+
20+
# PolynomialLike
21+
Base.promote_rule(::Type{PT}, ::Type{PT}) where {PT<:APL} = PT
22+
function Base.promote_rule(PS::Type{<:APL}, PT::Type{<:APL})
23+
return polynomialtype(promote_type(termtype(PS), termtype(PT)))
24+
end
525

26+
function promote_rule_constant(::Type{S}, PT::Type{<:APL{T}}) where {S, T}
27+
return polynomialtype(PT, promote_type(S, T))
28+
end
629
Base.promote_rule(::Type{PT}, ::Type{T}) where {T, PT<:APL} = promote_rule_constant(T, PT)
730
Base.promote_rule(::Type{T}, ::Type{PT}) where {T, PT<:APL} = promote_rule_constant(T, PT)
31+
32+
# Rational
33+
promote_rule_constant(::Type{T}, ::Type{RationalPoly{NT, DT}}) where {T, NT, DT} = RationalPoly{promote_type(T, NT), promote_type(DT, termtype(DT))}
34+
835
Base.promote_rule(::Type{T}, ::Type{RT}) where {T, RT<:RationalPoly} = promote_rule_constant(T, RT)
936
Base.promote_rule(::Type{RT}, ::Type{T}) where {T, RT<:RationalPoly} = promote_rule_constant(T, RT)
1037

@@ -15,21 +42,7 @@ Base.promote_rule(::Type{RS}, ::Type{RT}) where {RS<:RationalPoly, RT<:RationalP
1542
Base.promote_rule(::Type{PT}, ::Type{RT}) where {PT<:APL, RT<:RationalPoly} = promote_rule_rational(PT, RT)
1643
Base.promote_rule(::Type{RT}, ::Type{PT}) where {PT<:APL, RT<:RationalPoly} = promote_rule_rational(PT, RT)
1744

18-
# Promotion with Term
19-
function Base.promote_rule(ST::Type{<:AbstractTermLike{S}}, TT::Type{<:AbstractTerm{T}}) where {S, T}
20-
U = promote_type(S, T)
21-
UT = termtype(ST, U)
22-
if UT != termtype(TT, U)
23-
error("Cannot promote `$ST` and `$TT` to the same type.")
24-
end
25-
return UT
26-
end
27-
28-
#promote_rule(::Type{Term{C, U}}, ::Type{RationalPoly{C, S, T}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}
29-
#promote_rule(::Type{RationalPoly{C, S, T}}, ::Type{Term{C, U}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}
30-
#promote_rule(::Type{Polynomial{C, U}}, ::Type{RationalPoly{C, S, T}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}
31-
#promote_rule(::Type{RationalPoly{C, S, T}}, ::Type{Polynomial{C, U}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}
32-
45+
# MutableArithmetics
3346
function MA.promote_operation(
3447
op::Union{typeof(+), typeof(-)}, PT::Type{<:APL{S}},
3548
QT::Type{<:APL{T}}) where {S, T}

0 commit comments

Comments
 (0)