diff --git a/src/sage/categories/drinfeld_modules.py b/src/sage/categories/drinfeld_modules.py index 1e9bd910c70..75e57d0ba8b 100644 --- a/src/sage/categories/drinfeld_modules.py +++ b/src/sage/categories/drinfeld_modules.py @@ -70,7 +70,7 @@ class DrinfeldModules(Category_over_base_ring): sage: phi = DrinfeldModule(A, [p_root, 0, 0, 1]) sage: C = phi.category() sage: C - Category of Drinfeld modules over Finite Field in z of size 11^4 over its base + Category of Drinfeld modules over Finite Field in z of size 11^4 The output tells the user that the category is only defined by its base. @@ -88,7 +88,7 @@ class DrinfeldModules(Category_over_base_ring): sage: C.base_morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field of size 11 - To: Finite Field in z of size 11^4 over its base + To: Finite Field in z of size 11^4 Defn: T |--> z^3 + 7*z^2 + 6*z + 10 The so-called constant coefficient --- which is the same for all @@ -123,7 +123,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 over its base twisted by Frob + Ore Polynomial Ring in t over Finite Field in z of size 11^4 twisted by z |--> z^11 sage: C.ore_polring() is phi.ore_polring() True @@ -165,20 +165,24 @@ class DrinfeldModules(Category_over_base_ring): sage: K. = Fq.extension(4) sage: from sage.categories.drinfeld_modules import DrinfeldModules sage: base = Hom(A, K)(0) - sage: C = DrinfeldModules(base) + sage: C = DrinfeldModules(base) # known bug (blankline) + Traceback (most recent call last): ... TypeError: base field must be a ring extension - :: + Note that `C.base_morphism()` has codomain `K` while + the defining morphism of `C.base()` has codomain `K` viewed + as an `A`-field. Thus, they differ:: sage: C.base().defining_morphism() == C.base_morphism() - True + False :: sage: base = Hom(A, A)(1) - sage: C = DrinfeldModules(base) + sage: C = DrinfeldModules(base) # known bug (blankline) + Traceback (most recent call last): ... TypeError: base field must be a ring extension @@ -203,7 +207,7 @@ class DrinfeldModules(Category_over_base_ring): TypeError: function ring base must be a finite field """ - def __init__(self, base_field, name='t'): + def __init__(self, base_morphism, name='t'): r""" Initialize ``self``. @@ -223,34 +227,23 @@ def __init__(self, base_field, 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(phi.base(), phi.base().frobenius_endomorphism()) + sage: ore_polring. = OrePolynomialRing(K, K.frobenius_endomorphism()) sage: C._ore_polring is ore_polring True - sage: i = phi.base().coerce_map_from(K) - sage: base_morphism = Hom(A, K)(p_root) - sage: C.base() == K.over(base_morphism) - True - sage: C._base_morphism == i * base_morphism - True sage: C._function_ring is A True - sage: C._constant_coefficient == base_morphism(T) + sage: C._constant_coefficient == C._base_morphism(T) True sage: C._characteristic(C._constant_coefficient) 0 """ - # Check input is a ring extension - if not isinstance(base_field, RingExtension_generic): - raise TypeError('base field must be a ring extension') - base_morphism = base_field.defining_morphism() self._base_morphism = base_morphism + function_ring = self._function_ring = base_morphism.domain() + base_field = self._base_field = base_morphism.codomain() # Check input is a field if not base_field.is_field(): raise TypeError('input must be a field') - self._base_field = base_field - self._function_ring = base_morphism.domain() # Check domain of base morphism is Fq[T] - function_ring = self._function_ring if not isinstance(function_ring, PolynomialRing_generic): raise NotImplementedError('function ring must be a polynomial ' 'ring') @@ -262,7 +255,7 @@ def __init__(self, base_field, name='t'): Fq = function_ring_base A = function_ring T = A.gen() - K = base_field # A ring extension + K = base_field # Build K{t} d = log(Fq.cardinality(), Fq.characteristic()) tau = K.frobenius_endomorphism(d) @@ -284,7 +277,7 @@ def __init__(self, base_field, name='t'): i = A.coerce_map_from(Fq) Fq_to_K = self._base_morphism * i self._base_over_constants_field = base_field.over(Fq_to_K) - super().__init__(base=base_field) + super().__init__(base=base_field.over(base_morphism)) def _latex_(self): r""" @@ -321,7 +314,7 @@ def _repr_(self): sage: phi = DrinfeldModule(A, [p_root, 0, 0, 1]) sage: C = phi.category() sage: C - Category of Drinfeld modules over Finite Field in z of size 11^4 over its base + Category of Drinfeld modules over Finite Field in z of size 11^4 """ return f'Category of Drinfeld modules over {self._base_field}' @@ -378,7 +371,7 @@ def base_morphism(self): sage: C.base_morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field of size 11 - To: Finite Field in z of size 11^4 over its base + To: Finite Field in z of size 11^4 Defn: T |--> z^3 + 7*z^2 + 6*z + 10 sage: C.constant_coefficient() == C.base_morphism()(T) @@ -517,7 +510,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 over its base twisted by Frob + Ore Polynomial Ring in t over Finite Field in z of size 11^4 twisted by z |--> z^11 """ return self._ore_polring @@ -615,17 +608,16 @@ def base_morphism(self): sage: phi.base_morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 - To: Finite Field in z12 of size 5^12 over its base + To: Finite Field in z12 of size 5^12 Defn: 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 The base field can be infinite:: sage: sigma = DrinfeldModule(A, [Frac(A).gen(), 1]) sage: sigma.base_morphism() - Ring morphism: + Coercion map: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 - To: Fraction Field of Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 over its base - Defn: T |--> T + To: Fraction Field of Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 """ return self.category().base_morphism() @@ -753,7 +745,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 over its base twisted by Frob^2 + Ore Polynomial Ring in t 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:: @@ -782,7 +774,7 @@ 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 over its base twisted by Frob^2 + Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 twisted by z12 |--> z12^(5^2) sage: phi.ore_variable() t """ 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 d1842813ff1..594f8645ae1 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 @@ -504,7 +504,6 @@ def coefficient_in_function_ring(self, n): """ A = self.function_ring() g = self.coefficient(n) - g = g.backend(force=True) if g.denominator().is_one(): return A(g.numerator().list()) else: @@ -550,7 +549,6 @@ def coefficients_in_function_ring(self, sparse=True): A = self.function_ring() gs = [] for g in self.coefficients(sparse): - g = g.backend(force=True) if g.denominator().is_one(): gs.append(A(g.numerator().list())) else: 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 f65b6753831..6c2f2450118 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -194,7 +194,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): :class:`sage.categories.drinfeld_modules.DrinfeldModules`):: sage: phi.category() - Category of Drinfeld modules over Finite Field in z of size 3^12 over its base + Category of Drinfeld modules over Finite Field in z of size 3^12 sage: phi.category() is psi.category() False sage: phi.category() is rho.category() @@ -219,7 +219,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: phi.base_morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2 - To: Finite Field in z of size 3^12 over its base + To: Finite Field in z of size 3^12 Defn: T |--> z Note that the base field is *not* the field `K`. Rather, it is a @@ -237,14 +237,13 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: phi.base_morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2 - To: Finite Field in z of size 3^12 over its base + To: Finite Field in z of size 3^12 Defn: T |--> z :: sage: phi.ore_polring() # K{t} - Ore Polynomial Ring in t over Finite Field in z of size 3^12 over its base - twisted by Frob^2 + Ore Polynomial Ring in t over Finite Field in z of size 3^12 twisted by z |--> z^(3^2) :: @@ -268,9 +267,8 @@ 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 over its base - twisted by Frob^2 + To: Ore Polynomial Ring in t over Finite Field in z of size 3^12 + twisted by z |--> z^(3^2) Defn: T |--> t^2 + t + z One can compute the rank and height:: @@ -578,13 +576,13 @@ def __classcall_private__(cls, function_ring, gen, name='t'): if isinstance(gen, OrePolynomial): ore_polring = gen.parent() # Base ring without morphism structure: - base_field_noext = ore_polring.base() + base_field = ore_polring.base() name = ore_polring.variable_name() # `gen` is a list of coefficients (function_ring = Fq[T]): elif isinstance(gen, (list, tuple)): ore_polring = None # Base ring without morphism structure: - base_field_noext = Sequence(gen).universe() + base_field = Sequence(gen).universe() else: raise TypeError('generator must be list of coefficients or Ore ' 'polynomial') @@ -592,28 +590,23 @@ def __classcall_private__(cls, function_ring, gen, name='t'): 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_noext, 'has_coerce_map_from') and - base_field_noext.has_coerce_map_from(function_ring.base_ring())): + if not (hasattr(base_field, 'has_coerce_map_from') and + base_field.has_coerce_map_from(function_ring.base_ring())): raise ValueError('function ring base must coerce into base field') # Build the category T = function_ring.gen() - if isinstance(base_field_noext, RingExtension_generic): - base_field = base_field_noext - elif base_field_noext.has_coerce_map_from(function_ring) \ - and T == gen[0]: - base_morphism = base_field_noext.coerce_map_from(function_ring) - base_field = base_field_noext.over(base_morphism) + if base_field.has_coerce_map_from(function_ring) and T == gen[0]: + base_morphism = base_field.coerce_map_from(function_ring) else: - base_morphism = Hom(function_ring, base_field_noext)(gen[0]) - base_field = base_field_noext.over(base_morphism) + base_morphism = Hom(function_ring, base_field)(gen[0]) # This test is also done in the category. We put it here also # to have a friendlier error message if not base_field.is_field(): raise ValueError('generator coefficients must live in a field') - category = DrinfeldModules(base_field, name=name) + category = DrinfeldModules(base_morphism, name=name) # Check gen as Ore polynomial ore_polring = category.ore_polring() # Sanity cast @@ -622,12 +615,11 @@ def __classcall_private__(cls, function_ring, gen, name='t'): raise ValueError('generator must have positive degree') # Instantiate the appropriate class: - backend = base_field.backend(force=True) - if backend.is_finite(): + if base_field.is_finite(): from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite return DrinfeldModule_finite(gen, category) - if isinstance(backend, FractionField_generic): - ring = backend.ring() + if isinstance(base_field, FractionField_generic): + ring = base_field.ring() if (isinstance(ring, PolynomialRing_generic) and ring.base_ring() is function_ring_base and base_morphism(T) == ring.gen()): @@ -1792,7 +1784,7 @@ def morphism(self): 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 - over its base twisted by Frob^2 + 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 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: from sage.rings.morphism import RingHomomorphism diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index a06e0fc5022..beff948f980 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -593,7 +593,7 @@ def _motive_matrix(self): # The next rows: # each row is obtained from the previous one by # applying the semi-linear transformation f |-> t*f - inv = K(phiT[r]).inverse() + inv = ~phiT[r] B = inv * phiT T = KT.gen() for i in range(1, r):