Skip to content

Commit

Permalink
Trac #26889: use libGAP in MatrixGroup.as_permutation_group()
Browse files Browse the repository at this point in the history
Currently, one uses pexpect interface there to convert a libGAP matrix
group to strings, feed it to GAP's pexpect interface, etc.

This ticket will streamline this. One still will need one conversion to
pexpect GAP, at the end, to feed it to !PermutationGroup().

URL: https://trac.sagemath.org/26889
Reported by: dimpase
Ticket author(s): Dima Pasechnik
Reviewer(s): Sebastian Oehms
  • Loading branch information
Release Manager authored and vbraun committed Dec 23, 2018
2 parents c448fe6 + 7dd5fa6 commit 6c40fa6
Showing 1 changed file with 31 additions and 38 deletions.
69 changes: 31 additions & 38 deletions src/sage/groups/matrix_gps/finitely_generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,32 +62,25 @@
##############################################################################
from __future__ import print_function

from sage.groups.group import Group
from sage.rings.all import ZZ
from sage.rings.all import QQbar
from sage.rings.integer import is_Integer
from sage.rings.ring import is_Ring
from sage.rings.finite_rings.finite_field_constructor import is_FiniteField
from sage.interfaces.gap import gap
from sage.structure.element import is_Matrix
from sage.matrix.matrix_space import MatrixSpace, is_MatrixSpace
from sage.matrix.all import matrix
from sage.misc.latex import latex
from sage.structure.sequence import Sequence
from sage.misc.cachefunc import cached_method
from sage.modules.free_module_element import vector
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.power_series_ring import PowerSeriesRing
from sage.arith.all import gcd
from sage.rings.fraction_field import FractionField
from sage.misc.functional import cyclotomic_polynomial
from sage.rings.number_field.number_field import CyclotomicField
from sage.combinat.integer_vector import IntegerVectors

from sage.groups.matrix_gps.matrix_group import (
is_MatrixGroup, MatrixGroup_generic, MatrixGroup_gap )
from sage.groups.matrix_gps.group_element import (
is_MatrixGroupElement, MatrixGroupElement_generic, MatrixGroupElement_gap)
MatrixGroup_generic, MatrixGroup_gap )
from sage.groups.matrix_gps.group_element import is_MatrixGroupElement


