Exemplo n.º 1
0
    def __init__(self, coxeter_matrix, names):
        """
        Initialize ``self``.

        TESTS::

            sage: A = ArtinGroup(['D',4])
            sage: TestSuite(A).run()
            sage: A = ArtinGroup(['B',3], ['x','y','z'])
            sage: TestSuite(A).run()
        """
        self._coxeter_group = CoxeterGroup(coxeter_matrix)
        free_group = FreeGroup(names)
        rels = []
        # Generate the relations based on the Coxeter graph
        I = coxeter_matrix.index_set()
        for ii,i in enumerate(I):
            for j in I[ii+1:]:
                m = coxeter_matrix[i,j]
                if m == Infinity:  # no relation
                    continue
                elt = [i,j]*m
                for ind in range(m, 2*m):
                    elt[ind] = -elt[ind]
                rels.append(free_group(elt))
        FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
Exemplo n.º 2
0
    def __init__(self, G, names):
        """
        Initialize ``self``.

        TESTS::

            sage: G = RightAngledArtinGroup(graphs.CycleGraph(5))
            sage: TestSuite(G).run()
        """
        self._graph = G
        F = FreeGroup(names=names)
        CG = Graph(G).complement()  # Make sure it's mutable
        CG.relabel()  # Standardize the labels
        cm = [[-1] * CG.num_verts() for _ in range(CG.num_verts())]
        for i in range(CG.num_verts()):
            cm[i][i] = 1
        for u, v in CG.edge_iterator(labels=False):
            cm[u][v] = 2
            cm[v][u] = 2
        self._coxeter_group = CoxeterGroup(
            CoxeterMatrix(cm, index_set=G.vertices()))
        rels = tuple(
            F([i + 1, j + 1, -i - 1, -j - 1])
            for i, j in CG.edge_iterator(labels=False))  # +/- 1 for indexing
        FinitelyPresentedGroup.__init__(self, F, rels)
Exemplo n.º 3
0
    def __init__(self, coxeter_matrix, names):
        """
        Initialize ``self``.

        TESTS::

            sage: A = ArtinGroup(['D',4])
            sage: TestSuite(A).run()
            sage: A = ArtinGroup(['B',3], ['x','y','z'])
            sage: TestSuite(A).run()
        """
        self._coxeter_group = CoxeterGroup(coxeter_matrix)
        free_group = FreeGroup(names)
        rels = []
        # Generate the relations based on the Coxeter graph
        I = coxeter_matrix.index_set()
        for ii, i in enumerate(I):
            for j in I[ii + 1:]:
                m = coxeter_matrix[i, j]
                if m == Infinity:  # no relation
                    continue
                elt = [i, j] * m
                for ind in range(m, 2 * m):
                    elt[ind] = -elt[ind]
                rels.append(free_group(elt))
        FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
Exemplo n.º 4
0
    def __init__(self, names):
        """
        Python constructor.

        INPUT:

        - ``names`` -- a tuple of strings. The names of the
          generators.

        TESTS::

            sage: B1 = BraidGroup(5) # indirect doctest
            sage: B1
            Braid group on 5 strands
        """
        n = len(names)
        if n<2:
            raise ValueError("n must be an integer bigger than one")
        free_group = FreeGroup(names)
        rels = []
        for i in range(1, n):
            if i<n-1:
                rels.append(free_group([i, i+1, i, -i-1, -i, -i-1]))
            for j in range(i+2, n):
                rels.append(free_group([i, j, -i, -j]))
        FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
        self._nstrands_ = n+1
Exemplo n.º 5
0
    def __init__(self, names):
        """
        Python constructor.

        INPUT:

        - ``names`` -- a tuple of strings. The names of the
          generators.

        TESTS::

            sage: B1 = BraidGroup(5) # indirect doctest
            sage: B1
            Braid group on 5 strands

        Check that :trac:`14081` is fixed::

            sage: BraidGroup(2)
            Braid group on 2 strands
            sage: BraidGroup(('a',))
            Braid group on 2 strands
        """
        n = len(names)
        if n<1: #n is the number of generators, not the number of strands (see ticket 14081)
            raise ValueError("the number of strands must be an integer bigger than one")
        free_group = FreeGroup(names)
        rels = []
        for i in range(1, n):
            if i<n-1:
                rels.append(free_group([i, i+1, i, -i-1, -i, -i-1]))
            for j in range(i+2, n):
                rels.append(free_group([i, j, -i, -j]))
        FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
        self._nstrands_ = n+1
