### Navigation

- index
- modules |
- next |
- previous |
- Combinatorial Geometry »

# Lattice and reflexive polytopes

This module provides tools for work with lattice and reflexive polytopes. A convex polytope is the convex hull of finitely many points in \(\RR^n\). The dimension \(n\) of a polytope is the smallest \(n\) such that the polytope can be embedded in \(\RR^n\).

A lattice polytope is a polytope whose vertices all have integer coordinates.

If \(L\) is a lattice polytope, the dual polytope of \(L\) is

\[\{y \in \ZZ^n : x\cdot y \geq -1 \text{ all } x \in L\}\]

A reflexive polytope is a lattice polytope, such that its polar is also a lattice polytope, i.e. it is bounded and has vertices with integer coordinates.

This Sage module uses Package for Analyzing Lattice Polytopes (PALP), which is a program written in C by Maximilian Kreuzer and Harald Skarke, which is freely available under the GNU license terms at http://hep.itp.tuwien.ac.at/~kreuzer/CY/. Moreover, PALP is included standard with Sage.

PALP is described in the paper Arxiv math.SC/0204356. Its distribution also contains the application nef.x, which was created by Erwin Riegler and computes nef-partitions and Hodge data for toric complete intersections.

ACKNOWLEDGMENT: polytope.py module written by William Stein was used as an example of organizing an interface between an external program and Sage. William Stein also helped Andrey Novoseltsev with debugging and tuning of this module.

Robert Bradshaw helped Andrey Novoseltsev to realize plot3d function.

Note

IMPORTANT: PALP requires some parameters to be determined during compilation time, i.e., the maximum dimension of polytopes, the maximum number of points, etc. These limitations may lead to errors during calls to different functions of these module. Currently, a ValueError exception will be raised if the output of poly.x or nef.x is empty or contains the exclamation mark. The error message will contain the exact command that caused an error, the description and vertices of the polytope, and the obtained output.

Data obtained from PALP and some other data is cached and most returned values are immutable. In particular, you cannot change the vertices of the polytope or their order after creation of the polytope.

If you are going to work with large sets of data, take a look at `all_*` functions in this module. They precompute different data for sequences of polynomials with a few runs of external programs. This can significantly affect the time of future computations. You can also use dump/load, but not all data will be stored (currently only faces and the number of their internal and boundary points are stored, in addition to polytope vertices and its polar).

AUTHORS:

- Andrey Novoseltsev (2007-01-11): initial version

- Andrey Novoseltsev (2007-01-15): `all_*` functions

- Andrey Novoseltsev (2008-04-01): second version, including:

  > - dual nef-partitions and necessary convex_hull and minkowski_sum
  > - built-in sequences of 2- and 3-dimensional reflexive polytopes
  > - plot3d, skeleton_show

- Andrey Novoseltsev (2009-08-26): dropped maximal dimension requirement

- Andrey Novoseltsev (2010-12-15): new version of nef-partitions

- Andrey Novoseltsev (2013-09-30): switch to PointCollection.

- Maximilian Kreuzer and Harald Skarke: authors of PALP (which was also used to obtain the list of 3-dimensional reflexive polytopes)

- Erwin Riegler: the author of nef.x

`sage.geometry.lattice_polytope.``LatticePolytope`(data, desc=None, compute_vertices=True, n=0, lattice=None)

  Construct a lattice polytope.

  INPUT:

  - `data` – points spanning the lattice polytope, specified as one of:

    > - a `point collection` (this is the preferred input and it is the quickest and the most memory efficient one);
    > - an iterable of iterables (for example, a list of vectors) defining the point coordinates;
    > - a file with matrix data, opened for reading, or
    > - a filename of such a file, see `read_palp_matrix()` for the file format;

  - `desc` – DEPRECATED (default: “A lattice polytope”) a string description of the polytope;

  - `compute_vertices` – boolean (default: `True`). If `True`, the

      convex hull of the given points will be computed for determining vertices. Otherwise, the given points must be vertices;

  - `n` – an integer (default: 0) if `data` is a name of a file,

      that contains data blocks for several polytopes, the `n`-th block will be used;

  - `lattice` – the ambient lattice of the polytope. If not given, a suitable lattice will be determined automatically, most likely the `toric lattice` \(M\) of the appropriate dimension.

  OUTPUT:

  - a `lattice polytope`.

  EXAMPLES:

      sage: points = [(1,0,0), (0,1,0), (0,0,1), (-1,0,0), (0,-1,0), (0,0,-1)]
      sage: p = LatticePolytope(points)
      sage: p
      3-d reflexive polytope in 3-d lattice M
      sage: p.vertices_pc()
      M( 1,  0,  0),
      M( 0,  1,  0),
      M( 0,  0,  1),
      M(-1,  0,  0),
      M( 0, -1,  0),
      M( 0,  0, -1)
      in 3-d lattice M

  We draw a pretty picture of the polytope in 3-dimensional space:

      sage: p.plot3d().show()

  Now we add an extra point, which is in the interior of the polytope...

      sage: points.append((0,0,0))
      sage: p = LatticePolytope(points)
      sage: p.nvertices()
      6

  You can suppress vertex computation for speed but this can lead to mistakes:

      sage: p = LatticePolytope(points, compute_vertices=False)
      ...
      sage: p.nvertices()
      7

  Given points must be in the lattice:

      sage: LatticePolytope(matrix([1/2, 3/2]))
      Traceback (most recent call last):
      ...
      ValueError: points
      [(1/2), (3/2)]
      are not in 1-d lattice M!

  But it is OK to create polytopes of non-maximal dimension:

      sage: p = LatticePolytope([(1,0,0), (0,1,0), (0,0,0),
      ...         (-1,0,0), (0,-1,0), (0,0,0), (0,0,0)])
      sage: p
      2-d lattice polytope in 3-d lattice M
      sage: p.vertices_pc()
      M( 1,  0, 0),
      M( 0,  1, 0),
      M(-1,  0, 0),
      M( 0, -1, 0)
      in 3-d lattice M

  An empty lattice polytope can be considered as well:

      sage: p = LatticePolytope([], lattice=ToricLattice(3).dual()); p
      -1-d lattice polytope in 3-d lattice M
      sage: p.ambient_dim()
      3
      sage: p.npoints()
      0
      sage: p.nfacets()
      0
      sage: p.points_pc()
      Empty collection
      in 3-d lattice M
      sage: p.faces()
      []

