Generic fraction fields
AbstractAlgebra.jl provides a module, implemented in src/Fraction.jl for fraction fields over any gcd domain belonging to the AbstractAlgebra.jl abstract type hierarchy.
Generic fraction types
AbstractAlgebra.jl implements a generic fraction type Generic.Frac{T} where T is the type of elements of the base ring. See the file src/generic/GenericTypes.jl for details.
Parent objects of such fraction elements have type Generic.FracField{T}.
Abstract types
All fraction element types belong to the abstract type FracElem{T} and the fraction field types belong to the abstract type FracField{T}. This enables one to write generic functions that can accept any AbstractAlgebra fraction type.
Both the generic fraction field type Generic.FracField{T} and the abstract type it belongs to, FracField{T} are both called FracField. The former is a (parameterised) concrete type for a fraction field over a given base ring whose elements have type T. The latter is an abstract type representing all fraction field types in AbstractAlgebra.jl, whether generic or very specialised (e.g. supplied by a C library).
Fraction field constructors
In order to construct fractions in AbstractAlgebra.jl, one can first construct the fraction field itself. This is accomplished with the following constructor.
FractionField(R::Ring; cached::Bool = true)Given a base ring R return the parent object of the fraction field of $R$. By default the parent object S will depend only on R and will be cached. Setting the optional argument cached to false will prevent the parent object S from being cached.
Here are some examples of creating fraction fields and making use of the resulting parent objects to coerce various elements into the fraction field.
Examples
julia> R, x = PolynomialRing(ZZ, "x")
(Univariate Polynomial Ring in x over Integers, x)
julia> S = FractionField(R)
Fraction field of Univariate Polynomial Ring in x over Integers
julia> f = S()
0
julia> g = S(123)
123
julia> h = S(BigInt(1234))
1234
julia> k = S(x + 1)
x + 1
Fraction constructors
One can construct fractions using the fraction field parent object, as for any ring or field.
(R::FracField)() # constructs zero
(R::FracField)(c::Integer)
(R::FracField)(c::elem_type(R))
(R::FracField{T})(a::T) where T <: RingElementOne may also use the Julia double slash operator to construct elements of the fraction field without constructing the fraction field parent first.
//(x::T, y::T) where T <: RingElementExamples
julia> R, x = PolynomialRing(QQ, "x")
(Univariate Polynomial Ring in x over Rationals, x)
julia> S = FractionField(R)
Fraction field of Univariate Polynomial Ring in x over Rationals
julia> f = S(x + 1)
x + 1
julia> g = (x^2 + x + 1)//(x^3 + 3x + 1)
(x^2 + x + 1)//(x^3 + 3*x + 1)
julia> x//f
x//(x + 1)
julia> f//x
(x + 1)//xFunctions for types and parents of fraction fields
Fraction fields in AbstractAlgebra.jl implement the Ring interface.
base_ring(R::FracField)
base_ring(a::FracElem)Return the base ring of which the fraction field was constructed.
parent(a::FracElem)Return the fraction field of the given fraction.
characteristic(R::FracField)Return the characteristic of the base ring of the fraction field.
Examples
julia> R, x = PolynomialRing(QQ, "x")
(Univariate Polynomial Ring in x over Rationals, x)
julia> S = FractionField(R)
Fraction field of Univariate Polynomial Ring in x over Rationals
julia> f = S(x + 1)
x + 1
julia> U = base_ring(S)
Univariate Polynomial Ring in x over Rationals
julia> V = base_ring(f)
Univariate Polynomial Ring in x over Rationals
julia> T = parent(f)
Fraction field of Univariate Polynomial Ring in x over Rationals
julia> m = characteristic(S)
0Fraction field functions
Basic functions
Fraction fields implement the Ring interface.
zero(R::FracField)
one(R::FracField)
iszero(a::FracElem)
isone(a::FracElem)inv(a::T) where T <: FracElemThey also implement the field interface.
isunit(f::FracElem)And they implement the fraction field interface.
numerator(a::FracElem)
denominator(a::FracElem)Examples
julia> R, x = PolynomialRing(QQ, "x")
(Univariate Polynomial Ring in x over Rationals, x)
julia> S = FractionField(R)
Fraction field of Univariate Polynomial Ring in x over Rationals
julia> f = S(x + 1)
x + 1
julia> g = (x^2 + x + 1)//(x^3 + 3x + 1)
(x^2 + x + 1)//(x^3 + 3*x + 1)
julia> h = zero(S)
0
julia> k = one(S)
1
julia> isone(k)
true
julia> iszero(f)
false
julia> r = deepcopy(f)
x + 1
julia> n = numerator(g)
x^2 + x + 1
julia> d = denominator(g)
x^3 + 3*x + 1Greatest common divisor
Base.gcd — Methodgcd(a::FracElem{T}, b::FracElem{T}) where {T <: RingElem}Return a greatest common divisor of $a$ and $b$ if one exists. N.B: we define the GCD of $a/b$ and $c/d$ to be gcd$(ad, bc)/bd$, reduced to lowest terms. This requires the existence of a greatest common divisor function for the base ring.
Examples
julia> R, x = PolynomialRing(QQ, "x")
(Univariate Polynomial Ring in x over Rationals, x)
julia> f = (x + 1)//(x^3 + 3x + 1)
(x + 1)//(x^3 + 3*x + 1)
julia> g = (x^2 + 2x + 1)//(x^2 + x + 1)
(x^2 + 2*x + 1)//(x^2 + x + 1)
julia> h = gcd(f, g)
(x + 1)//(x^5 + x^4 + 4*x^3 + 4*x^2 + 4*x + 1)
Square root
AbstractAlgebra.issquare — Methodissquare(a::FracElem{T}) where T <: RingElemReturn true if $a$ is a square.
Base.sqrt — MethodBase.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElemReturn the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.
Examples
julia> R, x = PolynomialRing(QQ, "x")
(Univariate Polynomial Ring in x over Rationals, x)
julia> S = FractionField(R)
Fraction field of Univariate Polynomial Ring in x over Rationals
julia> a = (21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
julia> sqrt(a^2)
(21//4*x^6 - 15*x^5 + 27//14*x^4 + 9//20*x^3 + 3//7*x + 9//10)//(x + 3)
julia> issquare(a^2)
trueRemove and valuation
When working over a Euclidean domain, it is convenient to extend valuations to the fraction field. To facilitate this, we define the following functions.
AbstractAlgebra.remove — Methodremove(z::FracElem{T}, p::T) where {T <: RingElem}Return the tuple $n, x$ such that $z = p^nx$ where $x$ has valuation $0$ at $p$.
AbstractAlgebra.valuation — Methodvaluation(z::FracElem{T}, p::T) where {T <: RingElem}Return the valuation of $z$ at $p$.
Examples
julia> R, x = PolynomialRing(ZZ, "x")
(Univariate Polynomial Ring in x over Integers, x)
julia> f = (x + 1)//(x^3 + 3x + 1)
(x + 1)//(x^3 + 3*x + 1)
julia> g = (x^2 + 1)//(x^2 + x + 1)
(x^2 + 1)//(x^2 + x + 1)
julia> v, q = remove(f^3*g, x + 1)
(3, (x^2 + 1)//(x^11 + x^10 + 10*x^9 + 12*x^8 + 39*x^7 + 48*x^6 + 75*x^5 + 75*x^4 + 66*x^3 + 37*x^2 + 10*x + 1))
julia> v = valuation(f^3*g, x + 1)
3
Random generation
Random fractions can be generated using rand. The parameters passed after the fraction field tell rand how to generate random elements of the base ring.
rand(R::FracField, v...)Examples
julia> K = FractionField(ZZ)
Rationals
julia> f = rand(K, -10:10)
1//1
julia> R, x = PolynomialRing(ZZ, "x")
(Univariate Polynomial Ring in x over Integers, x)
julia> S = FractionField(R)
Fraction field of Univariate Polynomial Ring in x over Integers
julia> g = rand(S, -1:3, -10:10)
-5//10