Ticket #11763: trac_11763-polyhedra_coercion_folded.2.2.patch

File trac_11763-polyhedra_coercion_folded.2.2.patch, 177.7 KB (added by vbraun, 7 years ago)

Updated patch

  • doc/en/reference/geometry.rst

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1315501129 14400
    # Node ID 9338adc952c4f9f076fea71fab01f2c71ebf903f
    # Parent  3d78fbfaa8f71438e22265d0b65e831bfc0d9045
    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  
    127127from highest_weight_crystals import HighestWeightCrystals
    128128from finite_crystals import FiniteCrystals
    129129from classical_crystals import ClassicalCrystals
     130
     131# polyhedra
     132from 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]`` or ``None``. The
    9591      V-representation of the polyhedron. If ``None``, the polyhedron
     
    107103        sage: TestSuite(p).run()
    108104    """
    109105
    110     def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
     106    def __init__(self, parent, Vrep, Hrep, **kwds):
    111107        """
    112108        Initializes the polyhedron.
    113109
     
    118114
    119115            sage: p = Polyhedron()    # indirect doctests
    120116        """
    121         self._ambient_dim = ambient_dim
     117        Element.__init__(self, parent=parent)
    122118        if Vrep is not None:
    123119            vertices, rays, lines = Vrep
    124             if len(vertices)==0:
    125                 vertices = [[0] * ambient_dim]
    126             self._init_from_Vrepresentation(ambient_dim, vertices, rays, lines, **kwds)
     120            self._init_from_Vrepresentation(vertices, rays, lines, **kwds)
    127121        elif Hrep is not None:
    128122            ieqs, eqns = Hrep
    129             self._init_from_Hrepresentation(ambient_dim, ieqs, eqns, **kwds)
     123            self._init_from_Hrepresentation(ieqs, eqns, **kwds)
    130124        else:
    131             self._init_empty_polyhedron(ambient_dim)
    132 
    133 
    134     def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, **kwds):
     125            self._init_empty_polyhedron()
     126
     127
     128    def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds):
    135129        """
    136130        Construct polyhedron from V-representation data.
    137131
    138132        INPUT:
    139133
    140         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    141        
    142134        - ``vertices`` -- list of point. Each point can be specified
    143135           as any iterable container of
    144136           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    155147
    156148            sage: p = Polyhedron()
    157149            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    158             sage: Polyhedron_base._init_from_Vrepresentation(p, 2, [], [], [])
     150            sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], [])
    159151            Traceback (most recent call last):
    160152            ...
    161153            NotImplementedError: A derived class must implement this method.
     
    163155        raise NotImplementedError('A derived class must implement this method.')
    164156
    165157
    166     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, **kwds):
     158    def _init_from_Hrepresentation(self, ieqs, eqns, **kwds):
    167159        """
    168160        Construct polyhedron from H-representation data.
    169161
    170162        INPUT:
    171163
    172         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    173        
    174164        - ``ieqs`` -- list of inequalities. Each line can be specified
    175165          as any iterable container of
    176166          :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    183173
    184174            sage: p = Polyhedron()
    185175            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    186             sage: Polyhedron_base._init_from_Hrepresentation(p, 2, [], [])
     176            sage: Polyhedron_base._init_from_Hrepresentation(p, [], [])
    187177            Traceback (most recent call last):
    188178            ...
    189179            NotImplementedError: A derived class must implement this method.
    190180        """
    191181        raise NotImplementedError('A derived class must implement this method.')
    192182
    193 
    194     def _init_empty_polyhedron(self, ambient_dim):
     183    def _init_empty_polyhedron(self):
    195184        """
    196185        Initializes an empty polyhedron.
    197186
    198         INPUT:
    199 
    200         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    201 
    202187        TESTS::
    203188
    204189            sage: empty = Polyhedron(); empty
    205             The empty polyhedron in QQ^0
     190            The empty polyhedron in ZZ^0
    206191            sage: empty.Vrepresentation()
    207192            ()
    208193            sage: empty.Hrepresentation()
    209194            (An equation -1 == 0,)
    210195            sage: Polyhedron(vertices = [])
    211             The empty polyhedron in QQ^0
    212             sage: Polyhedron()._init_empty_polyhedron(0)
     196            The empty polyhedron in ZZ^0
     197            sage: Polyhedron(vertices = [])._init_empty_polyhedron()
     198            sage: from sage.geometry.polyhedron.parent import Polyhedra
     199            sage: Polyhedra(QQ,7)()
     200            A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex
    213201        """
    214202        self._Vrepresentation = []
    215203        self._Hrepresentation = []
    216         Equation(self, [-1] + [0]*ambient_dim);
     204        self.parent()._make_Equation(self, [-1] + [0]*self.ambient_dim());
    217205        self._Vrepresentation = tuple(self._Vrepresentation)
    218206        self._Hrepresentation = tuple(self._Hrepresentation)
    219207
    220         self._V_adjacency_matrix = matrix(ZZ, 0, 0, 0)
    221         self._V_adjacency_matrix.set_immutable()
    222 
    223         self._H_adjacency_matrix = matrix(ZZ, 1, 1, 0)
    224         self._H_adjacency_matrix.set_immutable()
    225 
    226 
    227     def _init_facet_adjacency_matrix(self):
     208        V_matrix = matrix(ZZ, 0, 0, 0)
     209        V_matrix.set_immutable()
     210        self.vertex_adjacency_matrix.set_cache(V_matrix)
     211
     212        H_matrix = matrix(ZZ, 1, 1, 0)
     213        H_matrix.set_immutable()
     214        self.facet_adjacency_matrix.set_cache(H_matrix)
     215
     216    def _facet_adjacency_matrix(self):
    228217        """
    229218        Compute the facet adjacency matrix in case it has not been
    230219        computed during initialization.
     
    232221        EXAMPLES::
    233222       
    234223            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
    235             sage: '_H_adjacency_matrix' in p.__dict__
    236             False
    237             sage: p._init_facet_adjacency_matrix()
    238             sage: p._H_adjacency_matrix
     224            sage: p._facet_adjacency_matrix()
    239225            [0 1 1]
    240226            [1 0 1]
    241227            [1 1 0]
     
    256242            Hrep = face.element.ambient_Hrepresentation()
    257243            if len(Hrep) == 2:
    258244                set_adjacent(Hrep[0], Hrep[1])
    259 
    260         self._H_adjacency_matrix = M
    261 
    262 
    263     def _init_vertex_adjacency_matrix(self):
     245        return M
     246
     247    def _vertex_adjacency_matrix(self):
    264248        """
    265249        Compute the vertex adjacency matrix in case it has not been
    266250        computed during initialization.
     
    268252        EXAMPLES::
    269253       
    270254            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
    271             sage: '_V_adjacency_matrix' in p.__dict__
    272             False
    273             sage: p._init_vertex_adjacency_matrix()
    274             sage: p._V_adjacency_matrix
     255            sage: p._vertex_adjacency_matrix()
    275256            [0 1 1]
    276257            [1 0 1]
    277258            [1 1 0]
     
    299280        for r in self.ray_generator():
    300281            for vrep in self.Vrep_generator():
    301282                set_adjacent(r, vrep)
    302                
    303         self._V_adjacency_matrix = M
    304 
    305 
    306     def __lt__(self, other):
     283        return M
     284
     285    def delete(self):
    307286        """
    308         Test whether ``self`` is a strict sub-polyhedron of ``other``.
     287        Delete this polyhedron.
     288
     289        This speeds up creation of new polyhedra by reusing
     290        objects. After recycling a polyhedron object, it is not in a
     291        consistent state any more and neither the polyhedron nor its
     292        H/V-representation objects may be used any more.
     293
     294        .. seealso:: :meth:`~sage.geometry.polyhedron.Polyhedra_base.recycle`
     295
     296
     297        EXAMPLES::
     298
     299            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
     300            sage: p.delete()
     301
     302            sage: def loop_polyhedra():
     303            ...       for i in range(0,100):
     304            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     305
     306            sage: timeit('loop_polyhedra()', repeat=25)                   # random output
     307            5 loops, best of 25: 44.2 ms per loop
     308
     309            sage: def loop_polyhedra_with_recycling():
     310            ...       for i in range(0,100):
     311            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     312            ...           p.delete()
     313
     314            sage: timeit('loop_polyhedra_with_recycling()', repeat=25)    # random output
     315            25 loops, best of 25: 36.3 ms per loop
     316        """
     317        self.parent().recycle(self)
     318        self._Hrepresentation = None
     319        self._Vrepresentation = None
     320
     321    def base_extend(self, base_ring, backend=None):
     322        """
     323        EXAMPLES::
     324
     325            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ);  P
     326            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray
     327            sage: P.base_extend(QQ)
     328            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
     329        """
     330        new_parent = self.parent().base_extend(base_ring, backend)
     331        return new_parent(self)
     332
     333    def __cmp__(self, other):
     334        """
     335        Compare ``self`` and ``other``.
    309336
    310337        INPUT:
    311338
    312         - ``other`` -- a :class:`Polyhedron`.
     339        - ``other`` -- anything.
    313340
    314341        OUTPUT:
    315342
    316         Boolean.
     343        `-1, 0, +1` depending on how ``self`` and ``other``
     344        compare. If ``other`` is a polyhedron, then the comparison
     345        operator "less or equal than" means "is contained in", and
     346        "less than" means "is strictly contained in".
    317347
    318348        EXAMPLES::
    319349
    320350            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    321351            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    322             sage: P < Q   # indirect doctest
     352            sage: abs(cmp(P,Q))
     353            1
     354            sage: abs(cmp(Q,P))
     355            1
     356            sage: cmp(P,P)
     357            0
     358            sage: abs(cmp(P, 'anything'))
     359            1
     360
     361       The polytope ``Q`` is contained in ``P``::
     362
     363            sage: P > Q
     364            True
     365            sage: P < Q
    323366            False
    324             sage: P < P   # indirect doctest
    325             False
    326             sage: Q < P   # indirect doctest
    327             True
    328         """
    329         return self._is_subpolyhedron(other) and not other._is_subpolyhedron(self)
    330 
    331 
    332     def __le__(self, other):
    333         """
    334         Test whether ``self`` is a (not necessarily strict)
    335         sub-polyhedron of ``other``.
    336 
    337         INPUT:
    338 
    339         - ``other`` -- a :class:`Polyhedron`.
    340 
    341         OUTPUT:
    342 
    343         Boolean.
    344 
    345         EXAMPLES::
    346 
    347             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    348             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    349             sage: P <= Q   # indirect doctest
    350             False
    351             sage: P <= P   # indirect doctest
    352             True
    353             sage: Q <= P   # indirect doctest
    354             True
    355         """
    356         return self._is_subpolyhedron(other)
    357        
    358 
    359     def __eq__(self, other):
    360         """
    361         Test whether ``self`` is a strict sub-polyhedron of ``other``.
    362 
    363         INPUT:
    364 
    365         - ``other`` -- a :class:`Polyhedron`.
    366 
    367         OUTPUT:
    368 
    369         Boolean.
    370 
    371         EXAMPLES::
    372 
    373             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    374             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    375             sage: P == Q   # indirect doctest
    376             False
    377             sage: P == P   # indirect doctest
    378             True
    379             sage: Q == P   # indirect doctest
     367            sage: P == Q
    380368            False
    381369        """
    382         return self._is_subpolyhedron(other) and other._is_subpolyhedron(self)
    383 
    384 
    385     def __ne__(self, other):
    386         """
    387         Test whether ``self`` is not equal to ``other``.
    388 
    389         INPUT:
    390 
    391         - ``other`` -- a :class:`Polyhedron`.
    392 
    393         OUTPUT:
    394 
    395         Boolean.
    396 
    397         EXAMPLES::
    398 
    399             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    400             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    401             sage: P != Q   # indirect doctest
    402             True
    403             sage: P != P   # indirect doctest
    404             False
    405             sage: Q != P   # indirect doctest
    406             True
    407         """
    408         return not self.__eq__(other)
    409 
    410 
    411     def __gt__(self, other):
    412         """
    413         Test whether ``self`` is a strict super-polyhedron of ``other``.
    414 
    415         INPUT:
    416 
    417         - ``other`` -- a :class:`Polyhedron`.
    418 
    419         OUTPUT:
    420 
    421         Boolean.
    422 
    423         EXAMPLES::
    424 
    425             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    426             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    427             sage: P > Q   # indirect doctest
    428             True
    429             sage: P > P   # indirect doctest
    430             False
    431             sage: Q > P   # indirect doctest
    432             False
    433         """
    434         return other._is_subpolyhedron(self) and not self._is_subpolyhedron(other)
    435 
    436 
    437     def __ge__(self, other):
    438         """
    439         Test whether ``self`` is a (not necessarily strict)
    440         super-polyhedron of ``other``.
    441 
    442         INPUT:
    443 
    444         - ``other`` -- a :class:`Polyhedron`.
    445 
    446         OUTPUT:
    447 
    448         Boolean.
    449 
    450         EXAMPLES::
    451 
    452             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    453             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    454             sage: P >= Q   # indirect doctest
    455             True
    456             sage: P >= P   # indirect doctest
    457             True
    458             sage: Q >= P   # indirect doctest
    459             False
    460         """
    461         return other._is_subpolyhedron(self)
    462 
    463 
     370        c = cmp(self.ambient_dim(), other.ambient_dim())
     371        if c != 0: return c
     372        c0 = self._is_subpolyhedron(other)
     373        c1 = other._is_subpolyhedron(self)
     374        if c0 and c1:
     375            return 0
     376        if c0:
     377            return -1
     378        else:
     379            return +1
     380
     381    @coerce_binop
    464382    def _is_subpolyhedron(self, other):
    465383        """
    466384        Test whether ``self`` is a (not necessarily strict)
     
    483401            sage: Q._is_subpolyhedron(P)
    484402            True
    485403        """
    486         if not is_Polyhedron(other):
    487             raise ValueError('Can only compare Polyhedron objects.')
    488404        return all( other_H.contains(self_V)
    489405                    for other_H, self_V in
    490406                    CartesianProduct(other.Hrep_generator(), self.Vrep_generator()) )
    491        
    492407
    493408    def plot(self, **kwds):
    494409        """
     
    519434        raise NotImplementedError('Plotting of '+str(self.ambient_dim())+
    520435                                  '-dimensional polyhedra not implemented')
    521436
    522 
    523437    show = plot
    524438
    525 
    526439    def _repr_(self):
    527440        """
    528441        Return a description of the polyhedron.
     
    531444
    532445            sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]])
    533446            sage: poly_test._repr_()
    534             'A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices'
     447            'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices'
    535448            sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]])
    536449            sage: grammar_test._repr_()
    537             'A 0-dimensional polyhedron in QQ^6 defined as the convex hull of 1 vertex'
     450            'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex'
    538451        """
    539452        desc = ''
    540453        if self.n_vertices()==0:
     
    542455        else:
    543456            desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron'
    544457        desc += ' in '
    545         if self.field()==QQ: desc += 'QQ'
    546         else:                desc += 'RDF'
     458        if   self.base_ring() is QQ:  desc += 'QQ'
     459        elif self.base_ring() is ZZ:  desc += 'ZZ'
     460        elif self.base_ring() is RDF: desc += 'RDF'
     461        else: assert False
    547462        desc += '^' + repr(self.ambient_dim())
    548463
    549464        if self.n_vertices()>0:
     
    568483
    569484        return desc
    570485
    571 
    572486    def cdd_Hrepresentation(self):
    573487        """
    574488        Write the inequalities/equations data of the polyhedron in
     
    596510        try:
    597511            cdd_type = self._cdd_type
    598512        except AttributeError:
    599             ring_to_cdd = { QQ:'rational', RDF:'real' }
    600             cdd_type = ring_to_cdd[self.base_ring()]
     513            if self.base_ring() is ZZ or self.base_ring() is QQ:
     514                cdd_type = 'rational'
     515            elif self.base_ring() is RDF:
     516                cdd_type = 'real'
     517            else:
     518                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    601519        return cdd_Hrepresentation(cdd_type,
    602520                                   list(self.inequality_generator()),
    603521                                   list(self.equation_generator()) )
    604522
    605 
    606523    def cdd_Vrepresentation(self):
    607524        """
    608525        Write the vertices/rays/lines data of the polyhedron in cdd's
     
    630547        try:
    631548            cdd_type = self._cdd_type
    632549        except AttributeError:
    633             ring_to_cdd = { QQ:'rational', RDF:'real' }
    634             cdd_type = ring_to_cdd[self.base_ring()]
     550            if self.base_ring() is ZZ or self.base_ring() is QQ:
     551                cdd_type = 'rational'
     552            elif self.base_ring() is RDF:
     553                cdd_type = 'real'
     554            else:
     555                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    635556        return cdd_Vrepresentation(cdd_type,
    636557                                   list(self.vertex_generator()),
    637558                                   list(self.ray_generator()),
    638559                                   list(self.line_generator()) )
    639560
    640 
     561    @cached_method
    641562    def n_equations(self):
    642563        """
    643564        Return the number of equations. The representation will
     
    650571            sage: p.n_equations()
    651572            1
    652573        """
    653         try:
    654             return self._n_equations
    655         except AttributeError:
    656             self._n_equations = len(self.equations())
    657             return self._n_equations
    658 
    659 
     574        return len(self.equations())
     575
     576    @cached_method
    660577    def n_inequalities(self):
    661578        """
    662579        Return the number of inequalities. The representation will
     
    668585            sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]])
    669586            sage: p.n_inequalities()
    670587            3
    671         """
    672         try:
    673             return self._n_inequalities
    674         except AttributeError:
    675             self._n_inequalities = 0
    676             for i in self.inequalities(): self._n_inequalities += 1
    677             return self._n_inequalities
    678 
    679 
    680     def n_facets(self):
    681         """
    682         Return the number of facets in the polyhedron.  This is the
    683         same as the n_inequalities function.
    684 
    685         EXAMPLES::
    686588
    687589            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)])
    688590            sage: p.n_facets()
    689591            8
    690592        """
    691         return self.n_inequalities()
    692 
    693 
     593        return len(self.inequalities())
     594
     595    n_facets = n_inequalities
     596
     597    @cached_method
    694598    def n_vertices(self):
    695599        """
    696600        Return the number of vertices. The representation will
     
    702606            sage: p.n_vertices()
    703607            2
    704608        """
    705         try:
    706             return self._n_vertices
    707         except AttributeError:
    708             self._n_vertices = 0
    709             for v in self.vertex_generator(): self._n_vertices += 1
    710             return self._n_vertices
    711 
    712 
     609        return len(self.vertices())
     610
     611    @cached_method
    713612    def n_rays(self):
    714613        """
    715614        Return the number of rays. The representation will
     
    721620            sage: p.n_rays()
    722621            1
    723622        """
    724         try:
    725             return self._n_rays
    726         except AttributeError:
    727             self._n_rays = 0
    728             for r in self.rays(): self._n_rays += 1
    729             return self._n_rays
    730 
    731 
     623        return len(self.rays())
     624
     625    @cached_method
    732626    def n_lines(self):
    733627        """
    734628        Return the number of lines. The representation will
     
    740634            sage: p.n_lines()
    741635            1
    742636        """
    743         try:
    744             return self._n_lines
    745         except AttributeError:
    746             self._n_lines = len(self.lines())
    747             return self._n_lines
    748 
     637        return len(self.lines())
    749638
    750639    def Hrepresentation(self, index=None):
    751640        """
     
    771660            sage: p.Hrepresentation(0) == p.Hrepresentation() [0]
    772661            True
    773662        """
    774         if index==None:
     663        if index is None:
    775664            return self._Hrepresentation
    776665        else:
    777666            return self._Hrepresentation[index]
     
    791680        for H in self.Hrepresentation():
    792681            yield H
    793682
    794 
     683    @cached_method
    795684    def n_Hrepresentation(self):
    796685        """
    797686        Return the number of objects that make up the
     
    811700        """
    812701        return len(self.Hrepresentation())
    813702
    814 
    815703    def Vrepresentation(self, index=None):
    816704        """
    817705        Return the objects of the V-representation. Each entry is
     
    836724            sage: p.Vrepresentation(0) == p.Vrepresentation() [0]
    837725            True
    838726        """
    839         if index==None:
     727        if index is None:
    840728            return self._Vrepresentation
    841729        else:
    842730            return self._Vrepresentation[index]
    843731
    844 
     732    @cached_method
    845733    def n_Vrepresentation(self):
    846734        """
    847735        Return the number of objects that make up the
     
    861749        """
    862750        return len(self.Vrepresentation())
    863751
    864 
    865752    def Vrep_generator(self):
    866753        """
    867754        Returns an iterator over the objects of the V-representation
     
    879766        for V in self.Vrepresentation():
    880767            yield V
    881768
    882 
    883769    def facial_adjacencies(self):
    884         """
     770        r"""
    885771        Return the list of face indices (i.e. indices of
    886772        H-representation objects) and the indices of faces adjacent to
    887773        them.
     
    896782
    897783            sage: p = polytopes.permutahedron(4)
    898784            sage: p.facial_adjacencies()[0:3]
     785            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is deprecated.
     786            Use self.Hrepresentation(i).neighbors() instead.
    899787            [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]]
    900788            sage: f0 = p.Hrepresentation(0)
    901789            sage: f0.index() == 0
     
    904792            sage: p.facial_adjacencies()[0] == f0_adjacencies
    905793            True
    906794        """
     795        from sage.misc.misc import deprecation
     796        deprecation('This method is deprecated. Use self.Hrepresentation(i).neighbors() instead.',
     797                    'Sage Version 4.7.2')
    907798        try:
    908799            return self._facial_adjacencies
    909800        except AttributeError:
     
    913804                  ] for h in self.Hrepresentation() ]
    914805            return self._facial_adjacencies
    915806
    916 
    917807    def facial_incidences(self):
    918808        """
    919809        Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`.
     
    935825
    936826            sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]])
    937827            sage: p.facial_incidences()
     828            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     829            deprecated. Use self.Hrepresentation(i).incident() instead.
    938830            [[0, [0, 1, 3, 4]],
    939831             [1, [0, 1, 2]],
    940832             [2, [0, 2, 3]],
     
    959851            sage: p.incidence_matrix().column(4)
    960852            (0, 1, 1, 0, 1)
    961853        """
     854        from sage.misc.misc import deprecation
     855        deprecation('This method is deprecated. Use self.Hrepresentation(i).incident() instead.',
     856                    'Sage Version 4.7.2')
    962857        try:
    963858            return self._facial_incidences
    964859        except AttributeError:
     
    968863                  ] for h in self.Hrepresentation() ]
    969864            return self._facial_incidences
    970865
    971 
    972866    def vertex_adjacencies(self):
    973867        """
    974868        Return a list of vertex indices and their adjacent vertices.
     
    987881
    988882            sage: permuta3 = Polyhedron(vertices = permutations([1,2,3,4]))
    989883            sage: permuta3.vertex_adjacencies()[0:3]
     884            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     885            deprecated. Use self.Vrepresentation(i).neighbors() instead.
    990886            [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]]
    991887            sage: v0 = permuta3.Vrepresentation(0)
    992888            sage: v0.index() == 0
     
    997893            sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies
    998894            True
    999895        """
     896        from sage.misc.misc import deprecation
     897        deprecation('This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.',
     898                    'Sage Version 4.7.2')
    1000899        try:
    1001900            return self._vertex_adjacencies
    1002901        except AttributeError:
     
    1006905                  ] for v in self.Vrepresentation() ]
    1007906            return self._vertex_adjacencies
    1008907
    1009 
    1010908    def vertex_incidences(self):
    1011909        """
    1012910        Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`.
     
    1021919
    1022920            sage: p = polytopes.n_simplex(3)
    1023921            sage: p.vertex_incidences()
     922            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     923            deprecated. Use self.Vrepresentation(i).incident() instead.
    1024924            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    1025925            sage: v0 = p.Vrepresentation(0)
    1026926            sage: v0.index() == 0
     
    1028928            sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ]
    1029929            True
    1030930        """
     931        from sage.misc.misc import deprecation
     932        deprecation('This method is deprecated. Use self.Vrepresentation(i).incident() instead.',
     933                    'Sage Version 4.7.2')
    1031934        try:
    1032935            return self._vertex_incidences
    1033936        except AttributeError:
     
    1037940                  ] for v in self.Vrepresentation() ]
    1038941            return self._vertex_incidences
    1039942
    1040 
    1041943    def inequality_generator(self):
    1042944        """
    1043945        Return  a generator for the defining inequalities of the
     
    1065967            if H.is_inequality():
    1066968                yield H
    1067969
    1068 
     970    @cached_method
    1069971    def inequalities(self):
    1070972        """
     973        Return all inequalities.
     974
     975        OUTPUT:
     976
     977        A tuple of inequalities.
     978
     979        EXAMPLES::
     980
     981            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
     982            sage: p.inequalities()[0:3]
     983            (An inequality (1, 0, 0) x + 0 >= 0,
     984             An inequality (0, 1, 0) x + 0 >= 0,
     985             An inequality (0, 0, 1) x + 0 >= 0)
     986            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
     987            sage: ieqs = p3.inequalities()
     988            sage: ieqs[0]
     989            An inequality (0, 1, 1, 1) x - 6 >= 0
     990            sage: list(_)
     991            [-6, 0, 1, 1, 1]
     992        """
     993        return tuple(self.inequality_generator())
     994
     995    def inequalities_list(self):
     996        """
    1071997        Return a list of inequalities as coefficient lists.
    1072998
    1073999        .. NOTE::
    10741000       
    1075             It is recommended to use :meth:`inequality_generator`
    1076             instead to iterate over the list of :class:`Inequality`
    1077             objects.
     1001            It is recommended to use :meth:`inequalities` or
     1002            :meth:`inequality_generator` instead to iterate over the
     1003            list of :class:`Inequality` objects.
    10781004
    10791005        EXAMPLES::
    10801006
    10811007            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
    1082             sage: p.inequalities()[0:3]
     1008            sage: p.inequalities_list()[0:3]
    10831009            [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    10841010            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    1085             sage: ieqs = p3.inequalities()
     1011            sage: ieqs = p3.inequalities_list()
    10861012            sage: ieqs[0]
    10871013            [-6, 0, 1, 1, 1]
    10881014            sage: ieqs[-1]
     
    10901016            sage: ieqs == [list(x) for x in p3.inequality_generator()]
    10911017            True
    10921018        """
    1093         try:
    1094             return self._inequalities
    1095         except AttributeError:
    1096             self._ieqs = [list(x) for x in self.inequality_generator()]
    1097             return self._ieqs
    1098 
     1019        return [list(x) for x in self.inequality_generator()]
    10991020
    11001021    def ieqs(self):
    11011022        """
     
    11051026         
    11061027            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    11071028            sage: p3.ieqs() == p3.inequalities()
     1029            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1030            deprecated. Use inequalities() instead.
    11081031            True
    11091032        """
     1033        from sage.misc.misc import deprecation
     1034        deprecation('This method is deprecated. Use inequalities() instead.',
     1035                    'Sage Version 4.7.2')
    11101036        return self.inequalities()
    11111037
    1112 
    11131038    def equation_generator(self):
    11141039        """
    11151040        Return a generator for the linear equations satisfied by the
     
    11261051            if H.is_equation():
    11271052                yield H
    11281053
    1129 
     1054    @cached_method
    11301055    def equations(self):
    11311056        """
     1057        Return all linear constraints of the polyhedron.
     1058
     1059        OUTPUT:
     1060
     1061        A tuple of equations.
     1062
     1063        EXAMPLES::
     1064
     1065            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
     1066            sage: test_p.equations()
     1067            (An equation (1, 1, 1, 1) x - 10 == 0,)
     1068        """
     1069        return tuple(self.equation_generator())
     1070
     1071    def equations_list(self):
     1072        """
    11321073        Return the linear constraints of the polyhedron. As with
    11331074        inequalities, each constraint is given as [b -a1 -a2 ... an]
    11341075        where for variables x1, x2,..., xn, the polyhedron satisfies
     
    11361077
    11371078        .. NOTE::
    11381079       
    1139             It is recommended to use :meth:`equation_generator()` instead
    1140             to iterate over the list of :class:`Equation` objects.
     1080            It is recommended to use :meth:`equations` or
     1081            :meth:`equation_generator()` instead to iterate over the
     1082            list of
     1083            :class:`~sage.geometry.polyhedron.representation.Equation`
     1084            objects.
    11411085
    11421086        EXAMPLES::
    11431087
    11441088            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    1145             sage: test_p.equations()
     1089            sage: test_p.equations_list()
    11461090            [[-10, 1, 1, 1, 1]]
    11471091        """
    1148         try:
    1149             return self._equations
    1150         except:
    1151             self._equations = [list(eq) for eq in self.equation_generator()]
    1152             return self._equations
    1153 
     1092        return [list(eq) for eq in self.equation_generator()]
    11541093
    11551094    def linearities(self):
    11561095        """
     
    11641103
    11651104            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    11661105            sage: test_p.linearities()
     1106            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1107            deprecated. Use equations_list() instead.
    11671108            [[-10, 1, 1, 1, 1]]
    1168             sage: test_p.linearities() == test_p.equations()
     1109            sage: test_p.linearities() == test_p.equations_list()
    11691110            True
    11701111        """
    1171         return self.equations()
    1172 
    1173 
    1174     def vertices(self):
     1112        from sage.misc.misc import deprecation
     1113        deprecation('This method is deprecated. Use equations_list() instead.',
     1114                    'Sage Version 4.7.2')
     1115        return self.equations_list()
     1116
     1117    def vertices_list(self):
    11751118        """
    11761119        Return a list of vertices of the polyhedron.
    11771120
     
    11831126        EXAMPLES::
    11841127
    11851128            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
    1186             sage: triangle.vertices()
     1129            sage: triangle.vertices_list()
    11871130            [[0, 1], [1, 0], [1, 1]]
    11881131            sage: a_simplex = Polyhedron(ieqs = [
    11891132            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
    11901133            ...        ], eqns = [[1,-1,-1,-1,-1]])
    1191             sage: a_simplex.vertices()
     1134            sage: a_simplex.vertices_list()
    11921135            [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    1193             sage: a_simplex.vertices() == [list(v) for v in a_simplex.vertex_generator()]
     1136            sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()]
    11941137            True
    11951138        """
    1196         try:
    1197             return self._vertices
    1198         except:
    1199             self._vertices = [list(x) for x in self.vertex_generator()]
    1200             return self._vertices
    1201 
     1139        return [list(x) for x in self.vertex_generator()]
    12021140       
    12031141    def vertex_generator(self):
    12041142        """
     
    12291167        for V in self.Vrepresentation():
    12301168            if V.is_vertex():
    12311169                yield V
     1170
     1171    @cached_method
     1172    def vertices(self):
     1173        """
     1174        Return all vertices of the polyhedron.
     1175
     1176        OUTPUT:
     1177
     1178        A tuple of vertices.
     1179
     1180        EXAMPLES::
     1181
     1182            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1183            sage: triangle.vertices()
     1184            (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1))
     1185            sage: a_simplex = Polyhedron(ieqs = [
     1186            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
     1187            ...        ], eqns = [[1,-1,-1,-1,-1]])
     1188            sage: a_simplex.vertices()
     1189            (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0),
     1190             A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1))
     1191        """
     1192        return tuple(self.vertex_generator())
     1193
     1194    @cached_method
     1195    def vertices_matrix(self, base_ring=None):
     1196        """
     1197        Return the coordinates of the vertices as the columns of a matrix.
     1198
     1199        INPUT:
    12321200       
     1201        - ``base_ring`` -- A ring or ``None`` (default). The base ring
     1202          of the returned matrix. If not specified, the base ring of
     1203          the polyhedron is used.
     1204
     1205        OUTPUT:
     1206
     1207        A matrix over ``base_ring`` whose columns are the coordinates
     1208        of the vertices. A ``TypeError`` is raised if the coordinates
     1209        cannot be converted to ``base_ring``.
     1210
     1211        EXAMPLES::
     1212
     1213            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1214            sage: triangle.vertices_matrix()
     1215            [0 1 1]
     1216            [1 0 1]
     1217            sage: (triangle/2).vertices_matrix()
     1218            [  0 1/2 1/2]
     1219            [1/2   0 1/2]
     1220            sage: (triangle/2).vertices_matrix(ZZ)
     1221            Traceback (most recent call last):
     1222            ...
     1223            TypeError: no conversion of this rational to integer
     1224        """
     1225        if base_ring is None:
     1226            base_ring = self.base_ring()
     1227        m = matrix(base_ring, self.ambient_dim(), self.n_vertices())
     1228        for i,v in enumerate(self.vertices()):
     1229            for j in range(0,self.ambient_dim()):
     1230                m[j,i] = v[j]
     1231        return m
    12331232
    12341233    def ray_generator(self):
    12351234        """
     
    12461245            if V.is_ray():
    12471246                yield V
    12481247
    1249 
     1248    @cached_method
    12501249    def rays(self):
    12511250        """
    12521251        Return a list of rays as coefficient lists.
    12531252
     1253        OUTPUT:
     1254
     1255        A tuple of rays.
     1256
     1257        EXAMPLES::
     1258
     1259            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
     1260            sage: p.rays()
     1261            (A ray in the direction (1, 0, 0),
     1262             A ray in the direction (0, 1, 0),
     1263             A ray in the direction (0, 0, 1))
     1264        """
     1265        return tuple(self.ray_generator())
     1266
     1267    def rays_list(self):
     1268        """
     1269        Return a list of rays as coefficient lists.
     1270
    12541271        .. NOTE::
    12551272       
    1256             It is recommended to use :meth:`ray_generator` instead to
    1257             iterate over the list of :class:`Ray` objects.
     1273            It is recommended to use :meth:`rays` or
     1274            :meth:`ray_generator` instead to iterate over the list of
     1275            :class:`Ray` objects.
    12581276
    12591277        OUTPUT:
    12601278
     
    12631281        EXAMPLES::
    12641282
    12651283            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
    1266             sage: p.rays()
     1284            sage: p.rays_list()
    12671285            [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    1268             sage: p.rays() == [list(r) for r in p.ray_generator()]
     1286            sage: p.rays_list() == [list(r) for r in p.ray_generator()]
    12691287            True
    12701288        """
    1271         try:
    1272             return self._rays
    1273         except:
    1274             self._rays = [list(x) for x in self.ray_generator()]
    1275             return self._rays
    1276 
     1289        return [list(x) for x in self.ray_generator()]
    12771290
    12781291    def line_generator(self):
    12791292        """
     
    12891302            if V.is_line():
    12901303                yield V
    12911304
    1292 
     1305    @cached_method
    12931306    def lines(self):
    12941307        """
     1308        Return all lines of the polyhedron.
     1309
     1310        OUTPUT:
     1311
     1312        A tuple of lines.
     1313
     1314        EXAMPLES::
     1315
     1316            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
     1317            sage: p.lines()
     1318            (A line in the direction (1, 0),)
     1319        """
     1320        return tuple(self.line_generator())
     1321
     1322    def lines_list(self):
     1323        """
    12951324        Return a list of lines of the polyhedron.  The line data is given
    12961325        as a list of coordinates rather than as a Hrepresentation object.
    12971326
     
    13031332        EXAMPLES::
    13041333
    13051334            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
    1306             sage: p.lines()
     1335            sage: p.lines_list()
    13071336            [[1, 0]]
    1308             sage: p.lines() == [list(x) for x in p.line_generator()]
     1337            sage: p.lines_list() == [list(x) for x in p.line_generator()]
    13091338            True
    13101339        """
    1311         try:
    1312             return self._lines
    1313         except:
    1314             self._lines = [list(x) for x in self.line_generator()]
    1315             return self._lines
    1316 
     1340        return [list(x) for x in self.line_generator()]
    13171341               
    13181342    def bounded_edges(self):
    13191343        """
     
    13401364                if self.vertex_adjacency_matrix()[i,j] == 0: continue
    13411365                yield (obj[i], obj[j])
    13421366
    1343 
    1344     @cached_method
    1345     def ambient_space(self):
     1367    def Vrepresentation_space(self):
    13461368        r"""
    13471369        Return the ambient vector space.
    13481370       
     
    13531375        EXAMPLES::
    13541376
    13551377            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1356             sage: poly_test.ambient_space()
    1357             Vector space of dimension 4 over Rational Field
     1378            sage: poly_test.Vrepresentation_space()
     1379            Ambient free module of rank 4 over the principal ideal domain Integer Ring
     1380            sage: poly_test.ambient_space() is poly_test.Vrepresentation_space()
     1381            True
    13581382        """
    1359         from sage.modules.free_module import VectorSpace
    1360         return VectorSpace(self.base_ring(), self.ambient_dim())
    1361 
    1362     Vrepresentation_space = ambient_space
    1363 
    1364     @cached_method
     1383        return self.parent().Vrepresentation_space()
     1384
     1385    ambient_space = Vrepresentation_space
     1386
    13651387    def Hrepresentation_space(self):
    13661388        r"""
    13671389        Return the linear space containing the H-representation vectors.
     
    13731395        EXAMPLES::
    13741396       
    13751397            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1376             sage: poly_test.ambient_space()
    1377             Vector space of dimension 4 over Rational Field
     1398            sage: poly_test.Hrepresentation_space()
     1399            Ambient free module of rank 5 over the principal ideal domain Integer Ring
    13781400        """
    1379         from sage.modules.free_module import VectorSpace
    1380         return VectorSpace(self.base_ring(), self.ambient_dim()+1)
    1381 
     1401        return self.parent().Hrepresentation_space()
    13821402
    13831403    def ambient_dim(self):
    13841404        r"""
     
    13901410            sage: poly_test.ambient_dim()
    13911411            4
    13921412        """
    1393         return self._ambient_dim
    1394 
     1413        return self.parent().ambient_dim()
    13951414           
    13961415    def dim(self):
    13971416        """
     
    14071426       """
    14081427        return self.ambient_dim() - self.n_equations()
    14091428
    1410 
    1411     def adjacency_matrix(self):
    1412         """
    1413         This is an alias for :meth:`vertex_adjacency_matrix`
    1414 
    1415         EXAMPLES::
    1416 
    1417             sage: polytopes.n_cube(3).adjacency_matrix()
    1418             [0 1 1 0 1 0 0 0]
    1419             [1 0 0 1 0 1 0 0]
    1420             [1 0 0 1 0 0 1 0]
    1421             [0 1 1 0 0 0 0 1]
    1422             [1 0 0 0 0 1 1 0]
    1423             [0 1 0 0 1 0 0 1]
    1424             [0 0 1 0 1 0 0 1]
    1425             [0 0 0 1 0 1 1 0]
    1426         """
    1427         return self.vertex_adjacency_matrix()
    1428 
    1429 
     1429    @cached_method
    14301430    def vertex_adjacency_matrix(self):
    14311431        """
    14321432        Return the binary matrix of vertex adjacencies.
     
    14401440            [1 1 1 0 1]
    14411441            [1 1 1 1 0]
    14421442        """
    1443         if '_V_adjacency_matrix' not in self.__dict__:
    1444             self._init_vertex_adjacency_matrix()
    1445         return self._V_adjacency_matrix;
    1446 
    1447 
     1443        return self._vertex_adjacency_matrix()
     1444
     1445    adjacency_matrix = vertex_adjacency_matrix
     1446
     1447    @cached_method
    14481448    def facet_adjacency_matrix(self):
    14491449        """
    14501450        Return the adjacency matrix for the facets and hyperplanes.
     
    14581458            [1 1 1 0 1]
    14591459            [1 1 1 1 0]
    14601460        """
    1461         if '_H_adjacency_matrix' not in self.__dict__:
    1462             self._init_facet_adjacency_matrix()
    1463         return self._H_adjacency_matrix;
    1464 
    1465 
     1461        return self._facet_adjacency_matrix()
     1462
     1463    @cached_method
    14661464    def incidence_matrix(self):
    14671465        """
    14681466        Return the incidence matrix.
     
    15071505            sage: p.incidence_matrix() [2,0]   # note: not symmetric
    15081506            0
    15091507        """
    1510         try:
    1511             return self._incidence_matrix
    1512         except AttributeError:
    1513             self._incidence_matrix = matrix(ZZ, len(self.Vrepresentation()),
    1514                                                 len(self.Hrepresentation()), 0)
    1515             for V in self.Vrep_generator():
    1516                 for H in self.Hrep_generator():
    1517                     if self._is_zero(H*V):
    1518                         self._incidence_matrix[V.index(),H.index()] = 1
    1519 
    1520             return self._incidence_matrix
    1521 
     1508        incidence_matrix = matrix(ZZ, self.n_Vrepresentation(),
     1509                                  self.n_Hrepresentation(), 0)
     1510        for V in self.Vrep_generator():
     1511            for H in self.Hrep_generator():
     1512                if self._is_zero(H*V):
     1513                    incidence_matrix[V.index(),H.index()] = 1
     1514        return incidence_matrix
    15221515
    15231516    def base_ring(self):
    15241517        """
     
    15321525        EXAMPLES::
    15331526
    15341527            sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]])
    1535             sage: triangle.base_ring() == QQ
     1528            sage: triangle.base_ring() == ZZ
    15361529            True
    15371530        """
    1538         return self._base_ring
     1531        return self.parent().base_ring()
    15391532
    15401533    field = base_ring
    15411534
    1542 
    1543     def coerce_field(self, other):
    1544         """
    1545         Return the common field for both ``self`` and ``other``.
    1546 
    1547         INPUT:
    1548 
    1549         - ``other`` -- must be either:
    1550        
    1551             * another ``Polyhedron`` object
    1552        
    1553             * `\QQ` or `RDF`
    1554        
    1555             * a constant that can be coerced to `\QQ` or `RDF`
    1556 
    1557         OUTPUT:
    1558 
    1559         Either `\QQ` or `RDF`. Raises ``TypeError`` if ``other`` is not a
    1560         suitable input.
    1561 
    1562         .. NOTE::
    1563        
    1564             "Real" numbers in sage are not necessarily elements of
    1565             `RDF`. For example, the literal `1.0` is not.
    1566 
    1567         EXAMPLES::
    1568 
    1569             sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ)
    1570             sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF)
    1571             sage: triangle_QQ.coerce_field(QQ)
    1572             Rational Field
    1573             sage: triangle_QQ.coerce_field(triangle_RDF)
    1574             Real Double Field
    1575             sage: triangle_RDF.coerce_field(triangle_QQ)
    1576             Real Double Field
    1577             sage: triangle_QQ.coerce_field(RDF)
    1578             Real Double Field
    1579             sage: triangle_QQ.coerce_field(ZZ)
    1580             Rational Field
    1581             sage: triangle_QQ.coerce_field(1/2)
    1582             Rational Field
    1583             sage: triangle_QQ.coerce_field(0.5)
    1584             Real Double Field
    1585         """
    1586         try:
    1587             # other is a Polyhedron object?
    1588             other_field = other.field()
    1589         except AttributeError:
    1590 
    1591             try:
    1592                 # other is a constant?
    1593                 other_parent = other.parent()
    1594             except AttributeError:
    1595                 other_parent = other
    1596 
    1597             # other is a field?
    1598             if QQ.coerce_map_from(other_parent) != None:
    1599                 other_field = QQ
    1600             elif RDF.coerce_map_from(other_parent) != None:
    1601                 other_field = RDF
    1602             else:
    1603                 raise TypeError("cannot determine field from %s!" % other)
    1604 
    1605         assert other_field==QQ or other_field==RDF
    1606            
    1607         if self.field()==RDF or other_field==RDF:
    1608             return RDF
    1609         else:
    1610             return QQ
    1611 
    1612 
    16131535    @cached_method
    16141536    def center(self):
    16151537        """
     
    16731595        """
    16741596        return sqrt(self.radius_square())
    16751597
    1676 
    16771598    def is_compact(self):
    16781599        """
    16791600        Test for boundedness of the polytope.
     
    16891610        """
    16901611        return self.n_rays()==0 and self.n_lines()==0
    16911612
    1692 
    16931613    def is_simple(self):
    16941614        """
    16951615        Test for simplicity of a polytope.
     
    17131633            adj = [a for a in v.neighbors()]
    17141634            if len(adj) != self.dim():
    17151635                return False
    1716 
    17171636        return True
    17181637
     1638    @cached_method
    17191639    def gale_transform(self):
    17201640        """
    17211641        Return the Gale transform of a polytope as described in the
     
    17431663        if not self.is_compact(): raise ValueError('Not a polytope.')
    17441664
    17451665        A = matrix(self.n_vertices(),
    1746                    [ [1]+list(x) for x in self.vertex_generator()])
     1666                   [ [1]+x for x in self.vertex_generator()])
    17471667        A = A.transpose()
    17481668        A_ker = A.right_kernel()
    17491669        return A_ker.basis_matrix().transpose().rows()
     
    18131733            [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1),
    18141734             A vertex at (-1, 1, -1), A vertex at (1, 1, 1)]
    18151735            sage: Polyhedron(simplex_vertices)
    1816             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     1736            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
    18171737        """
    18181738        if not self.is_compact():
    18191739            raise NotImplementedError('I can only triangulate compact polytopes.')
     
    18441764            ...             ).triangulated_facial_incidences()
    18451765            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18461766            This method is deprecated. Use triangulate() instead.
     1767            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1768            This method is deprecated. Use self.Hrepresentation(i).incident() instead.
    18471769            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    18481770                             
    18491771        Otherwise some faces get split up to triangles::
     
    18521774            ...       [1,1,0],[0,0,1]]).triangulated_facial_incidences()
    18531775            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18541776            This method is deprecated. Use triangulate() instead.
     1777            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1778            This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.
    18551779            [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]],
    18561780             [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]]
    18571781        """
     
    19061830        self._triangulated_facial_incidences = t_fac_incs
    19071831        return t_fac_incs
    19081832
    1909 
    19101833    def simplicial_complex(self):
    19111834        """
    19121835        Return a simplicial complex from a triangulation of the polytope.
     
    19371860        return SimplicialComplex(vertex_set = self.n_vertices(),
    19381861                                 maximal_faces = [x[1] for x in self.triangulated_facial_incidences()])
    19391862
    1940     def __add__(self, other):
     1863    @coerce_binop
     1864    def Minkowski_sum(self, other):
    19411865        """
     1866        Return the Minkowski sum.
     1867
     1868        INPUT:
     1869
     1870        - ``other`` -- a :class:`Polyhedron_base`.
     1871
     1872        OUTPUT:
     1873
    19421874        The Minkowski sum of ``self`` and ``other``.
    19431875
    1944         INPUT:
    1945 
    1946         - ``other`` -- a :class:`Polyhedron`.
    1947 
    19481876        EXAMPLES::
    19491877
    19501878            sage: four_cube = polytopes.n_cube(4)
    19511879            sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
    1952             sage: unholy_union = four_cube + four_simplex
    1953             sage: unholy_union.dim()
    1954             4
    1955             sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]])
    1956             sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]])
    1957             sage: poly_spam_and_eggs = poly_spam + poly_spam + poly_eggs
    1958             sage: poly_spam_and_eggs.n_vertices()
    1959             12
     1880            sage: four_cube + four_simplex
     1881            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 36 vertices
     1882            sage: four_cube.Minkowski_sum(four_simplex) == four_cube + four_simplex
     1883            True
     1884
     1885            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)
     1886            sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ)
     1887            sage: poly_spam + poly_spam + poly_eggs
     1888            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 12 vertices
    19601889        """
    1961         if is_Polyhedron(other):
    1962             new_vertices = []
    1963             for v1 in self.vertex_generator():
    1964                 for v2 in other.vertex_generator():
    1965                     new_vertices.append(list(v1() + v2()))
     1890        new_vertices = []
     1891        for v1 in self.vertex_generator():
     1892            for v2 in other.vertex_generator():
     1893                new_vertices.append(list(v1() + v2()))
     1894        if new_vertices != []:
    19661895            new_rays = self.rays() + other.rays()
    19671896            new_lines = self.lines() + other.lines()
    1968             other_field = other.field()
    1969 
    1970         else:  # assume other is a vector and try to add vertices
    1971             displacement = vector(other)
    1972             new_vertices = [list(x() + displacement) for x in self.vertex_generator()]
    1973             new_rays = self.rays()
    1974             new_lines = self.lines()
    1975             other_field = displacement.base_ring()
    1976 
     1897            return self.parent().element_class(self.parent(), [new_vertices, new_rays, new_lines], None)
     1898        else:
     1899            return self.parent().element_class(self.parent(), None, None)
     1900
     1901    _add_ = Minkowski_sum
     1902
     1903    def translation(self, displacement):
     1904        """
     1905        Return the translated polyhedron.
     1906
     1907        INPUT:
     1908
     1909        - ``displacement`` -- a displacement vector or a list/tuple of
     1910          coordinates that determines a displacement vector.
     1911
     1912        OUTPUT:
     1913
     1914        The translated polyhedron.
     1915
     1916        EXAMPLES::
     1917
     1918            sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ)
     1919            sage: P.translation([2,1])
     1920            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
     1921            sage: P.translation( vector(QQ,[2,1]) )
     1922            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     1923        """
     1924        displacement = vector(displacement)
     1925        new_vertices = [x.vector()+displacement for x in self.vertex_generator()]
     1926        new_rays = self.rays()
     1927        new_lines = self.lines()
     1928        new_ring = self.parent()._coerce_base_ring(displacement.base_ring())
     1929        return Polyhedron(vertices=new_vertices, rays=new_rays, lines=new_lines, base_ring=new_ring)
     1930
     1931    @coerce_binop
     1932    def product(self, other):
     1933        """
     1934        Return the cartesian product.
     1935
     1936        INPUT:
     1937
     1938        - ``other`` -- a :class:`Polyhedron_base`.
     1939
     1940        OUTPUT:
     1941
     1942        The cartesian product of ``self`` and ``other`` with a
     1943        suitable base ring to encompass the two.
     1944
     1945        EXAMPLES::
     1946
     1947            sage: P1 = Polyhedron([[0],[1]], base_ring=ZZ)
     1948            sage: P2 = Polyhedron([[0],[1]], base_ring=QQ)
     1949            sage: P1.product(P2)
     1950            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1951
     1952        The cartesian product is the product in the semiring of polyhedra::
     1953
     1954            sage: P1 * P1
     1955            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     1956            sage: P1 * P2
     1957            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1958            sage: P2 * P2
     1959            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1960            sage: 2 * P1
     1961            A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices
     1962            sage: P1 * 2.0
     1963            A 1-dimensional polyhedron in RDF^1 defined as the convex hull of 2 vertices
     1964        """
     1965        new_vertices = [ list(x)+list(y)
     1966                         for x in self.vertex_generator() for y in other.vertex_generator()]
     1967        new_rays = []
     1968        new_rays.extend( [ r+[0]*other.ambient_dim()
     1969                           for r in self.ray_generator() ] )
     1970        new_rays.extend( [ [0]*self.ambient_dim()+r
     1971                           for r in other.ray_generator() ] )
     1972        new_lines = []
     1973        new_lines.extend( [ l+[0]*other.ambient_dim()
     1974                            for l in self.line_generator() ] )
     1975        new_lines.extend( [ [0]*self.ambient_dim()+l
     1976                            for l in other.line_generator() ] )
    19771977        return Polyhedron(vertices=new_vertices,
    19781978                          rays=new_rays, lines=new_lines,
    1979                           base_ring=self.coerce_field(other_field))
    1980            
    1981 
    1982     def __mul__(self, other):
     1979                          base_ring=self.parent()._coerce_base_ring(other))
     1980
     1981    _mul_ = product
     1982
     1983    def dilation(self, scalar):
    19831984        """
    1984         Multiplication by ``other``.
     1985        Return the dilated (uniformly stretched) polyhedron.
    19851986
    19861987        INPUT:
    19871988
    1988         - ``other`` -- A scalar, not necessarily in :meth:`field`, or
    1989           a :class:`Polyhedron`.
     1989        - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring`,
     1990          or a :class:`Polyhedron`.
    19901991
    19911992        OUTPUT:
    19921993
     
    19992000             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
    20002001             sage: p.vertex_generator().next()
    20012002             A vertex at (2, 4, 8)
    2002              sage: p2 = p*2
     2003             sage: p2 = p.dilation(2)
    20032004             sage: p2.vertex_generator().next()
    20042005             A vertex at (4, 8, 16)
     2006             sage: p.dilation(2) == p * 2
     2007             True
    20052008        """
    2006         if is_Polyhedron(other):
    2007             new_vertices = [ list(x)+list(y)
    2008                              for x in self.vertex_generator() for y in other.vertex_generator()]
    2009             new_rays = []
    2010             new_rays.extend( [ list(r)+[0]*other.ambient_dim()
    2011                                for r in self.ray_generator() ] )
    2012             new_rays.extend( [ [0]*self.ambient_dim()+list(r)
    2013                                for r in other.ray_generator() ] )
    2014             new_lines = []
    2015             new_lines.extend( [ list(l)+[0]*other.ambient_dim()
    2016                                 for l in self.line_generator() ] )
    2017             new_lines.extend( [ [0]*self.ambient_dim()+list(l)
    2018                                for l in other.line_generator() ] )
    2019         else:
    2020             new_vertices = [ list(other*v()) for v in self.vertex_generator()]
    2021             new_rays =  self.rays()
    2022             new_lines = self.lines()
    2023 
     2009        new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator()]
     2010        new_rays =  self.rays()
     2011        new_lines = self.lines()
    20242012        return Polyhedron(vertices=new_vertices,
    20252013                          rays=new_rays, lines=new_lines,
    2026                           base_ring=self.coerce_field(other))
    2027 
    2028 
    2029     def __rmul__(self,other):
     2014                          base_ring=self.parent()._coerce_base_ring(scalar.parent()))
     2015
     2016    def _acted_upon_(self, actor, self_on_left):
    20302017        """
    2031         Right multiplication.
    2032 
    2033         See :meth:`__mul__` for details.
     2018        Implement the multiplicative action by scalars or other polyhedra.
     2019
     2020        INPUT:
     2021
     2022        - ``actor`` -- A scalar, not necessarily in :meth:`base_ring`,
     2023          or a :class:`Polyhedron`.
     2024
     2025        OUTPUT:
     2026
     2027        Multiplication by another polyhedron returns the product
     2028        polytope. Multiplication by a scalar returns the polytope
     2029        dilated by that scalar, possibly coerced to the bigger field.
    20342030
    20352031        EXAMPLES::
    20362032
     2033             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
     2034             sage: p._acted_upon_(2, True) == p.dilation(2)
     2035             True
     2036             sage: p*2 == p.dilation(2)
     2037             True
     2038             sage: p*p == p.product(p)
     2039             True
     2040             sage: p + vector(ZZ,[1,2,3]) == p.translation([1,2,3])
     2041             True
     2042        """
     2043        if is_Polyhedron(actor):
     2044            return self.product(actor)
     2045        if is_Vector(actor):
     2046            return self.translation(actor)
     2047        else:
     2048            return self.dilation(actor)
     2049
     2050    def __div__(self, scalar):
     2051        """
     2052        Divide by a scalar factor.
     2053
     2054        See :meth:`dilation` for details.
     2055
     2056        EXAMPLES::
     2057
    20372058            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,4)])
    2038             sage: p2 = 3*p + p
    2039             sage: p2.vertex_generator().next()
    2040             A vertex at (8, 16, 32)
     2059            sage: (p/5).Vrepresentation()
     2060            (A vertex at (2/5, 4/5, 8/5), A vertex at (3/5, 9/5, 27/5))
    20412061        """
    2042         return self.__mul__(other)
    2043 
    2044 
    2045     def union(self, other):
    2046         """
    2047         Deprecated.  Use ``self.convex_hull(other)`` instead.
    2048        
    2049         EXAMPLES::
    2050        
    2051             sage: Polyhedron(vertices=[[0]]).union( Polyhedron(vertices=[[1]]) )
    2052             doctest:...: DeprecationWarning: (Since Sage Version 4.4.4)
    2053             The function union is replaced by convex_hull.
    2054             A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices
    2055         """
    2056         from sage.misc.misc import deprecation
    2057         deprecation('The function union is replaced by convex_hull.', 'Sage Version 4.4.4')
    2058         return self.convex_hull(other)
    2059 
    2060 
     2062        return self.dilation(1/scalar)
     2063
     2064    @coerce_binop
    20612065    def convex_hull(self, other):
    20622066        """
    20632067        Return the convex hull of the set-theoretic union of the two
     
    20842088        hull_vertices = self.vertices() + other.vertices()
    20852089        hull_rays = self.rays() + other.rays()
    20862090        hull_lines = self.lines() + other.lines()
    2087         hull_field = self.coerce_field(other)
    2088         return Polyhedron(vertices=hull_vertices,
    2089                           rays=hull_rays, lines=hull_lines,
    2090                           base_ring=hull_field)
    2091 
    2092 
     2091        return self.parent().element_class(self.parent(), [hull_vertices, hull_rays, hull_lines], None)
     2092
     2093    @coerce_binop
    20932094    def intersection(self, other):
    20942095        """
    20952096        Return the intersection of one polyhedron with another.
     
    21022103
    21032104        The intersection.
    21042105
     2106        Note that the intersection of two `\ZZ`-polyhedra might not be
     2107        a `\ZZ`-polyhedron. In this case, a `\QQ`-polyhedron is
     2108        returned.
     2109
    21052110        EXAMPLES::
    21062111
    21072112            sage: cube = polytopes.n_cube(3)
    21082113            sage: oct = polytopes.cross_polytope(3)
    2109             sage: cube_oct = cube.intersection(oct*2)
    2110             sage: len(list( cube_oct.vertex_generator() ))
    2111             12
    2112             sage: cube_oct
    2113             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
     2114            sage: cube.intersection(oct*2)
     2115            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 12 vertices
     2116
     2117       The intersection of two `\ZZ`-polyhedra is not necessarily a `\ZZ`-polyhedron::
     2118
     2119            sage: P = Polyhedron([(0,0),(1,1)], base_ring=ZZ)
     2120            sage: P.intersection(P)
     2121            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices
     2122            sage: Q = Polyhedron([(0,1),(1,0)], base_ring=ZZ)
     2123            sage: P.intersection(Q)
     2124            A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
     2125            sage: _.Vrepresentation()
     2126            (A vertex at (1/2, 1/2),)
    21142127        """
    2115         new_ieqs = []
    2116         new_ieqs.extend(self.inequalities())
    2117         new_ieqs.extend(other.inequalities())
    2118 
    2119         new_eqns = []
    2120         new_eqns.extend(self.equations())
    2121         new_eqns.extend(other.equations())
    2122 
    2123         return Polyhedron(ieqs = new_ieqs, eqns = new_eqns,
    2124                           base_ring=self.coerce_field(other))
    2125 
     2128        new_ieqs = self.inequalities() + other.inequalities()
     2129        new_eqns = self.equations() + other.equations()
     2130        parent = self.parent()
     2131        try:
     2132            return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2133        except TypeError,msg:
     2134            if self.base_ring() is ZZ:
     2135                parent = parent.base_extend(QQ)
     2136                return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2137            else:
     2138                raise TypeError(msg)
    21262139
    21272140    def edge_truncation(self, cut_frac = Integer(1)/3):
    21282141        r"""
     
    21582171
    21592172        return Polyhedron(vertices=new_vertices, rays=new_rays,
    21602173                          lines=new_lines,
    2161                           base_ring=self.coerce_field(cut_frac))
     2174                          base_ring=self.parent()._coerce_base_ring(cut_frac))
    21622175
    21632176
    21642177    def _make_polyhedron_face(self, Vindices, Hindices):
     
    21872200        """
    21882201        return PolyhedronFace_base(self, Vindices, Hindices)
    21892202
    2190 
     2203    @cached_method
    21912204    def face_lattice(self):
    21922205        """
    21932206        Return the face-lattice poset.
     
    23322345            http://portal.acm.org/citation.cfm?id=763203 and free of
    23332346            charge at http://arxiv.org/abs/math/0106043
    23342347        """
    2335         try:
    2336             return self._face_lattice
    2337         except AttributeError:
    2338             pass
    2339        
    23402348        coatom_to_Hindex = [ h.index() for h in self.inequality_generator() ]
    23412349        Hindex_to_coatom = [None] * self.n_Hrepresentation()
    23422350        for i in range(0,len(coatom_to_Hindex)):
     
    23682376            return self._make_polyhedron_face(Vindices, Hindices)
    23692377
    23702378        from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
    2371         self._face_lattice = Hasse_diagram_from_incidences\
     2379        return Hasse_diagram_from_incidences\
    23722380            (atoms_incidences, coatoms_incidences,
    23732381             face_constructor=face_constructor, required_atoms=atoms_vertices)
    2374         return self._face_lattice
    2375 
    2376 
     2382
     2383
     2384    @cached_method
    23772385    def f_vector(self):
    23782386        r"""
    23792387        Return the f-vector.
     
    23902398            sage: p.f_vector()
    23912399            (1, 7, 12, 7, 1)
    23922400        """
    2393         try:
    2394             return self._f_vector
    2395         except AttributeError:
    2396             self._f_vector = vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
    2397             return self._f_vector
    2398 
    2399 
     2401        return vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
     2402
     2403    @cached_method
    24002404    def vertex_graph(self):
    24012405        """
    24022406        Return a graph in which the vertices correspond to vertices
     
    24112415            sage: s4.is_eulerian()
    24122416            True
    24132417        """
    2414         try:
    2415             return self._graph
    2416         except AttributeError:
    2417             self._graph = Graph(self.vertex_adjacency_matrix(), loops=True)
    2418             return self._graph
    2419 
     2418        return Graph(self.vertex_adjacency_matrix(), loops=True)
    24202419
    24212420    graph = vertex_graph
    24222421
    2423 
    24242422    def polar(self):
    24252423        """
    2426         Return the polar (dual) polytope.  The original vertices are
    2427         translated so that their barycenter is at the origin, and then
    2428         the vertices are used as the coefficients in the polar inequalities.
     2424        Return the polar (dual) polytope.
     2425
     2426        The original vertices are translated so that their barycenter
     2427        is at the origin, and then the vertices are used as the
     2428        coefficients in the polar inequalities.
    24292429
    24302430        EXAMPLES::
    24312431
    2432             sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]])
     2432            sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]], base_ring=QQ)
    24332433            sage: p
    24342434            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices
    24352435            sage: p.polar()
     
    24372437        """
    24382438        assert self.is_compact(), "Not a polytope."
    24392439
    2440         verts = [list(v() - self.center()) for v in self.vertex_generator()]
    2441         return Polyhedron(ieqs=[[1] + list(v) for v in verts],
    2442                           base_ring=self.base_ring())
    2443 
     2440        verts = [list(v.vector() - self.center()) for v in self.vertex_generator()]
     2441        base_ring = self.parent()._coerce_base_ring(self.center().parent().base_ring())
     2442        return Polyhedron(ieqs=[[1] + list(v) for v in verts], base_ring=base_ring)
    24442443
    24452444    def pyramid(self):
    24462445        """
     
    24482447
    24492448        EXAMPLES::
    24502449
    2451             sage: square = polytopes.n_cube(2)
    2452             sage: egyptian_pyramid = square.pyramid()
     2450            sage: square = polytopes.n_cube(2);  square
     2451            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     2452            sage: egyptian_pyramid = square.pyramid();  egyptian_pyramid
     2453            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices
    24532454            sage: egyptian_pyramid.n_vertices()
    24542455            5
    24552456            sage: for v in egyptian_pyramid.vertex_generator(): print v
     
    24602461            A vertex at (1, 0, 0)
    24612462        """
    24622463        new_verts = \
    2463             [[0] + list(x) for x in self.Vrep_generator()] + \
     2464            [[0] + x for x in self.Vrep_generator()] + \
    24642465            [[1] + list(self.center())]
    2465 
    2466         return Polyhedron(vertices = new_verts, base_ring=self.field())
    2467 
     2466        return Polyhedron(vertices=new_verts)
    24682467
    24692468    def bipyramid(self):
    24702469        """
     
    24992498            [[-1] + list(self.center())]
    25002499        new_rays = [[0] + r for r in self.rays()]
    25012500        new_lines = [[0] + list(l) for l in self.lines()]
    2502         return Polyhedron(vertices=new_verts,
    2503                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2504 
     2501        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines)
    25052502
    25062503    def prism(self):
    25072504        """
     
    25122509            sage: square = polytopes.n_cube(2)
    25132510            sage: cube = square.prism()
    25142511            sage: cube
    2515             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
     2512            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
    25162513            sage: hypercube = cube.prism()
    25172514            sage: hypercube.n_vertices()
    25182515            16
     
    25212518        new_verts.extend( [ [0] + v for v in self.vertices()] )
    25222519        new_verts.extend( [ [1] + v for v in self.vertices()] )
    25232520        new_rays =        [ [0] + r for r in self.rays()]
    2524         new_lines =       [ [0] + list(l) for l in self.lines()]
    2525         return Polyhedron(vertices=new_verts,
    2526                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2527 
     2521        new_lines =       [ [0] + l for l in self.lines()]
     2522        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines,
     2523                          base_ring=self.base_ring())
    25282524
    25292525    def projection(self):
    25302526        """
     
    25412537        self.projection = Projection(self)
    25422538        return self.projection
    25432539
    2544 
    25452540    def render_solid(self, **kwds):
    25462541        """
    25472542        Return a solid rendering of a 2- or 3-d polytope.
     
    25602555            return proj.render_fill_2d(**kwds)
    25612556        raise ValueError, "render_solid is only defined for 2 and 3 dimensional polyhedra."
    25622557
    2563 
    25642558    def render_wireframe(self, **kwds):
    25652559        """
    25662560        For polytopes in 2 or 3 dimensions, return the edges
     
    25802574            return proj.render_outline_2d(**kwds)
    25812575        raise ValueError, "render_wireframe is only defined for 2 and 3 dimensional polyhedra."
    25822576
    2583 
    25842577    def schlegel_projection(self, projection_dir = None, height = 1.1):
    25852578        """
    25862579        Returns a projection object whose transformed coordinates are
     
    25972590        """
    25982591        proj = self.projection()
    25992592        if projection_dir == None:
    2600             v = self.vertices()
    2601             f0 = (self.facial_incidences()[0])[1]
    2602             projection_dir = [sum([v[f0[i]][j]/len(f0) for i in range(len(f0))])
    2603                               for j in range(len(v[0]))]
     2593            vertices = self.vertices()
     2594            facet = self.Hrepresentation(0)
     2595            f0 = [ v.index() for v in facet.incident() ]
     2596            projection_dir = [sum([vertices[f0[i]][j]/len(f0) for i in range(len(f0))])
     2597                              for j in range(self.ambient_dim())]
    26042598        return proj.schlegel(projection_direction = projection_dir, height = height)
    26052599       
    2606 
    26072600    def lrs_volume(self, verbose = False):
    26082601        """
    26092602        Computes the volume of a polytope.
     
    26542647
    26552648        raise ValueError, "lrs did not return a volume"
    26562649
    2657 
    26582650    def contains(self, point):
    26592651        """
    26602652        Test whether the polyhedron contains the given ``point``.
     
    26962688        The empty polyhedron needs extra care, see trac #10238::
    26972689
    26982690            sage: empty = Polyhedron(); empty
    2699             The empty polyhedron in QQ^0
     2691            The empty polyhedron in ZZ^0
    27002692            sage: empty.contains([])
    27012693            False
    27022694            sage: empty.contains([0])               # not a point in QQ^0
    27032695            False
    27042696            sage: full = Polyhedron(vertices=[()]); full
    2705             A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex
     2697            A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex
    27062698            sage: full.contains([])
    27072699            True
    27082700            sage: full.contains([0])
     
    27142706            if len(point)>0:
    27152707                return False
    27162708            else:
    2717                 p = vector(self.field(), [])
     2709                p = vector(self.base_ring(), [])
    27182710
    27192711        if len(p)!=self.ambient_dim():
    27202712            return False
     
    27242716                return False
    27252717        return True
    27262718
    2727 
    27282719    def interior_contains(self, point):
    27292720        """
    27302721        Test whether the interior of the polyhedron contains the
     
    27612752        The empty polyhedron needs extra care, see trac #10238::
    27622753
    27632754            sage: empty = Polyhedron(); empty
    2764             The empty polyhedron in QQ^0
     2755            The empty polyhedron in ZZ^0
    27652756            sage: empty.interior_contains([])
    27662757            False
    27672758        """
     
    27712762            if len(point)>0:
    27722763                return False
    27732764            else:
    2774                 p = vector(self.field(), [])
     2765                p = vector(self.base_ring(), [])
    27752766
    27762767        if len(p)!=self.ambient_dim():
    27772768            return False
     
    27812772                return False
    27822773        return True
    27832774
    2784 
    27852775    def relative_interior_contains(self, point):
    27862776        """
    27872777        Test whether the relative interior of the polyhedron
     
    28122802        The empty polyhedron needs extra care, see trac #10238::
    28132803
    28142804            sage: empty = Polyhedron(); empty
    2815             The empty polyhedron in QQ^0
     2805            The empty polyhedron in ZZ^0
    28162806            sage: empty.relative_interior_contains([])
    28172807            False
    28182808        """
     
    28222812            if len(point)>0:
    28232813                return False
    28242814            else:
    2825                 p = vector(self.field(), [])
     2815                p = vector(self.base_ring(), [])
    28262816
    28272817        if len(p)!=self.ambient_dim():
    28282818            return False
     
    28522842        """
    28532843        return self.is_compact() and (self.dim()+1==self.n_vertices())
    28542844
     2845    @cached_method
    28552846    def is_lattice_polytope(self):
    28562847        r"""
    28572848        Return whether the polyhedron is a lattice polytope.
     
    28682859            sage: polytopes.regular_polygon(5).is_lattice_polytope()
    28692860            False
    28702861        """
    2871         try:
    2872             return self._is_lattice_polytope
    2873         except AttributeError:
    2874             pass
    2875         self._is_lattice_polytope = self.is_compact() and \
    2876             all(v.is_integral() for v in self.vertex_generator())
    2877         return self._is_lattice_polytope
     2862        if not self.is_compact():
     2863            return False
     2864        if self.base_ring() is ZZ:
     2865            return True
     2866        return all(v.is_integral() for v in self.vertex_generator())
    28782867       
     2868    @cached_method
    28792869    def lattice_polytope(self, envelope=False):
    28802870        r"""
    28812871        Return an encompassing lattice polytope.
     
    29382928        if not self.is_compact():
    29392929            raise NotImplementedError, 'Only compact lattice polytopes are allowed.'
    29402930
    2941         def nonintegral_error():
    2942             raise ValueError, 'Some vertices are not integral. '+\
    2943                 'You probably want to add the argument '+\
    2944                 '"envelope=True" to compute an enveloping lattice polytope.'
    2945 
    2946         # try to make use of cached values, if possible
    2947         if envelope:
    2948             try:
    2949                 return self._lattice_polytope
    2950             except AttributeError:
    2951                 pass
    2952         else:
    2953             try:
    2954                 assert self._is_lattice_polytope
    2955                 return self._lattice_polytope
    2956             except AttributeError:
    2957                 pass
    2958             except AssertionError:
    2959                 nonintegral_error()
    2960 
    2961         # find the integral vertices
    29622931        try:
    2963             vertices = matrix(ZZ, self.vertices()).transpose()
    2964             self._is_lattice_polytope = True
     2932            vertices = self.vertices_matrix(ZZ)
    29652933        except TypeError:
    2966             self._is_lattice_polytope = False
    2967             if envelope==False: nonintegral_error()
     2934            if envelope==False:
     2935                raise ValueError, 'Some vertices are not integral. '+\
     2936                    'You probably want to add the argument '+\
     2937                    '"envelope=True" to compute an enveloping lattice polytope.'
    29682938            vertices = []
    29692939            for v in self.vertex_generator():
    29702940                vbox = [ set([floor(x),ceil(x)]) for x in v ]
     
    29732943
    29742944        # construct the (enveloping) lattice polytope
    29752945        from sage.geometry.lattice_polytope import LatticePolytope
    2976         self._lattice_polytope = LatticePolytope(vertices)
    2977         return self._lattice_polytope
     2946        return LatticePolytope(vertices)
    29782947
    29792948    def _integral_points_PALP(self):
    29802949        r"""
     
    30423011        box_max = []
    30433012        if self.n_vertices==0:
    30443013            raise ValueError('Empty polytope is not allowed')
     3014        if not self.is_compact():
     3015            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
    30453016        for i in range(0,self.ambient_dim()):
    3046             coords = [ v[i] for v in self.Vrep_generator() ]
     3017            coords = [ v[i] for v in self.vertex_generator() ]
    30473018            max_coord = max(coords)
    30483019            min_coord = min(coords)
    30493020            if integral:
     
    31003071
    31013072            sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
    31023073            sage: simplex = Polyhedron(v); simplex
    3103             A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     3074            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
    31043075            sage: len(simplex.integral_points())
    31053076            49
    31063077
     
    31503121        # assert all(self.contains(p) for p in points)   # slow
    31513122        return tuple(points)
    31523123   
     3124    @cached_method
    31533125    def combinatorial_automorphism_group(self):
    31543126        """
    31553127        Computes the combinatorial automorphism group of the vertex
     
    31843156            sage: P.combinatorial_automorphism_group()
    31853157            Permutation Group with generators [(3,4)]
    31863158        """
    3187         if '_combinatorial_automorphism_group' in self.__dict__:
    3188             return self._combinatorial_automorphism_group
    3189 
    31903159        from sage.groups.perm_gps.permgroup import PermutationGroup
    3191 
    31923160        G = Graph()
    31933161        for edge in self.vertex_graph().edges():
    31943162            i = edge[0]
     
    32063174        self._combinatorial_automorphism_group = group
    32073175        return group
    32083176
    3209 
    32103177    def _affine_coordinates(self, Vrep_object):
    32113178        r"""
    32123179        Return affine coordinates for a V-representation object.
     
    32453212        if len(v) != self.ambient_dim():
    32463213            raise ValueError('Incorrect dimension: '+str(v))
    32473214
    3248         return vector(self.field(), [ v[i] for i in self._affine_coordinates_pivots ])
     3215        return vector(self.base_ring(), [ v[i] for i in self._affine_coordinates_pivots ])
    32493216       
    3250 
     3217    @cached_method
    32513218    def restricted_automorphism_group(self):
    32523219        r"""
    32533220        Return the restricted automorphism group.
     
    33953362            sage: p.restricted_automorphism_group()
    33963363            Permutation Group with generators [(2,3)]
    33973364        """
    3398         if '_restricted_automorphism_group' in self.__dict__:
    3399             return self._restricted_automorphism_group
    3400 
    34013365        from sage.groups.perm_gps.permgroup import PermutationGroup
    34023366
    3403         if self.field() is QQ:
     3367        if self.base_ring() is ZZ or self.base_ring() is QQ:
    34043368            def rational_approximation(c):
    34053369                return c
    34063370
    3407         else:  # self.field() is RDF
     3371        elif self.base_ring() is RDF:
    34083372            c_list = []
    34093373            def rational_approximation(c):
    34103374                # Implementation detail: Return unique integer if two
     
    34163380                        return i
    34173381                c_list.append(c)
    34183382                return len(c_list)-1
    3419        
     3383
    34203384        # The algorithm identifies the restricted automorphism group
    34213385        # with the automorphism group of a edge-colored graph. The
    34223386        # nodes of the graph are the V-representation objects. If all
     
    34733437
    34743438
    34753439
    3476 
    3477 
    3478 
    34793440#########################################################################
    3480 class PolyhedronFace_base(SageObject):
     3441class PolyhedronFace_base(Polyhedron_base):
    34813442    r"""
    34823443    A face of a polyhedron.
    34833444   
     
    35403501            sage: PolyhedronFace_base(Polyhedron(), [], [])   # indirect doctest
    35413502            <>
    35423503        """
     3504        Element.__init__(self, parent=polyhedron.parent())
    35433505        self._polyhedron = polyhedron
    35443506        self._ambient_Vrepresentation_indices = tuple(V_indices)
    35453507        self._ambient_Hrepresentation_indices = tuple(H_indices)
    35463508        self._ambient_Vrepresentation = tuple( polyhedron.Vrepresentation(i) for i in V_indices )
    35473509        self._ambient_Hrepresentation = tuple( polyhedron.Hrepresentation(i) for i in H_indices )
    3548         # self._Vrepresentation =
    3549         # self._Hrepresentation =
     3510        self._Vrepresentation = tuple()
     3511        self._Hrepresentation = tuple()
    35503512       
    3551 
    35523513    def ambient_Hrepresentation(self, index=None):
    35533514        r"""
    35543515        Return the H-representation objects of the ambient polytope
     
    35913552        else:
    35923553            return self._ambient_Hrepresentation[index]
    35933554       
    3594 
    35953555    def ambient_Vrepresentation(self, index=None):
    35963556        r"""
    35973557        Return the V-representation objects of the ambient polytope
     
    36343594        else:
    36353595            return self._ambient_Vrepresentation[index]
    36363596
    3637 
     3597    @cached_method
    36383598    def n_ambient_Hrepresentation(self):
    36393599        """
    36403600        Return the number of objects that make up the ambient
     
    36603620            sage: face.n_ambient_Hrepresentation()
    36613621            4
    36623622        """
    3663         return len(self._ambient_Hrepresentation)
    3664 
    3665 
     3623        return len(self.ambient_Hrepresentation())
     3624
     3625    @cached_method
    36663626    def n_ambient_Vrepresentation(self):
    36673627        """
    36683628        Return the number of objects that make up the ambient
     
    36853645            sage: face.n_ambient_Vrepresentation()
    36863646            2
    36873647        """
    3688         return len(self._ambient_Vrepresentation)
    3689 
    3690 
     3648        return len(self.ambient_Vrepresentation())
     3649
     3650    @cached_method
    36913651    def dim(self):
    36923652        """
    36933653        Return the dimension of the face.
     
    37043664              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    37053665              1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3]
    37063666        """
    3707         if '_dim' in self.__dict__:
    3708             return self._dim
    3709 
    37103667        if self.n_ambient_Vrepresentation()==0:
    3711             self._dim = -1
     3668            return -1
    37123669        else:
    37133670            origin = vector(self.ambient_Vrepresentation(0))
    37143671            v_list = [ vector(v)-origin for v in self.ambient_Vrepresentation() ]
    3715             self._dim = matrix(v_list).rank()
    3716         return self._dim
    3717 
     3672            return matrix(v_list).rank()
    37183673
    37193674    def _repr_(self):
    37203675        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
    - +  
     1r"""
     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.