1#  Copyright (c) 1997-2021
2#  Ewgenij Gawrilow, Michael Joswig, and the polymake team
3#  Technische Universität Berlin, Germany
4#  https://polymake.org
5#
6#  This program is free software; you can redistribute it and/or modify it
7#  under the terms of the GNU General Public License as published by the
8#  Free Software Foundation; either version 2, or (at your option) any
9#  later version: http://www.gnu.org/licenses/gpl.txt.
10#
11#  This program is distributed in the hope that it will be useful,
12#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#  GNU General Public License for more details.
15#-------------------------------------------------------------------------------
16
17
18# @topic objects/Polytope/specializations/Polytope<Rational>
19# A rational polyhedron realized in Q^d
20
21# @topic objects/Polytope/specializations/Polytope<Float>
22# A pointed polyhedron with float coordinates realized in R<sup>d</sup>.
23#
24# It mainly exists for visualization.
25#
26# Convex hull and related algorithms use floating-point arithmetics.
27# Due to numerical errors inherent to this kind of computations, the resulting
28# combinatorial description can be arbitrarily far away from the truth, or even
29# not correspond to any valid polytope.  You have been warned.
30#
31# None of the standard construction clients produces objects of this type.
32# If you want to get one, create it with the explicit constructor or [[convert_to]].
33
34object Polytope {
35
36file_suffix poly
37
38# @category Input property
39# Points such that the polyhedron is their convex hull.
40# Redundancies are allowed.
41# The vector (x<sub>0</sub>, x<sub>1</sub>, ... x<sub>d</sub>) represents a point in d-space given in homogeneous coordinates.
42# Affine points are identified by x<sub>0</sub> > 0.
43# Points with x<sub>0</sub> = 0 can be interpreted as rays.
44#
45# polymake automatically normalizes each coordinate vector, dividing them by the first non-zero element.
46# The clients and rule subroutines can always assume that x<sub>0</sub> is either 0 or 1.
47# All vectors in this section must be non-zero.
48# Dual to [[INEQUALITIES]].
49#
50# Input section only.  Ask for [[VERTICES]] if you want to compute a V-representation from an H-representation.
51# @example Given some (homogeneous) points in 3-space we first construct a matrix containing them. Assume we don't know wether these are all
52# vertices of their convex hull or not. To safely produce a polytope from these points, we set the input to the matrix representing them.
53# In the following the points under consideration are the vertices of the 3-simplex together with their barycenter, which will be no vertex:
54# > $M = new Matrix([[1,0,0,0],[1,1,0,0],[1,0,1,0],[1,0,0,1],[1,1/4,1/4,1/4]]);
55# > $p = new Polytope(POINTS=>$M);
56# > print $p->VERTICES;
57# | 1 0 0 0
58# | 1 1 0 0
59# | 1 0 1 0
60# | 1 0 0 1
61property POINTS = override INPUT_RAYS;
62
63
64# @category Geometry
65# Vertices of the polyhedron. No redundancies are allowed.
66# All vectors in this section must be non-zero.
67# The coordinates are normalized the same way as [[POINTS]]. Dual to [[FACETS]].
68# This section is empty if and only if the polytope is empty.
69# The property [[VERTICES]] appears only in conjunction with the property [[LINEALITY_SPACE]].
70# The specification of the property [[VERTICES]] requires the specification of [[LINEALITY_SPACE]], and vice versa.
71# @example To print the vertices (in homogeneous coordinates) of the standard 2-simplex, i.e. a right-angled isoceles triangle, type this:
72# > print simplex(2)->VERTICES;
73# | (3) (0 1)
74# | 1 1 0
75# | 1 0 1
76# @example If we know some points to be vertices of their convex hull, we can store them as rows in a Matrix and construct a new polytope with it.
77# The following produces a 3-dimensioanl pyramid over the standard 2-simplex with the specified vertices:
78# > $M = new Matrix([[1,0,0,0],[1,1,0,0],[1,0,1,0],[1,0,0,3]]);
79# > $p = new Polytope(VERTICES=>$M);
80# @example The following adds a (square) pyramid to one facet of a 3-cube. We do this by extracting the vertices of the cube via the built-in
81# method and then attach the apex of the pyramid to the matrix.
82# > $v = new Vector([1,0,0,3/2]);
83# > $M = cube(3)->VERTICES / $v;
84# > $p = new Polytope(VERTICES=>$M);
85property VERTICES = override RAYS;
86
87# @topic //properties//INEQUALITIES
88# Inequalities that describe half-spaces such that the polyhedron is their intersection.
89# Redundancies are allowed.  Dual to [[POINTS]].
90#
91# A vector (A<sub>0</sub>, A<sub>1</sub>, ..., A<sub>d</sub>) defines the
92# (closed affine) half-space of points (1, x<sub>1</sub>, ..., x<sub>d</sub>) such that
93# A<sub>0</sub> + A<sub>1</sub> x<sub>1</sub> + ... + A<sub>d</sub> x<sub>d</sub> >= 0.
94#
95# Input section only.  Ask for [[FACETS]] and [[AFFINE_HULL]] if you want to compute an H-representation
96# from a V-representation.
97
98
99# @topic //properties//EQUATIONS
100# Equations that hold for all points of the polyhedron.
101#
102# A vector (A<sub>0</sub>, A<sub>1</sub>, ..., A<sub>d</sub>) describes the hyperplane
103# of all points (1, x<sub>1</sub>, ..., x<sub>d</sub>) such that A<sub>0</sub> + A<sub>1</sub> x<sub>1</sub> + ... + A<sub>d</sub> x<sub>d</sub> = 0.
104# All vectors in this section must be non-zero.
105#
106# Input section only.  Ask for [[AFFINE_HULL]] if you want to see an irredundant description of the affine span.
107
108# @category Geometry
109# Dual basis of the affine hull of the polyhedron.
110# The property [[AFFINE_HULL]] appears only in conjunction with the property [[FACETS]].
111# The specification of the property [[FACETS]] requires the specification of [[AFFINE_HULL]], and vice versa.
112property AFFINE_HULL = override LINEAR_SPAN {
113   sub canonical { &orthogonalize_affine_subspace; }
114}
115
116method canonical_ineq {
117   add_extra_polytope_ineq($_[1]);
118}
119
120
121# @category Geometry
122# The i-th row is the normal vector of a hyperplane separating the i-th vertex from the others.
123# This property is a by-product of redundant point elimination algorithm.
124# All vectors in this section must be non-zero.
125# @example [require bundled:cdd] This prints a matrix in which each row represents a normal vector of a hyperplane seperating one vertex of a centered square
126# with side length 2 from the other ones. The first and the last hyperplanes as well as the second and third hyperplanes are the same
127# up to orientation.
128# > print cube(2)->VERTEX_NORMALS;
129# | 0 1/2 1/2
130# | 0 -1/2 1/2
131# | 0 1/2 -1/2
132# | 0 -1/2 -1/2
133property VERTEX_NORMALS = override RAY_SEPARATORS;
134
135# @category Geometry
136# Some point belonging to the polyhedron.
137# @example This stores a (homogeneous) point belonging to the 3-cube as a vector and prints its coordinates:
138# > $v = cube(3)->VALID_POINT;
139# > print $v;
140# | 1 -1 -1 -1
141property VALID_POINT : Vector<Scalar> {
142   sub canonical { &canonicalize_rays; }
143}
144
145# @category Geometry
146# True if the polyhedron is not empty.
147property FEASIBLE : Bool;
148
149# @topic //properties//CONE_DIM
150# One more than the dimension of the affine hull of the polyhedron
151#   = one more than the dimension of the polyhedron.
152#   = dimension of the homogenization of the polyhedron
153# If the polytope is given purely combinatorially, this is the dimension of a minimal embedding space
154# @example This prints the cone dimension of a 3-cube. Since the dimension of its affine closure is 3, the result is 4.
155# > print cube(3)->CONE_DIM;
156# | 4
157
158# @topic //properties//CONE_AMBIENT_DIM
159# One more than the dimension of the space in which the polyhedron lives.
160#   = dimension of the space in which the homogenization of the polyhedron lives
161
162# @topic //properties//POINTED
163# True if the polyhedron does not contain an affine line.
164# @example A square does not contain an affine line and is therefore pointed. Removing one facet does not change this, although
165# it is no longer bounded.  After removing two opposing facets, it contains infinitely many affine lines orthogonal to the
166# removed facets.
167# > $p = cube(2);
168# > print $p->POINTED;
169# | true
170# > print facet_to_infinity($p,0)->POINTED;
171# | true
172# > print new Polytope(INEQUALITIES=>$p->FACETS->minor([0,1],All))->POINTED;
173# | false
174
175# @category Geometry
176# A vertex of a pointed polyhedron.
177# @example This prints the first vertex of the 3-cube (corresponding to the first row in the vertex matrix).
178# > print cube(3)->ONE_VERTEX;
179# | 1 -1 -1 -1
180property ONE_VERTEX = override ONE_RAY;
181
182
183# @category Geometry
184# True if and only if [[LINEALITY_SPACE]] trivial and [[FAR_FACE]] is trivial.
185# @example A pyramid over a square is bounded. Removing the base square yields an unbounded pointed polyhedron
186# (the vertices with first entry equal to zero correspond to rays).
187# > $p = pyramid(cube(2));
188# > print $p->BOUNDED;
189# | true
190# > $q = facet_to_infinity($p,4);
191# > print $q->BOUNDED;
192# | false
193property BOUNDED : Bool;
194
195
196# @category Geometry
197# True if (1, 0, 0, ...) is in the relative interior.
198# If full-dimensional then polar to [[BOUNDED]].
199# @example The cube [0,1]^3 is not centered, since the origin is on the boundary. By a small translation we can make it centered:
200# > $p = cube(3,0,0);
201# > print $p->CENTERED;
202# | false
203# > $t = new Vector([-1/2,-1/2,-1/2]);
204# > print translate($p,$t)->CENTERED;
205# | true
206property CENTERED : Bool;
207
208
209# @category Geometry
210# True if (1, 0, 0, ...) is contained (possibly in the boundary).
211# @example The cube [0,1]^3 is only weakly centered, since the origin is on the boundary.
212# > $p = cube(3,0,0);
213# > print $p->WEAKLY_CENTERED;
214# | true
215# > print $p->CENTERED;
216# | false
217property WEAKLY_CENTERED : Bool;
218
219
220# @category Geometry
221# The following is defined for [[CENTERED]] polytopes only:
222# A facet is special if the cone over that facet with the origin as the apex contains the [[VERTEX_BARYCENTER]].
223# Motivated by Obro's work on Fano polytopes.
224property SPECIAL_FACETS : Set;
225
226# @category Geometry
227# True if P = -P.
228# @example A centered 3-cube is centrally symmetric. By stacking a single facet (5), this property is lost. We can
229# recover it by stacking the opposing facet (4) as well.
230# > $p = cube(3);
231# > print $p->CENTRALLY_SYMMETRIC;
232# | true
233# > print stack($p,5)->CENTRALLY_SYMMETRIC;
234# | false
235# > print stack($p,new Set<Int>(4,5))->CENTRALLY_SYMMETRIC;
236# | true
237property CENTRALLY_SYMMETRIC : Bool;
238
239# @category Geometry
240# The permutation induced by the central symmetry, if present.
241property CS_PERMUTATION : Array<Int>;
242
243# @category Geometry
244# Number of [[POINTS]].
245property N_POINTS = override N_INPUT_RAYS;
246
247# @category Combinatorics
248# Number of [[VERTICES]].
249# @example The following prints the number of vertices of a 3-dimensional cube:
250# > print cube(3)->N_VERTICES;
251# | 8
252# @example The following prints the number of vertices of the convex hull of 10 specific points lying in the unit square [0,1]^2:
253# > print rand_box(2,10,1,seed=>4583572)->N_VERTICES;
254# | 4
255property N_VERTICES = override N_RAYS;
256
257# @category Combinatorics
258# Number of pairs of incident vertices and facets.
259property N_VERTEX_FACET_INC = override N_RAY_FACET_INC;
260
261# @category Combinatorics
262# Vertex-facet incidence matrix, with rows corresponding to facets and columns
263# to vertices. Vertices and facets are numbered from 0 to [[N_VERTICES]]-1 rsp.
264# [[N_FACETS]]-1, according to their order in [[VERTICES]] rsp. [[FACETS]].
265#
266# This property is at the core of all combinatorial properties.  It has the following semantics:
267# (1) The combinatorics of an unbounded and pointed polyhedron is defined to be the combinatorics
268#     of the projective closure.
269# (2) The combiantorics of an unbounded polyhedron which is not pointed is defined to be the
270#     combinatorics of the quotient modulo the lineality space.
271# Therefore: [[VERTICES_IN_FACETS]] and each other property which is grouped under "Combinatorics"
272# always refers to some polytope.
273# @example [prefer cdd] [require bundled:cdd]
274# The following prints the vertex-facet incidence matrix of a 5-gon by listing all facets as a set of contained vertices
275# in a cyclic order (each line corresponds to an edge):
276# > print n_gon(5)->VERTICES_IN_FACETS;
277# | {1 2}
278# | {2 3}
279# | {3 4}
280# | {0 4}
281# | {0 1}
282# @example [prefer cdd] [require bundled:cdd] The following prints the Vertex_facet incidence matrix of the standard 3-simplex together with the facet numbers:
283# > print rows_numbered(simplex(3)->VERTICES_IN_FACETS);
284# | 0:1 2 3
285# | 1:0 2 3
286# | 2:0 1 3
287# | 3:0 1 2
288property VERTICES_IN_FACETS = override RAYS_IN_FACETS;
289
290# @category Geometry
291property VERTICES_IN_RIDGES = override RAYS_IN_RIDGES;
292
293# @category Geometry
294# Similar to [[VERTICES_IN_FACETS]], but with columns corresponding to [[POINTS]] instead of [[VERTICES]].
295# This property is a byproduct of convex hull computation algorithms.
296# It is discarded as soon as [[VERTICES_IN_FACETS]] is computed.
297property POINTS_IN_FACETS = override INPUT_RAYS_IN_FACETS;
298
299
300# @category Combinatorics
301# transposed [[VERTICES_IN_FACETS]]
302# Notice that this is a temporary property; it will not be stored in any file.
303property FACETS_THRU_VERTICES = override FACETS_THRU_RAYS;
304
305# @category Geometry
306# similar to [[FACETS_THRU_VERTICES]], but with [[POINTS]] instead of [[VERTICES]]
307# Notice that this is a temporary property; it will not be stored in any file.
308property FACETS_THRU_POINTS = override FACETS_THRU_INPUT_RAYS;
309
310# @category Geometry
311# Similar to [[VERTICES_IN_FACETS]], but with rows corresponding to [[INEQUALITIES]] instead of [[FACETS]].
312# This property is a byproduct of convex hull computation algorithms.
313# It is discarded as soon as [[VERTICES_IN_FACETS]] is computed.
314property VERTICES_IN_INEQUALITIES = override RAYS_IN_INEQUALITIES;
315
316# @category Geometry
317# transposed [[VERTICES_IN_INEQUALITIES]]
318property INEQUALITIES_THRU_VERTICES = override INEQUALITIES_THRU_RAYS;
319
320# @category Combinatorics
321# Number of incident facets for each vertex.
322# @example [require bundled:cdd] The following prints the number of incident facets for each vertex of the elongated pentagonal pyramid (Johnson solid 9)
323# > print johnson_solid(9)->VERTEX_SIZES;
324# | 5 4 4 4 4 4 3 3 3 3 3
325property VERTEX_SIZES = override RAY_SIZES;
326
327# @category Combinatorics
328# Measures the deviation of the cone from being simple in terms of the [[GRAPH]].
329# @example The excess vertex degree of an egyptian pyramid is one.
330# > print pyramid(cube(2))->EXCESS_VERTEX_DEGREE;
331# | 1
332property EXCESS_VERTEX_DEGREE = override EXCESS_RAY_DEGREE;
333
334# @topic //properties//HASSE_DIAGRAM
335# Number of incident vertices for each facet.
336
337# @category Unbounded polyhedra
338# Indices of vertices that are rays.
339property FAR_FACE : Set;
340
341rule FAR_FACE : VertexPerm.FAR_FACE, VertexPerm.PERMUTATION {
342   $this->FAR_FACE=permuted($this->VertexPerm->FAR_FACE, $this->VertexPerm->PERMUTATION);
343}
344weight 1.10;
345
346# @category Combinatorics
347# Vertex-edge graph.
348
349property GRAPH {
350
351   # @category Geometry
352   # Difference of the vertices for each edge (only defined up to signs).
353   property EDGE_DIRECTIONS : EdgeMap<Undirected, Vector<Scalar>> : construct(ADJACENCY);
354
355   # @category Geometry
356   # Squared Euclidean length of each edge
357   property SQUARED_EDGE_LENGTHS : EdgeMap<Undirected, Scalar> : construct(ADJACENCY);
358
359}
360
361property DUAL_GRAPH {
362
363   # @category Geometry
364   # Dihedral angles (in radians) between the two facets corresponding to
365   # each edge of the dual graph, i.e. the ridges of the polytope.
366   property DIHEDRAL_ANGLES : EdgeMap<Undirected, Float> : construct(ADJACENCY);
367
368}
369
370
371# @category Combinatorics
372# Lists for each occurring size (= number of incident vertices or edges) of a 2-face how many there are.
373# @example This prints the number of facets spanned by 3,4 or 5 vertices a truncated 3-dimensional cube has.
374# > $p = truncation(cube(3),5);
375# > print $p->TWO_FACE_SIZES;
376# | {(3 1) (4 3) (5 3)}
377property TWO_FACE_SIZES : Map<Int,Int>;
378
379# @category Combinatorics
380# Lists for each occurring size (= number of incident facets or ridges) of a subridge how many there are.
381property SUBRIDGE_SIZES : Map<Int,Int>;
382
383
384# @topic //properties//F_VECTOR
385# f<sub>k</sub> is the number of k-faces.
386# @example This prints the f-vector of a 3-dimensional cube. The first entry represents the vertices.
387# > print cube(3)->F_VECTOR;
388# | 8 12 6
389# @example This prints the f-vector of the 3-dimensional cross-polytope. Since the cube and the cross polytope
390# of equal dimension are dual, their f-vectors are the same up to reversion.
391# > print cross(3)->F_VECTOR;
392# | 6 12 8
393# @example After truncating the first standard basis vector of the 3-dimensional cross-polytope the f-vector changes.
394# Only segments of the incident edges of the cut off vertex remain and the intersection of these with the new hyperplane
395# generate four new vertices. These also constitute four new edges and a new facet.
396# > print truncation(cross(3),4)->F_VECTOR;
397# | 9 16 9
398
399
400# @topic //properties//F2_VECTOR
401# f<sub>ik</sub> is the number of incident pairs of i-faces and k-faces; the main diagonal contains the [[F_VECTOR]].
402# @example The following prints the f2-vector of a 3-dimensional cube:
403# > print cube(3)->F2_VECTOR;
404# | 8 24 24
405# | 24 12 24
406# | 24 24 6
407
408
409# @topic //properties//SIMPLICIAL
410# True if the polytope is simplicial.
411# @example A polytope with random vertices uniformly distributed on the unit sphere is simplicial. The following checks
412# this property and prints the result for 8 points in dimension 3:
413# > print rand_sphere(3,8)->SIMPLICIAL;
414# | true
415
416# @topic //properties//SIMPLE
417# True if the polytope is simple. Dual to [[SIMPLICIAL]].
418# @example This determines if a 3-dimensional cube is simple or not:
419# > print cube(3)->SIMPLE;
420# | true
421
422# @topic //properties//SELF_DUAL
423# True if the polytope is self-dual.
424# @example The following checks if the centered square with side length 2 is self dual:
425# > print cube(2)->SELF_DUAL;
426# | true
427# @example The elongated square pyramid (Johnson solid 8) is dual to itself, since the apex of the square pyramid attachted to the cube
428# and the opposing square of the cube swap roles. The following checks this property and prints the result:
429# > print johnson_solid(8)->SELF_DUAL;
430# | true
431
432
433# @category Combinatorics
434# Maximal dimension in which all faces are simplices.
435# @example The 3-dimensional cross-polytope is simplicial, i.e. its simplicity is 2. After truncating an arbitrary vertex
436# the simplicity is reduced to 1.
437# > print cross(3)->SIMPLICIALITY;
438# | 2
439# > print truncation(cross(3),4)->SIMPLICIALITY;
440# | 1
441property SIMPLICIALITY : Int;
442
443# @category Combinatorics
444# Maximal dimension in which all dual faces are simplices.
445# @example This checks the 3-dimensional cube for simplicity. Since the cube is dual to the cross-polytope of equal dimension and all its faces are simplices,
446# the result is 2.
447# > print cube(3)->SIMPLICITY;
448# | 2
449property SIMPLICITY : Int;
450
451# @category Combinatorics
452# Maximal dimension in which all faces are simple polytopes.
453# This checks the 3-dimensional cube for face simplicity. Since the cube is dual to the cross-polytope of equal dimension and it is simplicial,
454# the result is 3.
455# > print cube(3)->SIMPLICITY;
456# | 3
457property FACE_SIMPLICITY : Int;
458
459# @category Combinatorics
460# True if all facets are cubes.
461# @example A k-dimensional cube has k-1-dimensional cubes as facets and is therefore cubical. The following checks if this holds for the
462# 3-dimensional case:
463# > print cube(3)->CUBICAL;
464# | true
465# @example This checks if a zonotope generated by 4 random points on the 3-dimensional sphere is cubical, which is always the case.
466# > print zonotope(rand_sphere(3,4)->VERTICES)->CUBICAL;
467# | true
468property CUBICAL : Bool;
469
470# @category Combinatorics
471# Maximal dimension in which all facets are cubes.
472# @example We will modify the 3-dimensional cube in two different ways. While stacking some facets (in this case facets 4 and 5) preserves the cubicality up to
473# dimension 2, truncating an arbitrary vertex reduces the cubicality to 1.
474# > print stack(cube(3),[4,5])->CUBICALITY;
475# | 2
476# > print truncation(cube(3),5)->CUBICALITY;
477# | 1
478property CUBICALITY : Int;
479
480# @category Combinatorics
481# Dual to [[CUBICAL]].
482# @example Since the cross-polytope is dual to a cube of same dimension, it is cocubical. The following checks this for the 3-dimensional case:
483# > print cross(3)->COCUBICAL;
484# | true
485property COCUBICAL : Bool;
486
487# @category Combinatorics
488# Dual to [[CUBICALITY]].
489# @example After stacking a facet of the 3-dimensional cube, its cubicality is lowered to 2. Hence its dual polytope has cocubicality 2 as well. The
490# following produces such a stacked cube and asks for its cocubicality after polarization:
491# > $p = stack(cube(3),5);
492# > print polarize($p)->COCUBICALITY;
493# | 2
494property COCUBICALITY : Int;
495
496# @category Combinatorics
497# True if the polytope is neighborly.
498# @example This checks the 4-dimensional cyclic polytope with 6 points on the moment curve for neighborliness, i.e. if it is ⌊dim/2⌋ neighborly:
499# > print cyclic(4,6)->NEIGHBORLY;
500# | true
501property NEIGHBORLY : Bool;
502
503# @category Combinatorics
504# Maximal dimension in which all facets are neighborly.
505# @example [nocompare] This determines that the full dimensional polytope given by 10 specific vertices on the 8-dimensional sphere is 3-neighborly, i.e.
506# all 3-dimensional faces are tetrahedra. Hence the polytope is not neighborly.
507# > print rand_sphere(8,10,seed=>8866463)->NEIGHBORLINESS;
508# | 3
509property NEIGHBORLINESS : Int;
510
511# @category Combinatorics
512# Dual to [[NEIGHBORLY]].
513# @example Since cyclic polytopes generated by vertices on the moment curve are neighborly, their dual polytopes are balanced. The following checks this
514# for the 4-dimensional case by centering the cyclic polytope and then polarizing it:
515# > $p = cyclic(4,6);
516# > $q = polarize(center($p));
517# > print $q->BALANCED;
518# | true
519property BALANCED : Bool;
520
521# @category Combinatorics
522# Maximal dimension in which all facets are balanced.
523# @example [nocompare] The following full dimensional polytope given by 10 specific vertices on the 8-dimensional sphere is 3-neighborly. Hence the dual polytope is
524# 3-balanced, where we first center and then polarize it.
525# > $p = rand_sphere(8,10,seed=>8866463);
526# > $q = polarize(center($p));
527# > print $q->BALANCE;
528# | 3
529property BALANCE : Int;
530
531# @category Combinatorics
532# Parameter describing the shape of the face-lattice of a 4-polytope.
533property FATNESS : Float;
534
535# @category Combinatorics
536# Parameter describing the shape of the face-lattice of a 4-polytope.
537property COMPLEXITY : Float;
538
539# @category Geometry
540# The center of gravity of the vertices of a bounded polytope.
541# @example This prints the vertex barycenter of the standard 3-simplex:
542# > print simplex(3)->VERTEX_BARYCENTER;
543# | 1 1/4 1/4 1/4
544property VERTEX_BARYCENTER : Vector<Scalar>;
545
546# @category Geometry
547# The minimal angle between any two vertices (seen from the [[VERTEX_BARYCENTER]]).
548property MINIMAL_VERTEX_ANGLE : Float;
549
550# @category Geometry
551# The rows of this matrix contain a configuration of affine points in homogeneous cooordinates.
552# The zonotope is obtained as the Minkowski sum of all rows, normalized to x_0 = 1.
553# Thus, if the input matrix has n columns, the ambient affine dimension of the resulting zonotope is n-1.
554property ZONOTOPE_INPUT_POINTS : Matrix<Scalar>;
555
556# @category Geometry
557# is the zonotope calculated from ZONOTOPE_INPUT_POINTS or ZONOTOPE_INPUT_VECTORS to be centered at the origin?
558# The zonotope is always calculated as the Minkowski sum of all segments conv {x,v}, where
559# * v ranges over the ZONOTOPE_INPUT_POINTS or ZONOTOPE_INPUT_VECTORS, and
560# * x = -v if CENTERED_ZONOTOPE = 1,
561# * x = 0  if CENTERED_ZONOTOPE = 0.
562# Input section only.
563property CENTERED_ZONOTOPE : Bool;
564
565# @category Geometry
566# The minimal Ball which contains a the Polytope. The ball is
567# given by its center c and the square of it radius r.
568# @example
569# > $P = new Polytope(POINTS=>[[1,0],[1,4]]);
570# > print $P->MINIMAL_BALL;
571# | 4 <1 2>
572property MINIMAL_BALL : Pair<Scalar, Vector<Scalar>>;
573
574rule MINIMAL_BALL : POINTS | VERTICES | INEQUALITIES | FACETS{
575   $this->MINIMAL_BALL = minimal_ball($this);
576}
577
578
579
580} # /Polytope
581
582# @category Geometry
583# a lattice that is displaced from the origin, i.e.,
584# a set of the form x + L, where x is a non-zero vector and L a (linear) lattice
585# @tparam Scalar coordinate type
586declare object AffineLattice<Scalar=Rational> {
587
588# an affine point, ie first coordinate non-zero
589property ORIGIN : Vector<Scalar>;
590
591# rows are vectors, ie first coordinate zero
592property BASIS : Matrix<Scalar>;
593
594
595property SQUARED_DETERMINANT : Scalar;
596
597
598rule SQUARED_DETERMINANT : BASIS {
599   $this->SQUARED_DETERMINANT = det($this->BASIS * transpose($this->BASIS));
600}
601
602} # /AffineLattice
603
604
605object Polytope {
606
607# @category Geometry
608# An affine lattice L such that P + L tiles the affine span of P
609property TILING_LATTICE : AffineLattice<Scalar>;
610
611
612# @topic category properties/Triangulation and volume
613# Everything in this group is defined for [[BOUNDED]] polytopes only.
614
615
616# @category Triangulation and volume
617# Volume of the polytope.
618# @example The following prints the volume of the centered 3-dimensional cube with side length 2:
619# > print cube(3)->VOLUME;
620# | 8
621property VOLUME : Scalar;
622
623# @category Triangulation and volume
624# Mahler volume (or volume product) of the polytope.
625# Defined as the volume of the polytope and the volume of its polar (for [[BOUNDED]], [[CENTERED]] and [[FULL_DIM]] polytopes only).
626# Often studied for centrally symmetric convex bodies, where the regular cubes are conjectured to be the global minimiers.
627# @example The following prints the Mahler volume of the centered 2-cube:
628# > print cube(2)->MAHLER_VOLUME;
629# | 8
630property MAHLER_VOLUME : Scalar;
631
632# @category Triangulation and volume
633# Array of the squared relative //k//-dimensional volumes of the simplices in
634# a triangulation of a //d//-dimensional polytope.
635property SQUARED_RELATIVE_VOLUMES : Array<Scalar>;
636
637# @category Geometry
638# Centroid (center of mass) of the polytope.
639property CENTROID : Vector<Scalar>;
640
641property TRIANGULATION {
642
643   # @category Triangulation and volume
644   # GKZ-vector
645   # 	See Chapter 7 in Gelfand, Kapranov, and Zelevinsky:
646   # 	Discriminants, Resultants and Multidimensional Determinants, Birkhäuser 1994
647   property GKZ_VECTOR : Vector<Scalar>;
648
649}
650
651
652# @category Combinatorics
653# Minimal non-faces of a [[SIMPLICIAL]] polytope.
654property MINIMAL_NON_FACES : Array<Set>;
655
656rule MINIMAL_NON_FACES : VertexPerm.MINIMAL_NON_FACES, VertexPerm.PERMUTATION {
657   $this->MINIMAL_NON_FACES=permuted_elements($this->VertexPerm->MINIMAL_NON_FACES, $this->VertexPerm->PERMUTATION);
658}
659weight 1.20;
660
661
662# @category Visualization
663# Reordered [[VERTICES_IN_FACETS]] for 2d and 3d-polytopes.
664# Vertices are listed in the order of their appearance
665# when traversing the facet border counterclockwise seen from outside of the polytope.
666#
667# For a 2d-polytope (which is a closed polygon), lists all vertices in the border traversing order.
668property VIF_CYCLIC_NORMAL = override RIF_CYCLIC_NORMAL;
669
670# @category Visualization
671# Reordered transposed [[VERTICES_IN_FACETS]]. Dual to [[VIF_CYCLIC_NORMAL]].
672property FTV_CYCLIC_NORMAL = override FTR_CYCLIC_NORMAL;
673
674# @category Visualization
675# Reordered [[GRAPH]]. Dual to [[NEIGHBOR_FACETS_CYCLIC_NORMAL]].
676property NEIGHBOR_VERTICES_CYCLIC_NORMAL = override NEIGHBOR_RAYS_CYCLIC_NORMAL;
677
678
679# @category Visualization
680# Unique names assigned to the [[VERTICES]].
681# If specified, they are shown by visualization tools instead of vertex indices.
682#
683# For a polytope build from scratch, you should create this property by yourself,
684# either manually in a text editor, or with a client program.
685#
686# If you build a polytope with a construction function
687# taking some other input polytope(s), the labels are created the labels automatically
688# except if you call the function with a //no_labels// option. The exact format of the
689# abels is dependent on the construction, and is described in the corresponding help topic.
690# @option Bool no_labels
691property VERTEX_LABELS = override RAY_LABELS;
692
693# @category Visualization
694# Unique names assigned to the [[POINTS]], analogous to [[VERTEX_LABELS]].
695property POINT_LABELS = override INPUT_RAY_LABELS;
696
697# @category Geometry
698# Find the vertices by given labels.
699# @param String label ... vertex labels
700# @return Set<Int> vertex indices
701user_method labeled_vertices {
702   my $this=shift;
703   if (defined (my $labels=$this->lookup("VERTEX_LABELS"))) {
704      new Set([ find_labels($labels, @_) ]);
705   } else {
706      die "No VERTEX_LABELS stored in this complex";
707   }
708}
709
710# @topic //properties//FACET_LABELS
711# Unique names assigned to the [[FACETS]], analogous to [[VERTEX_LABELS]].
712
713# @topic //properties//INEQUALITY_LABELS
714# Unique names assigned to the [[INEQUALITIES]], analogous to [[VERTEX_LABELS]].
715
716# @category Geometry
717# The splits of the polytope, i.e., hyperplanes cutting the polytope in
718# two parts such that we have a regular subdivision.
719property SPLITS : Matrix<Scalar>;
720
721# @category Geometry
722# Two [[SPLITS]] are compatible if the defining hyperplanes do not intersect in the
723# interior of the polytope.  This defines a graph.
724property SPLIT_COMPATIBILITY_GRAPH : Graph;
725
726# @topic category properties/Matroid properties
727# Properties which belong to the corresponding (oriented) matroid
728
729# @category Matroid properties
730# Chirotope corresponding to the [[VERTICES]]. TOPCOM format.
731# @depends topcom
732property CHIROTOPE : Text;
733
734rule CHIROTOPE : VERTICES {
735   $this->CHIROTOPE = chirotope($this->VERTICES);
736}
737precondition : FULL_DIM && BOUNDED;
738weight 6.11;
739
740# @category Matroid properties
741# Circuits in [[VECTORS]]
742# @depends topcom
743property CIRCUITS : Set<Pair<Set<Int>,Set<Int>>>;
744
745# @category Matroid properties
746# Cocircuits in [[VECTORS]]
747# @depends topcom
748property COCIRCUITS : Set<Pair<Set<Int>,Set<Int>>>;
749
750# @category Geometry
751# The slack matrix of the polytope. The (i,j)-th entry is the value of the j-th
752# facet on the i-th vertex.
753#
754# See
755# > João Gouveia, Antonio Macchia, Rekha R. Thomas, Amy Wiebe:
756# > The Slack Realization Space of a Polytope
757# > (https://arxiv.org/abs/1708.04739)
758property SLACK_MATRIX : Matrix<Scalar>;
759
760rule SLACK_MATRIX : VERTICES, FACETS {
761   $this->SLACK_MATRIX = $this->VERTICES * transpose($this->FACETS);
762}
763
764# @category Geometry
765# Returns the inner description of a Polytope:
766# [V,L] where V are the vertices and L is the lineality space
767# @return Array<Matrix<Scalar>>
768user_method INNER_DESCRIPTION : VERTICES, LINEALITY_SPACE {
769    my $this=shift;
770    new Array<Matrix>([$this->VERTICES, $this->LINEALITY_SPACE]);
771}
772
773# @category Geometry
774# Returns the outer description of a Polytope:
775# [F,A] where F are the facets and A is the affine hull
776# @return Array<Matrix<Scalar>>
777user_method OUTER_DESCRIPTION : FACETS, AFFINE_HULL {
778    my $this=shift;
779    new Array<Matrix>([$this->FACETS, $this->AFFINE_HULL]);
780}
781
782# @category Geometry
783# checks if a given Ball B(c,r) is contained in a Polytope
784# @param Vector<Scalar> c the center of the ball
785# @param Scalar r the radius of the ball
786# @return Bool
787user_method contains_ball {
788    my ($self, $c, $r) = @_;
789    return polytope_contains_ball($c, $r, $self);
790}
791
792# @category Geometry
793# check if a given Ball B(c,r) contains a Polytope
794# @param Vector<Scalar> c the center of the ball
795# @param Scalar r the radius of the ball
796# @return Bool
797user_method contained_in_ball {
798    my  ($self, $c, $r) = @_;
799    return polytope_contained_in_ball($self, $c, $r);
800}
801
802}
803
804# @category Coordinate conversions
805# provide a Polytope object with desired coordinate type
806# @tparam Coord target coordinate type
807# @param Polytope P source object
808# @return Polytope<Coord> //P// if it already has the requested type, a new object otherwise
809# @example
810# > print cube(2)->type->full_name;
811# | Polytope<Rational>
812# > $pf = convert_to<Float>(cube(2));
813# > print $pf->type->full_name;
814# | Polytope<Float>
815
816user_function convert_to<Coord>(Polytope) {
817   my $target_type=typeof Coord;
818   if ($_[0]->type->params->[0] == $target_type) {
819      $_[0]
820   } else {
821      new Polytope<Coord>($_[0]);
822   }
823}
824
825# @category Coordinate conversions
826# Dehomogenize the [[VERTICES|vertex coordinates]] and convert them to Float
827# @param Polytope P source object
828# @return Matrix<Float> the dehomogenized vertices converted to Float
829# @example
830# > print cube(2,1/2)->VERTICES;
831# | 1 -1/2 -1/2
832# | 1 1/2 -1/2
833# | 1 -1/2 1/2
834# | 1 1/2 1/2
835# > print affine_float_coords(cube(2,1/2));
836# | -0.5 -0.5
837# | 0.5 -0.5
838# | -0.5 0.5
839# | 0.5 0.5
840user_function affine_float_coords(Polytope) {
841   my $P=shift;
842   if ($P->FAR_FACE->size()!=0) {
843      croak("polytope must be bounded");
844   }
845   dehomogenize(convert_to<Float>($P->VERTICES));
846}
847
848# Local Variables:
849# mode: perl
850# cperl-indent-level:3
851# indent-tabs-mode:nil
852# End:
853