示例#1
0
文件: library.py 项目: biasse/sage
    def six_hundred_cell(self):
        """
        Return the standard 600-cell polytope.

        OUTPUT:

        A Polyhedron object of the 4-dimensional 600-cell, a regular
        polytope.  In many ways this is an analogue of the
        icosahedron.  The coordinates of this polytope are rational
        approximations of the true coordinates of the 600-cell, some
        of which involve the (irrational) golden ratio.

        EXAMPLES::

            sage: p600 = polytopes.six_hundred_cell() # not tested - very long time
            sage: len(list(p600.bounded_edges())) # not tested - very long time
            120
        """
        verts = []
        q12 = QQ(1) / 2
        base = [q12, q12, q12, q12]
        for i in range(2):
            for j in range(2):
                for k in range(2):
                    for l in range(2):
                        verts.append([x for x in base])
                        base[3] = base[3] * (-1)
                    base[2] = base[2] * (-1)
                base[1] = base[1] * (-1)
            base[0] = base[0] * (-1)
        for x in permutations([0, 0, 0, 1]):
            verts.append(x)
        for x in permutations([0, 0, 0, -1]):
            verts.append(x)
        g = QQ(1618033) / 1000000  # Golden ratio approximation
        verts = verts + [
            i([q12, g / 2, 1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([q12, g / 2, -1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([q12, -g / 2, 1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([q12, -g / 2, -1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([-q12, g / 2, 1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([-q12, g / 2, -1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([-q12, -g / 2, 1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        verts = verts + [
            i([-q12, -g / 2, -1 / (g * 2), 0]) for i in AlternatingGroup(4)
        ]
        return Polyhedron(vertices=verts)
示例#2
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)
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)
示例#4
0
    def six_hundred_cell(self, exact=False):
        """
        Return the standard 600-cell polytope.

        The 600-cell is a 4-dimensional regular polytope. In many ways this is
        an analogue of the icosahedron.

        .. WARNING::

            The coordinates are not exact by default. The computation with exact
            coordinates takes a huge amount of time.

        INPUT:

        - ``exact`` - (boolean, default ``False``) if ``True`` use exact
          coordinates instead of floating point approximations

        EXAMPLES::

            sage: p600 = polytopes.six_hundred_cell()
            sage: p600
            A 4-dimensional polyhedron in RDF^4 defined as the convex hull of 120 vertices
            sage: p600.f_vector()
            (1, 120, 720, 1200, 600, 1)

        Computation with exact coordinates is currently too long to be useful::

            sage: p600 = polytopes.six_hundred_cell(exact=True) # not tested - very long time
            sage: len(list(p600.bounded_edges()))               # not tested - very long time
            120
        """
        if exact:
            from sage.rings.number_field.number_field import QuadraticField
            K = QuadraticField(5, 'sqrt5')
            sqrt5 = K.gen()
            g = (1 + sqrt5) / 2
            base_ring = K
        else:
            g = (1 + RDF(5).sqrt()) / 2
            base_ring = RDF

        q12 = base_ring(1) / base_ring(2)
        z = base_ring.zero()
        verts = [[s1 * q12, s2 * q12, s3 * q12, s4 * q12]
                 for s1, s2, s3, s4 in itertools.product([1, -1], repeat=4)]
        V = (base_ring)**4
        verts.extend(V.basis())
        verts.extend(-v for v in V.basis())
        pts = [[s1 * q12, s2 * g / 2, s3 / (2 * g), z]
               for (s1, s2, s3) in itertools.product([1, -1], repeat=3)]
        for p in AlternatingGroup(4):
            verts.extend(p(x) for x in pts)
        return Polyhedron(vertices=verts, base_ring=base_ring)
示例#5
0
    def icosahedron(self, base_ring=QQ):
        """
        Return an icosahedron with edge length 1.

        INPUT:

        - ``base_ring`` -- Either ``QQ`` or ``RDF``.

        OUTPUT:

        A Polyhedron object of a floating point or rational
        approximation to the regular 3d icosahedron.

        If ``base_ring=QQ``, a rational approximation is used and the
        points are not exactly the vertices of the icosahedron. The
        icosahedron's coordinates contain the golden ratio, so there
        is no exact representation possible.

        EXAMPLES::

            sage: ico = polytopes.icosahedron()
            sage: sum(sum( ico.vertex_adjacency_matrix() ))/2
            30
        """
        if base_ring == QQ:
            g = QQ(1618033) / 1000000  # Golden ratio approximation
            r12 = QQ(1) / 2
        elif base_ring == RDF:
            g = RDF((1 + sqrt(5)) / 2)
            r12 = RDF(QQ(1) / 2)
        else:
            raise ValueError("field must be QQ or RDF.")
        verts = [i([0, r12, g / 2]) for i in AlternatingGroup(3)]
        verts = verts + [i([0, r12, -g / 2]) for i in AlternatingGroup(3)]
        verts = verts + [i([0, -r12, g / 2]) for i in AlternatingGroup(3)]
        verts = verts + [i([0, -r12, -g / 2]) for i in AlternatingGroup(3)]
        return Polyhedron(vertices=verts, base_ring=base_ring)
示例#6
0
文件: library.py 项目: matsen/sage
    def icosidodecahedron(self, exact=True):
        """
        Return the Icosidodecahedron

        The Icosidodecahedron is a polyhedron with twenty triangular faces and
        twelve pentagonal faces. For more information see the
        :wikipedia:`Icosidodecahedron`.

        INPUT:

        - ``exact`` -- (boolean, default ``True``) If ``False`` use an
          approximate ring for the coordinates.

        EXAMPLES::

            sage: gr = polytopes.icosidodecahedron()
            sage: gr.f_vector()
            (1, 30, 60, 32, 1)

        TESTS::

            sage: polytopes.icosidodecahedron(exact=False)
            A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 30 vertices
        """
        from sage.rings.number_field.number_field import QuadraticField
        from itertools import product

        K = QuadraticField(5, 'sqrt5')
        one = K.one()
        phi = (one + K.gen()) / 2

        gens = [((-1)**a * one / 2, (-1)**b * phi / 2,
                 (-1)**c * (one + phi) / 2)
                for a, b, c in product([0, 1], repeat=3)]
        gens.extend([(0, 0, phi), (0, 0, -phi)])

        verts = []
        for p in AlternatingGroup(3):
            verts.extend(p(x) for x in gens)

        if exact:
            return Polyhedron(vertices=verts, base_ring=K)
        else:
            verts = [(RR(x), RR(y), RR(z)) for x, y, z in verts]
            return Polyhedron(vertices=verts)
示例#7
0
    def icosahedron(self, exact=True, base_ring=None):
        """
        Return an icosahedron with edge length 1.

        The icosahedron is one of the Platonic sold. It has 20 faces and is dual
        to the :meth:`dodecahedron`.

        INPUT:

        - ``exact`` -- (boolean, default ``True``) If ``False`` use an
          approximate ring for the coordinates.

        - ``base_ring`` -- (optional) the ring in which the coordinates will
          belong to.  Note that this ring must contain `\sqrt(5)`. If it is not
          provided and ``exact=True`` it will be the number field
          `\QQ[\sqrt(5)]` and if ``exact=False`` it will be the real double
          field.

        EXAMPLES::

            sage: ico = polytopes.icosahedron()
            sage: ico.f_vector()
            (1, 12, 30, 20, 1)
            sage: ico.volume()
            5/12*sqrt5 + 5/4

        Its non exact version::

            sage: ico = polytopes.icosahedron(exact=False)
            sage: ico.base_ring()
            Real Double Field
            sage: ico.volume()
            2.1816949907715726

        A version using `AA <sage.rings.qqbar.AlgebraicRealField>`::

            sage: ico = polytopes.icosahedron(base_ring=AA)   # long time
            sage: ico.base_ring()                             # long time
            Algebraic Real Field
            sage: ico.volume()                                # long time
            2.181694990624913?

        Note that if base ring is provided it must contain the square root of
        `5`. Otherwise you will get an error::

            sage: polytopes.icosahedron(base_ring=QQ)
            Traceback (most recent call last):
            ...
            TypeError: unable to convert 1/4*sqrt(5) + 1/4 to a rational
        """
        if base_ring is None and exact:
            from sage.rings.number_field.number_field import QuadraticField
            K = QuadraticField(5, 'sqrt5')
            sqrt5 = K.gen()
            g = (1 + sqrt5) / 2
            base_ring = K
        else:
            if base_ring is None:
                base_ring = RDF
            g = (1 + base_ring(5).sqrt()) / 2

        r12 = base_ring.one() / 2
        z = base_ring.zero()
        pts = [[z, s1 * r12, s2 * g / 2]
               for s1, s2 in itertools.product([1, -1], repeat=2)]
        verts = [p(v) for p in AlternatingGroup(3) for v in pts]
        return Polyhedron(vertices=verts, base_ring=base_ring)
print('')

# Use `g` as shorthand for the multiplication operation.
g = b.operations['*']
print('Perform multiplication on the pair (0,1) and give the result.')
print(g(0, 1))
print('')

print('Check the canonical ordering on `b`.')
print(b.canonical_order)
print('')

print('This ordering is used to create the action matrix for addition by 2.')
# Write "add 2" as a lambda function.
f = lambda x: b.operations['+'](x, b.canonical_order[1])
print(b.action_matrix(f))
print('')

print(
    'An example using the ``GroupStructure`` device with the alternating group on 5 letters follows.'
)
c = GroupStructure(AlternatingGroup(5))
print(c)
print('')

# Use `h` as shorthand for the group operation.
h = c.operations['*']
x = list(c.elements)[5]
y = list(c.elements)[26]
print('We multiply {} and {}.'.format(x, y))
print(h(x, y))