27
27
from sage .categories .drinfeld_modules import DrinfeldModules
28
28
from sage .categories .homset import Hom
29
29
from sage .misc .latex import latex
30
+ from sage .misc .latex import latex_variable_name
31
+ from sage .misc .lazy_string import _LazyString
30
32
from sage .rings .integer import Integer
31
33
from sage .rings .polynomial .ore_polynomial_element import OrePolynomial
32
34
from sage .rings .polynomial .polynomial_ring import PolynomialRing_general
33
35
from sage .rings .ring_extension import RingExtension_generic
34
36
from sage .structure .parent import Parent
37
+ from sage .structure .sage_object import SageObject
35
38
from sage .structure .sequence import Sequence
36
39
from sage .structure .unique_representation import UniqueRepresentation
37
40
@@ -172,20 +175,13 @@ class DrinfeldModule(Parent, UniqueRepresentation):
172
175
sage: phi(1) # phi_1
173
176
1
174
177
175
- One can give a LaTeX name to be used for LaTeX representation::
176
-
177
- sage: sigma = DrinfeldModule(A, [z, 1, 1], latexname='\sigma')
178
- ...
179
- sage: latex(sigma)
180
- \sigma
181
-
182
178
.. RUBRIC:: The category of Drinfeld modules
183
179
184
180
Drinfeld modules have their own category (see class
185
181
:class:`sage.categories.drinfeld_modules.DrinfeldModules`)::
186
182
187
183
sage: phi.category()
188
- Category of Drinfeld modules defined over Finite Field in z of size 3^12 over its base
184
+ Category of Drinfeld modules over Finite Field in z of size 3^12 over its base
189
185
sage: phi.category() is psi.category()
190
186
False
191
187
sage: phi.category() is rho.category()
@@ -271,10 +267,10 @@ class DrinfeldModule(Parent, UniqueRepresentation):
271
267
sage: phi.j_invariant() # j-invariant
272
268
1
273
269
274
- A Drinfeld `\mathbb{F}_q[T]`-module can be seen as an Ore
275
- polynomial with positive degree and constant coefficient
276
- `\gamma(T)`, where `\gamma` is the base morphism. This analogy is
277
- the motivation for the following methods::
270
+ A Drinfeld `\mathbb{F}_q[T]`-module can be seen as an Ore polynomial
271
+ with positive degree and constant coefficient `\gamma(T)`, where
272
+ `\gamma` is the base morphism. This analogy is the motivation for
273
+ the following methods::
278
274
279
275
sage: phi.coefficients()
280
276
[z, 1, 1]
@@ -316,20 +312,13 @@ class DrinfeldModule(Parent, UniqueRepresentation):
316
312
sage: identity_morphism = hom(1)
317
313
sage: zero_morphism = hom(0)
318
314
sage: frobenius_endomorphism
319
- Drinfeld Module morphism:
320
- From (gen): t^2 + t + z
321
- To (gen): t^2 + t + z
322
- Defn: t^6
315
+ Endomorphism of Drinfeld module defined by T |--> t^2 + t + z
316
+ Defn: t^6
323
317
sage: identity_morphism
324
- Drinfeld Module morphism:
325
- From (gen): t^2 + t + z
326
- To (gen): t^2 + t + z
327
- Defn: 1
318
+ Identity morphism of Drinfeld module defined by T |--> t^2 + t + z
328
319
sage: zero_morphism
329
- Drinfeld Module morphism:
330
- From (gen): t^2 + t + z
331
- To (gen): t^2 + t + z
332
- Defn: 0
320
+ Endomorphism of Drinfeld module defined by T |--> t^2 + t + z
321
+ Defn: 0
333
322
334
323
The underlying Ore polynomial is retrieved with the method
335
324
:meth:`ore_polynomial`::
@@ -512,7 +501,7 @@ class DrinfeldModule(Parent, UniqueRepresentation):
512
501
"""
513
502
514
503
@staticmethod
515
- def __classcall_private__ (cls , function_ring , gen , name = 't' , latexname = None ):
504
+ def __classcall_private__ (cls , function_ring , gen , name = 't' ):
516
505
"""
517
506
Check input validity and return a ``DrinfeldModule`` or
518
507
``FiniteDrinfeldModule`` object accordingly.
@@ -528,9 +517,6 @@ def __classcall_private__(cls, function_ring, gen, name='t', latexname=None):
528
517
- ``name`` (default: ``'t'``) -- the name of the Ore polynomial
529
518
ring gen
530
519
531
- - ``latexname`` (default: ``None``) -- the LaTeX name of the Drinfeld
532
- module
533
-
534
520
OUTPUT:
535
521
536
522
A DrinfeldModule or FiniteDrinfeldModule.
@@ -591,10 +577,6 @@ def __classcall_private__(cls, function_ring, gen, name='t', latexname=None):
591
577
base_field_noext .has_coerce_map_from (function_ring .base_ring ())):
592
578
raise ValueError ('function ring base must coerce into base field' )
593
579
594
- # Check LaTeX name
595
- if latexname is not None and type (latexname ) is not str :
596
- raise ValueError ('LaTeX name should be a string' )
597
-
598
580
# Build the category
599
581
T = function_ring .gen ()
600
582
if isinstance (base_field_noext , RingExtension_generic ):
@@ -607,6 +589,11 @@ def __classcall_private__(cls, function_ring, gen, name='t', latexname=None):
607
589
base_morphism = Hom (function_ring , base_field_noext )(gen [0 ])
608
590
base_field = base_field_noext .over (base_morphism )
609
591
592
+ # This test is also done in the category. We put it here also
593
+ # to have a friendlier error message
594
+ if not base_field .is_field ():
595
+ raise ValueError ('generator coefficients must live in a field' )
596
+
610
597
category = DrinfeldModules (base_field , name = name )
611
598
612
599
# Check gen as Ore polynomial
@@ -618,10 +605,10 @@ def __classcall_private__(cls, function_ring, gen, name='t', latexname=None):
618
605
# Instantiate the appropriate class
619
606
if base_field .is_finite ():
620
607
from sage .rings .function_field .drinfeld_modules .finite_drinfeld_module import FiniteDrinfeldModule
621
- return FiniteDrinfeldModule (gen , category , latexname )
622
- return cls .__classcall__ (cls , gen , category , latexname )
608
+ return FiniteDrinfeldModule (gen , category )
609
+ return cls .__classcall__ (cls , gen , category )
623
610
624
- def __init__ (self , gen , category , latexname = None ):
611
+ def __init__ (self , gen , category ):
625
612
"""
626
613
Initialize ``self``.
627
614
@@ -639,9 +626,6 @@ def __init__(self, gen, category, latexname=None):
639
626
- ``name`` (default: ``'t'``) -- the name of the Ore polynomial
640
627
ring gen
641
628
642
- - ``latexname`` (default: ``None``) -- the LaTeX name of the Drinfeld
643
- module
644
-
645
629
TESTS::
646
630
647
631
sage: Fq = GF(25)
@@ -661,13 +645,14 @@ def __init__(self, gen, category, latexname=None):
661
645
True
662
646
sage: phi._morphism == Hom(A, ore_polring)(phi._gen)
663
647
True
664
- sage: phi._latexname is None
665
- True
648
+
649
+ ::
650
+
651
+ sage: TestSuite(phi).run()
666
652
"""
667
653
self ._base = category .base ()
668
654
self ._function_ring = category .function_ring ()
669
655
self ._gen = gen
670
- self ._latexname = latexname
671
656
self ._morphism = category ._function_ring .hom ([gen ])
672
657
self ._ore_polring = gen .parent ()
673
658
self ._Fq = self ._function_ring .base_ring () # Must be last
@@ -777,8 +762,8 @@ def _latex_(self):
777
762
r"""
778
763
Return a LaTeX representation of the Drinfeld module.
779
764
780
- If a LaTeX name was given at initialization, we use it.
781
- Otherwise, we create a representation.
765
+ If a representation name is given with meth:`rename`, it is
766
+ taken into account for LaTeX representation.
782
767
783
768
EXAMPLES::
784
769
@@ -788,29 +773,20 @@ def _latex_(self):
788
773
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
789
774
sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
790
775
sage: latex(phi)
791
- \text{Drinfeld{ }module{ }defined{ }by{ }} 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}\text{{ }over{ }base{ }}\Bold{F}_{5^{12} }
776
+ \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}
792
777
793
778
::
794
779
795
- sage: psi = DrinfeldModule(A, [p_root, z12^3, z12^5], latexname='\psi')
796
- ...
797
- sage: latex(psi)
798
- \psi
799
-
800
- ::
801
-
802
- sage: psi = DrinfeldModule(A, [p_root, z12^3, z12^5], latexname=1729)
803
- Traceback (most recent call last):
804
- ...
805
- ValueError: LaTeX name should be a string
780
+ sage: phi.rename('phi')
781
+ sage: latex(phi)
782
+ \phi
783
+ sage: phi.reset_name()
806
784
"""
807
- if self . _latexname is not None :
808
- return self . _latexname
785
+ if hasattr ( self , '__custom_name' ) :
786
+ return latex_variable_name ( getattr ( self , '__custom_name' ))
809
787
else :
810
- return f'\\ text{{Drinfeld{{ }}module{{ }}defined{{ }}by{{ }}}} ' \
811
- f'{ latex (self ._function_ring .gen ())} ' \
812
- f'\\ mapsto { latex (self ._gen )} ' \
813
- f'\\ text{{{{ }}over{{ }}base{{ }}}}{ latex (self ._base )} '
788
+ return f'\\ phi: { latex (self ._function_ring .gen ())} \\ mapsto ' \
789
+ f'{ latex (self ._gen )} '
814
790
815
791
def _repr_ (self ):
816
792
r"""
@@ -829,6 +805,49 @@ def _repr_(self):
829
805
return f'Drinfeld module defined by { self ._function_ring .gen ()} ' \
830
806
f'|--> { self ._gen } '
831
807
808
+ def _test_category (self , ** options ):
809
+ """
810
+ Run generic tests on the method :meth:`.category`.
811
+
812
+ EXAMPLES::
813
+
814
+ sage: Fq = GF(25)
815
+ sage: A.<T> = Fq[]
816
+ sage: K.<z12> = Fq.extension(6)
817
+ 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
818
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
819
+ sage: phi._test_category()
820
+
821
+ .. NOTE::
822
+
823
+ We reimplemented this method because Drinfeld modules are
824
+ parents, and
825
+ meth:`sage.structure.parent.Parent._test_category` requires
826
+ parents' categories to be subcategories of ``Sets()``.
827
+ """
828
+ tester = self ._tester (** options )
829
+ SageObject ._test_category (self , tester = tester )
830
+ category = self .category ()
831
+ # Tests that self inherits methods from the categories
832
+ tester .assertTrue (isinstance (self , category .parent_class ),
833
+ _LazyString ("category of %s improperly initialized" , (self ,), {}))
834
+
835
+ def __hash__ (self ):
836
+ r"""
837
+ Return a hash of ``self``.
838
+
839
+ EXAMPLES::
840
+
841
+ sage: Fq = GF(25)
842
+ sage: A.<T> = Fq[]
843
+ sage: K.<z12> = Fq.extension(6)
844
+ 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
845
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
846
+ sage: hash(phi) # random
847
+ -6894299335185957188
848
+ """
849
+ return hash ((self .base (), self ._gen ))
850
+
832
851
def action (self ):
833
852
r"""
834
853
Return the action object
0 commit comments