Exemplo n.º 6
0
    def __init__(self, names):
        """
        Python constructor.

        INPUT:

        - ``names`` -- a tuple of strings. The names of the
          generators.

        TESTS::

            sage: B1 = BraidGroup(5) # indirect doctest
            sage: B1
            Braid group on 5 strands
            sage: TestSuite(B1).run()


        Check that :trac:`14081` is fixed::

            sage: BraidGroup(2)
            Braid group on 2 strands
            sage: BraidGroup(('a',))
            Braid group on 2 strands

        Check that :trac:`15505` is fixed::

            sage: B=BraidGroup(4)
            sage: B.relations()
            (s0*s1*s0*s1^-1*s0^-1*s1^-1, s0*s2*s0^-1*s2^-1, s1*s2*s1*s2^-1*s1^-1*s2^-1)
            sage: B=BraidGroup('a,b,c,d,e,f')
            sage: B.relations()
            (a*b*a*b^-1*a^-1*b^-1,
             a*c*a^-1*c^-1,
             a*d*a^-1*d^-1,
             a*e*a^-1*e^-1,
             a*f*a^-1*f^-1,
             b*c*b*c^-1*b^-1*c^-1,
             b*d*b^-1*d^-1,
             b*e*b^-1*e^-1,
             b*f*b^-1*f^-1,
             c*d*c*d^-1*c^-1*d^-1,
             c*e*c^-1*e^-1,
             c*f*c^-1*f^-1,
             d*e*d*e^-1*d^-1*e^-1,
             d*f*d^-1*f^-1,
             e*f*e*f^-1*e^-1*f^-1)
        """
        n = len(names)
        if n < 1:  #n is the number of generators, not the number of strands (see ticket 14081)
            raise ValueError(
                "the number of strands must be an integer bigger than one")
        free_group = FreeGroup(names)
        rels = []
        for i in range(1, n):
            rels.append(free_group([i, i + 1, i, -i - 1, -i, -i - 1]))
            for j in range(i + 2, n + 1):
                rels.append(free_group([i, j, -i, -j]))
        FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
        self._nstrands_ = n + 1
Exemplo n.º 7
0
    def __init__(self, names):
        """
        Python constructor.

        INPUT:

        - ``names`` -- a tuple of strings. The names of the
          generators.

        TESTS::

            sage: B1 = BraidGroup(5) # indirect doctest
            sage: B1
            Braid group on 5 strands
            sage: TestSuite(B1).run()


        Check that :trac:`14081` is fixed::

            sage: BraidGroup(2)
            Braid group on 2 strands
            sage: BraidGroup(('a',))
            Braid group on 2 strands

        Check that :trac:`15505` is fixed::

            sage: B=BraidGroup(4)
            sage: B.relations()
            (s0*s1*s0*s1^-1*s0^-1*s1^-1, s0*s2*s0^-1*s2^-1, s1*s2*s1*s2^-1*s1^-1*s2^-1)
            sage: B=BraidGroup('a,b,c,d,e,f')
            sage: B.relations()
            (a*b*a*b^-1*a^-1*b^-1,
             a*c*a^-1*c^-1,
             a*d*a^-1*d^-1,
             a*e*a^-1*e^-1,
             a*f*a^-1*f^-1,
             b*c*b*c^-1*b^-1*c^-1,
             b*d*b^-1*d^-1,
             b*e*b^-1*e^-1,
             b*f*b^-1*f^-1,
             c*d*c*d^-1*c^-1*d^-1,
             c*e*c^-1*e^-1,
             c*f*c^-1*f^-1,
             d*e*d*e^-1*d^-1*e^-1,
             d*f*d^-1*f^-1,
             e*f*e*f^-1*e^-1*f^-1)
        """
        n = len(names)
        if n<1: #n is the number of generators, not the number of strands (see ticket 14081)
            raise ValueError("the number of strands must be an integer bigger than one")
        free_group = FreeGroup(names)
        rels = []
        for i in range(1, n):
            rels.append(free_group([i, i+1, i, -i-1, -i, -i-1]))
            for j in range(i+2, n+1):
                rels.append(free_group([i, j, -i, -j]))
        FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
        self._nstrands_ = n+1
