Skip to content

Commit 7f78eda

Browse files
author
Matthias Koeppe
committed
src/sage/groups/galois_group_perm.py: Split out from src/sage/groups/galois_group.py
1 parent 50a6d3c commit 7f78eda

File tree

2 files changed

+197
-174
lines changed

2 files changed

+197
-174
lines changed

src/sage/groups/galois_group.py

Lines changed: 10 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@
1010
- David Roe (2019): initial version
1111
"""
1212

13-
from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic, PermutationGroup_subgroup
1413
from sage.groups.abelian_gps.abelian_group import AbelianGroup_class, AbelianGroup_subgroup
15-
from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
16-
from sage.misc.lazy_attribute import lazy_attribute
1714
from sage.misc.abstract_method import abstract_method
1815
from sage.misc.cachefunc import cached_method
19-
from sage.structure.category_object import normalize_names
16+
from sage.misc.lazy_attribute import lazy_attribute
17+
from sage.misc.lazy_import import lazy_import
2018
from sage.rings.integer_ring import ZZ
2119

20+
lazy_import('sage.groups.galois_group_perm', 'GaloisGroup_perm')
21+
lazy_import('sage.groups.perm_gps.permgroup', 'PermutationGroup')
22+
23+
2224
def _alg_key(self, algorithm=None, recompute=False):
2325
r"""
2426
Return a key for use in cached_method calls.
@@ -40,6 +42,7 @@ def _alg_key(self, algorithm=None, recompute=False):
4042
algorithm = self._get_algorithm(algorithm)
4143
return algorithm
4244

45+
4346
class _GMixin:
4447
r"""
4548
This class provides some methods for Galois groups to be used for both permutation groups
@@ -151,6 +154,7 @@ def _gc_map(self):
151154
"""
152155
return self._gcdata[1]
153156

157+
154158
class _GaloisMixin(_GMixin):
155159
"""
156160
This class provides methods for Galois groups, allowing concrete instances
@@ -275,6 +279,7 @@ def is_galois(self):
275279
"""
276280
return self.order() == self._field_degree
277281

282+
278283
class _SubGaloisMixin(_GMixin):
279284
"""
280285
This class provides methods for subgroups of Galois groups, allowing concrete instances
@@ -339,164 +344,6 @@ def _gcdata(self):
339344
"""
340345
return self._ambient_group._gcdata
341346

