Skip to content

Commit f58788e

Browse files
authored
Merge pull request #140 from JuliaAlgebra/bl/comparison_terms
Add comparison tests
2 parents 725642e + d656a46 commit f58788e

File tree

10 files changed

+92
-62
lines changed

10 files changed

+92
-62
lines changed

src/comparison.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ eqconstant(t::AbstractTermLike, α) = _termeqconstant(t, α)
4040
eqconstant(α, p::APL) = polyeqterm(p, α)
4141
eqconstant(p::APL, α) = polyeqterm(p, α)
4242

43+
function Base.:(==)(mono::AbstractMonomial, v::AbstractVariable)
44+
return isone(degree(mono)) && variable(mono) == v
45+
end
46+
function Base.:(==)(v::AbstractVariable, mono::AbstractMonomial)
47+
return isone(degree(mono)) && v == variable(mono)
48+
end
49+
function Base.:(==)(t::AbstractTerm, mono::AbstractMonomialLike)
50+
return isone(coefficient(t)) && monomial(t) == mono
51+
end
52+
function Base.:(==)(mono::AbstractMonomialLike, t::AbstractTerm)
53+
return isone(coefficient(t)) && mono == monomial(t)
54+
end
55+
4356
function Base.:(==)(t1::AbstractTerm, t2::AbstractTerm)
4457
c1 = coefficient(t1)
4558
c2 = coefficient(t2)

src/conversion.jl

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,53 @@ function Base.convert(::Type{P}, p::APL) where {T, P<:AbstractPolynomial{T}}
99
return convert(P, polynomial(p, T))
1010
end
1111

12+
function Base.convert(::Type{V}, mono::AbstractMonomial) where V <: AbstractVariable
13+
variable = nothing
14+
for v in variables(mono)
15+
d = degree(mono, v)
16+
if isone(d)
17+
if variable === nothing
18+
variable = v
19+
else
20+
throw(InexactError(:convert, V, mono))
21+
end
22+
elseif !iszero(d)
23+
throw(InexactError(:convert, V, mono))
24+
end
25+
end
26+
if variable === nothing
27+
throw(InexactError(:convert, V, mono))
28+
end
29+
return variable
30+
end
31+
32+
function Base.convert(::Type{M}, t::AbstractTerm) where M <: AbstractMonomialLike
33+
if isone(coefficient(t))
34+
return convert(M, monomial(t))
35+
else
36+
throw(InexactError(:convert, M, t))
37+
end
38+
end
39+
function Base.convert(TT::Type{<:AbstractTerm{T}}, m::AbstractMonomialLike) where T
40+
return convert(TT, one(T) * m)
41+
end
42+
function Base.convert(TT::Type{<:AbstractTerm{T}}, t::AbstractTerm) where T
43+
return convert(TT, convert(T, coefficient(t)) * monomial(t))
44+
end
45+
function Base.convert(::Type{T}, t::T) where T <: AbstractTerm
46+
return t
47+
end
48+
49+
function Base.convert(::Type{T}, p::AbstractPolynomial) where T <: AbstractTermLike
50+
if iszero(nterms(p))
51+
convert(T, zeroterm(p))
52+
elseif isone(nterms(p))
53+
convert(T, leadingterm(p))
54+
else
55+
throw(InexactError(:convert, T, p))
56+
end
57+
end
58+
1259
MA.scaling(p::AbstractPolynomialLike{T}) where {T} = convert(T, p)
1360
Base.convert(::Type{Any}, p::APL) = p
1461
# Conversion polynomial -> scalar
@@ -24,14 +71,4 @@ function Base.convert(S::Type{<:Union{Number, T}}, p::APL{T}) where T
2471
s
2572
end
2673

27-
# Fix ambiguity caused by above conversions
28-
Base.convert(::Type{P}, p::APL) where P<:APL = P(p)
29-
3074
Base.convert(::Type{PT}, p::PT) where {PT<:APL} = p
31-
function Base.convert(::Type{MT}, t::AbstractTerm) where {MT<:AbstractMonomial}
32-
if isone(coefficient(t))
33-
monomial(t)
34-
else
35-
error("Cannot convert a term with a coefficient that is not one into a monomial")
36-
end
37-
end

