Path: blob/master/src/sage/geometry/polyhedron/parent.py
8817 views
r"""1Parents for Polyhedra2"""34#*****************************************************************************5# Copyright (C) 2011 Volker Braun <[email protected]>6#7# Distributed under the terms of the GNU General Public License (GPL)8# http://www.gnu.org/licenses/9#******************************************************************************1011from sage.structure.parent import Parent12from sage.structure.element import get_coercion_model13from sage.structure.unique_representation import UniqueRepresentation14from sage.modules.free_module import is_FreeModule15from sage.misc.cachefunc import cached_method16from sage.rings.commutative_ring import is_CommutativeRing17from sage.rings.all import ZZ, QQ, RDF18from sage.categories.fields import Fields19_Fields = Fields()2021from sage.geometry.polyhedron.base import Polyhedron_base, is_Polyhedron22from representation import Inequality, Equation, Vertex, Ray, Line232425def Polyhedra(base_ring, ambient_dim, backend=None):26"""27Construct a suitable parent class for polyhedra2829INPUT:3031- ``base_ring`` -- A ring. Currently there are backends for `\ZZ`,32`\QQ`, and `\RDF`.3334- ``ambient_dim`` -- integer. The ambient space dimension.3536- ``backend`` -- string. The name of the backend for computations. Currently there are two backends implemented:3738* ``backend=ppl`` uses the Parma Polyhedra Library3940* ``backend=cdd`` uses CDD4142OUTPUT:4344A parent class for polyhedra over the given base ring if the45backend supports it. If not, the parent base ring can be larger46(for example, `\QQ` instead of `\ZZ`). If there is no47implementation at all, a ``ValueError`` is raised.4849EXAMPLES::5051sage: from sage.geometry.polyhedron.parent import Polyhedra52sage: Polyhedra(ZZ, 3)53Polyhedra in ZZ^354sage: type(_)55<class 'sage.geometry.polyhedron.parent.Polyhedra_ZZ_ppl_with_category'>56sage: Polyhedra(QQ, 3, backend='cdd')57Polyhedra in QQ^358sage: type(_)59<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_cdd_with_category'>6061CDD does not support integer polytopes directly::6263sage: Polyhedra(ZZ, 3, backend='cdd')64Polyhedra in QQ^365"""66if backend is None:67if base_ring is ZZ:68return Polyhedra_ZZ_ppl(base_ring, ambient_dim)69elif base_ring is QQ:70return Polyhedra_QQ_ppl(base_ring, ambient_dim)71elif base_ring is RDF:72return Polyhedra_RDF_cdd(base_ring, ambient_dim)73else:74raise ValueError('Polyhedral objects can only be constructed over ZZ, QQ, and RDF')75elif backend=='ppl' and base_ring is QQ:76return Polyhedra_QQ_ppl(base_ring, ambient_dim)77elif backend=='ppl' and base_ring is ZZ:78return Polyhedra_ZZ_ppl(base_ring, ambient_dim)79elif backend=='cdd' and base_ring in (ZZ, QQ):80return Polyhedra_QQ_cdd(QQ, ambient_dim)81elif backend=='cdd' and base_ring is RDF:82return Polyhedra_RDF_cdd(RDF, ambient_dim)83else:84raise ValueError('No such backend (='+str(backend)+85') implemented for given basering (='+str(base_ring)+').')86878889class Polyhedra_base(UniqueRepresentation, Parent):90r"""91Polyhedra in a fixed ambient space.9293INPUT:9495- ``base_ring`` -- either ``ZZ``, ``QQ``, or ``RDF``. The base96ring of the ambient module/vector space.9798- ``ambient_dim`` -- integer. The ambient space dimension.99100EXAMPLES::101102sage: from sage.geometry.polyhedron.parent import Polyhedra103sage: Polyhedra(ZZ, 3)104Polyhedra in ZZ^3105"""106def __init__(self, base_ring, ambient_dim):107"""108The Python constructor.109110EXAMPLES::111112sage: from sage.geometry.polyhedron.parent import Polyhedra113sage: Polyhedra(QQ, 3)114Polyhedra in QQ^3115116TESTS::117118sage: from sage.geometry.polyhedron.parent import Polyhedra119sage: P = Polyhedra(QQ, 3)120sage: TestSuite(P).run(skip='_test_pickling')121"""122self._ambient_dim = ambient_dim123from sage.categories.polyhedra import PolyhedralSets124Parent.__init__(self, base=base_ring, category=PolyhedralSets(base_ring))125self._Inequality_pool = []126self._Equation_pool = []127self._Vertex_pool = []128self._Ray_pool = []129self._Line_pool = []130131def recycle(self, polyhedron):132"""133Recycle the H/V-representation objects of a polyhedron.134135This speeds up creation of new polyhedra by reusing136objects. After recycling a polyhedron object, it is not in a137consistent state any more and neither the polyhedron nor its138H/V-representation objects may be used any more.139140INPUT:141142- ``polyhedron`` -- a polyhedron whose parent is ``self``.143144145EXAMPLES::146147sage: p = Polyhedron([(0,0),(1,0),(0,1)])148sage: p.parent().recycle(p)149150TESTS::151152sage: p = Polyhedron([(0,0),(1,0),(0,1)])153sage: n = len(p.parent()._Vertex_pool)154sage: p.delete()155sage: len(p.parent()._Vertex_pool) - n1563157"""158if self is not polyhedron.parent():159raise TypeError('The polyhedron has the wrong parent class.')160self._Inequality_pool.extend(polyhedron.inequalities())161self._Equation_pool.extend(polyhedron.equations())162self._Vertex_pool.extend(polyhedron.vertices())163self._Ray_pool.extend(polyhedron.rays())164self._Line_pool.extend(polyhedron.lines())165for Hrep in polyhedron.Hrep_generator():166Hrep._polyhedron = None167for Vrep in polyhedron.Vrep_generator():168Vrep._polyhedron = None169polyhedron._Hrepresentation = None170polyhedron._Vrepresentation = None171172def ambient_dim(self):173r"""174Return the dimension of the ambient space.175176EXAMPLES::177178sage: from sage.geometry.polyhedron.parent import Polyhedra179sage: Polyhedra(QQ, 3).ambient_dim()1803181"""182return self._ambient_dim183184@cached_method185def an_element(self):186r"""187Returns a Polyhedron.188189EXAMPLES::190191sage: from sage.geometry.polyhedron.parent import Polyhedra192sage: Polyhedra(QQ, 4).an_element()193A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices194"""195p = [0] * self.ambient_dim()196points = [p]197for i in range(0,self.ambient_dim()):198p = [0] * self.ambient_dim()199p[i] = 1200points.append(p)201return self.element_class(self, [points,[],[]], None)202203@cached_method204def some_elements(self):205r"""206Returns a list of some elements of the semigroup.207208EXAMPLES::209210sage: from sage.geometry.polyhedron.parent import Polyhedra211sage: Polyhedra(QQ, 4).some_elements()212[A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices,213A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex and 4 rays,214A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices and 1 ray,215The empty polyhedron in QQ^4]216sage: Polyhedra(ZZ,0).some_elements()217[The empty polyhedron in ZZ^0,218A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex]219"""220if self.ambient_dim() == 0:221return [222self.element_class(self, None, None),223self.element_class(self, None, [[],[]]) ]224points = []225for i in range(0,self.ambient_dim()+5):226points.append([i*j^2 for j in range(0,self.ambient_dim())])227return [228self.element_class(self, [points[0:self.ambient_dim()+1], [], []], None),229self.element_class(self, [points[0:1], points[1:self.ambient_dim()+1], []], None),230self.element_class(self, [points[0:3], points[4:5], []], None),231self.element_class(self, None, None) ]232233@cached_method234def zero_element(self):235r"""236Return the polyhedron consisting of the origin, which is the237neutral element for Minkowski addition.238239EXAMPLES::240241sage: from sage.geometry.polyhedron.parent import Polyhedra242sage: p = Polyhedra(QQ, 4).zero_element(); p243A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex244sage: p+p == p245True246"""247Vrep = [[[self.base_ring().zero()]*self.ambient_dim()], [], []]248return self.element_class(self, Vrep, None)249250def empty(self):251"""252Return the empty polyhedron.253254EXAMPLES::255256sage: from sage.geometry.polyhedron.parent import Polyhedra257sage: P = Polyhedra(QQ, 4)258sage: P.empty()259The empty polyhedron in QQ^4260sage: P.empty().is_empty()261True262"""263return self(None, None)264265def universe(self):266"""267Return the entire ambient space as polyhedron.268269EXAMPLES::270271sage: from sage.geometry.polyhedron.parent import Polyhedra272sage: P = Polyhedra(QQ, 4)273sage: P.universe()274A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex and 4 lines275sage: P.universe().is_universe()276True277"""278return self(None, [[[1]+[0]*self.ambient_dim()], []], convert=True)279280@cached_method281def Vrepresentation_space(self):282r"""283Return the ambient vector space.284285This is the vector space or module containing the286Vrepresentation vectors.287288OUTPUT:289290A free module over the base ring of dimension :meth:`ambient_dim`.291292EXAMPLES::293294sage: from sage.geometry.polyhedron.parent import Polyhedra295sage: Polyhedra(QQ, 4).Vrepresentation_space()296Vector space of dimension 4 over Rational Field297sage: Polyhedra(QQ, 4).ambient_space()298Vector space of dimension 4 over Rational Field299"""300if self.base_ring() in _Fields:301from sage.modules.free_module import VectorSpace302return VectorSpace(self.base_ring(), self.ambient_dim())303else:304from sage.modules.free_module import FreeModule305return FreeModule(self.base_ring(), self.ambient_dim())306307ambient_space = Vrepresentation_space308309@cached_method310def Hrepresentation_space(self):311r"""312Return the linear space containing the H-representation vectors.313314OUTPUT:315316A free module over the base ring of dimension :meth:`ambient_dim` + 1.317318EXAMPLES::319320sage: from sage.geometry.polyhedron.parent import Polyhedra321sage: Polyhedra(ZZ, 2).Hrepresentation_space()322Ambient free module of rank 3 over the principal ideal domain Integer Ring323"""324if self.base_ring() in _Fields:325from sage.modules.free_module import VectorSpace326return VectorSpace(self.base_ring(), self.ambient_dim()+1)327else:328from sage.modules.free_module import FreeModule329return FreeModule(self.base_ring(), self.ambient_dim()+1)330331def _repr_ambient_module(self):332"""333Return an abbreviated string representation of the ambient334space.335336OUTPUT:337338String.339340EXAMPLES::341342sage: from sage.geometry.polyhedron.parent import Polyhedra343sage: Polyhedra(QQ, 3)._repr_ambient_module()344'QQ^3'345"""346if self.base_ring() is ZZ:347s = 'ZZ'348elif self.base_ring() is QQ:349s = 'QQ'350elif self.base_ring() is RDF:351s = 'RDF'352else:353assert False354s += '^' + repr(self.ambient_dim())355return s356357def _repr_(self):358"""359Return a string representation.360361OUTPUT:362363String.364365EXAMPLES::366367sage: from sage.geometry.polyhedron.parent import Polyhedra368sage: Polyhedra(QQ, 3)369Polyhedra in QQ^3370sage: Polyhedra(QQ, 3)._repr_()371'Polyhedra in QQ^3'372"""373return 'Polyhedra in '+self._repr_ambient_module()374375def _element_constructor_(self, *args, **kwds):376"""377The element (polyhedron) constructor.378379INPUT:380381- ``Vrep`` -- a list `[vertices, rays, lines]`` or ``None``.382383- ``Hrep`` -- a list `[ieqs, eqns]`` or ``None``.384385- ``convert`` -- boolean keyword argument (default:386``True``). Whether to convert the cooordinates into the base387ring.388389- ``**kwds`` -- optional remaining keywords that are passed to the390polyhedron constructor.391392EXAMPLES::393394sage: from sage.geometry.polyhedron.parent import Polyhedra395sage: P = Polyhedra(QQ, 3)396sage: P._element_constructor_([[(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [], []], None)397A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices398sage: P([[(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [], []], None)399A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices400sage: P(0)401A 0-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex402"""403nargs = len(args)404convert = kwds.pop('convert', True)405if nargs==2:406Vrep, Hrep = args407def convert_base_ring(lstlst):408return [ [self.base_ring()(x) for x in lst] for lst in lstlst]409if convert and Hrep:410Hrep = map(convert_base_ring, Hrep)411if convert and Vrep:412Vrep = map(convert_base_ring, Vrep)413return self.element_class(self, Vrep, Hrep, **kwds)414if nargs==1 and is_Polyhedron(args[0]):415polyhedron = args[0]416Hrep = [ polyhedron.inequality_generator(), polyhedron.equation_generator() ]417return self.element_class(self, None, Hrep, **kwds)418if nargs==1 and args[0]==0:419return self.zero_element()420raise ValueError('Cannot convert to polyhedron object.')421422def base_extend(self, base_ring, backend=None):423"""424Return the base extended parent.425426INPUT:427428- ``base_ring``, ``backend`` -- see429:func:`~sage.geometry.polyhedron.constructor.Polyhedron`.430431EXAMPLES::432433sage: from sage.geometry.polyhedron.parent import Polyhedra434sage: Polyhedra(ZZ,3).base_extend(QQ)435Polyhedra in QQ^3436sage: Polyhedra(ZZ,3).an_element().base_extend(QQ)437A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices438"""439if self.base_ring().has_coerce_map_from(base_ring):440return self441elif base_ring.has_coerce_map_from(self.base_ring()):442return Polyhedra(base_ring, self.ambient_dim())443444def _coerce_base_ring(self, other):445"""446Return the common base rincg for both ``self`` and ``other``.447448This method is not part of the coercion framework, but only a449convenience function for :class:`Polyhedra_base`.450451INPUT:452453- ``other`` -- must be either:454455* another ``Polyhedron`` object456457* `\ZZ`, `\QQ`, `RDF`, or a ring that can be coerced into them.458459* a constant that can be coerced to `\ZZ`, `\QQ`, or `RDF`.460461OUTPUT:462463Either `\ZZ`, `\QQ`, or `RDF`. Raises ``TypeError`` if464``other`` is not a suitable input.465466.. NOTE::467468"Real" numbers in sage are not necessarily elements of469`RDF`. For example, the literal `1.0` is not.470471EXAMPLES::472473sage: triangle_QQ = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ).parent()474sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF).parent()475sage: triangle_QQ._coerce_base_ring(QQ)476Rational Field477sage: triangle_QQ._coerce_base_ring(triangle_RDF)478Real Double Field479sage: triangle_RDF._coerce_base_ring(triangle_QQ)480Real Double Field481sage: triangle_QQ._coerce_base_ring(RDF)482Real Double Field483sage: triangle_QQ._coerce_base_ring(ZZ)484Rational Field485sage: triangle_QQ._coerce_base_ring(1/2)486Rational Field487sage: triangle_QQ._coerce_base_ring(0.5)488Real Double Field489"""490try:491other_ring = other.base_ring()492except AttributeError:493try:494# other is a constant?495other_ring = other.parent()496except AttributeError:497other_ring = None498for ring in (ZZ, QQ, RDF):499try:500ring.coerce(other)501other_ring = ring502break503except TypeError:504pass505if other_ring is None:506raise TypeError('Could not coerce '+str(other)+' into ZZ, QQ, or RDF.')507508if not other_ring.is_exact():509other_ring = RDF # the only supported floating-point numbers for now510511cm_map, cm_ring = get_coercion_model().analyse(self.base_ring(), other_ring)512if cm_ring is None:513raise TypeError('Could not coerce type '+str(other)+' into ZZ, QQ, or RDF.')514return cm_ring515516def _coerce_map_from_(self, X):517r"""518Return whether there is a coercion from ``X``519520INPUT:521522- ``X`` -- anything.523524OUTPUT:525526Boolean.527528EXAMPLE::529530sage: from sage.geometry.polyhedron.parent import Polyhedra531sage: Polyhedra(QQ,3).has_coerce_map_from( Polyhedra(ZZ,3) ) # indirect doctest532True533sage: Polyhedra(ZZ,3).has_coerce_map_from( Polyhedra(QQ,3) )534False535"""536if not isinstance(X, Polyhedra_base):537return False538if self.ambient_dim() != X.ambient_dim():539return False540return self.base_ring().has_coerce_map_from(X.base_ring())541542def _get_action_(self, other, op, self_is_left):543"""544Register actions with the coercion model.545546The monoid actions are Minkowski sum and cartesian product. In547addition, we want multiplication by a scalar to be dilation548and addition by a vector to be translation. This is549implemented as an action in the coercion model.550551INPUT:552553- ``other`` -- a scalar or a vector.554555- ``op`` -- the operator.556557- ``self_is_left`` -- boolean. Whether ``self`` is on the left558of the operator.559560OUTPUT:561562An action that is used by the coercion model.563564EXAMPLES::565566sage: from sage.geometry.polyhedron.parent import Polyhedra567sage: Polyhedra(ZZ,2).get_action(ZZ) # indirect doctest568Right action by Integer Ring on Polyhedra in ZZ^2569sage: Polyhedra(ZZ,2).get_action(QQ)570Right action by Rational Field on Polyhedra in QQ^2571with precomposition on left by Conversion map:572From: Polyhedra in ZZ^2573To: Polyhedra in QQ^2574with precomposition on right by Identity endomorphism of Rational Field575sage: Polyhedra(QQ,2).get_action(ZZ)576Right action by Integer Ring on Polyhedra in QQ^2577sage: Polyhedra(QQ,2).get_action(QQ)578Right action by Rational Field on Polyhedra in QQ^2579580sage: Polyhedra(ZZ,2).an_element() * 2581A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices582sage: Polyhedra(ZZ,2).an_element() * (2/3)583A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices584sage: Polyhedra(QQ,2).an_element() * 2585A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices586sage: Polyhedra(QQ,2).an_element() * (2/3)587A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices588589sage: 2 * Polyhedra(ZZ,2).an_element()590A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices591sage: (2/3) * Polyhedra(ZZ,2).an_element()592A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices593sage: 2 * Polyhedra(QQ,2).an_element()594A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices595sage: (2/3) * Polyhedra(QQ,2).an_element()596A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices597598sage: from sage.geometry.polyhedron.parent import Polyhedra599sage: Polyhedra(ZZ,2).get_action( ZZ^2, op=operator.add)600Right action by Ambient free module of rank 2 over the principal ideal601domain Integer Ring on Polyhedra in ZZ^2602with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2603with precomposition on right by Free module morphism defined by the matrix604[1 0]605[0 1]606Domain: Ambient free module of rank 2 over the principal ideal domain ...607Codomain: Ambient free module of rank 2 over the principal ideal domain ...608"""609import operator610from sage.structure.coerce_actions import ActedUponAction611from sage.categories.action import PrecomposedAction612613if op is operator.add and is_FreeModule(other):614base_ring = self._coerce_base_ring(other)615extended_self = self.base_extend(base_ring)616extended_other = other.base_extend(base_ring)617action = ActedUponAction(extended_other, extended_self, not self_is_left)618if self_is_left:619action = PrecomposedAction(action,620extended_self.coerce_map_from(self),621extended_other.coerce_map_from(other))622else:623action = PrecomposedAction(action,624extended_other.coerce_map_from(other),625extended_self.coerce_map_from(self))626return action627628if op is operator.mul and is_CommutativeRing(other):629ring = self._coerce_base_ring(other)630if ring is self.base_ring():631return ActedUponAction(other, self, not self_is_left)632extended = self.base_extend(ring)633action = ActedUponAction(ring, extended, not self_is_left)634if self_is_left:635action = PrecomposedAction(action,636extended.coerce_map_from(self),637ring.coerce_map_from(other))638else:639action = PrecomposedAction(action,640ring.coerce_map_from(other),641extended.coerce_map_from(self))642return action643644def _make_Inequality(self, polyhedron, data):645"""646Create a new inequality object.647648INPUT:649650- ``polyhedron`` -- the new polyhedron.651652- ``data`` -- the H-representation data.653654OUTPUT:655656A new :class:`~sage.geometry.polyhedron.representation.Inequality` object.657658EXAMPLES::659660sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)]) # indirect doctest661sage: p.inequality_generator().next()662An inequality (0, 0, -1) x + 3 >= 0663"""664try:665obj = self._Inequality_pool.pop()666except IndexError:667obj = Inequality(self)668obj._set_data(polyhedron, data)669return obj670671def _make_Equation(self, polyhedron, data):672"""673Create a new equation object.674675INPUT:676677- ``polyhedron`` -- the new polyhedron.678679- ``data`` -- the H-representation data.680681OUTPUT:682683A new :class:`~sage.geometry.polyhedron.representation.Equation` object.684685EXAMPLES::686687sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)]) # indirect doctest688sage: p.equation_generator().next()689An equation (0, 44, -25) x - 13 == 0690"""691try:692obj = self._Equation_pool.pop()693except IndexError:694obj = Equation(self)695obj._set_data(polyhedron, data)696return obj697698def _make_Vertex(self, polyhedron, data):699"""700Create a new vertex object.701702INPUT:703704- ``polyhedron`` -- the new polyhedron.705706- ``data`` -- the V-representation data.707708OUTPUT:709710A new :class:`~sage.geometry.polyhedron.representation.Vertex` object.711712EXAMPLES::713714sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)]) # indirect doctest715sage: p.vertex_generator().next()716A vertex at (1, 2, 3)717"""718try:719obj = self._Vertex_pool.pop()720except IndexError:721obj = Vertex(self)722obj._set_data(polyhedron, data)723return obj724725def _make_Ray(self, polyhedron, data):726"""727Create a new ray object.728729INPUT:730731- ``polyhedron`` -- the new polyhedron.732733- ``data`` -- the V-representation data.734735OUTPUT:736737A new :class:`~sage.geometry.polyhedron.representation.Ray` object.738739EXAMPLES::740741sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)]) # indirect doctest742sage: p.ray_generator().next()743A ray in the direction (140, 144, 147)744"""745try:746obj = self._Ray_pool.pop()747except IndexError:748obj = Ray(self)749obj._set_data(polyhedron, data)750return obj751752def _make_Line(self, polyhedron, data):753"""754Create a new line object.755756INPUT:757758- ``polyhedron`` -- the new polyhedron.759760- ``data`` -- the V-representation data.761762OUTPUT:763764A new :class:`~sage.geometry.polyhedron.representation.Line` object.765766EXAMPLES::767768sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], lines=[(5/6,6/7,7/8)]) # indirect doctest769sage: p.line_generator().next()770A line in the direction (140, 144, 147)771"""772try:773obj = self._Line_pool.pop()774except IndexError:775obj = Line(self)776obj._set_data(polyhedron, data)777return obj778779780781from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd, Polyhedron_RDF_cdd782from sage.geometry.polyhedron.backend_ppl import Polyhedron_ZZ_ppl, Polyhedron_QQ_ppl783784class Polyhedra_ZZ_ppl(Polyhedra_base):785Element = Polyhedron_ZZ_ppl786787class Polyhedra_QQ_ppl(Polyhedra_base):788Element = Polyhedron_QQ_ppl789790class Polyhedra_QQ_cdd(Polyhedra_base):791Element = Polyhedron_QQ_cdd792793class Polyhedra_RDF_cdd(Polyhedra_base):794Element = Polyhedron_RDF_cdd795796797798