def n_simplex(self, dim_n=3, project=True): """ Return a rational approximation to a regular simplex in dimension ``dim_n``. INPUT: - ``dim_n`` -- The dimension of the simplex, a positive integer. - ``project`` -- Optional argument, whether to project orthogonally. Default is True. OUTPUT: A Polyhedron object of the ``dim_n``-dimensional simplex. EXAMPLES:: sage: s5 = polytopes.n_simplex(5) sage: s5.dim() 5 """ verts = Permutations([0 for i in range(dim_n)] + [1]).list() if project: verts = [Polytopes.project_1(x) for x in verts] return Polyhedron(vertices=verts)
def Kirkman_icosahedron(self): """ A non-uniform icosahedron with interesting properties. See [Fetter2012]_ for details. OUTPUT: The Kirkman icosahedron, a 3-dimensional polyhedron with 20 vertices, 20 faces, and 38 edges. EXAMPLES:: sage: KI = polytopes.Kirkman_icosahedron() sage: KI.f_vector() (1, 20, 38, 20, 1) sage: vertices = KI.vertices() sage: edges = [[vector(edge[0]),vector(edge[1])] for edge in KI.bounded_edges()] sage: edge_lengths = [norm(edge[0]-edge[1]) for edge in edges] sage: union(edge_lengths) [7, 8, 9, 11, 12, 14, 16] """ vertices = [[-12, -4, 0], [-12, 4, 0], [-9, -6, -6], [-9, -6, 6], [-9, 6, -6], [-9, 6, 6], [-6, 0, -12], [-6, 0, 12], [0, -12, -8], [0, -12, 8], [0, 12, -8], [0, 12, 8], [6, 0, -12], [6, 0, 12], [9, -6, -6], [9, -6, 6], [9, 6, -6], [9, 6, 6], [12, -4, 0], [12, 4, 0]] return Polyhedron(vertices=vertices)
def small_rhombicuboctahedron(self): """ Return an Archimedean solid with 24 vertices and 26 faces. EXAMPLES:: sage: sr = polytopes.small_rhombicuboctahedron() sage: sr.n_vertices() 24 sage: sr.n_inequalities() 26 """ verts = [[-3 / 2, -1 / 2, -1 / 2], [-3 / 2, -1 / 2, 1 / 2], [-3 / 2, 1 / 2, -1 / 2], [-3 / 2, 1 / 2, 1 / 2], [-1 / 2, -3 / 2, -1 / 2], [-1 / 2, -3 / 2, 1 / 2], [-1 / 2, -1 / 2, -3 / 2], [-1 / 2, -1 / 2, 3 / 2], [-1 / 2, 1 / 2, -3 / 2], [-1 / 2, 1 / 2, 3 / 2], [-1 / 2, 3 / 2, -1 / 2], [-1 / 2, 3 / 2, 1 / 2], [1 / 2, -3 / 2, -1 / 2], [1 / 2, -3 / 2, 1 / 2], [1 / 2, -1 / 2, -3 / 2], [1 / 2, -1 / 2, 3 / 2], [1 / 2, 1 / 2, -3 / 2], [1 / 2, 1 / 2, 3 / 2], [1 / 2, 3 / 2, -1 / 2], [1 / 2, 3 / 2, 1 / 2], [3 / 2, -1 / 2, -1 / 2], [3 / 2, -1 / 2, 1 / 2], [3 / 2, 1 / 2, -1 / 2], [3 / 2, 1 / 2, 1 / 2]] return Polyhedron(vertices=verts)
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)
def great_rhombicuboctahedron(self, base_ring=QQ): """ Return an Archimedean solid with 48 vertices and 26 faces. EXAMPLES:: sage: gr = polytopes.great_rhombicuboctahedron() sage: gr.n_vertices() 48 sage: gr.n_inequalities() 26 """ v1 = QQ(131739771357/54568400000) v2 = QQ(104455571357/27284200000) verts = [ [1, v1, v2], [1, v2, v1], [v1, 1, v2], [v1, v2, 1], [v2, 1, v1], [v2, v1, 1] ] verts = verts + [[x[0],x[1],-x[2]] for x in verts] verts = verts + [[x[0],-x[1],x[2]] for x in verts] verts = verts + [[-x[0],x[1],x[2]] for x in verts] if base_ring!=QQ: verts = [base_ring(v) for v in verts] return Polyhedron(vertices=verts, base_ring=base_ring)
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)
def rhombic_dodecahedron(self): """ This face-regular, vertex-uniform polytope is dual to the cuboctahedron. It has 14 vertices and 12 faces. EXAMPLES:: sage: rd = polytopes.rhombic_dodecahedron() sage: rd.n_vertices() 14 sage: rd.n_inequalities() 12 """ v = [[1, 1, 1], [1, 1, -1], [1, -1, 1], [1, -1, -1], [-1, 1, 1], [-1, 1, -1], [-1, -1, 1], [-1, -1, -1], [0, 0, 2], [0, 2, 0], [2, 0, 0], [0, 0, -2], [0, -2, 0], [-2, 0, 0]] return Polyhedron(vertices=v)
def cuboctahedron(self): """ An Archimedean solid with 12 vertices and 14 faces. Dual to the rhombic dodecahedron. EXAMPLES:: sage: co = polytopes.cuboctahedron() sage: co.n_vertices() 12 sage: co.n_inequalities() 14 """ one = Integer(1) v = [ [0, -one/2, -one/2], [0, one/2, -one/2], [one/2, -one/2, 0], [one/2, one/2, 0], [one/2, 0, one/2], [one/2, 0, -one/2], [0, one/2, one/2], [0, -one/2, one/2], [-one/2, 0, one/2], [-one/2, one/2, 0], [-one/2, 0, -one/2], [-one/2, -one/2, 0] ] return Polyhedron(vertices=v)
def Birkhoff_polytope(self, n): """ Return the Birkhoff polytope with n! vertices. Each vertex is a (flattened) n by n permutation matrix. INPUT: - ``n`` -- a positive integer giving the size of the permutation matrices. EXAMPLES:: sage: b3 = polytopes.Birkhoff_polytope(3) sage: b3.n_vertices() 6 """ verts = [] for p in Permutations(range(1,n+1)): verts += [ [Polytopes._pfunc(i,j,p) for j in range(1,n+1) for i in range(1,n+1) ] ] return Polyhedron(vertices=verts)
def twenty_four_cell(self): """ Return the standard 24-cell polytope. OUTPUT: A Polyhedron object of the 4-dimensional 24-cell, a regular polytope. The coordinates of this polytope are exact. EXAMPLES:: sage: p24 = polytopes.twenty_four_cell() sage: v = p24.vertex_generator().next() sage: for adj in v.neighbors(): print adj A vertex at (-1/2, -1/2, -1/2, 1/2) A vertex at (-1/2, -1/2, 1/2, -1/2) A vertex at (-1, 0, 0, 0) A vertex at (-1/2, 1/2, -1/2, -1/2) A vertex at (0, -1, 0, 0) A vertex at (0, 0, -1, 0) A vertex at (0, 0, 0, -1) A vertex at (1/2, -1/2, -1/2, -1/2) """ 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) verts = verts + Permutations([0, 0, 0, 1]).list() verts = verts + Permutations([0, 0, 0, -1]).list() return Polyhedron(vertices=verts)
def regular_polygon(self, n, base_ring=QQ): """ Return a regular polygon with `n` vertices. Over the rational field the vertices may not be exact. INPUT: - ``n`` -- a positive integer, the number of vertices. - ``base_ring`` -- a ring in which the coordinates will lie. EXAMPLES:: sage: octagon = polytopes.regular_polygon(8) sage: len(octagon.vertices()) 8 sage: polytopes.regular_polygon(3).vertices() (A vertex at (-125283617/144665060, -500399958596723/1000799917193445), A vertex at (0, 1), A vertex at (94875313/109552575, -1000799917193444/2001599834386889)) sage: polytopes.regular_polygon(3, base_ring=RealField(100)).vertices() (A vertex at (0.00000000000000000000000000000, 1.0000000000000000000000000000), A vertex at (0.86602540378443864676372317075, -0.50000000000000000000000000000), A vertex at (-0.86602540378443864676372317076, -0.50000000000000000000000000000)) sage: polytopes.regular_polygon(3, base_ring=RealField(10)).vertices() (A vertex at (0.00, 1.0), A vertex at (0.87, -0.50), A vertex at (-0.86, -0.50)) """ try: omega = 2 * base_ring.pi() / n except AttributeError: omega = 2 * RR.pi() / n verts = [] for i in range(n): t = omega * i verts.append([base_ring(t.sin()), base_ring(t.cos())]) return Polyhedron(vertices=verts, base_ring=base_ring)
def buckyball(self, base_ring=QQ): """ Also known as the truncated icosahedron, an Archimedean solid. It has 32 faces and 60 vertices. Rational coordinates are not exact. EXAMPLES:: sage: bb = polytopes.buckyball() sage: bb.n_vertices() 60 sage: bb.n_inequalities() # number of facets 32 sage: bb.base_ring() Rational Field """ # Note: QQ would give some incorrecty subdivided facets p = self.icosahedron(base_ring=RDF).edge_truncation() if base_ring==RDF: return p # Converting with low precision to save time. new_ieqs = [[int(1000*x)/QQ(1000) for x in y] for y in p.inequalities()] return Polyhedron(ieqs=new_ieqs)