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

Commit

Permalink
Cythonized matrix_gp/group_element.py and simplified the class struct…
Browse files Browse the repository at this point in the history
…ure.
  • Loading branch information
Travis Scrimshaw committed Jan 12, 2016
1 parent 989b6ea commit 6358d53
Show file tree
Hide file tree
Showing 5 changed files with 762 additions and 622 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
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 6358d53

Please sign in to comment.