Fraction fields of Ore polynomial rings#

Sage provides support for building the fraction field of any Ore polynomial ring and performing basic operations in it. The fraction field is constructed by the method sage.rings.polynomial.ore_polynomial_ring.OrePolynomialRing.fraction_field() as demonstrated below:

sage: R.<t> = QQ[]
sage: der = R.derivation()
sage: A.<d> = R['d', der]
sage: K = A.fraction_field()
sage: K
Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t
 over Rational Field twisted by d/dt

The simplest way to build elements in \(K\) is to use the division operator over Ore polynomial rings:

sage: f = 1/d
sage: f
d^(-1)
sage: f.parent() is K
True

REPRESENTATION OF ELEMENTS:

Elements in \(K\) are internally represented by fractions of the form \(s^{-1} t\) with the denominator on the left. Notice that, because of noncommutativity, this is not the same that fractions with denominator on the right. For example, a fraction created by the division operator is usually displayed with a different numerator and/or a different denominator:

sage: g = t / d
sage: g
(d - 1/t)^(-1) * t

The left numerator and right denominator are accessible as follows:

sage: g.left_numerator()
t
sage: g.right_denominator()
d

Similarly the methods OrePolynomial.left_denominator() and OrePolynomial.right_numerator() give access to the Ore polynomials \(s\) and \(t\) in the representation \(s^{-1} t\):

sage: g.left_denominator()
d - 1/t
sage: g.right_numerator()
t

We favored the writing \(s^{-1} t\) because it always exists. On the contrary, the writing \(s t^{-1}\) is only guaranteed when the twisting morphism defining the Ore polynomial ring is bijective. As a consequence, when the latter assumption is not fulfilled (or actually if Sage cannot invert the twisting morphism), computing the left numerator and the right denominator fails:

sage: # needs sage.rings.function_field
sage: sigma = R.hom([t^2])
sage: S.<x> = R['x', sigma]
sage: F = S.fraction_field()
sage: f = F.random_element()
sage: while not f:
....:     f = F.random_element()
sage: f.left_numerator()
Traceback (most recent call last):
...
NotImplementedError: inversion of the twisting morphism
Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field
  Defn: t |--> t^2

On a related note, fractions are systematically simplified when the twisting morphism is bijective but they are not otherwise. As an example, compare the two following computations:

sage: # needs sage.rings.function_field
sage: P = d^2 + t*d + 1
sage: Q = d + t^2
sage: D = d^3 + t^2 + 1
sage: f = P^(-1) * Q
sage: f
(d^2 + t*d + 1)^(-1) * (d + t^2)
sage: g = (D*P)^(-1) * (D*Q)
sage: g
(d^2 + t*d + 1)^(-1) * (d + t^2)

sage: # needs sage.rings.function_field
sage: P = x^2 + t*x + 1
sage: Q = x + t^2
sage: D = x^3 + t^2 + 1
sage: f = P^(-1) * Q
sage: f
(x^2 + t*x + 1)^(-1) * (x + t^2)
sage: g = (D*P)^(-1) * (D*Q)
sage: g
(x^5 + t^8*x^4 + x^3 + (t^2 + 1)*x^2 + (t^3 + t)*x + t^2 + 1)^(-1)
* (x^4 + t^16*x^3 + (t^2 + 1)*x + t^4 + t^2)
sage: f == g
True

OPERATIONS:

Basic arithmetical operations are available:

sage: # needs sage.rings.function_field
sage: f = 1 / d
sage: g = 1 / (d + t)
sage: u = f + g; u
(d^2 + ((t^2 - 1)/t)*d)^(-1) * (2*d + (t^2 - 2)/t)
sage: v = f - g; v
(d^2 + ((t^2 - 1)/t)*d)^(-1) * t
sage: u + v
d^(-1) * 2

sage: f * g
(d^2 + t*d)^(-1)
sage: f / g
d^(-1) * (d + t)

Of course, multiplication remains noncommutative:

sage: # needs sage.rings.function_field
sage: g * f
(d^2 + t*d + 1)^(-1)
sage: g^(-1) * f
(d - 1/t)^(-1) * (d + (t^2 - 1)/t)

AUTHOR:

  • Xavier Caruso (2020-05)

class sage.rings.polynomial.ore_function_field.OreFunctionCenterInjection(domain, codomain, ringembed)#

Bases: RingHomomorphism

Canonical injection of the center of a Ore function field into this field.

section()#

Return a section of this morphism.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^3)
sage: S.<x> = SkewPolynomialRing(k, k.frobenius_endomorphism())
sage: K = S.fraction_field()
sage: Z = K.center()
sage: iota = K.coerce_map_from(Z)
sage: sigma = iota.section()
sage: sigma(x^3 / (x^6 + 1))
z/(z^2 + 1)
class sage.rings.polynomial.ore_function_field.OreFunctionField(ring, category=None)#

Bases: Parent, UniqueRepresentation

A class for fraction fields of Ore polynomial rings.

Element = None#
change_var(var)#

