Skip to content

Commit

Permalink
Trac #25609: have libgap permutation to sage use permutation instead …
Browse files Browse the repository at this point in the history
…of permutation group element

This is a side improvement of #25477, as seen there in comment 62
(please properly link if possible):

{{{
sage: P = PermutationGroup([(1,2),(1,2,3,4,5,6,7,8)])
sage: l = [8,7,6,5,4,3,2,1]
sage: %timeit P(l, check=False)
The slowest run took 7.58 times longer than the fastest. This could mean
that an intermediate result is being cached.
10000 loops, best of 3: 44.3 µs per loop
sage: %timeit Permutation(l, check_input=False)
The slowest run took 7.85 times longer than the fastest. This could mean
that an intermediate result is being cached.
100000 loops, best of 3: 6.74 µs per loop
}}}

So creating a new permutation is much faster than creating a permutation
group element. If we know which permutation group we live in, there is
even a faster way:
{{{
sage: one = P.one()
sage: %timeit one._generate_new(l)
The slowest run took 128.70 times longer than the fastest. This could
mean that an intermediate result is being cached.
1000000 loops, best of 3: 241 ns per loop
}}}

URL: https://trac.sagemath.org/25609
Reported by: stumpc5
Ticket author(s): Christian Stump
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager authored and vbraun committed Oct 23, 2018
2 parents 0fc1b41 + 2396cf0 commit 2eebc67
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/sage/groups/perm_gps/partn_ref2/refinement_generic.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from sage.groups.perm_gps.partn_ref.data_structures cimport OrbitPartition, PartitionStack
from sage.libs.gap.element cimport GapElement, GapElement_Permutation
from sage.structure.parent cimport Parent

cdef extern from "refinement_generic.h":
cdef long *global_refine_vals_array
Expand All @@ -35,6 +36,7 @@ cdef class LabelledBranching:
cdef int *father
cdef int *act_perm
cpdef GapElement group, ClosureGroup
cdef Parent sym_gp
cdef bint has_empty_intersection(self, PartitionStack * part)
cpdef add_gen(self, GapElement_Permutation gen)

Expand Down
5 changes: 3 additions & 2 deletions src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,13 @@ cdef class LabelledBranching:
sage: L = LabelledBranching(3)
"""
from sage.libs.gap.libgap import libgap
from sage.groups.perm_gps.permgroup_named import SymmetricGroup

self.n = n
self.group = libgap.eval("Group(())")
self.ClosureGroup = libgap.eval("ClosureGroup")
self.father = < int *> sig_malloc(n * sizeof(int))
self.sym_gp = SymmetricGroup(self.n)
if self.father is NULL:
raise MemoryError('allocating LabelledBranching')
self.act_perm = < int *> sig_malloc(n * sizeof(int))
Expand Down Expand Up @@ -433,8 +435,7 @@ cdef class LabelledBranching:
[(1,2,3)]
"""
from sage.libs.gap.libgap import libgap

return libgap.SmallGeneratingSet(self.group).sage()
return libgap.SmallGeneratingSet(self.group).sage(parent=self.sym_gp)

def get_order(self):
r"""
Expand Down
1 change: 0 additions & 1 deletion src/sage/groups/perm_gps/permgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
- Javier Lopez Pena (2013): Added conjugacy classes.
- Sebastian Oehms (2018): added _coerce_map_from_ in order to use isomorphism coming up with as_permutation_group method (Trac #25706)
- Christian Stump (2018): Added alternative implementation of strong_generating_system directly using GAP.
REFERENCES:
Expand Down
22 changes: 18 additions & 4 deletions src/sage/libs/gap/element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ from sage.structure.sage_object cimport SageObject
from sage.structure.parent import Parent
from sage.rings.all import ZZ, QQ, RDF

from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement
from sage.combinat.permutation import Permutation

decode_type_number = {
libGAP_T_INT: 'T_INT (integer)',
libGAP_T_INTPOS: 'T_INTPOS (positive integer)',
Expand Down Expand Up @@ -2797,24 +2800,35 @@ cdef class GapElement_Permutation(GapElement):
<type 'sage.libs.gap.element.GapElement_Permutation'>
"""

def sage(self):
def sage(self, parent=None):
r"""
Return the Sage equivalent of the :class:`GapElement`
If the permutation group is given as parent, this method is
*much* faster.
EXAMPLES::
sage: perm_gap = libgap.eval('(1,5,2)(4,3,8)'); perm_gap
(1,5,2)(3,8,4)
sage: perm_gap.sage()
[5, 1, 8, 3, 2, 6, 7, 4]
sage: type(_)
<class 'sage.combinat.permutation.StandardPermutations_all_with_category.element_class'>
sage: perm_gap.sage(PermutationGroup([(1,2),(1,2,3,4,5,6,7,8)]))
(1,5,2)(3,8,4)
sage: type(_)
<type 'sage.groups.perm_gps.permgroup_element.PermutationGroupElement'>
"""
from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
libgap = self.parent()
return PermutationGroupElement(libgap.ListPerm(self).sage())
cdef PermutationGroupElement one_c

libgap = self.parent()
lst = libgap.ListPerm(self)

if parent is None:
return Permutation(lst.sage(), check_input=False)
else:
return parent.one()._generate_new_GAP(lst)

############################################################################
### GapElement_Record ######################################################
Expand Down
14 changes: 12 additions & 2 deletions src/sage/libs/gap/libgap.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,24 @@ equivalent::
sage: libgap.eval('5/3 + 7*E(3)').sage()
7*zeta3 + 5/3
sage: generators = libgap.AlternatingGroup(4).GeneratorsOfGroup().sage()
sage: gens_of_group = libgap.AlternatingGroup(4).GeneratorsOfGroup()
sage: generators = gens_of_group.sage()
sage: generators # a Sage list of Sage permutations!
[(1,2,3), (2,3,4)]
[[2, 3, 1], [1, 3, 4, 2]]
sage: PermutationGroup(generators).cardinality() # computed in Sage
12
sage: libgap.AlternatingGroup(4).Size() # computed in GAP
12
We can also specify which group in Sage the permutations should
consider themselves as elements of when converted to Sage::
sage: A4 = groups.permutation.Alternating(4)
sage: generators = gens_of_group.sage(parent=A4); generators
[(1,2,3), (2,3,4)]
sage: all(gen.parent() is A4 for gen in generators)
True
So far, the following GAP data types can be directly converted to the
corresponding Sage datatype:
Expand Down

0 comments on commit 2eebc67

Please sign in to comment.