class `sage.geometry.lattice_polytope.``LatticePolytopeClass`(points, compute_vertices)

  Bases: `sage.structure.sage_object.SageObject`, `_abcoll.Hashable`

  Construct a lattice polytope from prepared data.

  In most cases you should use `LatticePolytope()` for constructing polytopes.

  INPUT:

  - `points` – a `PointCollection`;
  - `compute_vertices` – boolean.
  `affine_transform`(a=1, b=0)

    Return a*P+b, where P is this lattice polytope.

    Note

    1. While `a` and `b` may be rational, the final result must be a lattice polytope, i.e. all vertices must be integral.
    2. If the transform (restricted to this polytope) is bijective, facial structure will be preserved, e.g. the first facet of the image will be spanned by the images of vertices which span the first facet of the original polytope.

    INPUT:

    - `a` - (default: 1) rational scalar or matrix
    - `b` - (default: 0) rational scalar or vector, scalars are interpreted as vectors with the same components

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(2)
        sage: o.vertices_pc()
        M( 1,  0),
        M( 0,  1),
        M(-1,  0),
        M( 0, -1)
        in 2-d lattice M
        sage: o.affine_transform(2).vertices_pc()
        M( 2,  0),
        M( 0,  2),
        M(-2,  0),
        M( 0, -2)
        in 2-d lattice M
        sage: o.affine_transform(1,1).vertices_pc()
        M(2, 1),
        M(1, 2),
        M(0, 1),
        M(1, 0)
        in 2-d lattice M
        sage: o.affine_transform(b=1).vertices_pc()
        M(2, 1),
        M(1, 2),
        M(0, 1),
        M(1, 0)
        in 2-d lattice M
        sage: o.affine_transform(b=(1, 0)).vertices_pc()
        M(2,  0),
        M(1,  1),
        M(0,  0),
        M(1, -1)
        in 2-d lattice M
        sage: a = matrix(QQ, 2, [1/2, 0, 0, 3/2])
        sage: o.polar().vertices_pc()
        N(-1,  1),
        N( 1,  1),
        N(-1, -1),
        N( 1, -1)
        in 2-d lattice N
        sage: o.polar().affine_transform(a, (1/2, -1/2)).vertices_pc()
        M(0,  1),
        M(1,  1),
        M(0, -2),
        M(1, -2)
        in 2-d lattice M

    While you can use rational transformation, the result must be integer:

        sage: o.affine_transform(a)
        Traceback (most recent call last):
        ...
        ValueError: points
        [(1/2, 0), (0, 3/2), (-1/2, 0), (0, -3/2)]
        are not in 2-d lattice M!

  `ambient_dim`()

    Return the dimension of the ambient space of this polytope.

    EXAMPLES: We create a 3-dimensional octahedron and check its ambient dimension:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.ambient_dim()
        3

  `dim`()

    Return the dimension of this polytope.

    EXAMPLES: We create a 3-dimensional octahedron and check its dimension:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.dim()
        3

    Now we create a 2-dimensional diamond in a 3-dimensional space:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.dim()
        2
        sage: p.ambient_dim()
        3

  `distances`(point=None)

    Return the matrix of distances for this polytope or distances for the given point.

    The matrix of distances m gives distances m[i,j] between the i-th facet (which is also the i-th vertex of the polar polytope in the reflexive case) and j-th point of this polytope.

    If point is specified, integral distances from the point to all facets of this polytope will be computed.

    This function CAN be used for polytopes whose dimension is smaller than the dimension of the ambient space. In this case distances are computed in the affine subspace spanned by the polytope and if the point is given, it must be in this subspace.

    EXAMPLES: The matrix of distances for a 3-dimensional octahedron:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.distances()
        [0 0 2 2 2 0 1]
        [2 0 2 0 2 0 1]
        [0 2 2 2 0 0 1]
        [2 2 2 0 0 0 1]
        [0 0 0 2 2 2 1]
        [2 0 0 0 2 2 1]
        [0 2 0 2 0 2 1]
        [2 2 0 0 0 2 1]

    Distances from facets to the point (1,2,3):

        sage: o.distances([1,2,3])
        (1, 3, 5, 7, -5, -3, -1, 1)

    It is OK to use RATIONAL coordinates:

        sage: o.distances([1,2,3/2])
        (-1/2, 3/2, 7/2, 11/2, -7/2, -3/2, 1/2, 5/2)
        sage: o.distances([1,2,sqrt(2)])
        Traceback (most recent call last):
        ...
        TypeError: unable to convert sqrt(2) to a rational

    Now we create a non-spanning polytope:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.distances()
        [0 2 2 0 1]
        [2 2 0 0 1]
        [0 0 2 2 1]
        [2 0 0 2 1]
        sage: p.distances((1/2, 3, 0))
        (7/2, 9/2, -5/2, -3/2)
        sage: p.distances((1, 1, 1))
        Traceback (most recent call last):
        ...
        ArithmeticError: vector is not in free module

  `dual_lattice`()

    Return the dual of the ambient lattice of `self`.

    OUTPUT:

    - a lattice. If possible (that is, if `lattice()` has a `dual()` method), the dual lattice is returned. Otherwise, \(\ZZ^n\) is returned, where \(n\) is the dimension of `self`.

    EXAMPLES:

        sage: LatticePolytope([(1,0)]).dual_lattice()
        2-d lattice N
        sage: LatticePolytope([], lattice=ZZ^3).dual_lattice()
        Ambient free module of rank 3
        over the principal ideal domain Integer Ring

  `edges`()

    Return the sequence of edges of this polytope (i.e. faces of dimension 1).

    EXAMPLES: The octahedron has 12 edges:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: len(o.edges())
        12
        sage: o.edges()
        [[1, 5], [0, 5], [0, 1], [3, 5], [1, 3], [4, 5], [0, 4], [3, 4], [1, 2], [0, 2], [2, 3], [2, 4]]

  `faces`(dim=None, codim=None)

    Return the sequence of proper faces of this polytope.

    If `dim` or `codim` are specified, returns a sequence of faces of the corresponding dimension or codimension. Otherwise returns the sequence of such sequences for all dimensions.

    EXAMPLES: All faces of the 3-dimensional octahedron:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.faces()
        [
        [[0], [1], [2], [3], [4], [5]],
        [[1, 5], [0, 5], [0, 1], [3, 5], [1, 3], [4, 5], [0, 4], [3, 4], [1, 2], [0, 2], [2, 3], [2, 4]],
        [[0, 1, 5], [1, 3, 5], [0, 4, 5], [3, 4, 5], [0, 1, 2], [1, 2, 3], [0, 2, 4], [2, 3, 4]]
        ]

    Its faces of dimension one (i.e., edges):

        sage: o.faces(dim=1)
        [[1, 5], [0, 5], [0, 1], [3, 5], [1, 3], [4, 5], [0, 4], [3, 4], [1, 2], [0, 2], [2, 3], [2, 4]]

    Its faces of codimension two (also edges):

        sage: o.faces(codim=2)
        [[1, 5], [0, 5], [0, 1], [3, 5], [1, 3], [4, 5], [0, 4], [3, 4], [1, 2], [0, 2], [2, 3], [2, 4]]

    It is an error to specify both dimension and codimension at the same time, even if they do agree:

        sage: o.faces(dim=1, codim=2)
        Traceback (most recent call last):
        ...
        ValueError: Both dim and codim are given!

    The only faces of a zero-dimensional polytope are the empty set and the polytope itself, i.e. it has no proper faces at all:

        sage: p = LatticePolytope([[1]])
        sage: p.vertices_pc()
        M(1)
        in 1-d lattice M
        sage: p.faces()
        []

    In particular, you an exception will be raised if you try to access faces of the given dimension or codimension, including edges and facets:

        sage: p.facets()
        Traceback (most recent call last):
        ...
        IndexError: list index out of range

  `facet_constant`(i)

    Return the constant in the `i`-th facet inequality of this polytope.

    The i-th facet inequality is given by self.facet_normal(i) * X + self.facet_constant(i) >= 0.

    INPUT:

    - `i` - integer, the index of the facet

    OUTPUT:

    - integer – the constant in the `i`-th facet inequality.

    EXAMPLES:

    Let’s take a look at facets of the octahedron and some polytopes inside it:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: o.facet_normal(0)
        N(-1, -1, 1)
        sage: o.facet_constant(0)
        1
        sage: p = LatticePolytope(o.vertices_pc()(1,2,3,4,5))
        sage: p.vertices_pc()
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: p.facet_normal(0)
        N(-1, 0, 0)
        sage: p.facet_constant(0)
        0
        sage: p = LatticePolytope(o.vertices_pc()(1,2,4,5))
        sage: p.vertices_pc()
        M(0,  1,  0),
        M(0,  0,  1),
        M(0, -1,  0),
        M(0,  0, -1)
        in 3-d lattice M
        sage: p.facet_normal(0)
        N(0, -1, 1)
        sage: p.facet_constant(0)
        1

    This is a 2-dimensional lattice polytope in a 4-dimensional space:

        sage: p = LatticePolytope([(1,-1,1,3), (-1,-1,1,3), (0,0,0,0)])
        sage: p
        2-d lattice polytope in 4-d lattice M
        sage: p.vertices_pc()
        M( 1, -1, 1, 3),
        M(-1, -1, 1, 3),
        M( 0,  0, 0, 0)
        in 4-d lattice M
        sage: fns = [p.facet_normal(i) for i in range(p.nfacets())]
        sage: fns
        [N(11, -1, 1, 3), N(-11, -1, 1, 3), N(0, 1, -1, -3)]
        sage: fcs = [p.facet_constant(i) for i in range(p.nfacets())]
        sage: fcs
        [0, 0, 11]

    Now we manually compute the distance matrix of this polytope. Since it is a triangle, each line (corresponding to a facet) should have two zeros (vertices of the corresponding facet) and one positive number (since our normals are inner):

        sage: matrix([[fns[i] * p.vertex(j) + fcs[i]
        ...            for j in range(p.nvertices())]
        ...           for i in range(p.nfacets())])
        [22  0  0]
        [ 0 22  0]
        [ 0  0 11]

  `facet_constants`()

    Return facet constants of `self`.

    OUTPUT:

    - an integer vector.

    EXAMPLES:

    For reflexive polytopes all constants are 1:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: o.facet_constants()
        (1, 1, 1, 1, 1, 1, 1, 1)

    Here is an example of a 3-dimensional polytope in a 4-dimensional space with 3 facets containing the origin:

        sage: p = LatticePolytope([(0,0,0,0), (1,1,1,3),
        ...                        (1,-1,1,3), (-1,-1,1,3)])
        sage: p.vertices_pc()
        M( 0,  0, 0, 0),
        M( 1,  1, 1, 3),
        M( 1, -1, 1, 3),
        M(-1, -1, 1, 3)
        in 4-d lattice M
        sage: p.facet_constants()
        (0, 0, 0, 10)

  `facet_normal`(i)

    Return the inner normal to the `i`-th facet of this polytope.

    If this polytope is not full-dimensional, facet normals will be orthogonal to the integer kernel of the affine subspace spanned by this polytope.

    INPUT:

    - `i` – integer, the index of the facet

    OUTPUT:

    - vectors – the inner normal of the `i`-th facet

    EXAMPLES:

    Let’s take a look at facets of the octahedron and some polytopes inside it:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: o.facet_normal(0)
        N(-1, -1, 1)
        sage: o.facet_constant(0)
        1
        sage: p = LatticePolytope(o.vertices_pc()(1,2,3,4,5))
        sage: p.vertices_pc()
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: p.facet_normal(0)
        N(-1, 0, 0)
        sage: p.facet_constant(0)
        0
        sage: p = LatticePolytope(o.vertices_pc()(1,2,4,5))
        sage: p.vertices_pc()
        M(0,  1,  0),
        M(0,  0,  1),
        M(0, -1,  0),
        M(0,  0, -1)
        in 3-d lattice M
        sage: p.facet_normal(0)
        N(0, -1, 1)
        sage: p.facet_constant(0)
        1

    Here is an example of a 3-dimensional polytope in a 4-dimensional space:

        sage: p = LatticePolytope([(0,0,0,0), (1,1,1,3),
        ...                        (1,-1,1,3), (-1,-1,1,3)])
        sage: p.vertices_pc()
        M( 0,  0, 0, 0),
        M( 1,  1, 1, 3),
        M( 1, -1, 1, 3),
        M(-1, -1, 1, 3)
        in 4-d lattice M
        sage: ker = p.vertices_pc().column_matrix().integer_kernel().matrix()
        sage: ker
        [ 0  0  3 -1]
        sage: ker * p.facet_normals()
        [0 0 0 0]

    Now we manually compute the distance matrix of this polytope. Since it is a simplex, each line (corresponding to a facet) should consist of zeros (indicating generating vertices of the corresponding facet) and a single positive number (since our normals are inner):

        sage: matrix([[p.facet_normal(i) * p.vertex(j)
        ...            + p.facet_constant(i)
        ...            for j in range(p.nvertices())]
        ...           for i in range(p.nfacets())])
        [ 0  0  0 20]
        [ 0  0 20  0]
        [ 0 20  0  0]
        [10  0  0  0]

  `facet_normals`()

    Return inner normals to the facets of `self`.

    OUTPUT:

    - a `point collection` in the `dual_lattice()` of `self`.

    EXAMPLES:

    Normals to facets of an octahedron are vertices of a cube:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: o.facet_normals()
        N(-1, -1,  1),
        N( 1, -1,  1),
        N(-1,  1,  1),
        N( 1,  1,  1),
        N(-1, -1, -1),
        N( 1, -1, -1),
        N(-1,  1, -1),
        N( 1,  1, -1)
        in 3-d lattice N

    Here is an example of a 3-dimensional polytope in a 4-dimensional space:

        sage: p = LatticePolytope([(0,0,0,0), (1,1,1,3),
        ...                        (1,-1,1,3), (-1,-1,1,3)])
        sage: p.vertices_pc()
        M( 0,  0, 0, 0),
        M( 1,  1, 1, 3),
        M( 1, -1, 1, 3),
        M(-1, -1, 1, 3)
        in 4-d lattice M
        sage: p.facet_normals()
        N(-10,   0,  1,  3),
        N( 10, -10,  0,  0),
        N(  0,  10,  1,  3),
        N(  0,   0, -1, -3)
        in 4-d lattice N

  `facets`()

    Return the sequence of facets of this polytope (i.e. faces of codimension 1).

    EXAMPLES: All facets of the 3-dimensional octahedron:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.facets()
        [[0, 1, 5], [1, 3, 5], [0, 4, 5], [3, 4, 5], [0, 1, 2], [1, 2, 3], [0, 2, 4], [2, 3, 4]]

    Facets are the same as faces of codimension one:

        sage: o.facets() is o.faces(codim=1)
        True

  `index`()

    Return the index of this polytope in the internal database of 2- or 3-dimensional reflexive polytopes. Databases are stored in the directory of the package.

    Note

    The first call to this function for each dimension can take a few seconds while the dictionary of all polytopes is constructed, but after that it is cached and fast.

    Return type: | integer

    EXAMPLES: We check what is the index of the “diamond” in the database:

        sage: d = lattice_polytope.cross_polytope(2)
        sage: d.index()
        3

    Note that polytopes with the same index are not necessarily the same:

        sage: d.vertices_pc()
        M( 1,  0),
        M( 0,  1),
        M(-1,  0),
        M( 0, -1)
        in 2-d lattice M
        sage: lattice_polytope.ReflexivePolytope(2,3).vertices_pc()
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M

    But they are in the same \(GL(Z^n)\) orbit and have the same normal form:

        sage: d.normal_form_pc()
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M
        sage: lattice_polytope.ReflexivePolytope(2,3).normal_form_pc()
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M

  `is_reflexive`()

    Return True if this polytope is reflexive.

    EXAMPLES: The 3-dimensional octahedron is reflexive (and 4318 other 3-polytopes):

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.is_reflexive()
        True

    But not all polytopes are reflexive:

        sage: p = LatticePolytope([(1,0,0), (0,1,17), (-1,0,0), (0,-1,0)])
        sage: p.is_reflexive()
        False

    Only full-dimensional polytopes can be reflexive (otherwise the polar set is not a polytope at all, since it is unbounded):

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.is_reflexive()
        False

  `lattice`()

    Return the ambient lattice of `self`.

    OUTPUT:

    - a lattice.

    EXAMPLES:

        sage: lattice_polytope.cross_polytope(3).lattice()
        3-d lattice M

  `linearly_independent_vertices`()

    Return a maximal set of linearly independent vertices.

    OUTPUT:

    A tuple of vertex indices.

    EXAMPLES:

        sage: L = LatticePolytope([[0, 0], [-1, 1], [-1, -1]])
        sage: L.linearly_independent_vertices()
        (1, 2)
        sage: L = LatticePolytope([[0, 0, 0]])
        sage: L.linearly_independent_vertices()
        ()
        sage: L = LatticePolytope([[0, 1, 0]])
        sage: L.linearly_independent_vertices()
        (0,)

  `nef_partitions`(keep_symmetric=False, keep_products=True, keep_projections=True, hodge_numbers=False)

    Return 2-part nef-partitions of `self`.

    INPUT:

    - `keep_symmetric` – (default: `False`) if `True`, “-s” option will be passed to `nef.x` in order to keep symmetric partitions, i.e. partitions related by lattice automorphisms preserving `self`;
    - `keep_products` – (default: `True`) if `True`, “-D” option will be passed to `nef.x` in order to keep product partitions, with corresponding complete intersections being direct products;
    - `keep_projections` – (default: `True`) if `True`, “-P” option will be passed to `nef.x` in order to keep projection partitions, i.e. partitions with one of the parts consisting of a single vertex;
    - `hodge_numbers` – (default: `False`) if `False`, “-p” option will be passed to `nef.x` in order to skip Hodge numbers computation, which takes a lot of time.

    OUTPUT:

    - a sequence of `nef-partitions`.

    Type `NefPartition?` for definitions and notation.

    EXAMPLES:

    Nef-partitions of the 4-dimensional cross-polytope:

        sage: p = lattice_polytope.cross_polytope(4)
        sage: p.nef_partitions()
        [
        Nef-partition {0, 1, 4, 5} U {2, 3, 6, 7} (direct product),
        Nef-partition {0, 1, 2, 4} U {3, 5, 6, 7},
        Nef-partition {0, 1, 2, 4, 5} U {3, 6, 7},
        Nef-partition {0, 1, 2, 4, 5, 6} U {3, 7} (direct product),
        Nef-partition {0, 1, 2, 3} U {4, 5, 6, 7},
        Nef-partition {0, 1, 2, 3, 4} U {5, 6, 7},
        Nef-partition {0, 1, 2, 3, 4, 5} U {6, 7},
        Nef-partition {0, 1, 2, 3, 4, 5, 6} U {7} (projection)
        ]

    Now we omit projections:

        sage: p.nef_partitions(keep_projections=False)
        [
        Nef-partition {0, 1, 4, 5} U {2, 3, 6, 7} (direct product),
        Nef-partition {0, 1, 2, 4} U {3, 5, 6, 7},
        Nef-partition {0, 1, 2, 4, 5} U {3, 6, 7},
        Nef-partition {0, 1, 2, 4, 5, 6} U {3, 7} (direct product),
        Nef-partition {0, 1, 2, 3} U {4, 5, 6, 7},
        Nef-partition {0, 1, 2, 3, 4} U {5, 6, 7},
        Nef-partition {0, 1, 2, 3, 4, 5} U {6, 7}
        ]

    Currently Hodge numbers cannot be computed for a given nef-partition:

        sage: p.nef_partitions()[1].hodge_numbers()
        Traceback (most recent call last):
        ...
        NotImplementedError: use nef_partitions(hodge_numbers=True)!

    But they can be obtained from `nef.x` for all nef-partitions at once. Partitions will be exactly the same:

        sage: p.nef_partitions(hodge_numbers=True)  # long time (2s on sage.math, 2011)
        [
        Nef-partition {0, 1, 4, 5} U {2, 3, 6, 7} (direct product),
        Nef-partition {0, 1, 2, 4} U {3, 5, 6, 7},
        Nef-partition {0, 1, 2, 4, 5} U {3, 6, 7},
        Nef-partition {0, 1, 2, 4, 5, 6} U {3, 7} (direct product),
        Nef-partition {0, 1, 2, 3} U {4, 5, 6, 7},
        Nef-partition {0, 1, 2, 3, 4} U {5, 6, 7},
        Nef-partition {0, 1, 2, 3, 4, 5} U {6, 7},
        Nef-partition {0, 1, 2, 3, 4, 5, 6} U {7} (projection)
        ]

    Now it is possible to get Hodge numbers:

        sage: p.nef_partitions(hodge_numbers=True)[1].hodge_numbers()
        (20,)

    Since nef-partitions are cached, their Hodge numbers are accessible after the first request, even if you do not specify `hodge_numbers=True` anymore:

        sage: p.nef_partitions()[1].hodge_numbers()
        (20,)

    We illustrate removal of symmetric partitions on a diamond:

        sage: p = lattice_polytope.cross_polytope(2)
        sage: p.nef_partitions()
        [
        Nef-partition {0, 2} U {1, 3} (direct product),
        Nef-partition {0, 1} U {2, 3},
        Nef-partition {0, 1, 2} U {3} (projection)
        ]
        sage: p.nef_partitions(keep_symmetric=True)
        [
        Nef-partition {0, 1, 3} U {2} (projection),
        Nef-partition {0, 2, 3} U {1} (projection),
        Nef-partition {0, 3} U {1, 2},
        Nef-partition {1, 2, 3} U {0} (projection),
        Nef-partition {1, 3} U {0, 2} (direct product),
        Nef-partition {2, 3} U {0, 1},
        Nef-partition {0, 1, 2} U {3} (projection)
        ]

    Nef-partitions can be computed only for reflexive polytopes:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (0,0,2),
        ...                        (-1,0,0), (0,-1,0), (0,0,-1)])
        sage: p.nef_partitions()
        Traceback (most recent call last):
        ...
        ValueError: The given polytope is not reflexive!
        Polytope: 3-d lattice polytope in 3-d lattice M

  `nef_x`(keys)

    Run nef.x with given `keys` on vertices of this polytope.

    INPUT:

    - `keys` - a string of options passed to nef.x. The key “-f” is added automatically.

    OUTPUT: the output of nef.x as a string.

    EXAMPLES: This call is used internally for computing nef-partitions:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: s = o.nef_x("-N -V -p")
        sage: s                      # output contains random time
        M:27 8 N:7 6  codim=2 #part=5
        3 6  Vertices of P:
            1    0    0   -1    0    0
            0    1    0    0   -1    0
            0    0    1    0    0   -1
         P:0 V:2 4 5       0sec  0cpu
         P:2 V:3 4 5       0sec  0cpu
         P:3 V:4 5       0sec  0cpu
        np=3 d:1 p:1    0sec     0cpu

  `nfacets`()

    Return the number of facets of this polytope.

    EXAMPLES: The number of facets of the 3-dimensional octahedron:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.nfacets()
        8

    The number of facets of an interval is 2:

        sage: LatticePolytope(([1],[2])).nfacets()
        2

    Now consider a 2-dimensional diamond in a 3-dimensional space:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.nfacets()
        4

  `normal_form`()

    Return the normal form of `self` as a matrix.

    EXAMPLES:

    We compute the normal form of the “diamond”:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.normal_form()
        doctest:...: DeprecationWarning: normal_form() output will change,
        please use normal_form_pc().column_matrix() instead
        or consider using normal_form_pc() directly!
        See http://trac.sagemath.org/15240 for details.
        [ 1  0  0  0  0 -1]
        [ 0  1  0  0 -1  0]
        [ 0  0  1 -1  0  0]

  `normal_form_pc`(algorithm='palp', permutation=False)

    Return the normal form of vertices of `self`.

    Two full-dimensional lattice polytopes are in the same `GL(\mathbb{Z})`-orbit if and only if their normal forms are the same. Normal form is not defined and thus cannot be used for polytopes whose dimension is smaller than the dimension of the ambient space.

    The original algorithm was presented in [KS98] and implemented in PALP. A modified version of the PALP algorithm is discussed in [GK13] and available here as “palp_modified”.

    INPUT:

    - `algorithm` – (default: “palp”) The algorithm which is used to compute the normal form. Options are:
      - “palp” – Run external PALP code, usually the fastest option.
      - “palp_native” – The original PALP algorithm implemented in sage. Currently considerably slower than PALP.
      - “palp_modified” – A modified version of the PALP algorithm which determines the maximal vertex-facet pairing matrix first and then computes its automorphisms, while the PALP algorithm does both things concurrently.
    - `permutation` – (default: `False`) If `True` the permutation applied to vertices to obtain the normal form is returned as well. Note that the different algorithms may return different results that nevertheless lead to the same normal form.

    OUTPUT:

    - a `point collection` in the `lattice()` of `self` or a tuple of it and a permutation.

    REFERENCES:

    [KS98] | Maximilian Kreuzer and Harald Skarke, Classification of Reflexive Polyhedra in Three Dimensions, arXiv:hep-th/9805190

    [GK13] | Roland Grinis and Alexander Kasprzyk, Normal forms of convex lattice polytopes, arXiv:1301.6641

    EXAMPLES:

    We compute the normal form of the “diamond”:

        sage: d = LatticePolytope([(1,0), (0,1), (-1,0), (0,-1)])
        sage: d.vertices_pc()
        M( 1,  0),
        M( 0,  1),
        M(-1,  0),
        M( 0, -1)
        in 2-d lattice M
        sage: d.normal_form_pc()
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M

    The diamond is the 3rd polytope in the internal database:

        sage: d.index()
        3
        sage: d
        2-d reflexive polytope #3 in 2-d lattice M

    You can get it in its normal form (in the default lattice) as

        sage: lattice_polytope.ReflexivePolytope(2, 3).vertices_pc()
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M

    It is not possible to compute normal forms for polytopes which do not span the space:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.normal_form()
        Traceback (most recent call last):
        ...
        ValueError: normal form is not defined for
        2-d lattice polytope in 3-d lattice M

    We can perform the same examples using other algorithms:

        sage: o = lattice_polytope.cross_polytope(2)
        sage: o.normal_form_pc(algorithm="palp_native")
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M

        sage: o = lattice_polytope.cross_polytope(2)
        sage: o.normal_form_pc(algorithm="palp_modified")
        M( 1,  0),
        M( 0,  1),
        M( 0, -1),
        M(-1,  0)
        in 2-d lattice M

  `npoints`()

    Return the number of lattice points of this polytope.

    EXAMPLES: The number of lattice points of the 3-dimensional octahedron and its polar cube:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.npoints()
        7
        sage: cube = o.polar()
        sage: cube.npoints()
        27

  `nvertices`()

    Return the number of vertices of this polytope.

    EXAMPLES: The number of vertices of the 3-dimensional octahedron and its polar cube:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.nvertices()
        6
        sage: cube = o.polar()
        sage: cube.nvertices()
        8

  `origin`()

    Return the index of the origin in the list of points of self.

    OUTPUT:

    - integer if the origin belongs to this polytope, `None` otherwise.

    EXAMPLES:

        sage: p = lattice_polytope.cross_polytope(2)
        sage: p.origin()
        4
        sage: p.point(p.origin())
        M(0, 0)

        sage: p = LatticePolytope(([1],[2]))
        sage: p.points_pc()
        M(1),
        M(2)
        in 1-d lattice M
        sage: print p.origin()
        None

    Now we make sure that the origin of non-full-dimensional polytopes can be identified correctly (Trac #10661):

        sage: LatticePolytope([(1,0,0), (-1,0,0)]).origin()
        2

  `parent`()

    Return the set of all lattice polytopes.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.parent()
        Set of all Lattice Polytopes

  `plot3d`(show_facets=True, facet_opacity=0.5, facet_color=(0, 1, 0), facet_colors=None, show_edges=True, edge_thickness=3, edge_color=(0.5, 0.5, 0.5), show_vertices=True, vertex_size=10, vertex_color=(1, 0, 0), show_points=True, point_size=10, point_color=(0, 0, 1), show_vindices=None, vindex_color=(0, 0, 0), vlabels=None, show_pindices=None, pindex_color=(0, 0, 0), index_shift=1.1)

    Return a 3d-plot of this polytope.

    Polytopes with ambient dimension 1 and 2 will be plotted along x-axis or in xy-plane respectively. Polytopes of dimension 3 and less with ambient dimension 4 and greater will be plotted in some basis of the spanned space.

    By default, everything is shown with more or less pretty combination of size and color parameters.

    INPUT: Most of the parameters are self-explanatory:

    - `show_facets` - (default:True)
    - `facet_opacity` - (default:0.5)
    - `facet_color` - (default:(0,1,0))
    - `facet_colors` - (default:None) if specified, must be a list of colors for each facet separately, used instead of `facet_color`
    - `show_edges` - (default:True) whether to draw edges as lines
    - `edge_thickness` - (default:3)
    - `edge_color` - (default:(0.5,0.5,0.5))
    - `show_vertices` - (default:True) whether to draw vertices as balls
    - `vertex_size` - (default:10)
    - `vertex_color` - (default:(1,0,0))
    - `show_points` - (default:True) whether to draw other poits as balls
    - `point_size` - (default:10)
    - `point_color` - (default:(0,0,1))
    - `show_vindices` - (default:same as show_vertices) whether to show indices of vertices
    - `vindex_color` - (default:(0,0,0)) color for vertex labels
    - `vlabels` - (default:None) if specified, must be a list of labels for each vertex, default labels are vertex indicies
    - `show_pindices` - (default:same as show_points) whether to show indices of other points
    - `pindex_color` - (default:(0,0,0)) color for point labels
    - `index_shift` - (default:1.1)) if 1, labels are placed exactly at the corresponding points. Otherwise the label position is computed as a multiple of the point position vector.

    EXAMPLES: The default plot of a cube:

        sage: c = lattice_polytope.cross_polytope(3).polar()
        sage: c.plot3d()
        Graphics3d Object

    Plot without facets and points, shown without the frame:

        sage: c.plot3d(show_facets=false,show_points=false).show(frame=False)

    Plot with facets of different colors:

        sage: c.plot3d(facet_colors=rainbow(c.nfacets(), 'rgbtuple'))
        Graphics3d Object

    It is also possible to plot lower dimensional polytops in 3D (let’s also change labels of vertices):

        sage: lattice_polytope.cross_polytope(2).plot3d(vlabels=["A", "B", "C", "D"])
        Graphics3d Object

    TESTS:

        sage: p = LatticePolytope([[0,0,0],[0,1,1],[1,0,1],[1,1,0]])
        sage: p.plot3d()
        Graphics3d Object

  `point`(i)

    Return the i-th point of this polytope, i.e. the i-th column of the matrix returned by points().

    EXAMPLES: First few points are actually vertices:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: o.point(1)
        M(0, 1, 0)

    The only other point in the octahedron is the origin:

        sage: o.point(6)
        M(0, 0, 0)
        sage: o.points_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1),
        M( 0,  0,  0)
        in 3-d lattice M

  `points`()

    Return all lattice points of this polytope as columns of a matrix.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.points()
        doctest:...: DeprecationWarning: points() output will change,
        please use points_pc().column_matrix() instead or
        consider using points_pc() directly!
        See http://trac.sagemath.org/15240 for details.
        [ 1  0  0 -1  0  0  0]
        [ 0  1  0  0 -1  0  0]
        [ 0  0  1  0  0 -1  0]

  `points_pc`()

    Return all lattice points of `self`.

    OUTPUT:

    - a `point collection`.

    EXAMPLES:

    Lattice points of the octahedron and its polar cube:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.points_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1),
        M( 0,  0,  0)
        in 3-d lattice M
        sage: cube = o.polar()
        sage: cube.points_pc()
        N(-1, -1,  1),
        N( 1, -1,  1),
        N(-1,  1,  1),
        N( 1,  1,  1),
        N(-1, -1, -1),
        N( 1, -1, -1),
        N(-1,  1, -1),
        N( 1,  1, -1),
        N(-1, -1,  0),
        N(-1,  0, -1),
        N(-1,  0,  0),
        N(-1,  0,  1),
        N(-1,  1,  0),
        N( 0, -1, -1),
        N( 0, -1,  0),
        N( 0, -1,  1),
        N( 0,  0, -1),
        N( 0,  0,  0),
        N( 0,  0,  1),
        N( 0,  1, -1),
        N( 0,  1,  0),
        N( 0,  1,  1),
        N( 1, -1,  0),
        N( 1,  0, -1),
        N( 1,  0,  0),
        N( 1,  0,  1),
        N( 1,  1,  0)
        in 3-d lattice N

    Lattice points of a 2-dimensional diamond in a 3-dimensional space:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.points_pc()
        M( 1,  0, 0),
        M( 0,  1, 0),
        M(-1,  0, 0),
        M( 0, -1, 0),
        M( 0,  0, 0)
        in 3-d lattice M

    We check that points of a zero-dimensional polytope can be computed:

        sage: p = LatticePolytope([[1]])
        sage: p.points_pc()
        M(1)
        in 1-d lattice M

  `polar`()

    Return the polar polytope, if this polytope is reflexive.

    EXAMPLES: The polar polytope to the 3-dimensional octahedron:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: cube = o.polar()
        sage: cube
        3-d reflexive polytope in 3-d lattice N

    The polar polytope “remembers” the original one:

        sage: cube.polar()
        3-d reflexive polytope in 3-d lattice M
        sage: cube.polar().polar() is cube
        True

    Only reflexive polytopes have polars:

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (0,0,2),
        ...                        (-1,0,0), (0,-1,0), (0,0,-1)])
        sage: p.polar()
        Traceback (most recent call last):
        ...
        ValueError: The given polytope is not reflexive!
        Polytope: 3-d lattice polytope in 3-d lattice M

  `poly_x`(keys, reduce_dimension=False)

    Run poly.x with given `keys` on vertices of this polytope.

    INPUT:

    - `keys` - a string of options passed to poly.x. The key “f” is added automatically.
    - `reduce_dimension` - (default: False) if `True` and this polytope is not full-dimensional, poly.x will be called for the vertices of this polytope in some basis of the spanned affine space.

    OUTPUT: the output of poly.x as a string.

    EXAMPLES: This call is used for determining if a polytope is reflexive or not:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: print o.poly_x("e")
        8 3  Vertices of P-dual <-> Equations of P
          -1  -1   1
           1  -1   1
          -1   1   1
           1   1   1
          -1  -1  -1
           1  -1  -1
          -1   1  -1
           1   1  -1

    Since PALP has limits on different parameters determined during compilation, the following code is likely to fail, unless you change default settings of PALP:

        sage: BIG = lattice_polytope.cross_polytope(7)
        sage: BIG
        7-d lattice polytope in 7-d lattice M
        sage: BIG.poly_x("e")      # possibly different output depending on your system
        Traceback (most recent call last):
        ...
        ValueError: Error executing 'poly.x -fe' for the given polytope!
        Output:
        Please increase POLY_Dmax to at least 7

    You cannot call poly.x for polytopes that don’t span the space (if you could, it would crush anyway):

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)])
        sage: p.poly_x("e")
        Traceback (most recent call last):
        ...
        ValueError: Cannot run PALP for a 2-dimensional polytope in a 3-dimensional space!

    But if you know what you are doing, you can call it for the polytope in some basis of the spanned space:

        sage: print p.poly_x("e", reduce_dimension=True)
        4 2  Equations of P
          -1   1     0
           1   1     2
          -1  -1     0
           1  -1     2

  `show3d`()

    Show a 3d picture of the polytope with default settings and without axes or frame.

    See self.plot3d? for more details.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.show3d()

  `skeleton`()

    Return the graph of the one-skeleton of this polytope.

    EXAMPLES: We construct the one-skeleton graph for the “diamond”:

        sage: d = lattice_polytope.cross_polytope(2)
        sage: g = d.skeleton()
        sage: g
        Graph on 4 vertices
        sage: g.edges()
        [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)]

  `skeleton_points`(k=1)

    Return the increasing list of indices of lattice points in k-skeleton of the polytope (k is 1 by default).

    EXAMPLES: We compute all skeleton points for the cube:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: c = o.polar()
        sage: c.skeleton_points()
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 19, 21, 22, 23, 25, 26]

    The default was 1-skeleton:

        sage: c.skeleton_points(k=1)
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 19, 21, 22, 23, 25, 26]

    0-skeleton just lists all vertices:

        sage: c.skeleton_points(k=0)
        [0, 1, 2, 3, 4, 5, 6, 7]

    2-skeleton lists all points except for the origin (point #17):

        sage: c.skeleton_points(k=2)
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26]

    3-skeleton includes all points:

        sage: c.skeleton_points(k=3)
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]

    It is OK to compute higher dimensional skeletons - you will get the list of all points:

        sage: c.skeleton_points(k=100)
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]

  `skeleton_show`(normal=None)

    Show the graph of one-skeleton of this polytope. Works only for polytopes in a 3-dimensional space.

    INPUT:

    - `normal` - a 3-dimensional vector (can be given as a list), which should be perpendicular to the screen. If not given, will be selected randomly (new each time and it may be far from “nice”).

    EXAMPLES: Show a pretty picture of the octahedron:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.skeleton_show([1,2,4])

    Does not work for a diamond at the moment:

        sage: d = lattice_polytope.cross_polytope(2)
        sage: d.skeleton_show()
        Traceback (most recent call last):
        ...
        NotImplementedError: skeleton view is implemented only in 3-d space

  `traverse_boundary`()

    Return a list of indices of vertices of a 2-dimensional polytope in their boundary order.

    Needed for plot3d function of polytopes.

    EXAMPLES:

    > sage: p = lattice_polytope.cross_polytope(2).polar() sage: p.traverse_boundary() [0, 1, 3, 2]

  `vertex`(i)

    Return the i-th vertex of this polytope, i.e. the i-th column of the matrix returned by vertices().

    EXAMPLES: Note that numeration starts with zero:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: o.vertex(3)
        M(-1, 0, 0)

  `vertex_facet_pairing_matrix`()

    Return the vertex facet pairing matrix \(PM\).

    Return a matrix whose the \(i, j^\text{th}\) entry is the height of the \(j^\text{th}\) vertex over the \(i^\text{th}\) facet. The ordering of the vertices and facets is as in `vertices()` and `facets()`.

    EXAMPLES:

        sage: L = lattice_polytope.cross_polytope(3)
        sage: L.vertex_facet_pairing_matrix()
        [0 0 2 2 2 0]
        [2 0 2 0 2 0]
        [0 2 2 2 0 0]
        [2 2 2 0 0 0]
        [0 0 0 2 2 2]
        [2 0 0 0 2 2]
        [0 2 0 2 0 2]
        [2 2 0 0 0 2]

  `vertices`()

    Return vertices of this polytope as columns of a matrix.

    EXAMPLES: The lattice points of the 3-dimensional octahedron and its polar cube:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices()
        doctest:...: DeprecationWarning: vertices() output will change,
        please use vertices_pc().column_matrix() instead or
        consider using vertices_pc() directly!
        See http://trac.sagemath.org/15240 for details.
        [ 1  0  0 -1  0  0]
        [ 0  1  0  0 -1  0]
        [ 0  0  1  0  0 -1]
        sage: cube = o.polar()
        sage: cube.vertices()
        [-1  1 -1  1 -1  1 -1  1]
        [-1 -1  1  1 -1 -1  1  1]
        [ 1  1  1  1 -1 -1 -1 -1]

  `vertices_pc`()

    Return vertices of `self`.

    OUTPUT:

    - a `point collection`.

    EXAMPLES:

    Vertices of the octahedron and its polar cube are in dual lattices:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: o.vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: cube = o.polar()
        sage: cube.vertices_pc()
        N(-1, -1,  1),
        N( 1, -1,  1),
        N(-1,  1,  1),
        N( 1,  1,  1),
        N(-1, -1, -1),
        N( 1, -1, -1),
        N(-1,  1, -1),
        N( 1,  1, -1)
        in 3-d lattice N

