Library of commonly used, famous, or interesting polytopes

This module gathers several constructors of polytopes that can be reached through polytopes.<tab>. For example, here is the hypercube in dimension 5:

sage: polytopes.hypercube(5)
A 5-dimensional polyhedron in ZZ^5 defined as the convex hull of 32 vertices

The following constructions are available

Birkhoff_polytope()
associahedron()
buckyball()
cross_polytope()
cube()
cuboctahedron()
cyclic_polytope()
dodecahedron()
flow_polytope()
Gosset_3_21()
grand_antiprism()
great_rhombicuboctahedron()
hypercube()
hypersimplex()
icosahedron()
icosidodecahedron()
Kirkman_icosahedron()
octahedron()
parallelotope()
pentakis_dodecahedron()
permutahedron()
regular_polygon()
rhombic_dodecahedron()
rhombicosidodecahedron()
simplex()
six_hundred_cell()
small_rhombicuboctahedron()
snub_cube()
snub_dodecahedron()
tetrahedron()
truncated_cube()
truncated_dodecahedron()
truncated_icosidodecahedron()
truncated_tetrahedron()
truncated_octahedron()
twenty_four_cell()
class sage.geometry.polyhedron.library.Polytopes

A class of constructors for commonly used, famous, or interesting polytopes.

Birkhoff_polytope(n, backend=None)

Return the Birkhoff polytope with \(n!\) vertices.

The vertices of this polyhedron are the (flattened) \(n\) by \(n\) permutation matrices. So the ambient vector space has dimension \(n^2\) but the dimension of the polyhedron is \((n-1)^2\).

INPUT:

  • n – a positive integer giving the size of the permutation matrices.
  • backend – the backend to use to create the polytope.

See also

sage.matrix.matrix2.Matrix.as_sum_of_permutations() – return the current matrix as a sum of permutation matrices

EXAMPLES:

sage: b3 = polytopes.Birkhoff_polytope(3)
sage: b3.f_vector()
(1, 6, 15, 18, 9, 1)
sage: b3.ambient_dim(), b3.dim()
(9, 4)
sage: b3.is_lattice_polytope()
True
sage: p3 = b3.ehrhart_polynomial()     # optional - latte_int
sage: p3                               # optional - latte_int
1/8*t^4 + 3/4*t^3 + 15/8*t^2 + 9/4*t + 1
sage: [p3(i) for i in [1,2,3,4]]       # optional - latte_int
[6, 21, 55, 120]
sage: [len((i*b3).integral_points()) for i in [1,2,3,4]]
[6, 21, 55, 120]

sage: b4 = polytopes.Birkhoff_polytope(4)
sage: b4.n_vertices(), b4.ambient_dim(), b4.dim()
(24, 16, 9)
Gosset_3_21(backend=None)

Return the Gosset \(3_{21}\) polytope.

The Gosset \(3_{21}\) polytope is a uniform 7-polytope. It has 56 vertices, and 702 facets: \(126\) \(3_{11}\) and \(576\) \(6\)-simplex. For more information, see the Wikipedia article 3_21_polytope.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: g = polytopes.Gosset_3_21(); g
A 7-dimensional polyhedron in ZZ^8 defined as the convex hull of 56 vertices
sage: g.f_vector() # not tested (~16s)
(1, 56, 756, 4032, 10080, 12096, 6048, 702, 1)
Kirkman_icosahedron(backend=None)

Return the Kirkman icosahedron.

The Kirkman icosahedron is a 3-polytope with integer coordinates: \((\pm 9, \pm 6, \pm 6)\), \((\pm 12, \pm 4, 0)\), \((0, \pm 12, \pm 8)\), \((\pm 6, 0, \pm 12)\). See [Fe2012] for more information.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: ki = polytopes.Kirkman_icosahedron()
sage: ki.f_vector()
(1, 20, 38, 20, 1)

sage: ki.volume()
6528

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]
static associahedron(cartan_type)

Construct an associahedron.

The generalized associahedron is a polytopal complex with vertices in one-to-one correspondence with clusters in the cluster complex, and with edges between two vertices if and only if the associated two clusters intersect in codimension 1.

The associahedron of type \(A_n\) is one way to realize the classical associahedron as defined in the Wikipedia article Associahedron.

A polytopal realization of the associahedron can be found in [CFZ2002]. The implementation is based on [CFZ2002], Theorem 1.5, Remark 1.6, and Corollary 1.9.

EXAMPLES:

sage: Asso = polytopes.associahedron(['A',2]); Asso
Generalized associahedron of type ['A', 2] with 5 vertices

sage: sorted(Asso.Hrepresentation(), key=repr)
[An inequality (-1, 0) x + 1 >= 0,
 An inequality (0, -1) x + 1 >= 0,
 An inequality (0, 1) x + 1 >= 0,
 An inequality (1, 0) x + 1 >= 0,
 An inequality (1, 1) x + 1 >= 0]

sage: Asso.Vrepresentation()
(A vertex at (1, -1), A vertex at (1, 1), A vertex at (-1, 1),
 A vertex at (-1, 0), A vertex at (0, -1))

sage: polytopes.associahedron(['B',2])
Generalized associahedron of type ['B', 2] with 6 vertices

The two pictures of [CFZ2002] can be recovered with:

sage: Asso = polytopes.associahedron(['A',3]); Asso
Generalized associahedron of type ['A', 3] with 14 vertices
sage: Asso.plot()  # long time
Graphics3d Object