src/monomial.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Note that the variables of `m` does not necessarily have nonzero degree.
2525
For instance, `variables([x^2*y, y*z][1])` is usually `(x, y, z)` since the two monomials have been promoted to a common type.
2626
"""
2727
function variables end
28+
variables(t::AbstractTerm) = variables(monomial(t))
2829

2930
"""
3031
nvariables(p::AbstractPolynomialLike)
@@ -36,6 +37,7 @@ Returns the number of variables in `p`, i.e. `length(variables(p))`. It could be
3637
Calling `nvariables(x^2*y)` should return at least 2 and calling `nvariables(x)` should return at least 1.
3738
"""
3839
nvariables(::Union{AbstractVariable, Type{<:AbstractVariable}}) = 1
40+
nvariables(p::APL) = length(variables(p))
3941

4042
"""
4143
exponents(t::AbstractTermLike)

src/promote.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ Base.promote_rule(::Type{RS}, ::Type{RT}) where {RS<:RationalPoly, RT<:RationalP
1515
Base.promote_rule(::Type{PT}, ::Type{RT}) where {PT<:APL, RT<:RationalPoly} = promote_rule_rational(PT, RT)
1616
Base.promote_rule(::Type{RT}, ::Type{PT}) where {PT<:APL, RT<:RationalPoly} = promote_rule_rational(PT, RT)
1717

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+
1828
#promote_rule(::Type{Term{C, U}}, ::Type{RationalPoly{C, S, T}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}
1929
#promote_rule(::Type{RationalPoly{C, S, T}}, ::Type{Term{C, U}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}
2030
#promote_rule(::Type{Polynomial{C, U}}, ::Type{RationalPoly{C, S, T}}) where {C, S, T, U} = RationalPoly{C, promote_type(U, S), T}

src/term.jl

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,11 @@ export constantterm, term, termtype, zeroterm, coefficient, monomial
44
term(p::AbstractPolynomialLike)
55
66
Converts the polynomial `p` to a term.
7-
When applied on a polynomial, it throws an error if it has more than one term.
7+
When applied on a polynomial, it throws an `InexactError` if it has more than one term.
88
When applied to a term, it is the identity and does not copy it.
99
When applied to a monomial, it create a term of type `AbstractTerm{Int}`.
1010
"""
11-
function term(p::APL{T}) where T
12-
if nterms(p) == 0
13-
zeroterm(p)
14-
elseif nterms(p) > 1
15-
error("A polynomial is more than one term cannot be converted to a term.")
16-
else
17-
leadingterm(p)
18-
end
19-
end
20-
term(t::AbstractTerm) = t
21-
term(m::AbstractMonomialLike) = 1 * m
11+
term(p::APL) = convert(termtype(p), p)
2212

2313
"""
2414
termtype(p::AbstractPolynomialLike)
@@ -61,6 +51,8 @@ Calling `coefficient` on ``4x^2y`` should return ``4``.
6151
Calling `coefficient(2x + 4y^2 + 3, y^2)` should return ``4``.
6252
Calling `coefficient(2x + 4y^2 + 3, x^2)` should return ``0``.
6353
"""
54+
function coefficient end
55+
coefficient(t::AbstractTerm) = t.coefficient # by convention, the field should be `coefficient`
6456
coefficient(m::AbstractMonomialLike) = 1
6557
function coefficient(p::AbstractPolynomialLike{T}, m::AbstractMonomialLike) where T
6658
for t in terms(p)
@@ -126,6 +118,7 @@ Returns the monomial of the term `t`.
126118
Calling `monomial` on ``4x^2y`` should return ``x^2y``.
127119
"""
128120
function monomial end
121+
monomial(t::AbstractTerm) = t.monomial # by convention, the field should be `monomial`.
129122
monomial(m::AbstractMonomial) = m
130123

131124
"""

src/variable.jl

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,49 +21,19 @@ function variable_union_type end
2121
"""
2222
variable(p::AbstractPolynomialLike)
2323
24-
Converts `p` to a variable. Throws an error if it is not possible.
24+
Converts `p` to a variable. Throws `InexactError` if it is not possible.
2525
2626
### Examples
2727
2828
Calling `variable(x^2 + x - x^2)` should return the variable `x` and
2929
calling `variable(1.0y)` should return the variable `y` however calling
30-
`variable(2x)` or `variable(x + y)` should throw an error.
30+
`variable(2x)` or `variable(x + y)` should throw `InexactError`.
3131
3232
### Note
3333
3434
This operation is not type stable for the TypedPolynomials implementation if `nvariables(p) > 1` but is type stable for DynamicPolynomials.
3535
"""
36-
variable(m::AbstractMonomialLike) = _mono2var(powers(m)...)
37-
variable(v::AbstractVariable) = v
38-
function variable(t::AbstractTermLike)
39-
if isone(coefficient(t))
40-
variable(monomial(t))
41-
else
42-
error("A term with non-one coefficient cannot be converted into a variable")
43-
end
44-
end
45-
variable(p::APL) = variable(term(p))
46-
47-
_errormono2var() = error("Monomial cannot be converted to a variable")
48-
_mono2var() = _errormono2var()
49-
function _checknovar() end
50-
function _checknovar(ve, ves...)
51-
if iszero(ve[2])
52-
_checknovar(ves...)
53-
else
54-
_errormono2var()
55-
end
56-
end
57-
function _mono2var(ve, ves...)
58-
if iszero(ve[2])
59-
_mono2var(ves...)
60-
elseif isone(ve[2])
61-
_checknovar(ves...)
62-
ve[1]
63-
else
64-
_errormono2var()
65-
end
66-
end
36+
variable(t::APL) = convert(variable_union_type(t), t)
6737

6838
"""
6939
name(v::AbstractVariable)::AbstractString

test/commutativetests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
include("mutable_arithmetics.jl")
1+
#include("mutable_arithmetics.jl")
22

33
include("zip.jl")
44
include("variable.jl")

test/monomial.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,16 @@ const MP = MultivariatePolynomials
2525
@test degree(x * y[2]^2, y[1]) == 0
2626
@test degree(x * y[2]^2, y[2]) == 2
2727

28-
@test_throws ErrorException variable(x^2)
29-
@test_throws ErrorException variable(x*y[1])
30-
@test_throws ErrorException variable(constantmonomial(typeof(x)))
28+
@test_throws InexactError variable(x^2)
29+
@test_throws InexactError variable(x*y[1])
30+
@test_throws InexactError variable(constantmonomial(typeof(x)))
31+
32+
@test x != constantmonomial(typeof(x))
33+
@test constantmonomial(typeof(x)) != x
3134

3235
m = x^2
36+
@test x != m
37+
@test m != x
3338
typetests(m)
3439
typetests([x^2, x^3])
3540
@test (@inferred polynomial(m)) isa AbstractPolynomial{Int}
@@ -41,7 +46,7 @@ const MP = MultivariatePolynomials
4146
@test variable(x^2 + x - x^2) isa AbstractVariable
4247
@test variable(1.0x) == x
4348
@test variable(1.0x) isa AbstractVariable
44-
@test_throws ErrorException variable(x + 2x) == x
49+
@test_throws InexactError variable(x + 2x) == x
4550

4651
@test monic(x^2) == x^2
4752

test/polynomial.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const MP = MultivariatePolynomials
3737
@test term(x + x^2 - x) == x^2
3838
@test term(x - x) isa AbstractTerm
3939
@test iszero(term(x - x))
40-
@test_throws ErrorException term(x + x^2)
40+
@test_throws InexactError term(x + x^2)
4141

4242
Mod.@polyvar y
4343

test/term.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Base.iszero(::CoefNotComparable) = false
5151
@test (@inferred polynomial(t, Float64)) isa AbstractPolynomial{Float64}
5252

5353
@test_throws InexactError push!([1], 2x)
54-
@test_throws ErrorException push!([x^2], 2x)
54+
@test_throws InexactError push!([x^2], 2x)
5555

5656
@testset "Effective variables" begin
5757
T = variable_union_type(x)

0 commit comments

Comments
 (0)