Ticket #11763: trac_11763-polyhedra_coercion_folded.patch

File trac_11763-polyhedra_coercion_folded.patch, 177.6 KB (added by davidloeffler, 8 years ago)

Apply only this patch. Patch against 5.0.beta7

  • doc/en/reference/geometry.rst

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1315501129 14400
    # Node ID f0729f1a72022dbb0c6f6fc274750603f18b8c11
    # Parent  fcf92c73da9d7fd61a4cdc525e877a7c9a9f603e
    Trac #11763: Add ZZ as allowed base ring for polyhedra
    * * *
    Trac #11763: Parents for polyhedra
    
    diff --git a/doc/en/reference/geometry.rst b/doc/en/reference/geometry.rst
    a b  
    2525   sage/geometry/polyhedron/plot
    2626   sage/geometry/polyhedron/base
    2727   sage/geometry/polyhedron/base_QQ
     28   sage/geometry/polyhedron/base_ZZ
    2829   sage/geometry/polyhedron/base_RDF
    2930   sage/geometry/polyhedron/backend_cdd
    3031   sage/geometry/polyhedron/backend_ppl
  • sage/categories/all.py

    diff --git a/sage/categories/all.py b/sage/categories/all.py
    a b  
    125125from highest_weight_crystals import HighestWeightCrystals
    126126from finite_crystals import FiniteCrystals
    127127from classical_crystals import ClassicalCrystals
     128
     129# polyhedra
     130from polyhedra import PolyhedralSets
  • new file sage/categories/polyhedra.py

    diff --git a/sage/categories/polyhedra.py b/sage/categories/polyhedra.py
    new file mode 100644
    - +  
     1r"""
     2Polyhedral subsets of free ZZ, QQ or RR-modules.
     3"""
     4#*****************************************************************************
     5#       Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
     6#
     7#  Distributed under the terms of the GNU General Public License (GPL)
     8#                  http://www.gnu.org/licenses/
     9#******************************************************************************
     10
     11from sage.structure.element_wrapper import ElementWrapper
     12from sage.categories.category_types import Category_over_base_ring
     13from sage.misc.cachefunc import cached_method
     14from sage.categories.category import HomCategory
     15
     16
     17
     18class PolyhedralSets(Category_over_base_ring):
     19    r"""
     20    The category of Polyhedra over a ring.
     21
     22    EXAMPLES:
     23
     24    We create the category of polyhedra over `\QQ`::
     25
     26        sage: PolyhedralSets(QQ)
     27        Category of Polyhedra over Rational Field
     28
     29    TESTS::
     30
     31        sage: TestSuite(PolyhedralSets(RDF)).run()
     32
     33        sage: P = Polyhedron()
     34        sage: P.parent().category().element_class
     35        <class 'sage.categories.category.PolyhedralSets.element_class'>
     36        sage: P.parent().category().element_class.mro()
     37        [<class 'sage.categories.category.PolyhedralSets.element_class'>,
     38         <class 'sage.categories.magmas.Magmas.element_class'>,
     39         <class 'sage.categories.additive_magmas.AdditiveMagmas.element_class'>,
     40         <class 'sage.categories.sets_cat.Sets.element_class'>,
     41         <class 'sage.categories.category.SetsWithPartialMaps.element_class'>,
     42         <class 'sage.categories.objects.Objects.element_class'>,
     43         <type 'object'>]
     44        sage: isinstance(P, P.parent().category().element_class)
     45        True
     46    """
     47
     48    def __init__(self, R):
     49        """
     50        TESTS::
     51
     52            sage: PolyhedralSets((1,2,3))
     53            Traceback (most recent call last):
     54            ...
     55            TypeError: base ring R (=(1, 2, 3)) must be ZZ, QQ, or RDF.
     56        """
     57        from sage.rings.all import ZZ, QQ, RDF
     58        if R not in [ZZ, QQ, RDF]:
     59            raise TypeError, 'base ring R (='+str(R)+') must be ZZ, QQ, or RDF.'
     60        Category_over_base_ring.__init__(self, R, 'Polyhedra')
     61
     62    @cached_method
     63    def super_categories(self):
     64        """
     65        EXAMPLES::
     66
     67            sage: PolyhedralSets(QQ).super_categories()
     68            [Category of magmas, Category of additive magmas]
     69        """
     70        from sage.categories.all import Magmas, AdditiveMagmas
     71        return [Magmas(), AdditiveMagmas()]
     72
     73
     74
     75
  • sage/geometry/cone.py

    diff --git a/sage/geometry/cone.py b/sage/geometry/cone.py
    a b  
    144144    sage: four_rays.lattice_polytope()
    145145    A lattice polytope: 3-dimensional, 5 vertices.
    146146    sage: four_rays.polyhedron()
    147     A 3-dimensional polyhedron in QQ^3 defined as
     147    A 3-dimensional polyhedron in ZZ^3 defined as
    148148    the convex hull of 1 vertex and 4 rays
    149149
    150150And of course you are always welcome to suggest new features that should be
     
    532532        V = lattice.base_extend(QQ)
    533533        for n, ray in enumerate(rays):
    534534            try:
    535                 ray = V(ray)
     535                if isinstance(ray, (list, tuple, V._element_class)):
     536                    ray = V(ray)
     537                else:
     538                    ray = V(list(ray))
    536539            except TypeError:
    537540                raise TypeError("cannot convert %s to %s!" % (ray, V))
    538541            if ray.is_zero():
     
    28762879
    28772880            sage: quadrant = Cone([(1,0), (0,1)])
    28782881            sage: quadrant.polyhedron()
    2879             A 2-dimensional polyhedron in QQ^2 defined as the convex hull
     2882            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull
    28802883            of 1 vertex and 2 rays
    28812884            sage: line = Cone([(1,0), (-1,0)])
    28822885            sage: line.polyhedron()
    2883             A 1-dimensional polyhedron in QQ^2 defined as the convex hull
     2886            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull
    28842887            of 1 vertex and 1 line
    28852888           
    28862889        Here is an example of a trivial cone (see Trac #10237)::
    28872890       
    28882891            sage: origin = Cone([], lattice=ZZ^2)
    28892892            sage: origin.polyhedron()
    2890             A 0-dimensional polyhedron in QQ^2 defined as the convex hull
     2893            A 0-dimensional polyhedron in ZZ^2 defined as the convex hull
    28912894            of 1 vertex
    28922895        """
    28932896        if "_polyhedron" not in self.__dict__:
  • sage/geometry/integral_points.pyx

    diff --git a/sage/geometry/integral_points.pyx b/sage/geometry/integral_points.pyx
    a b  
    266266   
    267267        sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
    268268        sage: simplex = Polyhedron(v); simplex
    269         A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     269        A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
    270270        sage: pts = simplex_points(simplex.Vrepresentation())
    271271        sage: len(pts)
    272272        49
     
    279279       
    280280        sage: v = [(4,-1,-1,-1), (-1,4,-1,-1), (-1,-1,4,-1), (-1,-1,-1,4), (-1,-1,-1,-1)]
    281281        sage: P4mirror = Polyhedron(v); P4mirror
    282         A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     282        A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
    283283        sage: len( simplex_points(P4mirror.Vrepresentation()) )
    284284        126
    285285    """
     
    878878        max_abs_coordinates = permutation.action(max_abs_coordinates)
    879879        self.ineqs_int = []
    880880        self.ineqs_generic = []
    881         if not polyhedron:
     881        if polyhedron is None:
    882882            return
    883883        for Hrep_obj in polyhedron.inequality_generator():
    884884            A, b = self._make_A_b(Hrep_obj, permutation)
  • sage/geometry/polyhedron/backend_cdd.py

    diff --git a/sage/geometry/polyhedron/backend_cdd.py b/sage/geometry/polyhedron/backend_cdd.py
    a b  
    1010from base import Polyhedron_base
    1111from base_QQ import Polyhedron_QQ
    1212from base_RDF import Polyhedron_RDF
    13 from representation import (
    14     PolyhedronRepresentation,
    15     Hrepresentation,
    16     Inequality, Equation,
    17     Vrepresentation,
    18     Vertex, Ray, Line )
    1913
    2014
    2115
     
    2519    Base class for the cdd backend.
    2620    """
    2721
    28     def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, verbose=False):
     22    def _init_from_Vrepresentation(self, vertices, rays, lines, verbose=False):
    2923        """
    3024        Construct polyhedron from V-representation data.
    3125
    3226        INPUT:
    3327
    34         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    35        
    3628        - ``vertices`` -- list of point. Each point can be specified
    3729           as any iterable container of
    3830           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    5143        EXAMPLES::
    5244
    5345            sage: Polyhedron(vertices=[(0,0)], rays=[(1,1)],
    54             ...              lines=[(1,-1)], backend='cddr')  # indirect doctest
     46            ...              lines=[(1,-1)], backend='cdd', base_ring=QQ)  # indirect doctest
    5547            A 2-dimensional polyhedron in QQ^2 defined as the
    5648            convex hull of 1 vertex, 1 ray, 1 line
    5749        """
     
    6052        self._init_from_cdd_input(s, '--reps', verbose)
    6153
    6254
    63     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, verbose=False):
     55    def _init_from_Hrepresentation(self, ieqs, eqns, verbose=False):
    6456        """
    6557        Construct polyhedron from H-representation data.
    6658
    6759        INPUT:
    6860
    69         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    70        
    7161        - ``ieqs`` -- list of inequalities. Each line can be specified
    7262          as any iterable container of
    7363          :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    8272        EXAMPLES::
    8373
    8474            sage: Polyhedron(ieqs=[(0,1,1)], eqns=[(0,1,-1)],
    85             ...              backend='cddr')  # indirect doctest
     75            ...              backend='cdd', base_ring=QQ)  # indirect doctest
    8676            A 1-dimensional polyhedron in QQ^2 defined as the
    8777            convex hull of 1 vertex and 1 ray
    8878        """
     
    9888
    9989        EXAMPLES::
    10090       
    101             sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cddr')
     91            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cdd', base_ring=QQ)
    10292            sage: '_H_adjacency_matrix' in p.__dict__
    10393            False
    10494            sage: p._init_facet_adjacency_matrix()
     
    118108
    119109        EXAMPLES::
    120110       
    121             sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cddr')
     111            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cdd', base_ring=QQ)
    122112            sage: '_V_adjacency_matrix' in p.__dict__
    123113            False
    124114            sage: p._init_vertex_adjacency_matrix()
     
    138128
    139129        TESTS::
    140130       
    141             sage: p = Polyhedron(vertices = [[0,0,0],[1,0,0],[0,1,0],[0,0,1]], backend='cddr')
     131            sage: p = Polyhedron(vertices = [[0,0,0],[1,0,0],[0,1,0],[0,0,1]], backend='cdd', base_ring=QQ)
    142132            sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation
    143133            sage: s = cdd_Vrepresentation('rational', [[0,0,1],[0,1,0],[1,0,0]], [], [])
    144134            sage: p._init_from_cdd_input(s)
     
    168158            sage: from subprocess import Popen, PIPE
    169159            sage: cdd_proc = Popen(['cdd_both_reps_gmp', '--all'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
    170160            sage: ans, err = cdd_proc.communicate(input=s)
    171             sage: p = Polyhedron(vertices = [[0,0],[1,0],[0,1],[1,1]], backend='cddr')
     161            sage: p = Polyhedron(vertices = [[0,0],[1,0],[0,1],[1,1]], backend='cdd', base_ring=QQ)
    172162            sage: p._init_from_cdd_output(ans)
    173163            sage: p.vertices()
    174             [[0, 0], [1, 0], [0, 1], [1, 1]]
     164            (A vertex at (0, 0), A vertex at (1, 0), A vertex at (0, 1), A vertex at (1, 1))
    175165        """
    176166        cddout=cdd_output_string.splitlines()
    177167        suppressed_vertex = False   # whether cdd suppressed the vertex in output
     168        parent = self.parent()
    178169
    179170        # nested function
    180171        def expect_in_cddout(expected_string):
     
    219210            lines = cdd_linearities()
    220211            expect_in_cddout('begin')
    221212            l = cddout.pop(0).split()
    222             assert self._ambient_dim == int(l[1])-1,  "Different ambient dimension?"
     213            assert self.ambient_dim() == int(l[1])-1,  "Different ambient dimension?"
    223214            suppressed_vertex = True
    224215            for i in range(int(l[0])):
    225216                l = cddout.pop(0).strip()
    226217                l_type = l[0]
    227218                l = l[1:]
    228219                if i in lines:
    229                     Line(self, cdd_convert(l));
     220                    parent._make_Line(self, cdd_convert(l));
    230221                elif l_type == '0':
    231                     Ray(self, cdd_convert(l));
     222                    parent._make_Ray(self, cdd_convert(l));
    232223                else:
    233                     Vertex(self, cdd_convert(l));
     224                    parent._make_Vertex(self, cdd_convert(l));
    234225                    suppressed_vertex = False
    235226            if suppressed_vertex and self.n_Vrepresentation()>0:
    236227                # cdd does not output the vertex if it is only the origin
    237                 Vertex(self, [0] * self._ambient_dim)
     228                parent._make_Vertex(self, [0] * self.ambient_dim())
    238229            self._Vrepresentation = tuple(self._Vrepresentation)
    239230            expect_in_cddout('end')
    240231       
     
    243234            equations = cdd_linearities()
    244235            expect_in_cddout('begin')
    245236            l = cddout.pop(0).split()
    246             assert self._ambient_dim == int(l[1])-1, "Different ambient dimension?"
     237            assert self.ambient_dim() == int(l[1])-1, "Different ambient dimension?"
    247238            for i in range(int(l[0])):
    248239                l = cddout.pop(0)
    249240                if i in equations:
    250                     Equation(self, cdd_convert(l));
     241                    parent._make_Equation(self, cdd_convert(l));
    251242                else:
    252                     Inequality(self, cdd_convert(l));
     243                    parent._make_Inequality(self, cdd_convert(l));
    253244            self._Hrepresentation = tuple(self._Hrepresentation)
    254245            expect_in_cddout('end')
    255246
     
    306297
    307298    INPUT:
    308299
    309     - ``ambient_dim`` -- integer. The dimension of the ambient space.
     300    - ``parent`` -- the parent, an instance of
     301      :class:`~sage.geometry.polyhedron.parent.Polyhedra`.
    310302
    311     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     303    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    312304       
    313     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     305    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    314306
    315307    EXAMPLES::
    316308
     309        sage: from sage.geometry.polyhedron.parent import Polyhedra
     310        sage: parent = Polyhedra(QQ, 2, backend='cdd')
    317311        sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd
    318         sage: Polyhedron_QQ_cdd(2, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
     312        sage: Polyhedron_QQ_cdd(parent, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
    319313        A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
    320314    """
    321315
     
    323317
    324318    _cdd_executable = 'cdd_both_reps_gmp'
    325319
    326     def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
     320    def __init__(self, parent, Vrep, Hrep, **kwds):
    327321        """
    328322        The Python constructor.
    329323
     
    332326
    333327        TESTS::
    334328       
    335             sage: p = Polyhedron(backend='cddr')
     329            sage: p = Polyhedron(backend='cdd', base_ring=QQ)
    336330            sage: type(p)
    337             <class 'sage.geometry.polyhedron.backend_cdd.Polyhedron_QQ_cdd'>
     331            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedra_QQ_cdd_with_category.element_class'>
    338332            sage: TestSuite(p).run()
    339333        """
    340         Polyhedron_cdd.__init__(self, ambient_dim, Vrep, Hrep, **kwds)
     334        Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
    341335   
    342336
    343337#########################################################################
     
    349343
    350344    - ``ambient_dim`` -- integer. The dimension of the ambient space.
    351345
    352     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     346    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    353347       
    354     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     348    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    355349
    356350    EXAMPLES::
    357351
     352        sage: from sage.geometry.polyhedron.parent import Polyhedra
     353        sage: parent = Polyhedra(RDF, 2, backend='cdd')
    358354        sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_RDF_cdd
    359         sage: Polyhedron_RDF_cdd(2, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
     355        sage: Polyhedron_RDF_cdd(parent, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
    360356        A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 3 vertices
    361357    """
    362358    _cdd_type = 'real'
    363359   
    364360    _cdd_executable = 'cdd_both_reps'
    365361
    366     def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
     362    def __init__(self, parent, Vrep, Hrep, **kwds):
    367363        """
    368364        The Python constructor.
    369365
     
    372368
    373369        TESTS::
    374370       
    375             sage: p = Polyhedron(backend='cddf')
     371            sage: p = Polyhedron(backend='cdd', base_ring=RDF)
    376372            sage: type(p)
    377             <class 'sage.geometry.polyhedron.backend_cdd.Polyhedron_RDF_cdd'>
     373            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedra_RDF_cdd_with_category.element_class'>
    378374            sage: TestSuite(p).run()
    379375        """
    380         Polyhedron_cdd.__init__(self, ambient_dim, Vrep, Hrep, **kwds)
     376        Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
    381377   
  • sage/geometry/polyhedron/backend_ppl.py

    diff --git a/sage/geometry/polyhedron/backend_ppl.py b/sage/geometry/polyhedron/backend_ppl.py
    a b  
    33"""
    44
    55from sage.rings.all import ZZ, QQ
    6 from sage.rings.arith import lcm
     6from sage.rings.integer import LCM_list
    77from sage.misc.functional import denominator
    88from sage.matrix.constructor import matrix
    99from sage.libs.ppl import (
     
    1111    Variable, Linear_Expression,
    1212    line, ray, point )
    1313
     14from base import Polyhedron_base
    1415from base_QQ import Polyhedron_QQ
    15 from representation import (
    16     PolyhedronRepresentation,
    17     Hrepresentation,
    18     Inequality, Equation,
    19     Vrepresentation,
    20     Vertex, Ray, Line )
    21 
     16from base_ZZ import Polyhedron_ZZ
    2217
    2318
    2419#########################################################################
    25 class Polyhedron_QQ_ppl(Polyhedron_QQ):
     20class Polyhedron_ppl(Polyhedron_base):
    2621    """
    27     Polyhedra over `\QQ` with ppl
     22    Polyhedra with ppl
    2823
    2924    INPUT:
    3025
    31     - ``ambient_dim`` -- integer. The dimension of the ambient space.
    32 
    33     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     26    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    3427       
    35     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     28    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    3629
    3730    EXAMPLES::
    3831
     
    4033        sage: TestSuite(p).run()
    4134    """
    4235
    43     def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, minimize=True):
     36    def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True):
    4437        """
    4538        Construct polyhedron from V-representation data.
    4639
    4740        INPUT:
    4841
    49         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    50        
    5142        - ``vertices`` -- list of point. Each point can be specified
    5243           as any iterable container of
    5344           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    6354        EXAMPLES::
    6455
    6556            sage: p = Polyhedron(backend='ppl')
    66             sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_QQ_ppl
    67             sage: Polyhedron_QQ_ppl._init_from_Vrepresentation(p, 2, [], [], [])
     57            sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl
     58            sage: Polyhedron_ppl._init_from_Vrepresentation(p, [], [], [])
    6859        """
    6960        gs = Generator_System()
    7061        if vertices is None: vertices = []
    7162        for v in vertices:
    72             d = lcm([denominator(v_i) for v_i in v])
    73             dv = [ ZZ(d*v_i) for v_i in v ]
    74             gs.insert(point(Linear_Expression(dv, 0), d))
     63            d = LCM_list([denominator(v_i) for v_i in v])
     64            if d.is_one():
     65                gs.insert(point(Linear_Expression(v, 0)))
     66            else:
     67                dv = [ d*v_i for v_i in v ]
     68                gs.insert(point(Linear_Expression(dv, 0), d))
    7569        if rays is None: rays = []
    7670        for r in rays:
    77             d = lcm([denominator(r_i) for r_i in r])
    78             dr = [ ZZ(d*r_i) for r_i in r ]
    79             gs.insert(ray(Linear_Expression(dr, 0)))
     71            d = LCM_list([denominator(r_i) for r_i in r])
     72            if d.is_one():
     73                gs.insert(ray(Linear_Expression(r, 0)))
     74            else:
     75                dr = [ d*r_i for r_i in r ]
     76                gs.insert(ray(Linear_Expression(dr, 0)))
    8077        if lines is None: lines = []
    8178        for l in lines:
    82             d = lcm([denominator(l_i) for l_i in l])
    83             dl = [ ZZ(d*l_i) for l_i in l ]
    84             gs.insert(line(Linear_Expression(dl, 0)))
    85         self._ppl_polyhedron = C_Polyhedron(gs)
     79            d = LCM_list([denominator(l_i) for l_i in l])
     80            if d.is_one():
     81                gs.insert(line(Linear_Expression(l, 0)))
     82            else:
     83                dl = [ d*l_i for l_i in l ]
     84                gs.insert(line(Linear_Expression(dl, 0)))
     85        if gs.empty():
     86            self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty')
     87        else:
     88            self._ppl_polyhedron = C_Polyhedron(gs)
    8689        self._init_Vrepresentation_from_ppl(minimize)
    8790        self._init_Hrepresentation_from_ppl(minimize)
    8891
    89 
    90     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, minimize=True):
     92    def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True):
    9193        """
    9294        Construct polyhedron from H-representation data.
    9395
    9496        INPUT:
    95 
    96         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    9797       
    9898        - ``ieqs`` -- list of inequalities. Each line can be specified
    9999          as any iterable container of
     
    106106        EXAMPLES::
    107107
    108108            sage: p = Polyhedron(backend='ppl')
    109             sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_QQ_ppl
    110             sage: Polyhedron_QQ_ppl._init_from_Hrepresentation(p, 2, [], [])
     109            sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl
     110            sage: Polyhedron_ppl._init_from_Hrepresentation(p, [], [])
    111111        """
    112112        cs = Constraint_System()
    113113        if ieqs is None: ieqs = []
    114114        for ieq in ieqs:
    115             d = lcm([denominator(ieq_i) for ieq_i in ieq])
     115            d = LCM_list([denominator(ieq_i) for ieq_i in ieq])
    116116            dieq = [ ZZ(d*ieq_i) for ieq_i in ieq ]
    117117            b = dieq[0]
    118118            A = dieq[1:]
    119119            cs.insert(Linear_Expression(A, b) >= 0)
    120120        if eqns is None: eqns = []
    121121        for eqn in eqns:
    122             d = lcm([denominator(eqn_i) for eqn_i in eqn])
     122            d = LCM_list([denominator(eqn_i) for eqn_i in eqn])
    123123            deqn = [ ZZ(d*eqn_i) for eqn_i in eqn ]
    124124            b = deqn[0]
    125125            A = deqn[1:]
    126126            cs.insert(Linear_Expression(A, b) == 0)
    127         self._ppl_polyhedron = C_Polyhedron(cs)
     127        if cs.empty():
     128            self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'universe')
     129        else:
     130            self._ppl_polyhedron = C_Polyhedron(cs)
    128131        self._init_Vrepresentation_from_ppl(minimize)
    129132        self._init_Hrepresentation_from_ppl(minimize)
    130133
    131        
    132134    def _init_Vrepresentation_from_ppl(self, minimize):
    133135        """
    134136        Create the Vrepresentation objects from the ppl polyhedron.
     
    150152        """
    151153        self._Vrepresentation = []
    152154        gs = self._ppl_polyhedron.minimized_generators()
     155        parent = self.parent()
    153156        for g in gs:
    154157            if g.is_point():
    155158                d = g.divisor()
    156                 Vertex(self, [x/d for x in g.coefficients()])
     159                if d.is_one():
     160                    parent._make_Vertex(self, g.coefficients())
     161                else:
     162                    parent._make_Vertex(self, [x/d for x in g.coefficients()])
    157163            elif g.is_ray():
    158                 Ray(self, g.coefficients())
     164                parent._make_Ray(self, g.coefficients())
    159165            elif g.is_line():
    160                 Line(self, g.coefficients())
     166                parent._make_Line(self, g.coefficients())
    161167            else:
    162168                assert False
    163169        self._Vrepresentation = tuple(self._Vrepresentation)
    164        
    165170
    166171    def _init_Hrepresentation_from_ppl(self, minimize):
    167172        """
    168         Create the Vrepresentation objects from the ppl polyhedron.
    169         
     173        Create the Hrepresentation objects from the ppl polyhedron.
     174 
    170175        EXAMPLES::
    171176
    172177            sage: p = Polyhedron(vertices=[(0,1/2),(2,0),(4,5/6)],
     
    184189        """
    185190        self._Hrepresentation = []
    186191        cs = self._ppl_polyhedron.minimized_constraints()
     192        parent = self.parent()
    187193        for c in cs:
    188194            if c.is_inequality():
    189                 Inequality(self, (c.inhomogeneous_term(),) + c.coefficients())
     195                parent._make_Inequality(self, (c.inhomogeneous_term(),) + c.coefficients())
    190196            elif c.is_equality():
    191                 Equation(self, (c.inhomogeneous_term(),) + c.coefficients())
     197                parent._make_Equation(self, (c.inhomogeneous_term(),) + c.coefficients())
    192198        self._Hrepresentation = tuple(self._Hrepresentation)
    193        
    194199
    195     def _init_empty_polyhedron(self, ambient_dim):
     200    def _init_empty_polyhedron(self):
    196201        """
    197202        Initializes an empty polyhedron.
    198203
    199         INPUT:
    200 
    201         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    202 
    203204        TESTS::
    204205
    205206            sage: empty = Polyhedron(backend='ppl'); empty
    206             The empty polyhedron in QQ^0
     207            The empty polyhedron in ZZ^0
    207208            sage: empty.Vrepresentation()
    208209            ()
    209210            sage: empty.Hrepresentation()
    210211            (An equation -1 == 0,)
    211212            sage: Polyhedron(vertices = [], backend='ppl')
    212             The empty polyhedron in QQ^0
    213             sage: Polyhedron(backend='ppl')._init_empty_polyhedron(0)
     213            The empty polyhedron in ZZ^0
     214            sage: Polyhedron(backend='ppl')._init_empty_polyhedron()
    214215        """
    215         super(Polyhedron_QQ_ppl, self)._init_empty_polyhedron(ambient_dim)
    216         self._ppl_polyhedron = C_Polyhedron(ambient_dim, 'empty')
     216        super(Polyhedron_ppl, self)._init_empty_polyhedron()
     217        self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty')
    217218
    218219
     220
     221
     222#########################################################################
     223class Polyhedron_QQ_ppl(Polyhedron_ppl, Polyhedron_QQ):
     224    """
     225    Polyhedra over `\QQ` with ppl
     226
     227    INPUT:
     228
     229    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
     230
     231    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
     232
     233    EXAMPLES::
     234
     235        sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], rays=[(1,1)], lines=[],
     236        ...                  backend='ppl', base_ring=QQ)
     237        sage: TestSuite(p).run(skip='_test_pickling')
     238    """
     239    pass
     240
     241
     242#########################################################################
     243class Polyhedron_ZZ_ppl(Polyhedron_ppl, Polyhedron_ZZ):
     244    """
     245    Polyhedra over `\ZZ` with ppl
     246
     247    INPUT:
     248
     249    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
     250
     251    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
     252
     253    EXAMPLES::
     254
     255        sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], rays=[(1,1)], lines=[])
     256        ...                  backend='ppl', base_ring=ZZ)
     257        sage: TestSuite(p).run(skip='_test_pickling')
     258    """
     259    pass
  • sage/geometry/polyhedron/base.py

    diff --git a/sage/geometry/polyhedron/base.py b/sage/geometry/polyhedron/base.py
    a b  
    1313########################################################################
    1414
    1515
    16 from sage.structure.sage_object import SageObject
     16from sage.structure.element import Element, coerce_binop, is_Vector
    1717
    1818from sage.misc.all import union, cached_method, prod
    1919from sage.misc.package import is_package_installed
     
    3333from sage.groups.perm_gps.permgroup_named import AlternatingGroup
    3434
    3535from constructor import Polyhedron
    36 from representation import (
    37     PolyhedronRepresentation,
    38     Hrepresentation,
    39     Inequality, Equation,
    40     Vrepresentation,
    41     Vertex, Ray, Line )
    4236
    4337
    4438#########################################################################
     
    5549#
    5650#  * You can of course also override any other method for which you
    5751#    have a faster implementation.
     52#########################################################################
    5853
    5954
    6055#########################################################################
     
    8378
    8479
    8580#########################################################################
    86 class Polyhedron_base(SageObject):
     81class Polyhedron_base(Element):
    8782    """
    8883    Base class for Polyhedron objects
    8984
    9085    INPUT:
    9186
    92     - ``ambient_dim`` -- integer. The dimension of the ambient space.
     87    - ``parent`` -- the parent, an instance of
     88      :class:`~sage.geometry.polyhedron.parent.Polyhedra`.
    9389
    9490    - ``Vrep`` -- a list `[vertices, rays, lines]``.
    9591       
     
    10197        sage: TestSuite(p).run()
    10298    """
    10399
    104     def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
     100    def __init__(self, parent, Vrep, Hrep, **kwds):
    105101        """
    106102        Initializes the polyhedron.
    107103
     
    112108
    113109            sage: p = Polyhedron()    # indirect doctests
    114110        """
    115         self._ambient_dim = ambient_dim
     111        Element.__init__(self, parent=parent)
    116112        if Vrep is not None:
    117113            vertices, rays, lines = Vrep
    118             if len(vertices)==0:
    119                 vertices = [[0] * ambient_dim]
    120             self._init_from_Vrepresentation(ambient_dim, vertices, rays, lines, **kwds)
     114            self._init_from_Vrepresentation(vertices, rays, lines, **kwds)
    121115        elif Hrep is not None:
    122116            ieqs, eqns = Hrep
    123             self._init_from_Hrepresentation(ambient_dim, ieqs, eqns, **kwds)
     117            self._init_from_Hrepresentation(ieqs, eqns, **kwds)
    124118        else:
    125             self._init_empty_polyhedron(ambient_dim)
    126 
    127 
    128     def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, **kwds):
     119            self._init_empty_polyhedron()
     120
     121
     122    def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds):
    129123        """
    130124        Construct polyhedron from V-representation data.
    131125
    132126        INPUT:
    133127
    134         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    135        
    136128        - ``vertices`` -- list of point. Each point can be specified
    137129           as any iterable container of
    138130           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    149141
    150142            sage: p = Polyhedron()
    151143            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    152             sage: Polyhedron_base._init_from_Vrepresentation(p, 2, [], [], [])
     144            sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], [])
    153145            Traceback (most recent call last):
    154146            ...
    155147            NotImplementedError: A derived class must implement this method.
     
    157149        raise NotImplementedError('A derived class must implement this method.')
    158150
    159151
    160     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, **kwds):
     152    def _init_from_Hrepresentation(self, ieqs, eqns, **kwds):
    161153        """
    162154        Construct polyhedron from H-representation data.
    163155
    164156        INPUT:
    165157
    166         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    167        
    168158        - ``ieqs`` -- list of inequalities. Each line can be specified
    169159          as any iterable container of
    170160          :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    177167
    178168            sage: p = Polyhedron()
    179169            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    180             sage: Polyhedron_base._init_from_Hrepresentation(p, 2, [], [])
     170            sage: Polyhedron_base._init_from_Hrepresentation(p, [], [])
    181171            Traceback (most recent call last):
    182172            ...
    183173            NotImplementedError: A derived class must implement this method.
    184174        """
    185175        raise NotImplementedError('A derived class must implement this method.')
    186176
    187 
    188     def _init_empty_polyhedron(self, ambient_dim):
     177    def _init_empty_polyhedron(self):
    189178        """
    190179        Initializes an empty polyhedron.
    191180
    192         INPUT:
    193 
    194         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    195 
    196181        TESTS::
    197182
    198183            sage: empty = Polyhedron(); empty
    199             The empty polyhedron in QQ^0
     184            The empty polyhedron in ZZ^0
    200185            sage: empty.Vrepresentation()
    201186            ()
    202187            sage: empty.Hrepresentation()
    203188            (An equation -1 == 0,)
    204189            sage: Polyhedron(vertices = [])
    205             The empty polyhedron in QQ^0
    206             sage: Polyhedron()._init_empty_polyhedron(0)
     190            The empty polyhedron in ZZ^0
     191            sage: Polyhedron(vertices = [])._init_empty_polyhedron()
     192            sage: from sage.geometry.polyhedron.parent import Polyhedra
     193            sage: Polyhedra(QQ,7)()
     194            A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex
    207195        """
    208196        self._Vrepresentation = []
    209197        self._Hrepresentation = []
    210         Equation(self, [-1] + [0]*ambient_dim);
     198        self.parent()._make_Equation(self, [-1] + [0]*self.ambient_dim());
    211199        self._Vrepresentation = tuple(self._Vrepresentation)
    212200        self._Hrepresentation = tuple(self._Hrepresentation)
    213201
    214         self._V_adjacency_matrix = matrix(ZZ, 0, 0, 0)
    215         self._V_adjacency_matrix.set_immutable()
    216 
    217         self._H_adjacency_matrix = matrix(ZZ, 1, 1, 0)
    218         self._H_adjacency_matrix.set_immutable()
    219 
    220 
    221     def _init_facet_adjacency_matrix(self):
     202        V_matrix = matrix(ZZ, 0, 0, 0)
     203        V_matrix.set_immutable()
     204        self.vertex_adjacency_matrix.set_cache(V_matrix)
     205
     206        H_matrix = matrix(ZZ, 1, 1, 0)
     207        H_matrix.set_immutable()
     208        self.facet_adjacency_matrix.set_cache(H_matrix)
     209
     210    def _facet_adjacency_matrix(self):
    222211        """
    223212        Compute the facet adjacency matrix in case it has not been
    224213        computed during initialization.
     
    226215        EXAMPLES::
    227216       
    228217            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
    229             sage: '_H_adjacency_matrix' in p.__dict__
    230             False
    231             sage: p._init_facet_adjacency_matrix()
    232             sage: p._H_adjacency_matrix
     218            sage: p._facet_adjacency_matrix()
    233219            [0 1 1]
    234220            [1 0 1]
    235221            [1 1 0]
     
    250236            Hrep = face.element.ambient_Hrepresentation()
    251237            if len(Hrep) == 2:
    252238                set_adjacent(Hrep[0], Hrep[1])
    253 
    254         self._H_adjacency_matrix = M
    255 
    256 
    257     def _init_vertex_adjacency_matrix(self):
     239        return M
     240
     241    def _vertex_adjacency_matrix(self):
    258242        """
    259243        Compute the vertex adjacency matrix in case it has not been
    260244        computed during initialization.
     
    262246        EXAMPLES::
    263247       
    264248            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
    265             sage: '_V_adjacency_matrix' in p.__dict__
    266             False
    267             sage: p._init_vertex_adjacency_matrix()
    268             sage: p._V_adjacency_matrix
     249            sage: p._vertex_adjacency_matrix()
    269250            [0 1 1]
    270251            [1 0 1]
    271252            [1 1 0]
     
    293274        for r in self.ray_generator():
    294275            for vrep in self.Vrep_generator():
    295276                set_adjacent(r, vrep)
    296                
    297         self._V_adjacency_matrix = M
    298 
    299 
    300     def __lt__(self, other):
     277        return M
     278
     279    def delete(self):
    301280        """
    302         Test whether ``self`` is a strict sub-polyhedron of ``other``.
     281        Delete this polyhedron.
     282
     283        This speeds up creation of new polyhedra by reusing
     284        objects. After recycling a polyhedron object, it is not in a
     285        consistent state any more and neither the polyhedron nor its
     286        H/V-representation objects may be used any more.
     287
     288        .. seealso:: :meth:`~sage.geometry.polyhedron.Polyhedra_base.recycle`
     289
     290
     291        EXAMPLES::
     292
     293            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
     294            sage: p.delete()
     295
     296            sage: def loop_polyhedra():
     297            ...       for i in range(0,100):
     298            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     299
     300            sage: timeit('loop_polyhedra()', repeat=25)                   # random output
     301            5 loops, best of 25: 44.2 ms per loop
     302
     303            sage: def loop_polyhedra_with_recycling():
     304            ...       for i in range(0,100):
     305            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     306            ...           p.delete()
     307
     308            sage: timeit('loop_polyhedra_with_recycling()', repeat=25)    # random output
     309            25 loops, best of 25: 36.3 ms per loop
     310        """
     311        self.parent().recycle(self)
     312        self._Hrepresentation = None
     313        self._Vrepresentation = None
     314
     315    def base_extend(self, base_ring, backend=None):
     316        """
     317        EXAMPLES::
     318
     319            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ);  P
     320            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray
     321            sage: P.base_extend(QQ)
     322            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
     323        """
     324        new_parent = self.parent().base_extend(base_ring, backend)
     325        return new_parent(self)
     326
     327    def __cmp__(self, other):
     328        """
     329        Compare ``self`` and ``other``.
    303330
    304331        INPUT:
    305332
    306         - ``other`` -- a :class:`Polyhedron`.
     333        - ``other`` -- anything.
    307334
    308335        OUTPUT:
    309336
    310         Boolean.
     337        `-1, 0, +1` depending on how ``self`` and ``other``
     338        compare. If ``other`` is a polyhedron, then the comparison
     339        operator "less or equal than" means "is contained in", and
     340        "less than" means "is strictly contained in".
    311341
    312342        EXAMPLES::
    313343
    314344            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    315345            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    316             sage: P < Q   # indirect doctest
     346            sage: cmp(P,Q)
     347            1
     348            sage: cmp(Q,P)
     349            -1
     350            sage: cmp(P,P)
     351            0
     352            sage: cmp(P, 'anything')
     353            -1
     354
     355       The polytope ``Q`` is contained in ``P``::
     356
     357            sage: P > Q
     358            True
     359            sage: P < Q
    317360            False
    318             sage: P < P   # indirect doctest
    319             False
    320             sage: Q < P   # indirect doctest
    321             True
    322         """
    323         return self._is_subpolyhedron(other) and not other._is_subpolyhedron(self)
    324 
    325 
    326     def __le__(self, other):
    327         """
    328         Test whether ``self`` is a (not necessarily strict)
    329         sub-polyhedron of ``other``.
    330 
    331         INPUT:
    332 
    333         - ``other`` -- a :class:`Polyhedron`.
    334 
    335         OUTPUT:
    336 
    337         Boolean.
    338 
    339         EXAMPLES::
    340 
    341             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    342             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    343             sage: P <= Q   # indirect doctest
    344             False
    345             sage: P <= P   # indirect doctest
    346             True
    347             sage: Q <= P   # indirect doctest
    348             True
    349         """
    350         return self._is_subpolyhedron(other)
    351        
    352 
    353     def __eq__(self, other):
    354         """
    355         Test whether ``self`` is a strict sub-polyhedron of ``other``.
    356 
    357         INPUT:
    358 
    359         - ``other`` -- a :class:`Polyhedron`.
    360 
    361         OUTPUT:
    362 
    363         Boolean.
    364 
    365         EXAMPLES::
    366 
    367             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    368             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    369             sage: P == Q   # indirect doctest
    370             False
    371             sage: P == P   # indirect doctest
    372             True
    373             sage: Q == P   # indirect doctest
     361            sage: P == Q
    374362            False
    375363        """
    376         return self._is_subpolyhedron(other) and other._is_subpolyhedron(self)
    377 
    378 
    379     def __ne__(self, other):
    380         """
    381         Test whether ``self`` is not equal to ``other``.
    382 
    383         INPUT:
    384 
    385         - ``other`` -- a :class:`Polyhedron`.
    386 
    387         OUTPUT:
    388 
    389         Boolean.
    390 
    391         EXAMPLES::
    392 
    393             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    394             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    395             sage: P != Q   # indirect doctest
    396             True
    397             sage: P != P   # indirect doctest
    398             False
    399             sage: Q != P   # indirect doctest
    400             True
    401         """
    402         return not self.__eq__(other)
    403 
    404 
    405     def __gt__(self, other):
    406         """
    407         Test whether ``self`` is a strict super-polyhedron of ``other``.
    408 
    409         INPUT:
    410 
    411         - ``other`` -- a :class:`Polyhedron`.
    412 
    413         OUTPUT:
    414 
    415         Boolean.
    416 
    417         EXAMPLES::
    418 
    419             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    420             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    421             sage: P > Q   # indirect doctest
    422             True
    423             sage: P > P   # indirect doctest
    424             False
    425             sage: Q > P   # indirect doctest
    426             False
    427         """
    428         return other._is_subpolyhedron(self) and not self._is_subpolyhedron(other)
    429 
    430 
    431     def __ge__(self, other):
    432         """
    433         Test whether ``self`` is a (not necessarily strict)
    434         super-polyhedron of ``other``.
    435 
    436         INPUT:
    437 
    438         - ``other`` -- a :class:`Polyhedron`.
    439 
    440         OUTPUT:
    441 
    442         Boolean.
    443 
    444         EXAMPLES::
    445 
    446             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    447             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    448             sage: P >= Q   # indirect doctest
    449             True
    450             sage: P >= P   # indirect doctest
    451             True
    452             sage: Q >= P   # indirect doctest
    453             False
    454         """
    455         return other._is_subpolyhedron(self)
    456 
    457 
     364        c = cmp(self.ambient_dim(), other.ambient_dim())
     365        if c != 0: return c
     366        c0 = self._is_subpolyhedron(other)
     367        c1 = other._is_subpolyhedron(self)
     368        if c0 and c1:
     369            return 0
     370        if c0:
     371            return -1
     372        else:
     373            return +1
     374
     375    @coerce_binop
    458376    def _is_subpolyhedron(self, other):
    459377        """
    460378        Test whether ``self`` is a (not necessarily strict)
     
    477395            sage: Q._is_subpolyhedron(P)
    478396            True
    479397        """
    480         if not is_Polyhedron(other):
    481             raise ValueError('Can only compare Polyhedron objects.')
    482398        return all( other_H.contains(self_V)
    483399                    for other_H, self_V in
    484400                    CartesianProduct(other.Hrep_generator(), self.Vrep_generator()) )
    485        
    486401
    487402    def plot(self, **kwds):
    488403        """
     
    513428        raise NotImplementedError('Plotting of '+str(self.ambient_dim())+
    514429                                  '-dimensional polyhedra not implemented')
    515430
    516 
    517431    show = plot
    518432
    519 
    520433    def _repr_(self):
    521434        """
    522435        Return a description of the polyhedron.
     
    525438
    526439            sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]])
    527440            sage: poly_test._repr_()
    528             'A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices'
     441            'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices'
    529442            sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]])
    530443            sage: grammar_test._repr_()
    531             'A 0-dimensional polyhedron in QQ^6 defined as the convex hull of 1 vertex'
     444            'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex'
    532445        """
    533446        desc = ''
    534447        if self.n_vertices()==0:
     
    536449        else:
    537450            desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron'
    538451        desc += ' in '
    539         if self.field()==QQ: desc += 'QQ'
    540         else:                desc += 'RDF'
     452        if   self.base_ring() is QQ:  desc += 'QQ'
     453        elif self.base_ring() is ZZ:  desc += 'ZZ'
     454        elif self.base_ring() is RDF: desc += 'RDF'
     455        else: assert False
    541456        desc += '^' + repr(self.ambient_dim())
    542457
    543458        if self.n_vertices()>0:
     
    562477
    563478        return desc
    564479
    565 
    566480    def cdd_Hrepresentation(self):
    567481        """
    568482        Write the inequalities/equations data of the polyhedron in
     
    590504        try:
    591505            cdd_type = self._cdd_type
    592506        except AttributeError:
    593             ring_to_cdd = { QQ:'rational', RDF:'real' }
    594             cdd_type = ring_to_cdd[self.base_ring()]
     507            if self.base_ring() is ZZ or self.base_ring() is QQ:
     508                cdd_type = 'rational'
     509            elif self.base_ring() is RDF:
     510                cdd_type = 'real'
     511            else:
     512                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    595513        return cdd_Hrepresentation(cdd_type,
    596514                                   list(self.inequality_generator()),
    597515                                   list(self.equation_generator()) )
    598516
    599 
    600517    def cdd_Vrepresentation(self):
    601518        """
    602519        Write the vertices/rays/lines data of the polyhedron in cdd's
     
    624541        try:
    625542            cdd_type = self._cdd_type
    626543        except AttributeError:
    627             ring_to_cdd = { QQ:'rational', RDF:'real' }
    628             cdd_type = ring_to_cdd[self.base_ring()]
     544            if self.base_ring() is ZZ or self.base_ring() is QQ:
     545                cdd_type = 'rational'
     546            elif self.base_ring() is RDF:
     547                cdd_type = 'real'
     548            else:
     549                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    629550        return cdd_Vrepresentation(cdd_type,
    630551                                   list(self.vertex_generator()),
    631552                                   list(self.ray_generator()),
    632553                                   list(self.line_generator()) )
    633554
    634 
     555    @cached_method
    635556    def n_equations(self):
    636557        """
    637558        Return the number of equations. The representation will
     
    644565            sage: p.n_equations()
    645566            1
    646567        """
    647         try:
    648             return self._n_equations
    649         except AttributeError:
    650             self._n_equations = len(self.equations())
    651             return self._n_equations
    652 
    653 
     568        return len(self.equations())
     569
     570    @cached_method
    654571    def n_inequalities(self):
    655572        """
    656573        Return the number of inequalities. The representation will
     
    662579            sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]])
    663580            sage: p.n_inequalities()
    664581            3
    665         """
    666         try:
    667             return self._n_inequalities
    668         except AttributeError:
    669             self._n_inequalities = 0
    670             for i in self.inequalities(): self._n_inequalities += 1
    671             return self._n_inequalities
    672 
    673 
    674     def n_facets(self):
    675         """
    676         Return the number of facets in the polyhedron.  This is the
    677         same as the n_inequalities function.
    678 
    679         EXAMPLES::
    680582
    681583            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)])
    682584            sage: p.n_facets()
    683585            8
    684586        """
    685         return self.n_inequalities()
    686 
    687 
     587        return len(self.inequalities())
     588
     589    n_facets = n_inequalities
     590
     591    @cached_method
    688592    def n_vertices(self):
    689593        """
    690594        Return the number of vertices. The representation will
     
    696600            sage: p.n_vertices()
    697601            2
    698602        """
    699         try:
    700             return self._n_vertices
    701         except AttributeError:
    702             self._n_vertices = 0
    703             for v in self.vertex_generator(): self._n_vertices += 1
    704             return self._n_vertices
    705 
    706 
     603        return len(self.vertices())
     604
     605    @cached_method
    707606    def n_rays(self):
    708607        """
    709608        Return the number of rays. The representation will
     
    715614            sage: p.n_rays()
    716615            1
    717616        """
    718         try:
    719             return self._n_rays
    720         except AttributeError:
    721             self._n_rays = 0
    722             for r in self.rays(): self._n_rays += 1
    723             return self._n_rays
    724 
    725 
     617        return len(self.rays())
     618
     619    @cached_method
    726620    def n_lines(self):
    727621        """
    728622        Return the number of lines. The representation will
     
    734628            sage: p.n_lines()
    735629            1
    736630        """
    737         try:
    738             return self._n_lines
    739         except AttributeError:
    740             self._n_lines = len(self.lines())
    741             return self._n_lines
    742 
     631        return len(self.lines())
    743632
    744633    def Hrepresentation(self, index=None):
    745634        """
     
    765654            sage: p.Hrepresentation(0) == p.Hrepresentation() [0]
    766655            True
    767656        """
    768         if index==None:
     657        if index is None:
    769658            return self._Hrepresentation
    770659        else:
    771660            return self._Hrepresentation[index]
     
    785674        for H in self.Hrepresentation():
    786675            yield H
    787676
    788 
     677    @cached_method
    789678    def n_Hrepresentation(self):
    790679        """
    791680        Return the number of objects that make up the
     
    805694        """
    806695        return len(self.Hrepresentation())
    807696
    808 
    809697    def Vrepresentation(self, index=None):
    810698        """
    811699        Return the objects of the V-representation. Each entry is
     
    830718            sage: p.Vrepresentation(0) == p.Vrepresentation() [0]
    831719            True
    832720        """
    833         if index==None:
     721        if index is None:
    834722            return self._Vrepresentation
    835723        else:
    836724            return self._Vrepresentation[index]
    837725
    838 
     726    @cached_method
    839727    def n_Vrepresentation(self):
    840728        """
    841729        Return the number of objects that make up the
     
    855743        """
    856744        return len(self.Vrepresentation())
    857745
    858 
    859746    def Vrep_generator(self):
    860747        """
    861748        Returns an iterator over the objects of the V-representation
     
    873760        for V in self.Vrepresentation():
    874761            yield V
    875762
    876 
    877763    def facial_adjacencies(self):
    878         """
     764        r"""
    879765        Return the list of face indices (i.e. indices of
    880766        H-representation objects) and the indices of faces adjacent to
    881767        them.
     
    890776
    891777            sage: p = polytopes.permutahedron(4)
    892778            sage: p.facial_adjacencies()[0:3]
     779            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is deprecated.
     780            Use self.Hrepresentation(i).neighbors() instead.
    893781            [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]]
    894782            sage: f0 = p.Hrepresentation(0)
    895783            sage: f0.index() == 0
     
    898786            sage: p.facial_adjacencies()[0] == f0_adjacencies
    899787            True
    900788        """
     789        from sage.misc.misc import deprecation
     790        deprecation('This method is deprecated. Use self.Hrepresentation(i).neighbors() instead.',
     791                    'Sage Version 4.7.2')
    901792        try:
    902793            return self._facial_adjacencies
    903794        except AttributeError:
     
    907798                  ] for h in self.Hrepresentation() ]
    908799            return self._facial_adjacencies
    909800
    910 
    911801    def facial_incidences(self):
    912802        """
    913803        Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`.
     
    929819
    930820            sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]])
    931821            sage: p.facial_incidences()
     822            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     823            deprecated. Use self.Hrepresentation(i).incident() instead.
    932824            [[0, [0, 1, 3, 4]],
    933825             [1, [0, 1, 2]],
    934826             [2, [0, 2, 3]],
     
    953845            sage: p.incidence_matrix().column(4)
    954846            (0, 1, 1, 0, 1)
    955847        """
     848        from sage.misc.misc import deprecation
     849        deprecation('This method is deprecated. Use self.Hrepresentation(i).incident() instead.',
     850                    'Sage Version 4.7.2')
    956851        try:
    957852            return self._facial_incidences
    958853        except AttributeError:
     
    962857                  ] for h in self.Hrepresentation() ]
    963858            return self._facial_incidences
    964859
    965 
    966860    def vertex_adjacencies(self):
    967861        """
    968862        Return a list of vertex indices and their adjacent vertices.
     
    981875
    982876            sage: permuta3 = Polyhedron(vertices = permutations([1,2,3,4]))
    983877            sage: permuta3.vertex_adjacencies()[0:3]
     878            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     879            deprecated. Use self.Vrepresentation(i).neighbors() instead.
    984880            [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]]
    985881            sage: v0 = permuta3.Vrepresentation(0)
    986882            sage: v0.index() == 0
     
    991887            sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies
    992888            True
    993889        """
     890        from sage.misc.misc import deprecation
     891        deprecation('This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.',
     892                    'Sage Version 4.7.2')
    994893        try:
    995894            return self._vertex_adjacencies
    996895        except AttributeError:
     
    1000899                  ] for v in self.Vrepresentation() ]
    1001900            return self._vertex_adjacencies
    1002901
    1003 
    1004902    def vertex_incidences(self):
    1005903        """
    1006904        Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`.
     
    1015913
    1016914            sage: p = polytopes.n_simplex(3)
    1017915            sage: p.vertex_incidences()
     916            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     917            deprecated. Use self.Vrepresentation(i).incident() instead.
    1018918            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    1019919            sage: v0 = p.Vrepresentation(0)
    1020920            sage: v0.index() == 0
     
    1022922            sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ]
    1023923            True
    1024924        """
     925        from sage.misc.misc import deprecation
     926        deprecation('This method is deprecated. Use self.Vrepresentation(i).incident() instead.',
     927                    'Sage Version 4.7.2')
    1025928        try:
    1026929            return self._vertex_incidences
    1027930        except AttributeError:
     
    1031934                  ] for v in self.Vrepresentation() ]
    1032935            return self._vertex_incidences
    1033936
    1034 
    1035937    def inequality_generator(self):
    1036938        """
    1037939        Return  a generator for the defining inequalities of the
     
    1059961            if H.is_inequality():
    1060962                yield H
    1061963
    1062 
     964    @cached_method
    1063965    def inequalities(self):
    1064966        """
     967        Return all inequalities.
     968
     969        OUTPUT:
     970
     971        A tuple of inequalities.
     972
     973        EXAMPLES::
     974
     975            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
     976            sage: p.inequalities()[0:3]
     977            (An inequality (1, 0, 0) x + 0 >= 0,
     978             An inequality (0, 1, 0) x + 0 >= 0,
     979             An inequality (0, 0, 1) x + 0 >= 0)
     980            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
     981            sage: ieqs = p3.inequalities()
     982            sage: ieqs[0]
     983            An inequality (0, 1, 1, 1) x - 6 >= 0
     984            sage: list(_)
     985            [-6, 0, 1, 1, 1]
     986        """
     987        return tuple(self.inequality_generator())
     988
     989    def inequalities_list(self):
     990        """
    1065991        Return a list of inequalities as coefficient lists.
    1066992
    1067993        .. NOTE::
    1068994       
    1069             It is recommended to use :meth:`inequality_generator`
    1070             instead to iterate over the list of :class:`Inequality`
    1071             objects.
     995            It is recommended to use :meth:`inequalities` or
     996            :meth:`inequality_generator` instead to iterate over the
     997            list of :class:`Inequality` objects.
    1072998
    1073999        EXAMPLES::
    10741000
    10751001            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
    1076             sage: p.inequalities()[0:3]
     1002            sage: p.inequalities_list()[0:3]
    10771003            [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    10781004            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    1079             sage: ieqs = p3.inequalities()
     1005            sage: ieqs = p3.inequalities_list()
    10801006            sage: ieqs[0]
    10811007            [-6, 0, 1, 1, 1]
    10821008            sage: ieqs[-1]
     
    10841010            sage: ieqs == [list(x) for x in p3.inequality_generator()]
    10851011            True
    10861012        """
    1087         try:
    1088             return self._inequalities
    1089         except AttributeError:
    1090             self._ieqs = [list(x) for x in self.inequality_generator()]
    1091             return self._ieqs
    1092 
     1013        return [list(x) for x in self.inequality_generator()]
    10931014
    10941015    def ieqs(self):
    10951016        """
     
    10991020         
    11001021            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    11011022            sage: p3.ieqs() == p3.inequalities()
     1023            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1024            deprecated. Use inequalities() instead.
    11021025            True
    11031026        """
     1027        from sage.misc.misc import deprecation
     1028        deprecation('This method is deprecated. Use inequalities() instead.',
     1029                    'Sage Version 4.7.2')
    11041030        return self.inequalities()
    11051031
    1106 
    11071032    def equation_generator(self):
    11081033        """
    11091034        Return a generator for the linear equations satisfied by the
     
    11201045            if H.is_equation():
    11211046                yield H
    11221047
    1123 
     1048    @cached_method
    11241049    def equations(self):
    11251050        """
     1051        Return all linear constraints of the polyhedron.
     1052
     1053        OUTPUT:
     1054
     1055        A tuple of equations.
     1056
     1057        EXAMPLES::
     1058
     1059            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
     1060            sage: test_p.equations()
     1061            (An equation (1, 1, 1, 1) x - 10 == 0,)
     1062        """
     1063        return tuple(self.equation_generator())
     1064
     1065    def equations_list(self):
     1066        """
    11261067        Return the linear constraints of the polyhedron. As with
    11271068        inequalities, each constraint is given as [b -a1 -a2 ... an]
    11281069        where for variables x1, x2,..., xn, the polyhedron satisfies
     
    11301071
    11311072        .. NOTE::
    11321073       
    1133             It is recommended to use :meth:`equation_generator()` instead
    1134             to iterate over the list of :class:`Equation` objects.
     1074            It is recommended to use :meth:`equations` or
     1075            :meth:`equation_generator()` instead to iterate over the
     1076            list of
     1077            :class:`~sage.geometry.polyhedron.representation.Equation`
     1078            objects.
    11351079
    11361080        EXAMPLES::
    11371081
    11381082            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    1139             sage: test_p.equations()
     1083            sage: test_p.equations_list()
    11401084            [[-10, 1, 1, 1, 1]]
    11411085        """
    1142         try:
    1143             return self._equations
    1144         except:
    1145             self._equations = [list(eq) for eq in self.equation_generator()]
    1146             return self._equations
    1147 
     1086        return [list(eq) for eq in self.equation_generator()]
    11481087
    11491088    def linearities(self):
    11501089        """
     
    11581097
    11591098            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    11601099            sage: test_p.linearities()
     1100            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1101            deprecated. Use equations_list() instead.
    11611102            [[-10, 1, 1, 1, 1]]
    1162             sage: test_p.linearities() == test_p.equations()
     1103            sage: test_p.linearities() == test_p.equations_list()
    11631104            True
    11641105        """
    1165         return self.equations()
    1166 
    1167 
    1168     def vertices(self):
     1106        from sage.misc.misc import deprecation
     1107        deprecation('This method is deprecated. Use equations_list() instead.',
     1108                    'Sage Version 4.7.2')
     1109        return self.equations_list()
     1110
     1111    def vertices_list(self):
    11691112        """
    11701113        Return a list of vertices of the polyhedron.
    11711114
     
    11771120        EXAMPLES::
    11781121
    11791122            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
    1180             sage: triangle.vertices()
     1123            sage: triangle.vertices_list()
    11811124            [[0, 1], [1, 0], [1, 1]]
    11821125            sage: a_simplex = Polyhedron(ieqs = [
    11831126            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
    11841127            ...        ], eqns = [[1,-1,-1,-1,-1]])
    1185             sage: a_simplex.vertices()
     1128            sage: a_simplex.vertices_list()
    11861129            [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    1187             sage: a_simplex.vertices() == [list(v) for v in a_simplex.vertex_generator()]
     1130            sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()]
    11881131            True
    11891132        """
    1190         try:
    1191             return self._vertices
    1192         except:
    1193             self._vertices = [list(x) for x in self.vertex_generator()]
    1194             return self._vertices
    1195 
     1133        return [list(x) for x in self.vertex_generator()]
    11961134       
    11971135    def vertex_generator(self):
    11981136        """
     
    12231161        for V in self.Vrepresentation():
    12241162            if V.is_vertex():
    12251163                yield V
     1164
     1165    @cached_method
     1166    def vertices(self):
     1167        """
     1168        Return all vertices of the polyhedron.
     1169
     1170        OUTPUT:
     1171
     1172        A tuple of vertices.
     1173
     1174        EXAMPLES::
     1175
     1176            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1177            sage: triangle.vertices()
     1178            (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1))
     1179            sage: a_simplex = Polyhedron(ieqs = [
     1180            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
     1181            ...        ], eqns = [[1,-1,-1,-1,-1]])
     1182            sage: a_simplex.vertices()
     1183            (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0),
     1184             A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1))
     1185        """
     1186        return tuple(self.vertex_generator())
     1187
     1188    @cached_method
     1189    def vertices_matrix(self, base_ring=None):
     1190        """
     1191        Return the coordinates of the vertices as the columns of a matrix.
     1192
     1193        INPUT:
    12261194       
     1195        - ``base_ring`` -- A ring or ``None`` (default). The base ring
     1196          of the returned matrix. If not specified, the base ring of
     1197          the polyhedron is used.
     1198
     1199        OUTPUT:
     1200
     1201        A matrix over ``base_ring`` whose columns are the coordinates
     1202        of the vertices. A ``TypeError`` is raised if the coordinates
     1203        cannot be converted to ``base_ring``.
     1204
     1205        EXAMPLES::
     1206
     1207            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1208            sage: triangle.vertices_matrix()
     1209            [0 1 1]
     1210            [1 0 1]
     1211            sage: (triangle/2).vertices_matrix()
     1212            [  0 1/2 1/2]
     1213            [1/2   0 1/2]
     1214            sage: (triangle/2).vertices_matrix(ZZ)
     1215            Traceback (most recent call last):
     1216            ...
     1217            TypeError: no conversion of this rational to integer
     1218        """
     1219        if base_ring is None:
     1220            base_ring = self.base_ring()
     1221        m = matrix(base_ring, self.ambient_dim(), self.n_vertices())
     1222        for i,v in enumerate(self.vertices()):
     1223            for j in range(0,self.ambient_dim()):
     1224                m[j,i] = v[j]
     1225        return m
    12271226
    12281227    def ray_generator(self):
    12291228        """
     
    12401239            if V.is_ray():
    12411240                yield V
    12421241
    1243 
     1242    @cached_method
    12441243    def rays(self):
    12451244        """
    12461245        Return a list of rays as coefficient lists.
    12471246
     1247        OUTPUT:
     1248
     1249        A tuple of rays.
     1250
     1251        EXAMPLES::
     1252
     1253            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
     1254            sage: p.rays()
     1255            (A ray in the direction (1, 0, 0),
     1256             A ray in the direction (0, 1, 0),
     1257             A ray in the direction (0, 0, 1))
     1258        """
     1259        return tuple(self.ray_generator())
     1260
     1261    def rays_list(self):
     1262        """
     1263        Return a list of rays as coefficient lists.
     1264
    12481265        .. NOTE::
    12491266       
    1250             It is recommended to use :meth:`ray_generator` instead to
    1251             iterate over the list of :class:`Ray` objects.
     1267            It is recommended to use :meth:`rays` or
     1268            :meth:`ray_generator` instead to iterate over the list of
     1269            :class:`Ray` objects.
    12521270
    12531271        OUTPUT:
    12541272
     
    12571275        EXAMPLES::
    12581276
    12591277            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
    1260             sage: p.rays()
     1278            sage: p.rays_list()
    12611279            [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    1262             sage: p.rays() == [list(r) for r in p.ray_generator()]
     1280            sage: p.rays_list() == [list(r) for r in p.ray_generator()]
    12631281            True
    12641282        """
    1265         try:
    1266             return self._rays
    1267         except:
    1268             self._rays = [list(x) for x in self.ray_generator()]
    1269             return self._rays
    1270 
     1283        return [list(x) for x in self.ray_generator()]
    12711284
    12721285    def line_generator(self):
    12731286        """
     
    12831296            if V.is_line():
    12841297                yield V
    12851298
    1286 
     1299    @cached_method
    12871300    def lines(self):
    12881301        """
     1302        Return all lines of the polyhedron.
     1303
     1304        OUTPUT:
     1305
     1306        A tuple of lines.
     1307
     1308        EXAMPLES::
     1309
     1310            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
     1311            sage: p.lines()
     1312            (A line in the direction (1, 0),)
     1313        """
     1314        return tuple(self.line_generator())
     1315
     1316    def lines_list(self):
     1317        """
    12891318        Return a list of lines of the polyhedron.  The line data is given
    12901319        as a list of coordinates rather than as a Hrepresentation object.
    12911320
     
    12971326        EXAMPLES::
    12981327
    12991328            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
    1300             sage: p.lines()
     1329            sage: p.lines_list()
    13011330            [[1, 0]]
    1302             sage: p.lines() == [list(x) for x in p.line_generator()]
     1331            sage: p.lines_list() == [list(x) for x in p.line_generator()]
    13031332            True
    13041333        """
    1305         try:
    1306             return self._lines
    1307         except:
    1308             self._lines = [list(x) for x in self.line_generator()]
    1309             return self._lines
    1310 
     1334        return [list(x) for x in self.line_generator()]
    13111335               
    13121336    def bounded_edges(self):
    13131337        """
     
    13341358                if self.vertex_adjacency_matrix()[i,j] == 0: continue
    13351359                yield (obj[i], obj[j])
    13361360
    1337 
    1338     @cached_method
    1339     def ambient_space(self):
     1361    def Vrepresentation_space(self):
    13401362        r"""
    13411363        Return the ambient vector space.
    13421364       
     
    13471369        EXAMPLES::
    13481370
    13491371            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1350             sage: poly_test.ambient_space()
    1351             Vector space of dimension 4 over Rational Field
     1372            sage: poly_test.Vrepresentation_space()
     1373            Ambient free module of rank 4 over the principal ideal domain Integer Ring
     1374            sage: poly_test.ambient_space() is poly_test.Vrepresentation_space()
     1375            True
    13521376        """
    1353         from sage.modules.free_module import VectorSpace
    1354         return VectorSpace(self.base_ring(), self.ambient_dim())
    1355 
    1356     Vrepresentation_space = ambient_space
    1357 
    1358     @cached_method
     1377        return self.parent().Vrepresentation_space()
     1378
     1379    ambient_space = Vrepresentation_space
     1380
    13591381    def Hrepresentation_space(self):
    13601382        r"""
    13611383        Return the linear space containing the H-representation vectors.
     
    13671389        EXAMPLES::
    13681390       
    13691391            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1370             sage: poly_test.ambient_space()
    1371             Vector space of dimension 4 over Rational Field
     1392            sage: poly_test.Hrepresentation_space()
     1393            Ambient free module of rank 5 over the principal ideal domain Integer Ring
    13721394        """
    1373         from sage.modules.free_module import VectorSpace
    1374         return VectorSpace(self.base_ring(), self.ambient_dim()+1)
    1375 
     1395        return self.parent().Hrepresentation_space()
    13761396
    13771397    def ambient_dim(self):
    13781398        r"""
     
    13841404            sage: poly_test.ambient_dim()
    13851405            4
    13861406        """
    1387         return self._ambient_dim
    1388 
     1407        return self.parent().ambient_dim()
    13891408           
    13901409    def dim(self):
    13911410        """
     
    14011420       """
    14021421        return self.ambient_dim() - self.n_equations()
    14031422
    1404 
    1405     def adjacency_matrix(self):
    1406         """
    1407         This is an alias for :meth:`vertex_adjacency_matrix`
    1408 
    1409         EXAMPLES::
    1410 
    1411             sage: polytopes.n_cube(3).adjacency_matrix()
    1412             [0 1 1 0 1 0 0 0]
    1413             [1 0 0 1 0 1 0 0]
    1414             [1 0 0 1 0 0 1 0]
    1415             [0 1 1 0 0 0 0 1]
    1416             [1 0 0 0 0 1 1 0]
    1417             [0 1 0 0 1 0 0 1]
    1418             [0 0 1 0 1 0 0 1]
    1419             [0 0 0 1 0 1 1 0]
    1420         """
    1421         return self.vertex_adjacency_matrix()
    1422 
    1423 
     1423    @cached_method
    14241424    def vertex_adjacency_matrix(self):
    14251425        """
    14261426        Return the binary matrix of vertex adjacencies.
     
    14341434            [1 1 1 0 1]
    14351435            [1 1 1 1 0]
    14361436        """
    1437         if '_V_adjacency_matrix' not in self.__dict__:
    1438             self._init_vertex_adjacency_matrix()
    1439         return self._V_adjacency_matrix;
    1440 
    1441 
     1437        return self._vertex_adjacency_matrix()
     1438
     1439    adjacency_matrix = vertex_adjacency_matrix
     1440
     1441    @cached_method
    14421442    def facet_adjacency_matrix(self):
    14431443        """
    14441444        Return the adjacency matrix for the facets and hyperplanes.
     
    14521452            [1 1 1 0 1]
    14531453            [1 1 1 1 0]
    14541454        """
    1455         if '_H_adjacency_matrix' not in self.__dict__:
    1456             self._init_facet_adjacency_matrix()
    1457         return self._H_adjacency_matrix;
    1458 
    1459 
     1455        return self._facet_adjacency_matrix()
     1456
     1457    @cached_method
    14601458    def incidence_matrix(self):
    14611459        """
    14621460        Return the incidence matrix.
     
    15011499            sage: p.incidence_matrix() [2,0]   # note: not symmetric
    15021500            0
    15031501        """
    1504         try:
    1505             return self._incidence_matrix
    1506         except AttributeError:
    1507             self._incidence_matrix = matrix(ZZ, len(self.Vrepresentation()),
    1508                                                 len(self.Hrepresentation()), 0)
    1509             for V in self.Vrep_generator():
    1510                 for H in self.Hrep_generator():
    1511                     if self._is_zero(H*V):
    1512                         self._incidence_matrix[V.index(),H.index()] = 1
    1513 
    1514             return self._incidence_matrix
    1515 
     1502        incidence_matrix = matrix(ZZ, self.n_Vrepresentation(),
     1503                                  self.n_Hrepresentation(), 0)
     1504        for V in self.Vrep_generator():
     1505            for H in self.Hrep_generator():
     1506                if self._is_zero(H*V):
     1507                    incidence_matrix[V.index(),H.index()] = 1
     1508        return incidence_matrix
    15161509
    15171510    def base_ring(self):
    15181511        """
     
    15261519        EXAMPLES::
    15271520
    15281521            sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]])
    1529             sage: triangle.base_ring() == QQ
     1522            sage: triangle.base_ring() == ZZ
    15301523            True
    15311524        """
    1532         return self._base_ring
     1525        return self.parent().base_ring()
    15331526
    15341527    field = base_ring
    15351528
    1536 
    1537     def coerce_field(self, other):
    1538         """
    1539         Return the common field for both ``self`` and ``other``.
    1540 
    1541         INPUT:
    1542 
    1543         - ``other`` -- must be either:
    1544        
    1545             * another ``Polyhedron`` object
    1546        
    1547             * `\QQ` or `RDF`
    1548        
    1549             * a constant that can be coerced to `\QQ` or `RDF`
    1550 
    1551         OUTPUT:
    1552 
    1553         Either `\QQ` or `RDF`. Raises ``TypeError`` if ``other`` is not a
    1554         suitable input.
    1555 
    1556         .. NOTE::
    1557        
    1558             "Real" numbers in sage are not necessarily elements of
    1559             `RDF`. For example, the literal `1.0` is not.
    1560 
    1561         EXAMPLES::
    1562 
    1563             sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ)
    1564             sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF)
    1565             sage: triangle_QQ.coerce_field(QQ)
    1566             Rational Field
    1567             sage: triangle_QQ.coerce_field(triangle_RDF)
    1568             Real Double Field
    1569             sage: triangle_RDF.coerce_field(triangle_QQ)
    1570             Real Double Field
    1571             sage: triangle_QQ.coerce_field(RDF)
    1572             Real Double Field
    1573             sage: triangle_QQ.coerce_field(ZZ)
    1574             Rational Field
    1575             sage: triangle_QQ.coerce_field(1/2)
    1576             Rational Field
    1577             sage: triangle_QQ.coerce_field(0.5)
    1578             Real Double Field
    1579         """
    1580         try:
    1581             # other is a Polyhedron object?
    1582             other_field = other.field()
    1583         except AttributeError:
    1584 
    1585             try:
    1586                 # other is a constant?
    1587                 other_parent = other.parent()
    1588             except AttributeError:
    1589                 other_parent = other
    1590 
    1591             # other is a field?
    1592             if QQ.coerce_map_from(other_parent) != None:
    1593                 other_field = QQ
    1594             elif RDF.coerce_map_from(other_parent) != None:
    1595                 other_field = RDF
    1596             else:
    1597                 raise TypeError("cannot determine field from %s!" % other)
    1598 
    1599         assert other_field==QQ or other_field==RDF
    1600            
    1601         if self.field()==RDF or other_field==RDF:
    1602             return RDF
    1603         else:
    1604             return QQ
    1605 
    1606 
    16071529    @cached_method
    16081530    def center(self):
    16091531        """
     
    16671589        """
    16681590        return sqrt(self.radius_square())
    16691591
    1670 
    16711592    def is_compact(self):
    16721593        """
    16731594        Test for boundedness of the polytope.
     
    16831604        """
    16841605        return self.n_rays()==0 and self.n_lines()==0
    16851606
    1686 
    16871607    def is_simple(self):
    16881608        """
    16891609        Test for simplicity of a polytope.
     
    17071627            adj = [a for a in v.neighbors()]
    17081628            if len(adj) != self.dim():
    17091629                return False
    1710 
    17111630        return True
    17121631
     1632    @cached_method
    17131633    def gale_transform(self):
    17141634        """
    17151635        Return the Gale transform of a polytope as described in the
     
    17371657        if not self.is_compact(): raise ValueError('Not a polytope.')
    17381658
    17391659        A = matrix(self.n_vertices(),
    1740                    [ [1]+list(x) for x in self.vertex_generator()])
     1660                   [ [1]+x for x in self.vertex_generator()])
    17411661        A = A.transpose()
    17421662        A_ker = A.right_kernel()
    17431663        return A_ker.basis_matrix().transpose().rows()
     
    18071727            [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1),
    18081728             A vertex at (-1, 1, -1), A vertex at (1, 1, 1)]
    18091729            sage: Polyhedron(simplex_vertices)
    1810             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     1730            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
    18111731        """
    18121732        if not self.is_compact():
    18131733            raise NotImplementedError('I can only triangulate compact polytopes.')
     
    18381758            ...             ).triangulated_facial_incidences()
    18391759            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18401760            This method is deprecated. Use triangulate() instead.
     1761            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1762            This method is deprecated. Use self.Hrepresentation(i).incident() instead.
    18411763            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    18421764                             
    18431765        Otherwise some faces get split up to triangles::
     
    18461768            ...       [1,1,0],[0,0,1]]).triangulated_facial_incidences()
    18471769            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18481770            This method is deprecated. Use triangulate() instead.
     1771            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1772            This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.
    18491773            [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]],
    18501774             [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]]
    18511775        """
     
    19001824        self._triangulated_facial_incidences = t_fac_incs
    19011825        return t_fac_incs
    19021826
    1903 
    19041827    def simplicial_complex(self):
    19051828        """
    19061829        Return a simplicial complex from a triangulation of the polytope.
     
    19311854        return SimplicialComplex(vertex_set = self.n_vertices(),
    19321855                                 maximal_faces = [x[1] for x in self.triangulated_facial_incidences()])
    19331856
    1934     def __add__(self, other):
     1857    @coerce_binop
     1858    def Minkowski_sum(self, other):
    19351859        """
     1860        Return the Minkowski sum.
     1861
     1862        INPUT:
     1863
     1864        - ``other`` -- a :class:`Polyhedron_base`.
     1865
     1866        OUTPUT:
     1867
    19361868        The Minkowski sum of ``self`` and ``other``.
    19371869
    1938         INPUT:
    1939 
    1940         - ``other`` -- a :class:`Polyhedron`.
    1941 
    19421870        EXAMPLES::
    19431871
    19441872            sage: four_cube = polytopes.n_cube(4)
    19451873            sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
    1946             sage: unholy_union = four_cube + four_simplex
    1947             sage: unholy_union.dim()
    1948             4
    1949             sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]])
    1950             sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]])
    1951             sage: poly_spam_and_eggs = poly_spam + poly_spam + poly_eggs
    1952             sage: poly_spam_and_eggs.n_vertices()
    1953             12
     1874            sage: four_cube + four_simplex
     1875            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 36 vertices
     1876            sage: four_cube.Minkowski_sum(four_simplex) == four_cube + four_simplex
     1877            True
     1878
     1879            sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]], base_ring=ZZ)
     1880            sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ)
     1881            sage: poly_spam + poly_spam + poly_eggs
     1882            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 12 vertices
    19541883        """
    1955         if is_Polyhedron(other):
    1956             new_vertices = []
    1957             for v1 in self.vertex_generator():
    1958                 for v2 in other.vertex_generator():
    1959                     new_vertices.append(list(v1() + v2()))
     1884        new_vertices = []
     1885        for v1 in self.vertex_generator():
     1886            for v2 in other.vertex_generator():
     1887                new_vertices.append(list(v1() + v2()))
     1888        if new_vertices != []:
    19601889            new_rays = self.rays() + other.rays()
    19611890            new_lines = self.lines() + other.lines()
    1962             other_field = other.field()
    1963 
    1964         else:  # assume other is a vector and try to add vertices
    1965             displacement = vector(other)
    1966             new_vertices = [list(x() + displacement) for x in self.vertex_generator()]
    1967             new_rays = self.rays()
    1968             new_lines = self.lines()
    1969             other_field = displacement.base_ring()
    1970 
     1891            return self.parent().element_class(self.parent(), [new_vertices, new_rays, new_lines], None)
     1892        else:
     1893            return self.parent().element_class(self.parent(), None, None)
     1894
     1895    _add_ = Minkowski_sum
     1896
     1897    def translation(self, displacement):
     1898        """
     1899        Return the translated polyhedron.
     1900
     1901        INPUT:
     1902
     1903        - ``displacement`` -- a displacement vector or a list/tuple of
     1904          coordinates that determines a displacement vector.
     1905
     1906        OUTPUT:
     1907
     1908        The translated polyhedron.
     1909
     1910        EXAMPLES::
     1911
     1912            sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ)
     1913            sage: P.translation([2,1])
     1914            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
     1915            sage: P.translation( vector(QQ,[2,1]) )
     1916            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     1917        """
     1918        displacement = vector(displacement)
     1919        new_vertices = [x.vector()+displacement for x in self.vertex_generator()]
     1920        new_rays = self.rays()
     1921        new_lines = self.lines()
     1922        new_ring = self.parent()._coerce_base_ring(displacement.base_ring())
     1923        return Polyhedron(vertices=new_vertices, rays=new_rays, lines=new_lines, base_ring=new_ring)
     1924
     1925    @coerce_binop
     1926    def product(self, other):
     1927        """
     1928        Return the cartesian product.
     1929
     1930        INPUT:
     1931
     1932        - ``other`` -- a :class:`Polyhedron_base`.
     1933
     1934        OUTPUT:
     1935
     1936        The cartesian product of ``self`` and ``other`` with a
     1937        suitable base ring to encompass the two.
     1938
     1939        EXAMPLES::
     1940
     1941            sage: P1 = Polyhedron([[0],[1]], base_ring=ZZ)
     1942            sage: P2 = Polyhedron([[0],[1]], base_ring=QQ)
     1943            sage: P1.product(P2)
     1944            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1945
     1946        The cartesian product is the product in the semiring of polyhedra::
     1947
     1948            sage: P1 * P1
     1949            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     1950            sage: P1 * P2
     1951            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1952            sage: P2 * P2
     1953            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1954            sage: 2 * P1
     1955            A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices
     1956            sage: P1 * 2.0
     1957            A 1-dimensional polyhedron in RDF^1 defined as the convex hull of 2 vertices
     1958        """
     1959        new_vertices = [ list(x)+list(y)
     1960                         for x in self.vertex_generator() for y in other.vertex_generator()]
     1961        new_rays = []
     1962        new_rays.extend( [ r+[0]*other.ambient_dim()
     1963                           for r in self.ray_generator() ] )
     1964        new_rays.extend( [ [0]*self.ambient_dim()+r
     1965                           for r in other.ray_generator() ] )
     1966        new_lines = []
     1967        new_lines.extend( [ l+[0]*other.ambient_dim()
     1968                            for l in self.line_generator() ] )
     1969        new_lines.extend( [ [0]*self.ambient_dim()+l
     1970                            for l in other.line_generator() ] )
    19711971        return Polyhedron(vertices=new_vertices,
    19721972                          rays=new_rays, lines=new_lines,
    1973                           base_ring=self.coerce_field(other_field))
    1974            
    1975 
    1976     def __mul__(self, other):
     1973                          base_ring=self.parent()._coerce_base_ring(other))
     1974
     1975    _mul_ = product
     1976
     1977    def dilation(self, scalar):
    19771978        """
    1978         Multiplication by ``other``.
     1979        Return the dilated (uniformly stretched) polyhedron.
    19791980
    19801981        INPUT:
    19811982
    1982         - ``other`` -- A scalar, not necessarily in :meth:`field`, or
    1983           a :class:`Polyhedron`.
     1983        - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring`,
     1984          or a :class:`Polyhedron`.
    19841985
    19851986        OUTPUT:
    19861987
     
    19931994             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
    19941995             sage: p.vertex_generator().next()
    19951996             A vertex at (2, 4, 8)
    1996              sage: p2 = p*2
     1997             sage: p2 = p.dilation(2)
    19971998             sage: p2.vertex_generator().next()
    19981999             A vertex at (4, 8, 16)
     2000             sage: p.dilation(2) == p * 2
     2001             True
    19992002        """
    2000         if is_Polyhedron(other):
    2001             new_vertices = [ list(x)+list(y)
    2002                              for x in self.vertex_generator() for y in other.vertex_generator()]
    2003             new_rays = []
    2004             new_rays.extend( [ list(r)+[0]*other.ambient_dim()
    2005                                for r in self.ray_generator() ] )
    2006             new_rays.extend( [ [0]*self.ambient_dim()+list(r)
    2007                                for r in other.ray_generator() ] )
    2008             new_lines = []
    2009             new_lines.extend( [ list(l)+[0]*other.ambient_dim()
    2010                                 for l in self.line_generator() ] )
    2011             new_lines.extend( [ [0]*self.ambient_dim()+list(l)
    2012                                for l in other.line_generator() ] )
    2013         else:
    2014             new_vertices = [ list(other*v()) for v in self.vertex_generator()]
    2015             new_rays =  self.rays()
    2016             new_lines = self.lines()
    2017 
     2003        new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator()]
     2004        new_rays =  self.rays()
     2005        new_lines = self.lines()
    20182006        return Polyhedron(vertices=new_vertices,
    20192007                          rays=new_rays, lines=new_lines,
    2020                           base_ring=self.coerce_field(other))
    2021 
    2022 
    2023     def __rmul__(self,other):
     2008                          base_ring=self.parent()._coerce_base_ring(scalar.parent()))
     2009
     2010    def _acted_upon_(self, actor, self_on_left):
    20242011        """
    2025         Right multiplication.
    2026 
    2027         See :meth:`__mul__` for details.
     2012        Implement the multiplicative action by scalars or other polyhedra.
     2013
     2014        INPUT:
     2015
     2016        - ``actor`` -- A scalar, not necessarily in :meth:`base_ring`,
     2017          or a :class:`Polyhedron`.
     2018
     2019        OUTPUT:
     2020
     2021        Multiplication by another polyhedron returns the product
     2022        polytope. Multiplication by a scalar returns the polytope
     2023        dilated by that scalar, possibly coerced to the bigger field.
    20282024
    20292025        EXAMPLES::
    20302026
     2027             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
     2028             sage: p._acted_upon_(2, True) == p.dilation(2)
     2029             True
     2030             sage: p*2 == p.dilation(2)
     2031             True
     2032             sage: p*p == p.product(p)
     2033             True
     2034             sage: p + vector(ZZ,[1,2,3]) == p.translation([1,2,3])
     2035             True
     2036        """
     2037        if is_Polyhedron(actor):
     2038            return self.product(actor)
     2039        if is_Vector(actor):
     2040            return self.translation(actor)
     2041        else:
     2042            return self.dilation(actor)
     2043
     2044    def __div__(self, scalar):
     2045        """
     2046        Divide by a scalar factor.
     2047
     2048        See :meth:`dilation` for details.
     2049
     2050        EXAMPLES::
     2051
    20312052            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,4)])
    2032             sage: p2 = 3*p + p
    2033             sage: p2.vertex_generator().next()
    2034             A vertex at (8, 16, 32)
     2053            sage: (p/5).Vrepresentation()
     2054            (A vertex at (2/5, 4/5, 8/5), A vertex at (3/5, 9/5, 27/5))
    20352055        """
    2036         return self.__mul__(other)
    2037 
    2038 
    2039     def union(self, other):
    2040         """
    2041         Deprecated.  Use ``self.convex_hull(other)`` instead.
    2042        
    2043         EXAMPLES::
    2044        
    2045             sage: Polyhedron(vertices=[[0]]).union( Polyhedron(vertices=[[1]]) )
    2046             doctest:...: DeprecationWarning: (Since Sage Version 4.4.4)
    2047             The function union is replaced by convex_hull.
    2048             A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices
    2049         """
    2050         from sage.misc.misc import deprecation
    2051         deprecation('The function union is replaced by convex_hull.', 'Sage Version 4.4.4')
    2052         return self.convex_hull(other)
    2053 
    2054 
     2056        return self.dilation(1/scalar)
     2057
     2058    @coerce_binop
    20552059    def convex_hull(self, other):
    20562060        """
    20572061        Return the convex hull of the set-theoretic union of the two
     
    20782082        hull_vertices = self.vertices() + other.vertices()
    20792083        hull_rays = self.rays() + other.rays()
    20802084        hull_lines = self.lines() + other.lines()
    2081         hull_field = self.coerce_field(other)
    2082         return Polyhedron(vertices=hull_vertices,
    2083                           rays=hull_rays, lines=hull_lines,
    2084                           base_ring=hull_field)
    2085 
    2086 
     2085        return self.parent().element_class(self.parent(), [hull_vertices, hull_rays, hull_lines], None)
     2086
     2087    @coerce_binop
    20872088    def intersection(self, other):
    20882089        """
    20892090        Return the intersection of one polyhedron with another.
     
    20962097
    20972098        The intersection.
    20982099
     2100        Note that the intersection of two `\ZZ`-polyhedra might not be
     2101        a `\ZZ`-polyhedron. In this case, a `\QQ`-polyhedron is
     2102        returned.
     2103
    20992104        EXAMPLES::
    21002105
    21012106            sage: cube = polytopes.n_cube(3)
    21022107            sage: oct = polytopes.cross_polytope(3)
    2103             sage: cube_oct = cube.intersection(oct*2)
    2104             sage: len(list( cube_oct.vertex_generator() ))
    2105             12
    2106             sage: cube_oct
    2107             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
     2108            sage: cube.intersection(oct*2)
     2109            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 12 vertices
     2110
     2111       The intersection of two `\ZZ`-polyhedra is not necessarily a `\ZZ`-polyhedron::
     2112
     2113            sage: P = Polyhedron([(0,0),(1,1)], base_ring=ZZ)
     2114            sage: P.intersection(P)
     2115            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices
     2116            sage: Q = Polyhedron([(0,1),(1,0)], base_ring=ZZ)
     2117            sage: P.intersection(Q)
     2118            A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
     2119            sage: _.Vrepresentation()
     2120            (A vertex at (1/2, 1/2),)
    21082121        """
    2109         new_ieqs = []
    2110         new_ieqs.extend(self.inequalities())
    2111         new_ieqs.extend(other.inequalities())
    2112 
    2113         new_eqns = []
    2114         new_eqns.extend(self.equations())
    2115         new_eqns.extend(other.equations())
    2116 
    2117         return Polyhedron(ieqs = new_ieqs, eqns = new_eqns,
    2118                           base_ring=self.coerce_field(other))
    2119 
     2122        new_ieqs = self.inequalities() + other.inequalities()
     2123        new_eqns = self.equations() + other.equations()
     2124        parent = self.parent()
     2125        try:
     2126            return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2127        except TypeError,msg:
     2128            if self.base_ring() is ZZ:
     2129                parent = parent.base_extend(QQ)
     2130                return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2131            else:
     2132                raise TypeError(msg)
    21202133
    21212134    def edge_truncation(self, cut_frac = Integer(1)/3):
    21222135        r"""
     
    21522165
    21532166        return Polyhedron(vertices=new_vertices, rays=new_rays,
    21542167                          lines=new_lines,
    2155                           base_ring=self.coerce_field(cut_frac))
     2168                          base_ring=self.parent()._coerce_base_ring(cut_frac))
    21562169
    21572170
    21582171    def _make_polyhedron_face(self, Vindices, Hindices):
     
    21812194        """
    21822195        return PolyhedronFace_base(self, Vindices, Hindices)
    21832196
    2184 
     2197    @cached_method
    21852198    def face_lattice(self):
    21862199        """
    21872200        Return the face-lattice poset.
     
    23262339            http://portal.acm.org/citation.cfm?id=763203 and free of
    23272340            charge at http://arxiv.org/abs/math/0106043
    23282341        """
    2329         try:
    2330             return self._face_lattice
    2331         except AttributeError:
    2332             pass
    2333        
    23342342        coatom_to_Hindex = [ h.index() for h in self.inequality_generator() ]
    23352343        Hindex_to_coatom = [None] * self.n_Hrepresentation()
    23362344        for i in range(0,len(coatom_to_Hindex)):
     
    23622370            return self._make_polyhedron_face(Vindices, Hindices)
    23632371
    23642372        from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
    2365         self._face_lattice = Hasse_diagram_from_incidences\
     2373        return Hasse_diagram_from_incidences\
    23662374            (atoms_incidences, coatoms_incidences,
    23672375             face_constructor=face_constructor, required_atoms=atoms_vertices)
    2368         return self._face_lattice
    2369 
    2370 
     2376
     2377
     2378    @cached_method
    23712379    def f_vector(self):
    23722380        r"""
    23732381        Return the f-vector.
     
    23842392            sage: p.f_vector()
    23852393            (1, 7, 12, 7, 1)
    23862394        """
    2387         try:
    2388             return self._f_vector
    2389         except AttributeError:
    2390             self._f_vector = vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
    2391             return self._f_vector
    2392 
    2393 
     2395        return vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
     2396
     2397    @cached_method
    23942398    def vertex_graph(self):
    23952399        """
    23962400        Return a graph in which the vertices correspond to vertices
     
    24052409            sage: s4.is_eulerian()
    24062410            True
    24072411        """
    2408         try:
    2409             return self._graph
    2410         except AttributeError:
    2411             self._graph = Graph(self.vertex_adjacency_matrix(), loops=True)
    2412             return self._graph
    2413 
     2412        return Graph(self.vertex_adjacency_matrix(), loops=True)
    24142413
    24152414    graph = vertex_graph
    24162415
    2417 
    24182416    def polar(self):
    24192417        """
    2420         Return the polar (dual) polytope.  The original vertices are
    2421         translated so that their barycenter is at the origin, and then
    2422         the vertices are used as the coefficients in the polar inequalities.
     2418        Return the polar (dual) polytope.
     2419
     2420        The original vertices are translated so that their barycenter
     2421        is at the origin, and then the vertices are used as the
     2422        coefficients in the polar inequalities.
    24232423
    24242424        EXAMPLES::
    24252425
    2426             sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]])
     2426            sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]], base_ring=QQ)
    24272427            sage: p
    24282428            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices
    24292429            sage: p.polar()
     
    24312431        """
    24322432        assert self.is_compact(), "Not a polytope."
    24332433
    2434         verts = [list(v() - self.center()) for v in self.vertex_generator()]
    2435         return Polyhedron(ieqs=[[1] + list(v) for v in verts],
    2436                           base_ring=self.base_ring())
    2437 
     2434        verts = [list(v.vector() - self.center()) for v in self.vertex_generator()]
     2435        base_ring = self.parent()._coerce_base_ring(self.center().parent().base_ring())
     2436        return Polyhedron(ieqs=[[1] + list(v) for v in verts], base_ring=base_ring)
    24382437
    24392438    def pyramid(self):
    24402439        """
     
    24422441
    24432442        EXAMPLES::
    24442443
    2445             sage: square = polytopes.n_cube(2)
    2446             sage: egyptian_pyramid = square.pyramid()
     2444            sage: square = polytopes.n_cube(2);  square
     2445            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     2446            sage: egyptian_pyramid = square.pyramid();  egyptian_pyramid
     2447            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices
    24472448            sage: egyptian_pyramid.n_vertices()
    24482449            5
    24492450            sage: for v in egyptian_pyramid.vertex_generator(): print v
     
    24542455            A vertex at (1, 0, 0)
    24552456        """
    24562457        new_verts = \
    2457             [[0] + list(x) for x in self.Vrep_generator()] + \
     2458            [[0] + x for x in self.Vrep_generator()] + \
    24582459            [[1] + list(self.center())]
    2459 
    2460         return Polyhedron(vertices = new_verts, base_ring=self.field())
    2461 
     2460        return Polyhedron(vertices=new_verts)
    24622461
    24632462    def bipyramid(self):
    24642463        """
     
    24932492            [[-1] + list(self.center())]
    24942493        new_rays = [[0] + r for r in self.rays()]
    24952494        new_lines = [[0] + list(l) for l in self.lines()]
    2496         return Polyhedron(vertices=new_verts,
    2497                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2498 
     2495        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines)
    24992496
    25002497    def prism(self):
    25012498        """
     
    25062503            sage: square = polytopes.n_cube(2)
    25072504            sage: cube = square.prism()
    25082505            sage: cube
    2509             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
     2506            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
    25102507            sage: hypercube = cube.prism()
    25112508            sage: hypercube.n_vertices()
    25122509            16
     
    25152512        new_verts.extend( [ [0] + v for v in self.vertices()] )
    25162513        new_verts.extend( [ [1] + v for v in self.vertices()] )
    25172514        new_rays =        [ [0] + r for r in self.rays()]
    2518         new_lines =       [ [0] + list(l) for l in self.lines()]
    2519         return Polyhedron(vertices=new_verts,
    2520                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2521 
     2515        new_lines =       [ [0] + l for l in self.lines()]
     2516        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines,
     2517                          base_ring=self.base_ring())
    25222518
    25232519    def projection(self):
    25242520        """
     
    25352531        self.projection = Projection(self)
    25362532        return self.projection
    25372533
    2538 
    25392534    def render_solid(self, **kwds):
    25402535        """
    25412536        Return a solid rendering of a 2- or 3-d polytope.
     
    25542549            return proj.render_fill_2d(**kwds)
    25552550        raise ValueError, "render_solid is only defined for 2 and 3 dimensional polyhedra."
    25562551
    2557 
    25582552    def render_wireframe(self, **kwds):
    25592553        """
    25602554        For polytopes in 2 or 3 dimensions, return the edges
     
    25742568            return proj.render_outline_2d(**kwds)
    25752569        raise ValueError, "render_wireframe is only defined for 2 and 3 dimensional polyhedra."
    25762570
    2577 
    25782571    def schlegel_projection(self, projection_dir = None, height = 1.1):
    25792572        """
    25802573        Returns a projection object whose transformed coordinates are
     
    25912584        """
    25922585        proj = self.projection()
    25932586        if projection_dir == None:
    2594             v = self.vertices()
    2595             f0 = (self.facial_incidences()[0])[1]
    2596             projection_dir = [sum([v[f0[i]][j]/len(f0) for i in range(len(f0))])
    2597                               for j in range(len(v[0]))]
     2587            vertices = self.vertices()
     2588            facet = self.Hrepresentation(0)
     2589            f0 = [ v.index() for v in facet.incident() ]
     2590            projection_dir = [sum([vertices[f0[i]][j]/len(f0) for i in range(len(f0))])
     2591                              for j in range(self.ambient_dim())]
    25982592        return proj.schlegel(projection_direction = projection_dir, height = height)
    25992593       
    2600 
    26012594    def lrs_volume(self, verbose = False):
    26022595        """
    26032596        Computes the volume of a polytope.
     
    26482641
    26492642        raise ValueError, "lrs did not return a volume"
    26502643
    2651 
    26522644    def contains(self, point):
    26532645        """
    26542646        Test whether the polyhedron contains the given ``point``.
     
    26902682        The empty polyhedron needs extra care, see trac #10238::
    26912683
    26922684            sage: empty = Polyhedron(); empty
    2693             The empty polyhedron in QQ^0
     2685            The empty polyhedron in ZZ^0
    26942686            sage: empty.contains([])
    26952687            False
    26962688            sage: empty.contains([0])               # not a point in QQ^0
    26972689            False
    26982690            sage: full = Polyhedron(vertices=[()]); full
    2699             A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex
     2691            A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex
    27002692            sage: full.contains([])
    27012693            True
    27022694            sage: full.contains([0])
     
    27082700            if len(point)>0:
    27092701                return False
    27102702            else:
    2711                 p = vector(self.field(), [])
     2703                p = vector(self.base_ring(), [])
    27122704
    27132705        if len(p)!=self.ambient_dim():
    27142706            return False
     
    27182710                return False
    27192711        return True
    27202712
    2721 
    27222713    def interior_contains(self, point):
    27232714        """
    27242715        Test whether the interior of the polyhedron contains the
     
    27552746        The empty polyhedron needs extra care, see trac #10238::
    27562747
    27572748            sage: empty = Polyhedron(); empty
    2758             The empty polyhedron in QQ^0
     2749            The empty polyhedron in ZZ^0
    27592750            sage: empty.interior_contains([])
    27602751            False
    27612752        """
     
    27652756            if len(point)>0:
    27662757                return False
    27672758            else:
    2768                 p = vector(self.field(), [])
     2759                p = vector(self.base_ring(), [])
    27692760
    27702761        if len(p)!=self.ambient_dim():
    27712762            return False
     
    27752766                return False
    27762767        return True
    27772768
    2778 
    27792769    def relative_interior_contains(self, point):
    27802770        """
    27812771        Test whether the relative interior of the polyhedron
     
    28062796        The empty polyhedron needs extra care, see trac #10238::
    28072797
    28082798            sage: empty = Polyhedron(); empty
    2809             The empty polyhedron in QQ^0
     2799            The empty polyhedron in ZZ^0
    28102800            sage: empty.relative_interior_contains([])
    28112801            False
    28122802        """
     
    28162806            if len(point)>0:
    28172807                return False
    28182808            else:
    2819                 p = vector(self.field(), [])
     2809                p = vector(self.base_ring(), [])
    28202810
    28212811        if len(p)!=self.ambient_dim():
    28222812            return False
     
    28462836        """
    28472837        return self.is_compact() and (self.dim()+1==self.n_vertices())
    28482838
     2839    @cached_method
    28492840    def is_lattice_polytope(self):
    28502841        r"""
    28512842        Return whether the polyhedron is a lattice polytope.
     
    28622853            sage: polytopes.regular_polygon(5).is_lattice_polytope()
    28632854            False
    28642855        """
    2865         try:
    2866             return self._is_lattice_polytope
    2867         except AttributeError:
    2868             pass
    2869         self._is_lattice_polytope = self.is_compact() and \
    2870             all(v.is_integral() for v in self.vertex_generator())
    2871         return self._is_lattice_polytope
     2856        if not self.is_compact():
     2857            return False
     2858        if self.base_ring() is ZZ:
     2859            return True
     2860        return all(v.is_integral() for v in self.vertex_generator())
    28722861       
     2862    @cached_method
    28732863    def lattice_polytope(self, envelope=False):
    28742864        r"""
    28752865        Return an encompassing lattice polytope.
     
    29322922        if not self.is_compact():
    29332923            raise NotImplementedError, 'Only compact lattice polytopes are allowed.'
    29342924
    2935         def nonintegral_error():
    2936             raise ValueError, 'Some vertices are not integral. '+\
    2937                 'You probably want to add the argument '+\
    2938                 '"envelope=True" to compute an enveloping lattice polytope.'
    2939 
    2940         # try to make use of cached values, if possible
    2941         if envelope:
    2942             try:
    2943                 return self._lattice_polytope
    2944             except AttributeError:
    2945                 pass
    2946         else:
    2947             try:
    2948                 assert self._is_lattice_polytope
    2949                 return self._lattice_polytope
    2950             except AttributeError:
    2951                 pass
    2952             except AssertionError:
    2953                 nonintegral_error()
    2954 
    2955         # find the integral vertices
    29562925        try:
    2957             vertices = matrix(ZZ, self.vertices()).transpose()
    2958             self._is_lattice_polytope = True
     2926            vertices = self.vertices_matrix(ZZ)
    29592927        except TypeError:
    2960             self._is_lattice_polytope = False
    2961             if envelope==False: nonintegral_error()
     2928            if envelope==False:
     2929                raise ValueError, 'Some vertices are not integral. '+\
     2930                    'You probably want to add the argument '+\
     2931                    '"envelope=True" to compute an enveloping lattice polytope.'
    29622932            vertices = []
    29632933            for v in self.vertex_generator():
    29642934                vbox = [ set([floor(x),ceil(x)]) for x in v ]
     
    29672937
    29682938        # construct the (enveloping) lattice polytope
    29692939        from sage.geometry.lattice_polytope import LatticePolytope
    2970         self._lattice_polytope = LatticePolytope(vertices)
    2971         return self._lattice_polytope
     2940        return LatticePolytope(vertices)
    29722941
    29732942    def _integral_points_PALP(self):
    29742943        r"""
     
    30363005        box_max = []
    30373006        if self.n_vertices==0:
    30383007            raise ValueError('Empty polytope is not allowed')
     3008        if not self.is_compact():
     3009            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
    30393010        for i in range(0,self.ambient_dim()):
    3040             coords = [ v[i] for v in self.Vrep_generator() ]
     3011            coords = [ v[i] for v in self.vertex_generator() ]
    30413012            max_coord = max(coords)
    30423013            min_coord = min(coords)
    30433014            if integral:
     
    30943065
    30953066            sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
    30963067            sage: simplex = Polyhedron(v); simplex
    3097             A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     3068            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
    30983069            sage: len(simplex.integral_points())
    30993070            49
    31003071
     
    31443115        # assert all(self.contains(p) for p in points)   # slow
    31453116        return tuple(points)
    31463117   
     3118    @cached_method
    31473119    def combinatorial_automorphism_group(self):
    31483120        """
    31493121        Computes the combinatorial automorphism group of the vertex
     
    31783150            sage: P.combinatorial_automorphism_group()
    31793151            Permutation Group with generators [(3,4)]
    31803152        """
    3181         if '_combinatorial_automorphism_group' in self.__dict__:
    3182             return self._combinatorial_automorphism_group
    3183 
    31843153        from sage.groups.perm_gps.permgroup import PermutationGroup
    3185 
    31863154        G = Graph()
    31873155        for edge in self.vertex_graph().edges():
    31883156            i = edge[0]
     
    32003168        self._combinatorial_automorphism_group = group
    32013169        return group
    32023170
    3203 
    32043171    def _affine_coordinates(self, Vrep_object):
    32053172        r"""
    32063173        Return affine coordinates for a V-representation object.
     
    32393206        if len(v) != self.ambient_dim():
    32403207            raise ValueError('Incorrect dimension: '+str(v))
    32413208
    3242         return vector(self.field(), [ v[i] for i in self._affine_coordinates_pivots ])
     3209        return vector(self.base_ring(), [ v[i] for i in self._affine_coordinates_pivots ])
    32433210       
    3244 
     3211    @cached_method
    32453212    def restricted_automorphism_group(self):
    32463213        r"""
    32473214        Return the restricted automorphism group.
     
    33893356            sage: p.restricted_automorphism_group()
    33903357            Permutation Group with generators [(2,3)]
    33913358        """
    3392         if '_restricted_automorphism_group' in self.__dict__:
    3393             return self._restricted_automorphism_group
    3394 
    33953359        from sage.groups.perm_gps.permgroup import PermutationGroup
    33963360
    3397         if self.field() is QQ:
     3361        if self.base_ring() is ZZ or self.base_ring() is QQ:
    33983362            def rational_approximation(c):
    33993363                return c
    34003364
    3401         else:  # self.field() is RDF
     3365        elif self.base_ring() is RDF:
    34023366            c_list = []
    34033367            def rational_approximation(c):
    34043368                # Implementation detail: Return unique integer if two
     
    34103374                        return i
    34113375                c_list.append(c)
    34123376                return len(c_list)-1
    3413        
     3377
    34143378        # The algorithm identifies the restricted automorphism group
    34153379        # with the automorphism group of a edge-colored graph. The
    34163380        # nodes of the graph are the V-representation objects. If all
     
    34673431
    34683432
    34693433
    3470 
    3471 
    3472 
    34733434#########################################################################
    3474 class PolyhedronFace_base(SageObject):
     3435class PolyhedronFace_base(Polyhedron_base):
    34753436    r"""
    34763437    A face of a polyhedron.
    34773438   
     
    35343495            sage: PolyhedronFace_base(Polyhedron(), [], [])   # indirect doctest
    35353496            <>
    35363497        """
     3498        Element.__init__(self, parent=polyhedron.parent())
    35373499        self._polyhedron = polyhedron
    35383500        self._ambient_Vrepresentation_indices = tuple(V_indices)
    35393501        self._ambient_Hrepresentation_indices = tuple(H_indices)
    35403502        self._ambient_Vrepresentation = tuple( polyhedron.Vrepresentation(i) for i in V_indices )
    35413503        self._ambient_Hrepresentation = tuple( polyhedron.Hrepresentation(i) for i in H_indices )
    3542         # self._Vrepresentation =
    3543         # self._Hrepresentation =
     3504        self._Vrepresentation = tuple()
     3505        self._Hrepresentation = tuple()
    35443506       
    3545 
    35463507    def ambient_Hrepresentation(self, index=None):
    35473508        r"""
    35483509        Return the H-representation objects of the ambient polytope
     
    35853546        else:
    35863547            return self._ambient_Hrepresentation[index]
    35873548       
    3588 
    35893549    def ambient_Vrepresentation(self, index=None):
    35903550        r"""
    35913551        Return the V-representation objects of the ambient polytope
     
    36283588        else:
    36293589            return self._ambient_Vrepresentation[index]
    36303590
    3631 
     3591    @cached_method
    36323592    def n_ambient_Hrepresentation(self):
    36333593        """
    36343594        Return the number of objects that make up the ambient
     
    36543614            sage: face.n_ambient_Hrepresentation()
    36553615            4
    36563616        """
    3657         return len(self._ambient_Hrepresentation)
    3658 
    3659 
     3617        return len(self.ambient_Hrepresentation())
     3618
     3619    @cached_method
    36603620    def n_ambient_Vrepresentation(self):
    36613621        """
    36623622        Return the number of objects that make up the ambient
     
    36793639            sage: face.n_ambient_Vrepresentation()
    36803640            2
    36813641        """
    3682         return len(self._ambient_Vrepresentation)
    3683 
    3684 
     3642        return len(self.ambient_Vrepresentation())
     3643
     3644    @cached_method
    36853645    def dim(self):
    36863646        """
    36873647        Return the dimension of the face.
     
    36983658              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    36993659              1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3]
    37003660        """
    3701         if '_dim' in self.__dict__:
    3702             return self._dim
    3703 
    37043661        if self.n_ambient_Vrepresentation()==0:
    3705             self._dim = -1
     3662            return -1
    37063663        else:
    37073664            origin = vector(self.ambient_Vrepresentation(0))
    37083665            v_list = [ vector(v)-origin for v in self.ambient_Vrepresentation() ]
    3709             self._dim = matrix(v_list).rank()
    3710         return self._dim
    3711 
     3666            return matrix(v_list).rank()
    37123667
    37133668    def _repr_(self):
    37143669        r"""
  • sage/geometry/polyhedron/base_QQ.py

    diff --git a/sage/geometry/polyhedron/base_QQ.py b/sage/geometry/polyhedron/base_QQ.py
    a b  
    8383        return x>0
    8484
    8585    _base_ring = QQ
    86      
    87      
    88      
     86 
  • new file sage/geometry/polyhedron/base_ZZ.py

    diff --git a/sage/geometry/polyhedron/base_ZZ.py b/sage/geometry/polyhedron/base_ZZ.py
    new file mode 100644
    - +  
     1"""
     2Base class for polyhedra over `\ZZ`
     3"""
     4
     5########################################################################
     6#       Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
     7#
     8#  Distributed under the terms of the GNU General Public License (GPL)
     9#
     10#                  http://www.gnu.org/licenses/
     11########################################################################
     12
     13
     14
     15from sage.rings.all import ZZ, QQ
     16from sage.misc.all import cached_method
     17from sage.matrix.constructor import matrix
     18
     19from constructor import Polyhedron
     20from base import Polyhedron_base
     21
     22
     23
     24#########################################################################
     25class Polyhedron_ZZ(Polyhedron_base):
     26    """
     27    Base class for Polyhedra over `\ZZ`
     28
     29    TESTS::
     30
     31        sage: p = Polyhedron([(0,0)], base_ring=ZZ);  p
     32        A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex
     33        sage: TestSuite(p).run(skip='_test_pickling')
     34    """
     35    def _is_zero(self, x):
     36        """
     37        Test whether ``x`` is zero.
     38
     39        INPUT:
     40
     41        - ``x`` -- a number in the base ring.
     42
     43        OUTPUT:
     44
     45        Boolean.
     46
     47        EXAMPLES::
     48
     49            sage: p = Polyhedron([(0,0)], base_ring=ZZ)
     50            sage: p._is_zero(0)
     51            True
     52            sage: p._is_zero(1/100000)
     53            False
     54        """
     55        return x==0
     56
     57    def _is_nonneg(self, x):
     58        """
     59        Test whether ``x`` is nonnegative.
     60
     61        INPUT:
     62
     63        - ``x`` -- a number in the base ring.
     64
     65        OUTPUT:
     66
     67        Boolean.
     68
     69        EXAMPLES::
     70
     71            sage: p = Polyhedron([(0,0)], base_ring=ZZ)
     72            sage: p._is_nonneg(1)
     73            True
     74            sage: p._is_nonneg(-1/100000)
     75            False
     76        """
     77        return x>=0
     78
     79    def _is_positive(self, x):
     80        """
     81        Test whether ``x`` is positive.
     82
     83        INPUT:
     84
     85        - ``x`` -- a number in the base ring.
     86
     87        OUTPUT:
     88
     89        Boolean.
     90
     91        EXAMPLES::
     92
     93            sage: p = Polyhedron([(0,0)], base_ring=ZZ)
     94            sage: p._is_positive(1)
     95            True
     96            sage: p._is_positive(0)
     97            False
     98        """
     99        return x>0
     100
     101    _base_ring = ZZ
     102
     103    def is_lattice_polytope(self):
     104        r"""
     105        Return whether the polyhedron is a lattice polytope.
     106
     107        OUTPUT:
     108
     109        ``True`` if the polyhedron is compact and has only integral
     110        vertices, ``False`` otherwise.
     111
     112        EXAMPLES::
     113
     114            sage: polytopes.cross_polytope(3).is_lattice_polytope()
     115            True
     116            sage: polytopes.regular_polygon(5).is_lattice_polytope()
     117            False
     118        """
     119        return True
     120
     121    @cached_method
     122    def polar(self):
     123        """
     124        Return the polar (dual) polytope.
     125
     126        The polytope must have the IP-property (see
     127        :meth:`has_IP_property`), that is, the origin must be an
     128        interior point. In particular, it must be full-dimensional.
     129
     130        OUTPUT:
     131
     132        The polytope whose vertices are the coefficient vectors of the
     133        inequalities of ``self`` with inhomogeneous term normalized to
     134        unity.
     135
     136        EXAMPLES::
     137
     138            sage: p = Polyhedron(vertices=[(1,0,0),(0,1,0),(0,0,1),(-1,-1,-1)], base_ring=ZZ)
     139            sage: p.polar()
     140            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
     141            sage: type(_)
     142            <class 'sage.geometry.polyhedron.backend_ppl.Polyhedra_ZZ_ppl_with_category.element_class'>
     143            sage: p.polar().base_ring()
     144            Integer Ring
     145        """
     146        if not self.has_IP_property():
     147            raise ValueError('The polytope must have the IP property.')
     148
     149        vertices = [ ieq.A()/ieq.b() for
     150                     ieq in self.inequality_generator() ]
     151        if all( all(v_i in ZZ for v_i in v) for v in vertices):
     152            return Polyhedron(vertices=vertices, base_ring=ZZ)
     153        else:
     154            return Polyhedron(vertices=vertices, base_ring=QQ)
     155
     156    @cached_method
     157    def is_reflexive(self):
     158        """
     159        EXAMPLES::
     160
     161            sage: p = Polyhedron(vertices=[(1,0,0),(0,1,0),(0,0,1),(-1,-1,-1)], base_ring=ZZ)
     162            sage: p.is_reflexive()
     163            True
     164        """
     165        return self.polar().is_lattice_polytope()
     166
     167    @cached_method
     168    def has_IP_property(self):
     169        """
     170        Test whether the polyhedron has the IP property.
     171
     172        The IP (interior point) property means that
     173
     174        * ``self`` is compact (a polytope).
     175
     176        * ``self`` contains the origin as an interior point.
     177
     178        This implies that
     179
     180        * ``self`` is full-dimensional.
     181
     182        * The dual polyhedron is again a polytope (that is, a compact
     183          polyhedron), though not necessarily a lattice polytope.
     184
     185        EXAMPLES::
     186
     187            sage: Polyhedron([(1,1),(1,0),(0,1)], base_ring=ZZ).has_IP_property()
     188            False
     189            sage: Polyhedron([(0,0),(1,0),(0,1)], base_ring=ZZ).has_IP_property()
     190            False
     191            sage: Polyhedron([(-1,-1),(1,0),(0,1)], base_ring=ZZ).has_IP_property()
     192            True
     193
     194        REFERENCES::
     195
     196        ..  [PALP]
     197            Maximilian Kreuzer, Harald Skarke:
     198            "PALP: A Package for Analyzing Lattice Polytopes
     199            with Applications to Toric Geometry"
     200            Comput.Phys.Commun. 157 (2004) 87-106
     201            http://arxiv.org/abs/math/0204356
     202        """
     203        return self.is_compact() and self.interior_contains(self.ambient_space().zero())
     204
     205    def fibration_generator(self, dim):
     206        """
     207        Generate the lattice polytope fibrations.
     208
     209        For the purposes of this function, a lattice polytope fiber is
     210        a sub-lattice polytope. Projecting the plane spanned by the
     211        subpolytope to a point yields another lattice polytope, the
     212        base of the fibration.
     213
     214        INPUT:
     215
     216        - ``dim`` -- integer. The dimension of the lattice polytope
     217          fiber.
     218
     219        OUTPUT:
     220
     221        A generator yielding the distinct lattice polytope fibers of
     222        given dimension.
     223
     224        EXAMPLES::
     225
     226            sage: P = Polyhedron(toric_varieties.P4_11169().fan().rays(), base_ring=ZZ)
     227            sage: list( P.fibration_generator(2) )
     228            [A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices]
     229        """
     230        from sage.combinat.combinat import combinations_iterator
     231        if not self.is_compact():
     232            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
     233
     234        nonzero_points = [p for p in self.integral_points() if not p.is_zero()]
     235        origin = [[0]*self.ambient_dim()]
     236        fibers = set()
     237        parent = self.parent()
     238
     239        for points in combinations_iterator(nonzero_points, dim):
     240                plane = parent.element_class(parent, [origin,[],points], None)
     241                if plane.dim() != dim:
     242                    continue
     243                fiber = self.intersection(plane)
     244                if fiber.base_ring() is not ZZ:
     245                    continue
     246                fiber_vertices = tuple(sorted(tuple(v) for v in fiber.vertex_generator()))
     247                if fiber_vertices not in fibers:
     248                    yield fiber
     249                    fibers.update([fiber_vertices])
     250                plane.delete()
     251
  • sage/geometry/polyhedron/constructor.py

    diff --git a/sage/geometry/polyhedron/constructor.py b/sage/geometry/polyhedron/constructor.py
    a b  
    3939
    4040    sage: trunc_quadr = Polyhedron(vertices=[[1,0],[0,1]], rays=[[1,0],[0,1]])
    4141    sage: trunc_quadr
    42     A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays
     42    A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 2 rays
    4343    sage: v = trunc_quadr.vertex_generator().next()  # the first vertex in the internal enumeration
    4444    sage: v
    4545    A vertex at (0, 1)
     
    5656    sage: type(v)
    5757    <class 'sage.geometry.polyhedron.representation.Vertex'>
    5858    sage: type( v() )
    59     <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
     59    <type 'sage.modules.vector_integer_dense.Vector_integer_dense'>
    6060    sage: v.polyhedron()
    61     A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays
     61    A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 2 rays
    6262    sage: r = trunc_quadr.ray_generator().next()
    6363    sage: r
    6464    A ray in the direction (0, 1)
     
    105105from sage.rings.all import QQ, ZZ, RDF
    106106from sage.misc.decorators import rename_keyword
    107107
    108 from misc import (
    109     _set_to_None_if_empty, _set_to_empty_if_None,
    110     _common_length_of )
     108from misc import _make_listlist, _common_length_of
    111109
    112110
    113111
     
    118116@rename_keyword(deprecated='Sage version 4.7.2', field='base_ring')
    119117def Polyhedron(vertices=None, rays=None, lines=None,
    120118               ieqs=None, eqns=None,
    121                base_ring=QQ, minimize=True, verbose=False,
     119               ambient_dim=None, base_ring=None, minimize=True, verbose=False,
    122120               backend=None):
    123121    """
    124122    Construct a polyhedron object.
     
    131129    INPUT:
    132130
    133131    - ``vertices`` -- list of point. Each point can be specified as
    134       any iterable container of ``base_ring`` elements.
     132      any iterable container of ``base_ring`` elements. If ``rays`` or
     133      ``lines`` are specified but no ``vertices``, the origin is
     134      taken to be the single vertex.
    135135       
    136136    - ``rays`` -- list of rays. Each ray can be specified as any
    137137      iterable container of ``base_ring`` elements.
     
    151151      used. Floating point arithmetic is faster but might give the
    152152      wrong result for degenerate input.
    153153
     154    - ``ambient_dim`` -- integer. The ambient space dimension. Usually
     155      can be figured out automatically from the H/Vrepresentation
     156      dimensions.
     157
    154158    - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are
    155159
    156       * ``'cddr'``: cdd (:mod:`~sage.geometry.polyhedron.backend_cdd`)
    157         with rational coefficients
     160      * ``'cdd'``: use cdd
     161        (:mod:`~sage.geometry.polyhedron.backend_cdd`) with `\QQ` or
     162        `\RDF` coefficients depending on ``base_ring``.
    158163
    159       * ``'cddf'``: cdd with floating-point coefficients
    160164
    161165      * ``'ppl'``: use ppl
    162         (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\QQ`
    163         coefficients.
     166        (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\ZZ` or
     167        `\QQ` coefficients depending on ``base_ring``.
    164168
    165169    Some backends support further optional arguments:
    166170
     
    221225        sage: positive_coords = Polyhedron(ieqs=[
    222226        ...       [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0],
    223227        ...       [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]])
    224         sage: P = Polyhedron(ieqs=positive_coords.inequalities() + [
    225         ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]], eqns=[[-31,1,1,1,1,1,1]])
     228        sage: P = Polyhedron(ieqs=positive_coords.inequalities() + (
     229        ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]), eqns=[[-31,1,1,1,1,1,1]])
    226230        sage: P
    227231        A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices
    228232        sage: P.dim()
     
    242246        setting of cdd.
    243247    """
    244248    # Clean up the arguments
    245     vertices = _set_to_None_if_empty(vertices)
    246     rays     = _set_to_None_if_empty(rays)
    247     lines    = _set_to_None_if_empty(lines)
    248     ieqs     = _set_to_None_if_empty(ieqs)
    249     eqns     = _set_to_None_if_empty(eqns)
     249    vertices = _make_listlist(vertices)
     250    rays     = _make_listlist(rays)
     251    lines    = _make_listlist(lines)
     252    ieqs     = _make_listlist(ieqs)
     253    eqns     = _make_listlist(eqns)
    250254
    251     got_Vrep = (vertices is not None or rays is not None or lines is not None)
    252     got_Hrep = (ieqs is not None or eqns is not None)
     255    got_Vrep = (len(vertices+rays+lines) > 0)
     256    got_Hrep = (len(ieqs+eqns) > 0)
    253257   
    254258    if got_Vrep and got_Hrep:
    255259        raise ValueError('You cannot specify both H- and V-representation.')
    256260    elif got_Vrep:
    257         vertices = _set_to_empty_if_None(vertices)
    258         rays     = _set_to_empty_if_None(rays)
    259         lines    = _set_to_empty_if_None(lines)
    260         Vrep = [vertices, rays, lines]
    261         Hrep = None
    262         ambient_dim = _common_length_of(*Vrep)[1]
     261        deduced_ambient_dim = _common_length_of(vertices, rays, lines)[1]
    263262    elif got_Hrep:
    264         ieqs = _set_to_empty_if_None(ieqs)
    265         eqns = _set_to_empty_if_None(eqns)
    266         Vrep = None
    267         Hrep = [ieqs, eqns]
    268         ambient_dim = _common_length_of(*Hrep)[1] - 1
     263        deduced_ambient_dim = _common_length_of(ieqs, eqns)[1] - 1
    269264    else:
    270         Vrep = None
    271         Hrep = None
    272         ambient_dim = 0
     265        if ambient_dim is None:
     266            deduced_ambient_dim = 0
     267        else:
     268            deduced_ambient_dim = ambient_dim
     269        if base_ring is None:
     270            base_ring = ZZ
    273271
    274     if backend is not None:
    275         if backend=='ppl':
    276             from backend_ppl import Polyhedron_QQ_ppl
    277             return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
    278         if backend=='cddr':
    279             from backend_cdd import Polyhedron_QQ_cdd
    280             return Polyhedron_QQ_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
    281         if backend=='cddf':
    282             from backend_cdd import Polyhedron_RDF_cdd
    283             return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
     272    # set ambient_dim
     273    if ambient_dim is not None and deduced_ambient_dim!=ambient_dim:
     274        raise ValueError('Ambient space dimension mismatch. Try removing the "ambient_dim" parameter.')
     275    ambient_dim = deduced_ambient_dim
    284276
    285     if base_ring is QQ:
    286         from backend_ppl import Polyhedron_QQ_ppl
    287         return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
    288     elif base_ring is RDF:
    289         from backend_cdd import Polyhedron_RDF_cdd
    290         return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
     277    # figure out base_ring
     278    from sage.misc.flatten import flatten
     279    values = flatten(vertices+rays+lines+ieqs+eqns)
     280    if base_ring is not None:
     281        try:
     282            convert = not all(x.parent() is base_ring for x in values)
     283        except AttributeError:   # No x.parent() method?
     284            convert = True
    291285    else:
    292         raise ValueError('Polyhedron objects can only be constructed over QQ and RDF')
     286        from sage.rings.integer import is_Integer
     287        from sage.rings.rational import is_Rational
     288        from sage.rings.real_double import is_RealDoubleElement
     289        if all(is_Integer(x) for x in values):
     290            if got_Vrep:
     291                base_ring = ZZ
     292            else:   # integral inequalities usually do not determine a latice polytope!
     293                base_ring = QQ
     294            convert=False
     295        elif all(is_Rational(x) for x in values):
     296            base_ring = QQ
     297            convert=False
     298        elif all(is_RealDoubleElement(x) for x in values):
     299            base_ring = RDF
     300            convert=False
     301        else:
     302            try:
     303                map(ZZ, values)
     304                if got_Vrep:
     305                    base_ring = ZZ
     306                else:
     307                    base_ring = QQ
     308                convert = True
     309            except TypeError:
     310                from sage.structure.sequence import Sequence
     311                values = Sequence(values)
     312                if QQ.has_coerce_map_from(values.universe()):
     313                    base_ring = QQ
     314                    convert = True
     315                else:
     316                    base_ring = RDF
     317                    convert = True
    293318
     319    # Add the origin if necesarry
     320    if got_Vrep and len(vertices)==0:
     321        vertices = [ [0]*ambient_dim ]
    294322
     323    # Specific backends can override the base_ring
     324    from sage.geometry.polyhedron.parent import Polyhedra
     325    parent = Polyhedra(base_ring, ambient_dim, backend=backend)
     326    base_ring = parent.base_ring()
    295327
     328    # Convert into base_ring if necessary
     329    def convert_base_ring(lstlst):
     330        return [ [base_ring(x) for x in lst] for lst in lstlst]
     331    Hrep = Vrep = None
     332    if got_Hrep:
     333        if convert:
     334            Hrep = [convert_base_ring(ieqs), convert_base_ring(eqns)]
     335        else:
     336            Hrep = [ieqs, eqns]
     337    if got_Vrep:
     338        if convert:
     339            Vrep = [convert_base_ring(vertices), convert_base_ring(rays), convert_base_ring(lines)]
     340        else:
     341            Vrep = [vertices, rays, lines]
    296342
    297 
     343    # finally, construct the Polyhedron
     344    return parent.element_class(parent, Vrep, Hrep)
  • sage/geometry/polyhedron/misc.py

    diff --git a/sage/geometry/polyhedron/misc.py b/sage/geometry/polyhedron/misc.py
    a b  
    5858        [1]
    5959    """
    6060    if x is None: return x
     61    x = list(x)
    6162    if len(x)==0: return None
    6263    return x
    6364
    6465
    6566#########################################################################
    66 def _set_to_empty_if_None(x):
     67def _make_listlist(x):
    6768    """
    68     Helper function to clean up arguments: Returns the empty list if
    69     x==None or x is an empty container.
     69    Helper function to clean up arguments.
     70
     71    INPUT:
     72
     73    - ``x`` -- ``None`` or an iterable of iterables.
     74
     75    OUTPUT
     76
     77    A list of lists.
    7078
    7179    EXAMPLES::
    7280
    7381        sage: import sage.geometry.polyhedron.misc as P
    74         sage: [] == P._set_to_empty_if_None(tuple())
     82        sage: [] == P._make_listlist(tuple())
    7583        True
    76         sage: [] == P._set_to_empty_if_None(None)
     84        sage: [] == P._make_listlist(None)
    7785        True
    78         sage: P._set_to_empty_if_None([1])
    79         [1]
     86        sage: P._make_listlist([(1,2),[3,4]])
     87        [[1, 2], [3, 4]]
    8088    """
    8189    if x is None: return []
    82     if len(x)==0: return []
    83     return x
     90    return [list(y) for y in x]
    8491
    8592
    8693#########################################################################
  • new file sage/geometry/polyhedron/parent.py

    diff --git a/sage/geometry/polyhedron/parent.py b/sage/geometry/polyhedron/parent.py
    new file mode 100644
    - +  
     1r"""
     2Parents for Polyhedra
     3"""
     4
     5#*****************************************************************************
     6#       Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
     7#
     8#  Distributed under the terms of the GNU General Public License (GPL)
     9#                  http://www.gnu.org/licenses/
     10#******************************************************************************
     11
     12from sage.structure.parent import Parent
     13from sage.structure.element import get_coercion_model
     14from sage.structure.unique_representation import UniqueRepresentation
     15from sage.modules.free_module import is_FreeModule
     16from sage.misc.cachefunc import cached_method
     17from sage.rings.all import ZZ, QQ, RDF, is_Field, is_CommutativeRing
     18
     19from sage.geometry.polyhedron.base import Polyhedron_base, is_Polyhedron
     20from representation import Inequality, Equation, Vertex, Ray, Line
     21
     22
     23def Polyhedra(base_ring, ambient_dim, backend=None):
     24    """
     25    EXAMPLES::
     26
     27        sage: from sage.geometry.polyhedron.parent import Polyhedra
     28        sage: Polyhedra(ZZ, 3)
     29        Polyhedra in ZZ^3
     30        sage: type(_)
     31        <class 'sage.geometry.polyhedron.parent.Polyhedra_ZZ_ppl_with_category'>
     32        sage: Polyhedra(QQ, 3, backend='cdd')
     33        Polyhedra in QQ^3
     34        sage: type(_)
     35        <class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_cdd_with_category'>
     36    """
     37    if backend is None:
     38        if base_ring is ZZ:
     39            return Polyhedra_ZZ_ppl(base_ring, ambient_dim)
     40        elif base_ring is QQ:
     41            return Polyhedra_QQ_ppl(base_ring, ambient_dim)
     42        elif base_ring is RDF:
     43            return Polyhedra_RDF_cdd(base_ring, ambient_dim)
     44        else:
     45            raise ValueError('Polyhedral objects can only be constructed over ZZ, QQ, and RDF')
     46    elif backend=='ppl' and base_ring is QQ:
     47        return Polyhedra_QQ_ppl(base_ring, ambient_dim)
     48    elif backend=='ppl' and base_ring is ZZ:
     49        return Polyhedra_ZZ_ppl(base_ring, ambient_dim)
     50    elif backend=='cdd' and base_ring is QQ:
     51        return Polyhedra_QQ_cdd(QQ, ambient_dim)
     52    elif backend=='cdd' and base_ring is RDF:
     53        return Polyhedra_RDF_cdd(RDF, ambient_dim)
     54    else:
     55        raise ValueError('No such backend (='+str(backend)+
     56                         ') implemented for given basering (='+str(base_ring)+').')
     57
     58
     59
     60class Polyhedra_base(UniqueRepresentation, Parent):
     61    r"""
     62    Polyhedra in a fixed ambient space.
     63
     64    INPUT:
     65
     66    - ``base_ring`` -- either ``ZZ``, ``QQ``, or ``RDF``. The base
     67      ring of the ambient module/vector space.
     68
     69    - ``ambient_dim`` -- integer. The ambient space dimension.
     70
     71    EXAMPLES::
     72
     73        sage: from sage.geometry.polyhedron.parent import Polyhedra
     74        sage: Polyhedra(ZZ, 3)
     75        Polyhedra in ZZ^3
     76    """
     77    def __init__(self, base_ring, ambient_dim):
     78        """
     79        The Python constructor.
     80
     81        EXAMPLES::
     82
     83            sage: from sage.geometry.polyhedron.parent import Polyhedra
     84            sage: Polyhedra(QQ, 3)
     85            Polyhedra in QQ^3
     86
     87        TESTS::
     88
     89            sage: from sage.geometry.polyhedron.parent import Polyhedra
     90            sage: P = Polyhedra(QQ, 3)
     91            sage: TestSuite(P).run(skip='_test_pickling')
     92        """
     93        self._ambient_dim = ambient_dim
     94        from sage.categories.polyhedra import PolyhedralSets
     95        Parent.__init__(self, base=base_ring, category=PolyhedralSets(base_ring))
     96        self._Inequality_pool = []
     97        self._Equation_pool = []
     98        self._Vertex_pool = []
     99        self._Ray_pool = []
     100        self._Line_pool = []
     101
     102    def recycle(self, polyhedron):
     103        """
     104        Recycle the H/V-representation objects of a polyhedron.
     105
     106        This speeds up creation of new polyhedra by reusing
     107        objects. After recycling a polyhedron object, it is not in a
     108        consistent state any more and neither the polyhedron nor its
     109        H/V-representation objects may be used any more.
     110
     111        INPUT:
     112
     113        - ``polyhedron`` -- a polyhedron whose parent is ``self``.
     114
     115
     116        EXAMPLES::
     117
     118            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
     119            sage: p.parent().recycle(p)
     120
     121        TESTS::
     122
     123            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
     124            sage: n = len(p.parent()._Vertex_pool)
     125            sage: p.delete()
     126            sage: len(p.parent()._Vertex_pool) - n
     127            3
     128        """
     129        if self is not polyhedron.parent():
     130            raise TypeError('The polyhedron has the wrong parent class.')
     131        self._Inequality_pool.extend(polyhedron.inequalities())
     132        self._Equation_pool.extend(polyhedron.equations())
     133        self._Vertex_pool.extend(polyhedron.vertices())
     134        self._Ray_pool.extend(polyhedron.rays())
     135        self._Line_pool.extend(polyhedron.lines())
     136        for Hrep in polyhedron.Hrep_generator():
     137            Hrep._polyhedron = None
     138        for Vrep in polyhedron.Vrep_generator():
     139            Vrep._polyhedron = None
     140
     141    def ambient_dim(self):
     142        r"""
     143        Return the dimension of the ambient space.
     144
     145        EXAMPLES::
     146
     147            sage: from sage.geometry.polyhedron.parent import Polyhedra
     148            sage: Polyhedra(QQ, 3).ambient_dim()
     149            3
     150        """
     151        return self._ambient_dim
     152
     153    @cached_method
     154    def an_element(self):
     155        r"""
     156        Returns a Polyhedron.
     157
     158        EXAMPLES::
     159
     160            sage: from sage.geometry.polyhedron.parent import Polyhedra
     161            sage: Polyhedra(QQ, 4).an_element()
     162            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     163        """
     164        p = [0] * self.ambient_dim()
     165        points = [p]
     166        for i in range(0,self.ambient_dim()):
     167            p = [0] * self.ambient_dim()
     168            p[i] = 1
     169            points.append(p)
     170        return self.element_class(self, [points,[],[]], None)
     171
     172    @cached_method
     173    def some_elements(self):
     174        r"""
     175        Returns a list of some elements of the semigroup.
     176
     177        EXAMPLES::
     178
     179            sage: from sage.geometry.polyhedron.parent import Polyhedra
     180            sage: Polyhedra(QQ, 4).some_elements()
     181            [A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices,
     182             A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex and 4 rays,
     183             A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices and 1 ray,
     184             The empty polyhedron in QQ^4]
     185            sage: Polyhedra(ZZ,0).some_elements()
     186            [The empty polyhedron in ZZ^0,
     187             A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex]
     188        """
     189        if self.ambient_dim() == 0:
     190            return [
     191                self.element_class(self, None, None),
     192                self.element_class(self, None, [[],[]]) ]
     193        points = []
     194        for i in range(0,self.ambient_dim()+5):
     195            points.append([i*j^2 for j in range(0,self.ambient_dim())])
     196        return [
     197            self.element_class(self, [points[0:self.ambient_dim()+1], [], []], None),
     198            self.element_class(self, [points[0:1], points[1:self.ambient_dim()+1], []], None),
     199            self.element_class(self, [points[0:3], points[4:5], []], None),
     200            self.element_class(self, None, None) ]
     201
     202    @cached_method
     203    def zero_element(self):
     204        r"""
     205        Returns the polyhedron consisting of the origin, which is the
     206        neutral element for Minkowski addition.
     207
     208        EXAMPLES::
     209
     210            sage: from sage.geometry.polyhedron.parent import Polyhedra
     211            sage: p = Polyhedra(QQ, 4).zero_element();  p
     212            A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex
     213            sage: p+p == p
     214            True
     215        """
     216        Vrep = [[[self.base_ring().zero()]*self.ambient_dim()], [], []]
     217        return self.element_class(self, Vrep, None)
     218
     219    @cached_method
     220    def Vrepresentation_space(self):
     221        r"""
     222        Return the ambient vector space.
     223
     224        This is the vector space or module containing the
     225        Vrepresentation vectors.
     226
     227        OUTPUT:
     228
     229        A free module over the base ring of dimension :meth:`ambient_dim`.
     230
     231        EXAMPLES::
     232
     233            sage: from sage.geometry.polyhedron.parent import Polyhedra
     234            sage: Polyhedra(QQ, 4).Vrepresentation_space()
     235            Vector space of dimension 4 over Rational Field
     236            sage: Polyhedra(QQ, 4).ambient_space()
     237            Vector space of dimension 4 over Rational Field
     238        """
     239        if is_Field(self.base_ring()):
     240            from sage.modules.free_module import VectorSpace
     241            return VectorSpace(self.base_ring(), self.ambient_dim())
     242        else:
     243            from sage.modules.free_module import FreeModule
     244            return FreeModule(self.base_ring(), self.ambient_dim())
     245
     246    ambient_space = Vrepresentation_space
     247
     248    @cached_method
     249    def Hrepresentation_space(self):
     250        r"""
     251        Return the linear space containing the H-representation vectors.
     252
     253        OUTPUT:
     254
     255        A free module over the base ring of dimension :meth:`ambient_dim` + 1.
     256
     257        EXAMPLES::
     258
     259            sage: from sage.geometry.polyhedron.parent import Polyhedra
     260            sage: Polyhedra(ZZ, 2).Hrepresentation_space()
     261            Ambient free module of rank 3 over the principal ideal domain Integer Ring
     262        """
     263        if is_Field(self.base_ring()):
     264            from sage.modules.free_module import VectorSpace
     265            return VectorSpace(self.base_ring(), self.ambient_dim()+1)
     266        else:
     267            from sage.modules.free_module import FreeModule
     268            return FreeModule(self.base_ring(), self.ambient_dim()+1)
     269
     270    def _repr_ambient_module(self):
     271        """
     272        Return an abbreviated string representation of the ambient
     273        space.
     274
     275        OUTPUT:
     276
     277        String.
     278
     279        EXAMPLES::
     280
     281            sage: from sage.geometry.polyhedron.parent import Polyhedra
     282            sage: Polyhedra(QQ, 3)._repr_ambient_module()
     283            'QQ^3'
     284        """
     285        if self.base_ring() is ZZ:
     286            s = 'ZZ'
     287        elif self.base_ring() is QQ:
     288            s = 'QQ'
     289        elif self.base_ring() is RDF:
     290            s = 'RDF'
     291        else:
     292            assert False
     293        s += '^' + repr(self.ambient_dim())
     294        return s
     295
     296    def _repr_(self):
     297        """
     298        Return a string representation.
     299
     300        OUTPUT:
     301
     302        String.
     303
     304        EXAMPLES::
     305
     306            sage: from sage.geometry.polyhedron.parent import Polyhedra
     307            sage: Polyhedra(QQ, 3)
     308            Polyhedra in QQ^3
     309            sage: Polyhedra(QQ, 3)._repr_()
     310            'Polyhedra in QQ^3'
     311        """
     312        return 'Polyhedra in '+self._repr_ambient_module()
     313
     314    def _element_constructor_(self, *args, **kwds):
     315        """
     316        The element (polyhedron) constructor.
     317
     318        INPUT:
     319
     320        - ``Vrep`` -- a list `[vertices, rays, lines]`` or ``None``.
     321
     322        - ``Hrep`` -- a list `[ieqs, eqns]`` or ``None``.
     323
     324        - ``**kwds`` -- optional keywords that are passed to the
     325          polyhedron constructor.
     326
     327        EXAMPLES::
     328
     329            sage: from sage.geometry.polyhedron.parent import Polyhedra
     330            sage: P = Polyhedra(QQ, 3)
     331            sage: P._element_constructor_([[(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [], []], None)
     332            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     333            sage: P([[(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [], []], None)
     334            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     335            sage: P(0)
     336            A 0-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex
     337        """
     338        nargs = len(args)
     339        if nargs==2:
     340            Vrep, Hrep = args
     341            return self.element_class(self, Vrep, Hrep, **kwds)
     342        if nargs==1 and is_Polyhedron(args[0]):
     343            polyhedron = args[0]
     344            Hrep = [ polyhedron.inequality_generator(), polyhedron.equation_generator() ]
     345            return self.element_class(self, None, Hrep, **kwds)
     346        if nargs==1 and args[0]==0:
     347            return self.zero_element()
     348        raise ValueError('Cannot convert to polyhedron object.')
     349
     350    def base_extend(self, base_ring, backend=None):
     351        """
     352        Return the base extended parent.
     353
     354        INPUT:
     355
     356        - ``base_ring``, ``backend`` -- see
     357          :func:`~sage.geometry.polyhedron.constructor.Polyhedron`.
     358
     359        EXAMPLES::
     360
     361            sage: from sage.geometry.polyhedron.parent import Polyhedra
     362            sage: Polyhedra(ZZ,3).base_extend(QQ)
     363            Polyhedra in QQ^3
     364            sage: Polyhedra(ZZ,3).an_element().base_extend(QQ)
     365            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     366        """
     367        if self.base_ring().has_coerce_map_from(base_ring):
     368            return self
     369        elif base_ring.has_coerce_map_from(self.base_ring()):
     370            return Polyhedra(base_ring, self.ambient_dim())
     371
     372    def _coerce_base_ring(self, other):
     373        """
     374        Return the common base rincg for both ``self`` and ``other``.
     375
     376        This method is not part of the coercion framework, but only a
     377        convenience function for :class:`Polyhedra_base`.
     378
     379        INPUT:
     380
     381        - ``other`` -- must be either:
     382
     383            * another ``Polyhedron`` object
     384
     385            * `\ZZ`, `\QQ`, `RDF`, or a ring that can be coerced into them.
     386
     387            * a constant that can be coerced to `\ZZ`, `\QQ`, or `RDF`.
     388
     389        OUTPUT:
     390
     391        Either `\ZZ`, `\QQ`, or `RDF`. Raises ``TypeError`` if
     392        ``other`` is not a suitable input.
     393
     394        .. NOTE::
     395
     396            "Real" numbers in sage are not necessarily elements of
     397            `RDF`. For example, the literal `1.0` is not.
     398
     399        EXAMPLES::
     400
     401            sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ).parent()
     402            sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF).parent()
     403            sage: triangle_QQ._coerce_base_ring(QQ)
     404            Rational Field
     405            sage: triangle_QQ._coerce_base_ring(triangle_RDF)
     406            Real Double Field
     407            sage: triangle_RDF._coerce_base_ring(triangle_QQ)
     408            Real Double Field
     409            sage: triangle_QQ._coerce_base_ring(RDF)
     410            Real Double Field
     411            sage: triangle_QQ._coerce_base_ring(ZZ)
     412            Rational Field
     413            sage: triangle_QQ._coerce_base_ring(1/2)
     414            Rational Field
     415            sage: triangle_QQ._coerce_base_ring(0.5)
     416            Real Double Field
     417        """
     418        try:
     419            other_ring = other.base_ring()
     420        except AttributeError:
     421            try:
     422                # other is a constant?
     423                other_ring = other.parent()
     424            except AttributeError:
     425                try:
     426                    ZZ.coerce(other)
     427                    other_ring = ZZ
     428                except TypeError:
     429                    pass
     430                try:
     431                    QQ.coerce(other)
     432                    other_ring = QQ
     433                except TypeError:
     434                    pass
     435                try:
     436                    RDF.coerce(other)
     437                    other_ring = RDF
     438                except TypeError:
     439                    other_ring = None
     440
     441        if not other_ring.is_exact():
     442            other_ring = RDF  # the only supported floating-point numbers for now
     443
     444        cm_map, cm_ring = get_coercion_model().analyse(self.base_ring(), other_ring)
     445        if cm_ring is None:
     446            raise TypeError('Could not coerce '+str(other)+' into ZZ, QQ, or RDF.')
     447        return cm_ring
     448
     449    def _coerce_map_from_(self, X):
     450        r"""
     451        Return whether there is a coercion from ``X``
     452
     453        INPUT:
     454
     455        - ``X`` -- anything.
     456
     457        OUTPUT:
     458
     459        Boolean.
     460
     461        EXAMPLE::
     462
     463            sage: from sage.geometry.polyhedron.parent import Polyhedra
     464            sage: Polyhedra(QQ,3).has_coerce_map_from( Polyhedra(ZZ,3) )   # indirect doctest
     465            True
     466            sage: Polyhedra(ZZ,3).has_coerce_map_from( Polyhedra(QQ,3) )
     467            False
     468        """
     469        if not isinstance(X, Polyhedra_base):
     470            return False
     471        if self.ambient_dim() != X.ambient_dim():
     472            return False
     473        return self.base_ring().has_coerce_map_from(X.base_ring())
     474
     475    def _get_action_(self, other, op, self_is_left):
     476        """
     477        Register actions with the coercion model.
     478
     479        The monoid actions are Minkowski sum and cartesian product. In
     480        addition, we want multiplication by a scalar to be dilation
     481        and addition by a vector to be translation. This is
     482        implemented as an action in the coercion model.
     483
     484        INPUT:
     485
     486        - ``other`` -- a scalar or a vector.
     487
     488        - ``op`` -- the operator.
     489
     490        - ``self_is_left`` -- boolean. Whether ``self`` is on the left
     491          of the operator.
     492
     493        OUTPUT:
     494
     495        An action that is used by the coercion model.
     496
     497        EXAMPLES::
     498
     499            sage: from sage.geometry.polyhedron.parent import Polyhedra
     500            sage: Polyhedra(ZZ,2).get_action(ZZ)   # indirect doctest
     501            Right action by Integer Ring on Polyhedra in ZZ^2
     502            sage: Polyhedra(ZZ,2).get_action(QQ)
     503            Right action by Rational Field on Polyhedra in QQ^2
     504            with precomposition on left by Conversion map:
     505              From: Polyhedra in ZZ^2
     506              To:   Polyhedra in QQ^2
     507            with precomposition on right by Identity endomorphism of Rational Field
     508            sage: Polyhedra(QQ,2).get_action(ZZ)
     509            Right action by Integer Ring on Polyhedra in QQ^2
     510            sage: Polyhedra(QQ,2).get_action(QQ)
     511            Right action by Rational Field on Polyhedra in QQ^2
     512
     513            sage: Polyhedra(ZZ,2).an_element() * 2
     514            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
     515            sage: Polyhedra(ZZ,2).an_element() * (2/3)
     516            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     517            sage: Polyhedra(QQ,2).an_element() * 2
     518            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     519            sage: Polyhedra(QQ,2).an_element() * (2/3)
     520            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     521
     522            sage: 2     * Polyhedra(ZZ,2).an_element()
     523            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
     524            sage: (2/3) * Polyhedra(ZZ,2).an_element()
     525            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     526            sage: 2     * Polyhedra(QQ,2).an_element()
     527            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     528            sage: (2/3) * Polyhedra(QQ,2).an_element()
     529            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     530
     531            sage: from sage.geometry.polyhedron.parent import Polyhedra
     532            sage: Polyhedra(ZZ,2).get_action( ZZ^2, op=operator.add)
     533            Right action by Ambient free module of rank 2 over the principal ideal
     534            domain Integer Ring on Polyhedra in ZZ^2
     535            with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2
     536            with precomposition on right by Free module morphism defined by the matrix
     537            [1 0]
     538            [0 1]
     539            Domain: Ambient free module of rank 2 over the principal ideal domain ...
     540            Codomain: Ambient free module of rank 2 over the principal ideal domain ...
     541        """
     542        import operator
     543        from sage.structure.coerce_actions import ActedUponAction
     544        from sage.categories.action import PrecomposedAction
     545
     546        if op is operator.add and is_FreeModule(other):
     547            base_ring = self._coerce_base_ring(other)
     548            extended_self = self.base_extend(base_ring)
     549            extended_other = other.base_extend(base_ring)
     550            action = ActedUponAction(extended_other, extended_self, not self_is_left)
     551            if self_is_left:
     552                action = PrecomposedAction(action,
     553                                           extended_self.coerce_map_from(self),
     554                                           extended_other.coerce_map_from(other))
     555            else:
     556                action = PrecomposedAction(action,
     557                                           extended_other.coerce_map_from(other),
     558                                           extended_self.coerce_map_from(self))
     559            return action
     560
     561        if op is operator.mul and is_CommutativeRing(other):
     562            ring = self._coerce_base_ring(other)
     563            if ring is self.base_ring():
     564                return ActedUponAction(other, self, not self_is_left)
     565            extended = self.base_extend(ring)
     566            action = ActedUponAction(ring, extended, not self_is_left)
     567            if self_is_left:
     568                action = PrecomposedAction(action,
     569                                           extended.coerce_map_from(self),
     570                                           ring.coerce_map_from(other))
     571            else:
     572                action = PrecomposedAction(action,
     573                                           ring.coerce_map_from(other),
     574                                           extended.coerce_map_from(self))
     575            return action
     576
     577    def _make_Inequality(self, polyhedron, data):
     578        """
     579        Create a new inequality object.
     580
     581        INPUT:
     582
     583        - ``polyhedron`` -- the new polyhedron.
     584
     585        - ``data`` -- the H-representation data.
     586
     587        OUTPUT:
     588
     589        A new :class:`~sage.geometry.polyhedron.representation.Inequality` object.
     590
     591        EXAMPLES::
     592
     593            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)])   # indirect doctest
     594            sage: p.inequality_generator().next()
     595            An inequality (0, 0, -1) x + 3 >= 0
     596        """
     597        try:
     598            obj = self._Inequality_pool.pop()
     599        except IndexError:
     600            obj = Inequality(self)
     601        obj._set_data(polyhedron, data)
     602        return obj
     603
     604    def _make_Equation(self, polyhedron, data):
     605        """
     606        Create a new equation object.
     607
     608        INPUT:
     609
     610        - ``polyhedron`` -- the new polyhedron.
     611
     612        - ``data`` -- the H-representation data.
     613
     614        OUTPUT:
     615
     616        A new :class:`~sage.geometry.polyhedron.representation.Equation` object.
     617
     618        EXAMPLES::
     619
     620            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)])   # indirect doctest
     621            sage: p.equation_generator().next()
     622            An equation (0, 44, -25) x - 13 == 0
     623        """
     624        try:
     625            obj = self._Equation_pool.pop()
     626        except IndexError:
     627            obj = Equation(self)
     628        obj._set_data(polyhedron, data)
     629        return obj
     630
     631    def _make_Vertex(self, polyhedron, data):
     632        """
     633        Create a new vertex object.
     634
     635        INPUT:
     636
     637        - ``polyhedron`` -- the new polyhedron.
     638
     639        - ``data`` -- the V-representation data.
     640
     641        OUTPUT:
     642
     643        A new :class:`~sage.geometry.polyhedron.representation.Vertex` object.
     644
     645        EXAMPLES::
     646
     647            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)])   # indirect doctest
     648            sage: p.vertex_generator().next()
     649            A vertex at (1, 2, 3)
     650        """
     651        try:
     652            obj = self._Vertex_pool.pop()
     653        except IndexError:
     654            obj = Vertex(self)
     655        obj._set_data(polyhedron, data)
     656        return obj
     657
     658    def _make_Ray(self, polyhedron, data):
     659        """
     660        Create a new ray object.
     661
     662        INPUT:
     663
     664        - ``polyhedron`` -- the new polyhedron.
     665
     666        - ``data`` -- the V-representation data.
     667
     668        OUTPUT:
     669
     670        A new :class:`~sage.geometry.polyhedron.representation.Ray` object.
     671
     672        EXAMPLES::
     673
     674            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)])   # indirect doctest
     675            sage: p.ray_generator().next()
     676            A ray in the direction (140, 144, 147)
     677        """
     678        try:
     679            obj = self._Ray_pool.pop()
     680        except IndexError:
     681            obj = Ray(self)
     682        obj._set_data(polyhedron, data)
     683        return obj
     684
     685    def _make_Line(self, polyhedron, data):
     686        """
     687        Create a new line object.
     688
     689        INPUT:
     690
     691        - ``polyhedron`` -- the new polyhedron.
     692
     693        - ``data`` -- the V-representation data.
     694
     695        OUTPUT:
     696
     697        A new :class:`~sage.geometry.polyhedron.representation.Line` object.
     698
     699        EXAMPLES::
     700
     701            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], lines=[(5/6,6/7,7/8)])   # indirect doctest
     702            sage: p.line_generator().next()
     703            A line in the direction (140, 144, 147)
     704        """
     705        try:
     706            obj = self._Line_pool.pop()
     707        except IndexError:
     708            obj = Line(self)
     709        obj._set_data(polyhedron, data)
     710        return obj
     711
     712
     713
     714from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd, Polyhedron_RDF_cdd
     715from sage.geometry.polyhedron.backend_ppl import Polyhedron_ZZ_ppl, Polyhedron_QQ_ppl
     716
     717class Polyhedra_ZZ_ppl(Polyhedra_base):
     718    Element = Polyhedron_ZZ_ppl
     719
     720class Polyhedra_QQ_ppl(Polyhedra_base):
     721    Element = Polyhedron_QQ_ppl
     722
     723class Polyhedra_QQ_cdd(Polyhedra_base):
     724    Element = Polyhedron_QQ_cdd
     725
     726class Polyhedra_RDF_cdd(Polyhedra_base):
     727    Element = Polyhedron_RDF_cdd
     728
  • sage/geometry/polyhedron/representation.py

    diff --git a/sage/geometry/polyhedron/representation.py b/sage/geometry/polyhedron/representation.py
    a b  
    1616from sage.structure.element import is_Vector
    1717from sage.rings.all import QQ, ZZ, RDF
    1818from sage.modules.free_module_element import vector
    19 from sage.misc.all import cached_method
    2019
    2120
    2221
     
    3938        You should not (and cannot) instantiate it yourself. You can
    4039        only obtain them from a Polyhedron() class.
    4140
     41    TESTS::
     42
     43            sage: import sage.geometry.polyhedron.representation as P
     44            sage: P.PolyhedronRepresentation()
     45            <class 'sage.geometry.polyhedron.representation.PolyhedronRepresentation'>
    4246    """
    4347   
    4448    # Numeric values for the output of the type() method
     
    4852    RAY = 3
    4953    LINE = 4
    5054   
    51     def __init__(self, polyhedron, data):
    52         """
    53         Initializes the PolyhedronRepresentation object.
    54        
    55         TESTS::
    56        
    57             sage: import sage.geometry.polyhedron.representation as P
    58             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    59             sage: tuple(pr)
    60             (1, 2, 3)
    61             sage: TestSuite(pr).run(skip='_test_pickling')
    62         """
    63         self._representation_data = tuple(data)
    64         self._polyhedron = polyhedron
    65 
    6655    def __len__(self):
    6756        """
    6857        Returns the length of the representation data.
    6958       
    7059        TESTS::
    7160       
    72             sage: import sage.geometry.polyhedron.representation as P
    73             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    74             sage: pr.__len__()
     61            sage: p = Polyhedron(vertices=[[1,2,3]])
     62            sage: v = p.Vrepresentation(0)
     63            sage: v.__len__()
    7564            3
    7665        """
    77         return len(self._representation_data)
     66        return self._vector.degree()
    7867
    7968    def __getitem__(self, i):
    8069        """
     
    8271       
    8372        TESTS::
    8473       
    85             sage: import sage.geometry.polyhedron.representation as P
    86             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    87             sage: pr.__getitem__(1)
     74            sage: p = Polyhedron(vertices=[[1,2,3]])
     75            sage: v = p.Vrepresentation(0)
     76            sage: v.__getitem__(1)
    8877            2
    8978        """
    90         return self._representation_data[i]
     79        return self._vector[i]
     80
     81    def __cmp__(self, other):
     82        """
     83        Compare two representation objects
     84
     85        They are equal if and only if they define the same
     86        vertex/ray/line or inequality/equation in the ambient space,
     87        regardless of the polyhedron that they belong to.
     88
     89        INPUT:
     90
     91        - ``other`` -- anything.
     92
     93        OUTPUT:
     94
     95        One of `-1`, `0`, `+1`.  ``True`` if and only if ``other`` represents the same
     96        H-representation object.
     97
     98        EXAMPLES::
     99
     100            sage: triangle = Polyhedron([(0,0), (1,0), (0,1)])
     101            sage: ieq = triangle.inequality_generator().next();  ieq
     102            An inequality (1, 0) x + 0 >= 0
     103            sage: ieq == copy(ieq)
     104            True
     105            sage: cmp(ieq, copy(ieq))
     106            0
     107
     108            sage: cmp(ieq, 'a string')
     109            -1
     110
     111            sage: square = Polyhedron([(0,0), (1,0), (0,1), (1,1)], base_ring=QQ)
     112            sage: cmp(square.Vrepresentation(0), triangle.Vrepresentation(0))
     113            0
     114
     115            sage: ieq = square.Hrepresentation(0);  ieq.vector()
     116            (0, 1, 0)
     117            sage: abs(cmp(ieq, Polyhedron([(0,1,0)]).Vrepresentation(0)))
     118            1
     119        """
     120        if not isinstance(other, PolyhedronRepresentation):
     121            return -1
     122        type_cmp = cmp(type(self), type(other))
     123        if (type_cmp != 0): return type_cmp
     124        return cmp(self._vector, other._vector)
     125
     126    def vector(self, base_ring=None):
     127        """
     128        Returns the vector representation of the H/V-representation object.
     129
     130        INPUT:
     131
     132        - ``base_ring`` -- the base ring of the vector.
     133
     134        OUTPUT:
     135
     136        For a V-representation object, a vector of length
     137        :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`. For
     138        a H-representation object, a vector of length
     139        :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`
     140        + 1.
     141
     142        EXAMPLES::
     143
     144            sage: s = polytopes.cuboctahedron()
     145            sage: v = s.vertex_generator().next()
     146            sage: v
     147            A vertex at (-1/2, -1/2, 0)
     148            sage: v.vector()
     149            (-1/2, -1/2, 0)
     150            sage: v()
     151            (-1/2, -1/2, 0)
     152            sage: type(v())
     153            <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
     154
     155       Conversion to a different base ring can be forced with the optional argument::
     156
     157            sage: v.vector(RDF)
     158            (-0.5, -0.5, 0.0)
     159            sage: vector(RDF, v)
     160            (-0.5, -0.5, 0.0)
     161        """
     162        if (base_ring is None) or (base_ring is self._base_ring):
     163            return self._vector
     164        else:
     165            return vector(base_ring, self._vector)
     166
     167    _vector_ = vector
    91168
    92169    def polyhedron(self):
    93170        """
     
    95172       
    96173        TESTS::
    97174       
    98             sage: import sage.geometry.polyhedron.representation as P
    99             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    100             sage: pr.polyhedron()
    101             A 0-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex
     175            sage: p = Polyhedron(vertices=[[1,2,3]])
     176            sage: v = p.Vrepresentation(0)
     177            sage: v.polyhedron()
     178            A 0-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex
    102179        """
    103180        return self._polyhedron
    104181
     
    107184        Returns the vector representation of the representation
    108185        object. Shorthand for the vector() method.
    109186
    110         Note that the vector() method is only implemented in derived
    111         classes.
    112 
    113187        TESTS::
    114188       
    115             sage: import sage.geometry.polyhedron.representation as P
    116             sage: pr = Polyhedron(vertices = [[1,2,3]]).Vrepresentation(0)
    117             sage: pr.__call__()
     189            sage: p = Polyhedron(vertices=[[1,2,3]])
     190            sage: v = p.Vrepresentation(0)
     191            sage: v.__call__()
    118192            (1, 2, 3)
    119            
    120             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    121             sage: pr.__call__()
    122             Traceback (most recent call last):
    123             ...
    124             AttributeError: 'PolyhedronRepresentation' object has no attribute 'vector'
    125193        """
    126         return self.vector()
     194        return self._vector
    127195
    128196    def index(self):
    129197        """
     
    149217        """
    150218        return self._index
    151219
     220    def __add__(self, coordinate_list):
     221        """
     222        Return the coordinates concatenated with ``coordinate_list``.
     223
     224        INPUT:
     225
     226        - ``coordinate_list`` -- a list.
     227
     228        OUTPUT:
     229
     230        The coordinates of ``self`` concatenated with ``coordinate_list``.
     231
     232        EXAMPLES::
     233
     234            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
     235            sage: v = p.Vrepresentation(0); v
     236            A vertex at (1, 0)
     237            sage: v + [4,5]
     238            [1, 0, 4, 5]
     239        """
     240        if not isinstance(coordinate_list, list):
     241            raise TypeError('Can only concatenate with a list of coordinates')
     242        return list(self) + coordinate_list
     243
     244    def __radd__(self, coordinate_list):
     245        """
     246        Return ``coordinate_list`` concatenated with the coordinates.
     247
     248        INPUT:
     249
     250        - ``coordinate_list`` -- a list.
     251
     252        OUTPUT:
     253
     254        ``coordinate_list`` concatenated with the coordinates of ``self``.
     255
     256        EXAMPLES::
     257
     258            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
     259            sage: v = p.Vrepresentation(0); v
     260            A vertex at (1, 0)
     261            sage: [4,5] + v
     262            [4, 5, 1, 0]
     263        """
     264        if not isinstance(coordinate_list, list):
     265            raise TypeError('Can only concatenate with a list of coordinates')
     266        return coordinate_list + list(self)
     267
     268    def count(self, i):
     269        """
     270        Count the number of occurrences of ``i`` in the coordinates.
     271
     272        INPUT:
     273
     274        - ``i`` -- Anything.
     275
     276        OUTPUT:
     277
     278        Integer. The number of occurrences of ``i`` in the coordinates.
     279
     280        EXAMPLES::
     281
     282            sage: p = Polyhedron(vertices=[(0,1,1,2,1)])
     283            sage: v = p.Vrepresentation(0); v
     284            A vertex at (0, 1, 1, 2, 1)
     285            sage: v.count(1)
     286            3
     287        """
     288        return sum([1 for j in self if i==j])
    152289
    153290
    154291class Hrepresentation(PolyhedronRepresentation):
     
    156293    The internal base class for H-representation objects of
    157294    a polyhedron. Inherits from ``PolyhedronRepresentation``.
    158295    """
    159     def __init__(self, polyhedron, data):
     296
     297    def __init__(self, polyhedron_parent):
     298        """
     299        Initializes the PolyhedronRepresentation object.
     300
     301        TESTS::
     302
     303            sage: from sage.geometry.polyhedron.representation import Hrepresentation
     304            sage: pr = Hrepresentation(Polyhedron(vertices = [[1,2,3]]).parent())
     305            sage: tuple(pr)
     306            (0, 0, 0, 0)
     307            sage: TestSuite(pr).run(skip='_test_pickling')
     308        """
     309        self._polyhedron_parent = polyhedron_parent
     310        self._base_ring = polyhedron_parent.base_ring()
     311        self._vector = polyhedron_parent.Hrepresentation_space()(0)
     312        self._A = polyhedron_parent.ambient_space()(0)
     313        self._b = polyhedron_parent.base_ring()(0)
     314        self._index = 0
     315
     316    def _set_data(self, polyhedron, data):
    160317        """
    161318        Initialization function.
    162319
     320        The H/V-representation objects are kept in a pool, and this
     321        function is used to reassign new values to already existing
     322        (but unused) objects. You must not call this function on
     323        objects that are in normal use.
     324
     325        INPUT:
     326
     327        - ``polyhedron`` -- the new polyhedron.
     328
     329        - ``data`` -- the H-representation data.
     330
    163331        TESTS::
    164332
    165333            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
    166             sage: pH = p.Hrepresentation(0)
     334            sage: pH = p.Hrepresentation(0) # indirect doctest
    167335            sage: TestSuite(pH).run(skip='_test_pickling')
    168336        """
    169         if len(data) != 1+polyhedron.ambient_dim():
     337        assert polyhedron.parent() is self._polyhedron_parent
     338        if len(data) != self._vector.degree():
    170339            raise ValueError, \
    171340                'H-representation data requires a list of length ambient_dim+1'
    172         super(Hrepresentation, self).__init__(polyhedron, data)
     341
     342        for i in range(0, self._vector.degree()):
     343            self._vector.set(i, data[i])
     344        for i in range(0, self._A.degree()):
     345            self._A.set(i, data[i+1])
     346        self._b = self._base_ring(data[0])
     347
    173348        self._index = len(polyhedron._Hrepresentation)
    174349        polyhedron._Hrepresentation.append(self)
    175    
    176     @cached_method
    177     def vector(self):
    178         """
    179         Returns the vector representation of the H-representation object.
    180 
    181         OUTPUT:
    182        
    183         A vector of length
    184         :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim` + 1.
    185 
    186         EXAMPLES::
    187 
    188             sage: s = polytopes.cuboctahedron()
    189             sage: v = s.vertex_generator().next()
    190             sage: v
    191             A vertex at (-1/2, -1/2, 0)
    192             sage: v.vector()
    193             (-1/2, -1/2, 0)
    194             sage: v()
    195             (-1/2, -1/2, 0)
    196             sage: type(v())
    197             <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
    198         """
    199         return self.polyhedron().Hrepresentation_space()(self._representation_data)
     350        self._polyhedron = polyhedron
    200351
    201352    def is_H(self):
    202353        """
     
    238389        """
    239390        return False
    240391   
    241     @cached_method
    242392    def A(self):
    243393        r"""
    244394        Returns the coefficient vector `A` in `A\vec{x}+b`.
     
    250400            sage: pH.A()
    251401            (1, 0)
    252402        """
    253         return self.polyhedron().ambient_space()(self._representation_data[1:])
     403        return self._A
    254404
    255     @cached_method
    256405    def b(self):
    257406        r"""
    258407        Returns the constant `b` in `A\vec{x}+b`.
     
    264413            sage: pH.b()
    265414            0
    266415        """
    267         return self._representation_data[0]
     416        return self._b
    268417
    269418    def neighbors(self):
    270419        """
     
    364513        if is_Vector(Vobj):
    365514            return self.A() * Vobj + self.b()
    366515        return Vobj.evaluated_on(self)
    367         #return self.A() * Vobj.vector() + self.b()
    368516
    369517    def incident(self):
    370518        """
     
    399547    A linear inequality (supporting hyperplane) of the
    400548    polyhedron. Inherits from ``Hrepresentation``.
    401549    """
    402     def __init__(self, polyhedron, data):
    403         """
    404         A linear inequality (supporting hyperplane) of the
    405         polyhedron. Inherits from ``Hrepresentation``.
    406 
    407         TESTS::
    408 
    409             sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
    410             sage: a = p.inequality_generator().next()
    411             sage: a
    412             An inequality (-1, 1, 0) x + 0 >= 0
    413             sage: TestSuite(a).run(skip='_test_pickling')
    414         """
    415         super(Inequality, self).__init__(polyhedron, data)
    416 
    417550
    418551    def type(self):
    419552        r"""
     
    558691    strictly smaller-dimensional than the ambient space, and contained
    559692    in this hyperplane. Inherits from ``Hrepresentation``.
    560693    """
    561     def __init__(self, polyhedron, data):
    562         """
    563         Initializes an equation object.
    564 
    565         TESTS::
    566 
    567             sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
    568             sage: a = p.equation_generator().next()
    569             sage: a
    570             An equation (0, 0, 1) x + 0 == 0
    571             sage: TestSuite(a).run(skip='_test_pickling')
    572         """
    573         super(Equation, self).__init__(polyhedron, data)
    574 
    575694
    576695    def type(self):
    577696        r"""
     
    692811    The base class for V-representation objects of a
    693812    polyhedron. Inherits from ``PolyhedronRepresentation``.
    694813    """
    695     def __init__(self, polyhedron, data):
     814
     815    def __init__(self, polyhedron_parent):
    696816        """
    697         Initialization function for the vertex representation.
     817        Initializes the PolyhedronRepresentation object.
    698818
    699819        TESTS::
    700820       
    701             sage: p = Polyhedron(ieqs = [[1, 0, 0, 0, 1], [1, 1, 0, 0, 0], [1, 0, 1, 0, 0]])
    702             sage: from sage.geometry.polyhedron.representation import Vrepresentation
    703             sage: p._Vrepresentation = Sequence([])
    704             sage: vr = Vrepresentation(p,[1,2,3,4])
    705             sage: vr.__init__(p,[1,2,3,5])
    706             sage: vr.vector()
    707             (1, 2, 3, 5)
    708             sage: TestSuite(vr).run(skip='_test_pickling')
     821            sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
     822            sage: a = p.inequality_generator().next()
     823            sage: a
     824            An inequality (-1, 1, 0) x + 0 >= 0
     825            sage: TestSuite(a).run(skip='_test_pickling')
    709826        """
    710         if len(data) != polyhedron.ambient_dim():
     827        self._polyhedron_parent = polyhedron_parent
     828        self._base_ring = polyhedron_parent.base_ring()
     829        self._vector = polyhedron_parent.Vrepresentation_space()(0)
     830        self._index = 0
     831
     832    def _set_data(self, polyhedron, data):
     833        """
     834        Initialization function.
     835
     836        The H/V-representation objects are kept in a pool, and this
     837        function is used to reassign new values to already existing
     838        (but unused) objects. You must not call this function on
     839        objects that are in normal use.
     840
     841        INPUT:
     842
     843        - ``polyhedron`` -- the new polyhedron.
     844
     845        - ``data`` -- the V-representation data.
     846
     847        TESTS::
     848
     849            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
     850            sage: pV = p.Vrepresentation(0)   # indirect doctest
     851            sage: TestSuite(pV).run(skip='_test_pickling')
     852        """
     853        assert polyhedron.parent() is self._polyhedron_parent
     854        if len(data) != self._vector.degree():
    711855            raise ValueError, \
    712856                'V-representation data requires a list of length ambient_dim'
    713         super(Vrepresentation, self).__init__(polyhedron, data)
     857
     858        for i in range(0, self._vector.degree()):
     859            self._vector.set(i, data[i])
     860
    714861        self._index = len(polyhedron._Vrepresentation)
    715862        polyhedron._Vrepresentation.append(self)
    716 
    717     @cached_method
    718     def vector(self):
    719         """
    720         Returns the vector representation of the V-representation object.
    721 
    722         OUTPUT:
    723        
    724         A vector of length
    725         :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`.
    726 
    727         EXAMPLES::
    728 
    729             sage: s = polytopes.cuboctahedron()
    730             sage: v = s.vertex_generator().next()
    731             sage: v
    732             A vertex at (-1/2, -1/2, 0)
    733             sage: v.vector()
    734             (-1/2, -1/2, 0)
    735             sage: v()
    736             (-1/2, -1/2, 0)
    737             sage: type(v())
    738             <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
    739         """
    740         return self.polyhedron().Vrepresentation_space()(self._representation_data)
     863        self._polyhedron = polyhedron
    741864
    742865    def is_V(self):
    743866        """
     
    9051028    """
    9061029    A vertex of the polyhedron. Inherits from ``Vrepresentation``.
    9071030    """
    908     def __init__(self, polyhedron, data):
    909         """
    910         Initializes the vertex object.
    911 
    912         TESTS::
    913 
    914             sage: p = Polyhedron(ieqs = [[0,0,1],[0,1,0],[1,-1,0]])
    915             sage: v1 = p.vertex_generator().next()
    916             sage: v1
    917             A vertex at (1, 0)
    918             sage: TestSuite(v1).run(skip='_test_pickling')
    919         """
    920         super(Vertex, self).__init__(polyhedron, data)
    921 
    9221031
    9231032    def type(self):
    9241033        r"""
     
    9981107        """
    9991108        return Hobj.A() * self.vector() + Hobj.b()
    10001109
    1001     @cached_method
    10021110    def is_integral(self):
    10031111        r"""
    10041112        Return whether the coordinates of the vertex are all integral.
     
    10131121            sage: [ v.is_integral() for v in p.vertex_generator() ]
    10141122            [True, False, True]
    10151123        """
    1016         return all(x in ZZ for x in self._representation_data)
     1124        return (self._base_ring is ZZ) or all(x in ZZ for x in self)
    10171125
    10181126
    10191127class Ray(Vrepresentation):
    10201128    """
    10211129    A ray of the polyhedron. Inherits from ``Vrepresentation``.
    10221130    """
    1023     def __init__(self, polyhedron, data):
    1024         """
    1025         Initializes a ray object.
    1026 
    1027         TESTS::
    1028 
    1029             sage: p = Polyhedron(ieqs = [[0,0,1],[0,1,0],[1,-1,0]])
    1030             sage: r1 = p.ray_generator().next()
    1031             sage: r1
    1032             A ray in the direction (0, 1)
    1033             sage: TestSuite(r1).run(skip='_test_pickling')
    1034         """
    1035         super(Ray, self).__init__(polyhedron, data)
    1036 
    10371131
    10381132    def type(self):
    10391133        r"""
     
    11111205    A line (Minkowski summand `\simeq\RR`) of the
    11121206    polyhedron. Inherits from ``Vrepresentation``.
    11131207    """
    1114     def __init__(self, polyhedron, data):
    1115         """
    1116         Initializes the line object.
    1117 
    1118         TESTS::
    1119 
    1120             sage: p = Polyhedron(ieqs = [[1, 0, 0, 1],[1,1,0,0]])
    1121             sage: a = p.line_generator().next()
    1122             sage: p._Vrepresentation = Sequence([])
    1123             sage: a.__init__(p,[1,2,3])
    1124             sage: a
    1125             A line in the direction (1, 2, 3)
    1126             sage: TestSuite(a).run(skip='_test_pickling')
    1127         """
    1128         super(Line, self).__init__(polyhedron, data)
    1129 
    11301208
    11311209    def type(self):
    11321210        r"""
     
    11571235        """
    11581236        return self.LINE
    11591237
    1160 
    11611238    def is_line(self):
    11621239        """
    11631240        Tests if the object is a line.  By construction it must be.
  • sage/geometry/triangulation/point_configuration.py

    diff --git a/sage/geometry/triangulation/point_configuration.py b/sage/geometry/triangulation/point_configuration.py
    a b  
    10721072
    10731073            sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
    10741074            sage: p.convex_hull()
    1075             A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1075            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
    10761076        """
    10771077        try:
    10781078            return self._polyhedron
     
    13351335
    13361336            sage: p = PointConfiguration([[0,0],[1,0],[2,1],[1,2],[0,1]])
    13371337            sage: poly = p.secondary_polytope()
    1338             sage: matrix(poly.vertices()).transpose()
     1338            sage: poly.vertices_matrix()
    13391339            [1 1 3 3 5]
    13401340            [3 5 1 4 1]
    13411341            [4 2 5 2 4]
  • sage/rings/polynomial/groebner_fan.py

    diff --git a/sage/rings/polynomial/groebner_fan.py b/sage/rings/polynomial/groebner_fan.py
    a b  
    10181018       
    10191019        INPUT:
    10201020       
    1021        
    1022         -  ``polyhedral_data`` - an object with 4d vertex and
    1023            adjacency information
    1024        
     1021        - ``polyhedral_data`` -- an object with 4d vertex and adjacency
     1022          information
    10251023       
    10261024        OUTPUT:
    10271025       
    1028        
    1029         -  ``edges`` - a list of edges in 3d - each list item
    1030            is a pair of points
    1031        
     1026        - ``edges`` -- a list of edges in 3d - each list item is a pair of
     1027          points
    10321028       
    10331029        EXAMPLES::
    10341030       
     
    10491045        """
    10501046        fpoints = polyhedral_data.vertices()
    10511047        tpoints = [self._embed_tetra(q) for q in fpoints]
    1052         adj_data = polyhedral_data.vertex_adjacencies()
    10531048        edges = []
    1054         for adj in adj_data:
    1055             for vert in adj[1]:
    1056                 if vert > adj[0]:
     1049        for vertex in polyhedral_data.vertices():
     1050            i = vertex.index()
     1051            for adjacent_vertex in vertex.adjacent():
     1052                j = adjacent_vertex.index()
     1053                if j>i:
    10571054                    try:
    1058                         edges.append([tpoints[adj[0]],tpoints[vert]])
     1055                        edges.append([tpoints[i],tpoints[j]])
    10591056                    except:
    10601057                        print adj
    10611058                        print 'tpoints: ' + str(tpoints)
    10621059                        print 'fpoints: ' + str(fpoints)
    1063                         print vert
     1060                        print adjacent_vertex
    10641061                        print polyhedral_data.ieqs()
    10651062                        raise RuntimeError, adj
    10661063        return edges
     
    11041101        #This is really just for debugging
    11051102        if verbose:
    11061103            for x in cone_info:
    1107                 print x.ieqs() + [[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]]
    1108                 print x.linearities()
     1104                print x.inequalities() + ([1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1])
     1105                print x.equations()
    11091106                print ""
    1110         cone_info = [Polyhedron(ieqs = x.ieqs() + [[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]], eqns = x.linearities()) for x in cone_info]
     1107        cone_info = [Polyhedron(ieqs = x.inequalities() +
     1108                                ([1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]),
     1109                                eqns = x.equations()) for x in cone_info]
    11111110        all_lines = []
    11121111        for cone_data in cone_info:
    11131112            try:
  • sage/rings/polynomial/multi_polynomial.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial.pyx b/sage/rings/polynomial/multi_polynomial.pyx
    a b  
    66
    77include "sage/ext/stdsage.pxi"
    88from sage.rings.integer cimport Integer
     9from sage.rings.integer_ring import ZZ
    910
    1011from sage.misc.derivative import multi_derivative
    1112from sage.rings.infinity import infinity
     
    864865            sage: f = 1 + x*y + x^3 + y^3
    865866            sage: P = f.newton_polytope()
    866867            sage: P
    867             A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     868            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
    868869            sage: P.is_simple()
    869870            True
    870871
     
    872873
    873874            sage: R.<x,y> = QQ[]
    874875            sage: R(0).newton_polytope()
    875             The empty polyhedron in QQ^0
     876            The empty polyhedron in ZZ^0
    876877            sage: R(1).newton_polytope()
    877             A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
    878            
     878            A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex
     879            sage: R(x^2+y^2).newton_polytope().integral_points()
     880            ((0, 2), (1, 1), (2, 0))
    879881        """
    880882        from sage.geometry.polyhedron.constructor import Polyhedron
    881883        e = self.exponents()
    882         P = Polyhedron(vertices = e)
     884        P = Polyhedron(vertices = e, base_ring=ZZ)
    883885        return P
    884886
    885887    def __iter__(self):
  • sage/rings/rational.pyx

    diff --git a/sage/rings/rational.pyx b/sage/rings/rational.pyx
    a b  
    292292    return (c, d) if not b_negative else (c, ~d)
    293293
    294294
     295def is_Rational(x):
     296    """
     297    Return true if x is of the Sage rational number type.
     298
     299    EXAMPLES::
     300
     301        sage: from sage.rings.rational import is_Rational
     302        sage: is_Rational(2)
     303        False
     304        sage: is_Rational(2/1)
     305        True
     306        sage: is_Rational(int(2))
     307        False
     308        sage: is_Rational(long(2))
     309        False
     310        sage: is_Rational('5')
     311        False
     312    """
     313    return isinstance(x, Rational)
     314
     315
    295316cdef class Rational(sage.structure.element.FieldElement):
    296317    """
    297318    A Rational number.