From 7c1a26ba86f74aad70668ecb174ee986d96afc60 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 17 Jul 2025 11:18:34 +0200 Subject: [PATCH 01/12] =?UTF-8?q?t=20->=20=CF=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sage/categories/drinfeld_modules.py | 23 +-- .../function_field/drinfeld_modules/action.py | 6 +- .../charzero_drinfeld_module.py | 10 +- .../drinfeld_modules/drinfeld_module.py | 126 +++++++-------- .../finite_drinfeld_module.py | 28 ++-- .../function_field/drinfeld_modules/homset.py | 92 +++++------ .../drinfeld_modules/morphism.py | 144 +++++++++--------- 7 files changed, 215 insertions(+), 214 deletions(-) diff --git a/src/sage/categories/drinfeld_modules.py b/src/sage/categories/drinfeld_modules.py index 95b7f67c8e0..aa80f8cc3b8 100644 --- a/src/sage/categories/drinfeld_modules.py +++ b/src/sage/categories/drinfeld_modules.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage_setup: distribution = sagemath-categories # sage.doctest: needs sage.rings.finite_rings r""" @@ -123,7 +124,7 @@ class DrinfeldModules(Category_over_base_ring): True sage: C.ore_polring() - Ore Polynomial Ring in t over Finite Field in z of size 11^4 twisted by z |--> z^11 + Ore Polynomial Ring in τ over Finite Field in z of size 11^4 twisted by z |--> z^11 sage: C.ore_polring() is phi.ore_polring() True @@ -135,7 +136,7 @@ class DrinfeldModules(Category_over_base_ring): sage: psi = C.object([p_root, 1]) sage: psi - Drinfeld module defined by T |--> t + z^3 + 7*z^2 + 6*z + 10 + Drinfeld module defined by T |--> τ + z^3 + 7*z^2 + 6*z + 10 sage: psi.category() is C True @@ -207,7 +208,7 @@ class DrinfeldModules(Category_over_base_ring): TypeError: function ring base must be a finite field """ - def __init__(self, base_morphism, name='t'): + def __init__(self, base_morphism, name='τ'): r""" Initialize ``self``. @@ -216,7 +217,7 @@ def __init__(self, base_morphism, name='t'): - ``base_field`` -- the base field, which is a ring extension over a base - - ``name`` -- (default: ``'t'``) the name of the Ore polynomial + - ``name`` -- (default: ``'τ'``) the name of the Ore polynomial variable TESTS:: @@ -227,7 +228,7 @@ def __init__(self, base_morphism, name='t'): sage: p_root = z^3 + 7*z^2 + 6*z + 10 sage: phi = DrinfeldModule(A, [p_root, 0, 0, 1]) sage: C = phi.category() - sage: ore_polring. = OrePolynomialRing(K, K.frobenius_endomorphism()) + sage: ore_polring.<τ> = OrePolynomialRing(K, K.frobenius_endomorphism()) sage: C._ore_polring is ore_polring True sage: C._function_ring is A @@ -507,7 +508,7 @@ def object(self, gen): sage: phi = C.object([p_root, 0, 1]) sage: phi - Drinfeld module defined by T |--> t^2 + z^3 + 7*z^2 + 6*z + 10 + Drinfeld module defined by T |--> τ^2 + z^3 + 7*z^2 + 6*z + 10 sage: t = phi.ore_polring().gen() sage: C.object(t^2 + z^3 + 7*z^2 + 6*z + 10) is phi True @@ -534,7 +535,7 @@ def ore_polring(self): sage: phi = DrinfeldModule(A, [p_root, 0, 0, 1]) sage: C = phi.category() sage: C.ore_polring() - Ore Polynomial Ring in t over Finite Field in z of size 11^4 twisted by z |--> z^11 + Ore Polynomial Ring in τ over Finite Field in z of size 11^4 twisted by z |--> z^11 """ return self._ore_polring @@ -770,7 +771,7 @@ def constant_coefficient(self): sage: t = phi.ore_polring().gen() sage: psi = C.object(phi.constant_coefficient() + t^3) sage: psi - Drinfeld module defined by T |--> t^3 + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 + Drinfeld module defined by T |--> τ^3 + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 Reciprocally, it is impossible to create two Drinfeld modules in this category if they do not share the same constant @@ -796,7 +797,7 @@ def ore_polring(self): sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: S = phi.ore_polring() sage: S - Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 twisted by z12 |--> z12^(5^2) + Ore Polynomial Ring in τ over Finite Field in z12 of size 5^12 twisted by z12 |--> z12^(5^2) The Ore polynomial ring can also be retrieved from the category of the Drinfeld module:: @@ -825,8 +826,8 @@ def ore_variable(self): sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: phi.ore_polring() - Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 twisted by z12 |--> z12^(5^2) + Ore Polynomial Ring in τ over Finite Field in z12 of size 5^12 twisted by z12 |--> z12^(5^2) sage: phi.ore_variable() - t + τ """ return self.category().ore_polring().gen() diff --git a/src/sage/rings/function_field/drinfeld_modules/action.py b/src/sage/rings/function_field/drinfeld_modules/action.py index 4962162424e..06f8897326d 100644 --- a/src/sage/rings/function_field/drinfeld_modules/action.py +++ b/src/sage/rings/function_field/drinfeld_modules/action.py @@ -60,7 +60,7 @@ class DrinfeldModuleAction(Action): sage: action = phi.action() sage: action Action on Finite Field in z of size 11^2 over its base - induced by Drinfeld module defined by T |--> t^3 + z + induced by Drinfeld module defined by T |--> τ^3 + z The action on elements is computed as follows:: @@ -154,7 +154,7 @@ def _latex_(self): sage: phi = DrinfeldModule(A, [z, 0, 0, 1]) sage: action = phi.action() sage: latex(action) - \text{Action{ }on{ }}\Bold{F}_{11^{2}}\text{{ }induced{ }by{ }}\phi: T \mapsto t^{3} + z + \text{Action{ }on{ }}\Bold{F}_{11^{2}}\text{{ }induced{ }by{ }}\phi: T \mapsto τ^{3} + z """ return f'\\text{{Action{{ }}on{{ }}}}' \ f'{latex(self._base)}\\text{{{{ }}' \ @@ -174,7 +174,7 @@ def _repr_(self): sage: phi = DrinfeldModule(A, [z, 0, 0, 1]) sage: action = phi.action() sage: action - Action on Finite Field in z of size 11^2 over its base induced by Drinfeld module defined by T |--> t^3 + z + Action on Finite Field in z of size 11^2 over its base induced by Drinfeld module defined by T |--> τ^3 + z """ return f'Action on {self._base} induced by ' \ f'{self._drinfeld_module}' diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 594f8645ae1..99dd8dc9ce5 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -60,7 +60,7 @@ class DrinfeldModule_charzero(DrinfeldModule): sage: K. = Frac(A) sage: phi = DrinfeldModule(A, [T, 1]) sage: phi - Drinfeld module defined by T |--> t + T + Drinfeld module defined by T |--> τ + T :: @@ -110,7 +110,7 @@ class DrinfeldModule_charzero(DrinfeldModule): sage: L. = LaurentSeriesRing(GF(2)) # s = 1/T sage: phi = DrinfeldModule(A, [1/s, s + s^2 + s^5 + O(s^6), 1+1/s]) sage: phi(T) - (s^-1 + 1)*t^2 + (s + s^2 + s^5 + O(s^6))*t + s^-1 + (s^-1 + 1)*τ^2 + (s + s^2 + s^5 + O(s^6))*τ + s^-1 One can also construct Drinfeld modules over SageMath's global function fields:: @@ -119,7 +119,7 @@ class DrinfeldModule_charzero(DrinfeldModule): sage: K. = FunctionField(GF(5)) # z = T sage: phi = DrinfeldModule(A, [z, 1, z^2]) sage: phi(T) - z^2*t^2 + t + z + z^2*τ^2 + τ + z """ @cached_method def _compute_coefficient_exp(self, k): @@ -462,7 +462,7 @@ class DrinfeldModule_rational(DrinfeldModule_charzero): sage: A = Fq['T'] sage: K. = Frac(A) sage: C = DrinfeldModule(A, [T, 1]); C - Drinfeld module defined by T |--> t + T + Drinfeld module defined by T |--> τ + T sage: type(C) """ @@ -573,7 +573,7 @@ def class_polynomial(self): sage: A = Fq['T'] sage: K. = Frac(A) sage: C = DrinfeldModule(A, [T, 1]); C - Drinfeld module defined by T |--> t + T + Drinfeld module defined by T |--> τ + T sage: C.class_polynomial() 1 diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 6c2f2450118..4d26afc2abb 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -90,7 +90,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z, 4, 1]) sage: phi - Drinfeld module defined by T |--> t^2 + 4*t + z + Drinfeld module defined by T |--> τ^2 + 4*τ + z :: @@ -99,7 +99,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: K = Frac(A) sage: psi = DrinfeldModule(A, [K(T), T+1]) sage: psi - Drinfeld module defined by T |--> (T + 1)*t + T + Drinfeld module defined by T |--> (T + 1)*τ + T .. NOTE:: @@ -140,7 +140,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z, 1, 1]) sage: phi - Drinfeld module defined by T |--> t^2 + t + z + Drinfeld module defined by T |--> τ^2 + τ + z .. NOTE:: @@ -153,7 +153,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: L = Frac(A) sage: psi = DrinfeldModule(A, [L(T), 1, T^3 + T + 1]) sage: psi - Drinfeld module defined by T |--> (T^3 + T + 1)*t^2 + t + T + Drinfeld module defined by T |--> (T^3 + T + 1)*τ^2 + τ + T :: @@ -163,15 +163,15 @@ class DrinfeldModule(Parent, UniqueRepresentation): False In those examples, we used a list of coefficients (``[z, 1, 1]``) to - represent the generator `\phi_T = z + t + t^2`. One can also use + represent the generator `\phi_T = z + τ + τ^2`. One can also use regular Ore polynomials:: sage: ore_polring = phi.ore_polring() - sage: t = ore_polring.gen() - sage: rho_T = z + t^3 + sage: tau = ore_polring.gen() + sage: rho_T = z + tau^3 sage: rho = DrinfeldModule(A, rho_T) sage: rho - Drinfeld module defined by T |--> t^3 + z + Drinfeld module defined by T |--> τ^3 + z sage: rho(T) == rho_T True @@ -179,12 +179,12 @@ class DrinfeldModule(Parent, UniqueRepresentation): object:: sage: phi(T) # phi_T, the generator of the Drinfeld module - t^2 + t + z + τ^2 + τ + z sage: phi(T^3 + T + 1) # phi_(T^3 + T + 1) - t^6 + (z^11 + z^9 + 2*z^6 + 2*z^4 + 2*z + 1)*t^4 - + (2*z^11 + 2*z^10 + z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^3)*t^3 - + (2*z^11 + z^10 + z^9 + 2*z^7 + 2*z^6 + z^5 + z^4 + 2*z^3 + 2*z + 2)*t^2 - + (2*z^11 + 2*z^8 + 2*z^6 + z^5 + z^4 + 2*z^2)*t + z^3 + z + 1 + τ^6 + (z^11 + z^9 + 2*z^6 + 2*z^4 + 2*z + 1)*τ^4 + + (2*z^11 + 2*z^10 + z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^3)*τ^3 + + (2*z^11 + z^10 + z^9 + 2*z^7 + 2*z^6 + z^5 + z^4 + 2*z^3 + 2*z + 2)*τ^2 + + (2*z^11 + 2*z^8 + 2*z^6 + z^5 + z^4 + 2*z^2)*τ + z^3 + z + 1 sage: phi(1) # phi_1 1 @@ -204,7 +204,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: cat = phi.category() sage: cat.object([z, 0, 0, 1]) - Drinfeld module defined by T |--> t^3 + z + Drinfeld module defined by T |--> τ^3 + z .. RUBRIC:: The base field of a Drinfeld module @@ -243,7 +243,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): :: sage: phi.ore_polring() # K{t} - Ore Polynomial Ring in t over Finite Field in z of size 3^12 twisted by z |--> z^(3^2) + Ore Polynomial Ring in τ over Finite Field in z of size 3^12 twisted by z |--> z^(3^2) :: @@ -253,7 +253,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): :: sage: phi.gen() # phi_T - t^2 + t + z + τ^2 + τ + z sage: phi.gen() == phi(T) True @@ -267,9 +267,9 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: phi.morphism() # The Drinfeld module as a morphism Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2 - To: Ore Polynomial Ring in t over Finite Field in z of size 3^12 + To: Ore Polynomial Ring in τ over Finite Field in z of size 3^12 twisted by z |--> z^(3^2) - Defn: T |--> t^2 + t + z + Defn: T |--> τ^2 + τ + z One can compute the rank and height:: @@ -309,9 +309,9 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: phi(T) in Hom(phi, phi) True - sage: t^6 in Hom(phi, phi) + sage: tau^6 in Hom(phi, phi) True - sage: t^5 + 2*t^3 + 1 in Hom(phi, phi) + sage: tau^5 + 2*tau^3 + 1 in Hom(phi, phi) False sage: 1 in Hom(phi, rho) False @@ -324,23 +324,23 @@ class DrinfeldModule(Parent, UniqueRepresentation): homset (``hom``):: sage: hom = Hom(phi, phi) - sage: frobenius_endomorphism = hom(t^6) + sage: frobenius_endomorphism = hom(tau^6) sage: identity_morphism = hom(1) sage: zero_morphism = hom(0) sage: frobenius_endomorphism - Endomorphism of Drinfeld module defined by T |--> t^2 + t + z - Defn: t^6 + Endomorphism of Drinfeld module defined by T |--> τ^2 + τ + z + Defn: τ^6 sage: identity_morphism - Identity morphism of Drinfeld module defined by T |--> t^2 + t + z + Identity morphism of Drinfeld module defined by T |--> τ^2 + τ + z sage: zero_morphism - Endomorphism of Drinfeld module defined by T |--> t^2 + t + z + Endomorphism of Drinfeld module defined by T |--> τ^2 + τ + z Defn: 0 The underlying Ore polynomial is retrieved with the method :meth:`ore_polynomial`:: sage: frobenius_endomorphism.ore_polynomial() - t^6 + τ^6 sage: identity_morphism.ore_polynomial() 1 @@ -366,11 +366,11 @@ class DrinfeldModule(Parent, UniqueRepresentation): defines an isogeny with a given domain and, if it does, find the codomain:: - sage: P = (2*z^6 + z^3 + 2*z^2 + z + 2)*t + z^11 + 2*z^10 + 2*z^9 + 2*z^8 + z^7 + 2*z^6 + z^5 + z^3 + z^2 + z + sage: P = (2*z^6 + z^3 + 2*z^2 + z + 2)*tau + z^11 + 2*z^10 + 2*z^9 + 2*z^8 + z^7 + 2*z^6 + z^5 + z^3 + z^2 + z sage: psi = phi.velu(P) sage: psi - Drinfeld module defined by T |--> (2*z^11 + 2*z^9 + z^6 + 2*z^5 + 2*z^4 + 2*z^2 + 1)*t^2 - + (2*z^11 + 2*z^10 + 2*z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^4 + 2*z^2 + 2*z)*t + z + Drinfeld module defined by T |--> (2*z^11 + 2*z^9 + z^6 + 2*z^5 + 2*z^4 + 2*z^2 + 1)*τ^2 + + (2*z^11 + 2*z^10 + 2*z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^4 + 2*z^2 + 2*z)*τ + z sage: P in Hom(phi, psi) True sage: P * phi(T) == psi(T) * P @@ -382,7 +382,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): Traceback (most recent call last): ... ValueError: the input does not define an isogeny - sage: phi.velu(t) + sage: phi.velu(tau) Traceback (most recent call last): ... ValueError: the input does not define an isogeny @@ -403,7 +403,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: action = phi.action() sage: action Action on Finite Field in z of size 3^12 over its base - induced by Drinfeld module defined by T |--> t^2 + t + z + induced by Drinfeld module defined by T |--> τ^2 + τ + z The action on elements is computed by calling the action object:: @@ -520,7 +520,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): """ @staticmethod - def __classcall_private__(cls, function_ring, gen, name='t'): + def __classcall_private__(cls, function_ring, gen, name='τ'): """ Check input validity and return a ``DrinfeldModule`` or ``DrinfeldModule_finite`` object accordingly. @@ -533,7 +533,7 @@ def __classcall_private__(cls, function_ring, gen, name='t'): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'t'``) the name of the Ore polynomial + - ``name`` -- (default: ``'τ'``) the name of the Ore polynomial ring gen OUTPUT: a DrinfeldModule or DrinfeldModule_finite @@ -774,7 +774,7 @@ def _latex_(self): sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: latex(phi) - \phi: T \mapsto z_{12}^{5} t^{2} + z_{12}^{3} t + 2 z_{12}^{11} + 2 z_{12}^{10} + z_{12}^{9} + 3 z_{12}^{8} + z_{12}^{7} + 2 z_{12}^{5} + 2 z_{12}^{4} + 3 z_{12}^{3} + z_{12}^{2} + 2 z_{12} + \phi: T \mapsto z_{12}^{5} τ^{2} + z_{12}^{3} τ + 2 z_{12}^{11} + 2 z_{12}^{10} + z_{12}^{9} + 3 z_{12}^{8} + z_{12}^{7} + 2 z_{12}^{5} + 2 z_{12}^{4} + 3 z_{12}^{3} + z_{12}^{2} + 2 z_{12} :: @@ -801,7 +801,7 @@ def _repr_(self): sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: phi - Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 + Drinfeld module defined by T |--> z12^5*τ^2 + z12^3*τ + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 """ return f'Drinfeld module defined by {self._function_ring.gen()} ' \ f'|--> {self._gen}' @@ -868,7 +868,7 @@ def action(self): sage: action = phi.action() sage: action Action on Finite Field in z12 of size 5^12 over its base - induced by Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + induced by Drinfeld module defined by T |--> z12^5*τ^2 + z12^3*τ + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 The action on elements is computed as follows:: @@ -1301,7 +1301,7 @@ def is_isomorphic(self, other, absolutely=False): sage: A. = Fq[] sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) - sage: t = phi.ore_variable() + sage: tau = phi.ore_variable() We create a second Drinfeld module, which is isomorphic to `\phi` and then check that they are indeed isomorphic:: @@ -1313,7 +1313,7 @@ def is_isomorphic(self, other, absolutely=False): In the example below, `\phi` and `\psi` are isogenous but not isomorphic:: - sage: psi = phi.velu(t + 1) + sage: psi = phi.velu(tau + 1) sage: phi.is_isomorphic(psi) False @@ -1783,9 +1783,9 @@ def morphism(self): sage: phi.morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 - To: Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 + To: Ore Polynomial Ring in τ over Finite Field in z12 of size 5^12 twisted by z12 |--> z12^(5^2) - Defn: T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + Defn: T |--> z12^5*τ^2 + z12^3*τ + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: from sage.rings.morphism import RingHomomorphism sage: isinstance(phi.morphism(), RingHomomorphism) @@ -1809,7 +1809,7 @@ class the ``__call__`` method of this morphism:: sage: m.codomain() is phi.ore_polring() True sage: m.im_gens() - [z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + [z12^5*τ^2 + z12^3*τ + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12] sage: phi(T) == m.im_gens()[0] True @@ -1899,8 +1899,8 @@ def velu(self, isog): sage: psi = phi.velu(isog) sage: psi Drinfeld module defined by T |--> - (z12^11 + 3*z12^10 + z12^9 + z12^7 + z12^5 + 4*z12^4 + 4*z12^3 + z12^2 + 1)*t^2 - + (2*z12^11 + 4*z12^10 + 2*z12^8 + z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + z12^2 + z12 + 4)*t + (z12^11 + 3*z12^10 + z12^9 + z12^7 + z12^5 + 4*z12^4 + 4*z12^3 + z12^2 + 1)*τ^2 + + (2*z12^11 + 4*z12^10 + 2*z12^8 + z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + z12^2 + z12 + 4)*τ + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: isog in Hom(phi, psi) True @@ -1963,7 +1963,7 @@ def hom(self, x, codomain=None): sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) sage: phi - Drinfeld module defined by T |--> z*t^3 + t^2 + z + Drinfeld module defined by T |--> z*τ^3 + τ^2 + z An important class of endomorphisms of a Drinfeld module `\phi` is given by scalar multiplications, that are endomorphisms @@ -1971,37 +1971,37 @@ def hom(self, x, codomain=None): ring `A`. We construct them as follows:: sage: phi.hom(T) - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: z*t^3 + t^2 + z + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: z*τ^3 + τ^2 + z :: sage: phi.hom(T^2 + 1) - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1 + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: z^2*τ^6 + (3*z^2 + z + 1)*τ^5 + τ^4 + 2*z^2*τ^3 + (3*z^2 + z + 1)*τ^2 + z^2 + 1 We can also define a morphism by passing in the Ore polynomial defining it. For example, below, we construct the Frobenius endomorphism of `\phi`:: - sage: t = phi.ore_variable() - sage: phi.hom(t^3) - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: t^3 + sage: tau = phi.ore_variable() + sage: phi.hom(tau^3) + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: τ^3 If the input Ore polynomial defines a morphism to another Drinfeld module, the latter is determined automatically:: - sage: phi.hom(t + 1) + sage: phi.hom(tau + 1) Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z*t^3 + t^2 + z - To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z - Defn: t + 1 + From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^3 + (3*z^2 + 2*z + 2)*τ^2 + (2*z^2 + 3*z + 4)*τ + z + Defn: τ + 1 TESTS:: - sage: phi.hom(t) + sage: phi.hom(tau) Traceback (most recent call last): ... ValueError: the input does not define an isogeny @@ -2015,7 +2015,7 @@ def hom(self, x, codomain=None): :: - sage: phi.hom(t + 1, codomain=phi) + sage: phi.hom(tau + 1, codomain=phi) Traceback (most recent call last): ... ValueError: Ore polynomial does not define a morphism @@ -2062,16 +2062,16 @@ def scalar_multiplication(self, x): sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) sage: phi - Drinfeld module defined by T |--> z*t^3 + t^2 + z + Drinfeld module defined by T |--> z*τ^3 + τ^2 + z sage: phi.hom(T) # indirect doctest - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: z*t^3 + t^2 + z + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: z*τ^3 + τ^2 + z :: sage: phi.hom(T^2 + 1) - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1 + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: z^2*τ^6 + (3*z^2 + z + 1)*τ^5 + τ^4 + 2*z^2*τ^3 + (3*z^2 + z + 1)*τ^2 + z^2 + 1 """ if not self.function_ring().has_coerce_map_from(x.parent()): raise ValueError("%s is not element of the function ring" % x) diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 38c93a70106..685d5b5c465 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -57,7 +57,7 @@ class DrinfeldModule_finite(DrinfeldModule): sage: K. = Fq.extension(2) sage: phi = DrinfeldModule(A, [z6, 0, 5]) sage: phi - Drinfeld module defined by T |--> 5*t^2 + z6 + Drinfeld module defined by T |--> 5*τ^2 + z6 :: @@ -84,8 +84,8 @@ class DrinfeldModule_finite(DrinfeldModule): sage: frobenius_endomorphism = phi.frobenius_endomorphism() sage: frobenius_endomorphism - Endomorphism of Drinfeld module defined by T |--> 5*t^2 + z6 - Defn: t^2 + Endomorphism of Drinfeld module defined by T |--> 5*τ^2 + z6 + Defn: τ^2 Its characteristic polynomial can be computed:: @@ -235,7 +235,7 @@ def frobenius_endomorphism(self): Let `q` be the order of the base field of the function ring. The *Frobenius endomorphism* is defined as the endomorphism whose - defining Ore polynomial is `t^q`. + defining Ore polynomial is `τ^q`. EXAMPLES:: @@ -244,8 +244,8 @@ def frobenius_endomorphism(self): sage: K. = Fq.extension(2) sage: phi = DrinfeldModule(A, [1, 0, z6]) sage: phi.frobenius_endomorphism() - Endomorphism of Drinfeld module defined by T |--> z6*t^2 + 1 - Defn: t^2 + Endomorphism of Drinfeld module defined by T |--> z6*τ^2 + 1 + Defn: τ^2 TESTS:: @@ -273,14 +273,14 @@ def frobenius_charpoly(self, var='X', algorithm=None): Let `\chi = X^r + \sum_{i=0}^{r-1} A_{i}(T)X^{i}` be the characteristic polynomial of the Frobenius endomorphism, and - let `t^n` be the Ore polynomial that defines the Frobenius + let `τ^n` be the Ore polynomial that defines the Frobenius endomorphism of `\phi`; by definition, `n` is the degree of `K` over the base field `\mathbb{F}_q`. Then we have .. MATH:: - \chi(t^n)(\phi(T)) - = t^{nr} + \sum_{i=1}^{r} \phi_{A_{i}}t^{n(i)} + \chi(τ^n)(\phi(T)) + = τ^{nr} + \sum_{i=1}^{r} \phi_{A_{i}}τ^{n(i)} = 0, with `\deg(A_i) \leq \frac{n(r-i)}{r}`. @@ -340,7 +340,7 @@ def frobenius_charpoly(self, var='X', algorithm=None): sage: chi(frob_pol, phi(T)) 0 sage: phi.frobenius_charpoly(algorithm='motive')(phi.frobenius_endomorphism()) - Endomorphism of Drinfeld module defined by T |--> z6*t^2 + 1 + Endomorphism of Drinfeld module defined by T |--> z6*τ^2 + 1 Defn: 0 :: @@ -935,15 +935,15 @@ def invert(self, ore_pol): When the input is not in the image of the Drinfeld module, an exception is raised:: - sage: t = phi.ore_polring().gen() - sage: phi.invert(t + 1) + sage: tau = phi.ore_variable() + sage: phi.invert(tau + 1) Traceback (most recent call last): ... ValueError: input must be in the image of the Drinfeld module :: - sage: phi.invert(t^4 + t^2 + 1) + sage: phi.invert(tau^4 + tau^2 + 1) Traceback (most recent call last): ... ValueError: input must be in the image of the Drinfeld module @@ -1091,7 +1091,7 @@ def is_supersingular(self): sage: phi.is_supersingular() True sage: phi(phi.characteristic()) # Purely inseparable - z6*t^2 + z6*τ^2 In rank two, a Drinfeld module is either ordinary or supersinguler. In higher ranks, it could be neither of diff --git a/src/sage/rings/function_field/drinfeld_modules/homset.py b/src/sage/rings/function_field/drinfeld_modules/homset.py index faf6b45c5b4..7dac2d93194 100644 --- a/src/sage/rings/function_field/drinfeld_modules/homset.py +++ b/src/sage/rings/function_field/drinfeld_modules/homset.py @@ -41,16 +41,16 @@ class DrinfeldModuleMorphismAction(Action): sage: phi = DrinfeldModule(A, [z, 1, z]) sage: psi = DrinfeldModule(A, [z, z^2 + 4*z + 3, 2*z^2 + 4*z + 4]) sage: H = Hom(phi, psi) - sage: t = phi.ore_variable() - sage: f = H(t + 2) + sage: tau = phi.ore_variable() + sage: f = H(tau + 2) Left action:: sage: (T + 1) * f Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z*t^2 + t + z - To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^2 + (z^2 + 4*z + 3)*t + z - Defn: (2*z^2 + 4*z + 4)*t^3 + (2*z + 1)*t^2 + (2*z^2 + 4*z + 2)*t + 2*z + 2 + From: Drinfeld module defined by T |--> z*τ^2 + τ + z + To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^2 + (z^2 + 4*z + 3)*τ + z + Defn: (2*z^2 + 4*z + 4)*τ^3 + (2*z + 1)*τ^2 + (2*z^2 + 4*z + 2)*τ + 2*z + 2 Right action currently does not work (it is a known bug, due to an incompatibility between multiplication of morphisms and the coercion @@ -60,9 +60,9 @@ class DrinfeldModuleMorphismAction(Action): Traceback (most recent call last): ... TypeError: right (=T + 1) must be a map to multiply it by Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z*t^2 + t + z - To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^2 + (z^2 + 4*z + 3)*t + z - Defn: t + 2 + From: Drinfeld module defined by T |--> z*τ^2 + τ + z + To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^2 + (z^2 + 4*z + 3)*τ + z + Defn: τ + 2 """ def __init__(self, A, H, is_left, op): r""" @@ -114,9 +114,9 @@ def _act_(self, a, f): sage: f = phi.hom(t + 1) sage: T*f # indirect doctest Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z*t^3 + t^2 + z - To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z - Defn: (2*z^2 + 4*z + 4)*t^4 + (z + 1)*t^3 + t^2 + (2*z^2 + 4*z + 4)*t + z + From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^3 + (3*z^2 + 2*z + 2)*τ^2 + (2*z^2 + 3*z + 4)*τ + z + Defn: (2*z^2 + 4*z + 4)*τ^4 + (z + 1)*τ^3 + τ^2 + (2*z^2 + 4*z + 4)*τ + z """ u = f.ore_polynomial() if self._is_left: @@ -147,8 +147,8 @@ class DrinfeldModuleHomset(Homset): sage: H = Hom(phi, psi) sage: H Set of Drinfeld module morphisms - from (gen) 2*t^2 + z6*t + z6 - to (gen) 2*t^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*t + z6 + from (gen) 2*τ^2 + z6*τ + z6 + to (gen) 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6 :: @@ -160,7 +160,7 @@ class DrinfeldModuleHomset(Homset): sage: E = End(phi) sage: E - Set of Drinfeld module morphisms from (gen) 2*t^2 + z6*t + z6 to (gen) 2*t^2 + z6*t + z6 + Set of Drinfeld module morphisms from (gen) 2*τ^2 + z6*τ + z6 to (gen) 2*τ^2 + z6*τ + z6 sage: E is Hom(phi, phi) True @@ -185,39 +185,39 @@ class DrinfeldModuleHomset(Homset): sage: identity_morphism = E(1) sage: identity_morphism - Identity morphism of Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 + Identity morphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 :: - sage: t = phi.ore_polring().gen() - sage: frobenius_endomorphism = E(t^6) + sage: tau = phi.ore_variable() + sage: frobenius_endomorphism = E(tau^6) sage: frobenius_endomorphism - Endomorphism of Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 - Defn: t^6 + Endomorphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 + Defn: τ^6 :: - sage: isogeny = H(t + 1) + sage: isogeny = H(tau + 1) sage: isogeny Drinfeld Module morphism: - From: Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 - To: Drinfeld module defined by T |--> 2*t^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*t + z6 - Defn: t + 1 + From: Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 + To: Drinfeld module defined by T |--> 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6 + Defn: τ + 1 And one can test if an Ore polynomial defines a morphism using the ``in`` syntax:: sage: 1 in H False - sage: t^6 in H + sage: tau^6 in H False - sage: t + 1 in H + sage: tau + 1 in H True sage: 1 in E True - sage: t^6 in E + sage: tau^6 in E True - sage: t + 1 in E + sage: tau + 1 in E False This also works if the candidate is a morphism object:: @@ -293,7 +293,7 @@ def _latex_(self): sage: psi = DrinfeldModule(A, [z6, 2*z6^5 + 2*z6^4 + 2*z6 + 1, 2]) sage: H = Hom(phi, psi) sage: latex(H) - \text{Set{ }of{ }Drinfeld{ }module{ }morphisms{ }from{ }(gen){ }}2 t^{2} + z_{6} t + z_{6}\text{{ }to{ }(gen){ }}2 t^{2} + \left(2 z_{6}^{5} + 2 z_{6}^{4} + 2 z_{6} + 1\right) t + z_{6} + \text{Set{ }of{ }Drinfeld{ }module{ }morphisms{ }from{ }(gen){ }}2 τ^{2} + z_{6} τ + z_{6}\text{{ }to{ }(gen){ }}2 τ^{2} + \left(2 z_{6}^{5} + 2 z_{6}^{4} + 2 z_{6} + 1\right) τ + z_{6} """ return f'\\text{{Set{{ }}of{{ }}Drinfeld{{ }}module{{ }}morphisms' \ f'{{ }}from{{ }}(gen){{ }}}}{latex(self.domain().gen())}' \ @@ -313,7 +313,7 @@ def _repr_(self): sage: psi = DrinfeldModule(A, [z6, 2*z6^5 + 2*z6^4 + 2*z6 + 1, 2]) sage: H = Hom(phi, psi) sage: H - Set of Drinfeld module morphisms from (gen) 2*t^2 + z6*t + z6 to (gen) 2*t^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*t + z6 + Set of Drinfeld module morphisms from (gen) 2*τ^2 + z6*τ + z6 to (gen) 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6 """ return f'Set of Drinfeld module morphisms from (gen) '\ f'{self.domain().gen()} to (gen) {self.codomain().gen()}' @@ -337,23 +337,23 @@ def __contains__(self, x): sage: psi = DrinfeldModule(A, [z6, 2*z6^5 + 2*z6^4 + 2*z6 + 1, 2]) sage: H = Hom(phi, psi) sage: E = End(phi) - sage: t = phi.ore_polring().gen() + sage: tau = phi.ore_variable() sage: 1 in H False - sage: t^6 in H + sage: tau^6 in H False - sage: t + 1 in H + sage: tau + 1 in H True sage: 1 in E True - sage: t^6 in E + sage: tau^6 in E True - sage: t + 1 in E + sage: tau + 1 in E False Whereas the input is now a Drinfeld module morphism:: - sage: isogeny = H(t + 1) + sage: isogeny = H(tau + 1) sage: isogeny in H True sage: E(0) in E @@ -385,33 +385,33 @@ def _element_constructor_(self, *args, **kwds): sage: psi = DrinfeldModule(A, [z6, 2*z6^5 + 2*z6^4 + 2*z6 + 1, 2]) sage: H = Hom(phi, psi) sage: E = End(phi) - sage: t = phi.ore_polring().gen() + sage: tau = phi.ore_variable() sage: identity_morphism = E(1) sage: identity_morphism - Identity morphism of Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 + Identity morphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 :: sage: scalar_multiplication = E(T) sage: scalar_multiplication - Endomorphism of Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 - Defn: 2*t^2 + z6*t + z6 + Endomorphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 + Defn: 2*τ^2 + z6*τ + z6 :: - sage: frobenius_endomorphism = E(t^6) + sage: frobenius_endomorphism = E(tau^6) sage: frobenius_endomorphism - Endomorphism of Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 - Defn: t^6 + Endomorphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 + Defn: τ^6 :: - sage: isogeny = H(t + 1) + sage: isogeny = H(tau + 1) sage: isogeny Drinfeld Module morphism: - From: Drinfeld module defined by T |--> 2*t^2 + z6*t + z6 - To: Drinfeld module defined by T |--> 2*t^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*t + z6 - Defn: t + 1 + From: Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6 + To: Drinfeld module defined by T |--> 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6 + Defn: τ + 1 """ # NOTE: This used to be self.element_class(self, ...), but this # would call __init__ instead of __classcall_private__. This diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index beff948f980..2c7bf3b19c8 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -48,15 +48,15 @@ class DrinfeldModuleMorphism(Morphism, UniqueRepresentation, sage: A. = Fq[] sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, z^2 + z, z^2 + z]) - sage: t = phi.ore_polring().gen() - sage: ore_pol = t + z^5 + z^3 + z + 1 + sage: tau = phi.ore_variable() + sage: ore_pol = tau + z^5 + z^3 + z + 1 sage: psi = phi.velu(ore_pol) sage: morphism = Hom(phi, psi)(ore_pol) sage: morphism Drinfeld Module morphism: - From: Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z - To: Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z - Defn: t + z^5 + z^3 + z + 1 + From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z)*τ + z + To: Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*τ^2 + (z^4 + z + 1)*τ + z + Defn: τ + z^5 + z^3 + z + 1 The given Ore polynomial must indeed define a morphism:: @@ -69,19 +69,19 @@ class DrinfeldModuleMorphism(Morphism, UniqueRepresentation, One can get basic data on the morphism:: sage: morphism.domain() - Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z + Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z)*τ + z sage: morphism.domain() is phi True sage: morphism.codomain() - Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z + Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*τ^2 + (z^4 + z + 1)*τ + z sage: morphism.codomain() is psi True :: sage: morphism.ore_polynomial() - t + z^5 + z^3 + z + 1 + τ + z^5 + z^3 + z + 1 sage: morphism.ore_polynomial() is ore_pol True @@ -117,9 +117,9 @@ class DrinfeldModuleMorphism(Morphism, UniqueRepresentation, sage: from sage.rings.function_field.drinfeld_modules.morphism import DrinfeldModuleMorphism sage: DrinfeldModuleMorphism(Hom(phi, psi), ore_pol) Drinfeld Module morphism: - From: Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z - To: Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z - Defn: t + z^5 + z^3 + z + 1 + From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z)*τ + z + To: Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*τ^2 + (z^4 + z + 1)*τ + z + Defn: τ + z^5 + z^3 + z + 1 sage: DrinfeldModuleMorphism(Hom(phi, psi), ore_pol) is morphism True """ @@ -145,21 +145,21 @@ def __classcall_private__(cls, parent, x): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: End(phi)(T + 1) - Endomorphism of Drinfeld module defined by T |--> t^2 + t + z6 - Defn: t^2 + t + z6 + 1 + Endomorphism of Drinfeld module defined by T |--> τ^2 + τ + z6 + Defn: τ^2 + τ + z6 + 1 :: - sage: t = phi.ore_polring().gen() + sage: tau = phi.ore_variable() sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism is Hom(phi, psi)(morphism) True :: sage: from sage.rings.function_field.drinfeld_modules.morphism import DrinfeldModuleMorphism - sage: morphism = DrinfeldModuleMorphism(Sets(), t + 1) + sage: morphism = DrinfeldModuleMorphism(Sets(), tau + 1) Traceback (most recent call last): ... TypeError: parent should be a DrinfeldModuleHomset @@ -203,13 +203,13 @@ def __init__(self, parent, ore_pol): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism._domain is phi True sage: morphism._codomain is psi True - sage: morphism._ore_polynomial == t + z6^5 + z6^2 + 1 + sage: morphism._ore_polynomial == tau + z6^5 + z6^2 + 1 True """ super().__init__(parent) @@ -228,10 +228,10 @@ def _latex_(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: latex(morphism) - t + z_{6}^{5} + z_{6}^{2} + 1 + τ + z_{6}^{5} + z_{6}^{2} + 1 """ return f'{latex(self._ore_polynomial)}' @@ -246,13 +246,13 @@ def _repr_(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism Drinfeld Module morphism: - From: Drinfeld module defined by T |--> t^2 + t + z6 - To: Drinfeld module defined by T |--> t^2 + (z6^4 + z6^2 + 1)*t + z6 - Defn: t + z6^5 + z6^2 + 1 + From: Drinfeld module defined by T |--> τ^2 + τ + z6 + To: Drinfeld module defined by T |--> τ^2 + (z6^4 + z6^2 + 1)*τ + z6 + Defn: τ + z6^5 + z6^2 + 1 """ if self.is_identity(): return f'Identity morphism of {self._domain}' @@ -276,8 +276,8 @@ def __hash__(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: hash(morphism) # random -4214883752078138009 """ @@ -294,8 +294,8 @@ def is_zero(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism.is_zero() False @@ -324,8 +324,8 @@ def is_identity(self): :: sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism.is_identity() False """ @@ -342,8 +342,8 @@ def is_isogeny(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism.is_isogeny() True @@ -378,8 +378,8 @@ def is_isomorphism(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: morphism.is_isomorphism() False @@ -414,11 +414,11 @@ def ore_polynomial(self): sage: K. = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) - sage: t = phi.ore_polring().gen() - sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) + sage: tau = phi.ore_variable() + sage: morphism = Hom(phi, psi)(tau + z6^5 + z6^2 + 1) sage: ore_pol = morphism.ore_polynomial() sage: ore_pol - t + z6^5 + z6^2 + 1 + τ + z6^5 + z6^2 + 1 :: @@ -443,21 +443,21 @@ def __add__(self, other): sage: A. = Fq[] sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) - sage: t = phi.ore_variable() - sage: f = phi.hom(t + 1) + sage: tau = phi.ore_variable() + sage: f = phi.hom(tau + 1) sage: g = T * f sage: f + g # indirect doctest Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z*t^3 + t^2 + z - To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z - Defn: (2*z^2 + 4*z + 4)*t^4 + (z + 1)*t^3 + t^2 + (2*z^2 + 4*z)*t + z + 1 + From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^3 + (3*z^2 + 2*z + 2)*τ^2 + (2*z^2 + 3*z + 4)*τ + z + Defn: (2*z^2 + 4*z + 4)*τ^4 + (z + 1)*τ^3 + τ^2 + (2*z^2 + 4*z)*τ + z + 1 We check that coercion from the function ring works:: sage: F = phi.frobenius_endomorphism() sage: F + T - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: (z + 1)*t^3 + t^2 + z + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: (z + 1)*τ^3 + τ^2 + z """ return self.parent()(self.ore_polynomial() + other.ore_polynomial()) @@ -473,11 +473,11 @@ def _composition_(self, other, H): sage: phi = DrinfeldModule(A, [z, 1, z, z^2]) sage: f = phi.frobenius_endomorphism() sage: f - Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z - Defn: t^3 + Endomorphism of Drinfeld module defined by T |--> z^2*τ^3 + z*τ^2 + τ + z + Defn: τ^3 sage: f * f # indirect doctest - Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z - Defn: t^6 + Endomorphism of Drinfeld module defined by T |--> z^2*τ^3 + z*τ^2 + τ + z + Defn: τ^6 """ return H(self.ore_polynomial() * other.ore_polynomial()) @@ -495,10 +495,10 @@ def inverse(self): sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 1, z, z^2]) sage: f = phi.hom(2); f - Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z + Endomorphism of Drinfeld module defined by T |--> z^2*τ^3 + z*τ^2 + τ + z Defn: 2 sage: f.inverse() - Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z + Endomorphism of Drinfeld module defined by T |--> z^2*τ^3 + z*τ^2 + τ + z Defn: 3 Inversion of general isomorphisms between different Drinfeld modules @@ -506,13 +506,13 @@ def inverse(self): sage: g = phi.hom(z); g Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z - To: Drinfeld module defined by T |--> z^2*t^3 + (z^2 + 2*z + 3)*t^2 + (z^2 + 3*z)*t + z + From: Drinfeld module defined by T |--> z^2*τ^3 + z*τ^2 + τ + z + To: Drinfeld module defined by T |--> z^2*τ^3 + (z^2 + 2*z + 3)*τ^2 + (z^2 + 3*z)*τ + z Defn: z sage: g.inverse() Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z^2*t^3 + (z^2 + 2*z + 3)*t^2 + (z^2 + 3*z)*t + z - To: Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z + From: Drinfeld module defined by T |--> z^2*τ^3 + (z^2 + 2*z + 3)*τ^2 + (z^2 + 3*z)*τ + z + To: Drinfeld module defined by T |--> z^2*τ^3 + z*τ^2 + τ + z Defn: 3*z^2 + 4 When the morphism is not invertible, an error is raised:: @@ -564,8 +564,8 @@ def _motive_matrix(self): sage: A. = Fq[] sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1]) - sage: t = phi.ore_variable() - sage: u = t^2 + (2*z^2 + 3*z + 3)*t + (2*z + 3) + sage: tau = phi.ore_variable() + sage: u = tau^2 + (2*z^2 + 3*z + 3)*tau + (2*z + 3) sage: f = phi.hom(u) sage: f._motive_matrix() [ T + 3 + z 3 + 3*z + 2*z^2] @@ -621,8 +621,8 @@ def norm(self, ideal=True): sage: A. = Fq[] sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) - sage: t = phi.ore_variable() - sage: f = phi.hom(t + 1) + sage: tau = phi.ore_variable() + sage: f = phi.hom(tau + 1) sage: f.norm() Principal ideal (T + 4) of Univariate Polynomial Ring in T over Finite Field of size 5 @@ -682,19 +682,19 @@ def dual_isogeny(self): sage: A. = Fq[] sage: K. = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) - sage: t = phi.ore_variable() - sage: f = phi.hom(t + 1) + sage: tau = phi.ore_variable() + sage: f = phi.hom(tau + 1) sage: f Drinfeld Module morphism: - From: Drinfeld module defined by T |--> z*t^3 + t^2 + z - To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z - Defn: t + 1 + From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^3 + (3*z^2 + 2*z + 2)*τ^2 + (2*z^2 + 3*z + 4)*τ + z + Defn: τ + 1 sage: g = f.dual_isogeny() sage: g Drinfeld Module morphism: - From: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z - To: Drinfeld module defined by T |--> z*t^3 + t^2 + z - Defn: z*t^2 + (4*z + 1)*t + z + 4 + From: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^3 + (3*z^2 + 2*z + 2)*τ^2 + (2*z^2 + 3*z + 4)*τ + z + To: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z + Defn: z*τ^2 + (4*z + 1)*τ + z + 4 We check that `f \circ g` (resp. `g \circ f`) is the multiplication by the norm of `f`:: @@ -760,8 +760,8 @@ def characteristic_polynomial(self, var='X'): TESTS:: - sage: t = phi.ore_variable() - sage: isog = phi.hom(t + 1) + sage: tau = phi.ore_variable() + sage: isog = phi.hom(tau + 1) sage: isog.characteristic_polynomial() Traceback (most recent call last): ... @@ -800,7 +800,7 @@ def charpoly(self, var='X'): morphism (Cayley-Hamilton's theorem):: sage: chi(f) - Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z + Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z Defn: 0 We verify, on an example, that the characteristic polynomial From 27e890b5b1771607f0ad009cba2b010abf71ae46 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 17 Jul 2025 11:19:59 +0200 Subject: [PATCH 02/12] declare encoding --- src/sage/rings/function_field/drinfeld_modules/action.py | 1 + .../function_field/drinfeld_modules/charzero_drinfeld_module.py | 1 + .../rings/function_field/drinfeld_modules/drinfeld_module.py | 1 + .../function_field/drinfeld_modules/finite_drinfeld_module.py | 1 + src/sage/rings/function_field/drinfeld_modules/homset.py | 1 + src/sage/rings/function_field/drinfeld_modules/morphism.py | 1 + 6 files changed, 6 insertions(+) diff --git a/src/sage/rings/function_field/drinfeld_modules/action.py b/src/sage/rings/function_field/drinfeld_modules/action.py index 06f8897326d..7cb428452b1 100644 --- a/src/sage/rings/function_field/drinfeld_modules/action.py +++ b/src/sage/rings/function_field/drinfeld_modules/action.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" The module action induced by a Drinfeld module diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 99dd8dc9ce5..4c0c4b21437 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage.doctest: optional - sage.rings.finite_rings r""" Drinfeld modules over rings of characteristic zero diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 4d26afc2abb..1720d445ae2 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Drinfeld modules diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 685d5b5c465..599aa775d72 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Finite Drinfeld modules diff --git a/src/sage/rings/function_field/drinfeld_modules/homset.py b/src/sage/rings/function_field/drinfeld_modules/homset.py index 7dac2d93194..e1918686519 100644 --- a/src/sage/rings/function_field/drinfeld_modules/homset.py +++ b/src/sage/rings/function_field/drinfeld_modules/homset.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Set of morphisms between two Drinfeld modules diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index 2c7bf3b19c8..490adc634ea 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Drinfeld module morphisms From 35cf2b6e87d6cb958fe8db4ce2dd2dcf08e6e896 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 17 Jul 2025 21:37:57 +0200 Subject: [PATCH 03/12] constructor for the Carlitz module --- src/sage/rings/function_field/all.py | 1 + .../drinfeld_modules/carlitz_module.py | 98 +++++++++++++++++++ .../drinfeld_modules/drinfeld_module.py | 17 +--- .../finite_drinfeld_module.py | 5 +- 4 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 src/sage/rings/function_field/drinfeld_modules/carlitz_module.py diff --git a/src/sage/rings/function_field/all.py b/src/sage/rings/function_field/all.py index b423a0d58f5..7ca581d670d 100644 --- a/src/sage/rings/function_field/all.py +++ b/src/sage/rings/function_field/all.py @@ -3,3 +3,4 @@ from sage.misc.lazy_import import lazy_import lazy_import("sage.rings.function_field.drinfeld_modules.drinfeld_module", "DrinfeldModule") +lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzModule") diff --git a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py new file mode 100644 index 00000000000..50048ee0b22 --- /dev/null +++ b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py @@ -0,0 +1,98 @@ +r""" +Carlitz module + +AUTHORS: + +- Xavier Caruso (2025-07): initial version +""" + +# ***************************************************************************** +# Copyright (C) 2025 Xavier Caruso +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +# ***************************************************************************** + +from sage.structure.parent import Parent +from sage.structure.element import Element +from sage.categories.finite_fields import FiniteFields + +from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic +from sage.rings.function_field.drinfeld_modules.drinfeld_module import DrinfeldModule + + +def CarlitzModule(A, base=None): + r""" + Return the Carlitz module over `A`. + + INPUT: + + - ``A`` -- a polynomial ring over a finite field + + - ``base`` -- a field or an element in a field + (default: the fraction field of ``A``) + + EXAMPLES:: + + sage: Fq = GF(7) + sage: A. = Fq[] + sage: CarlitzModule(A) + Drinfeld module defined by T |--> τ + T + + We can specify a different base. + This is interesting for instance for having two different variable + names:: + + sage: R. = Fq[] + sage: K = Frac(R) + sage: CarlitzModule(A, K) + Drinfeld module defined by T |--> τ + z + + Using a similar syntax, we can construct the reduction over the + Carlitz module modulo primes:: + + sage: F. = Fq.extension(z^2 + 1) + sage: CarlitzModule(A, F) + Drinfeld module defined by T |--> τ + a + + It is also possible to pass in any element in the base field + (in this case, the result might not be strictly speaking the + Carlitz module, but it is always a Drinfeld module of rank 1):: + + sage: CarlitzModule(A, z^2) + Drinfeld module defined by T |--> τ + z^2 + + TESTS:: + + sage: CarlitzModule(Fq) + Traceback (most recent call last): + ... + TypeError: the function ring must be defined over a finite field + + :: + + sage: S. = QQ[] + sage: CarlitzModule(A, S) + Traceback (most recent call last): + ... + ValueError: function ring base must coerce into base field + """ + if (not isinstance(A, PolynomialRing_generic) + or A.base_ring() not in FiniteFields()): + raise TypeError('the function ring must be defined over a finite field') + if base is None: + K = A.fraction_field() + z = K.gen() + elif isinstance(base, Parent): + if base.has_coerce_map_from(A): + z = base(A.gen()) + else: + z = base.gen() + elif isinstance(base, Element): + z = base + else: + raise ValueError("cannot construct a Carlitz module from the given data") + return DrinfeldModule(A, [z, 1]) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 1720d445ae2..26d6480dc69 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -435,16 +435,6 @@ class DrinfeldModule(Parent, UniqueRepresentation): ... ValueError: generator must have positive degree - The constant coefficient must be nonzero:: - - sage: Fq = GF(2) - sage: K. = Fq.extension(2) - sage: A. = Fq[] - sage: DrinfeldModule(A, [K(0), K(1)]) - Traceback (most recent call last): - ... - ValueError: constant coefficient must be nonzero - The coefficients of the generator must lie in an `\mathbb{F}_q[T]`-field, where `\mathbb{F}_q[T]` is the function ring of the Drinfeld module:: @@ -584,12 +574,13 @@ def __classcall_private__(cls, function_ring, gen, name='τ'): ore_polring = None # Base ring without morphism structure: base_field = Sequence(gen).universe() + try: + base_field = base_field.fraction_field() + except AttributeError: + pass else: raise TypeError('generator must be list of coefficients or Ore ' 'polynomial') - # Constant coefficient must be nonzero: - if gen[0].is_zero(): - raise ValueError('constant coefficient must be nonzero') # The coefficients are in a base field that has coercion from Fq: if not (hasattr(base_field, 'has_coerce_map_from') and base_field.has_coerce_map_from(function_ring.base_ring())): diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 599aa775d72..e2513579711 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -29,6 +29,7 @@ from sage.matrix.constructor import Matrix from sage.matrix.matrix_space import MatrixSpace from sage.matrix.special import companion_matrix +from sage.misc.functional import log from sage.misc.misc_c import prod from sage.modules.free_module_element import vector from sage.rings.function_field.drinfeld_modules.drinfeld_module import DrinfeldModule @@ -158,7 +159,7 @@ def __init__(self, gen, category): # added one to ensure that DrinfeldModule_finite would always # have _frobenius_norm and _frobenius_trace attributes. super().__init__(gen, category) - self._base_degree_over_constants = self.base_over_constants_field().degree(self._Fq) + self._base_degree_over_constants = log(self._base.cardinality(), self._Fq.cardinality()) self._frobenius_norm = None self._frobenius_trace = None self._frobenius_charpoly = None @@ -255,7 +256,7 @@ def frobenius_endomorphism(self): True """ t = self.ore_polring().gen() - deg = self.base_over_constants_field().degree_over() + deg = self._base_degree_over_constants return self._Hom_(self, category=self.category())(t**deg) def frobenius_charpoly(self, var='X', algorithm=None): From 8ebeba3fce4987d455fe6568c2b4181e3011e8d8 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 17 Jul 2025 23:54:16 +0200 Subject: [PATCH 04/12] Carlitz exponential and logarithm --- src/sage/rings/function_field/all.py | 2 + .../drinfeld_modules/carlitz_module.py | 89 +++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/src/sage/rings/function_field/all.py b/src/sage/rings/function_field/all.py index 7ca581d670d..873e235ea06 100644 --- a/src/sage/rings/function_field/all.py +++ b/src/sage/rings/function_field/all.py @@ -4,3 +4,5 @@ lazy_import("sage.rings.function_field.drinfeld_modules.drinfeld_module", "DrinfeldModule") lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzModule") +lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzExponential") +lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzLogarithm") diff --git a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py index 50048ee0b22..7f014cd57d3 100644 --- a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py @@ -20,6 +20,8 @@ from sage.structure.element import Element from sage.categories.finite_fields import FiniteFields +from sage.rings.infinity import Infinity + from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic from sage.rings.function_field.drinfeld_modules.drinfeld_module import DrinfeldModule @@ -96,3 +98,90 @@ def CarlitzModule(A, base=None): else: raise ValueError("cannot construct a Carlitz module from the given data") return DrinfeldModule(A, [z, 1]) + +def CarlitzExponential(A, prec=+Infinity, name='z'): + r""" + Return the Carlitz exponential attached the ring `A`. + + INPUT: + + - ``prec`` -- an integer or ``Infinity`` (default: ``Infinity``); + the precision at which the series is returned; if ``Infinity``, + a lazy power series in returned, else, a classical power series + is returned. + + - ``name`` -- string (default: ``'z'``); the name of the + generator of the lazy power series ring + + EXAMPLES:: + + sage: A. = GF(2)[] + + When ``prec`` is ``Infinity`` (which is the default), + the exponential is returned as a lazy power series, meaning + that any of its coefficients can be computed on demands:: + + sage: exp = CarlitzExponential(A) + sage: exp + z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8) + sage: exp[2^4] + 1/(T^64 + T^56 + T^52 + ... + T^27 + T^23 + T^15) + sage: exp[2^5] + 1/(T^160 + T^144 + T^136 + ... + T^55 + T^47 + T^31) + + On the contrary, when ``prec`` is a finite number, all the + required coefficients are computed at once:: + + sage: CarlitzExponential(A, prec=10) + z + (1/(T^2 + T))*z^2 + (1/(T^8 + T^6 + T^5 + T^3))*z^4 + (1/(T^24 + T^20 + T^18 + T^17 + T^14 + T^13 + T^11 + T^7))*z^8 + O(z^10) + + We check that the Carlitz exponential is the compositional inverse + of the Carlitz logarithm:: + + sage: log = CarlitzLogarithm(A) + sage: exp(log) + z + O(z^8) + sage: log(exp) + z + O(z^8) + """ + C = CarlitzModule(A) + return C.exponential(prec, name) + +def CarlitzLogarithm(A, prec=+Infinity, name='z'): + r""" + Return the Carlitz exponential attached the ring `A`. + + INPUT: + + - ``prec`` -- an integer or ``Infinity`` (default: ``Infinity``); + the precision at which the series is returned; if ``Infinity``, + a lazy power series in returned, else, a classical power series + is returned. + + - ``name`` -- string (default: ``'z'``); the name of the + generator of the lazy power series ring + + EXAMPLES:: + + sage: A. = GF(2)[] + + When ``prec`` is ``Infinity`` (which is the default), + the exponential is returned as a lazy power series, meaning + that any of its coefficients can be computed on demands:: + + sage: log = CarlitzLogarithm(A) + sage: log + z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8) + sage: log[2^4] + 1/(T^30 + T^29 + T^27 + ... + T^7 + T^5 + T^4) + sage: log[2^5] + 1/(T^62 + T^61 + T^59 + ... + T^8 + T^6 + T^5) + + On the contrary, when ``prec`` is a finite number, all the + required coefficients are computed at once:: + + sage: CarlitzLogarithm(A, prec=10) + z + (1/(T^2 + T))*z^2 + (1/(T^6 + T^5 + T^3 + T^2))*z^4 + (1/(T^14 + T^13 + T^11 + T^10 + T^7 + T^6 + T^4 + T^3))*z^8 + O(z^10) + """ + C = CarlitzModule(A) + return C.logarithm(prec, name) From 2caec64f2344fbea9b2a16f2bebd5e37d30005b4 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Fri, 18 Jul 2025 21:37:20 +0200 Subject: [PATCH 05/12] some remaining t --- .../function_field/drinfeld_modules/drinfeld_module.py | 10 +++++----- .../drinfeld_modules/finite_drinfeld_module.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 1720d445ae2..7e2de8a4161 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -128,7 +128,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring + - ``name`` -- (default: ``'τ'``) the name of the Ore polynomial ring generator .. RUBRIC:: Construction @@ -534,8 +534,8 @@ def __classcall_private__(cls, function_ring, gen, name='τ'): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'τ'``) the name of the Ore polynomial - ring gen + - ``name`` -- (default: ``'τ'``) the name of the variable of + the Ore polynomial OUTPUT: a DrinfeldModule or DrinfeldModule_finite @@ -646,8 +646,8 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'t'``) the name of the Ore polynomial - ring gen + - ``name`` -- (default: ``'τ'``) the name of the variable of + the Ore polynomial ring TESTS:: diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 599aa775d72..f0bf581caa2 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -139,8 +139,8 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'t'``) the name of the Ore polynomial - ring gen + - ``name`` -- (default: ``'τ'``) the name of the variable of + the Ore polynomial ring TESTS:: From 1708b4016e2822ce00d0913772c8ee49c2f892b1 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Fri, 18 Jul 2025 21:55:34 +0200 Subject: [PATCH 06/12] allow str for the base --- src/sage/rings/function_field/all.py | 4 +-- .../drinfeld_modules/carlitz_module.py | 30 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/function_field/all.py b/src/sage/rings/function_field/all.py index 873e235ea06..459ad867b0d 100644 --- a/src/sage/rings/function_field/all.py +++ b/src/sage/rings/function_field/all.py @@ -4,5 +4,5 @@ lazy_import("sage.rings.function_field.drinfeld_modules.drinfeld_module", "DrinfeldModule") lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzModule") -lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzExponential") -lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "CarlitzLogarithm") +lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "carlitz_exponential") +lazy_import("sage.rings.function_field.drinfeld_modules.carlitz_module", "carlitz_logarithm") diff --git a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py index 7f014cd57d3..d3737a6bd37 100644 --- a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py @@ -34,8 +34,8 @@ def CarlitzModule(A, base=None): - ``A`` -- a polynomial ring over a finite field - - ``base`` -- a field or an element in a field - (default: the fraction field of ``A``) + - ``base`` -- a field, an element in a field or a + string (default: the fraction field of ``A``) EXAMPLES:: @@ -49,8 +49,13 @@ def CarlitzModule(A, base=None): names:: sage: R. = Fq[] - sage: K = Frac(R) - sage: CarlitzModule(A, K) + sage: CarlitzModule(A, R) + Drinfeld module defined by T |--> τ + z + + One can even use the following shortcut, which avoids the + construction of `R`:: + + sage: CarlitzModule(A, 'z') Drinfeld module defined by T |--> τ + z Using a similar syntax, we can construct the reduction over the @@ -95,11 +100,14 @@ def CarlitzModule(A, base=None): z = base.gen() elif isinstance(base, Element): z = base + elif isinstance(base, str): + K = A.base_ring()[base] + z = K.gen() else: raise ValueError("cannot construct a Carlitz module from the given data") return DrinfeldModule(A, [z, 1]) -def CarlitzExponential(A, prec=+Infinity, name='z'): +def carlitz_exponential(A, prec=+Infinity, name='z'): r""" Return the Carlitz exponential attached the ring `A`. @@ -121,7 +129,7 @@ def CarlitzExponential(A, prec=+Infinity, name='z'): the exponential is returned as a lazy power series, meaning that any of its coefficients can be computed on demands:: - sage: exp = CarlitzExponential(A) + sage: exp = carlitz_exponential(A) sage: exp z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8) sage: exp[2^4] @@ -132,13 +140,13 @@ def CarlitzExponential(A, prec=+Infinity, name='z'): On the contrary, when ``prec`` is a finite number, all the required coefficients are computed at once:: - sage: CarlitzExponential(A, prec=10) + sage: carlitz_exponential(A, prec=10) z + (1/(T^2 + T))*z^2 + (1/(T^8 + T^6 + T^5 + T^3))*z^4 + (1/(T^24 + T^20 + T^18 + T^17 + T^14 + T^13 + T^11 + T^7))*z^8 + O(z^10) We check that the Carlitz exponential is the compositional inverse of the Carlitz logarithm:: - sage: log = CarlitzLogarithm(A) + sage: log = carlitz_logarithm(A) sage: exp(log) z + O(z^8) sage: log(exp) @@ -147,7 +155,7 @@ def CarlitzExponential(A, prec=+Infinity, name='z'): C = CarlitzModule(A) return C.exponential(prec, name) -def CarlitzLogarithm(A, prec=+Infinity, name='z'): +def carlitz_logarithm(A, prec=+Infinity, name='z'): r""" Return the Carlitz exponential attached the ring `A`. @@ -169,7 +177,7 @@ def CarlitzLogarithm(A, prec=+Infinity, name='z'): the exponential is returned as a lazy power series, meaning that any of its coefficients can be computed on demands:: - sage: log = CarlitzLogarithm(A) + sage: log = carlitz_logarithm(A) sage: log z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8) sage: log[2^4] @@ -180,7 +188,7 @@ def CarlitzLogarithm(A, prec=+Infinity, name='z'): On the contrary, when ``prec`` is a finite number, all the required coefficients are computed at once:: - sage: CarlitzLogarithm(A, prec=10) + sage: carlitz_logarithm(A, prec=10) z + (1/(T^2 + T))*z^2 + (1/(T^6 + T^5 + T^3 + T^2))*z^4 + (1/(T^14 + T^13 + T^11 + T^10 + T^7 + T^6 + T^4 + T^3))*z^8 + O(z^10) """ C = CarlitzModule(A) From 9c0ede59c7510182b1df6bb41e417aa75cd75b93 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Fri, 18 Jul 2025 21:58:26 +0200 Subject: [PATCH 07/12] fix lint --- .../rings/function_field/drinfeld_modules/carlitz_module.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py index d3737a6bd37..e7a813515fe 100644 --- a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py @@ -107,6 +107,7 @@ def CarlitzModule(A, base=None): raise ValueError("cannot construct a Carlitz module from the given data") return DrinfeldModule(A, [z, 1]) + def carlitz_exponential(A, prec=+Infinity, name='z'): r""" Return the Carlitz exponential attached the ring `A`. @@ -155,6 +156,7 @@ def carlitz_exponential(A, prec=+Infinity, name='z'): C = CarlitzModule(A) return C.exponential(prec, name) + def carlitz_logarithm(A, prec=+Infinity, name='z'): r""" Return the Carlitz exponential attached the ring `A`. From 3df54f3d8ea9223e0e08ad42e51dad33b9f5cb11 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Sat, 19 Jul 2025 08:26:43 +0200 Subject: [PATCH 08/12] typo --- .../rings/function_field/drinfeld_modules/carlitz_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py index e7a813515fe..efac57955f2 100644 --- a/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/carlitz_module.py @@ -58,7 +58,7 @@ def CarlitzModule(A, base=None): sage: CarlitzModule(A, 'z') Drinfeld module defined by T |--> τ + z - Using a similar syntax, we can construct the reduction over the + Using a similar syntax, we can construct the reduction of the Carlitz module modulo primes:: sage: F. = Fq.extension(z^2 + 1) From 15b399a7549334e781b37cc8c96a52eb2ff96e07 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Wed, 13 Aug 2025 17:40:23 +0200 Subject: [PATCH 09/12] remove coding utf8 --- src/sage/rings/function_field/drinfeld_modules/action.py | 1 - .../function_field/drinfeld_modules/charzero_drinfeld_module.py | 1 - .../rings/function_field/drinfeld_modules/drinfeld_module.py | 1 - .../function_field/drinfeld_modules/finite_drinfeld_module.py | 1 - src/sage/rings/function_field/drinfeld_modules/homset.py | 1 - src/sage/rings/function_field/drinfeld_modules/morphism.py | 1 - 6 files changed, 6 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/action.py b/src/sage/rings/function_field/drinfeld_modules/action.py index 7cb428452b1..06f8897326d 100644 --- a/src/sage/rings/function_field/drinfeld_modules/action.py +++ b/src/sage/rings/function_field/drinfeld_modules/action.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" The module action induced by a Drinfeld module diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 4c0c4b21437..99dd8dc9ce5 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: optional - sage.rings.finite_rings r""" Drinfeld modules over rings of characteristic zero diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 7e2de8a4161..eaf958ff0ee 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Drinfeld modules diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 0cb6d60d265..15d616b5d2f 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Finite Drinfeld modules diff --git a/src/sage/rings/function_field/drinfeld_modules/homset.py b/src/sage/rings/function_field/drinfeld_modules/homset.py index e1918686519..7dac2d93194 100644 --- a/src/sage/rings/function_field/drinfeld_modules/homset.py +++ b/src/sage/rings/function_field/drinfeld_modules/homset.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Set of morphisms between two Drinfeld modules diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index 490adc634ea..2c7bf3b19c8 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: needs sage.rings.finite_rings r""" Drinfeld module morphisms From 124db5bf4b685c6357fa4b574eb22fd126303585 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Fri, 15 Aug 2025 09:30:11 +0200 Subject: [PATCH 10/12] fix pdf documentation --- .../function_field/drinfeld_modules/drinfeld_module.py | 10 +++++----- .../drinfeld_modules/finite_drinfeld_module.py | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index eaf958ff0ee..c564cdd4935 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -127,8 +127,8 @@ class DrinfeldModule(Parent, UniqueRepresentation): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'τ'``) the name of the Ore polynomial ring - generator + - ``name`` -- (default: `\tau`) the name of the Ore + polynomial ring generator .. RUBRIC:: Construction @@ -163,7 +163,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): False In those examples, we used a list of coefficients (``[z, 1, 1]``) to - represent the generator `\phi_T = z + τ + τ^2`. One can also use + represent the generator `\phi_T = z + \tau + \tau^2`. One can also use regular Ore polynomials:: sage: ore_polring = phi.ore_polring() @@ -533,7 +533,7 @@ def __classcall_private__(cls, function_ring, gen, name='τ'): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'τ'``) the name of the variable of + - ``name`` -- (default: `\tau`) the name of the variable of the Ore polynomial OUTPUT: a DrinfeldModule or DrinfeldModule_finite @@ -645,7 +645,7 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'τ'``) the name of the variable of + - ``name`` -- (default: `\tau`) the name of the variable of the Ore polynomial ring TESTS:: diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 15d616b5d2f..c18aa88664f 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -138,7 +138,7 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module as a list of coefficients or an Ore polynomial - - ``name`` -- (default: ``'τ'``) the name of the variable of + - ``name`` -- (default: `\tau`) the name of the variable of the Ore polynomial ring TESTS:: @@ -235,7 +235,7 @@ def frobenius_endomorphism(self): Let `q` be the order of the base field of the function ring. The *Frobenius endomorphism* is defined as the endomorphism whose - defining Ore polynomial is `τ^q`. + defining Ore polynomial is `\tau^q`. EXAMPLES:: @@ -273,14 +273,14 @@ def frobenius_charpoly(self, var='X', algorithm=None): Let `\chi = X^r + \sum_{i=0}^{r-1} A_{i}(T)X^{i}` be the characteristic polynomial of the Frobenius endomorphism, and - let `τ^n` be the Ore polynomial that defines the Frobenius + let `\tau^n` be the Ore polynomial that defines the Frobenius endomorphism of `\phi`; by definition, `n` is the degree of `K` over the base field `\mathbb{F}_q`. Then we have .. MATH:: - \chi(τ^n)(\phi(T)) - = τ^{nr} + \sum_{i=1}^{r} \phi_{A_{i}}τ^{n(i)} + \chi(\tau^n)(\phi(T)) + = \tau^{nr} + \sum_{i=1}^{r} \phi_{A_{i}}\tau^{n(i)} = 0, with `\deg(A_i) \leq \frac{n(r-i)}{r}`. From 5dc6b4588bbcbfc4642565ae953ab6867ed82152 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Fri, 15 Aug 2025 10:59:05 +0200 Subject: [PATCH 11/12] =?UTF-8?q?default:=20``'=CF=84'``?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../function_field/drinfeld_modules/drinfeld_module.py | 6 +++--- .../drinfeld_modules/finite_drinfeld_module.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index c564cdd4935..1ab7e626232 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -127,7 +127,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: `\tau`) the name of the Ore + - ``name`` -- (default: ``'τ'``) the name of the Ore polynomial ring generator .. RUBRIC:: Construction @@ -533,7 +533,7 @@ def __classcall_private__(cls, function_ring, gen, name='τ'): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: `\tau`) the name of the variable of + - ``name`` -- (default: ``'τ'``) the name of the variable of the Ore polynomial OUTPUT: a DrinfeldModule or DrinfeldModule_finite @@ -645,7 +645,7 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module; as a list of coefficients or an Ore polynomial - - ``name`` -- (default: `\tau`) the name of the variable of + - ``name`` -- (default: ``'τ'``) the name of the variable of the Ore polynomial ring TESTS:: diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index c18aa88664f..6a9fc657ab3 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -138,7 +138,7 @@ def __init__(self, gen, category): - ``gen`` -- the generator of the Drinfeld module as a list of coefficients or an Ore polynomial - - ``name`` -- (default: `\tau`) the name of the variable of + - ``name`` -- (default: ``'τ'``) the name of the variable of the Ore polynomial ring TESTS:: From b4b4d901905e289e167b23c739363d97ad5a9607 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Sat, 16 Aug 2025 15:32:44 +0200 Subject: [PATCH 12/12] remove encoding declaration --- src/sage/categories/drinfeld_modules.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/categories/drinfeld_modules.py b/src/sage/categories/drinfeld_modules.py index aa80f8cc3b8..670ac3796b4 100644 --- a/src/sage/categories/drinfeld_modules.py +++ b/src/sage/categories/drinfeld_modules.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage_setup: distribution = sagemath-categories # sage.doctest: needs sage.rings.finite_rings r"""