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