Path: blob/master/sage/geometry/polyhedron/constructor.py
4058 views
r"""1Polyhedra23In this module, a polyhedron is a convex (possibly unbounded) set in4Euclidean space cut out by a finite set of linear inequalities and5linear equations. Note that the dimension of the polyhedron can be6less than the dimension of the ambient space. There are two7complementary representations of the same data:89**H(alf-space/Hyperplane)-representation**10This describes a polyhedron as the common solution set of a11finite number of1213* linear inequalities `A \vec{x} + b \geq 0`, and14* linear equations `C \vec{x} + d \geq 0`.151617**V(ertex)-representation**18The other representation is as the convex hull of vertices (and19rays and lines to all for unbounded polyhedra) as generators. The20polyhedron is then the Minkowski sum2122.. MATH::2324P = \text{conv}\{v_1,\dots,v_k\} +25\sum_{i=1}^m \RR_+ r_i +26\sum_{j=1}^n \RR \ell_j2728where2930* `v_1`, `\dots`, `v_k` are a finite number of vertices,31* `r_1`, `\dots`, `r_m` are generators of rays,32* and `\ell_1`, `\dots`, `\ell_n` are generators of full lines.333435A polytope is defined as a bounded polyhedron.3637EXAMPLES::3839sage: trunc_quadr = Polyhedron(vertices=[[1,0],[0,1]], rays=[[1,0],[0,1]])40sage: trunc_quadr41A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays42sage: v = trunc_quadr.vertex_generator().next() # the first vertex in the internal enumeration43sage: v44A vertex at (0, 1)45sage: v.vector()46(0, 1)47sage: list(v)48[0, 1]49sage: len(v)50251sage: v[0] + v[1]52153sage: v.is_vertex()54True55sage: type(v)56<class 'sage.geometry.polyhedron.representation.Vertex'>57sage: type( v() )58<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>59sage: v.polyhedron()60A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays61sage: r = trunc_quadr.ray_generator().next()62sage: r63A ray in the direction (0, 1)64sage: r.vector()65(0, 1)66sage: [x for x in v.neighbors()]67[A ray in the direction (0, 1), A ray in the direction (1, 0), A vertex at (1, 0)]6869Inequalities `A \vec{x} + b \geq 0` (and, similarly, equations) are70specified by a list ``[b, A]``::7172sage: Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,-1]]).Hrepresentation()73(An inequality (-1, -1) x + 1 >= 0,74An inequality (1, 0) x + 0 >= 0,75An inequality (0, 1) x + 0 >= 0)7677See :func:`Polyhedron` for a detailed description of all possible ways78to construct a polyhedron.7980REFERENCES:8182Komei Fukuda's `FAQ in Polyhedral Computation83<http://www.ifor.math.ethz.ch/~fukuda/polyfaq/polyfaq.html>`_8485AUTHORS:8687- Marshall Hampton: first version, bug fixes, and various improvements, 2008 and 200988- Arnaud Bergeron: improvements to triangulation and rendering, 200889- Sebastien Barthelemy: documentation improvements, 200890- Volker Braun: refactoring, handle non-compact case, 2009 and 201091- Andrey Novoseltsev: added Hasse_diagram_from_incidences, 201092- Volker Braun: rewrite to use PPL instead of cddlib, 201193"""9495########################################################################96# Copyright (C) 2008 Marshall Hampton <[email protected]>97# Copyright (C) 2011 Volker Braun <[email protected]>98#99# Distributed under the terms of the GNU General Public License (GPL)100#101# http://www.gnu.org/licenses/102########################################################################103104from sage.rings.all import QQ, ZZ, RDF105from sage.misc.decorators import rename_keyword106107from misc import (108_set_to_None_if_empty, _set_to_empty_if_None,109_common_length_of )110111112113114115116#########################################################################117@rename_keyword(deprecated='Sage version 4.7.2', field='base_ring')118def Polyhedron(vertices=None, rays=None, lines=None,119ieqs=None, eqns=None,120base_ring=QQ, minimize=True, verbose=False,121backend=None):122"""123Construct a polyhedron object.124125You may either define it with vertex/ray/line or126inequalities/equations data, but not both. Redundant data will127automatically be removed (unless ``minimize=False``), and the128complementary representation will be computed.129130INPUT:131132- ``vertices`` -- list of point. Each point can be specified as133any iterable container of ``base_ring`` elements.134135- ``rays`` -- list of rays. Each ray can be specified as any136iterable container of ``base_ring`` elements.137138- ``lines`` -- list of lines. Each line can be specified as any139iterable container of ``base_ring`` elements.140141- ``ieqs`` -- list of inequalities. Each line can be specified as142any iterable container of ``base_ring`` elements.143144- ``eqns`` -- list of equalities. Each line can be specified as145any iterable container of ``base_ring`` elements.146147- ``base_ring`` -- either ``QQ`` or ``RDF``. The field over which148the polyhedron will be defined. For ``QQ``, exact arithmetic149will be used. For ``RDF``, floating point numbers will be150used. Floating point arithmetic is faster but might give the151wrong result for degenerate input.152153- ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are154155* ``'cddr'``: cdd (:mod:`~sage.geometry.polyhedron.backend_cdd`)156with rational coefficients157158* ``'cddf'``: cdd with floating-point coefficients159160* ``'ppl'``: use ppl161(:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\QQ`162coefficients.163164Some backends support further optional arguments:165166- ``minimize`` -- boolean (default: ``True``). Whether to167immediately remove redundant H/V-representation data. Currently168not used.169170- ``verbose`` -- boolean (default: ``False``). Whether to print171verbose output for debugging purposes. Only supported by the cdd172backends.173174OUTPUT:175176The polyhedron defined by the input data.177178EXAMPLES:179180Construct some polyhedra::181182sage: square_from_vertices = Polyhedron(vertices = [[1, 1], [1, -1], [-1, 1], [-1, -1]])183sage: square_from_ieqs = Polyhedron(ieqs = [[1, 0, 1], [1, 1, 0], [1, 0, -1], [1, -1, 0]])184sage: list(square_from_ieqs.vertex_generator())185[A vertex at (1, -1),186A vertex at (1, 1),187A vertex at (-1, 1),188A vertex at (-1, -1)]189sage: list(square_from_vertices.inequality_generator())190[An inequality (1, 0) x + 1 >= 0,191An inequality (0, 1) x + 1 >= 0,192An inequality (-1, 0) x + 1 >= 0,193An inequality (0, -1) x + 1 >= 0]194sage: p = Polyhedron(vertices = [[1.1, 2.2], [3.3, 4.4]], base_ring=RDF)195sage: p.n_inequalities()1962197198The same polyhedron given in two ways::199200sage: p = Polyhedron(ieqs = [[0,1,0,0],[0,0,1,0]])201sage: p.Vrepresentation()202(A line in the direction (0, 0, 1),203A ray in the direction (1, 0, 0),204A ray in the direction (0, 1, 0),205A vertex at (0, 0, 0))206sage: q = Polyhedron(vertices=[[0,0,0]], rays=[[1,0,0],[0,1,0]], lines=[[0,0,1]])207sage: q.Hrepresentation()208(An inequality (1, 0, 0) x + 0 >= 0,209An inequality (0, 1, 0) x + 0 >= 0)210211Finally, a more complicated example. Take `\mathbb{R}_{\geq 0}^6` with212coordinates `a, b, \dots, f` and213214* The inequality `e+b \geq c+d`215* The inequality `e+c \geq b+d`216* The equation `a+b+c+d+e+f = 31`217218::219220sage: positive_coords = Polyhedron(ieqs=[221... [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0],222... [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]])223sage: P = Polyhedron(ieqs=positive_coords.inequalities() + [224... [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]], eqns=[[-31,1,1,1,1,1,1]])225sage: P226A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices227sage: P.dim()2285229sage: P.Vrepresentation()230(A vertex at (31, 0, 0, 0, 0, 0), A vertex at (0, 0, 0, 0, 0, 31),231A vertex at (0, 0, 0, 0, 31, 0), A vertex at (0, 0, 31/2, 0, 31/2, 0),232A vertex at (0, 31/2, 31/2, 0, 0, 0), A vertex at (0, 31/2, 0, 0, 31/2, 0),233A vertex at (0, 0, 0, 31/2, 31/2, 0))234235.. NOTE::236237* Once constructed, a ``Polyhedron`` object is immutable.238* Although the option ``field=RDF`` allows numerical data to239be used, it might not give the right answer for degenerate240input data - the results can depend upon the tolerance241setting of cdd.242"""243# Clean up the arguments244vertices = _set_to_None_if_empty(vertices)245rays = _set_to_None_if_empty(rays)246lines = _set_to_None_if_empty(lines)247ieqs = _set_to_None_if_empty(ieqs)248eqns = _set_to_None_if_empty(eqns)249250got_Vrep = (vertices is not None or rays is not None or lines is not None)251got_Hrep = (ieqs is not None or eqns is not None)252253if got_Vrep and got_Hrep:254raise ValueError('You cannot specify both H- and V-representation.')255elif got_Vrep:256vertices = _set_to_empty_if_None(vertices)257rays = _set_to_empty_if_None(rays)258lines = _set_to_empty_if_None(lines)259Vrep = [vertices, rays, lines]260Hrep = None261ambient_dim = _common_length_of(*Vrep)[1]262elif got_Hrep:263ieqs = _set_to_empty_if_None(ieqs)264eqns = _set_to_empty_if_None(eqns)265Vrep = None266Hrep = [ieqs, eqns]267ambient_dim = _common_length_of(*Hrep)[1] - 1268else:269Vrep = None270Hrep = None271ambient_dim = 0272273if backend is not None:274if backend=='ppl':275from backend_ppl import Polyhedron_QQ_ppl276return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)277if backend=='cddr':278from backend_cdd import Polyhedron_QQ_cdd279return Polyhedron_QQ_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)280if backend=='cddf':281from backend_cdd import Polyhedron_RDF_cdd282return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)283284if base_ring is QQ:285from backend_ppl import Polyhedron_QQ_ppl286return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)287elif base_ring is RDF:288from backend_cdd import Polyhedron_RDF_cdd289return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)290else:291raise ValueError('Polyhedron objects can only be constructed over QQ and RDF')292293294295296297298299