Exemplo n.º 8
0
    def quotient(self, relations):
        """
        Return the quotient of self by the normal subgroup generated
        by the given elements.

        This quotient is a finitely presented groups with the same
        generators as ``self``, and relations given by the elements of
        ``relations``.

        INPUT:

        - ``relations`` -- A list/tuple/iterable with the elements of
          the free group.

        OUTPUT:

        A finitely presented group, with generators corresponding to
        the generators of the free group, and relations corresponding
        to the elements in ``relations``.

        EXAMPLES::

            sage: F.<a,b> = FreeGroup()
            sage: F.quotient([a*b^2*a, b^3])
            Finitely presented group < a, b | a*b^2*a, b^3 >

        Division is shorthand for :meth:`quotient` ::

            sage: F /  [a*b^2*a, b^3]
            Finitely presented group < a, b | a*b^2*a, b^3 >
        """
        from sage.groups.finitely_presented import FinitelyPresentedGroup
        return FinitelyPresentedGroup(self, tuple(relations))
Exemplo n.º 9
0
def CyclicPresentation(n):
    r"""
    Build cyclic group of order `n` as a finitely presented group.

    INPUT:

    - ``n`` -- The order of the cyclic presentation to be returned.

    OUTPUT:

    The cyclic group of order `n` as finite presentation.

    EXAMPLES::

        sage: groups.presentation.Cyclic(10)
        Finitely presented group < a | a^10 >
        sage: n = 8; C = groups.presentation.Cyclic(n)
        sage: C.as_permutation_group().is_isomorphic(CyclicPermutationGroup(n))
        True

    TESTS::

        sage: groups.presentation.Cyclic(0)
        Traceback (most recent call last):
        ...
        ValueError: finitely presented group order must be positive
    """
    n = Integer(n)
    if n < 1:
        raise ValueError('finitely presented group order must be positive')
    F = FreeGroup('a')
    rls = F([1])**n,
    return FinitelyPresentedGroup(F, rls)
Exemplo n.º 10
0
def QuaternionPresentation():
    r"""
    Build the Quaternion group of order 8 as a finitely presented group.

    OUTPUT:

    Quaternion group as a finite presentation.

    EXAMPLES::

        sage: Q = groups.presentation.Quaternion(); Q
        Finitely presented group < a, b | a^4, b^2*a^-2, a*b*a*b^-1 >
        sage: Q.as_permutation_group().is_isomorphic(QuaternionGroup())
        True

    TESTS::

        sage: Q = groups.presentation.Quaternion()
        sage: Q.order(), Q.is_abelian()
        (8, False)
        sage: Q.is_isomorphic(groups.presentation.DiCyclic(2))
        #I  Forcing finiteness test
        True
    """
    F = FreeGroup(['a', 'b'])
    rls = F([1])**4, F([2, 2, -1, -1]), F([1, 2, 1, -2])
    return FinitelyPresentedGroup(F, rls)
Exemplo n.º 11
0
def BinaryDihedralPresentation(n):
    r"""
    Build a binary dihedral group of order `4n` as a finitely presented group.

    The binary dihedral group `BD_n` has the following presentation
    (note that there is a typo in [Sun]_):

    .. MATH::

        BD_n = \langle x, y, z | x^2 = y^2 = z^n = x y z \rangle.

    INPUT:

    - ``n`` -- the value `n`

    OUTPUT:

    The binary dihedral group of order `4n` as finite presentation.

    EXAMPLES::

        sage: groups.presentation.BinaryDihedral(9)
        Finitely presented group < x, y, z | x^-2*y^2, x^-2*z^9, x^-1*y*z >

    TESTS::

        sage: for n in range(3, 9):
        ....:     P = groups.presentation.BinaryDihedral(n)
        ....:     M = groups.matrix.BinaryDihedral(n)
        ....:     assert P.is_isomorphic(M)
    """
    F = FreeGroup('x,y,z')
    x,y,z = F.gens()
    rls = (x**-2 * y**2, x**-2 * z**n, x**-2 * x*y*z)
    return FinitelyPresentedGroup(F, rls)