Return the Ore function field in variable var with the same base ring, twisting morphism and twisting derivation as self.

INPUT:

  • var – a string representing the name of the new variable.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<t> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: R.<x> = OrePolynomialRing(k,Frob)
sage: K = R.fraction_field()
sage: K
Ore Function Field in x over Finite Field in t of size 5^3 twisted by t |--> t^5
sage: Ky = K.change_var('y'); Ky
Ore Function Field in y over Finite Field in t of size 5^3 twisted by t |--> t^5
sage: Ky is K.change_var('y')
True
characteristic()#

Return the characteristic of this Ore function field.

EXAMPLES:

sage: R.<t> = QQ[]
sage: sigma = R.hom([t+1])
sage: S = R['x',sigma]
sage: S.fraction_field().characteristic()                                   # needs sage.rings.function_field
0

sage: # needs sage.rings.finite_rings
sage: k.<u> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S = k['y',Frob]
sage: S.fraction_field().characteristic()                                   # needs sage.rings.function_field
5
fraction_field()#

Return the fraction field of this Ore function field, i.e. this Ore function field itself.

EXAMPLES:

sage: R.<t> = QQ[]
sage: der = R.derivation()
sage: A.<d> = R['d', der]
sage: K = A.fraction_field(); K
Ore Function Field in d
 over Fraction Field of Univariate Polynomial Ring in t over Rational Field
 twisted by d/dt
sage: K.fraction_field()
Ore Function Field in d
 over Fraction Field of Univariate Polynomial Ring in t over Rational Field
 twisted by d/dt
sage: K.fraction_field() is K
True
gen(n=0)#

Return the indeterminate generator of this Ore function field.

INPUT:

  • n – index of generator to return (default: 0). Exists for compatibility with other polynomial rings.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^4)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.gen()
x
gens()#

Return the tuple of generators of self.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^4)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.gens()
(x,)
gens_dict()#

Return a {name: variable} dictionary of the generators of this Ore function field.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: R.<t> = ZZ[]
sage: sigma = R.hom([t+1])
sage: S.<x> = OrePolynomialRing(R, sigma)
sage: K = S.fraction_field()
sage: K.gens_dict()
{'x': x}
is_commutative()#

Return True if this Ore function field is commutative, i.e. if the twisting morphism is the identity and the twisting derivation vanishes.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.is_commutative()
False
sage: T.<y> = k['y', Frob^3]
sage: L = T.fraction_field()
sage: L.is_commutative()
True
is_exact()#

Return True if elements of this Ore function field are exact. This happens if and only if elements of the base ring are exact.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<t> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.is_exact()
True

sage: # needs sage.rings.padics
sage: k.<u> = Qq(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.is_exact()
False
is_field(proof=False)#

Return always True since Ore function field are (skew) fields.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: S.is_field()
False
sage: K.is_field()
True
is_finite()#

Return False since Ore function field are not finite.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<t> = GF(5^3)
sage: k.is_finite()
True
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x',Frob]
sage: K = S.fraction_field()
sage: K.is_finite()
False
is_sparse()#

Return True if the elements of this Ore function field are sparsely represented.

Warning

Since sparse Ore polynomials are not yet implemented, this function always returns False.

EXAMPLES:

sage: # needs sage.rings.function_field sage.rings.real_mpfr
sage: R.<t> = RR[]
sage: sigma = R.hom([t+1])
sage: S.<x> = R['x', sigma]
sage: K = S.fraction_field()
sage: K.is_sparse()
False
ngens()#

Return the number of generators of this Ore function field, which is \(1\).

EXAMPLES:

sage: # needs sage.rings.function_field sage.rings.real_mpfr
sage: R.<t> = RR[]
sage: sigma = R.hom([t+1])
sage: S.<x> = R['x',sigma]
sage: K = S.fraction_field()
sage: K.ngens()
1
parameter(n=0)#

Return the indeterminate generator of this Ore function field.

INPUT:

  • n – index of generator to return (default: 0). Exists for compatibility with other polynomial rings.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^4)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.gen()
x
random_element(degree=2, monic=False, *args, **kwds)#

Return a random Ore function in this field.

