示例#1
0
def low_index_subgroups(G, N, Y=[]):
    """
    Implements the Low Index Subgroups algorithm, i.e find all subgroups of
    ``G`` upto a given index ``N``. This implements the method described in
    [Sim94]. This procedure involves a backtrack search over incomplete Coset
    Tables, rather than over forced coincidences.

    Parameters
    ==========

    G: An FpGroup < X|R >
    N: positive integer, representing the maximum index value for subgroups
    Y: (an optional argument) specifying a list of subgroup generators, such
    that each of the resulting subgroup contains the subgroup generated by Y.

    Examples
    ========

    >>> from sympy.combinatorics.free_groups import free_group
    >>> from sympy.combinatorics.fp_groups import FpGroup, low_index_subgroups
    >>> F, x, y = free_group("x, y")
    >>> f = FpGroup(F, [x**2, y**3, (x*y)**4])
    >>> L = low_index_subgroups(f, 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]]

    References
    ==========

    .. [1] Holt, D., Eick, B., O'Brien, E.
           "Handbook of Computational Group Theory"
           Section 5.4

    .. [2] Marston Conder and Peter Dobcsanyi
           "Applications and Adaptions of the Low Index Subgroups Procedure"

    """
    C = CosetTable(G, [])
    R = G.relators
    # length chosen for the length of the short relators
    len_short_rel = 5
    # elements of R2 only checked at the last step for complete
    # coset tables
    R2 = set([rel for rel in R if len(rel) > len_short_rel])
    # elements of R1 are used in inner parts of the process to prune
    # branches of the search tree,
    R1 = set([rel.identity_cyclic_reduction() for rel in set(R) - R2])
    R1_c_list = C.conjugates(R1)
    S = []
    descendant_subgroups(S, C, R1_c_list, C.A[0], R2, N, Y)
    return S
示例#2
0
文件: fp_groups.py 项目: bjodah/sympy
def low_index_subgroups(G, N, Y=[]):
    """
    Implements the Low Index Subgroups algorithm, i.e find all subgroups of
    ``G`` upto a given index ``N``. This implements the method described in
    [Sim94]. This procedure involves a backtrack search over incomplete Coset
    Tables, rather than over forced coincidences.

    Parameters
    ==========

    G: An FpGroup < X|R >
    N: positive integer, representing the maximum index value for subgroups
    Y: (an optional argument) specifying a list of subgroup generators, such
    that each of the resulting subgroup contains the subgroup generated by Y.

    Examples
    ========

    >>> from sympy.combinatorics.free_groups import free_group
    >>> from sympy.combinatorics.fp_groups import FpGroup, low_index_subgroups
    >>> F, x, y = free_group("x, y")
    >>> f = FpGroup(F, [x**2, y**3, (x*y)**4])
    >>> L = low_index_subgroups(f, 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]]

    References
    ==========

    .. [1] Holt, D., Eick, B., O'Brien, E.
           "Handbook of Computational Group Theory"
           Section 5.4

    .. [2] Marston Conder and Peter Dobcsanyi
           "Applications and Adaptions of the Low Index Subgroups Procedure"

    """
    C = CosetTable(G, [])
    R = G.relators
    # length chosen for the length of the short relators
    len_short_rel = 5
    # elements of R2 only checked at the last step for complete
    # coset tables
    R2 = set([rel for rel in R if len(rel) > len_short_rel])
    # elements of R1 are used in inner parts of the process to prune
    # branches of the search tree,
    R1 = set([rel.identity_cyclic_reduction() for rel in set(R) - R2])
    R1_c_list = C.conjugates(R1)
    S = []
    descendant_subgroups(S, C, R1_c_list, C.A[0], R2, N, Y)
    return S
