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
R.<t> = QQ[] der = R.derivation() A.<d> = R['d', der] K = A.fraction_field() K
The simplest way to build elements in
sage: f = 1/d
sage: f
d^(-1)
sage: f.parent() is K
True
f = 1/d f f.parent() is K
REPRESENTATION OF ELEMENTS:
Elements in
sage: g = t / d
sage: g
(d - 1/t)^(-1) * t
g = t / d g
The left numerator and right denominator are accessible as follows:
sage: g.left_numerator()
t
sage: g.right_denominator()
d
g.left_numerator() g.right_denominator()
Similarly the methods OrePolynomial.left_denominator()
and
OrePolynomial.right_numerator()
give access to the Ore polynomials
sage: g.left_denominator()
d - 1/t
sage: g.right_numerator()
t
g.left_denominator() g.right_numerator()
We favored the writing
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
sigma = R.hom([t^2]) S.<x> = R['x', sigma] F = S.fraction_field() f = F.random_element() while not f: f = F.random_element() f.left_numerator()
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: 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: 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
P = d^2 + t*d + 1 Q = d + t^2 D = d^3 + t^2 + 1 f = P^(-1) * Q f g = (D*P)^(-1) * (D*Q) g P = x^2 + t*x + 1 Q = x + t^2 D = x^3 + t^2 + 1 f = P^(-1) * Q f g = (D*P)^(-1) * (D*Q) g f == g
OPERATIONS:
Basic arithmetical operations are available:
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)
f = 1 / d g = 1 / (d + t) u = f + g; u v = f - g; v u + v f * g f / g
Of course, multiplication remains noncommutative:
sage: g * f
(d^2 + t*d + 1)^(-1)
sage: g^(-1) * f
(d - 1/t)^(-1) * (d + (t^2 - 1)/t)
g * f g^(-1) * f
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: 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)
k.<a> = GF(5^3) S.<x> = SkewPolynomialRing(k, k.frobenius_endomorphism()) K = S.fraction_field() Z = K.center() iota = K.coerce_map_from(Z) sigma = iota.section() sigma(x^3 / (x^6 + 1))
- class sage.rings.polynomial.ore_function_field.OreFunctionField(ring, category=None)#
Bases:
Algebra
,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 asself
.INPUT:
var
– a string representing the name of the new variable.
EXAMPLES:
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
k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() R.<x> = OrePolynomialRing(k,Frob) K = R.fraction_field() K Ky = K.change_var('y'); Ky Ky is K.change_var('y')
- 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() 0 sage: k.<u> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S = k['y',Frob] sage: S.fraction_field().characteristic() 5
R.<t> = QQ[] sigma = R.hom([t+1]) S = R['x',sigma] S.fraction_field().characteristic() k.<u> = GF(5^3) Frob = k.frobenius_endomorphism() S = k['y',Frob] S.fraction_field().characteristic()
- 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() sage: 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
R.<t> = QQ[] der = R.derivation() A.<d> = R['d', der] K = A.fraction_field() K K.fraction_field() K.fraction_field() is K
- 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: 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
k.<a> = GF(5^4) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() K.gen()
- gens_dict()#
Return a {name: variable} dictionary of the generators of this Ore function field.
EXAMPLES:
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}
R.<t> = ZZ[] sigma = R.hom([t+1]) S.<x> = OrePolynomialRing(R, sigma) K = S.fraction_field() K.gens_dict()
- 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: 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
k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() K.is_commutative() T.<y> = k['y', Frob^3] L = T.fraction_field() L.is_commutative()
- 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: 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: 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
k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() K.is_exact() k.<u> = Qq(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() K.is_exact()
- is_field(proof=False)#
Return always
True
since Ore function field are (skew) fields.EXAMPLES:
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
k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() S.is_field() K.is_field()
- is_finite()#
Return
False
since Ore function field are not finite.EXAMPLES:
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
k.<t> = GF(5^3) k.is_finite() Frob = k.frobenius_endomorphism() S.<x> = k['x',Frob] K = S.fraction_field() K.is_finite()
- 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: 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
R.<t> = RR[] sigma = R.hom([t+1]) S.<x> = R['x', sigma] K = S.fraction_field() K.is_sparse()
- ngens()#
Return the number of generators of this Ore function field, which is
.EXAMPLES:
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
R.<t> = RR[] sigma = R.hom([t+1]) S.<x> = R['x',sigma] K = S.fraction_field() K.ngens()
- 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: 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
k.<a> = GF(5^4) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() K.gen()
- 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 numeratormonic
– (default:False
) ifTrue
, return a monic Ore function with monic numerator and denominator*args, **kwds
– passed in to therandom_element
method for the base ring
EXAMPLES:
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)
k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() K.random_element() # random K.random_element(monic=True) # random K.random_element(degree=3) # random K.random_element(degree=[2,5]) # random
- 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: 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()
R.<t> = QQ[] der = R.derivation(); der A.<d> = R['d', der] F = A.fraction_field() F.twisting_derivation() k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() 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 orNone
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() sage: K.twisting_morphism() Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: t |--> t + 1
R.<t> = QQ[] sigma = R.hom([t+1]) S.<x> = R['x', sigma] K = S.fraction_field() K.twisting_morphism()
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() sage: F.twisting_morphism()
der = R.derivation() A.<d> = R['x', der] F = A.fraction_field() F.twisting_morphism()
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 orNone
(default:None
); the name for the central variabledefault
– a boolean (default:False
); ifTrue
, set the default variable name for the center toname
EXAMPLES:
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
k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x',Frob] K = S.fraction_field() Z = K.center(); Z
We can pass in another variable name:
sage: K.center(name='y') Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5
K.center(name='y')
or use the bracket notation:
sage: Zy.<y> = K.center(); Zy Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5
Zy.<y> = K.center(); Zy
A coercion map from the center to the Ore function field is set:
sage: K.has_coerce_map_from(Zy) True
K.has_coerce_map_from(Zy)
and pushout works:
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
x.parent() y.parent() P = x + y; P P.parent()
A conversion map in the reverse direction is also set:
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
Zy(x^(-6) + 2) Zy(1/x^2)
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: 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
k.<t> = GF(11^3) phi = k.frobenius_endomorphism() S.<X> = k['X', phi] K = S.fraction_field() C.<u> = K.center() # first call C K.center() # second call: the variable name is still u
We can update the default variable name by passing in the argument
default=True
: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
D.<v> = K.center(default=True) D K.center()