class `sage.geometry.lattice_polytope.``NefPartition`(data, Delta_polar, check=True)

  Bases: `sage.structure.sage_object.SageObject`, `_abcoll.Hashable`

  Create a nef-partition.

  INPUT:

  - `data` – a list of integers, the \(i\)-th element of this list must be the part of the $i$-th vertex of `Delta_polar` in this nef-partition;
  - `Delta_polar` – a `lattice polytope`;
  - `check` – by default the input will be checked for correctness, i.e. that `data` indeed specify a nef-partition. If you are sure that the input is correct, you can speed up construction via `check=False` option.

  OUTPUT:

  - a nef-partition of `Delta_polar`.

  Let \(M\) and \(N\) be dual lattices. Let \(\Delta \subset M_\RR\) be a reflexive polytope with polar \(\Delta^\circ \subset N_\RR\). Let \(X_\Delta\) be the toric variety associated to the normal fan of \(\Delta\). A nef-partition is a decomposition of the vertex set \(V\) of \(\Delta^\circ\) into a disjoint union \(V = V_0 \sqcup V_1 \sqcup \dots \sqcup V_{k-1}\) such that divisors \(E_i = \sum_{v\in V_i} D_v\) are Cartier (here \(D_v\) are prime torus-invariant Weil divisors corresponding to vertices of \(\Delta^\circ\)). Equivalently, let \(\nabla_i \subset N_\RR\) be the convex hull of vertices from \(V_i\) and the origin. These polytopes form a nef-partition if their Minkowski sum \(\nabla \subset N_\RR\) is a reflexive polytope.

  The dual nef-partition is formed by polytopes \(\Delta_i \subset M_\RR\) of \(E_i\), which give a decomposition of the vertex set of \(\nabla^\circ \subset M_\RR\) and their Minkowski sum is \(\Delta\), i.e. the polar duality of reflexive polytopes switches convex hull and Minkowski sum for dual nef-partitions:

  \[\begin{split}\Delta^\circ &= \mathrm{Conv} \left(\nabla_0, \nabla_1, \dots, \nabla_{k-1}\right), \\ \nabla^{\phantom{\circ}} &= \nabla_0 + \nabla_1 + \dots + \nabla_{k-1}, \\ & \\ \Delta^{\phantom{\circ}} &= \Delta_0 + \Delta_1 + \dots + \Delta_{k-1}, \\ \nabla^\circ &= \mathrm{Conv} \left(\Delta_0, \Delta_1, \dots, \Delta_{k-1}\right).\end{split}\]

  See Section 4.3.1 in [CK99] and references therein for further details, or [BN08] for a purely combinatorial approach.

  REFERENCES:

  [BN08] | (1, 2) Victor V. Batyrev and Benjamin Nill. Combinatorial aspects of mirror symmetry. In Integer points in polyhedra — geometry, number theory, representation theory, algebra, optimization, statistics, volume 452 of Contemp. Math., pages 35–66. Amer. Math. Soc., Providence, RI, 2008. arXiv:math/0703456v2 [math.CO].

  [CK99] | David A. Cox and Sheldon Katz. Mirror symmetry and algebraic geometry, volume 68 of Mathematical Surveys and Monographs. American Mathematical Society, Providence, RI, 1999.

  EXAMPLES:

  It is very easy to create a nef-partition for the octahedron, since for this polytope any decomposition of vertices is a nef-partition. We create a 3-part nef-partition with the 0-th and 1-st vertices belonging to the 0-th part (recall that numeration in Sage starts with 0), the 2-nd and 5-th vertices belonging to the 1-st part, and 3-rd and 4-th vertices belonging to the 2-nd part:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: np = NefPartition([0,0,1,2,2,1], o)
      sage: np
      Nef-partition {0, 1} U {2, 5} U {3, 4}

  The octahedron plays the role of \(\Delta^\circ\) in the above description:

      sage: np.Delta_polar() is o
      True

  The dual nef-partition (corresponding to the “mirror complete intersection”) gives decomposition of the vertex set of \(\nabla^\circ\):

      sage: np.dual()
      Nef-partition {4, 5, 6} U {1, 3} U {0, 2, 7}
      sage: np.nabla_polar().vertices_pc()
      N( 1,  1,  0),
      N( 0,  0,  1),
      N( 0,  1,  0),
      N( 0,  0, -1),
      N(-1, -1,  0),
      N( 0, -1,  0),
      N(-1,  0,  0),
      N( 1,  0,  0)
      in 3-d lattice N

  Of course, \(\nabla^\circ\) is \(\Delta^\circ\) from the point of view of the dual nef-partition:

      sage: np.dual().Delta_polar() is np.nabla_polar()
      True
      sage: np.Delta(1).vertices_pc()
      N(0, 0,  1),
      N(0, 0, -1)
      in 3-d lattice N
      sage: np.dual().nabla(1).vertices_pc()
      N(0, 0,  1),
      N(0, 0, -1)
      in 3-d lattice N

  Instead of constructing nef-partitions directly, you can request all 2-part nef-partitions of a given reflexive polytope (they will be computed using `nef.x` program from PALP):

      sage: o.nef_partitions()
      [
      Nef-partition {0, 1, 3} U {2, 4, 5},
      Nef-partition {0, 1, 3, 4} U {2, 5} (direct product),
      Nef-partition {0, 1, 2} U {3, 4, 5},
      Nef-partition {0, 1, 2, 3} U {4, 5},
      Nef-partition {0, 1, 2, 3, 4} U {5} (projection)
      ]

  `Delta`(i=None)

    Return the polytope \(\Delta\) or \(\Delta_i\) corresponding to `self`.

    INPUT:

    - `i` – an integer. If not given, \(\Delta\) will be returned.

    OUTPUT:

    - a `lattice polytope`.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.Delta().polar() is o
        True
        sage: np.Delta().vertices_pc()
        N(-1, -1,  1),
        N( 1, -1,  1),
        N(-1,  1,  1),
        N( 1,  1,  1),
        N(-1, -1, -1),
        N( 1, -1, -1),
        N(-1,  1, -1),
        N( 1,  1, -1)
        in 3-d lattice N
        sage: np.Delta(0).vertices_pc()
        N( 1, -1, 0),
        N( 1,  0, 0),
        N(-1, -1, 0),
        N(-1,  0, 0)
        in 3-d lattice N

  `Delta_polar`()

    Return the polytope \(\Delta^\circ\) corresponding to `self`.

    OUTPUT:

    - a `lattice polytope`.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLE:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.Delta_polar() is o
        True

  `Deltas`()

    Return the polytopes \(\Delta_i\) corresponding to `self`.

    OUTPUT:

    - a tuple of `lattice polytopes`.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.Delta().vertices_pc()
        N(-1, -1,  1),
        N( 1, -1,  1),
        N(-1,  1,  1),
        N( 1,  1,  1),
        N(-1, -1, -1),
        N( 1, -1, -1),
        N(-1,  1, -1),
        N( 1,  1, -1)
        in 3-d lattice N
        sage: [Delta_i.vertices_pc() for Delta_i in np.Deltas()]
        [N( 1, -1, 0),
        N( 1,  0, 0),
        N(-1, -1, 0),
        N(-1,  0, 0)
        in 3-d lattice N,
        N(0, 1,  1),
        N(0, 0,  1),
        N(0, 0, -1),
        N(0, 1, -1)
        in 3-d lattice N]
        sage: np.nabla_polar().vertices_pc()
        N( 1, -1,  0),
        N( 0,  1,  1),
        N( 1,  0,  0),
        N( 0,  0,  1),
        N( 0,  0, -1),
        N(-1, -1,  0),
        N( 0,  1, -1),
        N(-1,  0,  0)
        in 3-d lattice N

  `dual`()

    Return the dual nef-partition.

    OUTPUT:

    - a `nef-partition`.

    See the class documentation for the definition.

    ALGORITHM:

    See Proposition 3.19 in [BN08].

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.dual()
        Nef-partition {0, 2, 5, 7} U {1, 3, 4, 6}
        sage: np.dual().Delta() is np.nabla()
        True
        sage: np.dual().nabla(0) is np.Delta(0)
        True

  `hodge_numbers`()

    Return Hodge numbers corresponding to `self`.

    OUTPUT:

    - a tuple of integers (produced by `nef.x` program from PALP).

    EXAMPLES:

    Currently, you need to request Hodge numbers when you compute nef-partitions:

        sage: p = lattice_polytope.cross_polytope(5)
        sage: np = p.nef_partitions()[0]  # long time (4s on sage.math, 2011)
        sage: np.hodge_numbers()  # long time
        Traceback (most recent call last):
        ...
        NotImplementedError: use nef_partitions(hodge_numbers=True)!
        sage: np = p.nef_partitions(hodge_numbers=True)[0]  # long time (13s on sage.math, 2011)
        sage: np.hodge_numbers()  # long time
        (19, 19)

  `nabla`(i=None)

    Return the polytope \(\nabla\) or \(\nabla_i\) corresponding to `self`.

    INPUT:

    - `i` – an integer. If not given, \(\nabla\) will be returned.

    OUTPUT:

    - a `lattice polytope`.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.Delta_polar().vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: np.nabla(0).vertices_pc()
        M( 1, 0, 0),
        M( 0, 1, 0),
        M(-1, 0, 0)
        in 3-d lattice M
        sage: np.nabla().vertices_pc()
        M( 1,  0,  1),
        M( 1, -1,  0),
        M( 1,  0, -1),
        M( 0,  1,  1),
        M( 0,  1, -1),
        M(-1,  0,  1),
        M(-1, -1,  0),
        M(-1,  0, -1)
        in 3-d lattice M

  `nabla_polar`()

    Return the polytope \(\nabla^\circ\) corresponding to `self`.

    OUTPUT:

    - a `lattice polytope`.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.nabla_polar().vertices_pc()
        N( 1, -1,  0),
        N( 0,  1,  1),
        N( 1,  0,  0),
        N( 0,  0,  1),
        N( 0,  0, -1),
        N(-1, -1,  0),
        N( 0,  1, -1),
        N(-1,  0,  0)
        in 3-d lattice N
        sage: np.nabla_polar() is np.dual().Delta_polar()
        True

  `nablas`()

    Return the polytopes \(\nabla_i\) corresponding to `self`.

    OUTPUT:

    - a tuple of `lattice polytopes`.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.Delta_polar().vertices_pc()
        M( 1,  0,  0),
        M( 0,  1,  0),
        M( 0,  0,  1),
        M(-1,  0,  0),
        M( 0, -1,  0),
        M( 0,  0, -1)
        in 3-d lattice M
        sage: [nabla_i.vertices_pc() for nabla_i in np.nablas()]
        [M( 1, 0, 0),
        M( 0, 1, 0),
        M(-1, 0, 0)
        in 3-d lattice M,
        M(0,  0,  1),
        M(0, -1,  0),
        M(0,  0, -1)
        in 3-d lattice M]

  `nparts`()

    Return the number of parts in `self`.

    OUTPUT:

    - an integer.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.nparts()
        2

  `part`(i)

    Return the `i`-th part of `self`.

    INPUT:

    - `i` – an integer.

    OUTPUT:

    - a tuple of integers, indices of vertices of \(\Delta^\circ\) belonging to $V_i$.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.part(0)
        (0, 1, 3)

  `part_of`(i)

    Return the index of the part containing the `i`-th vertex.

    INPUT:

    - `i` – an integer.

    OUTPUT:

    - an integer \(j\) such that the `i`-th vertex of \(\Delta^\circ\) belongs to $V_j$.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.part_of(3)
        0
        sage: np.part_of(2)
        1

  `part_of_point`(i)

    Return the index of the part containing the `i`-th point.

    INPUT:

    - `i` – an integer.

    OUTPUT:

    - an integer \(j\) such that the `i`-th point of \(\Delta^\circ\) belongs to \(\nabla_j\).

    Note

    Since a nef-partition induces a partition on the set of boundary lattice points of \(\Delta^\circ\), the value of \(j\) is well-defined for all \(i\) but the one that corresponds to the origin, in which case this method will raise a `ValueError` exception. (The origin always belongs to all \(\nabla_j\).)

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

    We consider a relatively complicated reflexive polytope #2252 (easily accessible in Sage as `ReflexivePolytope(3, 2252)`, we create it here explicitly to avoid loading the whole database):

        sage: p = LatticePolytope([(1,0,0), (0,1,0), (0,0,1), (0,1,-1),
        ...           (0,-1,1), (-1,1,0), (0,-1,-1), (-1,-1,0), (-1,-1,2)])
        sage: np = p.nef_partitions()[0]
        sage: np
        Nef-partition {1, 2, 5, 7, 8} U {0, 3, 4, 6}
        sage: p.nvertices()
        9
        sage: p.npoints()
        15

    We see that the polytope has 6 more points in addition to vertices. One of them is the origin:

        sage: p.origin()
        14
        sage: np.part_of_point(14)
        Traceback (most recent call last):
        ...
        ValueError: the origin belongs to all parts!

    But the remaining 5 are partitioned by `np`:

        sage: [n for n in range(p.npoints())
        ...      if p.origin() != n and np.part_of_point(n) == 0]
        [1, 2, 5, 7, 8, 9, 11, 13]
        sage: [n for n in range(p.npoints())
        ...      if p.origin() != n and np.part_of_point(n) == 1]
        [0, 3, 4, 6, 10, 12]

  `parts`()

    Return all parts of `self`.

    OUTPUT:

    - a tuple of tuples of integers. The \(i\)-th tuple contains indices of vertices of $Delta^circ$ belonging to $V_i$.

    See `nef-partition` class documentation for definitions and notation.

    EXAMPLES:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: np = o.nef_partitions()[0]
        sage: np
        Nef-partition {0, 1, 3} U {2, 4, 5}
        sage: np.parts()
        ((0, 1, 3), (2, 4, 5))