Exemplo n.º 12
0
    def __init__(self, G):
        """
        Initialize ``self``.

        INPUT:

        - ``G`` -- a graph

        TESTS::

            sage: G = RightAngledArtinGroup(graphs.CycleGraph(5))
            sage: TestSuite(G).run()
        """
        self._graph = G
        F = FreeGroup(names=['v{}'.format(v) for v in self._graph.vertices()])
        CG = Graph(G).complement() # Make sure it's mutable
        CG.relabel() # Standardize the labels
        rels = tuple(F([i+1, j+1, -i-1, -j-1]) for i,j in CG.edges(False)) #+/- 1 for indexing
        FinitelyPresentedGroup.__init__(self, F, rels)
Exemplo n.º 13
0
Arquivo: raag.py Projeto: Babyll/sage
    def __init__(self, G):
        """
        Initialize ``self``.

        INPUT:

        - ``G`` -- a graph

        TESTS::

            sage: G = RightAngledArtinGroup(graphs.CycleGraph(5))
            sage: TestSuite(G).run()
        """
        self._graph = G
        F = FreeGroup(names=['v{}'.format(v) for v in self._graph.vertices()])
        CG = Graph(G).complement() # Make sure it's mutable
        CG.relabel() # Standardize the labels
        rels = tuple(F([i+1, j+1, -i-1, -j-1]) for i,j in CG.edges(False)) #+/- 1 for indexing
        FinitelyPresentedGroup.__init__(self, F, rels)
Exemplo n.º 14
0
def DiCyclicPresentation(n):
    r"""
    Build the dicyclic group of order `4n`, for `n \geq 2`, as a finitely
    presented group.

    INPUT:

    - ``n`` -- positive integer, 2 or greater, determining the order of
      the group (`4n`).

    OUTPUT:

    The dicyclic group of order `4n` is defined by the presentation

    .. MATH::

        \langle a, x \mid a^{2n}=1, x^{2}=a^{n}, x^{-1}ax=a^{-1} \rangle

    .. NOTE::

        This group is also available as a permutation group via
        :class:`groups.permutation.DiCyclic <sage.groups.perm_gps.permgroup_named.DiCyclicGroup>`.

    EXAMPLES::

        sage: D = groups.presentation.DiCyclic(9); D
        Finitely presented group < a, b | a^18, b^2*a^-9, b^-1*a*b*a >
        sage: D.as_permutation_group().is_isomorphic(groups.permutation.DiCyclic(9))
        True

    TESTS::

        sage: Q = groups.presentation.DiCyclic(2)
        sage: Q.as_permutation_group().is_isomorphic(QuaternionGroup())
        True
        sage: for i in [5, 8, 12, 32]:
        ....:     A = groups.presentation.DiCyclic(i).as_permutation_group()
        ....:     B = groups.permutation.DiCyclic(i)
        ....:     assert A.is_isomorphic(B)
        sage: groups.presentation.DiCyclic(1)
        Traceback (most recent call last):
        ...
        ValueError: input integer must be greater than 1
    """
    n = Integer(n)
    if n < 2:
        raise ValueError('input integer must be greater than 1')

    F = FreeGroup(['a', 'b'])
    rls = F([1])**(2 * n), F([2, 2]) * F([-1])**n, F([-2, 1, 2, 1])
    return FinitelyPresentedGroup(F, rls)
