Polytope
Polytope
¶
A lattice polytope.
This class handles all computations relating to lattice polytopes, such as the computation of lattice points and faces. When using reflexive polytopes, it also allows the computation of topological properties of the arising Calabi-Yau hypersurfaces that only depend on the polytope.
The polytope is the convex hull of the input points. All lattice points of
the polytope are computed on construction and are labelled. Input points
keep the labels given in labels (if any), and every other lattice point
receives an integer label that does not clash with the given ones. Most
methods accept and return labels, and the helpers
points_to_labels and
points_to_indices convert
between points, labels, and indices.
The Polytope class is also exported at the root of the package, so it can
be imported from either cytools.polytope or cytools.
Parameters:
-
points(ArrayLike) –The lattice points whose convex hull defines the polytope. CYTools only supports lattice polytopes, so the points must have integer coordinates. They must all be distinct, but they do not need to be vertices.
-
labels(ArrayLike | None, default:None) –Labels for the input points, i.e.
points[i]is labelledlabels[i]. The labels must be distinct and hashable, and there must be one per input point. If not specified, all points are given integer labels following the default point ordering (seepoints). -
backend(str | None, default:None) –The backend used to construct the convex hull. The options are
"ppl","qhull", or"palp". If not specified, PPL is used for polytopes of dimension 1 to 4, and PALP otherwise. 0-dimensional polytopes always use PALP. -
deterministic_glsm_basis(bool, default:False) –Whether to choose the GLSM (and thus divisor) basis in a deterministic manner, so that it is consistent across different machines. The basis chosen with this flag may differ from the default one.
Raises:
-
ValueError–If
pointsis a string, if the points or labels are not unique, if the number of labels does not match the number of points, or ifbackendis not one of the allowed options.
Examples:
We construct two polytopes from lists of points.
>>> from cytools import Polytope
>>> p1 = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-1,-1]])
>>> print(p1)
A 4-dimensional reflexive lattice polytope in ZZ^4
>>> p2 = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[-1,-1,-1,0]])
>>> print(p2)
A 3-dimensional reflexive lattice polytope in ZZ^4
Custom labels can be given to the input points.
Methods:
-
all_triangulations–Compute all triangulations of the polytope using TOPCOM.
-
ambient_dimension–Return the dimension of the ambient lattice.
-
automorphisms–Return the \(GL(d,\mathbb{Z})\) matrices that leave the polytope invariant.
-
chi–Compute the Euler characteristic of the associated Calabi-Yau.
-
clear_cache–Clear the cached results of any previous computation.
-
dimension–Return the dimension of the polytope.
-
dual_polytope–Return the dual polytope (also called polar polytope).
-
faces–Compute the faces of the polytope.
-
facets–Return the facets (codimension-1 faces) of the polytope.
-
find_2d_reflexive_subpolytopes–Find the 2-dimensional reflexive subpolytopes of a 4D polytope.
-
glsm_basis–Compute a basis of columns of the GLSM charge matrix.
-
glsm_charge_matrix–Compute the GLSM charge matrix of the theory arising from the polytope.
-
glsm_linear_relations–Compute the linear relations of the columns of the GLSM charge matrix.
-
h11–Return the Hodge number \(h^{1,1}\) of the associated Calabi-Yau.
-
h12–Return the Hodge number \(h^{1,2}\) of the associated Calabi-Yau.
-
h13–Return the Hodge number \(h^{1,3}\) of the associated Calabi-Yau.
-
h22–Return the Hodge number \(h^{2,2}\) of the associated Calabi-Yau.
-
hpq–Return the Hodge number \(h^{p,q}\) of the associated Calabi-Yau.
-
inequalities–Return the inequalities giving the hyperplane representation.
-
inequivalent_Z2_actions–Enumerate the inequivalent toric \(\mathbb{Z}_2\) actions.
-
is_affinely_equivalent–Return whether the polytopes are related by an integral affine map.
-
is_favorable–Return whether the associated Calabi-Yau hypersurface is favorable.
-
is_linearly_equivalent–Return whether the polytopes are related by a \(GL(d,\mathbb{Z})\) map.
-
is_reflexive–Return whether the polytope is reflexive.
-
is_solid–Return whether the polytope is solid (i.e. full-dimensional).
-
is_trilayer–Return whether the polytope is "trilayer".
-
minkowski_sum–Return the Minkowski sum of the two polytopes.
-
nef_partitions–Compute the nef partitions of the polytope using PALP.
-
normal_form–Return the normal form of the polytope as defined by Kreuzer-Skarke.
-
points–Return the lattice points of the polytope.
-
points_to_indices–Return the indices corresponding to the given points.
-
points_to_labels–Return the labels corresponding to the given points.
-
pts_bdry–Return the boundary lattice points of the polytope.
-
pts_codim2–Return the boundary lattice points not interior to facets.
-
pts_facet–Return the lattice points interior to facets.
-
pts_int–Return the interior lattice points of the polytope.
-
pts_not_facets–Return the lattice points not interior to facets.
-
random_triangulations_fair–Construct pseudorandom fine, regular triangulations of the polytope.
-
random_triangulations_fast–Construct pseudorandom regular triangulations of the polytope.
-
random_triangulations_gnn–Construct random NTFE FR(S)Ts of a reflexive 4-dimensional polytope.
-
triangulate–Return a single regular triangulation of the polytope.
-
vertices–Return the vertices of the polytope.
-
volume–Return the normalized volume of the polytope.
Attributes:
-
backend(str) –Return the backend used to compute the convex hull.
-
label_origin–Return the label of the origin.
-
labels–Return the labels of all lattice points, in order.
-
labels_bdry–Return the labels of the boundary points.
-
labels_codim2–Return the labels of the boundary points not interior to facets.
-
labels_facet–Return the labels of the points interior to facets.
-
labels_int–Return the labels of the interior points.
-
labels_not_facet–Return the labels of the points not interior to facets.
-
labels_vertices–Return the labels of the vertices, sorted.
backend
property
¶
Return the backend used to compute the convex hull.
Returns:
-
str–The backend, one of
"ppl","qhull", or"palp".
Examples:
label_origin
property
¶
Return the label of the origin.
Returns:
-
Hashable | None–The label of the origin, or
Noneif the origin is not a lattice point of the polytope.
labels
property
¶
labels_bdry
property
¶
Return the labels of the boundary points.
Returns:
-
tuple–The labels of the boundary points, ordered by decreasing number of saturated inequalities.
labels_codim2
property
¶
Return the labels of the boundary points not interior to facets.
These are the points that saturate at least two inequalities, i.e. the ones lying in faces of codimension 2 or higher.
Returns:
-
tuple–The labels of the boundary points not interior to facets.
labels_facet
property
¶
Return the labels of the points interior to facets.
These are the boundary points that saturate exactly one inequality.
Returns:
-
tuple–The labels of the points interior to facets.
labels_int
property
¶
Return the labels of the interior points.
Interior points are those that do not saturate any inequality of the polytope, i.e. the ones in the relative interior.
Returns:
-
tuple–The labels of the interior points.
labels_not_facet
property
¶
Return the labels of the points not interior to facets.
These are the interior points followed by the boundary points not interior to facets.
Returns:
-
tuple–The labels of the points not interior to facets.
labels_vertices
property
¶
Return the labels of the vertices, sorted.
The vertices are computed (and cached) if needed.
Returns:
-
tuple–The sorted labels of the vertices of the polytope.
Examples:
all_triangulations
¶
all_triangulations(points=None, only_fine=True, only_regular=True, only_star=None, star_origin=None, include_points_interior_to_facets=None, backend=None, as_list=False, raw_output=False)
Compute all triangulations of the polytope using TOPCOM.
There is the option to only compute fine, regular, or star triangulations. Regularity is checked separately for each triangulation, since checking it with TOPCOM is much slower.
If the polytope is a simplex, its unique triangulation is returned and the restriction flags are ignored.
Warning
Polytopes with more than around 15 points usually have too many triangulations, so this function may take too long or run out of memory. A warning is issued when 17 or more points are used.
Parameters:
-
points(ArrayLike | None, default:None) –The labels of the points to be used. If specified,
include_points_interior_to_facetsis ignored. -
only_fine(bool, default:True) –Whether to restrict to fine triangulations.
-
only_regular(bool, default:True) –Whether to restrict to regular triangulations. This is ignored if
raw_outputis true. -
only_star(bool | None, default:None) –Whether to restrict to star triangulations. If not specified, it is set to
Truefor reflexive polytopes (without translations) andFalseotherwise. -
star_origin(Hashable | None, default:None) –The label of the point that will be used as the star origin. If not specified and the polytope is reflexive (without translations), the origin is used. Otherwise, it must be specified when
only_staris true. -
include_points_interior_to_facets(bool | None, default:None) –Whether to include points interior to facets in the triangulation. If not specified, it is set to
Falsefor reflexive polytopes andTrueotherwise. -
backend(str | None, default:None) –The optimizer used to check regularity. The available options are the backends of
Cone.is_solid. If not specified, it is picked automatically. -
as_list(bool, default:False) –Whether to return the full list of triangulations at once instead of a generator. By default a generator is returned, which is usually preferred for efficiency.
-
raw_output(bool, default:False) –Whether to return each triangulation as an array of simplices, each specified by point labels, instead of as a
Triangulationobject. In this case regularity is not checked.
Returns:
-
Iterator | list–A generator of
Triangulationobjects (or of arrays of simplices ifraw_outputis true), or a list of them ifas_listis true.
Raises:
-
ValueError–If
only_staris true,star_originis not specified, and the polytope is not reflexive (without translations).
Examples:
We construct a polytope and find all of its triangulations. We try picking different restrictions and see how the number of triangulations changes.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],
... [-1,-2,-1,-1],[-2,-1,-1,-1]])
>>> g = p.all_triangulations()
>>> next(g) # takes some time while TOPCOM finds all triangulations
A fine, regular, star triangulation of a 4-dimensional point...
>>> next(g) # produces the next triangulation immediately
A fine, regular, star triangulation of a 4-dimensional point...
>>> len(p.all_triangulations(as_list=True)) # number of FRSTs
2
The number of triangulations, no matter if they are fine, regular, or star, is larger.
ambient_dimension
¶
Return the dimension of the ambient lattice.
Also available as ambient_dim.
Returns:
-
int | None–The dimension of the ambient lattice, or
Noneif the polytope was constructed from an empty list of points.
Examples:
We construct a polytope and check the dimension of the ambient lattice.
automorphisms
¶
Return the \(GL(d,\mathbb{Z})\) matrices that leave the polytope invariant.
These are the integer matrices with determinant \(\pm 1\) (i.e. elements of \(SL^{\pm}(d,\mathbb{Z})\)) that map the polytope to itself. By default, they act on the points (as row vectors) by multiplication on the right. The results are cached.
Parameters:
-
square_to_one(bool, default:False) –Whether to restrict to the matrices that square to the identity.
-
action(str, default:'right') –Whether the returned matrices act on the
"left"or on the"right". The matrices that act on the left are the transposes of the ones that act on the right. This option is ignored whenas_dictionaryis true. -
as_dictionary(bool, default:False) –Whether to return each automorphism as a dictionary that describes its action on the indices of the points. For an automorphism matrix
a(acting on the right), the dictionarydsatisfiespoints()[d[i]] @ a == points()[i]for every indexi, i.e. it maps each index to the index of its preimage.
Returns:
-
ndarray | list[dict[int, int]]–The automorphism matrices, as an array of shape
(n_autos, d, d), or a list of dictionaries ifas_dictionaryis true. In both cases the automorphisms are given in the same order.
Raises:
-
NotImplementedError–If the polytope is not full-dimensional.
-
ValueError–If
actionis not"left"or"right".
Examples:
We construct a polytope, and find its automorphisms. We also check that one of the non-trivial automorphisms is indeed an automorphism by checking that it acts as a permutation on the vertices.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> autos = p.automorphisms()
>>> a = autos[1]
>>> a
array([[ 1, 0, 0, 0],
[-1, -1, -6, -9],
[ 0, 0, 1, 0],
[ 0, 0, 0, 1]])
>>> p.vertices()
array([[-1, -1, -6, -9],
[ 0, 0, 0, 1],
[ 0, 0, 1, 0],
[ 0, 1, 0, 0],
[ 1, 0, 0, 0]])
>>> p.vertices() @ a
array([[ 0, 1, 0, 0],
[ 0, 0, 0, 1],
[ 0, 0, 1, 0],
[-1, -1, -6, -9],
[ 1, 0, 0, 0]])
We can restrict to automorphisms that square to the identity.
>>> autos2 = p.automorphisms(square_to_one=True)
>>> a2 = autos2[1]
>>> a2 @ a2
array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]])
We can also get matrices that act on the left, which are simply the transposes, so that the points are now columns.
>>> autos_left = p.automorphisms(square_to_one=True, action="left")
>>> autos_left[1] @ p.vertices().T
array([[ 0, 0, 0, -1, 1],
[ 1, 0, 0, -1, 0],
[ 0, 0, 1, -6, 0],
[ 0, 1, 0, -9, 0]])
Finally, we get dictionaries that describe how the indices of the points transform.
chi
¶
Compute the Euler characteristic of the associated Calabi-Yau.
The Calabi-Yau is the anticanonical hypersurface in the toric variety
given by a desingularization of the face fan (if lattice="N") or the
normal fan (if lattice="M") of the polytope. The Euler
characteristic is computed from the Hodge numbers, and for the "M"
lattice it is computed from the dual polytope. The result is cached.
Note
Only reflexive polytopes of dimension 2 to 5 are currently supported.
Parameters:
-
lattice(str) –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
int–The Euler characteristic of the arising Calabi-Yau manifold.
Raises:
-
ValueError–If the polytope is not reflexive or its dimension is not between 2 and 5, or if
latticeis not"N"or"M".
Examples:
We construct a polytope and compute the Euler characteristic of the associated hypersurfaces.
clear_cache
¶
Clear the cached results of any previous computation.
This clears cached quantities such as the vertices, faces, dual
polytope, automorphisms, normal forms, Euler characteristic,
favorability, GLSM data, and nef partitions. The results of
hpq are cached separately and are
not cleared. The lattice points, their labels, and the hyperplane
representation are computed on construction and are not cleared
either.
Examples:
We compute the faces of a polytope, which are cached, and then clear the cache.
dimension
¶
Return the dimension of the polytope.
Also available as dim.
Returns:
-
int–The dimension of the polytope. It is -1 for the empty polytope.
Examples:
We construct a polytope and check its dimension.
dual_polytope
¶
Return the dual polytope (also called polar polytope).
The dual polytope of a polytope \(\Delta \subset \mathbb{R}^n\) is
A lattice polytope is reflexive if its dual is also a lattice polytope.
Only lattice polytopes are currently supported, so only duals of
reflexive polytopes (with the origin as their unique interior point)
can be computed. The vertices of the dual polytope are the normal
vectors of the inequalities returned by
inequalities.
The result is cached, and the dual of the dual polytope is the
original Polytope object.
Also available as dual, polar_polytope, and polar.
Returns:
-
Polytope–The dual polytope.
Raises:
-
NotImplementedError–If the polytope is empty, or if it is not reflexive without translations (see
is_reflexive).
Examples:
We construct a reflexive polytope and find its dual. We then verify that the dual of the dual is the original polytope.
faces
¶
Compute the faces of the polytope.
The faces of each dimension are sorted lexicographically by their
labels, and the result is cached. If the faces of the dual polytope
have already been computed, they are obtained by duality. Otherwise,
when the polytope is 4-dimensional, the slightly more optimized
_faces4d function is used.
Parameters:
-
d(int | None, default:None) –The dimension of the desired faces. If not specified, the faces of all dimensions are returned.
Returns:
-
tuple–If
dis specified, a tuple ofPolytopeFaceobjects of dimensiond. Otherwise, a tuple of tuples ofPolytopeFaceobjects organized in ascending dimension, so that the \(i\)-th entry contains the \(i\)-dimensional faces. The last entry contains the polytope itself as a face.
Raises:
-
NotImplementedError–If the polytope is empty.
-
ValueError–If
dis not in the range from 0 to the dimension of the polytope.
Examples:
We show that this function returns a tuple of 2-faces if d is set
to 2. Otherwise, the function returns all faces in tuples organized
in ascending dimension. We verify that the first element in the
tuple of 2-faces is the same as the first element in the
corresponding subtuple in the tuple of all faces.
facets
¶
Return the facets (codimension-1 faces) of the polytope.
Returns:
-
tuple[PolytopeFace, ...]–The
PolytopeFaceobjects of codimension 1.
Examples:
We construct a polytope and find its facets.
find_2d_reflexive_subpolytopes
¶
Find the 2-dimensional reflexive subpolytopes of a 4D polytope.
This uses the algorithm by Huang and Taylor described in
arXiv:1907.09482. Each subpolytope
is the intersection of the polytope with a 2-dimensional plane through
the origin, and it is returned as a new Polytope (with default
labels) in the ambient lattice of this polytope. The subpolytopes are
not returned in any particular order.
Returns:
Raises:
-
NotImplementedError–If the polytope is not a reflexive 4-dimensional polytope.
Examples:
We construct a polytope and find its 2D reflexive subpolytopes.
glsm_basis
¶
glsm_basis(include_origin=True, include_points_interior_to_facets=False, points=None, integral=True)
Compute a basis of columns of the GLSM charge matrix.
The basis is computed (and cached) together with the charge matrix by
glsm_charge_matrix,
and the corresponding columns of the charge matrix form an identity
matrix (or a diagonal matrix, if integral is false). The chosen
basis can be made machine-independent with the
deterministic_glsm_basis option of the constructor.
Parameters:
-
include_origin(bool, default:True) –Whether to include the origin in the calculation. This corresponds to the inclusion of the canonical divisor. If
False, the returned indices are shifted so that they refer to the charge matrix without the origin column. -
include_points_interior_to_facets(bool, default:False) –Whether to also use the points interior to facets. By default only the origin and the boundary points not interior to facets are used.
-
points(ArrayLike | None, default:None) –The indices of the points that will be used. If specified,
include_originandinclude_points_interior_to_facetsare ignored, and the origin (index 0) is always included. Note that the returned indices then refer to the columns of the corresponding charge matrix, i.e. to the positions in the sorted list of point indices. -
integral(bool, default:True) –Whether to find an integral basis for the columns of the GLSM charge matrix, i.e. a basis such that the remaining columns can be written as integer linear combinations of the basis columns.
Returns:
-
ndarray–The indices of the columns that form a basis.
Raises:
-
ValueError–If any of the indices in
pointsis out of range, or if the polytope is not reflexive.
Examples:
We construct a polytope, find its GLSM charge matrix and a basis of columns.
glsm_charge_matrix
¶
glsm_charge_matrix(include_origin=True, include_points_interior_to_facets=False, points=None, integral=True)
Compute the GLSM charge matrix of the theory arising from the polytope.
Each column of the GLSM charge matrix corresponds to a lattice point of
the polytope (i.e. to a prime toric divisor), and the rows span the
integer linear relations among the points, so that the product of the
charge matrix with the matrix of points (one per row) vanishes. The
column of the origin is minus the sum of the other columns, so that
each row sums to zero. The matrix is chosen such that the columns
given by glsm_basis form an
identity matrix (or a diagonal matrix, if integral is false). The
results are cached.
Parameters:
-
include_origin(bool, default:True) –Whether to include the origin in the calculation. This corresponds to the inclusion of the canonical divisor.
-
include_points_interior_to_facets(bool, default:False) –Whether to also use the points interior to facets. By default only the origin and the boundary points not interior to facets are used.
-
points(ArrayLike | None, default:None) –The indices of the points that will be used. If specified,
include_originandinclude_points_interior_to_facetsare ignored, and the origin (index 0) is always included as the first column. -
integral(bool, default:True) –Whether to find an integral basis for the columns of the GLSM charge matrix, i.e. a basis such that the remaining columns can be written as integer linear combinations of the basis columns. If an integral basis cannot be found, a warning is issued and a non-integral one is computed.
Returns:
-
ndarray–The GLSM charge matrix, with one column per point.
Raises:
-
ValueError–If the polytope is not reflexive, or if any of the indices in
pointsis out of range.
Examples:
We construct a polytope and find the GLSM charge matrix with different parameters.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> p.glsm_charge_matrix()
array([[-18, 1, 9, 6, 1, 1, 0],
[ -6, 0, 3, 2, 0, 0, 1]])
By definition, this product must be zero.
>>> p.glsm_charge_matrix().dot(p.points_not_interior_to_facets())
array([[0, 0, 0, 0],
[0, 0, 0, 0]])
We can exclude the origin (i.e. the canonical divisor), or include points interior to facets.
>>> p.glsm_charge_matrix(include_origin=False)
array([[1, 9, 6, 1, 1, 0],
[0, 3, 2, 0, 0, 1]])
>>> p.glsm_charge_matrix(include_points_interior_to_facets=True)
array([[ 0, 1, 0, 6, 1, 1, 0, 0, 0, -9],
[-2, 0, 1, 0, 0, 0, 0, 0, 0, 1],
[ 0, 0, 0, 2, 0, 0, 1, 0, 0, -3],
[ 0, 0, 0, 1, 0, 0, 0, 1, 0, -2],
[-1, 0, 0, 1, 0, 0, 0, 0, 1, -1]])
glsm_linear_relations
¶
glsm_linear_relations(include_origin=True, include_points_interior_to_facets=False, points=None, integral=True)
Compute the linear relations of the columns of the GLSM charge matrix.
The rows of the returned matrix span the linear relations among the
columns of the GLSM charge matrix, so that the product of the two
(with one of them transposed) vanishes. When the origin is included,
one of the relations states that the rows of the charge matrix sum to
zero. They are computed (and cached) together with the charge matrix
by glsm_charge_matrix.
Parameters:
-
include_origin(bool, default:True) –Whether to include the origin in the calculation. This corresponds to the inclusion of the canonical divisor. If
False, the first row and column are dropped. -
include_points_interior_to_facets(bool, default:False) –Whether to also use the points interior to facets. By default only the origin and the boundary points not interior to facets are used.
-
points(ArrayLike | None, default:None) –The indices of the points that will be used. If specified,
include_originandinclude_points_interior_to_facetsare ignored, and the origin (index 0) is always included. -
integral(bool, default:True) –Whether to find an integral basis for the columns of the GLSM charge matrix, i.e. a basis such that the remaining columns can be written as integer linear combinations of the basis columns.
Returns:
-
ndarray–The matrix of linear relations of the columns of the GLSM charge matrix, one per row.
Raises:
-
ValueError–If any of the indices in
pointsis out of range, or if the polytope is not reflexive.
Examples:
We construct a polytope and find its linear relations with different parameters.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> p.glsm_linear_relations()
array([[ 1, 0, 0, 0, 0, 18, 6],
[ 0, 1, 0, 0, 0, -1, 0],
[ 0, 0, 1, 0, 0, -9, -3],
[ 0, 0, 0, 1, 0, -6, -2],
[ 0, 0, 0, 0, 1, -1, 0]])
By definition, this product must be zero.
>>> p.glsm_linear_relations().dot(p.glsm_charge_matrix().T)
array([[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]])
We can exclude the origin (i.e. the canonical divisor).
h11
¶
Return the Hodge number \(h^{1,1}\) of the associated Calabi-Yau.
This is a shortcut for
hpq(1, 1, lattice), where the
conventions are explained.
Parameters:
-
lattice(str, default:'N') –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
int–The Hodge number \(h^{1,1}\) of the arising Calabi-Yau manifold.
Examples:
h12
¶
Return the Hodge number \(h^{1,2}\) of the associated Calabi-Yau.
This is a shortcut for
hpq(1, 2, lattice), where the
conventions are explained. Note that lattice="M" currently gives
incorrect results for 4- and 5-dimensional polytopes (see the warning
in hpq).
Also available as h21.
Parameters:
-
lattice(str, default:'N') –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
int–The Hodge number \(h^{1,2}\) of the arising Calabi-Yau manifold.
Examples:
h13
¶
Return the Hodge number \(h^{1,3}\) of the associated Calabi-Yau.
This is a shortcut for
hpq(1, 3, lattice), where the
conventions are explained. It is only non-zero for Calabi-Yau
fourfolds, i.e. for 5-dimensional polytopes. Note that lattice="M"
currently gives incorrect results for 5-dimensional polytopes (see the
warning in hpq).
Also available as h31.
Parameters:
-
lattice(str, default:'N') –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
int–The Hodge number \(h^{1,3}\) of the arising Calabi-Yau manifold.
Examples:
h22
¶
Return the Hodge number \(h^{2,2}\) of the associated Calabi-Yau.
This is a shortcut for
hpq(2, 2, lattice), where the
conventions are explained. Note that it is currently only computed
correctly for Calabi-Yau fourfolds, i.e. for 5-dimensional polytopes
(see the warning in hpq).
Parameters:
-
lattice(str, default:'N') –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
int–The Hodge number \(h^{2,2}\) of the arising Calabi-Yau manifold.
Examples:
hpq
¶
Return the Hodge number \(h^{p,q}\) of the associated Calabi-Yau.
The Calabi-Yau is the anticanonical hypersurface in the toric variety
given by a desingularization of the face fan (if lattice="N") or the
normal fan (if lattice="M") of the polytope. The Hodge numbers are
computed combinatorially (Batyrev's formulas), and the results are
cached.
Note
Only reflexive polytopes of dimension 2 to 5 are currently supported.
Warning
Hodge numbers \(h^{p,q}\) with \(p+q\) larger than the complex
dimension of the Calabi-Yau (after mapping to the \(N\) lattice with
\(p \to d-1-p\) when lattice="M") are currently returned as 0,
even when they are not zero (e.g. \(h^{2,2}=h^{1,1}\) for Calabi-Yau
threefolds). In particular, h12(lattice="M") for 4- and
5-dimensional polytopes, h13(lattice="M") for 5-dimensional
polytopes, and h22 for 3- and 4-dimensional polytopes are
affected. Using the dual polytope with lattice="N" gives the
correct values for the "M" lattice.
Parameters:
-
p(int) –The holomorphic index of the Dolbeault cohomology of interest.
-
q(int) –The anti-holomorphic index of the Dolbeault cohomology of interest.
-
lattice(str, default:'N') –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
int–The Hodge number \(h^{p,q}\) of the arising Calabi-Yau manifold.
Raises:
-
ValueError–If the polytope is not reflexive or its dimension is not between 2 and 5, or if
latticeis not"N"or"M".
Examples:
We construct a polytope and check some Hodge numbers of the associated hypersurface.
inequalities
¶
Return the inequalities giving the hyperplane representation.
Each row \((c_0, \ldots, c_{d-1}, c_d)\) encodes the inequality
For polytopes that are not full-dimensional, the equalities defining the affine hull of the polytope are not included, so the inequalities only define the polytope when restricted to its affine hull.
Returns:
-
ndarray–The inequalities defining the polytope, one per row, as an integer array of shape
(n_ineqs, ambient_dim + 1).
Raises:
-
NotImplementedError–If the polytope is empty.
Examples:
We construct a polytope and find the defining inequalities.
inequivalent_Z2_actions
¶
Enumerate the inequivalent toric \(\mathbb{Z}_2\) actions.
A toric \(\mathbb{Z}_2\) action is specified by a half-integral point
\(q/2\), where \(q \in \{0,1\}^d\) is non-zero. Two such actions are
considered equivalent if their vectors \(q\) are related (modulo 2) by a
lattice automorphism of the polytope (see
automorphisms). The result
is cached.
Returns:
-
ndarray–The inequivalent representatives \(q\), one per row, sorted lexicographically. Each one is the lexicographically smallest vector in its equivalence class.
Raises:
-
NotImplementedError–If the polytope is not full-dimensional.
Examples:
is_affinely_equivalent
¶
Return whether the polytopes are related by an integral affine map.
Two polytopes are affinely equivalent if they can be transformed into
each other by a \(GL(d,\mathbb{Z})\) transformation followed by an
integral translation. This is checked by comparing their affine normal
forms (see normal_form).
Parameters:
-
other(Polytope) –The other polytope being compared.
-
backend(str, default:'palp') –The backend used to compute the normal form. The options are
"native", which uses native Python code, or"palp", which uses PALP for the computation.
Returns:
-
bool–Trueif the polytopes are affinely equivalent,Falseotherwise.
Examples:
We construct two polytopes and check if they are affinely equivalent.
is_favorable
¶
Return whether the associated Calabi-Yau hypersurface is favorable.
A Calabi-Yau hypersurface is favorable if all of its Kähler forms
descend from Kähler forms on the ambient toric variety. This is checked
by verifying that the number of lattice points not interior to facets
equals \(h^{1,1} + d + 1\). For the "M" lattice, the dual polytope is
used. The result is cached.
Note
Only reflexive polytopes of dimension 2 to 5 are currently supported.
Parameters:
-
lattice(str) –The lattice on which the polytope is defined. The options are
"N"and"M".
Returns:
-
bool–Trueif the hypersurface is favorable,Falseotherwise.
Raises:
-
ValueError–If
latticeis not"N"or"M", or if the polytope is not reflexive or its dimension is not between 2 and 5.
Examples:
We construct two reflexive polytopes and find whether they are favorable when considered in the N lattice.
is_linearly_equivalent
¶
Return whether the polytopes are related by a \(GL(d,\mathbb{Z})\) map.
Two polytopes are linearly equivalent if they can be transformed into
each other by a \(GL(d,\mathbb{Z})\) (i.e. \(SL^{\pm}(d,\mathbb{Z})\))
transformation. This is checked by comparing their normal forms (see
normal_form).
Parameters:
-
other(Polytope) –The other polytope being compared.
-
backend(str, default:'palp') –The backend used to compute the normal form. The options are
"native", which uses native Python code, or"palp", which uses PALP for the computation.
Returns:
-
bool–Trueif the polytopes are linearly equivalent,Falseotherwise.
Examples:
We construct two polytopes and check if they are linearly equivalent.
is_reflexive
¶
Return whether the polytope is reflexive.
A lattice polytope is reflexive if it has a unique interior lattice point and every facet is at lattice distance 1 from it. Polytopes that are not full-dimensional are checked relative to the lattice of their affine hull. Polytopes of dimension 0 or lower are never considered reflexive.
The result is cached.
Parameters:
-
allow_translations(bool, default:True) –Whether to allow the polytope to be translated. If
True, the polytope is checked for reflexivity after translating its unique interior point to the origin. IfFalse, the origin must be the unique interior point (and, for polytopes that are not full-dimensional, the affine hull must contain the origin).
Returns:
-
bool–Trueif the polytope is reflexive,Falseotherwise.
Examples:
We construct a polytope and check if it is reflexive.
A translated reflexive polytope is only reflexive if translations are allowed.
is_solid
¶
Return whether the polytope is solid (i.e. full-dimensional).
Returns:
-
bool–Trueif the dimension of the polytope equals the dimension of the ambient lattice,Falseotherwise.
Examples:
We construct a polytope and check if it is solid.
is_trilayer
¶
Return whether the polytope is "trilayer".
This computes the GLSM charges of the vertices (a basis of the integer linear relations among the vertices) and the anticanonical class, given by the sum of the charges of all vertices. The polytope is considered trilayer if the anticanonical class is divisible by 2 and some vertex has charges equal to half of it. The polytope is assumed to be full-dimensional.
Parameters:
-
return_anticanon(bool, default:False) –Whether to also return the charges of the anticanonical class.
Returns:
-
bool | tuple[bool, ndarray]–Trueif the polytope is trilayer,Falseotherwise. Ifreturn_anticanonis true, a tuple with this value and the charges of the anticanonical class is returned instead.
Examples:
minkowski_sum
¶
Return the Minkowski sum of the two polytopes.
The sum is computed as the convex hull of all pairwise sums of the vertices of the two polytopes, so both must lie in lattices of the same dimension. The resulting polytope uses the default backend.
Also available through the + operator.
Parameters:
-
other(Polytope) –The other polytope used for the Minkowski sum.
Returns:
-
Polytope–The Minkowski sum.
Examples:
We construct two polytopes and compute their Minkowski sum.
nef_partitions
¶
nef_partitions(keep_symmetric=False, keep_products=False, keep_projections=False, codim=2, compute_hodge_numbers=True, return_hodge_numbers=False)
Compute the nef partitions of the polytope using PALP.
A nef partition is a partition of the vertices of the polytope into
codim parts, which defines a complete intersection Calabi-Yau (CICY).
Each part is given as a tuple of vertex indices, where the vertices
are ordered as by PALP. For polytopes with default labels, this
matches the ordering of
vertices. The results are
cached.
Note
This is currently an experimental feature and may change
significantly in future versions. It requires the experimental
features to be enabled with
enable_experimental_features.
Parameters:
-
keep_symmetric(bool, default:False) –Whether to keep symmetric partitions related by lattice automorphisms.
-
keep_products(bool, default:False) –Whether to keep product partitions, corresponding to complete intersections that are direct products.
-
keep_projections(bool, default:False) –Whether to keep projection partitions, i.e. partitions where one of the parts consists of a single vertex.
-
codim(int, default:2) –The number of parts in the partition or, equivalently, the codimension of the complete intersection Calabi-Yau.
-
compute_hodge_numbers(bool, default:True) –Whether to compute the Hodge numbers of the CICYs. This is always done if
return_hodge_numbersis true. -
return_hodge_numbers(bool, default:False) –Whether to return the Hodge numbers along with the nef partitions. For each nef partition, the Hodge numbers are given as a tuple of tuples whose \((p,q)\) entry is \(h^{p,q}\).
Returns:
-
list | tuple[list, list]–The list of nef partitions of the polytope. If
return_hodge_numbersis true, a tuple with the list of nef partitions and the list of the corresponding Hodge numbers is returned instead.
Raises:
-
Exception–If the experimental features are not enabled.
-
ValueError–If the polytope is not reflexive.
Examples:
We construct a tesseract and find the 2- and 3-part nef partitions.
>>> from cytools import config
>>> config.enable_experimental_features()
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],
... [-1,0,0,0],[0,-1,0,0],[0,0,-1,0],[0,0,0,-1]])
>>> nef_part_2 = p.nef_partitions() # default codimension is 2
>>> nef_part_2[0] # the first of the nef partitions
((0, 1, 2, 5), (3, 4, 6, 7))
>>> nef_part_3 = p.nef_partitions(codim=3)
>>> nef_part_3[0]
((0, 1, 6), (2, 3, 4), (5, 7))
We can also get the Hodge numbers of the CICYs, which in this case are K3 surfaces.
normal_form
¶
Return the normal form of the polytope as defined by Kreuzer-Skarke.
The normal form is a canonical choice of the vertices such that two
polytopes have the same normal form if and only if they are related by
a \(GL(d,\mathbb{Z})\) transformation (or also a translation, if
affine_transform is true). The results are cached.
Parameters:
-
affine_transform(bool, default:False) –Whether to also allow translations, in addition to \(GL(d,\mathbb{Z})\) transformations.
-
backend(str, default:'palp') –The backend to use. The options are
"native", which uses native Python code, or"palp", which uses PALP for the computation. The native algorithm and PALP use different conventions for affine normal forms, and PALP generally works better. PALP only supports full-dimensional polytopes, so for other polytopes a warning is issued and the native backend is used instead.
Returns:
-
ndarray–The vertices in normal form, one per row.
Raises:
-
NotImplementedError–If the polytope is empty.
-
ValueError–If
backendis not"native"or"palp".
Examples:
We construct a polytope, and find its linear and affine normal forms.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> p.normal_form()
array([[ 1, 0, 0, 0],
[ 0, 1, 0, 0],
[ 0, 0, 1, 0],
[ 0, 0, 0, 1],
[-9, -6, -1, -1]])
>>> p.normal_form(affine_transform=True)
array([[ 1, 0, 0, 0],
[ 0, 1, 0, 0],
[ 0, 0, 1, 0],
[12, 17, 17, 18],
[ 0, 0, 0, 0]])
points
¶
Return the lattice points of the polytope.
Points are sorted so that interior points come first, and then the rest are arranged by decreasing number of saturated inequalities, with ties broken lexicographically by their coordinates. For reflexive polytopes this is useful since the origin will be at index 0 and the boundary points interior to facets will be last.
Also available as pts.
Parameters:
-
which(Hashable | list | ndarray | None, default:None) –The label, or list of labels, of the points to return. Note that these are labels and not indices. If not specified, all points are returned.
-
optimal(bool, default:False) –Whether to return the points in their optimal coordinates (i.e. translated and LLL-reduced, and with the dimension reduced if the polytope is not full-dimensional).
-
as_indices(bool, default:False) –Whether to return the indices of the points in the full list of points instead of their coordinates.
Returns:
-
ndarray | list[int]–The lattice points, one per row. If
as_indicesis true, a list of indices is returned instead.
Examples:
We construct a polytope and compute the lattice points. One can verify that the first point is the only interior point, and the last three points are the ones interior to facets. Thus it follows the aforementioned ordering.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> p.points()
array([[ 0, 0, 0, 0],
[-1, -1, -6, -9],
[ 0, 0, 0, 1],
[ 0, 0, 1, 0],
[ 0, 1, 0, 0],
[ 1, 0, 0, 0],
[ 0, 0, -2, -3],
[ 0, 0, -1, -2],
[ 0, 0, -1, -1],
[ 0, 0, 0, -1]])
Specific points can be selected by their labels.
points_to_indices
¶
Return the indices corresponding to the given points.
The indices refer to the list of points returned by
points. It also accepts a single
point, in which case it returns the corresponding index.
Parameters:
-
points(ArrayLike) –A point or a list of points.
-
is_optimal(bool, default:False) –Whether the points are given in the optimal (
True) or input (False) coordinates.
Returns:
-
list[int] | int–The list of indices corresponding to the given points, or the index of the point if only one is given. An empty integer array is returned if
pointsis empty.
Raises:
-
KeyError–If any of the points is not a lattice point of the polytope.
Examples:
We construct a polytope and find the indices of some of its points. For a single point, a single index is returned.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> p.points_to_indices([-1,-1,-6,-9])
1
For a list of points, a list of indices is returned.
points_to_labels
¶
Return the labels corresponding to the given points.
It also accepts a single point, in which case it returns the corresponding label.
Parameters:
-
points(ArrayLike) –A point or a list of points.
-
is_optimal(bool, default:False) –Whether the points are given in the optimal (
True) or input (False) coordinates.
Returns:
-
list | Hashable–The list of labels corresponding to the given points, or the label of the point if only one is given. An empty list is returned if
pointsis empty.
Raises:
-
KeyError–If any of the points is not a lattice point of the polytope.
Examples:
We construct a polytope with custom labels and find the labels of some of its points.
pts_bdry
¶
Return the boundary lattice points of the polytope.
The points are ordered by decreasing number of saturated inequalities,
as in points.
Also available as boundary_points and bdry_points.
Parameters:
-
as_indices(bool, default:False) –Whether to return the indices of the points in the full list of points instead of their coordinates.
Returns:
Examples:
pts_codim2
¶
Return the boundary lattice points not interior to facets.
These are the points that saturate at least two inequalities, i.e. those that lie in faces of codimension 2 or higher.
Also available as boundary_points_not_interior_to_facets and
boundary_pts_not_interior_to_facets.
Parameters:
-
as_indices(bool, default:False) –Whether to return the indices of the points in the full list of points instead of their coordinates.
Returns:
-
ndarray | list[int]–The boundary points not interior to facets, one per row, or their indices if
as_indicesis true.
Examples:
pts_facet
¶
Return the lattice points interior to facets.
These are the boundary points that saturate exactly one inequality.
Also available as points_interior_to_facets and
pts_interior_to_facets.
Parameters:
-
as_indices(bool, default:False) –Whether to return the indices of the points in the full list of points instead of their coordinates.
Returns:
-
ndarray | list[int]–The points interior to facets, one per row, or their indices if
as_indicesis true.
Examples:
pts_int
¶
Return the interior lattice points of the polytope.
These are the points in the relative interior of the polytope. The
ordering is the same as in points.
Also available as interior_points and interior_pts.
Parameters:
-
as_indices(bool, default:False) –Whether to return the indices of the points in the full list of points instead of their coordinates.
Returns:
Examples:
pts_not_facets
¶
Return the lattice points not interior to facets.
These are the interior points followed by the boundary points not interior to facets. For reflexive polytopes, these are the points typically used to construct triangulations, since the points interior to facets correspond to divisors that do not intersect a generic Calabi-Yau hypersurface.
Also available as points_not_interior_to_facets and
pts_not_interior_to_facets.
Parameters:
-
as_indices(bool, default:False) –Whether to return the indices of the points in the full list of points instead of their coordinates.
Returns:
-
ndarray | list[int]–The points not interior to facets, one per row, or their indices if
as_indicesis true.
Examples:
random_triangulations_fair
¶
random_triangulations_fair(N=None, n_walk=None, n_flip=None, initial_walk_steps=None, walk_step_size=0.01, max_steps_to_wall=25, fine_tune_steps=8, max_retries=50, make_star=None, include_points_interior_to_facets=None, points=None, backend='cgal', as_list=False, progress_bar=True, seed=None)
Construct pseudorandom fine, regular triangulations of the polytope.
The triangulations are fine and regular, and optionally star. This function implements Algorithm #3 from the paper Bounding the Kreuzer-Skarke Landscape by Mehmet Demirtas, Liam McAllister, and Andres Rios-Tascon (arXiv:2008.01730).
This is a Markov chain Monte Carlo algorithm that involves taking random walks inside the subset of the secondary fan corresponding to fine triangulations and performing random flips. For details, please see Section 4.1 in the paper. Only distinct triangulations are returned.
Note
- By default this function tries to guess reasonable parameters for the polytope that is being used. However, it may take some trial-and-error to find optimal parameters that produce a good sampling and prevent the algorithm from getting stuck.
- This function is designed mainly for large polytopes where sampling triangulations is challenging. When small polytopes are used it is likely to get stuck or not produce an optimal set.
- The time it takes to obtain each triangulation varies very significantly with the parameters used, so it is best to adjust them to the desired balance between speed and fairness of the sampling.
Parameters:
-
N(int | None, default:None) –The number of desired distinct triangulations. If not specified, it will generate as many triangulations as it can find until it fails to obtain a new triangulation
max_retriesconsecutive times. This parameter is required whenas_listis true. -
n_walk(int | None, default:None) –The number of hit-and-run steps per triangulation. If not specified, it is set to
n_points//10 + 10, wheren_pointsis the total number of lattice points of the polytope. -
n_flip(int | None, default:None) –The number of random flips performed per triangulation. If not specified, it is set to
n_points//10 + 10. -
initial_walk_steps(int | None, default:None) –The number of hit-and-run steps to take before starting to record triangulations. Small values may result in a bias towards Delaunay-like triangulations. If not specified, it is set to
2*n_points//10 + 10. -
walk_step_size(float, default:0.01) –The size of the random steps taken in the secondary fan. The algorithm may stall if it is too small.
-
max_steps_to_wall(int, default:25) –The maximum number of steps to take towards a wall of the subset of the secondary fan that corresponds to fine triangulations. If a wall is not found, a new random direction is selected. Setting this to be very large (>100) reduces performance. If it is too low, the algorithm may stall.
-
fine_tune_steps(int, default:8) –The number of steps used to determine the location of a wall. Decreasing it improves performance, but might result in biased samples.
-
max_retries(int, default:50) –The maximum number of consecutive failed attempts to obtain a new triangulation before the process is terminated. It is also the maximum number of random directions tried when searching for a wall.
-
make_star(bool | None, default:None) –Whether to convert the obtained triangulations into star triangulations. If not specified, it is set to
Truefor reflexive polytopes (without translations) andFalseotherwise. It is always set toFalseif the origin is not one of the points. -
include_points_interior_to_facets(bool | None, default:None) –Whether to include points interior to facets in the triangulation. If not specified, it is set to
Falsefor reflexive polytopes andTrueotherwise. -
points(ArrayLike | None, default:None) –The labels of the points to be used. If specified,
include_points_interior_to_facetsis ignored. -
backend(str, default:'cgal') –The backend used to compute the triangulations. The options are
"cgal"and"qhull". -
as_list(bool, default:False) –Whether to return the full list of triangulations at once instead of a generator. By default a generator is returned, which is usually preferred for efficiency.
-
progress_bar(bool, default:True) –Whether to show a progress bar with the number of triangulations obtained. This option only has an effect when
as_listis true. -
seed(int | None, default:None) –A seed for the random number generator. This can be used to obtain reproducible results.
Returns:
-
Iterator[Triangulation] | list[Triangulation]–A generator of
Triangulationobjects, or a list of them ifas_listis true.
Raises:
-
NotImplementedError–If the polytope is not full-dimensional.
-
ValueError–If
as_listis true butNis not specified.
Examples:
We construct a polytope and find some random triangulations. The
computation takes considerable time, but they should be a fair
sample from the full set of triangulations (if the parameters are
chosen correctly). For (some) machine learning purposes or when the
fairness of the sample is not crucial,
random_triangulations_fast should be
used instead.
>>> p = Polytope(
... [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-1,-1]]
... ).dual()
>>> g = p.random_triangulations_fair()
>>> next(g) # takes a long time
A fine, regular, star triangulation of a 4-dimensional point...
>>> next(g) # takes a similar amount of time
A fine, regular, star triangulation of a 4-dimensional point...
We can also get a list of 10 triangulations, which takes a while.
random_triangulations_fast
¶
random_triangulations_fast(N=None, c=0.2, max_retries=500, make_star=True, only_fine=True, include_points_interior_to_facets=None, points=None, backend='cgal', as_list=False, progress_bar=True, seed=None)
Construct pseudorandom regular triangulations of the polytope.
The triangulations are regular, and optionally fine and star. They are obtained by picking random heights around the Delaunay heights from a Gaussian distribution. Only distinct triangulations are returned.
Warning
This function produces random triangulations very quickly, but it
does not produce a fair sample. When a fair sampling is required,
random_triangulations_fair
should be used.
Parameters:
-
N(int | None, default:None) –The number of desired distinct triangulations. If not specified, it will generate as many triangulations as it can find until it fails to obtain a new triangulation
max_retriesconsecutive times. This parameter is required whenas_listis true. -
c(float, default:0.2) –The standard deviation of the Gaussian distribution used to pick the heights. A larger
cresults in a wider range of possible triangulations, but with a larger fraction of them being non-fine, which slows down the process whenonly_fineis true. -
max_retries(int, default:500) –The maximum number of consecutive failed attempts to obtain a new triangulation before the process is terminated.
-
make_star(bool | None, default:True) –Whether to convert the obtained triangulations into star triangulations. If set to
None, it is set toTruefor reflexive polytopes (without translations) andFalseotherwise. It is always set toFalseif the origin is not one of the points. -
only_fine(bool, default:True) –Whether to restrict to fine triangulations.
-
include_points_interior_to_facets(bool | None, default:None) –Whether to include points interior to facets in the triangulation. If not specified, it is set to
Falsefor reflexive polytopes andTrueotherwise. -
points(ArrayLike | None, default:None) –The labels of the points to be used. If specified,
include_points_interior_to_facetsis ignored. -
backend(str, default:'cgal') –The backend used to compute the triangulations. The options are
"cgal"and"qhull". -
as_list(bool, default:False) –Whether to return the full list of triangulations at once instead of a generator. By default a generator is returned, which is usually preferred for efficiency.
-
progress_bar(bool, default:True) –Whether to show a progress bar with the number of triangulations obtained. This option only has an effect when
as_listis true. -
seed(int | None, default:None) –A seed for the random number generator. This can be used to obtain reproducible results.
Returns:
-
Iterator[Triangulation] | list[Triangulation]–A generator of
Triangulationobjects, or a list of them ifas_listis true.
Raises:
-
ValueError–If
as_listis true butNis not specified.
Examples:
We construct a polytope and find some random triangulations. The
triangulations are obtained very quickly, but they are not a fair
sample of the space of triangulations. For a fair sample,
random_triangulations_fair
should be used.
>>> p = Polytope(
... [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-1,-1]]
... ).dual()
>>> g = p.random_triangulations_fast()
>>> next(g) # runs very quickly
A fine, regular, star triangulation of a 4-dimensional point...
>>> next(g) # keeps producing triangulations until it can't find more
A fine, regular, star triangulation of a 4-dimensional point...
We can also get a list of 10 triangulations, which is produced very quickly.
random_triangulations_gnn
¶
random_triangulations_gnn(N, make_star=True, max_npts=0, N_face_triangs=1000, as_heights=False, as_generator=False, seed=None, verbosity=0)
Construct random NTFE FR(S)Ts of a reflexive 4-dimensional polytope.
The fine, regular (and optionally star) triangulations (FR(S)Ts) are built by sampling fine, regular triangulations (FRTs) of the 2-faces with the dualGNN graph neural network (arXiv:2605.27770) and extending them via the NTFE algorithm (arXiv:2309.10855). Each attempt draws one FRT per 2-face uniformly from the sampled pools, and it is accepted if the combination extends to a triangulation of the full polytope (i.e. if its expanded secondary cone is solid). Only distinct NTFEs are returned.
This function provides a convenient interface for this use case.
When more control is needed (e.g. to provide precomputed face
triangulations, possibly sampled with a custom GNN checkpoint),
ntfe_frts with
triang_method="dualgnn" can be used directly.
This sampler is much closer to uniform over the set of FRSTs than
random_triangulations_fast, while being
far faster than
random_triangulations_fair at large
\(h^{1,1}\).
Note
This function requires the optional dualgnn package (which
depends on PyTorch). It can be installed with
pip install cytools[gnn] or pip install dualgnn.
Parameters:
-
N(int) –The number of NTFEs to sample. Since not every combination of 2-face FRTs glues into an NTFE (acceptance can be ~1% for polytopes with large 2-faces, e.g. the \(h^{1,1}=86\) benchmark of arXiv:2605.27770), draws are retried until
Ndistinct NTFEs are found. Fewer are returned only if the attempt budget (1000*Ndraws) is exhausted or every combination has been checked. -
make_star(bool, default:True) –Whether to convert the NTFE FRTs into FRSTs (i.e. to make them star).
-
max_npts(int, default:0) –The maximum number of points of 2-faces for which all FRTs are enumerated. The GNN samples the FRTs of 2-faces with more points. The default of 0 means that the GNN samples every 2-face, since enumerating the FRTs of a face can be slow even when only a handful of triangulations are wanted.
-
N_face_triangs(int, default:1000) –The number of FRTs the GNN samples per (large) 2-face. Every sampled NTFE is assembled from these per-face pools, so the pool size sets the support of the sampler: small pools restrict (and so bias) which NTFEs can appear, while the cost of building the pools is proportional to their size. Lower it (e.g. to 50) for quick exploratory draws on polytopes with large 2-faces, and raise it when coverage of the NTFE space matters.
-
as_heights(bool, default:False) –Whether to return the height vectors realizing each NTFE instead of
Triangulationobjects. This is cheaper when theTriangulationobjects are not needed. -
as_generator(bool, default:False) –Whether to return a generator instead of a list. Use generators if memory is a concern.
-
seed(int | None, default:None) –A seed for the random number generator. This can be used to obtain reproducible results.
-
verbosity(int, default:0) –The verbosity level. Higher means more verbose.
Returns:
-
list | Iterator–A list of
Triangulationobjects (or of height vectors ifas_heightsis true), or a generator of them ifas_generatoris true.
Raises:
-
NotImplementedError–If the polytope is not a reflexive 4-dimensional polytope.
-
ImportError–If the optional
dualgnnpackage is not installed.
Examples:
We construct a polytope and sample some random triangulations.
This polytope has a single NTFE, so a single triangulation is
returned regardless of N.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],
... [0,0,0,-1],[-1,-1,-6,-9]])
>>> p.random_triangulations_gnn(N=4, seed=0)
[A fine, regular, star triangulation of a 4-dimensional point...]
For large polytopes, the GNN-sampled 2-face FRT pools can be built
once with face_triangs and reused across NTFE draws with
ntfe_frts. Since only ~1% of the
sampled expanded secondary cones may be solid, request many more
than the desired count.
>>> verts = [[-1,-1,-1,-1],[-1,-1,-1,3],[-1,-1,3,-1],[-1,3,-1,-1],
... [ 1,-1,-1,-1],[ 1,-1,-1,3],[ 1,-1,3,-1],[ 1,3,-1,-1]]
>>> p = Polytope(verts) # h11=86
>>> pools = p.face_triangs(
... dim=2, triang_method="dualgnn", max_npts=0, N_face_triangs=50,
... seed=0,
... ) # the expensive step (~10s)
>>> frsts = p.ntfe_frts(N=300, face_triangs=pools, make_star=True,
... seed=0) # cheap (~2s)
triangulate
¶
triangulate(*, include_points_interior_to_facets=None, points=None, make_star=None, simplices=None, check_input_simplices=True, heights=None, check_heights=True, backend='cgal', verbosity=1, seed=None)
Return a single regular triangulation of the polytope.
When reflexive polytopes are used, it defaults to returning a fine, regular, star triangulation. The points of the triangulation are ordered by their labels. All arguments are keyword-only.
Parameters:
-
include_points_interior_to_facets(bool | None, default:None) –Whether to include points interior to facets in the triangulation. If not specified, it is set to
Falsefor reflexive polytopes andTrueotherwise. -
points(ArrayLike | None, default:None) –The labels of the points to be used. If specified,
include_points_interior_to_facetsis ignored. -
make_star(bool | None, default:None) –Whether to turn the triangulation into a star triangulation with respect to the origin, either by deleting internal lines and connecting all points to the origin, or equivalently by decreasing the height of the origin to be much lower than the rest. If not specified, it is set to
Trueif the polytope is reflexive (without translations) and neitherheightsnorsimplicesare given, and toFalseotherwise. It is always set toFalseif the polytope is not reflexive and the origin is not one of the points. -
simplices(ArrayLike | None, default:None) –The simplices specifying the triangulation, each given as a list of point labels. This is useful when a triangulation was previously computed and needs to be used again.
-
check_input_simplices(bool, default:True) –Whether to check that the input simplices define a valid triangulation.
-
heights(ArrayLike | None, default:None) –The heights specifying the regular triangulation. They can be given either for all the points of the polytope, in which case only the heights of the points used in the triangulation are kept, or for the points used in the triangulation, ordered by their labels. Heights can only be specified when using CGAL or QHull as the backend. If not specified, the triangulation depends on the backend: CGAL constructs the Delaunay triangulation, QHull uses random heights near the Delaunay heights, and TOPCOM constructs a placing triangulation.
-
check_heights(bool, default:True) –Whether to check that the input or default heights define a unique triangulation.
-
backend(str, default:'cgal') –The backend used to compute the triangulation. The options are
"cgal","qhull", and"topcom". CGAL is the default as it is very fast and robust. -
verbosity(int, default:1) –The verbosity level.
-
seed(int | None, default:None) –Seed for the height perturbation used by the QHull backend. Only that backend perturbs its heights, so this has no effect for CGAL or TOPCOM. If not specified, the perturbation is drawn afresh each time and the triangulation is not reproducible.
Returns:
-
Triangulation–A
Triangulationobject describing a triangulation of the polytope.
Raises:
-
ValueError–If the input simplices use more points than the ones selected for the triangulation. Further errors may be raised by the
Triangulationconstructor.
Examples:
We construct a triangulation of a reflexive polytope and check that by default it is a fine, regular, star triangulation.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],[-1,-1,-6,-9]])
>>> t = p.triangulate()
>>> t.is_fine(), t.is_regular(), t.is_star()
(True, True, True)
>>> len(t.points())
7
By default the points interior to facets are not included, but we can include them, or specify the points to use.
>>> len(p.triangulate(include_points_interior_to_facets=True).points())
10
>>> p.triangulate(points=[1,2,3,4,5]).is_star()
False
We also construct triangulations with heights, input simplices, and using the other backends.
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1],
... [-1,-2,-1,-1],[-2,-1,-1,-1]])
>>> t = p.triangulate(heights=[-30,5,5,24,-19,-14,29])
>>> t.simplices()
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 5],
[0, 1, 2, 4, 6],
[0, 1, 2, 5, 6],
[0, 1, 3, 4, 5],
[0, 1, 4, 5, 6],
[0, 2, 3, 4, 5],
[0, 2, 4, 5, 6]], dtype=uint8)
>>> t2 = p.triangulate(simplices=t.simplices())
>>> t2 == t
True
>>> t3 = p.triangulate(backend="qhull")
>>> t4 = p.triangulate(backend="topcom")
vertices
¶
Return the vertices of the polytope.
The vertices are sorted by their labels, and the result is cached.
Parameters:
-
optimal(bool, default:False) –Whether to return the vertices in their optimal coordinates.
-
as_indices(bool, default:False) –Whether to return the indices of the vertices in the full list of points instead of their coordinates.
Returns:
-
ndarray | list[int]–The vertices of the polytope, one per row, or their indices if
as_indicesis true.
Examples:
We construct a polytope and find its vertices. We can see that they match the points that we used to construct the polytope.
volume
¶
Return the normalized volume of the polytope.
The volume is computed relative to the lattice of the affine hull of the polytope, so it is well defined for polytopes that are not full-dimensional. The result is cached.
Warning
By convention, the standard simplex has unit volume. To get the more typical Euclidean volume it must be divided by \(d!\).
Returns:
-
int–The normalized volume of the polytope. It is 0 for 0-dimensional polytopes.
Examples:
We construct a standard simplex and a cube, and find their volumes.