`sage.geometry.lattice_polytope.``ReflexivePolytope`(dim, n)

  Return n-th reflexive polytope from the database of 2- or 3-dimensional reflexive polytopes.

  Note

  1. Numeration starts with zero: \(0 \leq n \leq 15\) for \({\rm dim} = 2\) and \(0 \leq n \leq 4318\) for \({\rm dim} = 3\).
  2. During the first call, all reflexive polytopes of requested dimension are loaded and cached for future use, so the first call for 3-dimensional polytopes can take several seconds, but all consecutive calls are fast.
  3. Equivalent to `ReflexivePolytopes(dim)[n]` but checks bounds first.

  EXAMPLES: The 3rd 2-dimensional polytope is “the diamond:”

      sage: ReflexivePolytope(2, 3)
      2-d reflexive polytope #3 in 2-d lattice M
      sage: lattice_polytope.ReflexivePolytope(2,3).vertices_pc()
      M( 1,  0),
      M( 0,  1),
      M( 0, -1),
      M(-1,  0)
      in 2-d lattice M

  There are 16 reflexive polygons and numeration starts with 0:

      sage: ReflexivePolytope(2,16)
      Traceback (most recent call last):
      ...
      ValueError: there are only 16 reflexive polygons!

  It is not possible to load a 4-dimensional polytope in this way:

      sage: ReflexivePolytope(4,16)
      Traceback (most recent call last):
      ...
      NotImplementedError: only 2- and 3-dimensional reflexive polytopes are available!

