Skip to content

Commit 1d3c791

Browse files
authored
Decide between Field or UFD with trait (#163)
1 parent 313e049 commit 1d3c791

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/division.jl

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,19 @@ divides(t1::AbstractVariable, t2::AbstractVariable) = t1 == t2
1818
Base.gcd(m1::AbstractMonomialLike, m2::AbstractMonomialLike) = mapexponents(min, m1, m2)
1919
Base.lcm(m1::AbstractMonomialLike, m2::AbstractMonomialLike) = mapexponents(max, m1, m2)
2020

21+
struct Field end
22+
struct UniqueFactorizationDomain end
23+
const UFD = UniqueFactorizationDomain
24+
25+
algebraic_structure(::Type{<:Union{Rational, AbstractFloat}}, ::Type{<:Union{Rational, AbstractFloat}}) = Field()
26+
algebraic_structure(::Type{<:Union{Rational, AbstractFloat}}, ::Type) = Field()
27+
algebraic_structure(::Type, ::Type{<:Union{Rational, AbstractFloat}}) = Field()
28+
algebraic_structure(::Type, ::Type) = UFD()
29+
2130
# _div(a, b) assumes that b divides a
22-
_div(a::Union{Rational, AbstractFloat}, b) = a / b
23-
_div(a, b) = div(a, b)
31+
_div(::Field, a, b) = a / b
32+
_div(::UFD, a, b) = div(a, b)
33+
_div(a, b) = _div(algebraic_structure(typeof(a), typeof(b)), a, b)
2434
_div(m1::AbstractMonomialLike, m2::AbstractMonomialLike) = mapexponents(-, m1, m2)
2535
function _div(t::AbstractTerm, m::AbstractMonomial)
2636
term(coefficient(t), _div(monomial(t), m))
@@ -46,12 +56,15 @@ end
4656
Base.div(f::APL, g::Union{APL, AbstractVector{<:APL}}; kwargs...) = divrem(f, g; kwargs...)[1]
4757
Base.rem(f::APL, g::Union{APL, AbstractVector{<:APL}}; kwargs...) = divrem(f, g; kwargs...)[2]
4858

49-
# FIXME What should we do for `Rational` ?
50-
function pseudo_rem(f::APL, g::APL{<:Union{Rational, AbstractFloat}}, algo)
59+
function pseudo_rem(f::APL{S}, g::APL{T}, algo) where {S,T}
60+
return _pseudo_rem(algebraic_structure(S, T), f, g, algo)
61+
end
62+
63+
function _pseudo_rem(::Field, f::APL, g::APL, algo)
5164
return true, rem(f, g)
5265
end
5366

54-
function pseudo_rem(f::APL, g::APL, algo)
67+
function _pseudo_rem(::UFD, f::APL, g::APL, algo)
5568
ltg = leadingterm(g)
5669
rg = removeleadingterm(g)
5770
ltf = leadingterm(f)
@@ -73,14 +86,28 @@ function pseudo_rem(f::APL, g::APL, algo)
7386
end
7487
return true, f
7588
end
89+
7690
function MA.promote_operation(
7791
::typeof(pseudo_rem),
7892
::Type{P},
7993
::Type{Q},
80-
) where {T,S<:Union{Rational, AbstractFloat},P<:APL{T},Q<:APL{S}}
94+
) where {T,S,P<:APL{T},Q<:APL{S}}
95+
return _promote_operation(algebraic_structure(T, S), pseudo_rem, P, Q)
96+
end
97+
function _promote_operation(
98+
::Field,
99+
::typeof(pseudo_rem),
100+
::Type{P},
101+
::Type{Q},
102+
) where {P<:APL,Q<:APL}
81103
return MA.promote_operation(rem, P, Q)
82104
end
83-
function MA.promote_operation(::typeof(pseudo_rem), ::Type{P}, ::Type{Q}) where {T,S,P<:APL{T},Q<:APL{S}}
105+
function _promote_operation(
106+
::UFD,
107+
::typeof(pseudo_rem),
108+
::Type{P},
109+
::Type{Q},
110+
) where {T,S,P<:APL{T},Q<:APL{S}}
84111
U1 = MA.promote_operation(*, S, T)
85112
U2 = MA.promote_operation(*, T, S)
86113
# `promote_type(P, Q)` is needed for TypedPolynomials in case they use different variables

src/gcd.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,10 @@ If the coefficients are not `AbstractFloat`, this
384384
*Art of computer programming, volume 2: Seminumerical algorithms.*
385385
Addison-Wesley Professional. Third edition.
386386
"""
387-
function univariate_gcd(p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm)
387+
function univariate_gcd(p1::APL{S}, p2::APL{T}, algo::AbstractUnivariateGCDAlgorithm) where {S,T}
388+
return univariate_gcd(algebraic_structure(S, T), p1, p2, algo)
389+
end
390+
function univariate_gcd(::UFD, p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm)
388391
f1, g1 = primitive_part_content(p1, algo)
389392
f2, g2 = primitive_part_content(p2, algo)
390393
pp = primitive_univariate_gcd(f1, f2, algo)
@@ -393,7 +396,7 @@ function univariate_gcd(p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm)
393396
return mapcoefficientsnz(Base.Fix1(*, gg), pp)
394397
end
395398

396-
function univariate_gcd(p1::APL, p2::APL{<:AbstractFloat}, algo::AbstractUnivariateGCDAlgorithm)
399+
function univariate_gcd(::Field, p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm)
397400
return primitive_univariate_gcd(p1, p2, algo)
398401
end
399402

0 commit comments

Comments
 (0)