Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge branch 'public/groups/cythonize_matrix_group_element-19870' int…
Browse files Browse the repository at this point in the history
…o public/combinat/speedup_coxeter_weyl_matrix_groups-19821
  • Loading branch information
Travis Scrimshaw committed Jan 21, 2016
2 parents 2e9535a + 9582f28 commit 525c753
Show file tree
Hide file tree
Showing 7 changed files with 823 additions and 648 deletions.
2 changes: 2 additions & 0 deletions src/module_list.py
Expand Up @@ -409,6 +409,8 @@ def uname_specific(name, value, alternative):

Extension('sage.groups.semimonomial_transformations.semimonomial_transformation',
sources = ['sage/groups/semimonomial_transformations/semimonomial_transformation.pyx']),
Extension('sage.groups.matrix_gps.group_element',
sources = ['sage/groups/matrix_gps/group_element.pyx']),

###################################
##
Expand Down
12 changes: 7 additions & 5 deletions src/sage/categories/primer.py
Expand Up @@ -462,16 +462,18 @@ class implements:
of classes for organizing the code. As we have seen above, the design
of the class hierarchy is easy since it can be modelled upon the
hierarchy of categories (bookshelves). Here is for example a piece of
the hierarchy of classes for an element of a group of matrices::
the hierarchy of classes for an element of a group of permutations::
sage: G = GL(2,ZZ)
sage: m = G.an_element()
sage: P = Permutations(4)
sage: m = P.an_element()
sage: for cls in m.__class__.mro(): print cls
<class 'sage.groups.matrix_gps.group_element.LinearMatrixGroup_gap_with_category.element_class'>
<class 'sage.groups.matrix_gps.group_element.MatrixGroupElement_gap'>
<class 'sage.combinat.permutation.StandardPermutations_n_with_category.element_class'>
<class 'sage.combinat.permutation.StandardPermutations_n.Element'>
<class 'sage.combinat.permutation.Permutation'>
...
<class 'sage.categories.groups.Groups.element_class'>
<class 'sage.categories.monoids.Monoids.element_class'>
...
<class 'sage.categories.semigroups.Semigroups.element_class'>
...
Expand Down
27 changes: 25 additions & 2 deletions src/sage/groups/affine_gps/group_element.py
Expand Up @@ -40,9 +40,9 @@

from sage.matrix.matrix import is_Matrix
from sage.misc.cachefunc import cached_method
from sage.groups.matrix_gps.group_element import MatrixGroupElement_base
from sage.structure.element import MultiplicativeGroupElement