INPUT:

  • degree – (default: 2) an integer or a list of two integers; the degrees of the denominator and numerator

  • monic – (default: False) if True, return a monic Ore function with monic numerator and denominator

  • *args, **kwds – passed in to the random_element method for the base ring

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<t> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.random_element()              # random
(x^2 + (2*t^2 + t + 1)*x + 2*t^2 + 2*t + 3)^(-1)
* ((2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2)
sage: K.random_element(monic=True)    # random
(x^2 + (4*t^2 + 3*t + 4)*x + 4*t^2 + t)^(-1)
* (x^2 + (2*t^2 + t + 3)*x + 3*t^2 + t + 2)
sage: K.random_element(degree=3)      # random
(x^3 + (2*t^2 + 3)*x^2 + (2*t^2 + 4)*x + t + 3)^(-1)
* ((t + 4)*x^3 + (4*t^2 + 2*t + 2)*x^2 + (2*t^2 + 3*t + 3)*x + 3*t^2 + 3*t + 1)
sage: K.random_element(degree=[2,5])  # random
(x^2 + (4*t^2 + 2*t + 2)*x + 4*t^2 + t + 2)^(-1)
* ((3*t^2 + t + 1)*x^5 + (2*t^2 + 2*t)*x^4 + (t^2 + 2*t + 4)*x^3
   + (3*t^2 + 2*t)*x^2 + (t^2 + t + 4)*x)
twisting_derivation()#

Return the twisting derivation defining this Ore function field or None if this Ore function field is not twisted by a derivation.

EXAMPLES:

sage: R.<t> = QQ[]
sage: der = R.derivation(); der
d/dt
sage: A.<d> = R['d', der]
sage: F = A.fraction_field()
sage: F.twisting_derivation()
d/dt

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x', Frob]
sage: K = S.fraction_field()
sage: K.twisting_derivation()

See also

sage.rings.polynomial.ore_polynomial_element.OrePolynomial.twisting_derivation(), twisting_morphism()

twisting_morphism(n=1)#

Return the twisting endomorphism defining this Ore function field iterated n times or None if this Ore function field is not twisted by an endomorphism.

INPUT:

  • n - an integer (default: 1)

EXAMPLES:

sage: R.<t> = QQ[]
sage: sigma = R.hom([t+1])
sage: S.<x> = R['x', sigma]
sage: K = S.fraction_field()                                                # needs sage.rings.function_field
sage: K.twisting_morphism()                                                 # needs sage.rings.function_field
Ring endomorphism of
 Fraction Field of Univariate Polynomial Ring in t over Rational Field
  Defn: t |--> t + 1

When the Ore polynomial ring is only twisted by a derivation, this method returns nothing:

sage: der = R.derivation()
sage: A.<d> = R['x', der]
sage: F = A.fraction_field()                                                # needs sage.rings.function_field
sage: F.twisting_morphism()                                                 # needs sage.rings.function_field

See also

sage.rings.polynomial.ore_polynomial_element.OrePolynomial.twisting_morphism(), twisting_derivation()

class sage.rings.polynomial.ore_function_field.OreFunctionField_with_large_center(ring, category=None)#

Bases: OreFunctionField

A specialized class for Ore polynomial fields whose center has finite index.

center(name=None, names=None, default=False)#

Return the center of this Ore function field.

Note

One can prove that the center is a field of rational functions over a subfield of the base ring of this Ore function field.

INPUT:

  • name – a string or None (default: None); the name for the central variable

  • default – a boolean (default: False); if True, set the default variable name for the center to name

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: k.<t> = GF(5^3)
sage: Frob = k.frobenius_endomorphism()
sage: S.<x> = k['x',Frob]
sage: K = S.fraction_field()
sage: Z = K.center(); Z
Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5

We can pass in another variable name:

sage: K.center(name='y')                                                    # needs sage.rings.finite_rings
Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5

or use the bracket notation:

sage: Zy.<y> = K.center(); Zy                                               # needs sage.rings.finite_rings
Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5

A coercion map from the center to the Ore function field is set:

sage: K.has_coerce_map_from(Zy)                                             # needs sage.rings.finite_rings
True

and pushout works:

sage: # needs sage.rings.finite_rings
sage: x.parent()
Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5
sage: y.parent()
Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5
sage: P = x + y; P
x^3 + x
sage: P.parent()
Ore Function Field in x over Finite Field in t of size 5^3 twisted by t |--> t^5

A conversion map in the reverse direction is also set:

sage: # needs sage.rings.finite_rings
sage: Zy(x^(-6) + 2)
(2*y^2 + 1)/y^2
sage: Zy(1/x^2)
Traceback (most recent call last):
...
ValueError: x^(-2) is not in the center

ABOUT THE DEFAULT NAME OF THE CENTRAL VARIABLE:

A priori, the default is z.

However, a variable name is given the first time this method is called, the given name become the default for the next calls:

sage: # needs sage.rings.finite_rings
sage: k.<t> = GF(11^3)
sage: phi = k.frobenius_endomorphism()
sage: S.<X> = k['X', phi]
sage: K = S.fraction_field()
sage: C.<u> = K.center()  # first call
sage: C
Fraction Field of Univariate Polynomial Ring in u over Finite Field of size 11
sage: K.center()  # second call: the variable name is still u
Fraction Field of Univariate Polynomial Ring in u over Finite Field of size 11

We can update the default variable name by passing in the argument default=True:

sage: # needs sage.rings.finite_rings
sage: D.<v> = K.center(default=True)
sage: D
Fraction Field of Univariate Polynomial Ring in v over Finite Field of size 11
sage: K.center()
Fraction Field of Univariate Polynomial Ring in v over Finite Field of size 11
class sage.rings.polynomial.ore_function_field.SectionOreFunctionCenterInjection(embed)#

Bases: Section

Section of the canonical injection of the center of a Ore function field into this field