Rational function fields
AbstractAlgebra.jl provides a module, implemented in src/generic/RationalFunctionField.jl for rational function fields $k(x)$ or k[x_1, x_2, \ldots, x_n] over a field $k$.
Generic rational function field type
Rational functions have type Generic.RationalFunctionFieldElem{T, U} where T is the type of elements of the coefficient field $k$ and U is the type of polynomials (either univariate or multivariate) over that field. See the file src/generic/GenericTypes.jl for details.
Parent objects corresponding to the rational function field $k$ have type Generic.RationalFunctionField{T, U}.
Abstract types
The rational function types belong to the abstract type Field and the rational function field types belong to the abstract type FieldElem.
Rational function field constructors
In order to construct rational functions in AbstractAlgebra.jl, one can first construct the function field itself. This is accomplished with one of the following constructors.
rational_function_field(k::Field, s::VarName; cached::Bool = true)
rational_function_field(k::Field, s::Vector{<:VarName}; cached::Bool = true)Given a coefficient field k return a tuple (S, x) consisting of the parent object of the rational function field over $k$ and the generator(s) x. By default the parent object S will depend only on R and s 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 rational function fields and making use of the resulting parent objects to coerce various elements into the function field.
Examples
julia> S, x = rational_function_field(QQ, :x)
(Rational function field over rationals, x)
julia> f = S()
0
julia> g = S(123)
123
julia> h = S(BigInt(1234))
1234
julia> k = S(x + 1)
x + 1
julia> m = S(numerator(x + 1, false), numerator(x + 2, false))
(x + 1)//(x + 2)
julia> R, (x, y) = rational_function_field(QQ, [:x, :y])
(Rational function field over rationals, AbstractAlgebra.Generic.RationalFunctionFieldElem{Rational{BigInt}, AbstractAlgebra.Generic.MPoly{Rational{BigInt}}}[x, y])
julia> (x + y)//y^2
(x + y)//y^2Basic rational function field functionality
Fraction fields in AbstractAlgebra.jl implement the full Field interface and the entire fraction field interface.
We give some examples of such functionality.
Examples
julia> S, x = rational_function_field(QQ, :x)
(Rational function field over rationals, x)
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> m = characteristic(S)
0
julia> U = base_ring(S)
Rationals
julia> V = base_ring(f)
Rationals
julia> T = parent(f)
Rational function field
over rationals
julia> r = deepcopy(f)
x + 1
julia> n = numerator(g)
x^2 + x + 1
julia> d = denominator(g)
x^3 + 3*x + 1
Note that numerator and denominator are returned as elements of a polynomial ring whose variable is printed the same way as that of the generator of the rational function field.
Rational function field functionality provided by AbstractAlgebra.jl
The following functionality is provided for rational function fields.
Greatest common divisor
gcd — Methodgcd(a::RationalFunctionFieldElem{T, U}, b::RationalFunctionFieldElem{T, U}) where {T <: FieldElement, U <: Union{PolyRingElem, MPolyRingElem}}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.
Examples
julia> R, x = rational_function_field(QQ, :x)
(Rational function field 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
is_square — Methodis_square(f::PolyRingElem{T}) where T <: RingElementReturn true if $f$ is a perfect square.
is_square(a::FracElem{T}) where T <: RingElemReturn true if $a$ is a square.
sqrt — MethodBase.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElementReturn the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.
Base.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.
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElementReturn the square root of the given Puiseux series $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 = rational_function_field(QQ, :x)
(Rational function field over rationals, x)
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> is_square(a^2)
trueUnivariate function fields
Univariate function fields in AbstractAlgebra are algebraic extensions $K/k(x)$ of a rational function field $k(x)$ over a field $k$.
These are implemented in a module implemented in src/generic/FunctionField.jl.
Generic function field types
Function field objects $K/k(x)$ in AbstractAlgebra have type Generic.FunctionField{T} where T is the type of elements of the field k.
Corresponding function field elements have type Generic.FunctionFieldElement{T}. See the file src/generic/GenericTypes.jl for details.
Abstract types
Function field types belong to the abstract type Field and their elements to the abstract type FieldElem.
Function field constructors
In order to construct function fields in AbstractAlgebra.jl, one first constructs the rational function field they are an extension of, then supplies a polynomial over this field to the following constructor:
function_field(p::Poly{RationalFunctionFieldElem{T, U}}, s::AbstractString; cached::Bool=true) where {T <: FieldElement, U <: PolyRingElem{T}}Given an irreducible polynomial p over a rational function field return a tuple (S, z) consisting of the parent object of the function field defined by that polynomial over $k(x)$ and the generator z. By default the parent object S will depend only on p and s 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 function fields and making use of the resulting parent objects to coerce various elements into the function field.
Examples
julia> R1, x1 = rational_function_field(QQ, "x1") # characteristic 0
(Rational function field over rationals, x1)
julia> U1, z1 = R1["z1"]
(Univariate polynomial ring in z1 over R1, z1)
julia> f = (x1^2 + 1)//(x1 + 1)*z1^3 + 4*z1 + 1//(x1 + 1)
(x1^2 + 1)//(x1 + 1)*z1^3 + 4*z1 + 1//(x1 + 1)
julia> S1, y1 = function_field(f, "y1")
(Function Field over rationals with defining polynomial (x1^2 + 1)*y1^3 + (4*x1 + 4)*y1 + 1, y1)
julia> a = S1()
0
julia> b = S1((x1 + 1)//(x1 + 2))
(x1 + 1)//(x1 + 2)
julia> c = S1(1//3)
1//3
julia> R2, x2 = rational_function_field(GF(23), "x1") # characteristic p
(Rational function field over finite field F_23, x1)
julia> U2, z2 = R2["z2"]
(Univariate polynomial ring in z2 over R2, z2)
julia> g = z2^2 + 3z2 + 1
z2^2 + 3*z2 + 1
julia> S2, y2 = function_field(g, "y2")
(Function Field over finite field F_23 with defining polynomial y2^2 + 3*y2 + 1, y2)
julia> d = S2(R2(5))
5
julia> e = S2(y2)
y2Basic function field functionality
Function fields implement the full Ring and Field interfaces. We give some examples of such functionality.
Examples
julia> R, x = rational_function_field(GF(23), :x) # characteristic p
(Rational function field over finite field F_23, x)
julia> U, z = R[:z]
(Univariate polynomial ring in z over R, z)
julia> g = z^2 + 3z + 1
z^2 + 3*z + 1
julia> S, y = function_field(g, :y)
(Function Field over finite field F_23 with defining polynomial y^2 + 3*y + 1, y)
julia> f = (x + 1)*y + 1
(x + 1)*y + 1
julia> base_ring(f)
Rational function field
over finite field F_23
julia> f^2
(20*x^2 + 19*x + 22)*y + 22*x^2 + 21*x
julia> f*inv(f)
1Function field functionality provided by AbstractAlgebra.jl
The following functionality is provided for function fields.
Basic manipulation
base_field — Methodbase_field(R::FunctionField)Return the rational function field that the field R is an extension of. Synonymous with base_ring.
var — Methodvar(R::FunctionField)Return the variable name of the generator of the function field R as a symbol.
characteristic — Methodcharacteristic(R::FunctionField)Return the characteristic of the underlying rational function field.
defining_polynomial — Methoddefining_polynomial(R::FunctionField)
modulus(R::FunctionField)Return the original polynomial that was used to define the function field R.
numerator — MethodBase.numerator(R::FunctionField{T}, canonicalise::Bool=true) where T <: FieldElement
Base.denominator(R::FunctionField{T}, canonicalise::Bool=true) where T <: FieldElementThinking of elements of the rational function field as fractions, put the defining polynomial of the function field over a common denominator and return the numerator/denominator respectively. Note that the resulting polynomials belong to a different ring than the original defining polynomial. The canonicalise is ignored, but exists for compatibility with the Generic interface.
numerator — MethodBase.numerator(a::FunctionFieldElem{T}, canonicalise::Bool=true) where T <: FieldElement
Base.denominator(a::FunctionFieldElem{T}, canonicalise::Bool=true) where T <: FieldElementReturn the numerator and denominator of the function field element a. Note that elements are stored in fraction free form so that the denominator is a common denominator for the coefficients of the element a. If canonicalise is set to true the fraction is first canonicalised.
degree — Methoddegree(S::FunctionField)Return the degree of the defining polynomial of the function field, i.e. the degree of the extension that the function field makes of the underlying rational function field.
gen — Methodgen(S::FunctionField{T}) where T <: FieldElementReturn the generator of the function field returned by the function field constructor.
is_gen — Methodis_gen(a::FunctionFieldElem)Return true if a is the generator of the function field returned by the function field constructor.
coeff — Methodcoeff(a::FunctionFieldElem, n::Int)Return the degree n coefficient of the element a in its polynomial representation in terms of the generator of the function field. The coefficient is returned as an element of the underlying rational function field.
num_coeff — Methodnum_coeff(a::FunctionFieldElem, n::Int)Return the degree n coefficient of the numerator of the element a (in its polynomial representation in terms of the generator of the function field, rationalised as per numerator/denominator described above). The coefficient will be an polynomial over the base_ring of the underlying rational function field.
Examples
julia> R, x = rational_function_field(QQ, :x)
(Rational function field over rationals, x)
julia> U, z = R[:z]
(Univariate polynomial ring in z over R, z)
julia> g = z^2 + 3*(x + 1)//(x + 2)*z + 1
z^2 + (3*x + 3)//(x + 2)*z + 1
julia> S, y = function_field(g, :y)
(Function Field over rationals with defining polynomial (x + 2)*y^2 + (3*x + 3)*y + x + 2, y)
julia> base_field(S)
Rational function field
over rationals
julia> var(S)
:y
julia> characteristic(S)
0
julia> defining_polynomial(S)
z^2 + (3*x + 3)//(x + 2)*z + 1
julia> numerator(S)
(x + 2)*y^2 + (3*x + 3)*y + x + 2
julia> denominator(S)
x + 2
julia> a = (x + 1)//(x^2 + 1)*y + 3x + 2
((x + 1)*y + 3*x^3 + 2*x^2 + 3*x + 2)//(x^2 + 1)
julia> numerator(a, false)
(x + 1)*y + 3*x^3 + 2*x^2 + 3*x + 2
julia> denominator(a, false)
x^2 + 1
julia> degree(S)
2
julia> gen(S)
y
julia> is_gen(y)
true
julia> coeff(a, 1)
(x + 1)//(x^2 + 1)
julia> num_coeff(a, 1)
x + 1Trace and norm
norm — Methodnorm(a::FunctionFieldElem)Return the absolute norm of a as an element of the underlying rational function field.
julia> R, x = rational_function_field(QQ, :x)
(Rational function field over rationals, x)
julia> U, z = R[:z]
(Univariate polynomial ring in z over R, z)
julia> g = z^2 + 3*(x + 1)//(x + 2)*z + 1
z^2 + (3*x + 3)//(x + 2)*z + 1
julia> S, y = function_field(g, :y)
(Function Field over rationals with defining polynomial (x + 2)*y^2 + (3*x + 3)*y + x + 2, y)
julia> f = (-3*x - 5//3)//(x - 2)*y + (x^3 + 1//9*x^2 + 5)//(x - 2)
((-3*x - 5//3)*y + x^3 + 1//9*x^2 + 5)//(x - 2)
julia> norm(f)
(x^7 + 20//9*x^6 + 766//81*x^5 + 2027//81*x^4 + 110//3*x^3 + 682//9*x^2 + 1060//9*x + 725//9)//(x^3 - 2*x^2 - 4*x + 8)
julia> tr(f)
(2*x^4 + 38//9*x^3 + 85//9*x^2 + 24*x + 25)//(x^2 - 4)