示例#3
0
def test_modified_methods():
    """
    Tests for modified coset table methods.
    Example 5.7 from [1] Holt, D., Eick, B., O'Brien
    "Handbook of Computational Group Theory".

    """
    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]
    C = CosetTable(f, H)
    C.modified_define(0, x)
    identity = C._grp.identity
    a_0 = C._grp.generators[0]
    a_1 = C._grp.generators[1]

    assert C.P == [[identity, None, None, None], [None, identity, None, None]]
    assert C.table == [[1, None, None, None], [None, 0, None, None]]

    C.modified_define(1, x)
    assert C.table == [[1, None, None, None], [2, 0, None, None], [None, 1, None, None]]
    assert C.P == [
        [identity, None, None, None],
        [identity, identity, None, None],
        [None, identity, None, None],
    ]

    C.modified_scan(0, x ** 3, C._grp.identity, fill=False)
    assert C.P == [
        [identity, identity, None, None],
        [identity, identity, None, None],
        [identity, identity, None, None],
    ]
    assert C.table == [[1, 2, None, None], [2, 0, None, None], [0, 1, None, None]]

    C.modified_scan(0, x * y, C._grp.generators[0], fill=False)
    assert C.P == [
        [identity, identity, None, a_0 ** -1],
        [identity, identity, a_0, None],
        [identity, identity, None, None],
    ]
    assert C.table == [[1, 2, None, 1], [2, 0, 0, None], [0, 1, None, None]]

    C.modified_define(2, y ** -1)
    assert C.table == [
        [1, 2, None, 1],
        [2, 0, 0, None],
        [0, 1, None, 3],
        [None, None, 2, None],
    ]
    assert C.P == [
        [identity, identity, None, a_0 ** -1],
        [identity, identity, a_0, None],
        [identity, identity, None, identity],
        [None, None, identity, None],
    ]

    C.modified_scan(0, x ** -1 * y ** -1 * x * y * x, C._grp.generators[1])
    assert C.table == [
        [1, 2, None, 1],
        [2, 0, 0, None],
        [0, 1, None, 3],
        [3, 3, 2, None],
    ]
    assert C.P == [
        [identity, identity, None, a_0 ** -1],
        [identity, identity, a_0, None],
        [identity, identity, None, identity],
        [a_1, a_1 ** -1, identity, None],
    ]

    C.modified_scan(2, (x * y) ** 2, C._grp.identity)
    assert C.table == [[1, 2, 3, 1], [2, 0, 0, None], [0, 1, None, 3], [3, 3, 2, 0]]
    assert C.P == [
        [identity, identity, a_1 ** -1, a_0 ** -1],
        [identity, identity, a_0, None],
        [identity, identity, None, identity],
        [a_1, a_1 ** -1, identity, a_1],
    ]

    C.modified_define(2, y)
    assert C.table == [
        [1, 2, 3, 1],
        [2, 0, 0, None],
        [0, 1, 4, 3],
        [3, 3, 2, 0],
        [None, None, None, 2],
    ]
    assert C.P == [
        [identity, identity, a_1 ** -1, a_0 ** -1],
        [identity, identity, a_0, None],
        [identity, identity, identity, identity],
        [a_1, a_1 ** -1, identity, a_1],
        [None, None, None, identity],
    ]

    C.modified_scan(0, y ** 5, C._grp.identity)
    assert C.table == [
        [1, 2, 3, 1],
        [2, 0, 0, 4],
        [0, 1, 4, 3],
        [3, 3, 2, 0],
        [None, None, 1, 2],
    ]
    assert C.P == [
        [identity, identity, a_1 ** -1, a_0 ** -1],
        [identity, identity, a_0, a_0 * a_1 ** -1],
        [identity, identity, identity, identity],
        [a_1, a_1 ** -1, identity, a_1],
        [None, None, a_1 * a_0 ** -1, identity],
    ]

    C.modified_scan(1, (x * y) ** 2, C._grp.identity)
    assert C.table == [
        [1, 2, 3, 1],
        [2, 0, 0, 4],
        [0, 1, 4, 3],
        [3, 3, 2, 0],
        [4, 4, 1, 2],
    ]
    assert C.P == [
        [identity, identity, a_1 ** -1, a_0 ** -1],
        [identity, identity, a_0, a_0 * a_1 ** -1],
        [identity, identity, identity, identity],
        [a_1, a_1 ** -1, identity, a_1],
        [a_0 * a_1 ** -1, a_1 * a_0 ** -1, a_1 * a_0 ** -1, identity],
    ]

    # Modified coset enumeration test
    f = FpGroup(F, [x ** 3, y ** 3, x ** -1 * y ** -1 * x * y])
    C = coset_enumeration_r(f, [x])
    C_m = modified_coset_enumeration_r(f, [x])
    assert C_m.table == C.table