`sage.geometry.lattice_polytope.``ReflexivePolytopes`(dim)

  Return the sequence of all 2- or 3-dimensional reflexive polytopes.

  Note

  During the first call the database is loaded and cached for future use, so repetitive calls will return the same object in memory.

  Parameters: | dim (2 or 3) – dimension of required reflexive polytopes
  Return type: | list of lattice polytopes

  EXAMPLES: There are 16 reflexive polygons:

      sage: len(ReflexivePolytopes(2))
      16

  It is not possible to load 4-dimensional polytopes in this way:

      sage: ReflexivePolytopes(4)
      Traceback (most recent call last):
      ...
      NotImplementedError: only 2- and 3-dimensional reflexive polytopes are available!

class `sage.geometry.lattice_polytope.``SetOfAllLatticePolytopesClass`

  Bases: `sage.structure.parent.Set_generic`

  Base class for all parents.

  Parents are the Sage/mathematical analogues of container objects in computer science.

  INPUT:

  - `base` – An algebraic structure considered to be the “base” of this parent (e.g. the base field for a vector space).
  - `category` – a category or list/tuple of categories. The category in which this parent lies (or list or tuple thereof). Since categories support more general super-categories, this should be the most specific category possible. If category is a list or tuple, a JoinCategory is created out of them. If category is not specified, the category will be guessed (see `CategoryObject`), but won’t be used to inherit parent’s or element’s code from this category.
  - `element_constructor` – A class or function that creates elements of this Parent given appropriate input (can also be filled in later with `_populate_coercion_lists_()`)
  - `gens` – Generators for this object (can also be filled in later with `_populate_generators_()`)
  - `names` – Names of generators.
  - `normalize` – Whether to standardize the names (remove punctuation, etc)
  - `facade` – a parent, or tuple thereof, or `True`

  If `facade` is specified, then `Sets().Facade()` is added to the categories of the parent. Furthermore, if `facade` is not `True`, the internal attribute `_facade_for` is set accordingly for use by `Sets.Facade.ParentMethods.facade_for()`.

  Internal invariants:

  - `self._element_init_pass_parent == guess_pass_parent(self, self._element_constructor)` Ensures that `__call__()` passes down the parent properly to `_element_constructor()`. See trac ticket #5979.

  Todo

  Eventually, category should be `Sets` by default.

  TESTS:

  We check that the facade option is compatible with specifying categories as a tuple:

      sage: class MyClass(Parent): pass
      sage: P = MyClass(facade = ZZ, category = (Monoids(), CommutativeAdditiveMonoids()))
      sage: P.category()
      Join of Category of monoids and Category of commutative additive monoids and Category of facade sets

  `__call__`(x)

    TESTS:

        sage: o = lattice_polytope.cross_polytope(3)
        sage: lattice_polytope.SetOfAllLatticePolytopesClass().__call__(o)
        3-d reflexive polytope in 3-d lattice M

  `_populate_coercion_lists_`(coerce_list=[], action_list=[], convert_list=[], embedding=None, convert_method_name=None, element_constructor=None, init_no_parent=None, unpickling=False)

    This function allows one to specify coercions, actions, conversions and embeddings involving this parent.

    IT SHOULD ONLY BE CALLED DURING THE __INIT__ method, often at the end.

    INPUT:

    - `coerce_list` – a list of coercion Morphisms to self and parents with canonical coercions to self

    - `action_list` – a list of actions on and by self

    - `convert_list` – a list of conversion Maps to self and

        parents with conversions to self

    - `embedding` – a single Morphism from self

    - `convert_method_name` – a name to look for that other elements can implement to create elements of self (e.g. _integer_)

    - `element_constructor` – A callable object used by the __call__ method to construct new elements. Typically the element class or a bound method (defaults to self._element_constructor_).

    - `init_no_parent` – if True omit passing self in as the first argument of element_constructor for conversion. This is useful if parents are unique, or element_constructor is a bound method (this latter case can be detected automatically).

  `__mul__`(x)

    This is a multiplication method that more or less directly calls another attribute `_mul_` (single underscore). This is because `__mul__` can not be implemented via inheritance from the parent methods of the category, but `_mul_` can be inherited. This is, e.g., used when creating twosided ideals of matrix algebras. See trac ticket #7797.

    EXAMPLE:

        sage: MS = MatrixSpace(QQ,2,2)

    This matrix space is in fact an algebra, and in particular it is a ring, from the point of view of categories:

        sage: MS.category()
        Category of algebras over quotient fields
        sage: MS in Rings()
        True

    However, its class does not inherit from the base class `Ring`:

        sage: isinstance(MS,Ring)
        False

    Its `_mul_` method is inherited from the category, and can be used to create a left or right ideal:

        sage: MS._mul_.__module__
        'sage.categories.rings'
        sage: MS*MS.1      # indirect doctest
        Left Ideal
        (
          [0 1]
          [0 0]
        )
         of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
        sage: MS*[MS.1,2]
        Left Ideal
        (
          [0 1]
          [0 0],
        <BLANKLINE>
          [2 0]
          [0 2]
        )
         of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
        sage: MS.1*MS
        Right Ideal
        (
          [0 1]
          [0 0]
        )
         of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
        sage: [MS.1,2]*MS
        Right Ideal
        (
          [0 1]
          [0 0],
        <BLANKLINE>
          [2 0]
          [0 2]
        )
         of Full MatrixSpace of 2 by 2 dense matrices over Rational Field

  `__contains__`(x)

    True if there is an element of self that is equal to x under ==, or if x is already an element of self. Also, True in other cases involving the Symbolic Ring, which is handled specially.

    For many structures we test this by using `__call__()` and then testing equality between x and the result.

    The Symbolic Ring is treated differently because it is ultra-permissive about letting other rings coerce in, but ultra-strict about doing comparisons.

    EXAMPLES:

        sage: 2 in Integers(7)
        True
        sage: 2 in ZZ
        True
        sage: Integers(7)(3) in ZZ
        True
        sage: 3/1 in ZZ
        True
        sage: 5 in QQ
        True
        sage: I in RR
        False
        sage: SR(2) in ZZ
        True
        sage: RIF(1, 2) in RIF
        True
        sage: pi in RIF # there is no element of RIF equal to pi
        False
        sage: sqrt(2) in CC
        True
        sage: pi in RR
        True
        sage: pi in CC
        True
        sage: pi in RDF
        True
        sage: pi in CDF
        True

    TESTS:

    Check that trac ticket #13824 is fixed:

        sage: 4/3 in GF(3)
        False
        sage: 15/50 in GF(25, 'a')
        False
        sage: 7/4 in Integers(4)
        False
        sage: 15/36 in Integers(6)
        False

  `_coerce_map_from_`(S)

    Override this method to specify coercions beyond those specified in coerce_list.

    If no such coercion exists, return None or False. Otherwise, it may return either an actual Map to use for the coercion, a callable (in which case it will be wrapped in a Map), or True (in which case a generic map will be provided).

  `_convert_map_from_`(S)

    Override this method to provide additional conversions beyond those given in convert_list.

    This function is called after coercions are attempted. If there is a coercion morphism in the opposite direction, one should consider adding a section method to that.

    This MUST return a Map from S to self, or None. If None is returned then a generic map will be provided.

  `_get_action_`(S, op, self_on_left)

    Override this method to provide an action of self on S or S on self beyond what was specified in action_list.

    This must return an action which accepts an element of self and an element of S (in the order specified by self_on_left).

  `_an_element_`()

    Returns an element of self. Want it in sufficient generality that poorly-written functions won’t work when they’re not supposed to. This is cached so doesn’t have to be super fast.

    EXAMPLES:

        sage: QQ._an_element_()
        1/2
        sage: ZZ['x,y,z']._an_element_()
        x

    TESTS:

    Since `Parent` comes before the parent classes provided by categories in the hierarchy of classes, we make sure that this default implementation of `_an_element_()` does not override some provided by the categories. Eventually, this default implementation should be moved into the categories to avoid this workaround:

        sage: S = FiniteEnumeratedSet([1,2,3])
        sage: S.category()
        Category of facade finite enumerated sets
        sage: super(Parent, S)._an_element_
        Cached version of <function _an_element_from_iterator at ...>
        sage: S._an_element_()
        1
        sage: S = FiniteEnumeratedSet([])
        sage: S._an_element_()
        Traceback (most recent call last):
        ...
        EmptySetError

  `_repr_option`(key)

    Metadata about the `_repr_()` output.

    INPUT:

    - `key` – string. A key for different metadata informations that can be inquired about.

    Valid `key` arguments are:

    - `'ascii_art'`: The `_repr_()` output is multi-line ascii art and each line must be printed starting at the same column, or the meaning is lost.
    - `'element_ascii_art'`: same but for the output of the elements. Used in `sage.repl.display.formatter`.
    - `'element_is_atomic'`: the elements print atomically, that is, parenthesis are not required when printing out any of \(x - y\), \(x + y\), \(x^y\) and \(x/y\).

    OUTPUT:

    Boolean.

    EXAMPLES:

        sage: ZZ._repr_option('ascii_art')
        False
        sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art')
        True

  `_init_category_`(category)

    Initialize the category framework

    Most parents initialize their category upon construction, and this is the recommended behavior. For example, this happens when the constructor calls `Parent.__init__()` directly or indirectly. However, some parents defer this for performance reasons. For example, `sage.matrix.matrix_space.MatrixSpace` does not.

    EXAMPLES:

        sage: P = Parent()
        sage: P.category()
        Category of sets
        sage: class MyParent(Parent):
        ....:     def __init__(self):
        ....:         self._init_category_(Groups())
        sage: MyParent().category()
        Category of groups