sage: Asso = polytopes.associahedron(['B',3]); Asso
Generalized associahedron of type ['B', 3] with 20 vertices
sage: Asso.plot()  # long time
Graphics3d Object
buckyball(exact=True, base_ring=None, backend=None)

Return the bucky ball.

The bucky ball, also known as the truncated icosahedron is an Archimedean solid. It has 32 faces and 60 vertices.

See also

icosahedron()

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: bb = polytopes.buckyball()   # long time - 6secs
sage: bb.f_vector()                # long time
(1, 60, 90, 32, 1)
sage: bb.base_ring()               # long time
Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?

A much faster implementation using floating point approximations:

sage: bb = polytopes.buckyball(exact=False)
sage: bb.f_vector()
(1, 60, 90, 32, 1)
sage: bb.base_ring()
Real Double Field

Its faces are 5 regular pentagons and 6 regular hexagons:

sage: sum(1 for f in bb.faces(2) if len(f.vertices()) == 5)
12
sage: sum(1 for f in bb.faces(2) if len(f.vertices()) == 6)
20
cross_polytope(dim, backend=None)

Return a cross-polytope in dimension dim.

A cross-polytope is a higher dimensional generalization of the octahedron. It is the convex hull of the \(2d\) points \((\pm 1, 0, \ldots, 0)\), \((0, \pm 1, \ldots, 0)\), ldots, \((0, 0, \ldots, \pm 1)\). See the Wikipedia article Cross-polytope for more information.

INPUT:

  • dim – integer. The dimension of the cross-polytope.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: four_cross = polytopes.cross_polytope(4)
sage: four_cross.f_vector()
(1, 8, 24, 32, 16, 1)
sage: four_cross.is_simple()
False
cube(backend=None)

Return the cube.

The cube is the Platonic solid that is obtained as the convex hull of the points \((\pm 1, \pm 1, \pm 1)\). It generalizes into several dimension into hypercubes.

See also

hypercube()

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: c = polytopes.cube()
sage: c
A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
sage: c.f_vector()
(1, 8, 12, 6, 1)
sage: c.volume()
8
sage: c.plot()
Graphics3d Object
cuboctahedron(backend=None)

Return the cuboctahedron.

The cuboctahedron is an Archimedean solid with 12 vertices and 14 faces dual to the rhombic dodecahedron. It can be defined as the convex hull of the twelve vertices \((0, \pm 1, \pm 1)\), \((\pm 1, 0, \pm 1)\) and \((\pm 1, \pm 1, 0)\). For more information, see the Wikipedia article Cuboctahedron.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: co = polytopes.cuboctahedron()
sage: co.f_vector()
(1, 12, 24, 14, 1)

Its faces are 8 triangles and 6 squares:

sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 3)
8
sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 4)
6

Some more computation:

sage: co.volume()
20/3
sage: co.ehrhart_polynomial()      # optional - latte_int
20/3*t^3 + 8*t^2 + 10/3*t + 1
cyclic_polytope(dim, n, base_ring=Rational Field, backend=None)

Return a cyclic polytope.

A cyclic polytope of dimension dim with n vertices is the convex hull of the points (t,t^2,...,t^dim) with \(t \in \{0,1,...,n-1\}\) . For more information, see the Wikipedia article Cyclic_polytope.

INPUT:

  • dim – positive integer. the dimension of the polytope.
  • n – positive integer. the number of vertices.
  • base_ring – either QQ (default) or RDF.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: c = polytopes.cyclic_polytope(4,10)
sage: c.f_vector()
(1, 10, 45, 70, 35, 1)
dodecahedron(exact=True, base_ring=None, backend=None)

Return a dodecahedron.

The dodecahedron is the Platonic solid dual to the icosahedron().

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.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: d12 = polytopes.dodecahedron()
sage: d12.f_vector()
(1, 20, 30, 12, 1)
sage: d12.volume()
-176*sqrt5 + 400
sage: numerical_approx(_)
6.45203596003699

sage: d12 = polytopes.dodecahedron(exact=False)
sage: d12.base_ring()
Real Double Field

Here is an error with a field that does not contain \(\sqrt(5)\):

sage: polytopes.dodecahedron(base_ring=QQ)
Traceback (most recent call last):
...
TypeError: unable to convert 1/4*sqrt(5) + 1/4 to a rational
static flow_polytope(edges=None, ends=None)

Return the flow polytope of a digraph.

The flow polytope of a directed graph is the polytope consisting of all nonnegative flows on the graph with a given set \(S\) of sources and a given set \(T\) of sinks.

A flow on a directed graph \(G\) with a given set \(S\) of sources and a given set \(T\) of sinks means an assignment of a nonnegative real to each edge of \(G\) such that the flow is conserved in each vertex outside of \(S\) and \(T\), and there is a unit of flow entering each vertex in \(S\) and a unit of flow leaving each vertex in \(T\). These flows clearly form a polytope in the space of all assignments of reals to the edges of \(G\).

The polytope is empty unless the sets \(S\) and \(T\) are equinumerous.

By default, \(S\) is taken to be the set of all sources (i.e., vertices of indegree \(0\)) of \(G\), and \(T\) is taken to be the set of all sinks (i.e., vertices of outdegree \(0\)) of \(G\). If a different choice of \(S\) and \(T\) is desired, it can be specified using the optional ends parameter.

The polytope is returned as a polytope in \(\RR^m\), where \(m\) is the number of edges of the digraph self. The \(k\)-th coordinate of a point in the polytope is the real assigned to the \(k\)-th edge of self. The order of the edges is the one returned by self.edges(). If a different order is desired, it can be specified using the optional edges parameter.

