Fraction field elements of Ore polynomial rings¶
AUTHOR:
Xavier Caruso (2020-05)
- class sage.rings.polynomial.ore_function_element.ConstantOreFunctionSection[source]¶
Bases:
Map
Representation of the canonical homomorphism from the constants of a Ore function field to the base field.
This class is needed by the coercion system.
EXAMPLES:
sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import ConstantOrePolynomialSection sage: k.<a> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S.<x> = k['x', Frob] sage: K = S.fraction_field() sage: iota = K.coerce_map_from(k) sage: sigma = iota.section(); sigma Generic map: From: Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 To: Finite Field in a of size 5^3
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> from sage.rings.polynomial.ore_polynomial_element import ConstantOrePolynomialSection >>> k = GF(Integer(5)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> K = S.fraction_field() >>> iota = K.coerce_map_from(k) >>> sigma = iota.section(); sigma Generic map: From: Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 To: Finite Field in a of size 5^3
# needs sage.rings.finite_rings from sage.rings.polynomial.ore_polynomial_element import ConstantOrePolynomialSection k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() iota = K.coerce_map_from(k) sigma = iota.section(); sigma
- class sage.rings.polynomial.ore_function_element.OreFunction(parent, numerator, denominator=None, simplify=True)[source]¶
Bases:
AlgebraElement
An element in a Ore function field.
- hilbert_shift(s, var=None)[source]¶
Return this Ore function with variable shifted by \(s\), i.e. if this Ore function is \(f(x)\), return \(f(x+s)\).
INPUT:
s
– an element in the base ringvar
– string; the variable name
EXAMPLES:
sage: R.<t> = GF(7)[] sage: der = R.derivation() sage: A.<d> = R['d', der] sage: K = A.fraction_field() sage: f = 1 / (d-t) sage: f.hilbert_shift(t) d^(-1)
>>> from sage.all import * >>> R = GF(Integer(7))['t']; (t,) = R._first_ngens(1) >>> der = R.derivation() >>> A = R['d', der]; (d,) = A._first_ngens(1) >>> K = A.fraction_field() >>> f = Integer(1) / (d-t) >>> f.hilbert_shift(t) d^(-1)
R.<t> = GF(7)[] der = R.derivation() A.<d> = R['d', der] K = A.fraction_field() f = 1 / (d-t) f.hilbert_shift(t)
One can specify another variable name:
sage: f.hilbert_shift(t, var='x') x^(-1)
>>> from sage.all import * >>> f.hilbert_shift(t, var='x') x^(-1)
f.hilbert_shift(t, var='x')
When the twisting morphism is not trivial, the output lies in a different Ore polynomial ring:
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: f = (x-a)^(-2) sage: g = f.hilbert_shift(a); g x^(-2) sage: g.parent() Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 and a*([a |--> a^5] - id) sage: g.parent() is S False
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> K = S.fraction_field() >>> f = (x-a)**(-Integer(2)) >>> g = f.hilbert_shift(a); g x^(-2) >>> g.parent() Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 and a*([a |--> a^5] - id) >>> g.parent() is S False
# needs sage.rings.finite_rings k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() f = (x-a)^(-2) g = f.hilbert_shift(a); g g.parent() g.parent() is S
This behavior ensures that the Hilbert shift by a fixed element defines a homomorphism of fields:
sage: # needs sage.rings.finite_rings sage: U = K.random_element(degree=5) sage: V = K.random_element(degree=5) sage: s = k.random_element() sage: (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) True sage: (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s) True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> U = K.random_element(degree=Integer(5)) >>> V = K.random_element(degree=Integer(5)) >>> s = k.random_element() >>> (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) True >>> (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s) True
# needs sage.rings.finite_rings U = K.random_element(degree=5) V = K.random_element(degree=5) s = k.random_element() (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s)
- is_zero()[source]¶
Return
True
if this element is equal to zero.EXAMPLES:
sage: R.<t> = GF(3)[] sage: der = R.derivation() sage: A.<d> = R['x', der] sage: f = t/d sage: f.is_zero() False sage: (f-f).is_zero() True
>>> from sage.all import * >>> R = GF(Integer(3))['t']; (t,) = R._first_ngens(1) >>> der = R.derivation() >>> A = R['x', der]; (d,) = A._first_ngens(1) >>> f = t/d >>> f.is_zero() False >>> (f-f).is_zero() True
R.<t> = GF(3)[] der = R.derivation() A.<d> = R['x', der] f = t/d f.is_zero() (f-f).is_zero()
- left_denominator()[source]¶
Return \(s\) if this element reads \(s^{-1} t\).
WARNING:
When the twisting morphism is bijective, there is a unique irreducible fraction of the form \(s^{-1} t\) representing this element. Here irreducible means that \(s\) and \(t\) have no nontrivial common left divisor. Under this additional assumption, this method always returns this distinguished denominator \(s\).
On the contrary, when the twisting morphism is not bijective, this method returns the denominator of some fraction representing the input element. However, the software guarantees that the method
right_numerator()
outputs the numerator of the same fraction.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: s = x + a sage: t = x^2 + a*x + a^2 sage: f = s^(-1) * t sage: f.left_denominator() x + a
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> s = x + a >>> t = x**Integer(2) + a*x + a**Integer(2) >>> f = s**(-Integer(1)) * t >>> f.left_denominator() x + a
# needs sage.rings.finite_rings k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] s = x + a t = x^2 + a*x + a^2 f = s^(-1) * t f.left_denominator()
In the example below, a simplification occurs:
sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (u*s)^(-1) * (u*t) sage: g.left_denominator() x + a
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> u = S.random_element(degree=Integer(2)) >>> g = (u*s)**(-Integer(1)) * (u*t) >>> g.left_denominator() x + a
# needs sage.rings.finite_rings u = S.random_element(degree=2) g = (u*s)^(-1) * (u*t) g.left_denominator()
When the twisting morphism is not invertible, simplifications do not occur in general:
sage: R.<z> = GF(11)[] sage: sigma = R.hom([z^2]) sage: S.<x> = R['x', sigma] sage: s = (x + z)^2 sage: t = (x + z) * (x^2 + z^2) sage: f = s^(-1) * t # needs sage.rings.function_field sage: f.left_denominator() # needs sage.rings.function_field x^2 + (z^2 + z)*x + z^2
>>> from sage.all import * >>> R = GF(Integer(11))['z']; (z,) = R._first_ngens(1) >>> sigma = R.hom([z**Integer(2)]) >>> S = R['x', sigma]; (x,) = S._first_ngens(1) >>> s = (x + z)**Integer(2) >>> t = (x + z) * (x**Integer(2) + z**Integer(2)) >>> f = s**(-Integer(1)) * t # needs sage.rings.function_field >>> f.left_denominator() # needs sage.rings.function_field x^2 + (z^2 + z)*x + z^2
R.<z> = GF(11)[] sigma = R.hom([z^2]) S.<x> = R['x', sigma] s = (x + z)^2 t = (x + z) * (x^2 + z^2) f = s^(-1) * t # needs sage.rings.function_field f.left_denominator() # needs sage.rings.function_field
However, the following always holds true:
sage: f == f.left_denominator()^(-1) * f.right_numerator() # needs sage.rings.function_field True
>>> from sage.all import * >>> f == f.left_denominator()**(-Integer(1)) * f.right_numerator() # needs sage.rings.function_field True
f == f.left_denominator()^(-1) * f.right_numerator() # needs sage.rings.function_field
See also
- left_numerator()[source]¶
Return \(t\) if this element reads \(t s^{-1}\).
WARNING:
When the twisting morphism is bijective, there is a unique irreducible fraction of the form \(t s^{-1}\) representing this element. Here irreducible means that \(s\) and \(t\) have no nontrivial common right divisor. Under this additional assumption, this method always returns this distinguished numerator \(t\).
On the contrary, when the twisting morphism is not bijective, the existence of the writing \(t s^{-1}\) is not guaranteed in general. In this case, this method raises an error.
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: s = x + a sage: t = x^2 + a*x + a^2 sage: f = t/s sage: f.left_numerator() x^2 + a*x + a^2
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> s = x + a >>> t = x**Integer(2) + a*x + a**Integer(2) >>> f = t/s >>> f.left_numerator() x^2 + a*x + a^2
# needs sage.rings.finite_rings k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] s = x + a t = x^2 + a*x + a^2 f = t/s f.left_numerator()
In the example below, a simplification occurs:
sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (t*u) / (s*u) sage: g.left_numerator() x^2 + a*x + a^2
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> u = S.random_element(degree=Integer(2)) >>> g = (t*u) / (s*u) >>> g.left_numerator() x^2 + a*x + a^2
# needs sage.rings.finite_rings u = S.random_element(degree=2) g = (t*u) / (s*u) g.left_numerator()
- right_denominator()[source]¶
Return \(s\) if this element reads \(t s^{-1}\).
WARNING:
When the twisting morphism is bijective, there is a unique irreducible fraction of the form \(t s^{-1}\) representing this element. Here irreducible means that \(s\) and \(t\) have no nontrivial common right divisor. Under this additional assumption, this method always returns this distinguished denominator \(s\).
On the contrary, when the twisting morphism is not bijective, the existence of the writing \(t s^{-1}\) is not guaranteed in general. In this case, this method raises an error.
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: s = x + a sage: t = x^2 + a*x + a^2 sage: f = t/s sage: f.right_denominator() x + a
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> s = x + a >>> t = x**Integer(2) + a*x + a**Integer(2) >>> f = t/s >>> f.right_denominator() x + a
# needs sage.rings.finite_rings k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] s = x + a t = x^2 + a*x + a^2 f = t/s f.right_denominator()
In the example below, a simplification occurs:
sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (t*u) / (s*u) sage: g.right_denominator() x + a
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> u = S.random_element(degree=Integer(2)) >>> g = (t*u) / (s*u) >>> g.right_denominator() x + a
# needs sage.rings.finite_rings u = S.random_element(degree=2) g = (t*u) / (s*u) g.right_denominator()
See also
- right_numerator()[source]¶
Return \(t\) if this element reads \(s^{-1} t\).
WARNING:
When the twisting morphism is bijective, there is a unique irreducible fraction of the form \(s^{-1} t\) representing this element. Here irreducible means that \(s\) and \(t\) have no nontrivial common left divisor. Under this additional assumption, this method always returns this distinguished numerator \(t\).
On the contrary, when the twisting morphism is not bijective, this method returns the numerator of some fraction representing the input element. However, the software guarantees that the method
left_denominator()
outputs the numerator of the same fraction.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: s = x + a sage: t = x^2 + a*x + a^2 sage: f = s^(-1) * t sage: f.right_numerator() x^2 + a*x + a^2
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> s = x + a >>> t = x**Integer(2) + a*x + a**Integer(2) >>> f = s**(-Integer(1)) * t >>> f.right_numerator() x^2 + a*x + a^2
# needs sage.rings.finite_rings k.<a> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] s = x + a t = x^2 + a*x + a^2 f = s^(-1) * t f.right_numerator()
In the example below, a simplification occurs:
sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (u*s)^(-1) * (u*t) sage: g.right_numerator() x^2 + a*x + a^2
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> u = S.random_element(degree=Integer(2)) >>> g = (u*s)**(-Integer(1)) * (u*t) >>> g.right_numerator() x^2 + a*x + a^2
# needs sage.rings.finite_rings u = S.random_element(degree=2) g = (u*s)^(-1) * (u*t) g.right_numerator()
- class sage.rings.polynomial.ore_function_element.OreFunctionBaseringInjection(domain, codomain)[source]¶
Bases:
Morphism
Representation of the canonical homomorphism from a field \(k\) into a Ore function field over \(k\).
This class is needed by the coercion system.
- an_element()[source]¶
Return an element of the codomain of the ring homomorphism.
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: m = K.coerce_map_from(k) sage: m.an_element() x
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x',Frob]; (x,) = S._first_ngens(1) >>> K = S.fraction_field() >>> m = K.coerce_map_from(k) >>> m.an_element() x
# needs sage.rings.finite_rings k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x',Frob] K = S.fraction_field() m = K.coerce_map_from(k) m.an_element()
- class sage.rings.polynomial.ore_function_element.OreFunction_with_large_center(parent, numerator, denominator=None, simplify=True)[source]¶
Bases:
OreFunction
A special class for elements of Ore function fields whose center has finite index.
- reduced_norm(var=None)[source]¶
Return the reduced norm of this Ore function.
INPUT:
var
– string orNone
(default:None
); the name of the central variable
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: a = (x + t) / (x^2 + t^2) sage: N = a.reduced_norm(); N (z + 2)/(z^2 + 4)
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> K = S.fraction_field() >>> a = (x + t) / (x**Integer(2) + t**Integer(2)) >>> N = a.reduced_norm(); N (z + 2)/(z^2 + 4)
# needs sage.rings.finite_rings k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() a = (x + t) / (x^2 + t^2) N = a.reduced_norm(); N
The reduced norm lies in the center of \(S\), which is the fraction field of a univariate polynomial ring in the variable \(z = x^3\) over \(GF(5)\).
sage: # needs sage.rings.finite_rings sage: N.parent() Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 sage: N.parent() is K.center() True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> N.parent() Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 >>> N.parent() is K.center() True
# needs sage.rings.finite_rings N.parent() N.parent() is K.center()
We can use explicit conversion to view
N
as a skew polynomial:sage: K(N) # needs sage.rings.finite_rings (x^6 + 4)^(-1) * (x^3 + 2)
>>> from sage.all import * >>> K(N) # needs sage.rings.finite_rings (x^6 + 4)^(-1) * (x^3 + 2)
K(N) # needs sage.rings.finite_rings
By default, the name of the central variable is usually
z
(seesage.rings.polynomial.skew_polynomial_ring.SkewPolynomiaRing_finite_order.center()
for more details about this). However, the user can specify a different variable name if desired:sage: a.reduced_norm(var='u') # needs sage.rings.finite_rings (u + 2)/(u^2 + 4)
>>> from sage.all import * >>> a.reduced_norm(var='u') # needs sage.rings.finite_rings (u + 2)/(u^2 + 4)
a.reduced_norm(var='u') # needs sage.rings.finite_rings
- reduced_trace(var=None)[source]¶
Return the reduced trace of this element.
INPUT:
var
– string orNone
(default:None
); the name of the central variable
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: a = 1 / (x^2 + t) sage: tr = a.reduced_trace(); tr 3/(z^2 + 2)
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x', Frob]; (x,) = S._first_ngens(1) >>> K = S.fraction_field() >>> a = Integer(1) / (x**Integer(2) + t) >>> tr = a.reduced_trace(); tr 3/(z^2 + 2)
# needs sage.rings.finite_rings k.<t> = GF(5^3) Frob = k.frobenius_endomorphism() S.<x> = k['x', Frob] K = S.fraction_field() a = 1 / (x^2 + t) tr = a.reduced_trace(); tr
The reduced trace lies in the center of \(S\), which is the fraction field of a univariate polynomial ring in the variable \(z = x^3\) over \(GF(5)\):
sage: # needs sage.rings.finite_rings sage: tr.parent() Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 sage: tr.parent() is K.center() True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> tr.parent() Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 >>> tr.parent() is K.center() True
# needs sage.rings.finite_rings tr.parent() tr.parent() is K.center()
We can use explicit conversion to view
tr
as a Ore function:sage: K(tr) # needs sage.rings.finite_rings (x^6 + 2)^(-1) * 3
>>> from sage.all import * >>> K(tr) # needs sage.rings.finite_rings (x^6 + 2)^(-1) * 3
K(tr) # needs sage.rings.finite_rings
By default, the name of the central variable is usually
z
(seesage.rings.polynomial.skew_polynomial_ring.OreFunctionField_with_large_center.center()
for more details about this). However, the user can specify a different variable name if desired:sage: a.reduced_trace(var='u') # needs sage.rings.finite_rings 3/(u^2 + 2)
>>> from sage.all import * >>> a.reduced_trace(var='u') # needs sage.rings.finite_rings 3/(u^2 + 2)
a.reduced_trace(var='u') # needs sage.rings.finite_rings