示例#4
0
def test_scan_1():
    # Example 5.1 from [1]
    F, x, y = free_group("x, y")
    f = FpGroup(F, [x ** 3, y ** 3, x ** -1 * y ** -1 * x * y])
    c = CosetTable(f, [x])

    c.scan_and_fill(0, x)
    assert c.table == [[0, 0, None, None]]
    assert c.p == [0]
    assert c.n == 1
    assert c.omega == [0]

    c.scan_and_fill(0, x ** 3)
    assert c.table == [[0, 0, None, None]]
    assert c.p == [0]
    assert c.n == 1
    assert c.omega == [0]

    c.scan_and_fill(0, y ** 3)
    assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [None, None, 0, 1]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(0, x ** -1 * y ** -1 * x * y)
    assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [2, 2, 0, 1]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, x ** 3)
    assert c.table == [
        [0, 0, 1, 2],
        [3, 4, 2, 0],
        [2, 2, 0, 1],
        [4, 1, None, None],
        [1, 3, None, None],
    ]
    assert c.p == [0, 1, 2, 3, 4]
    assert c.n == 5
    assert c.omega == [0, 1, 2, 3, 4]

    c.scan_and_fill(1, y ** 3)
    assert c.table == [
        [0, 0, 1, 2],
        [3, 4, 2, 0],
        [2, 2, 0, 1],
        [4, 1, None, None],
        [1, 3, None, None],
    ]
    assert c.p == [0, 1, 2, 3, 4]
    assert c.n == 5
    assert c.omega == [0, 1, 2, 3, 4]

    c.scan_and_fill(1, x ** -1 * y ** -1 * x * y)
    assert c.table == [
        [0, 0, 1, 2],
        [1, 1, 2, 0],
        [2, 2, 0, 1],
        [None, 1, None, None],
        [1, 3, None, None],
    ]
    assert c.p == [0, 1, 2, 1, 1]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    # Example 5.2 from [1]
    f = FpGroup(F, [x ** 2, y ** 3, (x * y) ** 3])
    c = CosetTable(f, [x * y])

    c.scan_and_fill(0, x * y)
    assert c.table == [[1, None, None, 1], [None, 0, 0, None]]
    assert c.p == [0, 1]
    assert c.n == 2
    assert c.omega == [0, 1]

    c.scan_and_fill(0, x ** 2)
    assert c.table == [[1, 1, None, 1], [0, 0, 0, None]]
    assert c.p == [0, 1]
    assert c.n == 2
    assert c.omega == [0, 1]

    c.scan_and_fill(0, y ** 3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(0, (x * y) ** 3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, x ** 2)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, y ** 3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, (x * y) ** 3)
    assert c.table == [
        [1, 1, 2, 1],
        [0, 0, 0, 2],
        [3, 4, 1, 0],
        [None, 2, 4, None],
        [2, None, None, 3],
    ]
    assert c.p == [0, 1, 2, 3, 4]
    assert c.n == 5
    assert c.omega == [0, 1, 2, 3, 4]

    c.scan_and_fill(2, x ** 2)
    assert c.table == [
        [1, 1, 2, 1],
        [0, 0, 0, 2],
        [3, 3, 1, 0],
        [2, 2, 3, 3],
        [2, None, None, 3],
    ]
    assert c.p == [0, 1, 2, 3, 3]
    assert c.n == 4
    assert c.omega == [0, 1, 2, 3]
