Spaces:
Sleeping
Sleeping
| Finitely Presented Groups | |
| ========================= | |
| Introduction | |
| ------------ | |
| This module presents the functionality designed for computing with | |
| finitely-presented groups (fp-groups for short). The name of the corresponding | |
| SymPy object is ``FpGroup``. The functions or classes described here are | |
| studied under **computational group theory**. All code examples assume: | |
| >>> from sympy.combinatorics.free_groups import free_group, vfree_group, xfree_group | |
| >>> from sympy.combinatorics.fp_groups import FpGroup, CosetTable, coset_enumeration_r | |
| Overview of Facilities | |
| `````````````````````` | |
| The facilities provided for fp-groups fall into a number of natural groupings | |
| * The construction of fp-groups using a free group and a list of words in | |
| generators of that free group. | |
| * Index determination using the famous Todd-Coxeter procedure. | |
| * The construction of all subgroups having index less than some (small) | |
| specified positive integer, using the *Low-Index Subgroups* algorithm. | |
| * Algorithms for computing presentations of a subgroup of finite index | |
| in a group defined by finite presentation. | |
| For a description of fundamental algorithms of finitely presented groups | |
| we often make use of *Handbook of Computational Group Theory*. | |
| The Construction of Finitely Presented Groups | |
| --------------------------------------------- | |
| Finitely presented groups are constructed by factoring a free group by a | |
| set of relators. The set of relators is taken in as a list of words in | |
| generators of free group in SymPy, using a list provides ordering to the | |
| relators. If the list of relators is empty, the associated free group is | |
| returned. | |
| Example of construction of a finitely-presented group. | |
| The symmetric group of degree 4 may be represented as a two generator group | |
| with presentation `\left\langle a, b \mid a^2, b^3, (ab)^4 \right\rangle`. Giving the relations as a | |
| list of relators, group in SymPy would be specified as: | |
| >>> F, a, b = free_group("a, b") | |
| >>> G = FpGroup(F, [a**2, b**3, (a*b)**4]) | |
| >>> G | |
| <fp group on the generators (a, b)> | |
| Currently groups with relators having presentation like | |
| `\left\langle r, s, t \mid r^2, s^2, t^2, rst = str = trs \right\rangle` will have to be specified as: | |
| >>> F, r, s, t = free_group("r, s, t") | |
| >>> G = FpGroup(F, [r**2, s**2, t**2, r*s*t*r**-1*t**-1*s**-1, s*t*r*s**-1*r**-1*t**-1]) | |
| Obviously this is not a unique way to make that particular group, but the point | |
| is that in case of equality with non-identity the user has to manually do that. | |
| Free Groups and Words | |
| --------------------- | |
| Construction of a Free Group | |
| ```````````````````````````` | |
| ``free_group("gen0, gen1, ..., gen_(n-1)")`` constructs a free group ``F`` on | |
| ``n`` generators, where ``n`` is a positive integer. The `i`-th generator of | |
| `F` may be obtained using the method ``.generators[i]``, `i = 0, \ldots n-1`. | |
| >>> F, x, y = free_group("x, y") | |
| creates a free group ``F`` of rank 2 and assigns the variables ``x`` and ``y`` | |
| to the two generators. | |
| >>> F = vfree_group("x, y") | |
| >>> F | |
| <free group on the generators (x, y)> | |
| creates a free group ``F`` of rank 2, with tuple of generators ``F.generators``, | |
| and inserts ``x`` and ``y`` as generators into the global namespace. | |
| >>> F = xfree_group("x, y") | |
| >>> F | |
| (<free group on the generators (x, y)>, (x, y)) | |
| >>> x**2 | |
| x**2 | |
| creates a free groups ``F[0]`` of rank 2, with tuple of generators ``F[1]``. | |
| Construction of words | |
| ````````````````````` | |
| This section is applicable to words of ``FreeGroup`` as well as ``FpGroup``. | |
| When we say *word* in SymPy, it actually means a `reduced word | |
| <https://en.wikipedia.org/wiki/Word_(group_theory)#Reduced_words>`_ , since the | |
| words are automatically reduced. Given a group ``G`` defined on `n` generators | |
| `x_1, x_2, x_3, \ldots, x_n`, a word is constructed as | |
| `s_1^{r_1}s_2^{r_2} \cdots s_k^{r_k}` where `s_i \in \{x_1, x_2, \ldots, x_n\}` | |
| , `r_i \in \mathbb{Z}` for all `k`. | |
| Each word can be constructed in a variety of ways, since after reduction they | |
| may be equivalent. | |
| Coset Enumeration: The Todd-Coxeter Algorithm | |
| --------------------------------------------- | |
| This section describes the use of coset enumeration techniques in SymPy. The | |
| algorithm used for coset enumeration procedure is Todd-Coxeter algorithm and | |
| is developed in SymPy using [Ho05] and [CDHW73]. The reader should consult | |
| [CDHW73] and [Hav91] for a general description of the algorithm. | |
| We have two strategies of coset enumeration *relator-based* and | |
| *coset-table based* and the two have been implemented as | |
| ``coset_enumeration_r``, ``coset_enumeration_c`` respectively. The two | |
| strategies differ in the way they make new definitions for the cosets. | |
| Though from the user point of view it is suggested to rather use the | |
| ``.coset_enumeration`` method of ``FpGroup`` and specify the ``strategy`` | |
| argument. | |
| ``strategy``: | |
| (default="relator_based") specifies the strategy of coset | |
| enumeration to be used, possible values are *"relator_based"* or | |
| *"coset_table_based"*. | |
| CosetTable | |
| `````````` | |
| Class used to manipulate the information regarding the coset enumeration of | |
| the finitely presented group ``G`` on the cosets of the subgroup ``H``. | |
| Basically a *coset table* ``CosetTable(G,H)``, is the permutation representation | |
| of the finitely presented group on the cosets of a subgroup. Most of the set | |
| theoretic and group functions use the regular representation of ``G``, i.e., | |
| the coset table of ``G`` over the trivial subgroup. | |
| The actual mathematical coset table is obtained using ``.table`` attribute and | |
| is a list of lists. For each generator ``g`` of ``G`` it contains a column and | |
| the next column corresponds to ``g**-1`` and so on for other generators, so in | |
| total it has ``2*G.rank()`` columns. Each column is simply a list of integers. | |
| If ``l`` is the generator list for the generator `g` and if ``l[i] = j`` then | |
| generator ``g`` takes the coset `i` to the coset `j` by multiplication from the | |
| right. | |
| For finitely presented groups, a coset table is computed by a Todd-Coxeter | |
| coset enumeration. Note that you may influence the performance of that | |
| enumeration by changing the values of the variable | |
| ``CosetTable.coset_table_max_limit``. | |
| Attributes of CosetTable | |
| ```````````````````````` | |
| For ``CosetTable(G, H)`` where ``G`` is the group and ``H`` is the subgroup. | |
| * ``n``: A non-negative integer, non-mutable attribute, dependently | |
| calculated as the maximum among the live-cosets (i.e. `\Omega`). | |
| * ``table``: A list of lists, mutable attribute, mathematically represents the | |
| coset table. | |
| * ``omega``: A list, dependent on the internal attribute ``p``. `\Omega` | |
| represents the list of live-cosets. A *standard* coset-table has its | |
| `\Omega = \{0, 1, \ldots, index-1 \}` where `index` is the index of subgroup | |
| `H` in `G`. | |
| For experienced users we have a number of parameters that can be used to | |
| manipulate the algorithm, like | |
| * ``coset_table_max_limit`` (default value = `4096000`): manipulate the maximum | |
| number of cosets allowed in coset enumeration, i.e. the number of rows allowed | |
| in coset table. A coset enumeration will not finish if the subgroup does not | |
| have finite index, and even if it has it may take many more intermediate | |
| cosets than the actual index of the subgroup is. To avoid a coset enumeration | |
| "running away" therefore SymPy has a "safety stop" built-in. This is | |
| controlled by this variable. To change it, use `max_cosets` keyword. | |
| For example: | |
| >>> F, a, b = free_group("a, b") | |
| >>> Cox = FpGroup(F, [a**6, b**6, (a*b)**2, (a**2*b**2)**2, (a**3*b**3)**5]) | |
| >>> C_r = coset_enumeration_r(Cox, [a], max_cosets=50) | |
| Traceback (most recent call last): | |
| ... | |
| ValueError: the coset enumeration has defined more than 50 cosets | |
| * ``max_stack_size`` (default value = `500`): manipulate the maximum size of | |
| ``deduction_stack`` above or equal to which the stack is emptied. | |
| Compression and Standardization | |
| ``````````````````````````````` | |
| For any two entries `i, j` with `i < j` in coset table, the first | |
| occurrence of `i` in a coset table precedes the first occurrence of `j` with | |
| respect to the usual row-wise ordering of the table entries. We call such a | |
| table a standard coset table. To standardize a ``CosetTable`` we use the | |
| ``.standardize`` method. | |
| **Note** the method alters the given table, it does not create a copy. | |
| Subgroups of Finite Index | |
| ------------------------- | |
| The functionality in this section are concerned with the construction of | |
| subgroups of finite index. We describe a method for computing all subgroups | |
| whose index does not exceed some (modest) integer bound. | |
| Low Index Subgroups | |
| ``````````````````` | |
| ``low_index_subgroups(G, N)``: Given a finitely presented group `G = \left\langle X \mid R \right\rangle` | |
| (can be a free group), and ``N`` a positive integer, determine the conjugacy classes of | |
| subgroups of ``G`` whose indices is less than or equal to ``N``. | |
| For example to find all subgroups of `G = \left\langle a, b \mid a^2 = b^3 = (ab)^4 = 1 \right\rangle` | |
| having index `\le` 4, can be found as follows: | |
| >>> from sympy.combinatorics.fp_groups import low_index_subgroups | |
| >>> F, a, b = free_group("a, b") | |
| >>> G = FpGroup(F, [a**2, b**3, (a*b)**4]) | |
| >>> l = low_index_subgroups(G, 4) | |
| >>> for coset_table in l: | |
| ... print(coset_table.table) | |
| ... | |
| [[0, 0, 0, 0]] | |
| [[0, 0, 1, 2], [1, 1, 2, 0], [3, 3, 0, 1], [2, 2, 3, 3]] | |
| [[0, 0, 1, 2], [2, 2, 2, 0], [1, 1, 0, 1]] | |
| [[1, 1, 0, 0], [0, 0, 1, 1]] | |
| This returns the coset tables of subgroups of satisfying the property | |
| that index, `index`, of subgroup in group is `\le n`. | |
| Constructing a presentation for a subgroup | |
| ------------------------------------------ | |
| In this section we discuss finding the presentation of a subgroup in a finitely | |
| presentation group. While the *subgroup* is currently allowed as input only in | |
| the form of a list of generators for the subgroup, you can expect the | |
| functionality of a *coset table* as input for subgroup in the group in near | |
| future. | |
| There are two ways to construct a set of defining relations for subgroup from | |
| those of ``G``. First is on a set of Schreier generators, known generally as | |
| Reidemeister-Schreier algorithm or on the given list of generators of ``H``. | |
| Reidemeister Schreier algorithm | |
| ``````````````````````````````` | |
| called using ``reidemeister_presentation(G, Y)`` where ``G`` is the group and | |
| ``Y`` is a list of generators for subgroup ``H`` whose presentation we want to | |
| find. | |
| >>> from sympy.combinatorics.fp_groups import reidemeister_presentation | |
| >>> F, x, y = free_group("x, y") | |
| >>> f = FpGroup(F, [x**3, y**5, (x*y)**2]) | |
| >>> H = [x*y, x**-1*y**-1*x*y*x] | |
| >>> p1 = reidemeister_presentation(f, H) | |
| >>> p1 | |
| ((y_1, y_2), (y_1**2, y_2**3, y_2*y_1*y_2*y_1*y_2*y_1)) | |
| Bibliography | |
| ------------ | |
| .. [CDHW73] John J. Cannon, Lucien A. Dimino, George Havas, and Jane M. Watson. | |
| Implementation and analysis of the Todd-Coxeter algorithm. Math. Comp., 27:463– | |
| 490, 1973. | |
| .. [Ho05] Derek F. Holt, | |
| Handbook of Computational Group Theory. | |
| In the series 'Discrete Mathematics and its Applications', | |
| `Chapman & Hall/CRC 2005, xvi + 514 p <https://www.routledge.com/Handbook-of-Computational-Group-Theory/Holt-Eick-OBrien/p/book/9781584883722>`_. | |
| .. [Hav91] George Havas, Coset enumeration strategies. | |
| In Proceedings of the International Symposium on Symbolic and Algebraic Computation (ISSAC'91), Bonn 1991, pages 191--199. ACM Press, 1991. | |