Exemplo n.º 15
0
    def __init__(self, G, names):
        """
        Initialize ``self``.

        TESTS::

            sage: G = RightAngledArtinGroup(graphs.CycleGraph(5))
            sage: TestSuite(G).run()
        """
        self._graph = G
        F = FreeGroup(names=names)
        CG = Graph(G).complement()  # Make sure it's mutable
        CG.relabel()  # Standardize the labels
        cm = [[-1]*CG.num_verts() for _ in range(CG.num_verts())]
        for i in range(CG.num_verts()):
            cm[i][i] = 1
        for u,v in CG.edge_iterator(labels=False):
            cm[u][v] = 2
            cm[v][u] = 2
        self._coxeter_group = CoxeterGroup(CoxeterMatrix(cm, index_set=G.vertices()))
        rels = tuple(F([i + 1, j + 1, -i - 1, -j - 1])
                     for i, j in CG.edge_iterator(labels=False))  # +/- 1 for indexing
        FinitelyPresentedGroup.__init__(self, F, rels)
Exemplo n.º 16
0
def SymmetricPresentation(n):
    r"""
    Build the Symmetric group of order `n!` as a finitely presented group.

    INPUT:

    - ``n`` -- The size of the underlying set of arbitrary symbols being acted
      on by the Symmetric group of order `n!`.

    OUTPUT:

    Symmetric group as a finite presentation, implementation uses GAP to find an
    isomorphism from a permutation representation to a finitely presented group
    representation. Due to this fact, the exact output presentation may not be
    the same for every method call on a constant ``n``.

    EXAMPLES::

        sage: S4 = groups.presentation.Symmetric(4)
        sage: S4.as_permutation_group().is_isomorphic(SymmetricGroup(4))
        True

    TESTS::

        sage: S = [groups.presentation.Symmetric(i) for i in range(1,4)]; S[0].order()
        1
        sage: S[1].order(), S[2].as_permutation_group().is_isomorphic(DihedralGroup(3))
        (2, True)
        sage: S5 = groups.presentation.Symmetric(5)
        sage: perm_S5 = S5.as_permutation_group(); perm_S5.is_isomorphic(SymmetricGroup(5))
        True
        sage: groups.presentation.Symmetric(8).order()
        40320
    """
    from sage.groups.perm_gps.permgroup_named import SymmetricGroup
    from sage.groups.free_group import _lexi_gen

    n = Integer(n)
    perm_rep = SymmetricGroup(n)
    GAP_fp_rep = libgap.Image(
        libgap.IsomorphismFpGroupByGenerators(perm_rep, perm_rep.gens()))
    image_gens = GAP_fp_rep.FreeGeneratorsOfFpGroup()
    name_itr = _lexi_gen()  # Python generator object for variable names
    F = FreeGroup([next(name_itr) for x in perm_rep.gens()])
    ret_rls = tuple([
        F(rel_word.TietzeWordAbstractWord(image_gens).sage())
        for rel_word in GAP_fp_rep.RelatorsOfFpGroup()
    ])
    return FinitelyPresentedGroup(F, ret_rls)
Exemplo n.º 17
0
def AlternatingPresentation(n):
    r"""
    Build the Alternating group of order `n!/2` as a finitely presented group.

    INPUT:

    - ``n`` -- The size of the underlying set of arbitrary symbols being acted
      on by the Alternating group of order `n!/2`.

    OUTPUT:

    Alternating group as a finite presentation, implementation uses GAP to find an
    isomorphism from a permutation representation to a finitely presented group
    representation. Due to this fact, the exact output presentation may not be
    the same for every method call on a constant ``n``.

    EXAMPLES::

        sage: A6 = groups.presentation.Alternating(6)
        sage: A6.as_permutation_group().is_isomorphic(AlternatingGroup(6)), A6.order()
        (True, 360)

    TESTS::

        sage: #even permutation test..
        sage: A1 = groups.presentation.Alternating(1); A2 = groups.presentation.Alternating(2)
        sage: A1.is_isomorphic(A2), A1.order()
        (True, 1)
        sage: A3 = groups.presentation.Alternating(3); A3.order(), A3.as_permutation_group().is_cyclic()
        (3, True)
        sage: A8 = groups.presentation.Alternating(8); A8.order()
        20160
    """
    from sage.groups.perm_gps.permgroup_named import AlternatingGroup
    from sage.groups.free_group import _lexi_gen

    n = Integer(n)
    perm_rep = AlternatingGroup(n)
    GAP_fp_rep = libgap.Image(
        libgap.IsomorphismFpGroupByGenerators(perm_rep, perm_rep.gens()))
    image_gens = GAP_fp_rep.FreeGeneratorsOfFpGroup()
    name_itr = _lexi_gen()  # Python generator object for variable names
    F = FreeGroup([next(name_itr) for x in perm_rep.gens()])
    ret_rls = tuple([
        F(rel_word.TietzeWordAbstractWord(image_gens).sage())
        for rel_word in GAP_fp_rep.RelatorsOfFpGroup()
    ])
    return FinitelyPresentedGroup(F, ret_rls)