The faces and volume of these polytopes are of interest. Examples of these polytopes are the Chan-Robbins-Yuen polytope and the Pitman-Stanley polytope [PitSta].

INPUT:

  • edges – (optional, default: self.edges()) a list or tuple of all edges of self (each only once). This determines which coordinate of a point in the polytope will correspond to which edge of self. It is also possible to specify a list which contains not all edges of self; this results in a polytope corresponding to the flows which are \(0\) on all remaining edges. Notice that the edges entered here must be in the precisely same format as outputted by self.edges(); so, if self.edges() outputs an edge in the form (1, 3, None), then (1, 3) will not do!
  • ends – (optional, default: (self.sources(), self.sinks())) a pair \((S, T)\) of an iterable \(S\) and an iterable \(T\).

Note

Flow polytopes can also be built through the polytopes.<tab> object:

sage: polytopes.flow_polytope(digraphs.Path(5))
A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex

EXAMPLES:

A commutative square:

sage: G = DiGraph({1: [2, 3], 2: [4], 3: [4]})
sage: fl = G.flow_polytope(); fl
A 1-dimensional polyhedron in QQ^4 defined as the convex hull
of 2 vertices
sage: fl.vertices()
(A vertex at (0, 1, 0, 1), A vertex at (1, 0, 1, 0))

Using a different order for the edges of the graph:

sage: fl = G.flow_polytope(edges=G.edges(key=lambda x: x[0] - x[1])); fl
A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices
sage: fl.vertices()
(A vertex at (0, 1, 1, 0), A vertex at (1, 0, 0, 1))

A tournament on 4 vertices:

sage: H = digraphs.TransitiveTournament(4)
sage: fl = H.flow_polytope(); fl
A 3-dimensional polyhedron in QQ^6 defined as the convex hull
of 4 vertices
sage: fl.vertices()
(A vertex at (0, 0, 1, 0, 0, 0),
 A vertex at (0, 1, 0, 0, 0, 1),
 A vertex at (1, 0, 0, 0, 1, 0),
 A vertex at (1, 0, 0, 1, 0, 1))

Restricting to a subset of the edges:

sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None),
....:                             (2, 3, None), (0, 3, None)])
sage: fl
A 1-dimensional polyhedron in QQ^4 defined as the convex hull
of 2 vertices
sage: fl.vertices()
(A vertex at (0, 0, 0, 1), A vertex at (1, 1, 1, 0))

Using a different choice of sources and sinks:

sage: fl = H.flow_polytope(ends=([1], [3])); fl
A 1-dimensional polyhedron in QQ^6 defined as the convex hull
of 2 vertices
sage: fl.vertices()
(A vertex at (0, 0, 0, 1, 0, 1), A vertex at (0, 0, 0, 0, 1, 0))
sage: fl = H.flow_polytope(ends=([0, 1], [3])); fl
The empty polyhedron in QQ^6
sage: fl = H.flow_polytope(ends=([3], [0])); fl
The empty polyhedron in QQ^6
sage: fl = H.flow_polytope(ends=([0, 1], [2, 3])); fl
A 3-dimensional polyhedron in QQ^6 defined as the convex hull
of 5 vertices
sage: fl.vertices()
(A vertex at (0, 0, 1, 1, 0, 0),
 A vertex at (0, 1, 0, 0, 1, 0),
 A vertex at (1, 0, 0, 2, 0, 1),
 A vertex at (1, 0, 0, 1, 1, 0),
 A vertex at (0, 1, 0, 1, 0, 1))
sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None),
....:                             (2, 3, None), (0, 2, None),
....:                             (1, 3, None)],
....:                      ends=([0, 1], [2, 3])); fl
A 2-dimensional polyhedron in QQ^5 defined as the convex hull
of 4 vertices
sage: fl.vertices()
(A vertex at (0, 0, 0, 1, 1),
 A vertex at (1, 2, 1, 0, 0),
 A vertex at (1, 1, 0, 0, 1),
 A vertex at (0, 1, 1, 1, 0))

A digraph with one source and two sinks:

sage: Y = DiGraph({1: [2], 2: [3, 4]})
sage: Y.flow_polytope()
The empty polyhedron in QQ^3

A digraph with one vertex and no edge:

sage: Z = DiGraph({1: []})
sage: Z.flow_polytope()
A 0-dimensional polyhedron in QQ^0 defined as the convex hull
of 1 vertex

REFERENCES:

[PitSta]Jim Pitman, Richard Stanley, “A polytope related to empirical distributions, plane trees, parking functions, and the associahedron”, Arxiv math/9908029
grand_antiprism(exact=True, backend=None)

Return the grand antiprism.

The grand antiprism is a 4-dimensional non-Wythoffian uniform polytope. The coordinates were taken from http://eusebeia.dyndns.org/4d/gap. For more information, see the Wikipedia article Grand_antiprism.

Warning

The coordinates are exact by default. The computation with exact coordinates is not as fast as with floating point approximations. If you find this method to be too slow, consider using floating point approximations

INPUT:

  • exact - (boolean, default True) if False use floating point approximations instead of exact coordinates
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: gap = polytopes.grand_antiprism()  # not tested - very long time
sage: gap                                # not tested - very long time
A 4-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5)^4 defined as the convex hull of 100 vertices

Computation with approximated coordinates is much faster:

sage: gap = polytopes.grand_antiprism(exact=False) # random
sage: gap
A 4-dimensional polyhedron in RDF^4 defined as the convex hull of 100 vertices
sage: gap.f_vector()
(1, 100, 500, 720, 320, 1)
sage: len(list(gap.bounded_edges()))
500
great_rhombicuboctahedron(exact=True, base_ring=None, backend=None)