class AffineGroupElement(MatrixGroupElement_base):
class AffineGroupElement(MultiplicativeGroupElement):
"""
An affine group element.
Expand Down Expand Up @@ -416,3 +416,26 @@ def __cmp__(self, other):
return c
return cmp(self._b, other._b)

def list(self):
"""
Return list representation of ``self``.
EXAMPLES::
sage: F = AffineGroup(3, QQ)
sage: g = F([1,2,3,4,5,6,7,8,0], [10,11,12])
sage: g
[1 2 3] [10]
x |-> [4 5 6] x + [11]
[7 8 0] [12]
sage: g.matrix()
[ 1 2 3|10]
[ 4 5 6|11]
[ 7 8 0|12]
[--------+--]
[ 0 0 0| 1]
sage: g.list()
[[1, 2, 3, 10], [4, 5, 6, 11], [7, 8, 0, 12], [0, 0, 0, 1]]
"""
return [r.list() for r in self.matrix().rows()]

170 changes: 0 additions & 170 deletions src/sage/groups/libgap_mixin.py
Expand Up @@ -14,176 +14,6 @@
from sage.libs.all import libgap
from sage.misc.cachefunc import cached_method


class GroupElementMixinLibGAP(object):

@cached_method
def order(self):
"""
Return the order of this group element, which is the smallest
positive integer `n` such that `g^n = 1`, or
+Infinity if no such integer exists.
EXAMPLES::
sage: k = GF(7);
sage: G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])]); G
Matrix group over Finite Field of size 7 with 2 generators (
[1 1] [1 0]
[0 1], [0 2]
)
sage: G.order()
21
sage: G.gen(0).order(), G.gen(1).order()
(7, 3)
sage: k = QQ;
sage: G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])]); G
Matrix group over Rational Field with 2 generators (
[1 1] [1 0]
[0 1], [0 2]
)
sage: G.order()
+Infinity
sage: G.gen(0).order(), G.gen(1).order()
(+Infinity, +Infinity)
sage: gl = GL(2, ZZ); gl
General Linear Group of degree 2 over Integer Ring
sage: g = gl.gen(2); g
[1 1]
[0 1]
sage: g.order()
+Infinity
"""
order = self.gap().Order()
if order.IsInt():
return order.sage()
else:
assert order.IsInfinity()
from sage.rings.all import Infinity
return Infinity

def word_problem(self, gens=None):
r"""
Solve the word problem.
This method writes the group element as a product of the
elements of the list ``gens``, or the standard generators of
the parent of self if ``gens`` is None.
INPUT:
- ``gens`` -- a list/tuple/iterable of elements (or objects
that can be converted to group elements), or ``None``
(default). By default, the generators of the parent group
are used.
OUTPUT:
A factorization object that contains information about the
order of factors and the exponents. A ``ValueError`` is raised
if the group element cannot be written as a word in ``gens``.
ALGORITHM:
Use GAP, which has optimized algorithms for solving the word
problem (the GAP functions ``EpimorphismFromFreeGroup`` and
``PreImagesRepresentative``).
EXAMPLE::
sage: G = GL(2,5); G
General Linear Group of degree 2 over Finite Field of size 5
sage: G.gens()
(
[2 0] [4 1]
[0 1], [4 0]
)
sage: G(1).word_problem([G.gen(0)])
1
sage: type(_)
<class 'sage.structure.factorization.Factorization'>
sage: g = G([0,4,1,4])
sage: g.word_problem()
([4 1]
[4 0])^-1
Next we construct a more complicated element of the group from the
generators::
sage: s,t = G.0, G.1
sage: a = (s * t * s); b = a.word_problem(); b
([2 0]
[0 1]) *
([4 1]
[4 0]) *
([2 0]
[0 1])
sage: flatten(b)
[
[2 0] [4 1] [2 0]
[0 1], 1, [4 0], 1, [0 1], 1
]
sage: b.prod() == a
True
We solve the word problem using some different generators::
sage: s = G([2,0,0,1]); t = G([1,1,0,1]); u = G([0,-1,1,0])
sage: a.word_problem([s,t,u])
([2 0]
[0 1])^-1 *
([1 1]
[0 1])^-1 *
([0 4]
[1 0]) *
([2 0]
[0 1])^-1
We try some elements that don't actually generate the group::
sage: a.word_problem([t,u])
Traceback (most recent call last):
...
ValueError: word problem has no solution
AUTHORS:
- David Joyner and William Stein
- David Loeffler (2010): fixed some bugs
- Volker Braun (2013): LibGAP
"""
from sage.libs.gap.libgap import libgap
G = self.parent()
if gens:
gen = lambda i:gens[i]
H = libgap.Group([G(x).gap() for x in gens])
else:
gen = G.gen
H = G.gap()
hom = H.EpimorphismFromFreeGroup()
preimg = hom.PreImagesRepresentative(self.gap())

if preimg.is_bool():
assert preimg == libgap.eval('fail')
raise ValueError('word problem has no solution')

result = []
n = preimg.NumberSyllables().sage()
exponent_syllable = libgap.eval('ExponentSyllable')
generator_syllable = libgap.eval('GeneratorSyllable')
for i in range(n):
exponent = exponent_syllable(preimg, i+1).sage()
generator = gen(generator_syllable(preimg, i+1).sage() - 1)
result.append( (generator, exponent) )
from sage.structure.factorization import Factorization
result = Factorization(result)
result._set_cr(True)
return result


class GroupMixinLibGAP(object):

@cached_method
Expand Down

0 comments on commit 525c753

Please sign in to comment.