示例#5
0
def test_modified_methods():
    '''
    Tests for modified coset table methods.
    Example 5.7 from [1] Holt, D., Eick, B., O'Brien
    "Handbook of Computational Group Theory".

    '''
    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]
    C = CosetTable(f, H)
    C.modified_define(0, x)
    identity = C._grp.identity
    a_0 = C._grp.generators[0]
    a_1 = C._grp.generators[1]

    assert C.P == [[identity, None, None, None],
                    [None, identity, None, None]]
    assert C.table == [[1, None, None, None],
                        [None, 0, None, None]]

    C.modified_define(1, x)
    assert C.table == [[1, None, None, None],
                        [2, 0, None, None],
                        [None, 1, None, None]]
    assert C.P == [[identity, None, None, None],
                    [identity, identity, None, None],
                    [None, identity, None, None]]

    C.modified_scan(0, x**3, C._grp.identity, fill=False)
    assert C.P == [[identity, identity, None, None],
                     [identity, identity, None, None],
                     [identity, identity, None, None]]
    assert C.table == [[1, 2, None, None],
                        [2, 0, None, None],
                        [0, 1, None, None]]

    C.modified_scan(0, x*y, C._grp.generators[0], fill=False)
    assert C.P == [[identity, identity, None, a_0**-1],
                    [identity, identity, a_0, None],
                    [identity, identity, None, None]]
    assert C.table == [[1, 2, None, 1],
                        [2, 0, 0, None],
                        [0, 1, None, None]]

    C.modified_define(2, y**-1)
    assert C.table == [[1, 2, None, 1],
                        [2, 0, 0, None],
                        [0, 1, None, 3],
                        [None, None, 2, None]]
    assert C.P == [[identity, identity, None, a_0**-1],
                    [identity, identity, a_0, None],
                    [identity, identity, None, identity],
                    [None, None, identity, None]]

    C.modified_scan(0, x**-1*y**-1*x*y*x, C._grp.generators[1])
    assert C.table == [[1, 2, None, 1],
                        [2, 0, 0, None],
                        [0, 1, None, 3],
                        [3, 3, 2, None]]
    assert C.P == [[identity, identity, None, a_0**-1],
                    [identity, identity, a_0, None],
                    [identity, identity, None, identity],
                    [a_1, a_1**-1, identity, None]]

    C.modified_scan(2, (x*y)**2, C._grp.identity)
    assert C.table == [[1, 2, 3, 1],
                        [2, 0, 0, None],
                        [0, 1, None, 3],
                        [3, 3, 2, 0]]
    assert C.P == [[identity, identity, a_1**-1, a_0**-1],
                    [identity, identity, a_0, None],
                    [identity, identity, None, identity],
                    [a_1, a_1**-1, identity, a_1]]

    C.modified_define(2, y)
    assert C.table == [[1, 2, 3, 1],
                        [2, 0, 0, None],
                        [0, 1, 4, 3],
                        [3, 3, 2, 0],
                        [None, None, None, 2]]
    assert C.P == [[identity, identity, a_1**-1, a_0**-1],
                    [identity, identity, a_0, None],
                    [identity, identity, identity, identity],
                    [a_1, a_1**-1, identity, a_1],
                    [None, None, None, identity]]

    C.modified_scan(0, y**5, C._grp.identity)
    assert C.table == [[1, 2, 3, 1], [2, 0, 0, 4], [0, 1, 4, 3], [3, 3, 2, 0], [None, None, 1, 2]]
    assert C.P == [[identity, identity, a_1**-1, a_0**-1],
                    [identity, identity, a_0, a_0*a_1**-1],
                    [identity, identity, identity, identity],
                    [a_1, a_1**-1, identity, a_1],
                    [None, None, a_1*a_0**-1, identity]]

    C.modified_scan(1, (x*y)**2, C._grp.identity)
    assert C.table == [[1, 2, 3, 1],
                        [2, 0, 0, 4],
                        [0, 1, 4, 3],
                        [3, 3, 2, 0],
                        [4, 4, 1, 2]]
    assert C.P == [[identity, identity, a_1**-1, a_0**-1],
                    [identity, identity, a_0, a_0*a_1**-1],
                    [identity, identity, identity, identity],
                    [a_1, a_1**-1, identity, a_1],
                    [a_0*a_1**-1, a_1*a_0**-1, a_1*a_0**-1, identity]]

    # Modified coset enumeration test
    f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y])
    C = coset_enumeration_r(f, [x])
    C_m = modified_coset_enumeration_r(f, [x])
    assert C_m.table == C.table