Return the great rhombicuboctahedron.

The great rhombicuboctahedron (or truncated cuboctahedron) is an Archimedean solid with 48 vertices and 26 faces. For more information see the Wikipedia article Truncated_cuboctahedron.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: gr = polytopes.great_rhombicuboctahedron()  # long time ~ 3sec
sage: gr.f_vector()                               # long time
(1, 48, 72, 26, 1)

A faster implementation is obtained by setting exact=False:

sage: gr = polytopes.great_rhombicuboctahedron(exact=False)
sage: gr.f_vector()
(1, 48, 72, 26, 1)

Its faces are 4 squares, 8 regular hexagons and 6 regular octagons:

sage: sum(1 for f in gr.faces(2) if len(f.vertices()) == 4)
12
sage: sum(1 for f in gr.faces(2) if len(f.vertices()) == 6)
8
sage: sum(1 for f in gr.faces(2) if len(f.vertices()) == 8)
6
hypercube(dim, backend=None)

Return a hypercube in the given dimension.

The \(d\) dimensional hypercube is the convex hull of the points \((\pm 1, \pm 1, \ldots, \pm 1)\) in \(\RR^d\). For more information see the Wikipedia article Hypercube.

INPUT:

  • dim – integer. The dimension of the cube.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: four_cube = polytopes.hypercube(4)
sage: four_cube.is_simple()
True
sage: four_cube.base_ring()
Integer Ring
sage: four_cube.volume()
16
sage: four_cube.ehrhart_polynomial()    # optional - latte_int
16*t^4 + 32*t^3 + 24*t^2 + 8*t + 1
hypersimplex(dim, k, project=False, backend=None)

Return the hypersimplex in dimension dim and parameter k.

The hypersimplex \(\Delta_{d,k}\) is the convex hull of the vertices made of \(k\) ones and \(d-k\) zeros. It lies in the \(d-1\) hyperplane of vectors of sum \(k\). If you want a projected version to \(\RR^{d-1}\) (with floating point coordinates) then set project=True in the options.

See also

simplex()

INPUT:

  • dim – the dimension
  • n – the numbers (1,...,n) are permuted
  • project – (boolean, default False) if True, the polytope is (isometrically) projected to a vector space of dimension dim-1. This operation turns the coordinates into floating point approximations and corresponds to the projection given by the matrix from zero_sum_projection().
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: h_4_2 = polytopes.hypersimplex(4, 2)
sage: h_4_2
A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 6 vertices
sage: h_4_2.f_vector()
(1, 6, 12, 8, 1)
sage: h_4_2.ehrhart_polynomial()    # optional - latte_int
2/3*t^3 + 2*t^2 + 7/3*t + 1

sage: h_7_3 = polytopes.hypersimplex(7, 3, project=True)
sage: h_7_3
A 6-dimensional polyhedron in RDF^6 defined as the convex hull of 35 vertices
sage: h_7_3.f_vector()
(1, 35, 210, 350, 245, 84, 14, 1)
icosahedron(exact=True, base_ring=None, backend=None)

Return an icosahedron with edge length 1.

The icosahedron is one of the Platonic solids. It has 20 faces and is dual to the 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.
  • backend – the backend to use to create the polytope.

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() # known bug (trac 18214)
2.181694990...

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
icosidodecahedron(exact=True, backend=None)

Return the icosidodecahedron.

The Icosidodecahedron is a polyhedron with twenty triangular faces and twelve pentagonal faces. For more information see the Wikipedia article Icosidodecahedron.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: id = polytopes.icosidodecahedron()
sage: id.f_vector()
(1, 30, 60, 32, 1)
icosidodecahedron_V2(exact=True, base_ring=None, backend=None)

Return the icosidodecahedron.

The icosidodecahedron is an Archimedean solid. It has 32 faces and 30 vertices. For more information, see the Wikipedia article Icosidodecahedron.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: id = polytopes.icosidodecahedron()   # long time - 6secs
sage: id.f_vector()                # long time
(1, 30, 60, 32, 1)
sage: id.base_ring()               # long time
Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?

A much faster implementation using floating point approximations:

sage: id = polytopes.icosidodecahedron(exact=False)
sage: id.f_vector()
(1, 30, 60, 32, 1)
sage: id.base_ring()
Real Double Field

Its faces are 20 triangles and 12 regular pentagons:

sage: sum(1 for f in id.faces(2) if len(f.vertices()) == 3)
20
sage: sum(1 for f in id.faces(2) if len(f.vertices()) == 5)
12
octahedron(backend=None)

Return the octahedron.

The octahedron is a Platonic solid with 6 vertices and 8 faces dual to the cube. It can be defined as the convex hull of the six vertices \((0, 0, \pm 1)\), \((\pm 1, 0, 0)\) and \((0, \pm 1, 0)\). For more information, see the Wikipedia article Octahedron.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: co = polytopes.octahedron()
sage: co.f_vector()
(1, 6, 12, 8, 1)

Its faces are 8 triangles:

sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 3)
8

Some more computation:

sage: co.volume()
4/3
sage: co.ehrhart_polynomial()      # optional - latte_int
4/3*t^3 + 2*t^2 + 8/3*t + 1
parallelotope(generators, backend=None)

Return the zonotope, or parallelotope, spanned by the generators.

The parallelotope is the multi-dimensional generalization of a parallelogram (2 generators) and a parallelepiped (3 generators).