`sage.geometry.lattice_polytope.``all_cached_data`(polytopes)

  Compute all cached data for all given `polytopes` and their polars.

  This functions does it MUCH faster than member functions of `LatticePolytope` during the first run. So it is recommended to use this functions if you work with big sets of data. None of the polytopes in the given sequence should be constructed as the polar polytope to another one.

  INPUT: a sequence of lattice polytopes.

  EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short sequences as well:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.all_cached_data([o])
      sage: o.faces()
      [
      [[0], [1], [2], [3], [4], [5]],
      [[1, 5], [0, 5], [0, 1], [3, 5], [1, 3], [4, 5], [0, 4], [3, 4], [1, 2], [0, 2], [2, 3], [2, 4]],
      [[0, 1, 5], [1, 3, 5], [0, 4, 5], [3, 4, 5], [0, 1, 2], [1, 2, 3], [0, 2, 4], [2, 3, 4]]
      ]

  However, you cannot use it for polytopes that are constructed as polar polytopes of others:

      sage: lattice_polytope.all_cached_data([o.polar()])
      Traceback (most recent call last):
      ...
      ValueError: Cannot read face structure for a polytope constructed as polar, use _compute_faces!

`sage.geometry.lattice_polytope.``all_faces`(polytopes)

  Compute faces for all given `polytopes`.

  This functions does it MUCH faster than member functions of `LatticePolytope` during the first run. So it is recommended to use this functions if you work with big sets of data.

  INPUT: a sequence of lattice polytopes.

  EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short sequences as well:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.all_faces([o])
      sage: o.faces()
      [
      [[0], [1], [2], [3], [4], [5]],
      [[1, 5], [0, 5], [0, 1], [3, 5], [1, 3], [4, 5], [0, 4], [3, 4], [1, 2], [0, 2], [2, 3], [2, 4]],
      [[0, 1, 5], [1, 3, 5], [0, 4, 5], [3, 4, 5], [0, 1, 2], [1, 2, 3], [0, 2, 4], [2, 3, 4]]
      ]

  However, you cannot use it for polytopes that are constructed as polar polytopes of others:

      sage: lattice_polytope.all_faces([o.polar()])
      Traceback (most recent call last):
      ...
      ValueError: Cannot read face structure for a polytope constructed as polar, use _compute_faces!