def normalize_square_matrices(matrices):
Expand Down Expand Up @@ -549,14 +542,12 @@ def as_permutation_group(self, algorithm=None):
sage: G = MatrixGroup([A])
sage: G.as_permutation_group()
Permutation Group with generators [(1,2)]
sage: MS = MatrixSpace( GF(7), 12, 12)
sage: GG = gap("ImfMatrixGroup( 12, 3 )")
sage: GG.GeneratorsOfGroup().Length()
3
sage: g1 = MS(eval(str(GG.GeneratorsOfGroup()[1]).replace("\n","")))
sage: g2 = MS(eval(str(GG.GeneratorsOfGroup()[2]).replace("\n","")))
sage: g3 = MS(eval(str(GG.GeneratorsOfGroup()[3]).replace("\n","")))
sage: G = MatrixGroup([g1, g2, g3])
A finite subgroup of GL(12,Z) as a permutation group::
sage: imf=libgap.function_factory('ImfMatrixGroup')
sage: GG = imf( 12, 3 )
sage: G = MatrixGroup(GG.GeneratorsOfGroup())
sage: G.cardinality()
21499084800
sage: set_random_seed(0); current_randstate().set_seed_gap()
Expand Down Expand Up @@ -587,39 +578,43 @@ def as_permutation_group(self, algorithm=None):
sage: a.order(), b.order()
(2, 1)
The above example in GL(12,Z), reduced modulo 7::
sage: MS = MatrixSpace( GF(7), 12, 12)
sage: G = MatrixGroup(map(MS, GG.GeneratorsOfGroup()))
sage: G.cardinality()
21499084800
sage: P = G.as_permutation_group()
sage: P.cardinality()
21499084800
Check that large degree is still working::
sage: Sp(6,3).as_permutation_group().cardinality()
9170703360
Check that ``_permutation_group_morphism`` works (:trac:`25706`)::
sage: MG = GU(3,2).as_matrix_group()
sage: PG = MG.as_permutation_group() # this constructs the morphism
sage: mg = MG.an_element()
sage: MG._permutation_group_morphism(mg)
(1,2,6,19,35,33)(3,9,26,14,31,23)(4,13,5)(7,22,17)(8,24,12)(10,16,32,27,20,28)(11,30,18)(15,25,36,34,29,21)
(1,2,6,19,35,33)(3,9,26,14,31,23)(4,13,5)(7,22,17)(8,24,12)(10,16,32,27,20,28)(11,30,18)(15,25,36,34,29,21)
"""
# Note that the output of IsomorphismPermGroup() depends on
# memory locations and will change if you change the order of
# doctests and/or architecture
from sage.groups.perm_gps.permgroup import PermutationGroup
if not self.is_finite():
raise NotImplementedError("Group must be finite.")
n = self.degree()
MS = MatrixSpace(self.base_ring(), n, n)
mats = [] # initializing list of mats by which the gens act on self
for g in self.gens():
p = MS(g.matrix())
m = p.rows()
mats.append(m)
mats_str = str(gap([[list(r) for r in m] for m in mats]))
gap.eval("iso:=IsomorphismPermGroup(Group("+mats_str+"))")
gap_permutation_map = gap("iso;")
iso=self._libgap_().IsomorphismPermGroup()
if algorithm == "smaller":
gap.eval("small:= SmallerDegreePermutationRepresentation( Image( iso ) );")
C = gap("Image( small )")
else:
C = gap("Image( iso )")
PG = PermutationGroup(gap_group=C, canonicalize=False)
iso=iso.Image().SmallerDegreePermutationRepresentation()
PG = PermutationGroup(iso.Image().GeneratorsOfGroup().sage(), \
canonicalize=False) # applying gap() - as PermutationGroup is not libGAP

def permutation_group_map(element):
return PG(gap_permutation_map.ImageElm(element.gap()))
return PG(iso.ImageElm(element.gap()).sage())

from sage.categories.homset import Hom
self._permutation_group_morphism = Hom(self, PG)(permutation_group_map)
Expand Down Expand Up @@ -666,7 +661,6 @@ def module_composition_factors(self, algorithm=None):
n = self.degree()
MS = MatrixSpace(F,n,n)
mats = [] # initializing list of mats by which the gens act on self
W = self.matrix_space().row_space()
for g in gens:
p = MS(g.matrix())
m = p.rows()
Expand Down Expand Up @@ -774,15 +768,15 @@ def invariant_generators(self):
else:
VarStr = 'x'
VarNames='('+','.join((VarStr+str(i+1) for i in range(n)))+')'
R=singular.ring(FieldStr,VarNames,'dp')
R=singular.ring(FieldStr,VarNames,'dp') # this does have a side-effect
if hasattr(F,'polynomial') and F.gen()!=1: # we have to define minpoly
singular.eval('minpoly = '+str(F.polynomial()).replace('x',str(F.gen())))
A = [singular.matrix(n,n,str((x.matrix()).list())) for x in gens]
Lgens = ','.join((x.name() for x in A))
PR = PolynomialRing(F,n,[VarStr+str(i) for i in range(1,n+1)])

if q == 0 or (q > 0 and self.cardinality()%q != 0):
from sage.all import Integer, Matrix
from sage.all import Matrix
try:
elements = [ g.matrix() for g in self.list() ]
except (TypeError,ValueError):
Expand All @@ -799,7 +793,6 @@ def invariant_generators(self):
for t in D[row].items():
singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)'
%(ReyName,i,row+1,ReyName,i,row+1, repr(t[1]),t[0]+1))
foobar = singular(ReyName)
IRName = 't'+singular._next_var_name()
singular.eval('matrix %s = invariant_algebra_reynolds(%s)'%(IRName,ReyName))
else:
Expand Down

0 comments on commit 6c40fa6

Please sign in to comment.