INPUT:

  • generators – a list of vectors of same dimension
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: polytopes.parallelotope([ (1,0), (0,1) ])
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
sage: polytopes.parallelotope([[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]])
A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 16 vertices

sage: K = QuadraticField(2, 'sqrt2')
sage: sqrt2 = K.gen()
sage: polytopes.parallelotope([ (1,sqrt2), (1,-1) ])
A 2-dimensional polyhedron in (Number Field in sqrt2 with defining 
polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^2 defined as the convex hull of 4 vertices
pentakis_dodecahedron(exact=True, base_ring=None, backend=None)

Return the pentakis dodecahedron.

The pentakis dodecahedron (orkisdodecahedron) is a face-regular, vertex-uniform polytope dual to the truncated icosahedron. It has 60 faces and 32 vertices. See the Wikipedia article Pentakis_dodecahedron for more information.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: pd = polytopes.pentakis_dodecahedron()    # long time - ~10 sec
sage: pd.n_vertices()                           # long time
32
sage: pd.n_inequalities()                       # long time
60

A much faster implementation is obtained when setting exact=False:

sage: pd = polytopes.pentakis_dodecahedron(exact=False)
sage: pd.n_vertices()
32
sage: pd.n_inequalities()
60

The 60 are triangles:

sage: all(len(f.vertices()) == 3 for f in pd.faces(2))
True
permutahedron(n, project=False, backend=None)

Return the standard permutahedron of (1,…,n).

The permutahedron (or permutohedron) is the convex hull of the permutations of \(\{1,\ldots,n\}\) seen as vectors. The edges between the permutations correspond to multiplication on the right by an elementary transposition in the SymmetricGroup.

If we take the graph in which the vertices correspond to vertices of the polyhedron, and edges to edges, we get the BubbleSortGraph().

INPUT:

  • n – integer
  • project – (boolean, default False) if True, the polytope is (isometrically) projected to a vector space of dimension dim-1. This operation turns the coordinates into floating point approximations and corresponds to the projection given by the matrix from zero_sum_projection().
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: perm4 = polytopes.permutahedron(4)
sage: perm4
A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 24 vertices
sage: perm4.is_lattice_polytope()
True
sage: perm4.ehrhart_polynomial()   # optional - latte_int
16*t^3 + 15*t^2 + 6*t + 1

sage: perm4 = polytopes.permutahedron(4, project=True)
sage: perm4
A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24 vertices
sage: perm4.plot()
Graphics3d Object
sage: perm4.graph().is_isomorphic(graphs.BubbleSortGraph(4))
True
regular_polygon(n, exact=True, base_ring=None, backend=None)

Return a regular polygon with \(n\) vertices.

INPUT:

  • n – a positive integer, the number of vertices.
  • exact – (boolean, default True) if False floating point numbers are used for coordinates.
  • base_ring – a ring in which the coordinates will lie. It is None by default. If it is not provided and exact is True then it will be the field of real algebraic number, if exact is False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: octagon = polytopes.regular_polygon(8)
sage: octagon
A 2-dimensional polyhedron in AA^2 defined as the convex hull of 8 vertices
sage: octagon.n_vertices()
8
sage: v = octagon.volume()
sage: v
2.828427124746190?
sage: v == 2*QQbar(2).sqrt()
True

Its non exact version:

sage: polytopes.regular_polygon(3, exact=False).vertices()
(A vertex at (0.0, 1.0),
 A vertex at (0.8660254038, -0.5),
 A vertex at (-0.8660254038, -0.5))
sage: polytopes.regular_polygon(25, exact=False).n_vertices()
25
rhombic_dodecahedron(backend=None)

Return the rhombic dodecahedron.

The rhombic dodecahedron is a a polytope dual to the cuboctahedron. It has 14 vertices and 12 faces. For more information see the Wikipedia article Rhombic_dodecahedron.

INPUT:

  • backend – the backend to use to create the polytope.

See also

cuboctahedron()

EXAMPLES:

sage: rd = polytopes.rhombic_dodecahedron()
sage: rd.f_vector()
(1, 14, 24, 12, 1)

Its faces are 12 quadrilaterals (not all identical):

sage: sum(1 for f in rd.faces(2) if len(f.vertices()) == 4)
12

Some more computations:

sage: p = rd.ehrhart_polynomial()    # optional - latte_int
sage: p                              # optional - latte_int
16*t^3 + 12*t^2 + 4*t + 1
sage: [p(i) for i in [1,2,3,4]]      # optional - latte_int
[33, 185, 553, 1233]
sage: [len((i*rd).integral_points()) for i in [1,2,3,4]]
[33, 185, 553, 1233]
rhombicosidodecahedron(exact=True, base_ring=None, backend=None)

Return the rhombicosidodecahedron.

The rhombicosidodecahedron is an Archimedean solid. It has 62 faces and 60 vertices. For more information, see the Wikipedia article Rhombicosidodecahedron.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: rid = polytopes.rhombicosidodecahedron()   # long time - 6secs
sage: rid.f_vector()                # long time
(1, 60, 120, 62, 1)
sage: rid.base_ring()               # long time
Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?

A much faster implementation using floating point approximations:

sage: rid = polytopes.rhombicosidodecahedron(exact=False)
sage: rid.f_vector()
(1, 60, 120, 62, 1)
sage: rid.base_ring()
Real Double Field

Its faces are 20 triangles, 30 squares and 12 pentagons:

sage: sum(1 for f in rid.faces(2) if len(f.vertices()) == 3)
20
sage: sum(1 for f in rid.faces(2) if len(f.vertices()) == 4)
30
sage: sum(1 for f in rid.faces(2) if len(f.vertices()) == 5)
12
simplex(dim=3, project=False, base_ring=None, backend=None)

Return the dim dimensional simplex.

The \(d\)-simplex is the convex hull in \(\RR^{d+1}\) of the standard basis \((1,0,\ldots,0)\), \((0,1,\ldots,0)\), ldots, \((0,0,\ldots,1)\). For more information, see the Wikipedia article Simplex.

INPUT:

  • dim – The dimension of the simplex, a positive integer.
  • project – (boolean, default False) if True, the polytope is (isometrically) projected to a vector space of dimension dim-1. This corresponds to the projection given by the matrix from zero_sum_projection(). By default, this operation turns the coordinates into floating point approximations (see base_ring).
  • base_ring – the base ring to use to create the polytope. If project is False, this defaults to \(\ZZ\). Otherwise, it defaults to RDF.
  • backend – the backend to use to create the polytope.

See also

tetrahedron()

EXAMPLES:

sage: s5 = polytopes.simplex(5)
sage: s5
A 5-dimensional polyhedron in ZZ^6 defined as the convex hull of 6 vertices
sage: s5.f_vector()
(1, 6, 15, 20, 15, 6, 1)

sage: s5 = polytopes.simplex(5, project=True)
sage: s5
A 5-dimensional polyhedron in RDF^5 defined as the convex hull of 6 vertices

Its volume is \(\sqrt{d+1} / d!\):

sage: s5 = polytopes.simplex(5, project=True)
sage: s5.volume()      # abs tol 1e-10
0.0204124145231931
sage: sqrt(6.) / factorial(5)
0.0204124145231931

sage: s6 = polytopes.simplex(6, project=True)
sage: s6.volume()      # abs tol 1e-10
0.00367465459870082
sage: sqrt(7.) / factorial(6)
0.00367465459870082

Computation in algebraic reals:

sage: s3 = polytopes.simplex(3, project=True, base_ring=AA)
sage: s3.volume() == sqrt(3+1) / factorial(3)
True
six_hundred_cell(exact=False, backend=None)

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
  • backend – the backend to use to create the polytope.

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()  # long time ~2sec
(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
small_rhombicuboctahedron(exact=True, base_ring=None, backend=None)

Return the (small) rhombicuboctahedron.

The rhombicuboctahedron is an Archimedean solid with 24 vertices and 26 faces. See the Wikipedia article Rhombicuboctahedron for more information.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: sr = polytopes.small_rhombicuboctahedron()
sage: sr.f_vector()
(1, 24, 48, 26, 1)
sage: sr.volume()
80/3*sqrt2 + 32

The faces are \(8\) equilateral triangles and \(18\) squares:

sage: sum(1 for f in sr.faces(2) if len(f.vertices()) == 3)
8
sage: sum(1 for f in sr.faces(2) if len(f.vertices()) == 4)
18

Its non exact version:

sage: sr = polytopes.small_rhombicuboctahedron(False)
sage: sr
A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24
vertices
sage: sr.f_vector()
(1, 24, 48, 26, 1)
snub_cube(exact=False, base_ring=None, backend=None, verbose=False)

Return a snub cube.

The snub cube is an Archimedean solid. It has 24 vertices and 38 faces. For more information see the Wikipedia article Snub_cube.

The constant \(z\) used in constructing this polytope is the reciprocal of the tribonacci constant, that is, the solution of the equation \(x^3 + x^2 + x - 1 = 0\). See Wikipedia article Generalizations_of_Fibonacci_numbers#Tribonacci_numbers.

INPUT:

  • exact – (boolean, default False) if True use exact coordinates instead of floating point approximations
  • base_ring – the field to use. If None (the default), construct the exact number field needed (if exact is True) or default to RDF (if exact is True).
  • backend – the backend to use to create the polytope. If None (the default), the backend will be selected automatically.

EXAMPLES:

sage: sc_inexact = polytopes.snub_cube(exact=False)
sage: sc_inexact
A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24 vertices
sage: sc_inexact.f_vector()
(1, 24, 60, 38, 1)
sage: sc_exact = polytopes.snub_cube(exact=True)  # long time - 30secs
sage: sc_exact.f_vector()               # long time
(1, 24, 60, 38, 1)
sage: sc_exact.vertices()               # long time
(A vertex at (-1, -z, -z^2),
 A vertex at (-z^2, -1, -z),
 A vertex at (-z, -z^2, -1),
 A vertex at (-1, z^2, -z),
 A vertex at (-z, -1, z^2),
 A vertex at (z^2, -z, -1),
 A vertex at (z, -1, -z^2),
 A vertex at (-z^2, z, -1),
 A vertex at (-1, -z^2, z),
 A vertex at (z, z^2, -1),
 A vertex at (-1, z, z^2),
 A vertex at (z^2, -1, z),
 A vertex at (-z, 1, -z^2),
 A vertex at (z^2, 1, -z),
 A vertex at (-z^2, -z, 1),
 A vertex at (-z, z^2, 1),
 A vertex at (-z^2, 1, z),
 A vertex at (1, -z^2, -z),
 A vertex at (1, -z, z^2),
 A vertex at (1, z, -z^2),
 A vertex at (z, -z^2, 1),
 A vertex at (z, 1, z^2),
 A vertex at (z^2, z, 1),
 A vertex at (1, z^2, z))
sage: sc_exact.is_combinatorially_isomorphic(sc_inexact) #long time
True
snub_dodecahedron(base_ring=None, backend=None)

Return the snub dodecahedron.

The snub dodecahedron is an Archimedean solid. It has 92 faces and 60 vertices. For more information, see the Wikipedia article Snub_dodecahedron.

INPUT:

  • base_ring – the ring in which the coordinates will belong to. If it is not provided it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

Unfortunately, no polyhedra backend supports the construction of the snub dodecahedron at the moment:

sage: sd = polytopes.snub_dodecahedron()
sage: sd.f_vector() # not tested
(1, 60, 150, 92, 1)
sage: sd.base_ring() # not tested
Real Double Field

Its faces are 80 triangles and 12 pentagons:

sage: sum(1 for f in sd.faces(2) if len(f.vertices()) == 3) # not tested
80
sage: sum(1 for f in sd.faces(2) if len(f.vertices()) == 5) # not tested
12
tetrahedron(backend=None)

Return the tetrahedron.

The tetrahedron is a Platonic solid with 4 vertices and 4 faces dual to itself. It can be defined as the convex hull of the 4 vertices \((0, 0, 0)\), \((1, 1, 0)\), \((1, 0, 1)\) and \((0, 1, 1)\). For more information, see the Wikipedia article Tetrahedron.

INPUT:

  • backend – the backend to use to create the polytope.

See also

simplex()

EXAMPLES:

sage: co = polytopes.tetrahedron()
sage: co.f_vector()
(1, 4, 6, 4, 1)

Its faces are 4 triangles:

sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 3)
4

Some more computation:

sage: co.volume()
1/3
sage: co.ehrhart_polynomial()      # optional - latte_int
1/3*t^3 + t^2 + 5/3*t + 1
truncated_cube(exact=True, base_ring=None, backend=None)

Return the truncated cube.

The truncated cube is an Archimedean solid with 24 vertices and 14 faces. It can be defined as the convex hull of the 24 vertices \((\pm x, \pm 1, \pm 1), (\pm 1, \pm x, \pm 1), (\pm 1, \pm 1, \pm x)\) where \(x = \sqrt(2) - 1\). For more information, see the Wikipedia article Truncated_cube.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\sqrt{2}]\) and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: co = polytopes.truncated_cube()
sage: co.f_vector()
(1, 24, 36, 14, 1)