`sage.geometry.lattice_polytope.``all_facet_equations`(polytopes)

  Compute polar polytopes for all reflexive and equations of facets for all non-reflexive `polytopes`.

  `all_facet_equations` and `all_polars` are synonyms.

  This functions does it MUCH faster than member functions of `LatticePolytope` during the first run. So it is recommended to use this functions if you work with big sets of data.

  INPUT: a sequence of lattice polytopes.

  EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short sequences as well:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.all_polars([o])
      sage: o.polar()
      3-d reflexive polytope in 3-d lattice N

`sage.geometry.lattice_polytope.``all_nef_partitions`(polytopes, keep_symmetric=False)

  Compute nef-partitions for all given `polytopes`.

  This functions does it MUCH faster than member functions of `LatticePolytope` during the first run. So it is recommended to use this functions if you work with big sets of data.

  Note: member function `is_reflexive` will be called separately for each polytope. It is strictly recommended to call `all_polars` on the sequence of `polytopes` before using this function.

  INPUT: a sequence of lattice polytopes.

  EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short sequences as well:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.all_nef_partitions([o])
      sage: o.nef_partitions()
      [
      Nef-partition {0, 1, 3} U {2, 4, 5},
      Nef-partition {0, 1, 3, 4} U {2, 5} (direct product),
      Nef-partition {0, 1, 2} U {3, 4, 5},
      Nef-partition {0, 1, 2, 3} U {4, 5},
      Nef-partition {0, 1, 2, 3, 4} U {5} (projection)
      ]

  You cannot use this function for non-reflexive polytopes:

      sage: p = LatticePolytope([(1,0,0), (0,1,0), (0,0,2),
      ...                        (-1,0,0), (0,-1,0), (0,0,-1)])
      sage: lattice_polytope.all_nef_partitions([o, p])
      Traceback (most recent call last):
      ...
      ValueError: nef-partitions can be computed for reflexive polytopes only

`sage.geometry.lattice_polytope.``all_points`(polytopes)

  Compute lattice points for all given `polytopes`.

  This functions does it MUCH faster than member functions of `LatticePolytope` during the first run. So it is recommended to use this functions if you work with big sets of data.

  INPUT: a sequence of lattice polytopes.

  EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short sequences as well:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.all_points([o])
      sage: o.points_pc()
      M( 1,  0,  0),
      M( 0,  1,  0),
      M( 0,  0,  1),
      M(-1,  0,  0),
      M( 0, -1,  0),
      M( 0,  0, -1),
      M( 0,  0,  0)
      in 3-d lattice M

`sage.geometry.lattice_polytope.``all_polars`(polytopes)

  Compute polar polytopes for all reflexive and equations of facets for all non-reflexive `polytopes`.

  `all_facet_equations` and `all_polars` are synonyms.

  This functions does it MUCH faster than member functions of `LatticePolytope` during the first run. So it is recommended to use this functions if you work with big sets of data.

  INPUT: a sequence of lattice polytopes.

  EXAMPLES: This function has no output, it is just a fast way to work with long sequences of polytopes. Of course, you can use short sequences as well:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.all_polars([o])
      sage: o.polar()
      3-d reflexive polytope in 3-d lattice N

`sage.geometry.lattice_polytope.``always_use_files`(new_state=None)

  Set or get the way of using PALP for lattice polytopes.

  INPUT:

  - `new_state` - (default:None) if specified, must be `True` or `False`.

  OUTPUT: The current state of using PALP. If `True`, files are used for all calls to PALP, otherwise pipes are used for single polytopes. While the latter may have some advantage in speed, the first method is more reliable when working with large outputs. The initial state is `True`.

  EXAMPLES:

      sage: lattice_polytope.always_use_files()
      doctest:...: DeprecationWarning: using PALP via pipes is deprecated and
      will be removed, if you have a use case for this,
      please email Andrey Novoseltsev
      See http://trac.sagemath.org/15240 for details.
      True
      sage: p = LatticePolytope(([1], [20]))
      sage: p.npoints()
      20

  Now let’s use pipes instead of files:

      sage: lattice_polytope.always_use_files(False)
      False
      sage: p = LatticePolytope(([1], [20]))
      sage: p.npoints()
      20

`sage.geometry.lattice_polytope.``convex_hull`(points)

  Compute the convex hull of the given points.

  Note

  `points` might not span the space. Also, it fails for large numbers of vertices in dimensions 4 or greater

  INPUT:

  - `points` - a list that can be converted into vectors of the same dimension over ZZ.

  OUTPUT: list of vertices of the convex hull of the given points (as vectors).

  EXAMPLES: Let’s compute the convex hull of several points on a line in the plane:

      sage: lattice_polytope.convex_hull([[1,2],[3,4],[5,6],[7,8]])
      [(1, 2), (7, 8)]

`sage.geometry.lattice_polytope.``cross_polytope`(dim)

  Return a cross-polytope of the given dimension.

  INPUT:

  - `dim` – an integer.

  OUTPUT:

  - a `lattice polytope`.

  EXAMPLES:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: o
      3-d reflexive polytope in 3-d lattice M
      sage: o.vertices_pc()
      M( 1,  0,  0),
      M( 0,  1,  0),
      M( 0,  0,  1),
      M(-1,  0,  0),
      M( 0, -1,  0),
      M( 0,  0, -1)
      in 3-d lattice M

`sage.geometry.lattice_polytope.``filter_polytopes`(f, polytopes, subseq=None, print_numbers=False)

  Use the function `f` to filter polytopes in a list.

  INPUT:

  - `f` - filtering function, it must take one argument, a lattice polytope, and return True or False.
  - `polytopes` - list of polytopes.
  - `subseq` - (default: None) list of integers. If it is specified, only polytopes with these numbers will be considered.
  - `print_numbers` - (default: False) if True, the number of the current polytope will be printed on the screen before calling `f`.

  OUTPUT: a list of integers – numbers of polytopes in the given list, that satisfy the given condition (i.e. function `f` returns True) and are elements of subseq, if it is given.

  EXAMPLES: Consider a sequence of cross-polytopes:

      sage: polytopes = Sequence([lattice_polytope.cross_polytope(n)
      ....:                       for n in range(2, 7)], cr=True)
      sage: polytopes
      [
      2-d reflexive polytope #3 in 2-d lattice M,
      3-d reflexive polytope in 3-d lattice M,
      4-d reflexive polytope in 4-d lattice M,
      5-d reflexive polytope in 5-d lattice M,
      6-d reflexive polytope in 6-d lattice M
      ]

  This filters polytopes of dimension at least 4:

      sage: lattice_polytope.filter_polytopes(lambda p: p.dim() >= 4, polytopes)
      doctest:...: DeprecationWarning: filter_polytopes is deprecated,
      use standard tools instead
      See http://trac.sagemath.org/15240 for details.
      [2, 3, 4]

  For long tests you can see the current progress:

      sage: lattice_polytope.filter_polytopes(lambda p: p.nvertices() >= 10, polytopes, print_numbers=True)
      0
      1
      2
      3
      4
      [3, 4]

  Here we consider only some of the polytopes:

      sage: lattice_polytope.filter_polytopes(lambda p: p.nvertices() >= 10, polytopes, [2, 3, 4], print_numbers=True)
      2
      3
      4
      [3, 4]