Exemplo n.º 18
0
    def quotient(self, relations, **kwds):
        """
        Return the quotient of ``self`` by the normal subgroup generated
        by the given elements.

        This quotient is a finitely presented groups with the same
        generators as ``self``, and relations given by the elements of
        ``relations``.

        INPUT:

        - ``relations`` -- A list/tuple/iterable with the elements of
          the free group.
        - further named arguments, that are passed to the constructor
          of a finitely presented group.

        OUTPUT:

        A finitely presented group, with generators corresponding to
        the generators of the free group, and relations corresponding
        to the elements in ``relations``.

        EXAMPLES::

            sage: F.<a,b> = FreeGroup()
            sage: F.quotient([a*b^2*a, b^3])
            Finitely presented group < a, b | a*b^2*a, b^3 >

        Division is shorthand for :meth:`quotient` ::

            sage: F /  [a*b^2*a, b^3]
            Finitely presented group < a, b | a*b^2*a, b^3 >

        Relations are converted to the free group, even if they are not
        elements of it (if possible) ::

            sage: F1.<a,b,c,d>=FreeGroup()
            sage: F2.<a,b>=FreeGroup()
            sage: r=a*b/a
            sage: r.parent()
            Free Group on generators {a, b}
            sage: F1/[r]
            Finitely presented group < a, b, c, d | a*b*a^-1 >

        """
        from sage.groups.finitely_presented import FinitelyPresentedGroup
        return FinitelyPresentedGroup(self, tuple(map(self, relations)),
                                      **kwds)
Exemplo n.º 19
0
def KleinFourPresentation():
    r"""
    Build the Klein group of order `4` as a finitely presented group.

    OUTPUT:

    Klein four group (`C_2 \times C_2`) as a finitely presented group.

    EXAMPLES::

        sage: K = groups.presentation.KleinFour(); K
        Finitely presented group < a, b | a^2, b^2, a^-1*b^-1*a*b >
    """
    F = FreeGroup(['a', 'b'])
    rls = F([1])**2, F([2])**2, F([-1]) * F([-2]) * F([1]) * F([2])
    return FinitelyPresentedGroup(F, rls)
Exemplo n.º 20
0
def DihedralPresentation(n):
    r"""
    Build the Dihedral group of order `2n` as a finitely presented group.

    INPUT:

    - ``n`` -- The size of the set that `D_n` is acting on.

    OUTPUT:

    Dihedral group of order `2n`.

    EXAMPLES::

        sage: D = groups.presentation.Dihedral(7); D
        Finitely presented group < a, b | a^7, b^2, (a*b)^2 >
        sage: D.as_permutation_group().is_isomorphic(DihedralGroup(7))
        True

    TESTS::

        sage: n = 9
        sage: D = groups.presentation.Dihedral(n)
        sage: D.ngens() == 2
        True
        sage: groups.presentation.Dihedral(0)
        Traceback (most recent call last):
        ...
        ValueError: finitely presented group order must be positive
    """
    n = Integer(n)
    if n < 1:
        raise ValueError('finitely presented group order must be positive')
    F = FreeGroup(['a', 'b'])
    rls = F([1])**n, F([2])**2, (F([1]) * F([2]))**2
    return FinitelyPresentedGroup(F, rls)
