def cdd_Hrepresentation(cdd_type, ieqs, eqns): r""" Return a string containing the H-representation in cddlib's ine format. EXAMPLES:: sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Hrepresentation sage: cdd_Hrepresentation('rational', None, [[0,1]]) 'H-representation\nlinearity 1 1\nbegin\n 1 2 rational\n 0 1\nend\n' """ ieqs = _set_to_None_if_empty(ieqs) eqns = _set_to_None_if_empty(eqns) num, ambient_dim = _common_length_of(ieqs, eqns) ambient_dim -= 1 s = 'H-representation\n' if eqns is not None: assert len(eqns)>0 n = len(eqns) s += "linearity " + repr(n) + ' ' s += _to_space_separated_string(range(1,n+1)) + '\n' s += 'begin\n' s += ' ' + repr(num) + ' ' + repr(ambient_dim+1) + ' ' + cdd_type + '\n' if eqns is not None: for e in eqns: s += ' ' + _to_space_separated_string(e) + '\n' if ieqs is not None: for i in ieqs: s += ' ' + _to_space_separated_string(i) + '\n' s += 'end\n' return s
def cdd_Vrepresentation(cdd_type, vertices, rays, lines): r""" Return a string containing the V-representation in cddlib's ext format. NOTE: If there is no vertex given, then the origin will be implicitly added. You cannot write the empty V-representation (which cdd would refuse to process). EXAMPLES:: sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation sage: print cdd_Vrepresentation('rational', [[0,0]], [[1,0]], [[0,1]]) V-representation linearity 1 1 begin 3 3 rational 0 0 1 0 1 0 1 0 0 end """ vertices = _set_to_None_if_empty(vertices) rays = _set_to_None_if_empty(rays) lines = _set_to_None_if_empty(lines) num, ambient_dim = _common_length_of(vertices, rays, lines) # cdd implicitly assumes that the origin is a vertex if none is given if vertices is None: vertices = [[0]*ambient_dim] num += 1 s = 'V-representation\n' if lines is not None: n = len(lines) s += "linearity " + repr(n) + ' ' s += _to_space_separated_string(range(1,n+1)) + '\n' s += 'begin\n' s += ' ' + repr(num) + ' ' + repr(ambient_dim+1) + ' ' + cdd_type + '\n' if lines is not None: for l in lines: s += ' 0 ' + _to_space_separated_string(l) + '\n' if rays is not None: for r in rays: s += ' 0 ' + _to_space_separated_string(r) + '\n' if vertices is not None: for v in vertices: s += ' 1 ' + _to_space_separated_string(v) + '\n' s += 'end\n' return s
def cdd_Hrepresentation(cdd_type, ieqs, eqns, file_output=None): r""" Return a string containing the H-representation in cddlib's ine format. INPUT: - ``file_output`` (string; optional) -- a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. EXAMPLES:: sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Hrepresentation sage: cdd_Hrepresentation('rational', None, [[0,1]]) 'H-representation\nlinearity 1 1\nbegin\n 1 2 rational\n 0 1\nend\n' TESTS:: sage: from sage.misc.temporary_file import tmp_filename sage: filename = tmp_filename(ext='.ine') sage: cdd_Hrepresentation('rational', None, [[0,1]], file_output=filename) """ ieqs = _set_to_None_if_empty(ieqs) eqns = _set_to_None_if_empty(eqns) num, ambient_dim = _common_length_of(ieqs, eqns) ambient_dim -= 1 s = 'H-representation\n' if eqns is not None: assert len(eqns) > 0 n = len(eqns) s += "linearity " + repr(n) + ' ' s += _to_space_separated_string(range(1, n + 1)) + '\n' s += 'begin\n' s += ' ' + repr(num) + ' ' + repr(ambient_dim + 1) + ' ' + cdd_type + '\n' if eqns is not None: for e in eqns: s += ' ' + _to_space_separated_string(e) + '\n' if ieqs is not None: for i in ieqs: s += ' ' + _to_space_separated_string(i) + '\n' s += 'end\n' if file_output is not None: in_file = open(file_output, 'w') in_file.write(s) in_file.close() else: return s
def cdd_Hrepresentation(cdd_type, ieqs, eqns, file_output=None): r""" Return a string containing the H-representation in cddlib's ine format. INPUT: - ``file_output`` (string; optional) -- a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. EXAMPLES:: sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Hrepresentation sage: cdd_Hrepresentation('rational', None, [[0,1]]) 'H-representation\nlinearity 1 1\nbegin\n 1 2 rational\n 0 1\nend\n' TESTS:: sage: from sage.misc.temporary_file import tmp_filename sage: filename = tmp_filename(ext='.ine') sage: cdd_Hrepresentation('rational', None, [[0,1]], file_output=filename) """ ieqs = _set_to_None_if_empty(ieqs) eqns = _set_to_None_if_empty(eqns) num, ambient_dim = _common_length_of(ieqs, eqns) ambient_dim -= 1 s = "H-representation\n" if eqns is not None: assert len(eqns) > 0 n = len(eqns) s += "linearity " + repr(n) + " " s += _to_space_separated_string(range(1, n + 1)) + "\n" s += "begin\n" s += " " + repr(num) + " " + repr(ambient_dim + 1) + " " + cdd_type + "\n" if eqns is not None: for e in eqns: s += " " + _to_space_separated_string(e) + "\n" if ieqs is not None: for i in ieqs: s += " " + _to_space_separated_string(i) + "\n" s += "end\n" if file_output is not None: in_file = open(file_output, "w") in_file.write(s) in_file.close() else: return s
def cdd_Vrepresentation(cdd_type, vertices, rays, lines, file_output=None): r""" Return a string containing the V-representation in cddlib's ext format. INPUT: - ``file_output`` (string; optional) -- a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. .. NOTE:: If there is no vertex given, then the origin will be implicitly added. You cannot write the empty V-representation (which cdd would refuse to process). EXAMPLES:: sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation sage: print cdd_Vrepresentation('rational', [[0,0]], [[1,0]], [[0,1]]) V-representation linearity 1 1 begin 3 3 rational 0 0 1 0 1 0 1 0 0 end TESTS:: sage: from sage.misc.temporary_file import tmp_filename sage: filename = tmp_filename(ext='.ext') sage: cdd_Vrepresentation('rational', [[0,0]], [[1,0]], [[0,1]], file_output=filename) """ vertices = _set_to_None_if_empty(vertices) rays = _set_to_None_if_empty(rays) lines = _set_to_None_if_empty(lines) num, ambient_dim = _common_length_of(vertices, rays, lines) # cdd implicitly assumes that the origin is a vertex if none is given if vertices is None: vertices = [[0] * ambient_dim] num += 1 s = 'V-representation\n' if lines is not None: n = len(lines) s += "linearity " + repr(n) + ' ' s += _to_space_separated_string(range(1, n + 1)) + '\n' s += 'begin\n' s += ' ' + repr(num) + ' ' + repr(ambient_dim + 1) + ' ' + cdd_type + '\n' if lines is not None: for l in lines: s += ' 0 ' + _to_space_separated_string(l) + '\n' if rays is not None: for r in rays: s += ' 0 ' + _to_space_separated_string(r) + '\n' if vertices is not None: for v in vertices: s += ' 1 ' + _to_space_separated_string(v) + '\n' s += 'end\n' if file_output is not None: in_file = open(file_output, 'w') in_file.write(s) in_file.close() else: return s
def Polyhedron(vertices=None, rays=None, lines=None, ieqs=None, eqns=None, base_ring=QQ, minimize=True, verbose=False, backend=None): """ Construct a polyhedron object. You may either define it with vertex/ray/line or inequalities/equations data, but not both. Redundant data will automatically be removed (unless ``minimize=False``), and the complementary representation will be computed. INPUT: - ``vertices`` -- list of point. Each point can be specified as any iterable container of ``base_ring`` elements. - ``rays`` -- list of rays. Each ray can be specified as any iterable container of ``base_ring`` elements. - ``lines`` -- list of lines. Each line can be specified as any iterable container of ``base_ring`` elements. - ``ieqs`` -- list of inequalities. Each line can be specified as any iterable container of ``base_ring`` elements. - ``eqns`` -- list of equalities. Each line can be specified as any iterable container of ``base_ring`` elements. - ``base_ring`` -- either ``QQ`` or ``RDF``. The field over which the polyhedron will be defined. For ``QQ``, exact arithmetic will be used. For ``RDF``, floating point numbers will be used. Floating point arithmetic is faster but might give the wrong result for degenerate input. - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are * ``'cddr'``: cdd (:mod:`~sage.geometry.polyhedron.backend_cdd`) with rational coefficients * ``'cddf'``: cdd with floating-point coefficients * ``'ppl'``: use ppl (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\QQ` coefficients. Some backends support further optional arguments: - ``minimize`` -- boolean (default: ``True``). Whether to immediately remove redundant H/V-representation data. Currently not used. - ``verbose`` -- boolean (default: ``False``). Whether to print verbose output for debugging purposes. Only supported by the cdd backends. OUTPUT: The polyhedron defined by the input data. EXAMPLES: Construct some polyhedra:: sage: square_from_vertices = Polyhedron(vertices = [[1, 1], [1, -1], [-1, 1], [-1, -1]]) sage: square_from_ieqs = Polyhedron(ieqs = [[1, 0, 1], [1, 1, 0], [1, 0, -1], [1, -1, 0]]) sage: list(square_from_ieqs.vertex_generator()) [A vertex at (1, -1), A vertex at (1, 1), A vertex at (-1, 1), A vertex at (-1, -1)] sage: list(square_from_vertices.inequality_generator()) [An inequality (1, 0) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0, An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0] sage: p = Polyhedron(vertices = [[1.1, 2.2], [3.3, 4.4]], base_ring=RDF) sage: p.n_inequalities() 2 The same polyhedron given in two ways:: sage: p = Polyhedron(ieqs = [[0,1,0,0],[0,0,1,0]]) sage: p.Vrepresentation() (A line in the direction (0, 0, 1), A ray in the direction (1, 0, 0), A ray in the direction (0, 1, 0), A vertex at (0, 0, 0)) sage: q = Polyhedron(vertices=[[0,0,0]], rays=[[1,0,0],[0,1,0]], lines=[[0,0,1]]) sage: q.Hrepresentation() (An inequality (1, 0, 0) x + 0 >= 0, An inequality (0, 1, 0) x + 0 >= 0) Finally, a more complicated example. Take `\mathbb{R}_{\geq 0}^6` with coordinates `a, b, \dots, f` and * The inequality `e+b \geq c+d` * The inequality `e+c \geq b+d` * The equation `a+b+c+d+e+f = 31` :: sage: positive_coords = Polyhedron(ieqs=[ ... [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], ... [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]]) sage: P = Polyhedron(ieqs=positive_coords.inequalities() + [ ... [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]], eqns=[[-31,1,1,1,1,1,1]]) sage: P A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices sage: P.dim() 5 sage: P.Vrepresentation() (A vertex at (31, 0, 0, 0, 0, 0), A vertex at (0, 0, 0, 0, 0, 31), A vertex at (0, 0, 0, 0, 31, 0), A vertex at (0, 0, 31/2, 0, 31/2, 0), A vertex at (0, 31/2, 31/2, 0, 0, 0), A vertex at (0, 31/2, 0, 0, 31/2, 0), A vertex at (0, 0, 0, 31/2, 31/2, 0)) .. NOTE:: * Once constructed, a ``Polyhedron`` object is immutable. * Although the option ``field=RDF`` allows numerical data to be used, it might not give the right answer for degenerate input data - the results can depend upon the tolerance setting of cdd. """ # Clean up the arguments vertices = _set_to_None_if_empty(vertices) rays = _set_to_None_if_empty(rays) lines = _set_to_None_if_empty(lines) ieqs = _set_to_None_if_empty(ieqs) eqns = _set_to_None_if_empty(eqns) got_Vrep = (vertices is not None or rays is not None or lines is not None) got_Hrep = (ieqs is not None or eqns is not None) if got_Vrep and got_Hrep: raise ValueError('You cannot specify both H- and V-representation.') elif got_Vrep: vertices = _set_to_empty_if_None(vertices) rays = _set_to_empty_if_None(rays) lines = _set_to_empty_if_None(lines) Vrep = [vertices, rays, lines] Hrep = None ambient_dim = _common_length_of(*Vrep)[1] elif got_Hrep: ieqs = _set_to_empty_if_None(ieqs) eqns = _set_to_empty_if_None(eqns) Vrep = None Hrep = [ieqs, eqns] ambient_dim = _common_length_of(*Hrep)[1] - 1 else: Vrep = None Hrep = None ambient_dim = 0 if backend is not None: if backend == 'ppl': from backend_ppl import Polyhedron_QQ_ppl return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize) if backend == 'cddr': from backend_cdd import Polyhedron_QQ_cdd return Polyhedron_QQ_cdd(ambient_dim, Vrep, Hrep, verbose=verbose) if backend == 'cddf': from backend_cdd import Polyhedron_RDF_cdd return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose) if base_ring is QQ: from backend_ppl import Polyhedron_QQ_ppl return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize) elif base_ring is RDF: from backend_cdd import Polyhedron_RDF_cdd return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose) else: raise ValueError( 'Polyhedron objects can only be constructed over QQ and RDF')
def Polyhedron(vertices=None, rays=None, lines=None, ieqs=None, eqns=None, base_ring=QQ, minimize=True, verbose=False, backend=None): """ Construct a polyhedron object. You may either define it with vertex/ray/line or inequalities/equations data, but not both. Redundant data will automatically be removed (unless ``minimize=False``), and the complementary representation will be computed. INPUT: - ``vertices`` -- list of point. Each point can be specified as any iterable container of ``base_ring`` elements. - ``rays`` -- list of rays. Each ray can be specified as any iterable container of ``base_ring`` elements. - ``lines`` -- list of lines. Each line can be specified as any iterable container of ``base_ring`` elements. - ``ieqs`` -- list of inequalities. Each line can be specified as any iterable container of ``base_ring`` elements. - ``eqns`` -- list of equalities. Each line can be specified as any iterable container of ``base_ring`` elements. - ``base_ring`` -- either ``QQ`` or ``RDF``. The field over which the polyhedron will be defined. For ``QQ``, exact arithmetic will be used. For ``RDF``, floating point numbers will be used. Floating point arithmetic is faster but might give the wrong result for degenerate input. - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are * ``'cddr'``: cdd (:mod:`~sage.geometry.polyhedron.backend_cdd`) with rational coefficients * ``'cddf'``: cdd with floating-point coefficients * ``'ppl'``: use ppl (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\QQ` coefficients. Some backends support further optional arguments: - ``minimize`` -- boolean (default: ``True``). Whether to immediately remove redundant H/V-representation data. Currently not used. - ``verbose`` -- boolean (default: ``False``). Whether to print verbose output for debugging purposes. Only supported by the cdd backends. OUTPUT: The polyhedron defined by the input data. EXAMPLES: Construct some polyhedra:: sage: square_from_vertices = Polyhedron(vertices = [[1, 1], [1, -1], [-1, 1], [-1, -1]]) sage: square_from_ieqs = Polyhedron(ieqs = [[1, 0, 1], [1, 1, 0], [1, 0, -1], [1, -1, 0]]) sage: list(square_from_ieqs.vertex_generator()) [A vertex at (1, -1), A vertex at (1, 1), A vertex at (-1, 1), A vertex at (-1, -1)] sage: list(square_from_vertices.inequality_generator()) [An inequality (1, 0) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0, An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0] sage: p = Polyhedron(vertices = [[1.1, 2.2], [3.3, 4.4]], base_ring=RDF) sage: p.n_inequalities() 2 The same polyhedron given in two ways:: sage: p = Polyhedron(ieqs = [[0,1,0,0],[0,0,1,0]]) sage: p.Vrepresentation() (A line in the direction (0, 0, 1), A ray in the direction (1, 0, 0), A ray in the direction (0, 1, 0), A vertex at (0, 0, 0)) sage: q = Polyhedron(vertices=[[0,0,0]], rays=[[1,0,0],[0,1,0]], lines=[[0,0,1]]) sage: q.Hrepresentation() (An inequality (1, 0, 0) x + 0 >= 0, An inequality (0, 1, 0) x + 0 >= 0) Finally, a more complicated example. Take `\mathbb{R}_{\geq 0}^6` with coordinates `a, b, \dots, f` and * The inequality `e+b \geq c+d` * The inequality `e+c \geq b+d` * The equation `a+b+c+d+e+f = 31` :: sage: positive_coords = Polyhedron(ieqs=[ ... [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], ... [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]]) sage: P = Polyhedron(ieqs=positive_coords.inequalities() + [ ... [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]], eqns=[[-31,1,1,1,1,1,1]]) sage: P A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices sage: P.dim() 5 sage: P.Vrepresentation() (A vertex at (31, 0, 0, 0, 0, 0), A vertex at (0, 0, 0, 0, 0, 31), A vertex at (0, 0, 0, 0, 31, 0), A vertex at (0, 0, 31/2, 0, 31/2, 0), A vertex at (0, 31/2, 31/2, 0, 0, 0), A vertex at (0, 31/2, 0, 0, 31/2, 0), A vertex at (0, 0, 0, 31/2, 31/2, 0)) .. NOTE:: * Once constructed, a ``Polyhedron`` object is immutable. * Although the option ``field=RDF`` allows numerical data to be used, it might not give the right answer for degenerate input data - the results can depend upon the tolerance setting of cdd. """ # Clean up the arguments vertices = _set_to_None_if_empty(vertices) rays = _set_to_None_if_empty(rays) lines = _set_to_None_if_empty(lines) ieqs = _set_to_None_if_empty(ieqs) eqns = _set_to_None_if_empty(eqns) got_Vrep = (vertices is not None or rays is not None or lines is not None) got_Hrep = (ieqs is not None or eqns is not None) if got_Vrep and got_Hrep: raise ValueError('You cannot specify both H- and V-representation.') elif got_Vrep: vertices = _set_to_empty_if_None(vertices) rays = _set_to_empty_if_None(rays) lines = _set_to_empty_if_None(lines) Vrep = [vertices, rays, lines] Hrep = None ambient_dim = _common_length_of(*Vrep)[1] elif got_Hrep: ieqs = _set_to_empty_if_None(ieqs) eqns = _set_to_empty_if_None(eqns) Vrep = None Hrep = [ieqs, eqns] ambient_dim = _common_length_of(*Hrep)[1] - 1 else: Vrep = None Hrep = None ambient_dim = 0 if backend is not None: if backend=='ppl': from backend_ppl import Polyhedron_QQ_ppl return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize) if backend=='cddr': from backend_cdd import Polyhedron_QQ_cdd return Polyhedron_QQ_cdd(ambient_dim, Vrep, Hrep, verbose=verbose) if backend=='cddf': from backend_cdd import Polyhedron_RDF_cdd return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose) if base_ring is QQ: from backend_ppl import Polyhedron_QQ_ppl return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize) elif base_ring is RDF: from backend_cdd import Polyhedron_RDF_cdd return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose) else: raise ValueError('Polyhedron objects can only be constructed over QQ and RDF')
def cdd_Vrepresentation(cdd_type, vertices, rays, lines, file_output=None): r""" Return a string containing the V-representation in cddlib's ext format. INPUT: - ``file_output`` (string; optional) -- a filename to which the representation should be written. If set to ``None`` (default), representation is returned as a string. .. NOTE:: If there is no vertex given, then the origin will be implicitly added. You cannot write the empty V-representation (which cdd would refuse to process). EXAMPLES:: sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation sage: print cdd_Vrepresentation('rational', [[0,0]], [[1,0]], [[0,1]]) V-representation linearity 1 1 begin 3 3 rational 0 0 1 0 1 0 1 0 0 end TESTS:: sage: from sage.misc.temporary_file import tmp_filename sage: filename = tmp_filename(ext='.ext') sage: cdd_Vrepresentation('rational', [[0,0]], [[1,0]], [[0,1]], file_output=filename) """ vertices = _set_to_None_if_empty(vertices) rays = _set_to_None_if_empty(rays) lines = _set_to_None_if_empty(lines) num, ambient_dim = _common_length_of(vertices, rays, lines) # cdd implicitly assumes that the origin is a vertex if none is given if vertices is None: vertices = [[0] * ambient_dim] num += 1 s = "V-representation\n" if lines is not None: n = len(lines) s += "linearity " + repr(n) + " " s += _to_space_separated_string(range(1, n + 1)) + "\n" s += "begin\n" s += " " + repr(num) + " " + repr(ambient_dim + 1) + " " + cdd_type + "\n" if lines is not None: for l in lines: s += " 0 " + _to_space_separated_string(l) + "\n" if rays is not None: for r in rays: s += " 0 " + _to_space_separated_string(r) + "\n" if vertices is not None: for v in vertices: s += " 1 " + _to_space_separated_string(v) + "\n" s += "end\n" if file_output is not None: in_file = open(file_output, "w") in_file.write(s) in_file.close() else: return s