Ticket #11763: trac_11763_parents-rebase.patch

File trac_11763_parents-rebase.patch, 173.6 KB (added by davidloeffler, 7 years ago)

Rebased for new patch at #11634

  • sage/categories/all.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1329617140 28800
    # Node ID 9ae71d9811e8599330b1a869db064ca1ba7b00b3
    # Parent  01ee8583d6d33ad70ced4ac52f0c5c237335fddb
    Trac #11763: Parents for polyhedra
    
    diff --git a/sage/categories/all.py b/sage/categories/all.py
    a b  
    125125from highest_weight_crystals import HighestWeightCrystals
    126126from finite_crystals import FiniteCrystals
    127127from classical_crystals import ClassicalCrystals
     128
     129# polyhedra
     130from polyhedra import PolyhedralSets
  • new file sage/categories/polyhedra.py

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

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

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

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

    diff --git a/sage/geometry/polyhedron/backend_ppl.py b/sage/geometry/polyhedron/backend_ppl.py
    a b  
    33"""
    44
    55from sage.rings.all import ZZ, QQ
    6 from sage.rings.arith import lcm
     6from sage.rings.integer import LCM_list
    77from sage.misc.functional import denominator
    88from sage.matrix.constructor import matrix
    99from sage.libs.ppl import (
     
    1414from base import Polyhedron_base
    1515from base_QQ import Polyhedron_QQ
    1616from base_ZZ import Polyhedron_ZZ
    17 from representation import (
    18     PolyhedronRepresentation,
    19     Hrepresentation,
    20     Inequality, Equation,
    21     Vrepresentation,
    22     Vertex, Ray, Line )
    23 
    2417
    2518
    2619#########################################################################
     
    3023
    3124    INPUT:
    3225
    33     - ``ambient_dim`` -- integer. The dimension of the ambient space.
    34 
    35     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     26    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    3627       
    37     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     28    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    3829
    3930    EXAMPLES::
    4031
     
    4233        sage: TestSuite(p).run()
    4334    """
    4435
    45     def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, minimize=True):
     36    def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True):
    4637        """
    4738        Construct polyhedron from V-representation data.
    4839
    4940        INPUT:
    5041
    51         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    52        
    5342        - ``vertices`` -- list of point. Each point can be specified
    5443           as any iterable container of
    5544           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    6655
    6756            sage: p = Polyhedron(backend='ppl')
    6857            sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl
    69             sage: Polyhedron_ppl._init_from_Vrepresentation(p, 2, [], [], [])
     58            sage: Polyhedron_ppl._init_from_Vrepresentation(p, [], [], [])
    7059        """
    7160        gs = Generator_System()
    7261        if vertices is None: vertices = []
    7362        for v in vertices:
    74             d = lcm([denominator(v_i) for v_i in v])
    75             dv = [ ZZ(d*v_i) for v_i in v ]
    76             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))
    7769        if rays is None: rays = []
    7870        for r in rays:
    79             d = lcm([denominator(r_i) for r_i in r])
    80             dr = [ ZZ(d*r_i) for r_i in r ]
    81             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)))
    8277        if lines is None: lines = []
    8378        for l in lines:
    84             d = lcm([denominator(l_i) for l_i in l])
    85             dl = [ ZZ(d*l_i) for l_i in l ]
    86             gs.insert(line(Linear_Expression(dl, 0)))
    87         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)
    8889        self._init_Vrepresentation_from_ppl(minimize)
    8990        self._init_Hrepresentation_from_ppl(minimize)
    9091
    91 
    92     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, minimize=True):
     92    def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True):
    9393        """
    9494        Construct polyhedron from H-representation data.
    9595
    9696        INPUT:
    97 
    98         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    9997       
    10098        - ``ieqs`` -- list of inequalities. Each line can be specified
    10199          as any iterable container of
     
    109107
    110108            sage: p = Polyhedron(backend='ppl')
    111109            sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl
    112             sage: Polyhedron_ppl._init_from_Hrepresentation(p, 2, [], [])
     110            sage: Polyhedron_ppl._init_from_Hrepresentation(p, [], [])
    113111        """
    114112        cs = Constraint_System()
    115113        if ieqs is None: ieqs = []
    116114        for ieq in ieqs:
    117             d = lcm([denominator(ieq_i) for ieq_i in ieq])
     115            d = LCM_list([denominator(ieq_i) for ieq_i in ieq])
    118116            dieq = [ ZZ(d*ieq_i) for ieq_i in ieq ]
    119117            b = dieq[0]
    120118            A = dieq[1:]
    121119            cs.insert(Linear_Expression(A, b) >= 0)
    122120        if eqns is None: eqns = []
    123121        for eqn in eqns:
    124             d = lcm([denominator(eqn_i) for eqn_i in eqn])
     122            d = LCM_list([denominator(eqn_i) for eqn_i in eqn])
    125123            deqn = [ ZZ(d*eqn_i) for eqn_i in eqn ]
    126124            b = deqn[0]
    127125            A = deqn[1:]
    128126            cs.insert(Linear_Expression(A, b) == 0)
    129         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)
    130131        self._init_Vrepresentation_from_ppl(minimize)
    131132        self._init_Hrepresentation_from_ppl(minimize)
    132133
    133        
    134134    def _init_Vrepresentation_from_ppl(self, minimize):
    135135        """
    136136        Create the Vrepresentation objects from the ppl polyhedron.
     
    152152        """
    153153        self._Vrepresentation = []
    154154        gs = self._ppl_polyhedron.minimized_generators()
     155        parent = self.parent()
    155156        for g in gs:
    156157            if g.is_point():
    157158                d = g.divisor()
    158                 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()])
    159163            elif g.is_ray():
    160                 Ray(self, g.coefficients())
     164                parent._make_Ray(self, g.coefficients())
    161165            elif g.is_line():
    162                 Line(self, g.coefficients())
     166                parent._make_Line(self, g.coefficients())
    163167            else:
    164168                assert False
    165169        self._Vrepresentation = tuple(self._Vrepresentation)
    166        
    167 
     170 
    168171    def _init_Hrepresentation_from_ppl(self, minimize):
    169172        """
    170173        Create the Vrepresentation objects from the ppl polyhedron.
     
    186189        """
    187190        self._Hrepresentation = []
    188191        cs = self._ppl_polyhedron.minimized_constraints()
     192        parent = self.parent()
    189193        for c in cs:
    190194            if c.is_inequality():
    191                 Inequality(self, (c.inhomogeneous_term(),) + c.coefficients())
     195                parent._make_Inequality(self, (c.inhomogeneous_term(),) + c.coefficients())
    192196            elif c.is_equality():
    193                 Equation(self, (c.inhomogeneous_term(),) + c.coefficients())
     197                parent._make_Equation(self, (c.inhomogeneous_term(),) + c.coefficients())
    194198        self._Hrepresentation = tuple(self._Hrepresentation)
    195        
    196199
    197     def _init_empty_polyhedron(self, ambient_dim):
     200    def _init_empty_polyhedron(self):
    198201        """
    199202        Initializes an empty polyhedron.
    200203
    201         INPUT:
    202 
    203         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    204 
    205204        TESTS::
    206205
    207206            sage: empty = Polyhedron(backend='ppl'); empty
    208             The empty polyhedron in QQ^0
     207            The empty polyhedron in ZZ^0
    209208            sage: empty.Vrepresentation()
    210209            ()
    211210            sage: empty.Hrepresentation()
    212211            (An equation -1 == 0,)
    213212            sage: Polyhedron(vertices = [], backend='ppl')
    214             The empty polyhedron in QQ^0
    215             sage: Polyhedron(backend='ppl')._init_empty_polyhedron(0)
     213            The empty polyhedron in ZZ^0
     214            sage: Polyhedron(backend='ppl')._init_empty_polyhedron()
    216215        """
    217         super(Polyhedron_ppl, self)._init_empty_polyhedron(ambient_dim)
    218         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')
    219218
    220219
    221220
     
    227226
    228227    INPUT:
    229228
    230     - ``ambient_dim`` -- integer. The dimension of the ambient space.
    231 
    232     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     229    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    233230       
    234     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     231    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    235232
    236233    EXAMPLES::
    237234
     
    249246
    250247    INPUT:
    251248
    252     - ``ambient_dim`` -- integer. The dimension of the ambient space.
    253 
    254     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     249    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    255250       
    256     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     251    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    257252
    258253    EXAMPLES::
    259254
  • sage/geometry/polyhedron/base.py

    diff --git a/sage/geometry/polyhedron/base.py b/sage/geometry/polyhedron/base.py
    a b  
    1313########################################################################
    1414
    1515
    16 from sage.structure.sage_object import SageObject
     16from sage.structure.element import Element, coerce_binop, is_Vector
    1717
    1818from sage.misc.all import union, cached_method, prod
    1919from sage.misc.package import is_package_installed
     
    3333from sage.groups.perm_gps.permgroup_named import AlternatingGroup
    3434
    3535from constructor import Polyhedron
    36 from representation import (
    37     PolyhedronRepresentation,
    38     Hrepresentation,
    39     Inequality, Equation,
    40     Vrepresentation,
    41     Vertex, Ray, Line )
    4236
    4337
    4438#########################################################################
     
    5549#
    5650#  * You can of course also override any other method for which you
    5751#    have a faster implementation.
     52#########################################################################
    5853
    5954
    6055#########################################################################
     
    8378
    8479
    8580#########################################################################
    86 class Polyhedron_base(SageObject):
     81class Polyhedron_base(Element):
    8782    """
    8883    Base class for Polyhedron objects
    8984
    9085    INPUT:
    9186
    92     - ``ambient_dim`` -- integer. The dimension of the ambient space.
     87    - ``parent`` -- the parent, an instance of
     88      :class:`~sage.geometry.polyhedron.parent.Polyhedra`.
    9389
    9490    - ``Vrep`` -- a list `[vertices, rays, lines]``.
    9591       
     
    10197        sage: TestSuite(p).run()
    10298    """
    10399
    104     def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
     100    def __init__(self, parent, Vrep, Hrep, **kwds):
    105101        """
    106102        Initializes the polyhedron.
    107103
     
    112108
    113109            sage: p = Polyhedron()    # indirect doctests
    114110        """
    115         self._ambient_dim = ambient_dim
     111        Element.__init__(self, parent=parent)
    116112        if Vrep is not None:
    117113            vertices, rays, lines = Vrep
    118             if len(vertices)==0:
    119                 vertices = [[0] * ambient_dim]
    120             self._init_from_Vrepresentation(ambient_dim, vertices, rays, lines, **kwds)
     114            self._init_from_Vrepresentation(vertices, rays, lines, **kwds)
    121115        elif Hrep is not None:
    122116            ieqs, eqns = Hrep
    123             self._init_from_Hrepresentation(ambient_dim, ieqs, eqns, **kwds)
     117            self._init_from_Hrepresentation(ieqs, eqns, **kwds)
    124118        else:
    125             self._init_empty_polyhedron(ambient_dim)
    126 
    127 
    128     def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, **kwds):
     119            self._init_empty_polyhedron()
     120
     121
     122    def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds):
    129123        """
    130124        Construct polyhedron from V-representation data.
    131125
    132126        INPUT:
    133127
    134         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    135        
    136128        - ``vertices`` -- list of point. Each point can be specified
    137129           as any iterable container of
    138130           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    149141
    150142            sage: p = Polyhedron()
    151143            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    152             sage: Polyhedron_base._init_from_Vrepresentation(p, 2, [], [], [])
     144            sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], [])
    153145            Traceback (most recent call last):
    154146            ...
    155147            NotImplementedError: A derived class must implement this method.
     
    157149        raise NotImplementedError('A derived class must implement this method.')
    158150
    159151
    160     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, **kwds):
     152    def _init_from_Hrepresentation(self, ieqs, eqns, **kwds):
    161153        """
    162154        Construct polyhedron from H-representation data.
    163155
    164156        INPUT:
    165157
    166         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    167        
    168158        - ``ieqs`` -- list of inequalities. Each line can be specified
    169159          as any iterable container of
    170160          :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    177167
    178168            sage: p = Polyhedron()
    179169            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    180             sage: Polyhedron_base._init_from_Hrepresentation(p, 2, [], [])
     170            sage: Polyhedron_base._init_from_Hrepresentation(p, [], [])
    181171            Traceback (most recent call last):
    182172            ...
    183173            NotImplementedError: A derived class must implement this method.
    184174        """
    185175        raise NotImplementedError('A derived class must implement this method.')
    186176
    187 
    188     def _init_empty_polyhedron(self, ambient_dim):
     177    def _init_empty_polyhedron(self):
    189178        """
    190179        Initializes an empty polyhedron.
    191180
    192         INPUT:
    193 
    194         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    195 
    196181        TESTS::
    197182
    198183            sage: empty = Polyhedron(); empty
    199             The empty polyhedron in QQ^0
     184            The empty polyhedron in ZZ^0
    200185            sage: empty.Vrepresentation()
    201186            ()
    202187            sage: empty.Hrepresentation()
    203188            (An equation -1 == 0,)
    204189            sage: Polyhedron(vertices = [])
    205             The empty polyhedron in QQ^0
    206             sage: Polyhedron()._init_empty_polyhedron(0)
     190            The empty polyhedron in ZZ^0
     191            sage: Polyhedron(vertices = [])._init_empty_polyhedron()
     192            sage: from sage.geometry.polyhedron.parent import Polyhedra
     193            sage: Polyhedra(QQ,7)()
     194            A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex
    207195        """
    208196        self._Vrepresentation = []
    209197        self._Hrepresentation = []
    210         Equation(self, [-1] + [0]*ambient_dim);
     198        self.parent()._make_Equation(self, [-1] + [0]*self.ambient_dim());
    211199        self._Vrepresentation = tuple(self._Vrepresentation)
    212200        self._Hrepresentation = tuple(self._Hrepresentation)
    213201
    214         self._V_adjacency_matrix = matrix(ZZ, 0, 0, 0)
    215         self._V_adjacency_matrix.set_immutable()
    216 
    217         self._H_adjacency_matrix = matrix(ZZ, 1, 1, 0)
    218         self._H_adjacency_matrix.set_immutable()
    219 
    220 
    221     def _init_facet_adjacency_matrix(self):
     202        V_matrix = matrix(ZZ, 0, 0, 0)
     203        V_matrix.set_immutable()
     204        self.vertex_adjacency_matrix.set_cache(V_matrix)
     205
     206        H_matrix = matrix(ZZ, 1, 1, 0)
     207        H_matrix.set_immutable()
     208        self.facet_adjacency_matrix.set_cache(H_matrix)
     209
     210    def _facet_adjacency_matrix(self):
    222211        """
    223212        Compute the facet adjacency matrix in case it has not been
    224213        computed during initialization.
     
    226215        EXAMPLES::
    227216       
    228217            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
    229             sage: '_H_adjacency_matrix' in p.__dict__
    230             False
    231             sage: p._init_facet_adjacency_matrix()
    232             sage: p._H_adjacency_matrix
     218            sage: p._facet_adjacency_matrix()
    233219            [0 1 1]
    234220            [1 0 1]
    235221            [1 1 0]
     
    250236            Hrep = face.element.ambient_Hrepresentation()
    251237            if len(Hrep) == 2:
    252238                set_adjacent(Hrep[0], Hrep[1])
    253 
    254         self._H_adjacency_matrix = M
    255 
    256 
    257     def _init_vertex_adjacency_matrix(self):
     239        return M
     240
     241    def _vertex_adjacency_matrix(self):
    258242        """
    259243        Compute the vertex adjacency matrix in case it has not been
    260244        computed during initialization.
     
    262246        EXAMPLES::
    263247       
    264248            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
    265             sage: '_V_adjacency_matrix' in p.__dict__
    266             False
    267             sage: p._init_vertex_adjacency_matrix()
    268             sage: p._V_adjacency_matrix
     249            sage: p._vertex_adjacency_matrix()
    269250            [0 1 1]
    270251            [1 0 1]
    271252            [1 1 0]
     
    293274        for r in self.ray_generator():
    294275            for vrep in self.Vrep_generator():
    295276                set_adjacent(r, vrep)
    296                
    297         self._V_adjacency_matrix = M
    298 
    299 
    300     def __lt__(self, other):
     277        return M
     278
     279    def delete(self):
    301280        """
    302         Test whether ``self`` is a strict sub-polyhedron of ``other``.
     281        Delete this polyhedron.
     282       
     283        This speeds up creation of new polyhedra by reusing
     284        objects. After recycling a polyhedron object, it is not in a
     285        consistent state any more and neither the polyhedron nor its
     286        H/V-representation objects may be used any more.
     287
     288        .. seealso:: :meth:`~sage.geometry.polyhedron.Polyhedra_base.recycle`
     289
     290
     291        EXAMPLES::
     292
     293            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
     294            sage: p.delete()
     295
     296            sage: def loop_polyhedra():
     297            ...       for i in range(0,100):
     298            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     299
     300            sage: timeit('loop_polyhedra()', repeat=25)                   # random output
     301            5 loops, best of 25: 44.2 ms per loop
     302
     303            sage: def loop_polyhedra_with_recycling():
     304            ...       for i in range(0,100):
     305            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     306            ...           p.delete()
     307
     308            sage: timeit('loop_polyhedra_with_recycling()', repeat=25)    # random output
     309            25 loops, best of 25: 36.3 ms per loop
     310        """
     311        self.parent().recycle(self)
     312        self._Hrepresentation = None
     313        self._Vrepresentation = None
     314
     315    def base_extend(self, base_ring, backend=None):
     316        """
     317        EXAMPLES::
     318           
     319            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ);  P
     320            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray
     321            sage: P.base_extend(QQ)
     322            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
     323        """
     324        new_parent = self.parent().base_extend(base_ring, backend)
     325        return new_parent(self)
     326
     327    def __cmp__(self, other):
     328        """
     329        Compare ``self`` and ``other``.
    303330
    304331        INPUT:
    305332
    306         - ``other`` -- a :class:`Polyhedron`.
     333        - ``other`` -- anything.
    307334
    308335        OUTPUT:
    309336
    310         Boolean.
     337        `-1, 0, +1` depending on how ``self`` and ``other``
     338        compare. If ``other`` is a polyhedron, then the comparison
     339        operator "less or equal than" means "is contained in", and
     340        "less than" means "is strictly contained in".
    311341
    312342        EXAMPLES::
    313343
    314344            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    315345            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    316             sage: P < Q   # indirect doctest
     346            sage: cmp(P,Q)
     347            1
     348            sage: cmp(Q,P)
     349            -1
     350            sage: cmp(P,P)
     351            0
     352            sage: cmp(P, 'anything')
     353            -1
     354
     355       The polytope ``Q`` is contained in ``P``::
     356           
     357            sage: P > Q
     358            True
     359            sage: P < Q
    317360            False
    318             sage: P < P   # indirect doctest
    319             False
    320             sage: Q < P   # indirect doctest
    321             True
    322         """
    323         return self._is_subpolyhedron(other) and not other._is_subpolyhedron(self)
    324 
    325 
    326     def __le__(self, other):
    327         """
    328         Test whether ``self`` is a (not necessarily strict)
    329         sub-polyhedron of ``other``.
    330 
    331         INPUT:
    332 
    333         - ``other`` -- a :class:`Polyhedron`.
    334 
    335         OUTPUT:
    336 
    337         Boolean.
    338 
    339         EXAMPLES::
    340 
    341             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    342             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    343             sage: P <= Q   # indirect doctest
    344             False
    345             sage: P <= P   # indirect doctest
    346             True
    347             sage: Q <= P   # indirect doctest
    348             True
    349         """
    350         return self._is_subpolyhedron(other)
    351        
    352 
    353     def __eq__(self, other):
    354         """
    355         Test whether ``self`` is a strict sub-polyhedron of ``other``.
    356 
    357         INPUT:
    358 
    359         - ``other`` -- a :class:`Polyhedron`.
    360 
    361         OUTPUT:
    362 
    363         Boolean.
    364 
    365         EXAMPLES::
    366 
    367             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    368             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    369             sage: P == Q   # indirect doctest
    370             False
    371             sage: P == P   # indirect doctest
    372             True
    373             sage: Q == P   # indirect doctest
     361            sage: P == Q
    374362            False
    375363        """
    376         return self._is_subpolyhedron(other) and other._is_subpolyhedron(self)
    377 
    378 
    379     def __ne__(self, other):
    380         """
    381         Test whether ``self`` is not equal to ``other``.
    382 
    383         INPUT:
    384 
    385         - ``other`` -- a :class:`Polyhedron`.
    386 
    387         OUTPUT:
    388 
    389         Boolean.
    390 
    391         EXAMPLES::
    392 
    393             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    394             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    395             sage: P != Q   # indirect doctest
    396             True
    397             sage: P != P   # indirect doctest
    398             False
    399             sage: Q != P   # indirect doctest
    400             True
    401         """
    402         return not self.__eq__(other)
    403 
    404 
    405     def __gt__(self, other):
    406         """
    407         Test whether ``self`` is a strict super-polyhedron of ``other``.
    408 
    409         INPUT:
    410 
    411         - ``other`` -- a :class:`Polyhedron`.
    412 
    413         OUTPUT:
    414 
    415         Boolean.
    416 
    417         EXAMPLES::
    418 
    419             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    420             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    421             sage: P > Q   # indirect doctest
    422             True
    423             sage: P > P   # indirect doctest
    424             False
    425             sage: Q > P   # indirect doctest
    426             False
    427         """
    428         return other._is_subpolyhedron(self) and not self._is_subpolyhedron(other)
    429 
    430 
    431     def __ge__(self, other):
    432         """
    433         Test whether ``self`` is a (not necessarily strict)
    434         super-polyhedron of ``other``.
    435 
    436         INPUT:
    437 
    438         - ``other`` -- a :class:`Polyhedron`.
    439 
    440         OUTPUT:
    441 
    442         Boolean.
    443 
    444         EXAMPLES::
    445 
    446             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    447             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    448             sage: P >= Q   # indirect doctest
    449             True
    450             sage: P >= P   # indirect doctest
    451             True
    452             sage: Q >= P   # indirect doctest
    453             False
    454         """
    455         return other._is_subpolyhedron(self)
    456 
    457 
     364        c = cmp(self.ambient_dim(), other.ambient_dim())
     365        if c != 0: return c
     366        c0 = self._is_subpolyhedron(other)
     367        c1 = other._is_subpolyhedron(self)
     368        if c0 and c1:
     369            return 0
     370        if c0:
     371            return -1
     372        else:
     373            return +1
     374           
     375    @coerce_binop
    458376    def _is_subpolyhedron(self, other):
    459377        """
    460378        Test whether ``self`` is a (not necessarily strict)
     
    477395            sage: Q._is_subpolyhedron(P)
    478396            True
    479397        """
    480         if not is_Polyhedron(other):
    481             raise ValueError('Can only compare Polyhedron objects.')
    482398        return all( other_H.contains(self_V)
    483399                    for other_H, self_V in
    484400                    CartesianProduct(other.Hrep_generator(), self.Vrep_generator()) )
    485        
    486401
    487402    def plot(self, **kwds):
    488403        """
     
    513428        raise NotImplementedError('Plotting of '+str(self.ambient_dim())+
    514429                                  '-dimensional polyhedra not implemented')
    515430
    516 
    517431    show = plot
    518432
    519 
    520433    def _repr_(self):
    521434        """
    522435        Return a description of the polyhedron.
     
    525438
    526439            sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]])
    527440            sage: poly_test._repr_()
    528             'A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices'
     441            'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices'
    529442            sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]])
    530443            sage: grammar_test._repr_()
    531             'A 0-dimensional polyhedron in QQ^6 defined as the convex hull of 1 vertex'
     444            'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex'
    532445        """
    533446        desc = ''
    534447        if self.n_vertices()==0:
     
    565478
    566479        return desc
    567480
    568 
    569481    def cdd_Hrepresentation(self):
    570482        """
    571483        Write the inequalities/equations data of the polyhedron in
     
    593505        try:
    594506            cdd_type = self._cdd_type
    595507        except AttributeError:
    596             ring_to_cdd = { QQ:'rational', RDF:'real' }
    597             cdd_type = ring_to_cdd[self.base_ring()]
     508            if self.base_ring() is ZZ or self.base_ring() is QQ:
     509                cdd_type = 'rational'
     510            elif self.base_ring() is RDF:
     511                cdd_type = 'real'
     512            else:
     513                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    598514        return cdd_Hrepresentation(cdd_type,
    599515                                   list(self.inequality_generator()),
    600516                                   list(self.equation_generator()) )
    601517
    602 
    603518    def cdd_Vrepresentation(self):
    604519        """
    605520        Write the vertices/rays/lines data of the polyhedron in cdd's
     
    627542        try:
    628543            cdd_type = self._cdd_type
    629544        except AttributeError:
    630             ring_to_cdd = { QQ:'rational', RDF:'real' }
    631             cdd_type = ring_to_cdd[self.base_ring()]
     545            if self.base_ring() is ZZ or self.base_ring() is QQ:
     546                cdd_type = 'rational'
     547            elif self.base_ring() is RDF:
     548                cdd_type = 'real'
     549            else:
     550                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    632551        return cdd_Vrepresentation(cdd_type,
    633552                                   list(self.vertex_generator()),
    634553                                   list(self.ray_generator()),
    635554                                   list(self.line_generator()) )
    636555
    637 
     556    @cached_method
    638557    def n_equations(self):
    639558        """
    640559        Return the number of equations. The representation will
     
    647566            sage: p.n_equations()
    648567            1
    649568        """
    650         try:
    651             return self._n_equations
    652         except AttributeError:
    653             self._n_equations = len(self.equations())
    654             return self._n_equations
    655 
    656 
     569        return len(self.equations())
     570
     571    @cached_method
    657572    def n_inequalities(self):
    658573        """
    659574        Return the number of inequalities. The representation will
     
    665580            sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]])
    666581            sage: p.n_inequalities()
    667582            3
    668         """
    669         try:
    670             return self._n_inequalities
    671         except AttributeError:
    672             self._n_inequalities = 0
    673             for i in self.inequalities(): self._n_inequalities += 1
    674             return self._n_inequalities
    675 
    676 
    677     def n_facets(self):
    678         """
    679         Return the number of facets in the polyhedron.  This is the
    680         same as the n_inequalities function.
    681 
    682         EXAMPLES::
    683583
    684584            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)])
    685585            sage: p.n_facets()
    686586            8
    687587        """
    688         return self.n_inequalities()
    689 
    690 
     588        return len(self.inequalities())
     589
     590    n_facets = n_inequalities
     591
     592    @cached_method
    691593    def n_vertices(self):
    692594        """
    693595        Return the number of vertices. The representation will
     
    699601            sage: p.n_vertices()
    700602            2
    701603        """
    702         try:
    703             return self._n_vertices
    704         except AttributeError:
    705             self._n_vertices = 0
    706             for v in self.vertex_generator(): self._n_vertices += 1
    707             return self._n_vertices
    708 
    709 
     604        return len(self.vertices())
     605
     606    @cached_method
    710607    def n_rays(self):
    711608        """
    712609        Return the number of rays. The representation will
     
    718615            sage: p.n_rays()
    719616            1
    720617        """
    721         try:
    722             return self._n_rays
    723         except AttributeError:
    724             self._n_rays = 0
    725             for r in self.rays(): self._n_rays += 1
    726             return self._n_rays
    727 
    728 
     618        return len(self.rays())
     619
     620    @cached_method
    729621    def n_lines(self):
    730622        """
    731623        Return the number of lines. The representation will
     
    737629            sage: p.n_lines()
    738630            1
    739631        """
    740         try:
    741             return self._n_lines
    742         except AttributeError:
    743             self._n_lines = len(self.lines())
    744             return self._n_lines
    745 
     632        return len(self.lines())
    746633
    747634    def Hrepresentation(self, index=None):
    748635        """
     
    768655            sage: p.Hrepresentation(0) == p.Hrepresentation() [0]
    769656            True
    770657        """
    771         if index==None:
     658        if index is None:
    772659            return self._Hrepresentation
    773660        else:
    774661            return self._Hrepresentation[index]
     
    788675        for H in self.Hrepresentation():
    789676            yield H
    790677
    791 
     678    @cached_method
    792679    def n_Hrepresentation(self):
    793680        """
    794681        Return the number of objects that make up the
     
    808695        """
    809696        return len(self.Hrepresentation())
    810697
    811 
    812698    def Vrepresentation(self, index=None):
    813699        """
    814700        Return the objects of the V-representation. Each entry is
     
    833719            sage: p.Vrepresentation(0) == p.Vrepresentation() [0]
    834720            True
    835721        """
    836         if index==None:
     722        if index is None:
    837723            return self._Vrepresentation
    838724        else:
    839725            return self._Vrepresentation[index]
    840726
    841 
     727    @cached_method
    842728    def n_Vrepresentation(self):
    843729        """
    844730        Return the number of objects that make up the
     
    858744        """
    859745        return len(self.Vrepresentation())
    860746
    861 
    862747    def Vrep_generator(self):
    863748        """
    864749        Returns an iterator over the objects of the V-representation
     
    876761        for V in self.Vrepresentation():
    877762            yield V
    878763
    879 
    880764    def facial_adjacencies(self):
    881         """
     765        r"""
    882766        Return the list of face indices (i.e. indices of
    883767        H-representation objects) and the indices of faces adjacent to
    884768        them.
     
    893777
    894778            sage: p = polytopes.permutahedron(4)
    895779            sage: p.facial_adjacencies()[0:3]
     780            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is deprecated.
     781            Use self.Hrepresentation(i).neighbors() instead.
    896782            [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]]
    897783            sage: f0 = p.Hrepresentation(0)
    898784            sage: f0.index() == 0
     
    901787            sage: p.facial_adjacencies()[0] == f0_adjacencies
    902788            True
    903789        """
     790        from sage.misc.misc import deprecation
     791        deprecation('This method is deprecated. Use self.Hrepresentation(i).neighbors() instead.',
     792                    'Sage Version 4.7.2')
    904793        try:
    905794            return self._facial_adjacencies
    906795        except AttributeError:
     
    910799                  ] for h in self.Hrepresentation() ]
    911800            return self._facial_adjacencies
    912801
    913 
    914802    def facial_incidences(self):
    915803        """
    916804        Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`.
     
    932820
    933821            sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]])
    934822            sage: p.facial_incidences()
     823            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     824            deprecated. Use self.Hrepresentation(i).incident() instead.
    935825            [[0, [0, 1, 3, 4]],
    936826             [1, [0, 1, 2]],
    937827             [2, [0, 2, 3]],
     
    956846            sage: p.incidence_matrix().column(4)
    957847            (0, 1, 1, 0, 1)
    958848        """
     849        from sage.misc.misc import deprecation
     850        deprecation('This method is deprecated. Use self.Hrepresentation(i).incident() instead.',
     851                    'Sage Version 4.7.2')
    959852        try:
    960853            return self._facial_incidences
    961854        except AttributeError:
     
    965858                  ] for h in self.Hrepresentation() ]
    966859            return self._facial_incidences
    967860
    968 
    969861    def vertex_adjacencies(self):
    970862        """
    971863        Return a list of vertex indices and their adjacent vertices.
     
    984876
    985877            sage: permuta3 = Polyhedron(vertices = permutations([1,2,3,4]))
    986878            sage: permuta3.vertex_adjacencies()[0:3]
     879            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     880            deprecated. Use self.Vrepresentation(i).neighbors() instead.
    987881            [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]]
    988882            sage: v0 = permuta3.Vrepresentation(0)
    989883            sage: v0.index() == 0
     
    994888            sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies
    995889            True
    996890        """
     891        from sage.misc.misc import deprecation
     892        deprecation('This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.',
     893                    'Sage Version 4.7.2')
    997894        try:
    998895            return self._vertex_adjacencies
    999896        except AttributeError:
     
    1003900                  ] for v in self.Vrepresentation() ]
    1004901            return self._vertex_adjacencies
    1005902
    1006 
    1007903    def vertex_incidences(self):
    1008904        """
    1009905        Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`.
     
    1018914
    1019915            sage: p = polytopes.n_simplex(3)
    1020916            sage: p.vertex_incidences()
     917            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     918            deprecated. Use self.Vrepresentation(i).incident() instead.
    1021919            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    1022920            sage: v0 = p.Vrepresentation(0)
    1023921            sage: v0.index() == 0
     
    1025923            sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ]
    1026924            True
    1027925        """
     926        from sage.misc.misc import deprecation
     927        deprecation('This method is deprecated. Use self.Vrepresentation(i).incident() instead.',
     928                    'Sage Version 4.7.2')
    1028929        try:
    1029930            return self._vertex_incidences
    1030931        except AttributeError:
     
    1034935                  ] for v in self.Vrepresentation() ]
    1035936            return self._vertex_incidences
    1036937
    1037 
    1038938    def inequality_generator(self):
    1039939        """
    1040940        Return  a generator for the defining inequalities of the
     
    1062962            if H.is_inequality():
    1063963                yield H
    1064964
    1065 
     965    @cached_method
    1066966    def inequalities(self):
    1067967        """
     968        Return all inequalities.
     969
     970        OUTPUT:
     971
     972        A tuple of inequalities.
     973
     974        EXAMPLES::
     975
     976            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
     977            sage: p.inequalities()[0:3]
     978            (An inequality (1, 0, 0) x + 0 >= 0,
     979             An inequality (0, 1, 0) x + 0 >= 0,
     980             An inequality (0, 0, 1) x + 0 >= 0)
     981            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
     982            sage: ieqs = p3.inequalities()
     983            sage: ieqs[0]
     984            An inequality (0, 1, 1, 1) x - 6 >= 0
     985            sage: list(_)
     986            [-6, 0, 1, 1, 1]
     987        """
     988        return tuple(self.inequality_generator())
     989   
     990    def inequalities_list(self):
     991        """
    1068992        Return a list of inequalities as coefficient lists.
    1069993
    1070994        .. NOTE::
    1071995       
    1072             It is recommended to use :meth:`inequality_generator`
    1073             instead to iterate over the list of :class:`Inequality`
    1074             objects.
     996            It is recommended to use :meth:`inequalities` or
     997            :meth:`inequality_generator` instead to iterate over the
     998            list of :class:`Inequality` objects.
    1075999
    10761000        EXAMPLES::
    10771001
    10781002            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
    1079             sage: p.inequalities()[0:3]
     1003            sage: p.inequalities_list()[0:3]
    10801004            [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    10811005            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    1082             sage: ieqs = p3.inequalities()
     1006            sage: ieqs = p3.inequalities_list()
    10831007            sage: ieqs[0]
    10841008            [-6, 0, 1, 1, 1]
    10851009            sage: ieqs[-1]
     
    10871011            sage: ieqs == [list(x) for x in p3.inequality_generator()]
    10881012            True
    10891013        """
    1090         try:
    1091             return self._inequalities
    1092         except AttributeError:
    1093             self._ieqs = [list(x) for x in self.inequality_generator()]
    1094             return self._ieqs
    1095 
     1014        return [list(x) for x in self.inequality_generator()]
    10961015
    10971016    def ieqs(self):
    10981017        """
     
    11021021         
    11031022            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    11041023            sage: p3.ieqs() == p3.inequalities()
     1024            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1025            deprecated. Use inequalities() instead.
    11051026            True
    11061027        """
     1028        from sage.misc.misc import deprecation
     1029        deprecation('This method is deprecated. Use inequalities() instead.',
     1030                    'Sage Version 4.7.2')
    11071031        return self.inequalities()
    11081032
    1109 
    11101033    def equation_generator(self):
    11111034        """
    11121035        Return a generator for the linear equations satisfied by the
     
    11231046            if H.is_equation():
    11241047                yield H
    11251048
    1126 
     1049    @cached_method
    11271050    def equations(self):
    11281051        """
     1052        Return all linear constraints of the polyhedron.
     1053
     1054        OUTPUT:
     1055
     1056        A tuple of equations.
     1057
     1058        EXAMPLES::
     1059
     1060            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
     1061            sage: test_p.equations()
     1062            (An equation (1, 1, 1, 1) x - 10 == 0,)
     1063        """
     1064        return tuple(self.equation_generator())
     1065
     1066    def equations_list(self):
     1067        """
    11291068        Return the linear constraints of the polyhedron. As with
    11301069        inequalities, each constraint is given as [b -a1 -a2 ... an]
    11311070        where for variables x1, x2,..., xn, the polyhedron satisfies
     
    11331072
    11341073        .. NOTE::
    11351074       
    1136             It is recommended to use :meth:`equation_generator()` instead
    1137             to iterate over the list of :class:`Equation` objects.
     1075            It is recommended to use :meth:`equations` or
     1076            :meth:`equation_generator()` instead to iterate over the
     1077            list of
     1078            :class:`~sage.geometry.polyhedron.representation.Equation`
     1079            objects.
    11381080
    11391081        EXAMPLES::
    11401082
    11411083            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    1142             sage: test_p.equations()
     1084            sage: test_p.equations_list()
    11431085            [[-10, 1, 1, 1, 1]]
    11441086        """
    1145         try:
    1146             return self._equations
    1147         except:
    1148             self._equations = [list(eq) for eq in self.equation_generator()]
    1149             return self._equations
    1150 
     1087        return [list(eq) for eq in self.equation_generator()]
    11511088
    11521089    def linearities(self):
    11531090        """
     
    11611098
    11621099            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    11631100            sage: test_p.linearities()
     1101            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1102            deprecated. Use equations_list() instead.
    11641103            [[-10, 1, 1, 1, 1]]
    1165             sage: test_p.linearities() == test_p.equations()
     1104            sage: test_p.linearities() == test_p.equations_list()
    11661105            True
    11671106        """
    1168         return self.equations()
    1169 
    1170 
    1171     def vertices(self):
     1107        from sage.misc.misc import deprecation
     1108        deprecation('This method is deprecated. Use equations_list() instead.',
     1109                    'Sage Version 4.7.2')
     1110        return self.equations_list()
     1111
     1112    def vertices_list(self):
    11721113        """
    11731114        Return a list of vertices of the polyhedron.
    11741115
     
    11801121        EXAMPLES::
    11811122
    11821123            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
    1183             sage: triangle.vertices()
     1124            sage: triangle.vertices_list()
    11841125            [[0, 1], [1, 0], [1, 1]]
    11851126            sage: a_simplex = Polyhedron(ieqs = [
    11861127            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
    11871128            ...        ], eqns = [[1,-1,-1,-1,-1]])
    1188             sage: a_simplex.vertices()
     1129            sage: a_simplex.vertices_list()
    11891130            [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    1190             sage: a_simplex.vertices() == [list(v) for v in a_simplex.vertex_generator()]
     1131            sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()]
    11911132            True
    11921133        """
    1193         try:
    1194             return self._vertices
    1195         except:
    1196             self._vertices = [list(x) for x in self.vertex_generator()]
    1197             return self._vertices
    1198 
     1134        return [list(x) for x in self.vertex_generator()]
    11991135       
    12001136    def vertex_generator(self):
    12011137        """
     
    12261162        for V in self.Vrepresentation():
    12271163            if V.is_vertex():
    12281164                yield V
     1165
     1166    @cached_method
     1167    def vertices(self):
     1168        """
     1169        Return all vertices of the polyhedron.
     1170
     1171        OUTPUT:
     1172
     1173        A tuple of vertices.
     1174
     1175        EXAMPLES::
     1176
     1177            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1178            sage: triangle.vertices()
     1179            (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1))
     1180            sage: a_simplex = Polyhedron(ieqs = [
     1181            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
     1182            ...        ], eqns = [[1,-1,-1,-1,-1]])
     1183            sage: a_simplex.vertices()
     1184            (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0),
     1185             A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1))
     1186        """
     1187        return tuple(self.vertex_generator())
     1188
     1189    @cached_method
     1190    def vertices_matrix(self, base_ring=None):
     1191        """
     1192        Return the coordinates of the vertices as the columns of a matrix.
     1193
     1194        INPUT:
    12291195       
    1230 
     1196        - ``base_ring`` -- A ring or ``None`` (default). The base ring
     1197          of the returned matrix. If not specified, the base ring of
     1198          the polyhedron is used.
     1199
     1200        OUTPUT:
     1201
     1202        A matrix over ``base_ring`` whose columns are the coordinates
     1203        of the vertices. A ``TypeError`` is raised if the coordinates
     1204        cannot be converted to ``base_ring``.
     1205
     1206        EXAMPLES::
     1207
     1208            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1209            sage: triangle.vertices_matrix()
     1210            [0 1 1]
     1211            [1 0 1]
     1212            sage: (triangle/2).vertices_matrix()
     1213            [  0 1/2 1/2]
     1214            [1/2   0 1/2]
     1215            sage: (triangle/2).vertices_matrix(ZZ)
     1216            Traceback (most recent call last):
     1217            ...
     1218            TypeError: no conversion of this rational to integer
     1219        """
     1220        if base_ring is None:
     1221            base_ring = self.base_ring()
     1222        m = matrix(base_ring, self.ambient_dim(), self.n_vertices())
     1223        for i,v in enumerate(self.vertices()):
     1224            for j in range(0,self.ambient_dim()):
     1225                m[j,i] = v[j]
     1226        return m
     1227       
    12311228    def ray_generator(self):
    12321229        """
    12331230        Return a generator for the rays of the polyhedron.
     
    12431240            if V.is_ray():
    12441241                yield V
    12451242
    1246 
     1243    @cached_method
    12471244    def rays(self):
    12481245        """
    12491246        Return a list of rays as coefficient lists.
    12501247
     1248        OUTPUT:
     1249
     1250        A tuple of rays.
     1251
     1252        EXAMPLES::
     1253
     1254            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
     1255            sage: p.rays()
     1256            (A ray in the direction (1, 0, 0),
     1257             A ray in the direction (0, 1, 0),
     1258             A ray in the direction (0, 0, 1))
     1259        """
     1260        return tuple(self.ray_generator())
     1261
     1262    def rays_list(self):
     1263        """
     1264        Return a list of rays as coefficient lists.
     1265
    12511266        .. NOTE::
    12521267       
    1253             It is recommended to use :meth:`ray_generator` instead to
    1254             iterate over the list of :class:`Ray` objects.
     1268            It is recommended to use :meth:`rays` or
     1269            :meth:`ray_generator` instead to iterate over the list of
     1270            :class:`Ray` objects.
    12551271
    12561272        OUTPUT:
    12571273
     
    12601276        EXAMPLES::
    12611277
    12621278            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
    1263             sage: p.rays()
     1279            sage: p.rays_list()
    12641280            [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    1265             sage: p.rays() == [list(r) for r in p.ray_generator()]
     1281            sage: p.rays_list() == [list(r) for r in p.ray_generator()]
    12661282            True
    12671283        """
    1268         try:
    1269             return self._rays
    1270         except:
    1271             self._rays = [list(x) for x in self.ray_generator()]
    1272             return self._rays
    1273 
     1284        return [list(x) for x in self.ray_generator()]
    12741285
    12751286    def line_generator(self):
    12761287        """
     
    12861297            if V.is_line():
    12871298                yield V
    12881299
    1289 
     1300    @cached_method
    12901301    def lines(self):
    12911302        """
     1303        Return all lines of the polyhedron.
     1304       
     1305        OUTPUT:
     1306
     1307        A tuple of lines.
     1308
     1309        EXAMPLES::
     1310
     1311            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
     1312            sage: p.lines()
     1313            (A line in the direction (1, 0),)
     1314        """
     1315        return tuple(self.line_generator())
     1316
     1317    def lines_list(self):
     1318        """
    12921319        Return a list of lines of the polyhedron.  The line data is given
    12931320        as a list of coordinates rather than as a Hrepresentation object.
    12941321
     
    13001327        EXAMPLES::
    13011328
    13021329            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
    1303             sage: p.lines()
     1330            sage: p.lines_list()
    13041331            [[1, 0]]
    1305             sage: p.lines() == [list(x) for x in p.line_generator()]
     1332            sage: p.lines_list() == [list(x) for x in p.line_generator()]
    13061333            True
    13071334        """
    1308         try:
    1309             return self._lines
    1310         except:
    1311             self._lines = [list(x) for x in self.line_generator()]
    1312             return self._lines
    1313 
     1335        return [list(x) for x in self.line_generator()]
    13141336               
    13151337    def bounded_edges(self):
    13161338        """
     
    13371359                if self.vertex_adjacency_matrix()[i,j] == 0: continue
    13381360                yield (obj[i], obj[j])
    13391361
    1340 
    1341     @cached_method
    1342     def ambient_space(self):
     1362    def Vrepresentation_space(self):
    13431363        r"""
    13441364        Return the ambient vector space.
    13451365       
     
    13501370        EXAMPLES::
    13511371
    13521372            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1353             sage: poly_test.ambient_space()
    1354             Vector space of dimension 4 over Rational Field
     1373            sage: poly_test.Vrepresentation_space()
     1374            Ambient free module of rank 4 over the principal ideal domain Integer Ring
     1375            sage: poly_test.ambient_space() is poly_test.Vrepresentation_space()
     1376            True
    13551377        """
    1356         from sage.modules.free_module import FreeModule
    1357         return FreeModule(self.base_ring(), self.ambient_dim())
    1358 
    1359     Vrepresentation_space = ambient_space
    1360 
    1361     @cached_method
     1378        return self.parent().Vrepresentation_space()
     1379
     1380    ambient_space = Vrepresentation_space
     1381
    13621382    def Hrepresentation_space(self):
    13631383        r"""
    13641384        Return the linear space containing the H-representation vectors.
     
    13701390        EXAMPLES::
    13711391       
    13721392            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1373             sage: poly_test.ambient_space()
    1374             Vector space of dimension 4 over Rational Field
     1393            sage: poly_test.Hrepresentation_space()
     1394            Ambient free module of rank 5 over the principal ideal domain Integer Ring
    13751395        """
    1376         from sage.modules.free_module import VectorSpace
    1377         return VectorSpace(self.base_ring(), self.ambient_dim()+1)
    1378 
     1396        return self.parent().Hrepresentation_space()
    13791397
    13801398    def ambient_dim(self):
    13811399        r"""
     
    13871405            sage: poly_test.ambient_dim()
    13881406            4
    13891407        """
    1390         return self._ambient_dim
    1391 
     1408        return self.parent().ambient_dim()
    13921409           
    13931410    def dim(self):
    13941411        """
     
    14041421       """
    14051422        return self.ambient_dim() - self.n_equations()
    14061423
    1407 
    1408     def adjacency_matrix(self):
    1409         """
    1410         This is an alias for :meth:`vertex_adjacency_matrix`
    1411 
    1412         EXAMPLES::
    1413 
    1414             sage: polytopes.n_cube(3).adjacency_matrix()
    1415             [0 1 1 0 1 0 0 0]
    1416             [1 0 0 1 0 1 0 0]
    1417             [1 0 0 1 0 0 1 0]
    1418             [0 1 1 0 0 0 0 1]
    1419             [1 0 0 0 0 1 1 0]
    1420             [0 1 0 0 1 0 0 1]
    1421             [0 0 1 0 1 0 0 1]
    1422             [0 0 0 1 0 1 1 0]
    1423         """
    1424         return self.vertex_adjacency_matrix()
    1425 
    1426 
     1424    @cached_method
    14271425    def vertex_adjacency_matrix(self):
    14281426        """
    14291427        Return the binary matrix of vertex adjacencies.
     
    14371435            [1 1 1 0 1]
    14381436            [1 1 1 1 0]
    14391437        """
    1440         if '_V_adjacency_matrix' not in self.__dict__:
    1441             self._init_vertex_adjacency_matrix()
    1442         return self._V_adjacency_matrix;
    1443 
    1444 
     1438        return self._vertex_adjacency_matrix()
     1439
     1440    adjacency_matrix = vertex_adjacency_matrix
     1441
     1442    @cached_method
    14451443    def facet_adjacency_matrix(self):
    14461444        """
    14471445        Return the adjacency matrix for the facets and hyperplanes.
     
    14551453            [1 1 1 0 1]
    14561454            [1 1 1 1 0]
    14571455        """
    1458         if '_H_adjacency_matrix' not in self.__dict__:
    1459             self._init_facet_adjacency_matrix()
    1460         return self._H_adjacency_matrix;
    1461 
    1462 
     1456        return self._facet_adjacency_matrix()
     1457
     1458    @cached_method
    14631459    def incidence_matrix(self):
    14641460        """
    14651461        Return the incidence matrix.
     
    15041500            sage: p.incidence_matrix() [2,0]   # note: not symmetric
    15051501            0
    15061502        """
    1507         try:
    1508             return self._incidence_matrix
    1509         except AttributeError:
    1510             self._incidence_matrix = matrix(ZZ, len(self.Vrepresentation()),
    1511                                                 len(self.Hrepresentation()), 0)
    1512             for V in self.Vrep_generator():
    1513                 for H in self.Hrep_generator():
    1514                     if self._is_zero(H*V):
    1515                         self._incidence_matrix[V.index(),H.index()] = 1
    1516 
    1517             return self._incidence_matrix
    1518 
     1503        incidence_matrix = matrix(ZZ, self.n_Vrepresentation(),
     1504                                  self.n_Hrepresentation(), 0)
     1505        for V in self.Vrep_generator():
     1506            for H in self.Hrep_generator():
     1507                if self._is_zero(H*V):
     1508                    incidence_matrix[V.index(),H.index()] = 1
     1509        return incidence_matrix
    15191510
    15201511    def base_ring(self):
    15211512        """
     
    15291520        EXAMPLES::
    15301521
    15311522            sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]])
    1532             sage: triangle.base_ring() == QQ
     1523            sage: triangle.base_ring() == ZZ
    15331524            True
    15341525        """
    1535         return self._base_ring
     1526        return self.parent().base_ring()
    15361527
    15371528    field = base_ring
    15381529
    1539 
    1540     def coerce_field(self, other):
    1541         """
    1542         Return the common field for both ``self`` and ``other``.
    1543 
    1544         INPUT:
    1545 
    1546         - ``other`` -- must be either:
    1547        
    1548             * another ``Polyhedron`` object
    1549        
    1550             * `\QQ` or `RDF`
    1551        
    1552             * a constant that can be coerced to `\QQ` or `RDF`
    1553 
    1554         OUTPUT:
    1555 
    1556         Either `\QQ` or `RDF`. Raises ``TypeError`` if ``other`` is not a
    1557         suitable input.
    1558 
    1559         .. NOTE::
    1560        
    1561             "Real" numbers in sage are not necessarily elements of
    1562             `RDF`. For example, the literal `1.0` is not.
    1563 
    1564         EXAMPLES::
    1565 
    1566             sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ)
    1567             sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF)
    1568             sage: triangle_QQ.coerce_field(QQ)
    1569             Rational Field
    1570             sage: triangle_QQ.coerce_field(triangle_RDF)
    1571             Real Double Field
    1572             sage: triangle_RDF.coerce_field(triangle_QQ)
    1573             Real Double Field
    1574             sage: triangle_QQ.coerce_field(RDF)
    1575             Real Double Field
    1576             sage: triangle_QQ.coerce_field(ZZ)
    1577             Rational Field
    1578             sage: triangle_QQ.coerce_field(1/2)
    1579             Rational Field
    1580             sage: triangle_QQ.coerce_field(0.5)
    1581             Real Double Field
    1582         """
    1583         try:
    1584             # other is a Polyhedron object?
    1585             other_field = other.field()
    1586         except AttributeError:
    1587 
    1588             try:
    1589                 # other is a constant?
    1590                 other_parent = other.parent()
    1591             except AttributeError:
    1592                 other_parent = other
    1593 
    1594             # other is a field?
    1595             if QQ.coerce_map_from(other_parent) != None:
    1596                 other_field = QQ
    1597             elif RDF.coerce_map_from(other_parent) != None:
    1598                 other_field = RDF
    1599             else:
    1600                 raise TypeError("cannot determine field from %s!" % other)
    1601 
    1602         assert other_field==QQ or other_field==RDF
    1603            
    1604         if self.field()==RDF or other_field==RDF:
    1605             return RDF
    1606         else:
    1607             return QQ
    1608 
    1609 
    16101530    @cached_method
    16111531    def center(self):
    16121532        """
     
    16701590        """
    16711591        return sqrt(self.radius_square())
    16721592
    1673 
    16741593    def is_compact(self):
    16751594        """
    16761595        Test for boundedness of the polytope.
     
    16861605        """
    16871606        return self.n_rays()==0 and self.n_lines()==0
    16881607
    1689 
    16901608    def is_simple(self):
    16911609        """
    16921610        Test for simplicity of a polytope.
     
    17101628            adj = [a for a in v.neighbors()]
    17111629            if len(adj) != self.dim():
    17121630                return False
    1713 
    17141631        return True
    17151632
     1633    @cached_method
    17161634    def gale_transform(self):
    17171635        """
    17181636        Return the Gale transform of a polytope as described in the
     
    17401658        if not self.is_compact(): raise ValueError('Not a polytope.')
    17411659
    17421660        A = matrix(self.n_vertices(),
    1743                    [ [1]+list(x) for x in self.vertex_generator()])
     1661                   [ [1]+x for x in self.vertex_generator()])
    17441662        A = A.transpose()
    17451663        A_ker = A.right_kernel()
    17461664        return A_ker.basis_matrix().transpose().rows()
     
    18101728            [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1),
    18111729             A vertex at (-1, 1, -1), A vertex at (1, 1, 1)]
    18121730            sage: Polyhedron(simplex_vertices)
    1813             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     1731            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
    18141732        """
    18151733        if not self.is_compact():
    18161734            raise NotImplementedError('I can only triangulate compact polytopes.')
     
    18411759            ...             ).triangulated_facial_incidences()
    18421760            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18431761            This method is deprecated. Use triangulate() instead.
     1762            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1763            This method is deprecated. Use self.Hrepresentation(i).incident() instead.
    18441764            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    18451765                             
    18461766        Otherwise some faces get split up to triangles::
     
    18491769            ...       [1,1,0],[0,0,1]]).triangulated_facial_incidences()
    18501770            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18511771            This method is deprecated. Use triangulate() instead.
     1772            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1773            This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.
    18521774            [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]],
    18531775             [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]]
    18541776        """
     
    19031825        self._triangulated_facial_incidences = t_fac_incs
    19041826        return t_fac_incs
    19051827
    1906 
    19071828    def simplicial_complex(self):
    19081829        """
    19091830        Return a simplicial complex from a triangulation of the polytope.
     
    19341855        return SimplicialComplex(vertex_set = self.n_vertices(),
    19351856                                 maximal_faces = [x[1] for x in self.triangulated_facial_incidences()])
    19361857
    1937     def __add__(self, other):
     1858    @coerce_binop
     1859    def Minkowski_sum(self, other):
    19381860        """
     1861        Return the Minkowski sum.
     1862
     1863        INPUT:
     1864
     1865        - ``other`` -- a :class:`Polyhedron_base`.
     1866
     1867        OUTPUT:
     1868       
    19391869        The Minkowski sum of ``self`` and ``other``.
    19401870
    1941         INPUT:
    1942 
    1943         - ``other`` -- a :class:`Polyhedron`.
    1944 
    19451871        EXAMPLES::
    19461872
    19471873            sage: four_cube = polytopes.n_cube(4)
    19481874            sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
    1949             sage: unholy_union = four_cube + four_simplex
    1950             sage: unholy_union.dim()
    1951             4
    1952             sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]])
    1953             sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]])
    1954             sage: poly_spam_and_eggs = poly_spam + poly_spam + poly_eggs
    1955             sage: poly_spam_and_eggs.n_vertices()
    1956             12
     1875            sage: four_cube + four_simplex
     1876            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 36 vertices
     1877            sage: four_cube.Minkowski_sum(four_simplex) == four_cube + four_simplex
     1878            True
     1879
     1880            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)
     1881            sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ)
     1882            sage: poly_spam + poly_spam + poly_eggs
     1883            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 12 vertices
    19571884        """
    1958         if is_Polyhedron(other):
    1959             new_vertices = []
    1960             for v1 in self.vertex_generator():
    1961                 for v2 in other.vertex_generator():
    1962                     new_vertices.append(list(v1() + v2()))
     1885        new_vertices = []
     1886        for v1 in self.vertex_generator():
     1887            for v2 in other.vertex_generator():
     1888                new_vertices.append(list(v1() + v2()))
     1889        if new_vertices != []:
    19631890            new_rays = self.rays() + other.rays()
    19641891            new_lines = self.lines() + other.lines()
    1965             other_field = other.field()
    1966 
    1967         else:  # assume other is a vector and try to add vertices
    1968             displacement = vector(other)
    1969             new_vertices = [list(x() + displacement) for x in self.vertex_generator()]
    1970             new_rays = self.rays()
    1971             new_lines = self.lines()
    1972             other_field = displacement.base_ring()
    1973 
     1892            return self.parent().element_class(self.parent(), [new_vertices, new_rays, new_lines], None)
     1893        else:
     1894            return self.parent().element_class(self.parent(), None, None)
     1895
     1896    _add_ = Minkowski_sum
     1897
     1898    def translation(self, displacement):
     1899        """
     1900        Return the translated polyhedron.
     1901
     1902        INPUT:
     1903
     1904        - ``displacement`` -- a displacement vector or a list/tuple of
     1905          coordinates that determines a displacement vector.
     1906
     1907        OUTPUT:
     1908
     1909        The translated polyhedron.
     1910
     1911        EXAMPLES::
     1912       
     1913            sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ)
     1914            sage: P.translation([2,1])
     1915            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
     1916            sage: P.translation( vector(QQ,[2,1]) )
     1917            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     1918        """
     1919        displacement = vector(displacement)
     1920        new_vertices = [x.vector()+displacement for x in self.vertex_generator()]
     1921        new_rays = self.rays()
     1922        new_lines = self.lines()
     1923        new_ring = self.parent()._coerce_base_ring(displacement.base_ring())
     1924        return Polyhedron(vertices=new_vertices, rays=new_rays, lines=new_lines, base_ring=new_ring)
     1925
     1926    @coerce_binop
     1927    def product(self, other):
     1928        """
     1929        Return the cartesian product.
     1930
     1931        INPUT:
     1932       
     1933        - ``other`` -- a :class:`Polyhedron_base`.
     1934
     1935        OUTPUT:
     1936
     1937        The cartesian product of ``self`` and ``other`` with a
     1938        suitable base ring to encompass the two.
     1939
     1940        EXAMPLES::
     1941
     1942            sage: P1 = Polyhedron([[0],[1]], base_ring=ZZ)
     1943            sage: P2 = Polyhedron([[0],[1]], base_ring=QQ)
     1944            sage: P1.product(P2)
     1945            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1946
     1947        The cartesian product is the product in the semiring of polyhedra::
     1948
     1949            sage: P1 * P1
     1950            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     1951            sage: P1 * P2
     1952            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1953            sage: P2 * P2
     1954            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1955            sage: 2 * P1
     1956            A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices
     1957            sage: P1 * 2.0
     1958            A 1-dimensional polyhedron in RDF^1 defined as the convex hull of 2 vertices
     1959        """
     1960        new_vertices = [ list(x)+list(y)
     1961                         for x in self.vertex_generator() for y in other.vertex_generator()]
     1962        new_rays = []
     1963        new_rays.extend( [ r+[0]*other.ambient_dim()
     1964                           for r in self.ray_generator() ] )
     1965        new_rays.extend( [ [0]*self.ambient_dim()+r
     1966                           for r in other.ray_generator() ] )
     1967        new_lines = []
     1968        new_lines.extend( [ l+[0]*other.ambient_dim()
     1969                            for l in self.line_generator() ] )
     1970        new_lines.extend( [ [0]*self.ambient_dim()+l
     1971                            for l in other.line_generator() ] )
    19741972        return Polyhedron(vertices=new_vertices,
    19751973                          rays=new_rays, lines=new_lines,
    1976                           base_ring=self.coerce_field(other_field))
    1977            
    1978 
    1979     def __mul__(self, other):
     1974                          base_ring=self.parent()._coerce_base_ring(other))
     1975
     1976    _mul_ = product
     1977   
     1978    def dilation(self, scalar):
    19801979        """
    1981         Multiplication by ``other``.
     1980        Return the dilated (uniformly stretched) polyhedron.
    19821981
    19831982        INPUT:
    19841983
    1985         - ``other`` -- A scalar, not necessarily in :meth:`field`, or
    1986           a :class:`Polyhedron`.
     1984        - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring`,
     1985          or a :class:`Polyhedron`.
    19871986
    19881987        OUTPUT:
    19891988
     
    19961995             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
    19971996             sage: p.vertex_generator().next()
    19981997             A vertex at (2, 4, 8)
    1999              sage: p2 = p*2
     1998             sage: p2 = p.dilation(2)
    20001999             sage: p2.vertex_generator().next()
    20012000             A vertex at (4, 8, 16)
     2001             sage: p.dilation(2) == p * 2
     2002             True
    20022003        """
    2003         if is_Polyhedron(other):
    2004             new_vertices = [ list(x)+list(y)
    2005                              for x in self.vertex_generator() for y in other.vertex_generator()]
    2006             new_rays = []
    2007             new_rays.extend( [ list(r)+[0]*other.ambient_dim()
    2008                                for r in self.ray_generator() ] )
    2009             new_rays.extend( [ [0]*self.ambient_dim()+list(r)
    2010                                for r in other.ray_generator() ] )
    2011             new_lines = []
    2012             new_lines.extend( [ list(l)+[0]*other.ambient_dim()
    2013                                 for l in self.line_generator() ] )
    2014             new_lines.extend( [ [0]*self.ambient_dim()+list(l)
    2015                                for l in other.line_generator() ] )
    2016         else:
    2017             new_vertices = [ list(other*v()) for v in self.vertex_generator()]
    2018             new_rays =  self.rays()
    2019             new_lines = self.lines()
    2020 
     2004        new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator()]
     2005        new_rays =  self.rays()
     2006        new_lines = self.lines()
    20212007        return Polyhedron(vertices=new_vertices,
    20222008                          rays=new_rays, lines=new_lines,
    2023                           base_ring=self.coerce_field(other))
    2024 
    2025 
    2026     def __rmul__(self,other):
     2009                          base_ring=self.parent()._coerce_base_ring(scalar.parent()))
     2010
     2011    def _acted_upon_(self, actor, self_on_left):
    20272012        """
    2028         Right multiplication.
    2029 
    2030         See :meth:`__mul__` for details.
     2013        Implement the multiplicative action by scalars or other polyhedra.
     2014
     2015        INPUT:
     2016
     2017        - ``actor`` -- A scalar, not necessarily in :meth:`base_ring`,
     2018          or a :class:`Polyhedron`.
     2019
     2020        OUTPUT:
     2021
     2022        Multiplication by another polyhedron returns the product
     2023        polytope. Multiplication by a scalar returns the polytope
     2024        dilated by that scalar, possibly coerced to the bigger field.
    20312025
    20322026        EXAMPLES::
    20332027
     2028             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
     2029             sage: p._acted_upon_(2, True) == p.dilation(2)
     2030             True
     2031             sage: p*2 == p.dilation(2)
     2032             True
     2033             sage: p*p == p.product(p)
     2034             True
     2035             sage: p + vector(ZZ,[1,2,3]) == p.translation([1,2,3])
     2036             True
     2037        """
     2038        if is_Polyhedron(actor):
     2039            return self.product(actor)
     2040        if is_Vector(actor):
     2041            return self.translation(actor)
     2042        else:
     2043            return self.dilation(actor)
     2044
     2045    def __div__(self, scalar):
     2046        """
     2047        Divide by a scalar factor.
     2048
     2049        See :meth:`dilation` for details.
     2050
     2051        EXAMPLES::
     2052
    20342053            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,4)])
    2035             sage: p2 = 3*p + p
    2036             sage: p2.vertex_generator().next()
    2037             A vertex at (8, 16, 32)
     2054            sage: (p/5).Vrepresentation()
     2055            (A vertex at (2/5, 4/5, 8/5), A vertex at (3/5, 9/5, 27/5))
    20382056        """
    2039         return self.__mul__(other)
    2040 
    2041 
    2042     def union(self, other):
    2043         """
    2044         Deprecated.  Use ``self.convex_hull(other)`` instead.
    2045        
    2046         EXAMPLES::
    2047        
    2048             sage: Polyhedron(vertices=[[0]]).union( Polyhedron(vertices=[[1]]) )
    2049             doctest:...: DeprecationWarning: (Since Sage Version 4.4.4)
    2050             The function union is replaced by convex_hull.
    2051             A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices
    2052         """
    2053         from sage.misc.misc import deprecation
    2054         deprecation('The function union is replaced by convex_hull.', 'Sage Version 4.4.4')
    2055         return self.convex_hull(other)
    2056 
    2057 
     2057        return self.dilation(1/scalar)
     2058
     2059    @coerce_binop
    20582060    def convex_hull(self, other):
    20592061        """
    20602062        Return the convex hull of the set-theoretic union of the two
     
    20812083        hull_vertices = self.vertices() + other.vertices()
    20822084        hull_rays = self.rays() + other.rays()
    20832085        hull_lines = self.lines() + other.lines()
    2084         hull_field = self.coerce_field(other)
    2085         return Polyhedron(vertices=hull_vertices,
    2086                           rays=hull_rays, lines=hull_lines,
    2087                           base_ring=hull_field)
    2088 
    2089 
     2086        return self.parent().element_class(self.parent(), [hull_vertices, hull_rays, hull_lines], None)
     2087
     2088    @coerce_binop
    20902089    def intersection(self, other):
    20912090        """
    20922091        Return the intersection of one polyhedron with another.
     
    20972096
    20982097        OUTPUT:
    20992098
    2100         The intersection.
     2099        The intersection.
     2100
     2101        Note that the intersection of two `\ZZ`-polyhedra might not be
     2102        a `\ZZ`-polyhedron. In this case, a `\QQ`-polyhedron is
     2103        returned.
    21012104
    21022105        EXAMPLES::
    21032106
    21042107            sage: cube = polytopes.n_cube(3)
    21052108            sage: oct = polytopes.cross_polytope(3)
    2106             sage: cube_oct = cube.intersection(oct*2)
    2107             sage: len(list( cube_oct.vertex_generator() ))
    2108             12
    2109             sage: cube_oct
    2110             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
     2109            sage: cube.intersection(oct*2)
     2110            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 12 vertices
     2111
     2112       The intersection of two `\ZZ`-polyhedra is not necessarily a `\ZZ`-polyhedron::
     2113
     2114            sage: P = Polyhedron([(0,0),(1,1)], base_ring=ZZ)
     2115            sage: P.intersection(P)
     2116            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices
     2117            sage: Q = Polyhedron([(0,1),(1,0)], base_ring=ZZ)
     2118            sage: P.intersection(Q)
     2119            A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
     2120            sage: _.Vrepresentation()
     2121            (A vertex at (1/2, 1/2),)
    21112122        """
    2112         new_ieqs = []
    2113         new_ieqs.extend(self.inequalities())
    2114         new_ieqs.extend(other.inequalities())
    2115 
    2116         new_eqns = []
    2117         new_eqns.extend(self.equations())
    2118         new_eqns.extend(other.equations())
    2119 
    2120         return Polyhedron(ieqs = new_ieqs, eqns = new_eqns,
    2121                           base_ring=self.coerce_field(other))
    2122 
     2123        new_ieqs = self.inequalities() + other.inequalities()
     2124        new_eqns = self.equations() + other.equations()
     2125        parent = self.parent()
     2126        try:
     2127            return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2128        except TypeError,msg:
     2129            if self.base_ring() is ZZ:
     2130                parent = parent.base_extend(QQ)
     2131                return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2132            else:
     2133                raise TypeError(msg)
    21232134
    21242135    def edge_truncation(self, cut_frac = Integer(1)/3):
    21252136        r"""
     
    21552166
    21562167        return Polyhedron(vertices=new_vertices, rays=new_rays,
    21572168                          lines=new_lines,
    2158                           base_ring=self.coerce_field(cut_frac))
     2169                          base_ring=self.parent()._coerce_base_ring(cut_frac))
    21592170
    21602171
    21612172    def _make_polyhedron_face(self, Vindices, Hindices):
     
    21842195        """
    21852196        return PolyhedronFace_base(self, Vindices, Hindices)
    21862197
    2187 
     2198    @cached_method
    21882199    def face_lattice(self):
    21892200        """
    21902201        Return the face-lattice poset.
     
    23292340            http://portal.acm.org/citation.cfm?id=763203 and free of
    23302341            charge at http://arxiv.org/abs/math/0106043
    23312342        """
    2332         try:
    2333             return self._face_lattice
    2334         except AttributeError:
    2335             pass
    2336        
    23372343        coatom_to_Hindex = [ h.index() for h in self.inequality_generator() ]
    23382344        Hindex_to_coatom = [None] * self.n_Hrepresentation()
    23392345        for i in range(0,len(coatom_to_Hindex)):
     
    23652371            return self._make_polyhedron_face(Vindices, Hindices)
    23662372
    23672373        from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
    2368         self._face_lattice = Hasse_diagram_from_incidences\
     2374        return Hasse_diagram_from_incidences\
    23692375            (atoms_incidences, coatoms_incidences,
    23702376             face_constructor=face_constructor, required_atoms=atoms_vertices)
    2371         return self._face_lattice
    2372 
    2373 
     2377
     2378
     2379    @cached_method
    23742380    def f_vector(self):
    23752381        r"""
    23762382        Return the f-vector.
     
    23872393            sage: p.f_vector()
    23882394            (1, 7, 12, 7, 1)
    23892395        """
    2390         try:
    2391             return self._f_vector
    2392         except AttributeError:
    2393             self._f_vector = vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
    2394             return self._f_vector
    2395 
    2396 
     2396        return vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
     2397   
     2398    @cached_method
    23972399    def vertex_graph(self):
    23982400        """
    23992401        Return a graph in which the vertices correspond to vertices
     
    24082410            sage: s4.is_eulerian()
    24092411            True
    24102412        """
    2411         try:
    2412             return self._graph
    2413         except AttributeError:
    2414             self._graph = Graph(self.vertex_adjacency_matrix(), loops=True)
    2415             return self._graph
    2416 
     2413        return Graph(self.vertex_adjacency_matrix(), loops=True)
    24172414
    24182415    graph = vertex_graph
    24192416
    2420 
    24212417    def polar(self):
    24222418        """
    2423         Return the polar (dual) polytope.  The original vertices are
    2424         translated so that their barycenter is at the origin, and then
    2425         the vertices are used as the coefficients in the polar inequalities.
     2419        Return the polar (dual) polytope.
     2420
     2421        The original vertices are translated so that their barycenter
     2422        is at the origin, and then the vertices are used as the
     2423        coefficients in the polar inequalities.
    24262424
    24272425        EXAMPLES::
    24282426
    2429             sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]])
     2427            sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]], base_ring=QQ)
    24302428            sage: p
    24312429            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices
    24322430            sage: p.polar()
     
    24342432        """
    24352433        assert self.is_compact(), "Not a polytope."
    24362434
    2437         verts = [list(v() - self.center()) for v in self.vertex_generator()]
    2438         return Polyhedron(ieqs=[[1] + list(v) for v in verts],
    2439                           base_ring=self.base_ring())
    2440 
     2435        verts = [list(v.vector() - self.center()) for v in self.vertex_generator()]
     2436        base_ring = self.parent()._coerce_base_ring(self.center().parent().base_ring())
     2437        return Polyhedron(ieqs=[[1] + list(v) for v in verts], base_ring=base_ring)
    24412438
    24422439    def pyramid(self):
    24432440        """
     
    24452442
    24462443        EXAMPLES::
    24472444
    2448             sage: square = polytopes.n_cube(2)
    2449             sage: egyptian_pyramid = square.pyramid()
     2445            sage: square = polytopes.n_cube(2);  square
     2446            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     2447            sage: egyptian_pyramid = square.pyramid();  egyptian_pyramid
     2448            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices
    24502449            sage: egyptian_pyramid.n_vertices()
    24512450            5
    24522451            sage: for v in egyptian_pyramid.vertex_generator(): print v
     
    24572456            A vertex at (1, 0, 0)
    24582457        """
    24592458        new_verts = \
    2460             [[0] + list(x) for x in self.Vrep_generator()] + \
     2459            [[0] + x for x in self.Vrep_generator()] + \
    24612460            [[1] + list(self.center())]
    2462 
    2463         return Polyhedron(vertices = new_verts, base_ring=self.field())
    2464 
     2461        return Polyhedron(vertices=new_verts)
    24652462
    24662463    def bipyramid(self):
    24672464        """
     
    24962493            [[-1] + list(self.center())]
    24972494        new_rays = [[0] + r for r in self.rays()]
    24982495        new_lines = [[0] + list(l) for l in self.lines()]
    2499         return Polyhedron(vertices=new_verts,
    2500                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2501 
     2496        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines)
    25022497
    25032498    def prism(self):
    25042499        """
     
    25092504            sage: square = polytopes.n_cube(2)
    25102505            sage: cube = square.prism()
    25112506            sage: cube
    2512             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
     2507            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
    25132508            sage: hypercube = cube.prism()
    25142509            sage: hypercube.n_vertices()
    25152510            16
     
    25182513        new_verts.extend( [ [0] + v for v in self.vertices()] )
    25192514        new_verts.extend( [ [1] + v for v in self.vertices()] )
    25202515        new_rays =        [ [0] + r for r in self.rays()]
    2521         new_lines =       [ [0] + list(l) for l in self.lines()]
    2522         return Polyhedron(vertices=new_verts,
    2523                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2524 
     2516        new_lines =       [ [0] + l for l in self.lines()]
     2517        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines,
     2518                          base_ring=self.base_ring())
    25252519
    25262520    def projection(self):
    25272521        """
     
    25382532        self.projection = Projection(self)
    25392533        return self.projection
    25402534
    2541 
    25422535    def render_solid(self, **kwds):
    25432536        """
    25442537        Return a solid rendering of a 2- or 3-d polytope.
     
    25572550            return proj.render_fill_2d(**kwds)
    25582551        raise ValueError, "render_solid is only defined for 2 and 3 dimensional polyhedra."
    25592552
    2560 
    25612553    def render_wireframe(self, **kwds):
    25622554        """
    25632555        For polytopes in 2 or 3 dimensions, return the edges
     
    25772569            return proj.render_outline_2d(**kwds)
    25782570        raise ValueError, "render_wireframe is only defined for 2 and 3 dimensional polyhedra."
    25792571
    2580 
    25812572    def schlegel_projection(self, projection_dir = None, height = 1.1):
    25822573        """
    25832574        Returns a projection object whose transformed coordinates are
     
    25942585        """
    25952586        proj = self.projection()
    25962587        if projection_dir == None:
    2597             v = self.vertices()
    2598             f0 = (self.facial_incidences()[0])[1]
    2599             projection_dir = [sum([v[f0[i]][j]/len(f0) for i in range(len(f0))])
    2600                               for j in range(len(v[0]))]
     2588            vertices = self.vertices()
     2589            facet = self.Hrepresentation(0)
     2590            f0 = [ v.index() for v in facet.incident() ]
     2591            projection_dir = [sum([vertices[f0[i]][j]/len(f0) for i in range(len(f0))])
     2592                              for j in range(self.ambient_dim())]
    26012593        return proj.schlegel(projection_direction = projection_dir, height = height)
    26022594       
    2603 
    26042595    def lrs_volume(self, verbose = False):
    26052596        """
    26062597        Computes the volume of a polytope.
     
    26512642
    26522643        raise ValueError, "lrs did not return a volume"
    26532644
    2654 
    26552645    def contains(self, point):
    26562646        """
    26572647        Test whether the polyhedron contains the given ``point``.
     
    26932683        The empty polyhedron needs extra care, see trac #10238::
    26942684
    26952685            sage: empty = Polyhedron(); empty
    2696             The empty polyhedron in QQ^0
     2686            The empty polyhedron in ZZ^0
    26972687            sage: empty.contains([])
    26982688            False
    26992689            sage: empty.contains([0])               # not a point in QQ^0
    27002690            False
    27012691            sage: full = Polyhedron(vertices=[()]); full
    2702             A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex
     2692            A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex
    27032693            sage: full.contains([])
    27042694            True
    27052695            sage: full.contains([0])
     
    27112701            if len(point)>0:
    27122702                return False
    27132703            else:
    2714                 p = vector(self.field(), [])
     2704                p = vector(self.base_ring(), [])
    27152705
    27162706        if len(p)!=self.ambient_dim():
    27172707            return False
     
    27212711                return False
    27222712        return True
    27232713
    2724 
    27252714    def interior_contains(self, point):
    27262715        """
    27272716        Test whether the interior of the polyhedron contains the
     
    27582747        The empty polyhedron needs extra care, see trac #10238::
    27592748
    27602749            sage: empty = Polyhedron(); empty
    2761             The empty polyhedron in QQ^0
     2750            The empty polyhedron in ZZ^0
    27622751            sage: empty.interior_contains([])
    27632752            False
    27642753        """
     
    27682757            if len(point)>0:
    27692758                return False
    27702759            else:
    2771                 p = vector(self.field(), [])
     2760                p = vector(self.base_ring(), [])
    27722761
    27732762        if len(p)!=self.ambient_dim():
    27742763            return False
     
    27782767                return False
    27792768        return True
    27802769
    2781 
    27822770    def relative_interior_contains(self, point):
    27832771        """
    27842772        Test whether the relative interior of the polyhedron
     
    28092797        The empty polyhedron needs extra care, see trac #10238::
    28102798
    28112799            sage: empty = Polyhedron(); empty
    2812             The empty polyhedron in QQ^0
     2800            The empty polyhedron in ZZ^0
    28132801            sage: empty.relative_interior_contains([])
    28142802            False
    28152803        """
     
    28192807            if len(point)>0:
    28202808                return False
    28212809            else:
    2822                 p = vector(self.field(), [])
     2810                p = vector(self.base_ring(), [])
    28232811
    28242812        if len(p)!=self.ambient_dim():
    28252813            return False
     
    28492837        """
    28502838        return self.is_compact() and (self.dim()+1==self.n_vertices())
    28512839
     2840    @cached_method
    28522841    def is_lattice_polytope(self):
    28532842        r"""
    28542843        Return whether the polyhedron is a lattice polytope.
     
    28652854            sage: polytopes.regular_polygon(5).is_lattice_polytope()
    28662855            False
    28672856        """
    2868         try:
    2869             return self._is_lattice_polytope
    2870         except AttributeError:
    2871             pass
    2872         self._is_lattice_polytope = self.is_compact() and \
    2873             all(v.is_integral() for v in self.vertex_generator())
    2874         return self._is_lattice_polytope
     2857        if not self.is_compact():
     2858            return False
     2859        if self.base_ring() is ZZ:
     2860            return True
     2861        return all(v.is_integral() for v in self.vertex_generator())
    28752862       
     2863    @cached_method
    28762864    def lattice_polytope(self, envelope=False):
    28772865        r"""
    28782866        Return an encompassing lattice polytope.
     
    29352923        if not self.is_compact():
    29362924            raise NotImplementedError, 'Only compact lattice polytopes are allowed.'
    29372925
    2938         def nonintegral_error():
    2939             raise ValueError, 'Some vertices are not integral. '+\
    2940                 'You probably want to add the argument '+\
    2941                 '"envelope=True" to compute an enveloping lattice polytope.'
    2942 
    2943         # try to make use of cached values, if possible
    2944         if envelope:
    2945             try:
    2946                 return self._lattice_polytope
    2947             except AttributeError:
    2948                 pass
    2949         else:
    2950             try:
    2951                 assert self._is_lattice_polytope
    2952                 return self._lattice_polytope
    2953             except AttributeError:
    2954                 pass
    2955             except AssertionError:
    2956                 nonintegral_error()
    2957 
    2958         # find the integral vertices
    29592926        try:
    2960             vertices = matrix(ZZ, self.vertices()).transpose()
    2961             self._is_lattice_polytope = True
     2927            vertices = self.vertices_matrix(ZZ)
    29622928        except TypeError:
    2963             self._is_lattice_polytope = False
    2964             if envelope==False: nonintegral_error()
     2929            if envelope==False:
     2930                raise ValueError, 'Some vertices are not integral. '+\
     2931                    'You probably want to add the argument '+\
     2932                    '"envelope=True" to compute an enveloping lattice polytope.'
    29652933            vertices = []
    29662934            for v in self.vertex_generator():
    29672935                vbox = [ set([floor(x),ceil(x)]) for x in v ]
     
    29702938
    29712939        # construct the (enveloping) lattice polytope
    29722940        from sage.geometry.lattice_polytope import LatticePolytope
    2973         self._lattice_polytope = LatticePolytope(vertices)
    2974         return self._lattice_polytope
     2941        return LatticePolytope(vertices)
    29752942
    29762943    def _integral_points_PALP(self):
    29772944        r"""
     
    30393006        box_max = []
    30403007        if self.n_vertices==0:
    30413008            raise ValueError('Empty polytope is not allowed')
     3009        if not self.is_compact():
     3010            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
    30423011        for i in range(0,self.ambient_dim()):
    3043             coords = [ v[i] for v in self.Vrep_generator() ]
     3012            coords = [ v[i] for v in self.vertex_generator() ]
    30443013            max_coord = max(coords)
    30453014            min_coord = min(coords)
    30463015            if integral:
     
    30973066
    30983067            sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
    30993068            sage: simplex = Polyhedron(v); simplex
    3100             A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     3069            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
    31013070            sage: len(simplex.integral_points())
    31023071            49
    31033072
     
    31473116        # assert all(self.contains(p) for p in points)   # slow
    31483117        return tuple(points)
    31493118   
     3119    @cached_method
    31503120    def combinatorial_automorphism_group(self):
    31513121        """
    31523122        Computes the combinatorial automorphism group of the vertex
     
    31813151            sage: P.combinatorial_automorphism_group()
    31823152            Permutation Group with generators [(3,4)]
    31833153        """
    3184         if '_combinatorial_automorphism_group' in self.__dict__:
    3185             return self._combinatorial_automorphism_group
    3186 
    31873154        from sage.groups.perm_gps.permgroup import PermutationGroup
    3188 
    31893155        G = Graph()
    31903156        for edge in self.vertex_graph().edges():
    31913157            i = edge[0]
     
    32033169        self._combinatorial_automorphism_group = group
    32043170        return group
    32053171
    3206 
    32073172    def _affine_coordinates(self, Vrep_object):
    32083173        r"""
    32093174        Return affine coordinates for a V-representation object.
     
    32423207        if len(v) != self.ambient_dim():
    32433208            raise ValueError('Incorrect dimension: '+str(v))
    32443209
    3245         return vector(self.field(), [ v[i] for i in self._affine_coordinates_pivots ])
     3210        return vector(self.base_ring(), [ v[i] for i in self._affine_coordinates_pivots ])
    32463211       
    3247 
     3212    @cached_method
    32483213    def restricted_automorphism_group(self):
    32493214        r"""
    32503215        Return the restricted automorphism group.
     
    33923357            sage: p.restricted_automorphism_group()
    33933358            Permutation Group with generators [(2,3)]
    33943359        """
    3395         if '_restricted_automorphism_group' in self.__dict__:
    3396             return self._restricted_automorphism_group
    3397 
    33983360        from sage.groups.perm_gps.permgroup import PermutationGroup
    33993361
    3400         if self.field() is QQ:
     3362        if self.base_ring() is ZZ or self.base_ring() is QQ:
    34013363            def rational_approximation(c):
    34023364                return c
    34033365
    3404         else:  # self.field() is RDF
     3366        elif self.base_ring() is RDF:
    34053367            c_list = []
    34063368            def rational_approximation(c):
    34073369                # Implementation detail: Return unique integer if two
     
    34133375                        return i
    34143376                c_list.append(c)
    34153377                return len(c_list)-1
    3416        
     3378
    34173379        # The algorithm identifies the restricted automorphism group
    34183380        # with the automorphism group of a edge-colored graph. The
    34193381        # nodes of the graph are the V-representation objects. If all
     
    34703432
    34713433
    34723434
    3473 
    3474 
    3475 
    34763435#########################################################################
    3477 class PolyhedronFace_base(SageObject):
     3436class PolyhedronFace_base(Polyhedron_base):
    34783437    r"""
    34793438    A face of a polyhedron.
    34803439   
     
    35373496            sage: PolyhedronFace_base(Polyhedron(), [], [])   # indirect doctest
    35383497            <>
    35393498        """
     3499        Element.__init__(self, parent=polyhedron.parent())
    35403500        self._polyhedron = polyhedron
    35413501        self._ambient_Vrepresentation_indices = tuple(V_indices)
    35423502        self._ambient_Hrepresentation_indices = tuple(H_indices)
    35433503        self._ambient_Vrepresentation = tuple( polyhedron.Vrepresentation(i) for i in V_indices )
    35443504        self._ambient_Hrepresentation = tuple( polyhedron.Hrepresentation(i) for i in H_indices )
    3545         # self._Vrepresentation =
    3546         # self._Hrepresentation =
     3505        self._Vrepresentation = tuple()
     3506        self._Hrepresentation = tuple()
    35473507       
    3548 
    35493508    def ambient_Hrepresentation(self, index=None):
    35503509        r"""
    35513510        Return the H-representation objects of the ambient polytope
     
    35883547        else:
    35893548            return self._ambient_Hrepresentation[index]
    35903549       
    3591 
    35923550    def ambient_Vrepresentation(self, index=None):
    35933551        r"""
    35943552        Return the V-representation objects of the ambient polytope
     
    36313589        else:
    36323590            return self._ambient_Vrepresentation[index]
    36333591
    3634 
     3592    @cached_method
    36353593    def n_ambient_Hrepresentation(self):
    36363594        """
    36373595        Return the number of objects that make up the ambient
     
    36573615            sage: face.n_ambient_Hrepresentation()
    36583616            4
    36593617        """
    3660         return len(self._ambient_Hrepresentation)
    3661 
    3662 
     3618        return len(self.ambient_Hrepresentation())
     3619
     3620    @cached_method
    36633621    def n_ambient_Vrepresentation(self):
    36643622        """
    36653623        Return the number of objects that make up the ambient
     
    36823640            sage: face.n_ambient_Vrepresentation()
    36833641            2
    36843642        """
    3685         return len(self._ambient_Vrepresentation)
    3686 
    3687 
     3643        return len(self.ambient_Vrepresentation())
     3644
     3645    @cached_method
    36883646    def dim(self):
    36893647        """
    36903648        Return the dimension of the face.
     
    37013659              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    37023660              1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3]
    37033661        """
    3704         if '_dim' in self.__dict__:
    3705             return self._dim
    3706 
    37073662        if self.n_ambient_Vrepresentation()==0:
    3708             self._dim = -1
     3663            return -1
    37093664        else:
    37103665            origin = vector(self.ambient_Vrepresentation(0))
    37113666            v_list = [ vector(v)-origin for v in self.ambient_Vrepresentation() ]
    3712             self._dim = matrix(v_list).rank()
    3713         return self._dim
    3714 
     3667            return matrix(v_list).rank()
    37153668
    37163669    def _repr_(self):
    37173670        r"""
  • sage/geometry/polyhedron/base_ZZ.py

    diff --git a/sage/geometry/polyhedron/base_ZZ.py b/sage/geometry/polyhedron/base_ZZ.py
    a b  
    139139            sage: p.polar()
    140140            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
    141141            sage: type(_)
    142             <class 'sage.geometry.polyhedron.backend_ppl.Polyhedron_ZZ_ppl'>
     142            <class 'sage.geometry.polyhedron.backend_ppl.Polyhedra_ZZ_ppl_with_category.element_class'>
    143143            sage: p.polar().base_ring()
    144144            Integer Ring
    145145        """
     
    173173       
    174174        * ``self`` is compact (a polytope).
    175175
    176         * ``self`` contains the origin.
     176        * ``self`` contains the origin as an interior point.
    177177
    178178        This implies that
    179179       
     
    182182        * The dual polyhedron is again a polytope (that is, a compact
    183183          polyhedron), though not necessarily a lattice polytope.
    184184
     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
    185194        REFERENCES::
    186195
    187196        ..  [PALP]
     
    191200            Comput.Phys.Commun. 157 (2004) 87-106
    192201            http://arxiv.org/abs/math/0204356
    193202        """
    194         return self.is_compact() and self.contains(self.ambient_space().zero())
     203        return self.is_compact() and self.interior_contains(self.ambient_space().zero())
    195204
    196     def fibrations(self):
     205    def fibration_generator(self, dim):
    197206        """
     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       
    198224        EXAMPLES::
    199225
    200226            sage: P = Polyhedron(toric_varieties.P4_11169().fan().rays(), base_ring=ZZ)
    201             sage: list( P.fibrations() )
    202             [A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices]
     227            sage: list( P.fibration_generator(2) )
     228            [A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices]
    203229        """
    204         if not self.has_IP_property():
    205             raise ValueError('The polytope must have the IP property.')
    206         # todo: just go through pairs of points on the same facet
    207         fiber_dimension = 2
    208         points = self.integral_points()
     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()]
    209236        fibers = set()
    210         for i1 in range(0,len(points)):
    211             p1 = points[i1]
    212             if p1.is_zero():
    213                 continue
    214             for i2 in range(i1+1,len(points)):
    215                 p2 = points[i2]
    216                 if p2.is_zero():
     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:
    217242                    continue
    218                 plane_12 = Polyhedron(lines=[p1,p2])
    219                 if plane_12.dim() != 2:
     243                fiber = self.intersection(plane)
     244                if fiber.base_ring() is not ZZ:
    220245                    continue
    221                 fiber = self.intersection(plane_12)
    222                 if not fiber.is_lattice_polytope():
    223                     continue
    224                 fiber_matrix = matrix(ZZ,sorted(fiber.integral_points()))
    225                 fiber_matrix.set_immutable()
    226                 if fiber_matrix not in fibers:
     246                fiber_vertices = tuple(sorted(tuple(v) for v in fiber.vertex_generator()))
     247                if fiber_vertices not in fibers:
    227248                    yield fiber
    228                     fibers.update([fiber_matrix])
     249                    fibers.update([fiber_vertices])
     250                plane.delete()
    229251               
    230 
     252                   
    231253
    232254
    233255       
  • 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` or
    163         `\ZZ` coefficients depending on ``base_ring``.
     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
     271 
     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
    273276
    274     if backend is not None:
    275         if backend=='ppl' and base_ring is QQ:
    276             from backend_ppl import Polyhedron_QQ_ppl
    277             return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
    278         if backend=='ppl' and base_ring is ZZ:
    279             from backend_ppl import Polyhedron_ZZ_ppl
    280             return Polyhedron_ZZ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
    281         if backend=='cddr':
    282             from backend_cdd import Polyhedron_QQ_cdd
    283             return Polyhedron_QQ_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
    284         if backend=='cddf':
    285             from backend_cdd import Polyhedron_RDF_cdd
    286             return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
    287         raise ValueError('No suitable backend implemented.')
     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
     285    else:
     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
    288318
    289     if base_ring is QQ:
    290         from backend_ppl import Polyhedron_QQ_ppl
    291         return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
    292     elif base_ring is RDF:
    293         from backend_cdd import Polyhedron_RDF_cdd
    294         return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
    295     elif base_ring is ZZ:
    296         from backend_ppl import Polyhedron_ZZ_ppl
    297         return Polyhedron_ZZ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
    298     else:
    299         raise ValueError('Polyhedron objects can only be constructed over QQ and RDF')
     319    # Add the origin if necesarry
     320    if got_Vrep and len(vertices)==0:
     321        vertices = [ [0]*ambient_dim ]
    300322
     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()
     327   
     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]
    301342
    302 
    303 
    304 
     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         R = polyhedron.base_ring()
    64         self._representation_data = tuple(R(x) for x in data)
    65         self._polyhedron = polyhedron
    66 
    6755    def __len__(self):
    6856        """
    6957        Returns the length of the representation data.
    7058       
    7159        TESTS::
    7260       
    73             sage: import sage.geometry.polyhedron.representation as P
    74             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    75             sage: pr.__len__()
     61            sage: p = Polyhedron(vertices=[[1,2,3]])
     62            sage: v = p.Vrepresentation(0)
     63            sage: v.__len__()
    7664            3
    7765        """
    7866        return len(self._representation_data)
     
    8371       
    8472        TESTS::
    8573       
    86             sage: import sage.geometry.polyhedron.representation as P
    87             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    88             sage: pr.__getitem__(1)
     74            sage: p = Polyhedron(vertices=[[1,2,3]])
     75            sage: v = p.Vrepresentation(0)
     76            sage: v.__getitem__(1)
    8977            2
    9078        """
    91         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
    92168
    93169    def polyhedron(self):
    94170        """
     
    96172       
    97173        TESTS::
    98174       
    99             sage: import sage.geometry.polyhedron.representation as P
    100             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    101             sage: pr.polyhedron()
    102             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
    103179        """
    104180        return self._polyhedron
    105181
     
    108184        Returns the vector representation of the representation
    109185        object. Shorthand for the vector() method.
    110186
    111         Note that the vector() method is only implemented in derived
    112         classes.
    113 
    114187        TESTS::
    115188       
    116             sage: import sage.geometry.polyhedron.representation as P
    117             sage: pr = Polyhedron(vertices = [[1,2,3]]).Vrepresentation(0)
    118             sage: pr.__call__()
     189            sage: p = Polyhedron(vertices=[[1,2,3]])
     190            sage: v = p.Vrepresentation(0)
     191            sage: v.__call__()
    119192            (1, 2, 3)
    120            
    121             sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
    122             sage: pr.__call__()
    123             Traceback (most recent call last):
    124             ...
    125             AttributeError: 'PolyhedronRepresentation' object has no attribute 'vector'
    126193        """
    127         return self.vector()
     194        return self._vector
    128195
    129196    def index(self):
    130197        """
     
    150217        """
    151218        return self._index
    152219
     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])
    153289
    154290
    155291class Hrepresentation(PolyhedronRepresentation):
     
    157293    The internal base class for H-representation objects of
    158294    a polyhedron. Inherits from ``PolyhedronRepresentation``.
    159295    """
    160     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):
    161317        """
    162318        Initialization function.
    163319
     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
    164331        TESTS::
    165332
    166333            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
    167             sage: pH = p.Hrepresentation(0)
     334            sage: pH = p.Hrepresentation(0) # indirect doctest
    168335            sage: TestSuite(pH).run(skip='_test_pickling')
    169336        """
    170         if len(data) != 1+polyhedron.ambient_dim():
     337        assert polyhedron.parent() is self._polyhedron_parent
     338        if len(data) != self._vector.degree():
    171339            raise ValueError, \
    172340                'H-representation data requires a list of length ambient_dim+1'
    173         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
    174348        self._index = len(polyhedron._Hrepresentation)
    175349        polyhedron._Hrepresentation.append(self)
    176    
    177     @cached_method
    178     def vector(self):
    179         """
    180         Returns the vector representation of the H-representation object.
    181 
    182         OUTPUT:
    183        
    184         A vector of length
    185         :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim` + 1.
    186 
    187         EXAMPLES::
    188 
    189             sage: s = polytopes.cuboctahedron()
    190             sage: v = s.vertex_generator().next()
    191             sage: v
    192             A vertex at (-1/2, -1/2, 0)
    193             sage: v.vector()
    194             (-1/2, -1/2, 0)
    195             sage: v()
    196             (-1/2, -1/2, 0)
    197             sage: type(v())
    198             <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
    199         """
    200         return self.polyhedron().Hrepresentation_space()(self._representation_data)
     350        self._polyhedron = polyhedron
    201351
    202352    def is_H(self):
    203353        """
     
    239389        """
    240390        return False
    241391   
    242     @cached_method
    243392    def A(self):
    244393        r"""
    245394        Returns the coefficient vector `A` in `A\vec{x}+b`.
     
    251400            sage: pH.A()
    252401            (1, 0)
    253402        """
    254         return self.polyhedron().ambient_space()(self._representation_data[1:])
     403        return self._A
    255404
    256     @cached_method
    257405    def b(self):
    258406        r"""
    259407        Returns the constant `b` in `A\vec{x}+b`.
     
    265413            sage: pH.b()
    266414            0
    267415        """
    268         return self._representation_data[0]
     416        return self._b
    269417
    270418    def neighbors(self):
    271419        """
     
    365513        if is_Vector(Vobj):
    366514            return self.A() * Vobj + self.b()
    367515        return Vobj.evaluated_on(self)
    368         #return self.A() * Vobj.vector() + self.b()
    369516
    370517    def incident(self):
    371518        """
     
    400547    A linear inequality (supporting hyperplane) of the
    401548    polyhedron. Inherits from ``Hrepresentation``.
    402549    """
    403     def __init__(self, polyhedron, data):
    404         """
    405         A linear inequality (supporting hyperplane) of the
    406         polyhedron. Inherits from ``Hrepresentation``.
    407 
    408         TESTS::
    409 
    410             sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
    411             sage: a = p.inequality_generator().next()
    412             sage: a
    413             An inequality (-1, 1, 0) x + 0 >= 0
    414             sage: TestSuite(a).run(skip='_test_pickling')
    415         """
    416         super(Inequality, self).__init__(polyhedron, data)
    417 
    418550
    419551    def type(self):
    420552        r"""
     
    559691    strictly smaller-dimensional than the ambient space, and contained
    560692    in this hyperplane. Inherits from ``Hrepresentation``.
    561693    """
    562     def __init__(self, polyhedron, data):
    563         """
    564         Initializes an equation object.
    565 
    566         TESTS::
    567 
    568             sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
    569             sage: a = p.equation_generator().next()
    570             sage: a
    571             An equation (0, 0, 1) x + 0 == 0
    572             sage: TestSuite(a).run(skip='_test_pickling')
    573         """
    574         super(Equation, self).__init__(polyhedron, data)
    575 
    576694
    577695    def type(self):
    578696        r"""
     
    693811    The base class for V-representation objects of a
    694812    polyhedron. Inherits from ``PolyhedronRepresentation``.
    695813    """
    696     def __init__(self, polyhedron, data):
     814
     815    def __init__(self, polyhedron_parent):
    697816        """
    698         Initialization function for the vertex representation.
    699 
     817        Initializes the PolyhedronRepresentation object.
     818       
    700819        TESTS::
    701820       
    702             sage: p = Polyhedron(ieqs = [[1, 0, 0, 0, 1], [1, 1, 0, 0, 0], [1, 0, 1, 0, 0]])
    703             sage: from sage.geometry.polyhedron.representation import Vrepresentation
    704             sage: p._Vrepresentation = Sequence([])
    705             sage: vr = Vrepresentation(p,[1,2,3,4])
    706             sage: vr.__init__(p,[1,2,3,5])
    707             sage: vr.vector()
    708             (1, 2, 3, 5)
    709             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')
    710826        """
    711         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():
    712855            raise ValueError, \
    713856                'V-representation data requires a list of length ambient_dim'
    714         super(Vrepresentation, self).__init__(polyhedron, data)
     857       
     858        for i in range(0, self._vector.degree()):
     859            self._vector.set(i, data[i])
     860
    715861        self._index = len(polyhedron._Vrepresentation)
    716862        polyhedron._Vrepresentation.append(self)
    717 
    718     @cached_method
    719     def vector(self):
    720         """
    721         Returns the vector representation of the V-representation object.
    722 
    723         OUTPUT:
    724        
    725         A vector of length
    726         :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`.
    727 
    728         EXAMPLES::
    729 
    730             sage: s = polytopes.cuboctahedron()
    731             sage: v = s.vertex_generator().next()
    732             sage: v
    733             A vertex at (-1/2, -1/2, 0)
    734             sage: v.vector()
    735             (-1/2, -1/2, 0)
    736             sage: v()
    737             (-1/2, -1/2, 0)
    738             sage: type(v())
    739             <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
    740         """
    741         return self.polyhedron().Vrepresentation_space()(self._representation_data)
     863        self._polyhedron = polyhedron
    742864
    743865    def is_V(self):
    744866        """
     
    9061028    """
    9071029    A vertex of the polyhedron. Inherits from ``Vrepresentation``.
    9081030    """
    909     def __init__(self, polyhedron, data):
    910         """
    911         Initializes the vertex object.
    912 
    913         TESTS::
    914 
    915             sage: p = Polyhedron(ieqs = [[0,0,1],[0,1,0],[1,-1,0]])
    916             sage: v1 = p.vertex_generator().next()
    917             sage: v1
    918             A vertex at (1, 0)
    919             sage: TestSuite(v1).run(skip='_test_pickling')
    920         """
    921         super(Vertex, self).__init__(polyhedron, data)
    922 
    9231031
    9241032    def type(self):
    9251033        r"""
     
    9991107        """
    10001108        return Hobj.A() * self.vector() + Hobj.b()
    10011109
    1002     @cached_method
    10031110    def is_integral(self):
    10041111        r"""
    10051112        Return whether the coordinates of the vertex are all integral.
     
    10141121            sage: [ v.is_integral() for v in p.vertex_generator() ]
    10151122            [True, False, True]
    10161123        """
    1017         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)
    10181125
    10191126
    10201127class Ray(Vrepresentation):
    10211128    """
    10221129    A ray of the polyhedron. Inherits from ``Vrepresentation``.
    10231130    """
    1024     def __init__(self, polyhedron, data):
    1025         """
    1026         Initializes a ray object.
    1027 
    1028         TESTS::
    1029 
    1030             sage: p = Polyhedron(ieqs = [[0,0,1],[0,1,0],[1,-1,0]])
    1031             sage: r1 = p.ray_generator().next()
    1032             sage: r1
    1033             A ray in the direction (0, 1)
    1034             sage: TestSuite(r1).run(skip='_test_pickling')
    1035         """
    1036         super(Ray, self).__init__(polyhedron, data)
    1037 
    10381131
    10391132    def type(self):
    10401133        r"""
     
    11121205    A line (Minkowski summand `\simeq\RR`) of the
    11131206    polyhedron. Inherits from ``Vrepresentation``.
    11141207    """
    1115     def __init__(self, polyhedron, data):
    1116         """
    1117         Initializes the line object.
    1118 
    1119         TESTS::
    1120 
    1121             sage: p = Polyhedron(ieqs = [[1, 0, 0, 1],[1,1,0,0]])
    1122             sage: a = p.line_generator().next()
    1123             sage: p._Vrepresentation = Sequence([])
    1124             sage: a.__init__(p,[1,2,3])
    1125             sage: a
    1126             A line in the direction (1, 2, 3)
    1127             sage: TestSuite(a).run(skip='_test_pickling')
    1128         """
    1129         super(Line, self).__init__(polyhedron, data)
    1130 
    11311208
    11321209    def type(self):
    11331210        r"""
     
    11581235        """
    11591236        return self.LINE
    11601237
    1161 
    11621238    def is_line(self):
    11631239        """
    11641240        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.