示例#6
0
def test_scan_1():
    # Example 5.1 from [1]
    F, x, y = free_group("x, y")
    f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y])
    c = CosetTable(f, [x])

    c.scan_and_fill(0, x)
    assert c.table == [[0, 0, None, None]]
    assert c.p == [0]
    assert c.n == 1
    assert c.omega == [0]

    c.scan_and_fill(0, x**3)
    assert c.table == [[0, 0, None, None]]
    assert c.p == [0]
    assert c.n == 1
    assert c.omega == [0]

    c.scan_and_fill(0, y**3)
    assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [None, None, 0, 1]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(0, x**-1*y**-1*x*y)
    assert c.table == [[0, 0, 1, 2], [None, None, 2, 0], [2, 2, 0, 1]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, x**3)
    assert c.table == [[0, 0, 1, 2], [3, 4, 2, 0], [2, 2, 0, 1], \
            [4, 1, None, None], [1, 3, None, None]]
    assert c.p == [0, 1, 2, 3, 4]
    assert c.n == 5
    assert c.omega == [0, 1, 2, 3, 4]

    c.scan_and_fill(1, y**3)
    assert c.table == [[0, 0, 1, 2], [3, 4, 2, 0], [2, 2, 0, 1], \
            [4, 1, None, None], [1, 3, None, None]]
    assert c.p == [0, 1, 2, 3, 4]
    assert c.n == 5
    assert c.omega == [0, 1, 2, 3, 4]

    c.scan_and_fill(1, x**-1*y**-1*x*y)
    assert c.table == [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1], \
            [None, 1, None, None], [1, 3, None, None]]
    assert c.p == [0, 1, 2, 1, 1]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    # Example 5.2 from [1]
    f = FpGroup(F, [x**2, y**3, (x*y)**3])
    c = CosetTable(f, [x*y])

    c.scan_and_fill(0, x*y)
    assert c.table == [[1, None, None, 1], [None, 0, 0, None]]
    assert c.p == [0, 1]
    assert c.n == 2
    assert c.omega == [0, 1]

    c.scan_and_fill(0, x**2)
    assert c.table == [[1, 1, None, 1], [0, 0, 0, None]]
    assert c.p == [0, 1]
    assert c.n == 2
    assert c.omega == [0, 1]

    c.scan_and_fill(0, y**3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(0, (x*y)**3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, x**2)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, y**3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [None, None, 1, 0]]
    assert c.p == [0, 1, 2]
    assert c.n == 3
    assert c.omega == [0, 1, 2]

    c.scan_and_fill(1, (x*y)**3)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [3, 4, 1, 0], [None, 2, 4, None], [2, None, None, 3]]
    assert c.p == [0, 1, 2, 3, 4]
    assert c.n == 5
    assert c.omega == [0, 1, 2, 3, 4]

    c.scan_and_fill(2, x**2)
    assert c.table == [[1, 1, 2, 1], [0, 0, 0, 2], [3, 3, 1, 0], [2, 2, 3, 3], [2, None, None, 3]]
    assert c.p == [0, 1, 2, 3, 3]
    assert c.n == 4
    assert c.omega == [0, 1, 2, 3]