Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/AbstractTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ abstract type ResidueField{T<:RingElement} <: Field end

abstract type FracField{T<:RingElement} <: Field end

abstract type TotFracRing{T<:RingElement} <: Ring end

abstract type MatRing{T<:NCRingElement} <: NCRing end

abstract type FreeAssociativeAlgebra{T<:RingElement} <: NCRing end
Expand Down Expand Up @@ -135,6 +137,8 @@ abstract type ResFieldElem{T<:RingElement} <: FieldElem end

abstract type FracElem{T<:RingElement} <: FieldElem end

abstract type TotFrac{T<:RingElement} <: RingElem end
Comment thread
fingolfin marked this conversation as resolved.

abstract type SeriesElem{T<:RingElement} <: RingElem end

abstract type MSeriesElem{T<:RingElement} <: RingElem end
Expand Down
17 changes: 13 additions & 4 deletions src/Fraction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,21 @@ end
###############################################################################

function //(x::T, y::T) where {T <: RingElem}
R = parent(x)
iszero(y) && throw(DivideError())
R = parent(x)
g = gcd(x, y)
z = Generic.FracFieldElem{T}(divexact(x, g), divexact(y, g))
z.parent = get(Generic.FracDict, R) do
return Generic.fraction_field(R)
if is_domain_type(R)
z = Generic.FracFieldElem{T}(divexact(x, g), divexact(y, g))
z.parent = get(Generic.FracDict, R) do
return Generic.fraction_field(R)
end
return z
end
# R might not be integral, so construct total ring of fractions
is_zero_divisor(y) && error("Division by a zero-divisor")
z = Generic.TotFrac{T}(divexact(x, g), divexact(y, g))
z.parent = get(Generic.TotFracDict, R) do
return Generic.total_ring_of_fractions(R)
end
return z
end
Expand Down
2 changes: 2 additions & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ export SimpleNumFieldElem
export SkewDiagram
export Strassen
export SymmetricGroup
export TotFrac
export TotFracRing
export UniversalPolyRing
export UniversalPolyRingElem
export UniversalRing
Expand Down
4 changes: 2 additions & 2 deletions src/generic/GenericTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ end
#
###############################################################################

@attributes mutable struct TotFracRing{T <: RingElem} <: AbstractAlgebra.Ring
@attributes mutable struct TotFracRing{T <: RingElem} <: AbstractAlgebra.TotFracRing{T}
base_ring::Ring

function TotFracRing{T}(R::Ring, cached::Bool = true) where T <: RingElem
Expand All @@ -942,7 +942,7 @@ end

const TotFracDict = CacheDictType{Ring, Ring}()

mutable struct TotFrac{T <: RingElem} <: AbstractAlgebra.RingElem
mutable struct TotFrac{T <: RingElem} <: AbstractAlgebra.TotFrac{T}
num::T
den::T
parent::TotFracRing{T}
Expand Down
2 changes: 1 addition & 1 deletion src/generic/Residue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function (a::EuclideanRingResidueRing{T})(b::Integer) where {T <: RingElement}
return z
end

function (a::EuclideanRingResidueRing)(b::T) where {T <: Union{Rational, FracElem}}
function (a::EuclideanRingResidueRing)(b::T) where {T <: Union{Rational, FracElem, TotFrac}}
return inv(a(denominator(b))) * a(numerator(b))
end

Expand Down
42 changes: 42 additions & 0 deletions src/generic/TotalFraction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,48 @@ end
# Division is not possible generically due to the possibility of non-units
# that are also non-zero divisors

##############################################################################
#
# Evaluation
#
##############################################################################

function evaluate(f::TotFrac, V::Vector{<:RingElement})
return evaluate(numerator(f), V)//evaluate(denominator(f), V)
end

function evaluate(f::TotFrac, v::RingElement)
return evaluate(numerator(f), v)//evaluate(denominator(f), v)
end

function evaluate(f::TotFrac{<:PolyRingElem}, v::Integer)
return evaluate(numerator(f), v)//evaluate(denominator(f), v)
end

# function evaluate(f::TotFrac, vals::Vector{<:RingElement})
# @req length(vals) == ngens(base_ring(parent(a))) "Evaluation point needs 1 coordinate per variable"
# vars = collect(1:ngens(base_ring(parent(a))))
# return evaluate(numerator(f), vars, vals)//evaluate(denominator(f), vars, vals)
# end

function evaluate(f::TotFrac, vars::Vector{Int}, vals::Vector{<:RingElement})
return evaluate(numerator(f), vars, vals)//evaluate(denominator(f), vars, vals)
end

function (a::TotFrac)(val::RingElement)
return evaluate(a, val)
end

function (a::TotFrac)(vals::RingElement...)
vars = collect(1:ngens(base_ring(parent(a))))
return evaluate(a, vars, [vals...])
end

function (a::TotFrac)(vals::Vector{<:RingElement})
vars = collect(1:ngens(base_ring(parent(a))))
return evaluate(a, vars, vals)
end

###############################################################################
#
# Powering
Expand Down
17 changes: 16 additions & 1 deletion test/generic/Fraction-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ end
S, x = polynomial_ring(R, "x")

f = (x^2 + 2)//(x + 1)
@test f isa Generic.FracFieldElem
@test f isa Generic.TotFrac

@test evaluate(f, 1) == R(4)
@test evaluate(f, R(1)) == R(4)
Expand All @@ -308,6 +308,21 @@ end
@test f(1, 2) == ZZ(3)//ZZ(4)
@test f(ZZ(1), ZZ(2)) == ZZ(3)//ZZ(4)

# multivariate over non domain
R, = residue_ring(ZZ, 15)
S, (x,y) = polynomial_ring(R, ["x","y"])

f = (x^2 + 3)//(x + 1)
@test f isa Generic.TotFrac

@test evaluate(f, [1,2]) == R(2)
@test evaluate(f, [R(1),R(2)]) == R(2)

@test f([1,2]) == R(2)
@test f([R(1),R(2)]) == R(2)
@test f(1,2) == R(2)
@test f(R(1),R(2)) == R(2)

# universal
R = universal_polynomial_ring(ZZ)
x, y = gens(R, [:x, :y])
Expand Down
Loading