Exemplo n.º 21
0
def FinitelyGeneratedHeisenbergPresentation(n=1, p=0):
    r"""
    Return a finite presentation of the Heisenberg group.

    The Heisenberg group is the group of `(n+2) \times (n+2)` matrices
    over a ring `R` with diagonal elements equal to 1, first row and
    last column possibly nonzero, and all the other entries equal to zero.

    INPUT:

    - ``n`` -- the degree of the Heisenberg group

    - ``p`` -- (optional) a prime number, where we construct the
      Heisenberg group over the finite field `\ZZ/p\ZZ`
 
    OUTPUT:

    Finitely generated Heisenberg group over the finite field
    of order ``p`` or over the integers.

    .. SEEALSO::

        :class:`~sage.groups.matrix_gps.heisenberg.HeisenbergGroup`

    EXAMPLES::

        sage: H = groups.presentation.Heisenberg(); H
        Finitely presented group < x1, y1, z |
         x1*y1*x1^-1*y1^-1*z^-1, z*x1*z^-1*x1^-1, z*y1*z^-1*y1^-1 >
        sage: H.order()
        +Infinity
        sage: r1, r2, r3 = H.relations()
        sage: A = matrix([[1, 1, 0], [0, 1, 0], [0, 0, 1]])
        sage: B = matrix([[1, 0, 0], [0, 1, 1], [0, 0, 1]])
        sage: C = matrix([[1, 0, 1], [0, 1, 0], [0, 0, 1]])
        sage: r1(A, B, C)
        [1 0 0]
        [0 1 0]
        [0 0 1]
        sage: r2(A, B, C)
        [1 0 0]
        [0 1 0]
        [0 0 1]
        sage: r3(A, B, C)
        [1 0 0]
        [0 1 0]
        [0 0 1]
        sage: p = 3
        sage: Hp = groups.presentation.Heisenberg(p=3)
        sage: Hp.order() == p**3 
        True
        sage: Hnp = groups.presentation.Heisenberg(n=2, p=3)
        sage: len(Hnp.relations())
        13

    REFERENCES:

    - :wikipedia:`Heisenberg_group`
    """
    n = Integer(n)
    if n < 1:
        raise ValueError('n must be a positive integer')

    # generators' names are x1, .., xn, y1, .., yn, z
    vx = ['x' + str(i) for i in range(1, n + 1)]
    vy = ['y' + str(i) for i in range(1, n + 1)]
    str_generators = ', '.join(vx + vy + ['z'])

    F = FreeGroup(str_generators)
    x = F.gens()[0:n]  # list of generators x1, x2, ..., xn
    y = F.gens()[n:2 * n]  # list of generators x1, x2, ..., xn
    z = F.gen(n * 2)

    def commutator(a, b):
        return a * b * a**-1 * b**-1

    # First set of relations: [xi, yi] = z
    r1 = [commutator(x[i], y[i]) * z**-1 for i in range(n)]
    # Second set of relations: [z, xi] = 1
    r2 = [commutator(z, x[i]) for i in range(n)]
    # Third set of relations: [z, yi] = 1
    r3 = [commutator(z, y[i]) for i in range(n)]
    # Fourth set of relations: [xi, yi] = 1 for i != j
    r4 = [commutator(x[i], y[j]) for i in range(n) for j in range(n) if i != j]
    rls = r1 + r2 + r3 + r4

    from sage.sets.primes import Primes
    if p not in Primes() and p != 0:
        raise ValueError("p must be 0 or a prime number")
    if p > 0:
        rls += [w**p for w in F.gens()]
    return FinitelyPresentedGroup(F, tuple(rls))