Its faces are 8 triangles and 6 octogons:

sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 3)
8
sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 8)
6

Some more computation:

sage: co.volume()
56/3*sqrt2 - 56/3
truncated_dodecahedron(exact=True, base_ring=None, backend=None)

Return the truncated dodecahedron.

The truncated dodecahedron is an Archimedean solid. It has 32 faces and 60 vertices. For more information, see the Wikipedia article Truncated dodecahedron.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: td = polytopes.truncated_dodecahedron()
sage: td.f_vector()
(1, 60, 90, 32, 1)
sage: td.base_ring()
Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?

Its faces are 20 triangles and 12 regular decagons:

sage: sum(1 for f in td.faces(2) if len(f.vertices()) == 3)
20
sage: sum(1 for f in td.faces(2) if len(f.vertices()) == 10)
12

The faster implementation using floating point approximations does not fully work unfortunately, see https://github.com/cddlib/cddlib/pull/7 for a detailed discussion of this case:

sage: td = polytopes.truncated_dodecahedron(exact=False) # random
doctest:warning
...
UserWarning: This polyhedron data is numerically complicated; cdd could not convert between the inexact V and H representation without loss of data. The resulting object might show inconsistencies.
sage: td.f_vector()
Traceback (most recent call last):
...
KeyError: ...
sage: td.base_ring()
Real Double Field
truncated_icosidodecahedron(exact=True, base_ring=None, backend=None)

