diff --git a/src/sage/combinat/matrices/latin.py b/src/sage/combinat/matrices/latin.py index 1a369bba355..53790970c0b 100644 --- a/src/sage/combinat/matrices/latin.py +++ b/src/sage/combinat/matrices/latin.py @@ -2496,7 +2496,7 @@ def check_bitrade_generators(a, b, c): sage: a, b, c, G = p3_group_bitrade_generators(3) sage: check_bitrade_generators(a, b, c) True - sage: check_bitrade_generators(a, b, gap('()')) + sage: check_bitrade_generators(a, b, libgap(gap('()'))) False """ A = PermutationGroup([a]) diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 3ed9a0a43fd..f1885ad164b 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -708,7 +708,7 @@ def _gap_(self, gap): sage: gap(Permutation((1,2,3))) # needs sage.libs.gap (1,2,3) sage: type(_) # needs sage.libs.gap - + """ return self.to_permutation_group_element()._gap_(gap) diff --git a/src/sage/groups/class_function.py b/src/sage/groups/class_function.py index c788a596809..e390cbbf288 100644 --- a/src/sage/groups/class_function.py +++ b/src/sage/groups/class_function.py @@ -17,12 +17,12 @@ - Volker Braun (October 2010): Bugfixes, exterior and symmetric power. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Franco Saliola # # Distributed under the terms of the GNU General Public License (GPL) # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.structure.sage_object import SageObject from sage.structure.richcmp import richcmp, richcmp_method @@ -66,24 +66,26 @@ class function on the conjugacy classes, in that order. sage: chi = ClassFunction(G, values); chi Character of Cyclic group of order 4 as a permutation group """ + from sage.misc.superseded import deprecation try: return group.class_function(values) except AttributeError: pass - if isinstance(values, LibGapElement): + if isinstance(values, (LibGapElement, tuple, list)): return ClassFunction_libgap(group, values) + # deprecation(36889, "please use libgap class functions instead") return ClassFunction_gap(group, values) ##################################################################### -### -### GAP Interface-based Class Function -### -### This is old code that should be deleted once we have transitioned -### everything to using the library interface to GAP. -### +# +# GAP Interface-based Class Function +# +# This is old code that should be deleted once we have transitioned +# everything to using the library interface to GAP. +# ##################################################################### @richcmp_method @@ -130,13 +132,13 @@ def __init__(self, G, values): def _gap_init_(self): r""" - Returns a string showing how to declare / initialize self in Gap. + Return a string showing how to declare / initialize self in Gap. Stored in the \code{self._gap_string} attribute. EXAMPLES:: sage: G = CyclicPermutationGroup(4) - sage: values = [1, -1, 1, -1] + sage: values = gap([1, -1, 1, -1]) sage: ClassFunction(G, values)._gap_init_() 'ClassFunction( CharacterTable( Group( [ (1,2,3,4) ] ) ), [ 1, -1, 1, -1 ] )' """ @@ -149,7 +151,7 @@ def _gap_(self, *args): EXAMPLES:: sage: G = CyclicPermutationGroup(4) - sage: values = [1, -1, 1, -1] + sage: values = gap([1, -1, 1, -1]) sage: chi = ClassFunction(G, values); chi Character of Cyclic group of order 4 as a permutation group sage: type(_) @@ -173,7 +175,7 @@ def __repr__(self): sage: G = SymmetricGroup(4) sage: values = [1, -1, 1, 1, -1] - sage: ClassFunction(G, values) + sage: ClassFunction(G, gap(values)) Character of Symmetric group of order 4! as a permutation group """ return "Character of %s" % repr(self._group) @@ -185,7 +187,7 @@ def __iter__(self): EXAMPLES:: - sage: xi = ClassFunction(SymmetricGroup(4), [1, -1, 1, 1, -1]) + sage: xi = ClassFunction(SymmetricGroup(4), gap([1, -1, 1, 1, -1])) sage: list(xi) [1, -1, 1, 1, -1] """ @@ -239,7 +241,7 @@ def __reduce__(self): EXAMPLES:: sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]]) - sage: chi = ClassFunction(G, [1, 1, 1, 1, 1, 1, 1]) + sage: chi = ClassFunction(G, gap([1, 1, 1, 1, 1, 1, 1])) sage: type(chi) sage: loads(dumps(chi)) == chi @@ -249,7 +251,7 @@ def __reduce__(self): def domain(self): r""" - Returns the domain of the self. + Return the domain of the ``self``. OUTPUT: @@ -294,7 +296,7 @@ def __call__(self, g): def __add__(self, other): r""" - Returns the sum of the characters self and other. + Return the sum of the characters self and other. INPUT: @@ -307,7 +309,7 @@ def __add__(self, other): EXAMPLES:: - sage: chi = ClassFunction(SymmetricGroup(4), [3, 1, -1, 0, -1]) + sage: chi = ClassFunction(SymmetricGroup(4), gap([3, 1, -1, 0, -1])) sage: s = chi+chi sage: s Character of Symmetric group of order 4! as a permutation group @@ -321,7 +323,7 @@ def __add__(self, other): def __sub__(self, other): r""" - Returns the difference of the characters ``self`` and ``other``. + Return the difference of the characters ``self`` and ``other``. INPUT: @@ -366,7 +368,7 @@ def __mul__(self, other): EXAMPLES:: sage: G = SymmetricGroup(4) - sage: chi1 = ClassFunction(G, [3, 1, -1, 0, -1]) + sage: chi1 = ClassFunction(G, gap([3, 1, -1, 0, -1])) sage: 3*chi1 Character of Symmetric group of order 4! as a permutation group sage: 3*chi1 == chi1+chi1+chi1 @@ -384,7 +386,7 @@ def __mul__(self, other): sage: (zeta3 * chi1).values() [3*zeta3, zeta3, -zeta3, 0, -zeta3] - sage: chi2 = ClassFunction(G, [1, -1, 1, 1, -1]) + sage: chi2 = ClassFunction(G, gap([1, -1, 1, 1, -1])) sage: p = chi1*chi2 sage: p Character of Symmetric group of order 4! as a permutation group @@ -456,7 +458,7 @@ def __neg__(self): def __pow__(self, other): r""" - Returns the product of self with itself other times. + Return the product of self with itself other times. EXAMPLES:: @@ -467,13 +469,13 @@ def __pow__(self, other): sage: p.values() [27, 1, -1, 0, -1] """ - if not isinstance(other, (int,Integer)): + if not isinstance(other, (int, Integer)): raise NotImplementedError return ClassFunction(self._group, self._gap_classfunction ** other) def symmetric_power(self, n): r""" - Returns the symmetrized product of self with itself ``n`` times. + Return the symmetrized product of self with itself ``n`` times. INPUT: @@ -486,7 +488,7 @@ def symmetric_power(self, n): EXAMPLES:: - sage: chi = ClassFunction(SymmetricGroup(4), [3, 1, -1, 0, -1]) + sage: chi = ClassFunction(SymmetricGroup(4), gap([3, 1, -1, 0, -1])) sage: p = chi.symmetric_power(3) sage: p Character of Symmetric group of order 4! as a permutation group @@ -495,11 +497,11 @@ def symmetric_power(self, n): """ n = Integer(n) tbl = gap.UnderlyingCharacterTable(self) - return ClassFunction(self._group, gap.SymmetricParts(tbl,[self],n)[1]) + return ClassFunction(self._group, gap.SymmetricParts(tbl, [self], n)[1]) def exterior_power(self, n): r""" - Returns the anti-symmetrized product of self with itself ``n`` times. + Return the anti-symmetrized product of self with itself ``n`` times. INPUT: @@ -512,7 +514,7 @@ def exterior_power(self, n): EXAMPLES:: - sage: chi = ClassFunction(SymmetricGroup(4), [3, 1, -1, 0, -1]) + sage: chi = ClassFunction(SymmetricGroup(4), gap([3, 1, -1, 0, -1])) sage: p = chi.exterior_power(3) # the highest anti-symmetric power for a 3-d character sage: p Character of Symmetric group of order 4! as a permutation group @@ -523,11 +525,11 @@ def exterior_power(self, n): """ n = Integer(n) tbl = gap.UnderlyingCharacterTable(self) - return ClassFunction(self._group, gap.AntiSymmetricParts(tbl,[self],n)[1]) + return ClassFunction(self._group, gap.AntiSymmetricParts(tbl, [self], n)[1]) def scalar_product(self, other): r""" - Returns the scalar product of self with other. + Return the scalar product of self with other. EXAMPLES:: @@ -544,7 +546,7 @@ def scalar_product(self, other): def is_irreducible(self): r""" - Returns True if self cannot be written as the sum of two nonzero + Return True if self cannot be written as the sum of two nonzero characters of self. EXAMPLES:: @@ -558,7 +560,7 @@ def is_irreducible(self): def degree(self): r""" - Returns the degree of the character self. + Return the degree of the character self. EXAMPLES:: @@ -571,7 +573,7 @@ def degree(self): def irreducible_constituents(self): r""" - Returns a list of the characters that appear in the decomposition + Return a list of the characters that appear in the decomposition of chi. EXAMPLES:: @@ -694,7 +696,7 @@ def tensor_product(self, other): sage: chi1.tensor_product(chi3).values() [1, -1, 1] """ - return ClassFunction(self._group, gap.Tensored([self],[other])[1]) + return ClassFunction(self._group, gap.Tensored([self], [other])[1]) def restrict(self, H): r""" @@ -791,9 +793,9 @@ def adams_operation(self, k): ##################################################################### -### -### Class function using the GAP library -### +# +# Class function using the GAP library +# ##################################################################### @@ -834,12 +836,11 @@ def __init__(self, G, values): if isinstance(values, LibGapElement) and values.IsClassFunction(): self._gap_classfunction = values else: - self._gap_classfunction = libgap.ClassFunction(G._libgap_(), - list(values)) + self._gap_classfunction = libgap.ClassFunction(G, list(values)) e = self._gap_classfunction.Conductor().sage() self._base_ring = CyclotomicField(e) - def gap(self): + def _libgap_(self): r""" Return the underlying LibGAP element. @@ -850,15 +851,15 @@ def gap(self): sage: chi = ClassFunction(G, values); chi Character of Cyclic group of order 4 as a permutation group sage: type(chi) - - sage: gap(chi) - ClassFunction( CharacterTable( Group( [ (1,2,3,4) ] ) ), [ 1, -1, 1, -1 ] ) + + sage: libgap(chi) + ClassFunction( CharacterTable( Group([ (1,2,3,4) ]) ), [ 1, -1, 1, -1 ] ) sage: type(_) - + """ return self._gap_classfunction - _libgap_ = _gap_ = gap + gap = _gap_ = _libgap_ def _repr_(self): r""" @@ -877,6 +878,16 @@ def _repr_(self): """ return "Character of %s" % repr(self._group) + def __hash__(self): + r""" + TESTS:: + + sage: G = SymmetricGroup(5) + sage: chi1 = ClassFunction(G,[1,1,1,1,1,1,1]) + sage: d = {chi1:'trivial'} + """ + return hash((self._group, tuple(self))) + def __iter__(self): r""" Iterate through the values. @@ -1162,7 +1173,7 @@ def __pow__(self, other): sage: p.values() [27, 1, -1, 0, -1] """ - if not isinstance(other, (int,Integer)): + if not isinstance(other, (int, Integer)): raise NotImplementedError return ClassFunction(self._group, self._gap_classfunction ** other) @@ -1189,8 +1200,8 @@ def symmetric_power(self, n): [10, 2, -2, 1, 0] """ n = Integer(n) - tbl = self._gap_classfunction.UnderlyingCharacterTable(self) - return ClassFunction(self._group, tbl.SymmetricParts([self],n)[1]) + tbl = self._gap_classfunction.UnderlyingCharacterTable() + return ClassFunction(self._group, tbl.SymmetricParts([self], n)[0]) def exterior_power(self, n): r""" @@ -1217,8 +1228,8 @@ def exterior_power(self, n): True """ n = Integer(n) - tbl = self._gap_classfunction.UnderlyingCharacterTable(self) - return ClassFunction(self._group, tbl.AntiSymmetricParts([self],n)[1]) + tbl = self._gap_classfunction.UnderlyingCharacterTable() + return ClassFunction(self._group, tbl.AntiSymmetricParts([self], n)[0]) def scalar_product(self, other): r""" diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index a459451bd6d..493ff9bb8ea 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -410,7 +410,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): sage: k._gap_() (1,2)(3,5,6) sage: k._gap_().parent() - Gap + C library interface to GAP List notation:: @@ -835,13 +835,11 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): sage: g._gap_() (1,2,3)(4,5) """ - if gap is None: - from sage.interfaces.gap import gap - return gap(self._gap_init_()) + return self._libgap_() def _libgap_(self): r""" - Returns self as a libgap element + Return ``self`` as a libgap element. EXAMPLES:: @@ -867,7 +865,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): sage: p_libgap == p_pexpect True sage: type(p_libgap) == type(p_pexpect) - False + True If the permutation element is built from a libgap element, it is cached and returned by this function:: diff --git a/src/sage/groups/perm_gps/permgroup_morphism.py b/src/sage/groups/perm_gps/permgroup_morphism.py index 0a86068790b..c453934141a 100644 --- a/src/sage/groups/perm_gps/permgroup_morphism.py +++ b/src/sage/groups/perm_gps/permgroup_morphism.py @@ -84,7 +84,7 @@ def kernel(self): sage: G.is_isomorphic(pr1.kernel()) True """ - return self.domain().subgroup(gap_group=self._gap_().Kernel()) + return self.domain().subgroup(gap_group=self._libgap_().Kernel()) def image(self, J): r""" @@ -133,10 +133,10 @@ def image(self, J): H = self.codomain() if J in self.domain(): J = PermutationGroup([J]) - G = self._gap_().Image(J) + G = self._libgap_().Image(J) return H.subgroup(gap_group=G).gens()[0] else: - G = self._gap_().Image(J) + G = self._libgap_().Image(J) return H.subgroup(gap_group=G) def __call__(self, g): @@ -210,7 +210,7 @@ def _repr_defn(self): """ return str(self._gap_hom).replace('\n', '') - def _gap_(self, gap=None): + def _libgap_(self): r""" Return a GAP version of this morphism. @@ -220,7 +220,7 @@ def _gap_(self, gap=None): sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]]) sage: H = G.subgroup([G([(1,2,3,4)])]) sage: phi = PermutationGroupMorphism_from_gap(H, G, gap.Identity) - sage: phi._gap_() + sage: phi._libgap_() Identity """ return self._gap_hom @@ -239,7 +239,7 @@ def __call__(self, g): sage: [pr1(g) for g in G.gens()] [(3,7,5)(4,8,6), (1,2,6)(3,4,8)] """ - return self.codomain()(self._gap_().Image(g)) + return self.codomain()(self._libgap_().Image(g)) class PermutationGroupMorphism_im_gens(PermutationGroupMorphism): @@ -295,7 +295,7 @@ def _repr_defn(self): """ return "%s -> %s" % (list(self.domain().gens()), self._images) - def _gap_(self): + def _libgap_(self): r""" Return a GAP representation of this morphism. @@ -304,11 +304,10 @@ def _gap_(self): sage: G = CyclicPermutationGroup(4) sage: H = DihedralGroup(4) sage: phi = PermutationGroupMorphism_im_gens(G, H, map(H, G.gens())) - sage: phi._gap_() - GroupHomomorphismByImages( Group( [ (1,2,3,4) ] ), Group( - [ (1,2,3,4), (1,4)(2,3) ] ), [ (1,2,3,4) ], [ (1,2,3,4) ] ) + sage: phi._libgap_() + [ (1,2,3,4) ] -> [ (1,2,3,4) ] """ - return self.domain()._gap_().GroupHomomorphismByImages(self.codomain(), self.domain().gens(), self._images) + return self.domain()._libgap_().GroupHomomorphismByImages(self.codomain(), self.domain().gens(), self._images) def is_PermutationGroupMorphism(f) -> bool: diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index e522bf5bc03..58bbe8922d9 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -380,7 +380,7 @@ cdef GapElement make_GapElement(parent, Obj obj) noexcept: sage: libgap(None) Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute '_libgap_init_'... + AttributeError: 'NoneType' object has no attribute '_gap_init_'... """ cdef GapElement r = GapElement.__new__(GapElement) r._initialize(parent, obj) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 63400adab4c..17a7aca9003 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -319,7 +319,7 @@ class Gap(Parent): return x._libgap_() except AttributeError: pass - x = str(x._libgap_init_()) + x = str(x._gap_init_()) return make_any_gap_element(self, gap_eval(x)) def _construct_matrix(self, M): @@ -400,7 +400,7 @@ class Gap(Parent): cdef GapElement elem if not isinstance(gap_command, str): - gap_command = str(gap_command._libgap_init_()) + gap_command = str(gap_command._gap_init_()) initialize() elem = make_any_gap_element(self, gap_eval(gap_command)) diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 3408e8abf0b..edcd603185f 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -22,6 +22,7 @@ from sage.categories.finite_dimensional_modules_with_basis import FiniteDimensionalModulesWithBasis from sage.sets.family import Family from sage.matrix.constructor import Matrix +from sage.libs.gap.libgap import libgap class FiniteDimensionalInvariantModule(SubmoduleWithBasis): @@ -801,25 +802,22 @@ def __classcall_private__(cls, M, G, chi, Check the :class:`ValueError`:: - sage: from sage.groups.class_function import ClassFunction_libgap - sage: chi = ClassFunction_libgap(G, chi) - sage: T = M.twisted_invariant_module(G, chi, action_on_basis=action) + sage: T = M.twisted_invariant_module(G, "ichigo", action_on_basis=action) Traceback (most recent call last): ... ValueError: chi must be a list/tuple or a class function of the group G """ + from sage.groups.class_function import ClassFunction, ClassFunction_libgap - from sage.groups.class_function import ClassFunction, ClassFunction_gap - - if isinstance(chi,(list,tuple)): - chi = ClassFunction(G, chi) - elif not isinstance(chi, ClassFunction_gap): + if isinstance(chi, (list, tuple)): + chi = ClassFunction(G, libgap(chi)) + elif not isinstance(chi, ClassFunction_libgap): raise ValueError("chi must be a list/tuple or a class function of the group G") try: - is_trivial = all(chi(conj.an_element()) == 1 for conj in G.conjugacy_classes()) - except AttributeError: # to handle ReflectionGroups - is_trivial = all(chi(G(list(conj)[0])) == 1 for conj in G.conjugacy_classes().values()) + is_trivial = all(chi(next(iter(conj))) == 1 for conj in G.conjugacy_classes()) + except AttributeError: # to handle ReflectionGroups + is_trivial = all(chi(G(next(iter(conj)))) == 1 for conj in G.conjugacy_classes()) if is_trivial: action_on_basis = kwargs.pop('action_on_basis', None) diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 10000aef394..39a5487226f 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -755,14 +755,7 @@ cdef class SageObject: def _libgap_(self): from sage.libs.gap.libgap import libgap - return libgap.eval(self._libgap_init_()) - - def _libgap_init_(self): - """ - For consistency's sake we provide a ``_libgap_init_`` but in most cases - we can use the same as ``_gap_init_`` here. - """ - return self._gap_init_() + return libgap.eval(self._gap_init_()) def _gp_(self, G=None): if G is None: diff --git a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py index 29b25d1efde..abff8d3189c 100644 --- a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py +++ b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py @@ -155,8 +155,8 @@ sage: tau.kernel() Traceback (most recent call last): ... - RuntimeError: Gap produced error output - ... + sage.libs.gap.util.GAPError: Error, no method found! Error, no 1st choice method found for `Kernel' on 1 arguments + The 1st argument is 'fail' which might point to an earlier problem ~~~~~~~~~~~~~~~~~~~~~~ ::