Exemplo n.º 22
0
def FinitelyGeneratedAbelianPresentation(int_list):
    r"""
    Return canonical presentation of finitely generated abelian group.

    INPUT:

    - ``int_list`` -- List of integers defining the group to be returned, the defining list
      is reduced to the invariants of the input list before generating the corresponding
      group.

    OUTPUT:

    Finitely generated abelian group, `\ZZ_{n_1} \times \ZZ_{n_2} \times \cdots \times \ZZ_{n_k}`
    as a finite presentation, where `n_i` forms the invariants of the input list.

    EXAMPLES::

        sage: groups.presentation.FGAbelian([2,2])
        Finitely presented group < a, b | a^2, b^2, a^-1*b^-1*a*b >
        sage: groups.presentation.FGAbelian([2,3])
        Finitely presented group < a | a^6 >
        sage: groups.presentation.FGAbelian([2,4])
        Finitely presented group < a, b | a^2, b^4, a^-1*b^-1*a*b >

    You can create free abelian groups::

        sage: groups.presentation.FGAbelian([0])
        Finitely presented group < a |  >
        sage: groups.presentation.FGAbelian([0,0])
        Finitely presented group < a, b | a^-1*b^-1*a*b >
        sage: groups.presentation.FGAbelian([0,0,0])
        Finitely presented group < a, b, c | a^-1*b^-1*a*b, a^-1*c^-1*a*c, b^-1*c^-1*b*c >

    And various infinite abelian groups::

        sage: groups.presentation.FGAbelian([0,2])
        Finitely presented group < a, b | a^2, a^-1*b^-1*a*b >
        sage: groups.presentation.FGAbelian([0,2,2])
        Finitely presented group < a, b, c | a^2, b^2, a^-1*b^-1*a*b, a^-1*c^-1*a*c, b^-1*c^-1*b*c >

    Outputs are reduced to minimal generators and relations::

        sage: groups.presentation.FGAbelian([3,5,2,7,3])
        Finitely presented group < a, b | a^3, b^210, a^-1*b^-1*a*b >
        sage: groups.presentation.FGAbelian([3,210])
        Finitely presented group < a, b | a^3, b^210, a^-1*b^-1*a*b >

    The trivial group is an acceptable output::

        sage: groups.presentation.FGAbelian([])
        Finitely presented group <  |  >
        sage: groups.presentation.FGAbelian([1])
        Finitely presented group <  |  >
        sage: groups.presentation.FGAbelian([1,1,1,1,1,1,1,1,1,1])
        Finitely presented group <  |  >

    Input list must consist of positive integers::

        sage: groups.presentation.FGAbelian([2,6,3,9,-4])
        Traceback (most recent call last):
        ...
        ValueError: input list must contain nonnegative entries
        sage: groups.presentation.FGAbelian([2,'a',4])
        Traceback (most recent call last):
        ...
        TypeError: unable to convert 'a' to an integer

    TESTS::

        sage: ag = groups.presentation.FGAbelian([2,2])
        sage: ag.as_permutation_group().is_isomorphic(groups.permutation.KleinFour())
        True
        sage: G = groups.presentation.FGAbelian([2,4,8])
        sage: C2 = CyclicPermutationGroup(2)
        sage: C4 = CyclicPermutationGroup(4)
        sage: C8 = CyclicPermutationGroup(8)
        sage: gg = (C2.direct_product(C4)[0]).direct_product(C8)[0]
        sage: gg.is_isomorphic(G.as_permutation_group())
        True
        sage: all(groups.presentation.FGAbelian([i]).as_permutation_group().is_isomorphic(groups.presentation.Cyclic(i).as_permutation_group()) for i in [2..35])
        True
    """
    from sage.groups.free_group import _lexi_gen
    check_ls = [Integer(x) for x in int_list if Integer(x) >= 0]
    if len(check_ls) != len(int_list):
        raise ValueError('input list must contain nonnegative entries')

    col_sp = diagonal_matrix(int_list).column_space()
    invariants = FGP_Module(ZZ**(len(int_list)), col_sp).invariants()
    name_gen = _lexi_gen()
    F = FreeGroup([next(name_gen) for i in invariants])
    ret_rls = [
        F([i + 1])**invariants[i] for i in range(len(invariants))
        if invariants[i] != 0
    ]

    # Build commutator relations
    gen_pairs = [[F.gen(i), F.gen(j)] for i in range(F.ngens() - 1)
                 for j in range(i + 1, F.ngens())]
    ret_rls = ret_rls + [
        x[0]**(-1) * x[1]**(-1) * x[0] * x[1] for x in gen_pairs
    ]
    return FinitelyPresentedGroup(F, tuple(ret_rls))