Return the truncated icosidodecahedron.

The truncated icosidodecahedron is an Archimedean solid. It has 62 faces and 120 vertices. For more information, see the Wikipedia article Truncated_icosidodecahedron.

INPUT:

  • exact – (boolean, default True) If False use an approximate ring for the coordinates.
  • base_ring – the ring in which the coordinates will belong to. If it is not provided and exact=True it will be a the number field \(\QQ[\phi]\) where \(\phi\) is the golden ratio and if exact=False it will be the real double field.
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: ti = polytopes.truncated_icosidodecahedron()   # long time
sage: ti.f_vector()                # long time
(1, 120, 180, 62, 1)
sage: ti.base_ring()               # long time
Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?

The implementation using floating point approximations is much faster:

sage: ti = polytopes.truncated_icosidodecahedron(exact=False) # random
sage: ti.f_vector()
(1, 120, 180, 62, 1)
sage: ti.base_ring()
Real Double Field

Its faces are 30 squares, 20 hexagons and 12 decagons:

sage: sum(1 for f in ti.faces(2) if len(f.vertices()) == 4)
30
sage: sum(1 for f in ti.faces(2) if len(f.vertices()) == 6)
20
sage: sum(1 for f in ti.faces(2) if len(f.vertices()) == 10)
12
truncated_octahedron(backend=None)

Return the truncated octahedron.

The truncated octahedron is an Archimedean solid with 24 vertices and 14 faces. It can be defined as the convex hull off all the permutations of \((0, \pm 1, \pm 2)\). For more information, see the Wikipedia article Truncated_octahedron.

This is also known as the permutohedron of dimension 3.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: co = polytopes.truncated_octahedron()
sage: co.f_vector()
(1, 24, 36, 14, 1)

Its faces are 6 squares and 8 hexagons:

sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 4)
6
sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 6)
8

Some more computation:

sage: co.volume()
32
sage: co.ehrhart_polynomial()      # optional - latte_int
32*t^3 + 18*t^2 + 6*t + 1
truncated_tetrahedron(backend=None)

Return the truncated tetrahedron.