`sage.geometry.lattice_polytope.``integral_length`(v)

  Compute the integral length of a given rational vector.

  INPUT:

  - `v` - any object which can be converted to a list of rationals

  OUTPUT: Rational number `r` such that `v = r u`, where `u` is the primitive integral vector in the direction of `v`.

  EXAMPLES:

      sage: lattice_polytope.integral_length([1, 2, 4])
      1
      sage: lattice_polytope.integral_length([2, 2, 4])
      2
      sage: lattice_polytope.integral_length([2/3, 2, 4])
      2/3

`sage.geometry.lattice_polytope.``is_LatticePolytope`(x)

  Check if `x` is a lattice polytope.

  INPUT:

  - `x` – anything.

  OUTPUT:

  - `True` if `x` is a `lattice polytope`, `False` otherwise.

  EXAMPLES:

      sage: from sage.geometry.lattice_polytope import is_LatticePolytope
      sage: is_LatticePolytope(1)
      False
      sage: p = LatticePolytope([(1,0), (0,1), (-1,-1)])
      sage: p
      2-d reflexive polytope #0 in 2-d lattice M
      sage: is_LatticePolytope(p)
      True

`sage.geometry.lattice_polytope.``is_NefPartition`(x)

  Check if `x` is a nef-partition.

  INPUT:

  - `x` – anything.

  OUTPUT:

  - `True` if `x` is a `nef-partition` and `False` otherwise.

  EXAMPLES:

      sage: from sage.geometry.lattice_polytope import is_NefPartition
      sage: is_NefPartition(1)
      False
      sage: o = lattice_polytope.cross_polytope(3)
      sage: np = o.nef_partitions()[0]
      sage: np
      Nef-partition {0, 1, 3} U {2, 4, 5}
      sage: is_NefPartition(np)
      True

`sage.geometry.lattice_polytope.``minkowski_sum`(points1, points2)

  Compute the Minkowski sum of two convex polytopes.

  Note

  Polytopes might not be of maximal dimension.

  INPUT:

  - `points1, points2` - lists of objects that can be converted into vectors of the same dimension, treated as vertices of two polytopes.

  OUTPUT: list of vertices of the Minkowski sum, given as vectors.

  EXAMPLES: Let’s compute the Minkowski sum of two line segments:

      sage: lattice_polytope.minkowski_sum([[1,0],[-1,0]],[[0,1],[0,-1]])
      [(1, 1), (1, -1), (-1, 1), (-1, -1)]

`sage.geometry.lattice_polytope.``positive_integer_relations`(points)

  Return relations between given points.

  INPUT:

  - `points` - lattice points given as columns of a matrix

  OUTPUT: matrix of relations between given points with non-negative integer coefficients

  EXAMPLES: This is a 3-dimensional reflexive polytope:

      sage: p = LatticePolytope([(1,0,0), (0,1,0),
      ...             (-1,-1,0), (0,0,1), (-1,0,-1)])
      sage: p.points_pc()
      M( 1,  0,  0),
      M( 0,  1,  0),
      M(-1, -1,  0),
      M( 0,  0,  1),
      M(-1,  0, -1),
      M( 0,  0,  0)
      in 3-d lattice M

  We can compute linear relations between its points in the following way:

      sage: p.points_pc().matrix().kernel().echelonized_basis_matrix()
      [ 1  0  0  1  1  0]
      [ 0  1  1 -1 -1  0]
      [ 0  0  0  0  0  1]

  However, the above relations may contain negative and rational numbers. This function transforms them in such a way, that all coefficients are non-negative integers:

      sage: lattice_polytope.positive_integer_relations(p.points_pc().column_matrix())
      [1 0 0 1 1 0]
      [1 1 1 0 0 0]
      [0 0 0 0 0 1]
      sage: lattice_polytope.positive_integer_relations(ReflexivePolytope(2,1).vertices_pc().column_matrix())
      [2 1 1]

`sage.geometry.lattice_polytope.``projective_space`(dim)

  Return a simplex of the given dimension, corresponding to \(P_{dim}\).

  EXAMPLES: We construct 3- and 4-dimensional simplexes:

      sage: p = lattice_polytope.projective_space(3)
      doctest:...: DeprecationWarning: this function is deprecated,
      perhaps toric_varieties.P(n) is what you are looking for?
      See http://trac.sagemath.org/15240 for details.
      sage: p
      3-d reflexive polytope in 3-d lattice M
      sage: p.vertices_pc()
      M( 1,  0,  0),
      M( 0,  1,  0),
      M( 0,  0,  1),
      M(-1, -1, -1)
      in 3-d lattice M
      sage: p = lattice_polytope.projective_space(4)
      sage: p
      4-d reflexive polytope in 4-d lattice M
      sage: p.vertices_pc()
      M( 1,  0,  0,  0),
      M( 0,  1,  0,  0),
      M( 0,  0,  1,  0),
      M( 0,  0,  0,  1),
      M(-1, -1, -1, -1)
      in 4-d lattice M

`sage.geometry.lattice_polytope.``read_all_polytopes`(file_name, desc=None)

  Read all polytopes from the given file.

  INPUT:

  - `file_name` – a string with the name of a file with VERTICES of polytopes.

  OUTPUT:

  - a sequence of polytopes.

  EXAMPLES:

  We use poly.x to compute two polar polytopes and read them:

      sage: d = lattice_polytope.cross_polytope(2)
      sage: o = lattice_polytope.cross_polytope(3)
      sage: result_name = lattice_polytope._palp("poly.x -fe", [d, o])
      sage: with open(result_name) as f:
      ....:     print f.read()
      4 2  Vertices of P-dual <-> Equations of P
        -1   1
         1   1
        -1  -1
         1  -1
      8 3  Vertices of P-dual <-> Equations of P
        -1  -1   1
         1  -1   1
        -1   1   1
         1   1   1
        -1  -1  -1
         1  -1  -1
        -1   1  -1
         1   1  -1
      sage: lattice_polytope.read_all_polytopes(result_name)
      [
      2-d reflexive polytope #14 in 2-d lattice M,
      3-d reflexive polytope in 3-d lattice M
      ]
      sage: os.remove(result_name)

`sage.geometry.lattice_polytope.``read_palp_matrix`(data, permutation=False)

  Read and return an integer matrix from a string or an opened file.

  First input line must start with two integers m and n, the number of rows and columns of the matrix. The rest of the first line is ignored. The next m lines must contain n numbers each.

  If m>n, returns the transposed matrix. If the string is empty or EOF is reached, returns the empty matrix, constructed by `matrix()`.

  INPUT:

  - `data` – Either a string containing the filename or the file itself

      containing the output by PALP.

  - `permutation` – (default: `False`) If `True`, try to retrieve the permutation output by PALP. This parameter makes sense only when PALP computed the normal form of a lattice polytope.

  OUTPUT:

  A matrix or a tuple of a matrix and a permutation.

  EXAMPLES:

      sage: lattice_polytope.read_palp_matrix("2 3 comment \n 1 2 3 \n 4 5 6")
      [1 2 3]
      [4 5 6]
      sage: lattice_polytope.read_palp_matrix("3 2 Will be transposed \n 1 2 \n 3 4 \n 5 6")
      [1 3 5]
      [2 4 6]

`sage.geometry.lattice_polytope.``sage_matrix_to_maxima`(m)

  Convert a Sage matrix to the string representation of Maxima.

  EXAMPLE:

      sage: m = matrix(ZZ,2)
      sage: lattice_polytope.sage_matrix_to_maxima(m)
      matrix([0,0],[0,0])

`sage.geometry.lattice_polytope.``set_palp_dimension`(d)

  Set the dimension for PALP calls to `d`.

  INPUT:

  - `d` – an integer from the list [4,5,6,11] or `None`.

  OUTPUT:

  - none.

  PALP has many hard-coded limits, which must be specified before compilation, one of them is dimension. Sage includes several versions with different dimension settings (which may also affect other limits and enable certain features of PALP). You can change the version which will be used by calling this function. Such a change is not done automatically for each polytope based on its dimension, since depending on what you are doing it may be necessary to use dimensions higher than that of the input polytope.

  EXAMPLES:

  By default, it is not possible to create the 7-dimensional simplex with vertices at the basis of the 8-dimensional space:

      sage: LatticePolytope(identity_matrix(8))
      Traceback (most recent call last):
      ...
      ValueError: Error executing 'poly.x -fv' for the given polytope!
      Output:
      Please increase POLY_Dmax to at least 7

  However, we can work with this polytope by changing PALP dimension to 11:

      sage: lattice_polytope.set_palp_dimension(11)
      sage: LatticePolytope(identity_matrix(8))
      7-d lattice polytope in 8-d lattice M

  Let’s go back to default settings:

      sage: lattice_polytope.set_palp_dimension(None)

`sage.geometry.lattice_polytope.``skip_palp_matrix`(data, n=1)

  Skip matrix data in a file.

  INPUT:

  - `data` - opened file with blocks of matrix data in the following format: A block consisting of m+1 lines has the number m as the first element of its first line.
  - `n` - (default: 1) integer, specifies how many blocks should be skipped

  If EOF is reached during the process, raises ValueError exception.

  EXAMPLE: We create a file with vertices of the square and the cube, but read only the second set:

      sage: d = lattice_polytope.cross_polytope(2)
      sage: o = lattice_polytope.cross_polytope(3)
      sage: result_name = lattice_polytope._palp("poly.x -fe", [d, o])
      sage: with open(result_name) as f:
      ....:     print f.read()
      4 2  Vertices of P-dual <-> Equations of P
        -1   1
         1   1
        -1  -1
         1  -1
      8 3  Vertices of P-dual <-> Equations of P
        -1  -1   1
         1  -1   1
        -1   1   1
         1   1   1
        -1  -1  -1
         1  -1  -1
        -1   1  -1
         1   1  -1
      sage: f = open(result_name)
      sage: lattice_polytope.skip_palp_matrix(f)
      sage: lattice_polytope.read_palp_matrix(f)
      [-1  1 -1  1 -1  1 -1  1]
      [-1 -1  1  1 -1 -1  1  1]
      [ 1  1  1  1 -1 -1 -1 -1]
      sage: f.close()
      sage: os.remove(result_name)

`sage.geometry.lattice_polytope.``write_palp_matrix`(m, ofile=None, comment='', format=None)

  Write `m` into `ofile` in PALP format.

  INPUT:

  - `m` – a matrix over integers or a `point collection`.
  - `ofile` – a file opened for writing (default: stdout)
  - `comment` – a string (default: empty) see output description
  - `format` – a format string used to print matrix entries.

  OUTPUT:

  - nothing is returned, output written to `ofile` has the format
    - First line: number_of_rows number_of_columns comment
    - Next number_of_rows lines: rows of the matrix.

  EXAMPLES:

      sage: o = lattice_polytope.cross_polytope(3)
      sage: lattice_polytope.write_palp_matrix(o.vertices_pc(), comment="3D Octahedron")
      3 6 3D Octahedron
       1  0  0 -1  0  0
       0  1  0  0 -1  0
       0  0  1  0  0 -1
      sage: lattice_polytope.write_palp_matrix(o.vertices_pc(), format="%4d")
      3 6
         1    0    0   -1    0    0
         0    1    0    0   -1    0
         0    0    1    0    0   -1

### Navigation

- index
- modules |
- next |
- previous |
- Combinatorial Geometry »