342-
class GaloisGroup_perm(_GaloisMixin, PermutationGroup_generic):
343-
r"""
344-
The group of automorphisms of a Galois closure of a given field.
345-
346-
INPUT:
347-
348-
- ``field`` -- a field, separable over its base
349-
350-
- ``names`` -- a string or tuple of length 1, giving a variable name for the splitting field
351-
352-
- ``gc_numbering`` -- boolean, whether to express permutations in terms of the
353-
roots of the defining polynomial of the splitting field (versus the defining polynomial
354-
of the original extension). The default value may vary based on the type of field.
355-
"""
356-
@abstract_method
357-
def transitive_number(self, algorithm=None, recompute=False):
358-
"""
359-
The transitive number (as in the GAP and Magma databases of transitive groups)
360-
for the action on the roots of the defining polynomial of the top field.
361-
362-
EXAMPLES::
363-
364-
sage: R.<x> = ZZ[]
365-
sage: K.<a> = NumberField(x^3 + 2*x + 2) # needs sage.rings.number_field
366-
sage: G = K.galois_group() # needs sage.rings.number_field
367-
sage: G.transitive_number() # needs sage.rings.number_field
368-
2
369-
"""
370-
371-
@lazy_attribute
372-
def _gens(self):
373-
"""
374-
The generators of this Galois group as permutations of the roots. It's important that this
375-
be computed lazily, since it's often possible to compute other attributes (such as the order
376-
or transitive number) more cheaply.
377-
378-
EXAMPLES::
379-
380-
sage: R.<x> = ZZ[]
381-
sage: K.<a> = NumberField(x^5 - 2) # needs sage.rings.number_field
382-
sage: G = K.galois_group(gc_numbering=False) # needs sage.rings.number_field
383-
sage: G._gens # needs sage.rings.number_field
384-
[(1,2,3,5), (1,4,3,2,5)]
385-
"""
386-
return NotImplemented
387-
388-
def __init__(self, field, algorithm=None, names=None, gc_numbering=False):
389-
r"""
390-
EXAMPLES::
391-
392-
sage: R.<x> = ZZ[]
393-
sage: K.<a> = NumberField(x^3 + 2*x + 2) # needs sage.rings.number_field
394-
sage: G = K.galois_group() # needs sage.rings.number_field
395-
sage: TestSuite(G).run() # needs sage.rings.number_field
396-
"""
397-
self._field = field
398-
self._default_algorithm = algorithm
399-
self._base = field.base_field()
400-
self._gc_numbering = gc_numbering
401-
if names is None:
402-
# add a c for Galois closure
403-
names = field.variable_name() + 'c'
404-
self._gc_names = normalize_names(1, names)
405-
# We do only the parts of the initialization of PermutationGroup_generic
406-
# that don't depend on _gens
407-
from sage.categories.permutation_groups import PermutationGroups
408-
category = PermutationGroups().FinitelyGenerated().Finite()
409-
# Note that we DON'T call the __init__ method for PermutationGroup_generic
410-
# Instead, the relevant attributes are computed lazily
411-
super(PermutationGroup_generic, self).__init__(category=category)
412-
413-
@lazy_attribute
414-
def _deg(self):
415-
r"""
416-
The number of moved points in the permutation representation.
417-
418-
This will be the degree of the original number field if `_gc_numbering``
419-
is ``False``, or the degree of the Galois closure otherwise.
420-
421-
EXAMPLES::
422-
423-
sage: # needs sage.rings.number_field
424-
sage: R.<x> = ZZ[]
425-
sage: K.<a> = NumberField(x^5 - 2)
426-
sage: G = K.galois_group(gc_numbering=False); G
427-
Galois group 5T3 (5:4) with order 20 of x^5 - 2
428-
sage: G._deg
429-
5
430-
sage: G = K.galois_group(gc_numbering=True); G._deg
431-
20
432-
"""
433-
if self._gc_numbering:
434-
return self.order()
435-
else:
436-
try:
437-
return self._field.degree()
438-
except NotImplementedError: # relative number fields don't support degree
439-
return self._field.relative_degree()
440-
441-
@lazy_attribute
442-
def _domain(self):
443-
r"""
444-
The integers labeling the roots on which this Galois group acts.
445-
446-
EXAMPLES::
447-
448-
sage: # needs sage.rings.number_field
449-
sage: R.<x> = ZZ[]
450-
sage: K.<a> = NumberField(x^5 - 2)
451-
sage: G = K.galois_group(gc_numbering=False); G
452-
Galois group 5T3 (5:4) with order 20 of x^5 - 2
453-
sage: G._domain
454-
{1, 2, 3, 4, 5}
455-
sage: G = K.galois_group(gc_numbering=True); G._domain
456-
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
457-
"""
458-
return FiniteEnumeratedSet(range(1, self._deg+1))
459-
460-
@lazy_attribute
461-
def _domain_to_gap(self):
462-
r"""
463-
Dictionary implementing the identity (used by PermutationGroup_generic).
464-
465-
EXAMPLES::
466-
467-
sage: R.<x> = ZZ[]
468-
sage: K.<a> = NumberField(x^5 - 2) # needs sage.rings.number_field
469-
sage: G = K.galois_group(gc_numbering=False) # needs sage.rings.number_field
470-
sage: G._domain_to_gap[5] # needs sage.rings.number_field
471-
5
472-
"""
473-
return {key: i+1 for i, key in enumerate(self._domain)}
474-
475-
@lazy_attribute
476-
def _domain_from_gap(self):
477-
r"""
478-
Dictionary implementing the identity (used by PermutationGroup_generic).
479-
480-
EXAMPLES::
481-
482-
sage: R.<x> = ZZ[]
483-
sage: K.<a> = NumberField(x^5 - 2) # needs sage.rings.number_field
484-
sage: G = K.galois_group(gc_numbering=True) # needs sage.rings.number_field
485-
sage: G._domain_from_gap[20] # needs sage.rings.number_field
486-
20
487-
"""
488-
return {i+1: key for i, key in enumerate(self._domain)}
489-
490-
def ngens(self):
491-
r"""
492-
Number of generators of this Galois group
493-
494-
EXAMPLES::
495-
496-
sage: QuadraticField(-23, 'a').galois_group().ngens() # needs sage.rings.number_field
497-
1
498-
"""
499-
return len(self._gens)
500347

501348
class GaloisGroup_ab(_GaloisMixin, AbelianGroup_class):
502349
r"""
@@ -573,6 +420,7 @@ def transitive_number(self, algorithm=None, recompute=False):
573420
"""
574421
return ZZ(self.permutation_group()._gap_().TransitiveIdentification())
575422

423+
576424
class GaloisGroup_cyc(GaloisGroup_ab):
577425
r"""
578426
Cyclic Galois groups
@@ -614,17 +462,6 @@ def signature(self):
614462
"""
615463
return ZZ(1) if (self._field.degree() % 2) else ZZ(-1)
616464

617-
class GaloisSubgroup_perm(PermutationGroup_subgroup, _SubGaloisMixin):
618-
"""
619-
Subgroups of Galois groups (implemented as permutation groups), specified
620-
by giving a list of generators.
621-
622-
Unlike ambient Galois groups, where we use a lazy ``_gens`` attribute in order
623-
to enable creation without determining a list of generators,
624-
we require that generators for a subgroup be specified during initialization,
625-
as specified in the ``__init__`` method of permutation subgroups.
626-
"""
627-
pass
628465

629466
class GaloisSubgroup_ab(AbelianGroup_subgroup, _SubGaloisMixin):
630467
"""
@@ -633,5 +470,4 @@ class GaloisSubgroup_ab(AbelianGroup_subgroup, _SubGaloisMixin):
633470
pass
634471

635472

636-
GaloisGroup_perm.Subgroup = GaloisSubgroup_perm
637473
GaloisGroup_ab.Subgroup = GaloisSubgroup_ab

0 commit comments

Comments
 (0)