The truncated tetrahedron is an Archimedean solid with 12 vertices and 8 faces. It can be defined as the convex hull off all the permutations of \((\pm 1, \pm 1, \pm 3)\) with an even number of minus signs. For more information, see the Wikipedia article Truncated_tetrahedron.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: co = polytopes.truncated_tetrahedron()
sage: co.f_vector()
(1, 12, 18, 8, 1)

Its faces are 4 triangles and 4 hexagons:

sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 3)
4
sage: sum(1 for f in co.faces(2) if len(f.vertices()) == 6)
4

Some more computation:

sage: co.volume()
184/3
sage: co.ehrhart_polynomial()      # optional - latte_int
184/3*t^3 + 28*t^2 + 26/3*t + 1
twenty_four_cell(backend=None)

Return the standard 24-cell polytope.

The 24-cell polyhedron (also called icositetrachoron or octaplex) is a regular polyhedron in 4-dimension. For more information see the Wikipedia article 24-cell.

INPUT:

  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: p24 = polytopes.twenty_four_cell()
sage: p24.f_vector()
(1, 24, 96, 96, 24, 1)
sage: v = next(p24.vertex_generator())
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)

sage: p24.volume()
2
zonotope(generators, backend=None)

Return the zonotope, or parallelotope, spanned by the generators.

The parallelotope is the multi-dimensional generalization of a parallelogram (2 generators) and a parallelepiped (3 generators).

INPUT:

  • generators – a list of vectors of same dimension
  • backend – the backend to use to create the polytope.

EXAMPLES:

sage: polytopes.parallelotope([ (1,0), (0,1) ])
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
sage: polytopes.parallelotope([[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]])
A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 16 vertices

sage: K = QuadraticField(2, 'sqrt2')
sage: sqrt2 = K.gen()
sage: polytopes.parallelotope([ (1,sqrt2), (1,-1) ])
A 2-dimensional polyhedron in (Number Field in sqrt2 with defining 
polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^2 defined as the convex hull of 4 vertices
sage.geometry.polyhedron.library.project_points(*points, **kwds)

Projects a set of points into a vector space of dimension one less.

INPUT:

  • points… – the points to project.
  • base_ring – (defaults to RDF if keyword is None or not provided in kwds) the base ring to use.

The projection is isometric to the orthogonal projection on the hyperplane made of zero sum vector. Hence, if the set of points have all equal sums, then their projection is isometric (as a set of points).

The projection used is the matrix given by zero_sum_projection().

EXAMPLES:

sage: from sage.geometry.polyhedron.library import project_points
sage: project_points([2,-1,3,2])          # abs tol 1e-15
[(2.1213203435596424, -2.041241452319315, -0.577350269189626)]
sage: project_points([1,2,3],[3,3,5])     # abs tol 1e-15
[(-0.7071067811865475, -1.2247448713915892), (0.0, -1.6329931618554523)]

These projections are compatible with the restriction. More precisely, given a vector \(v\), the projection of \(v\) restricted to the first \(i\) coordinates will be equal to the projection of the first \(i+1\) coordinates of \(v\):

sage: project_points([1,2])    # abs tol 1e-15
[(-0.7071067811865475)]
sage: project_points([1,2,3])  # abs tol 1e-15
[(-0.7071067811865475, -1.2247448713915892)]
sage: project_points([1,2,3,4])     # abs tol 1e-15
[(-0.7071067811865475, -1.2247448713915892, -1.7320508075688776)]
sage: project_points([1,2,3,4,0])   # abs tol 1e-15
[(-0.7071067811865475, -1.2247448713915892, -1.7320508075688776, 2.23606797749979)]

Check that it is (almost) an isometry:

sage: V = list(map(vector, IntegerVectors(n=5,length=3)))
sage: P = project_points(*V)
sage: for i in range(21):
....:     for j in range(21):
....:         assert abs((V[i]-V[j]).norm() - (P[i]-P[j]).norm()) < 0.00001

Example with exact computation:

sage: V = [ vector(v) for v in IntegerVectors(n=4,length=2) ]
sage: P = project_points(*V, base_ring=AA)
sage: for i in range(len(V)):
....:     for j in range(len(V)):
....:         assert (V[i]-V[j]).norm() == (P[i]-P[j]).norm()
sage.geometry.polyhedron.library.zero_sum_projection(d, base_ring=Real Double Field)

Return a matrix corresponding to the projection on the orthogonal of \((1,1,\ldots,1)\) in dimension \(d\).

The projection maps the orthonormal basis \((1,-1,0,\ldots,0) / \sqrt(2)\), \((1,1,-1,0,\ldots,0) / \sqrt(3)\), ldots, \((1,1,\ldots,1,-1) / \sqrt(d)\) to the canonical basis in \(\RR^{d-1}\).

OUTPUT:

A matrix of dimensions \((d-1)\times d\) defined over base_ring (default: RDF).

EXAMPLES:

sage: from sage.geometry.polyhedron.library import zero_sum_projection
sage: zero_sum_projection(2)
[ 0.7071067811865475 -0.7071067811865475]
sage: zero_sum_projection(3)
[ 0.7071067811865475 -0.7071067811865475                 0.0]
[ 0.4082482904638631  0.4082482904638631 -0.8164965809277261]

Exact computation in \(AA <sage.rings.qqbar.AlgebraicRealField>\):

sage: zero_sum_projection(3, base_ring=AA)
[ 0.7071067811865475? -0.7071067811865475?                    0]
[ 0.4082482904638630?  0.4082482904638630? -0.8164965809277260?]