Ticket #11763: trac_11763_parents_for_polyhedron.patch

File trac_11763_parents_for_polyhedron.patch, 174.0 KB (added by vbraun, 7 years ago)

Updated patch

  • sage/categories/all.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1329617140 28800
    # Node ID 152bda889a12f2f2897fdc90c03e34ea5bcf540e
    # Parent  f216549bf940e0cdc4848bde8b23aa752d31b6bd
    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)
    166170       
    167 
    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')
    219 
     216        super(Polyhedron_ppl, self)._init_empty_polyhedron()
     217        self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty')
    220218
    221219
    222220
     
    227225
    228226    INPUT:
    229227
    230     - ``ambient_dim`` -- integer. The dimension of the ambient space.
    231 
    232     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     228    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    233229       
    234     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     230    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    235231
    236232    EXAMPLES::
    237233
     
    249245
    250246    INPUT:
    251247
    252     - ``ambient_dim`` -- integer. The dimension of the ambient space.
    253 
    254     - ``Vrep`` -- a list ``[vertices, rays, lines]``.
     248    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
    255249       
    256     - ``Hrep`` -- a list ``[ieqs, eqns]``.
     250    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
    257251
    258252    EXAMPLES::
    259253
  • 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    def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds):
    129122        """
    130123        Construct polyhedron from V-representation data.
    131124
    132125        INPUT:
    133126
    134         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    135        
    136127        - ``vertices`` -- list of point. Each point can be specified
    137128           as any iterable container of
    138129           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    149140
    150141            sage: p = Polyhedron()
    151142            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    152             sage: Polyhedron_base._init_from_Vrepresentation(p, 2, [], [], [])
     143            sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], [])
    153144            Traceback (most recent call last):
    154145            ...
    155146            NotImplementedError: A derived class must implement this method.
    156147        """
    157148        raise NotImplementedError('A derived class must implement this method.')
    158149
    159 
    160     def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, **kwds):
     150    def _init_from_Hrepresentation(self, ieqs, eqns, **kwds):
    161151        """
    162152        Construct polyhedron from H-representation data.
    163153
    164154        INPUT:
    165155
    166         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    167        
    168156        - ``ieqs`` -- list of inequalities. Each line can be specified
    169157          as any iterable container of
    170158          :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
     
    177165
    178166            sage: p = Polyhedron()
    179167            sage: from sage.geometry.polyhedron.base import Polyhedron_base
    180             sage: Polyhedron_base._init_from_Hrepresentation(p, 2, [], [])
     168            sage: Polyhedron_base._init_from_Hrepresentation(p, [], [])
    181169            Traceback (most recent call last):
    182170            ...
    183171            NotImplementedError: A derived class must implement this method.
    184172        """
    185173        raise NotImplementedError('A derived class must implement this method.')
    186174
    187 
    188     def _init_empty_polyhedron(self, ambient_dim):
     175    def _init_empty_polyhedron(self):
    189176        """
    190177        Initializes an empty polyhedron.
    191178
    192         INPUT:
    193 
    194         - ``ambient_dim`` -- integer. The dimension of the ambient space.
    195 
    196179        TESTS::
    197180
    198181            sage: empty = Polyhedron(); empty
    199             The empty polyhedron in QQ^0
     182            The empty polyhedron in ZZ^0
    200183            sage: empty.Vrepresentation()
    201184            ()
    202185            sage: empty.Hrepresentation()
    203186            (An equation -1 == 0,)
    204187            sage: Polyhedron(vertices = [])
    205             The empty polyhedron in QQ^0
    206             sage: Polyhedron()._init_empty_polyhedron(0)
     188            The empty polyhedron in ZZ^0
     189            sage: Polyhedron(vertices = [])._init_empty_polyhedron()
     190            sage: from sage.geometry.polyhedron.parent import Polyhedra
     191            sage: Polyhedra(QQ,7)()
     192            A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex
    207193        """
    208194        self._Vrepresentation = []
    209195        self._Hrepresentation = []
    210         Equation(self, [-1] + [0]*ambient_dim);
     196        self.parent()._make_Equation(self, [-1] + [0]*self.ambient_dim());
    211197        self._Vrepresentation = tuple(self._Vrepresentation)
    212198        self._Hrepresentation = tuple(self._Hrepresentation)
    213199
    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):
     200        V_matrix = matrix(ZZ, 0, 0, 0)
     201        V_matrix.set_immutable()
     202        self.vertex_adjacency_matrix.set_cache(V_matrix)
     203
     204        H_matrix = matrix(ZZ, 1, 1, 0)
     205        H_matrix.set_immutable()
     206        self.facet_adjacency_matrix.set_cache(H_matrix)
     207
     208    def _facet_adjacency_matrix(self):
    222209        """
    223210        Compute the facet adjacency matrix in case it has not been
    224211        computed during initialization.
     
    226213        EXAMPLES::
    227214       
    228215            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
     216            sage: p._facet_adjacency_matrix()
    233217            [0 1 1]
    234218            [1 0 1]
    235219            [1 1 0]
     
    250234            Hrep = face.element.ambient_Hrepresentation()
    251235            if len(Hrep) == 2:
    252236                set_adjacent(Hrep[0], Hrep[1])
    253 
    254         self._H_adjacency_matrix = M
    255 
    256 
    257     def _init_vertex_adjacency_matrix(self):
     237        return M
     238
     239    def _vertex_adjacency_matrix(self):
    258240        """
    259241        Compute the vertex adjacency matrix in case it has not been
    260242        computed during initialization.
     
    262244        EXAMPLES::
    263245       
    264246            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
     247            sage: p._vertex_adjacency_matrix()
    269248            [0 1 1]
    270249            [1 0 1]
    271250            [1 1 0]
     
    293272        for r in self.ray_generator():
    294273            for vrep in self.Vrep_generator():
    295274                set_adjacent(r, vrep)
    296                
    297         self._V_adjacency_matrix = M
    298 
    299 
    300     def __lt__(self, other):
     275        return M
     276
     277    def delete(self):
    301278        """
    302         Test whether ``self`` is a strict sub-polyhedron of ``other``.
     279        Delete this polyhedron.
     280       
     281        This speeds up creation of new polyhedra by reusing
     282        objects. After recycling a polyhedron object, it is not in a
     283        consistent state any more and neither the polyhedron nor its
     284        H/V-representation objects may be used any more.
     285
     286        .. seealso:: :meth:`~sage.geometry.polyhedron.Polyhedra_base.recycle`
     287
     288
     289        EXAMPLES::
     290
     291            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
     292            sage: p.delete()
     293
     294            sage: def loop_polyhedra():
     295            ...       for i in range(0,100):
     296            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     297
     298            sage: timeit('loop_polyhedra()', repeat=25)                   # random output
     299            5 loops, best of 25: 44.2 ms per loop
     300
     301            sage: def loop_polyhedra_with_recycling():
     302            ...       for i in range(0,100):
     303            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
     304            ...           p.delete()
     305
     306            sage: timeit('loop_polyhedra_with_recycling()', repeat=25)    # random output
     307            25 loops, best of 25: 36.3 ms per loop
     308        """
     309        self.parent().recycle(self)
     310        self._Hrepresentation = None
     311        self._Vrepresentation = None
     312
     313    def base_extend(self, base_ring, backend=None):
     314        """
     315        EXAMPLES::
     316           
     317            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ);  P
     318            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray
     319            sage: P.base_extend(QQ)
     320            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
     321        """
     322        new_parent = self.parent().base_extend(base_ring, backend)
     323        return new_parent(self)
     324
     325    def __cmp__(self, other):
     326        """
     327        Compare ``self`` and ``other``.
    303328
    304329        INPUT:
    305 
    306         - ``other`` -- a :class:`Polyhedron`.
     330       
     331        - ``other`` -- anything.
    307332
    308333        OUTPUT:
    309 
    310         Boolean.
     334       
     335        `-1, 0, +1` depending on how ``self`` and ``other``
     336        compare. If ``other`` is a polyhedron, then the comparison
     337        operator "less or equal than" means "is contained in", and
     338        "less than" means "is strictly contained in".
    311339
    312340        EXAMPLES::
    313341
    314342            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
    315343            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
    316             sage: P < Q   # indirect doctest
     344            sage: cmp(P,Q)
     345            1
     346            sage: cmp(Q,P)
     347            -1
     348            sage: cmp(P,P)
     349            0
     350            sage: cmp(P, 'anything')
     351            -1
     352
     353       The polytope ``Q`` is contained in ``P``::
     354           
     355            sage: P > Q
     356            True
     357            sage: P < Q
    317358            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
     359            sage: P == Q
    374360            False
    375361        """
    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 
     362        c = cmp(self.ambient_dim(), other.ambient_dim())
     363        if c != 0: return c
     364        c0 = self._is_subpolyhedron(other)
     365        c1 = other._is_subpolyhedron(self)
     366        if c0 and c1:
     367            return 0
     368        if c0:
     369            return -1
     370        else:
     371            return +1
     372           
     373    @coerce_binop
    458374    def _is_subpolyhedron(self, other):
    459375        """
    460376        Test whether ``self`` is a (not necessarily strict)
     
    477393            sage: Q._is_subpolyhedron(P)
    478394            True
    479395        """
    480         if not is_Polyhedron(other):
    481             raise ValueError('Can only compare Polyhedron objects.')
    482396        return all( other_H.contains(self_V)
    483397                    for other_H, self_V in
    484398                    CartesianProduct(other.Hrep_generator(), self.Vrep_generator()) )
    485        
    486399
    487400    def plot(self, **kwds):
    488401        """
     
    513426        raise NotImplementedError('Plotting of '+str(self.ambient_dim())+
    514427                                  '-dimensional polyhedra not implemented')
    515428
    516 
    517429    show = plot
    518430
    519 
    520431    def _repr_(self):
    521432        """
    522433        Return a description of the polyhedron.
     
    525436
    526437            sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]])
    527438            sage: poly_test._repr_()
    528             'A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices'
     439            'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices'
    529440            sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]])
    530441            sage: grammar_test._repr_()
    531             'A 0-dimensional polyhedron in QQ^6 defined as the convex hull of 1 vertex'
     442            'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex'
    532443        """
    533444        desc = ''
    534445        if self.n_vertices()==0:
     
    564475
    565476        return desc
    566477
    567 
    568478    def cdd_Hrepresentation(self):
    569479        """
    570480        Write the inequalities/equations data of the polyhedron in
     
    592502        try:
    593503            cdd_type = self._cdd_type
    594504        except AttributeError:
    595             ring_to_cdd = { QQ:'rational', RDF:'real' }
    596             cdd_type = ring_to_cdd[self.base_ring()]
     505            if self.base_ring() is ZZ or self.base_ring() is QQ:
     506                cdd_type = 'rational'
     507            elif self.base_ring() is RDF:
     508                cdd_type = 'real'
     509            else:
     510                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    597511        return cdd_Hrepresentation(cdd_type,
    598512                                   list(self.inequality_generator()),
    599513                                   list(self.equation_generator()) )
    600514
    601 
    602515    def cdd_Vrepresentation(self):
    603516        """
    604517        Write the vertices/rays/lines data of the polyhedron in cdd's
     
    626539        try:
    627540            cdd_type = self._cdd_type
    628541        except AttributeError:
    629             ring_to_cdd = { QQ:'rational', RDF:'real' }
    630             cdd_type = ring_to_cdd[self.base_ring()]
     542            if self.base_ring() is ZZ or self.base_ring() is QQ:
     543                cdd_type = 'rational'
     544            elif self.base_ring() is RDF:
     545                cdd_type = 'real'
     546            else:
     547                raise TypeError('The base ring must be ZZ, QQ, or RDF')
    631548        return cdd_Vrepresentation(cdd_type,
    632549                                   list(self.vertex_generator()),
    633550                                   list(self.ray_generator()),
    634551                                   list(self.line_generator()) )
    635 
    636 
     552   
     553    @cached_method
    637554    def n_equations(self):
    638555        """
    639556        Return the number of equations. The representation will
     
    646563            sage: p.n_equations()
    647564            1
    648565        """
    649         try:
    650             return self._n_equations
    651         except AttributeError:
    652             self._n_equations = len(self.equations())
    653             return self._n_equations
    654 
    655 
     566        return len(self.equations())
     567
     568    @cached_method
    656569    def n_inequalities(self):
    657570        """
    658571        Return the number of inequalities. The representation will
     
    664577            sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]])
    665578            sage: p.n_inequalities()
    666579            3
    667         """
    668         try:
    669             return self._n_inequalities
    670         except AttributeError:
    671             self._n_inequalities = 0
    672             for i in self.inequalities(): self._n_inequalities += 1
    673             return self._n_inequalities
    674 
    675 
    676     def n_facets(self):
    677         """
    678         Return the number of facets in the polyhedron.  This is the
    679         same as the n_inequalities function.
    680 
    681         EXAMPLES::
    682580
    683581            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)])
    684582            sage: p.n_facets()
    685583            8
    686584        """
    687         return self.n_inequalities()
    688 
    689 
     585        return len(self.inequalities())
     586
     587    n_facets = n_inequalities
     588
     589    @cached_method
    690590    def n_vertices(self):
    691591        """
    692592        Return the number of vertices. The representation will
     
    698598            sage: p.n_vertices()
    699599            2
    700600        """
    701         try:
    702             return self._n_vertices
    703         except AttributeError:
    704             self._n_vertices = 0
    705             for v in self.vertex_generator(): self._n_vertices += 1
    706             return self._n_vertices
    707 
    708 
     601        return len(self.vertices())
     602
     603    @cached_method
    709604    def n_rays(self):
    710605        """
    711606        Return the number of rays. The representation will
     
    717612            sage: p.n_rays()
    718613            1
    719614        """
    720         try:
    721             return self._n_rays
    722         except AttributeError:
    723             self._n_rays = 0
    724             for r in self.rays(): self._n_rays += 1
    725             return self._n_rays
    726 
    727 
     615        return len(self.rays())
     616
     617    @cached_method
    728618    def n_lines(self):
    729619        """
    730620        Return the number of lines. The representation will
     
    736626            sage: p.n_lines()
    737627            1
    738628        """
    739         try:
    740             return self._n_lines
    741         except AttributeError:
    742             self._n_lines = len(self.lines())
    743             return self._n_lines
    744 
     629        return len(self.lines())
    745630
    746631    def Hrepresentation(self, index=None):
    747632        """
     
    767652            sage: p.Hrepresentation(0) == p.Hrepresentation() [0]
    768653            True
    769654        """
    770         if index==None:
     655        if index is None:
    771656            return self._Hrepresentation
    772657        else:
    773658            return self._Hrepresentation[index]
    774            
    775659
    776660    def Hrep_generator(self):
    777661        """
     
    787671        for H in self.Hrepresentation():
    788672            yield H
    789673
    790 
     674    @cached_method
    791675    def n_Hrepresentation(self):
    792676        """
    793677        Return the number of objects that make up the
     
    807691        """
    808692        return len(self.Hrepresentation())
    809693
    810 
    811694    def Vrepresentation(self, index=None):
    812695        """
    813696        Return the objects of the V-representation. Each entry is
     
    832715            sage: p.Vrepresentation(0) == p.Vrepresentation() [0]
    833716            True
    834717        """
    835         if index==None:
     718        if index is None:
    836719            return self._Vrepresentation
    837720        else:
    838721            return self._Vrepresentation[index]
    839722
    840 
     723    @cached_method
    841724    def n_Vrepresentation(self):
    842725        """
    843726        Return the number of objects that make up the
     
    857740        """
    858741        return len(self.Vrepresentation())
    859742
    860 
    861743    def Vrep_generator(self):
    862744        """
    863745        Returns an iterator over the objects of the V-representation
     
    875757        for V in self.Vrepresentation():
    876758            yield V
    877759
    878 
    879760    def facial_adjacencies(self):
    880         """
     761        r"""
    881762        Return the list of face indices (i.e. indices of
    882763        H-representation objects) and the indices of faces adjacent to
    883764        them.
     
    892773
    893774            sage: p = polytopes.permutahedron(4)
    894775            sage: p.facial_adjacencies()[0:3]
     776            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is deprecated.
     777            Use self.Hrepresentation(i).neighbors() instead.
    895778            [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]]
    896779            sage: f0 = p.Hrepresentation(0)
    897780            sage: f0.index() == 0
     
    900783            sage: p.facial_adjacencies()[0] == f0_adjacencies
    901784            True
    902785        """
     786        from sage.misc.misc import deprecation
     787        deprecation('This method is deprecated. Use self.Hrepresentation(i).neighbors() instead.',
     788                    'Sage Version 4.7.2')
    903789        try:
    904790            return self._facial_adjacencies
    905791        except AttributeError:
     
    909795                  ] for h in self.Hrepresentation() ]
    910796            return self._facial_adjacencies
    911797
    912 
    913798    def facial_incidences(self):
    914799        """
    915800        Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`.
     
    931816
    932817            sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]])
    933818            sage: p.facial_incidences()
     819            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     820            deprecated. Use self.Hrepresentation(i).incident() instead.
    934821            [[0, [0, 1, 3, 4]],
    935822             [1, [0, 1, 2]],
    936823             [2, [0, 2, 3]],
     
    955842            sage: p.incidence_matrix().column(4)
    956843            (0, 1, 1, 0, 1)
    957844        """
     845        from sage.misc.misc import deprecation
     846        deprecation('This method is deprecated. Use self.Hrepresentation(i).incident() instead.',
     847                    'Sage Version 4.7.2')
    958848        try:
    959849            return self._facial_incidences
    960850        except AttributeError:
     
    964854                  ] for h in self.Hrepresentation() ]
    965855            return self._facial_incidences
    966856
    967 
    968857    def vertex_adjacencies(self):
    969858        """
    970859        Return a list of vertex indices and their adjacent vertices.
     
    983872
    984873            sage: permuta3 = Polyhedron(vertices = permutations([1,2,3,4]))
    985874            sage: permuta3.vertex_adjacencies()[0:3]
     875            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     876            deprecated. Use self.Vrepresentation(i).neighbors() instead.
    986877            [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]]
    987878            sage: v0 = permuta3.Vrepresentation(0)
    988879            sage: v0.index() == 0
     
    993884            sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies
    994885            True
    995886        """
     887        from sage.misc.misc import deprecation
     888        deprecation('This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.',
     889                    'Sage Version 4.7.2')
    996890        try:
    997891            return self._vertex_adjacencies
    998892        except AttributeError:
     
    1002896                  ] for v in self.Vrepresentation() ]
    1003897            return self._vertex_adjacencies
    1004898
    1005 
    1006899    def vertex_incidences(self):
    1007900        """
    1008901        Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`.
     
    1017910
    1018911            sage: p = polytopes.n_simplex(3)
    1019912            sage: p.vertex_incidences()
     913            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     914            deprecated. Use self.Vrepresentation(i).incident() instead.
    1020915            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    1021916            sage: v0 = p.Vrepresentation(0)
    1022917            sage: v0.index() == 0
     
    1024919            sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ]
    1025920            True
    1026921        """
     922        from sage.misc.misc import deprecation
     923        deprecation('This method is deprecated. Use self.Vrepresentation(i).incident() instead.',
     924                    'Sage Version 4.7.2')
    1027925        try:
    1028926            return self._vertex_incidences
    1029927        except AttributeError:
     
    1033931                  ] for v in self.Vrepresentation() ]
    1034932            return self._vertex_incidences
    1035933
    1036 
    1037934    def inequality_generator(self):
    1038935        """
    1039936        Return  a generator for the defining inequalities of the
     
    1061958            if H.is_inequality():
    1062959                yield H
    1063960
    1064 
     961    @cached_method
    1065962    def inequalities(self):
    1066963        """
     964        Return all inequalities.
     965
     966        OUTPUT:
     967
     968        A tuple of inequalities.
     969
     970        EXAMPLES::
     971
     972            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
     973            sage: p.inequalities()[0:3]
     974            (An inequality (1, 0, 0) x + 0 >= 0,
     975             An inequality (0, 1, 0) x + 0 >= 0,
     976             An inequality (0, 0, 1) x + 0 >= 0)
     977            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
     978            sage: ieqs = p3.inequalities()
     979            sage: ieqs[0]
     980            An inequality (0, 1, 1, 1) x - 6 >= 0
     981            sage: list(_)
     982            [-6, 0, 1, 1, 1]
     983        """
     984        return tuple(self.inequality_generator())
     985   
     986    def inequalities_list(self):
     987        """
    1067988        Return a list of inequalities as coefficient lists.
    1068989
    1069990        .. NOTE::
    1070991       
    1071             It is recommended to use :meth:`inequality_generator`
    1072             instead to iterate over the list of :class:`Inequality`
    1073             objects.
     992            It is recommended to use :meth:`inequalities` or
     993            :meth:`inequality_generator` instead to iterate over the
     994            list of :class:`Inequality` objects.
    1074995
    1075996        EXAMPLES::
    1076997
    1077998            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
    1078             sage: p.inequalities()[0:3]
     999            sage: p.inequalities_list()[0:3]
    10791000            [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    10801001            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    1081             sage: ieqs = p3.inequalities()
     1002            sage: ieqs = p3.inequalities_list()
    10821003            sage: ieqs[0]
    10831004            [-6, 0, 1, 1, 1]
    10841005            sage: ieqs[-1]
     
    10861007            sage: ieqs == [list(x) for x in p3.inequality_generator()]
    10871008            True
    10881009        """
    1089         try:
    1090             return self._inequalities
    1091         except AttributeError:
    1092             self._ieqs = [list(x) for x in self.inequality_generator()]
    1093             return self._ieqs
    1094 
     1010        return [list(x) for x in self.inequality_generator()]
    10951011
    10961012    def ieqs(self):
    10971013        """
     
    11011017         
    11021018            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
    11031019            sage: p3.ieqs() == p3.inequalities()
     1020            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1021            deprecated. Use inequalities() instead.
    11041022            True
    11051023        """
     1024        from sage.misc.misc import deprecation
     1025        deprecation('This method is deprecated. Use inequalities() instead.',
     1026                    'Sage Version 4.7.2')
    11061027        return self.inequalities()
    11071028
    1108 
    11091029    def equation_generator(self):
    11101030        """
    11111031        Return a generator for the linear equations satisfied by the
     
    11221042            if H.is_equation():
    11231043                yield H
    11241044
    1125 
     1045    @cached_method
    11261046    def equations(self):
    11271047        """
     1048        Return all linear constraints of the polyhedron.
     1049
     1050        OUTPUT:
     1051
     1052        A tuple of equations.
     1053
     1054        EXAMPLES::
     1055
     1056            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
     1057            sage: test_p.equations()
     1058            (An equation (1, 1, 1, 1) x - 10 == 0,)
     1059        """
     1060        return tuple(self.equation_generator())
     1061
     1062    def equations_list(self):
     1063        """
    11281064        Return the linear constraints of the polyhedron. As with
    11291065        inequalities, each constraint is given as [b -a1 -a2 ... an]
    11301066        where for variables x1, x2,..., xn, the polyhedron satisfies
     
    11321068
    11331069        .. NOTE::
    11341070       
    1135             It is recommended to use :meth:`equation_generator()` instead
    1136             to iterate over the list of :class:`Equation` objects.
     1071            It is recommended to use :meth:`equations` or
     1072            :meth:`equation_generator()` instead to iterate over the
     1073            list of
     1074            :class:`~sage.geometry.polyhedron.representation.Equation`
     1075            objects.
    11371076
    11381077        EXAMPLES::
    11391078
    11401079            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    1141             sage: test_p.equations()
     1080            sage: test_p.equations_list()
    11421081            [[-10, 1, 1, 1, 1]]
    11431082        """
    1144         try:
    1145             return self._equations
    1146         except:
    1147             self._equations = [list(eq) for eq in self.equation_generator()]
    1148             return self._equations
    1149 
     1083        return [list(eq) for eq in self.equation_generator()]
    11501084
    11511085    def linearities(self):
    11521086        """
     
    11601094
    11611095            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
    11621096            sage: test_p.linearities()
     1097            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
     1098            deprecated. Use equations_list() instead.
    11631099            [[-10, 1, 1, 1, 1]]
    1164             sage: test_p.linearities() == test_p.equations()
     1100            sage: test_p.linearities() == test_p.equations_list()
    11651101            True
    11661102        """
    1167         return self.equations()
    1168 
    1169 
    1170     def vertices(self):
     1103        from sage.misc.misc import deprecation
     1104        deprecation('This method is deprecated. Use equations_list() instead.',
     1105                    'Sage Version 4.7.2')
     1106        return self.equations_list()
     1107
     1108    def vertices_list(self):
    11711109        """
    11721110        Return a list of vertices of the polyhedron.
    11731111
     
    11791117        EXAMPLES::
    11801118
    11811119            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
    1182             sage: triangle.vertices()
     1120            sage: triangle.vertices_list()
    11831121            [[0, 1], [1, 0], [1, 1]]
    11841122            sage: a_simplex = Polyhedron(ieqs = [
    11851123            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
    11861124            ...        ], eqns = [[1,-1,-1,-1,-1]])
    1187             sage: a_simplex.vertices()
     1125            sage: a_simplex.vertices_list()
    11881126            [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
    1189             sage: a_simplex.vertices() == [list(v) for v in a_simplex.vertex_generator()]
     1127            sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()]
    11901128            True
    11911129        """
    1192         try:
    1193             return self._vertices
    1194         except:
    1195             self._vertices = [list(x) for x in self.vertex_generator()]
    1196             return self._vertices
    1197 
     1130        return [list(x) for x in self.vertex_generator()]
    11981131       
    11991132    def vertex_generator(self):
    12001133        """
     
    12251158        for V in self.Vrepresentation():
    12261159            if V.is_vertex():
    12271160                yield V
     1161
     1162    @cached_method
     1163    def vertices(self):
     1164        """
     1165        Return all vertices of the polyhedron.
     1166
     1167        OUTPUT:
     1168
     1169        A tuple of vertices.
     1170
     1171        EXAMPLES::
     1172
     1173            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1174            sage: triangle.vertices()
     1175            (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1))
     1176            sage: a_simplex = Polyhedron(ieqs = [
     1177            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
     1178            ...        ], eqns = [[1,-1,-1,-1,-1]])
     1179            sage: a_simplex.vertices()
     1180            (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0),
     1181             A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1))
     1182        """
     1183        return tuple(self.vertex_generator())       
     1184
     1185    @cached_method
     1186    def vertices_matrix(self, base_ring=None):
     1187        """
     1188        Return the coordinates of the vertices as the columns of a matrix.
     1189
     1190        INPUT:
    12281191       
    1229 
     1192        - ``base_ring`` -- A ring or ``None`` (default). The base ring
     1193          of the returned matrix. If not specified, the base ring of
     1194          the polyhedron is used.
     1195
     1196        OUTPUT:
     1197
     1198        A matrix over ``base_ring`` whose columns are the coordinates
     1199        of the vertices. A ``TypeError`` is raised if the coordinates
     1200        cannot be converted to ``base_ring``.
     1201
     1202        EXAMPLES::
     1203
     1204            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
     1205            sage: triangle.vertices_matrix()
     1206            [0 1 1]
     1207            [1 0 1]
     1208            sage: (triangle/2).vertices_matrix()
     1209            [  0 1/2 1/2]
     1210            [1/2   0 1/2]
     1211            sage: (triangle/2).vertices_matrix(ZZ)
     1212            Traceback (most recent call last):
     1213            ...
     1214            TypeError: no conversion of this rational to integer
     1215        """
     1216        if base_ring is None:
     1217            base_ring = self.base_ring()
     1218        m = matrix(base_ring, self.ambient_dim(), self.n_vertices())
     1219        for i,v in enumerate(self.vertices()):
     1220            for j in range(0,self.ambient_dim()):
     1221                m[j,i] = v[j]
     1222        return m
     1223       
    12301224    def ray_generator(self):
    12311225        """
    12321226        Return a generator for the rays of the polyhedron.
     
    12421236            if V.is_ray():
    12431237                yield V
    12441238
    1245 
     1239    @cached_method
    12461240    def rays(self):
    12471241        """
    12481242        Return a list of rays as coefficient lists.
    12491243
     1244        OUTPUT:
     1245
     1246        A tuple of rays.
     1247
     1248        EXAMPLES::
     1249
     1250            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
     1251            sage: p.rays()
     1252            (A ray in the direction (1, 0, 0),
     1253             A ray in the direction (0, 1, 0),
     1254             A ray in the direction (0, 0, 1))
     1255        """
     1256        return tuple(self.ray_generator())
     1257
     1258    def rays_list(self):
     1259        """
     1260        Return a list of rays as coefficient lists.
     1261
    12501262        .. NOTE::
    12511263       
    1252             It is recommended to use :meth:`ray_generator` instead to
    1253             iterate over the list of :class:`Ray` objects.
     1264            It is recommended to use :meth:`rays` or
     1265            :meth:`ray_generator` instead to iterate over the list of
     1266            :class:`Ray` objects.
    12541267
    12551268        OUTPUT:
    12561269
     
    12591272        EXAMPLES::
    12601273
    12611274            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
    1262             sage: p.rays()
     1275            sage: p.rays_list()
    12631276            [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    1264             sage: p.rays() == [list(r) for r in p.ray_generator()]
     1277            sage: p.rays_list() == [list(r) for r in p.ray_generator()]
    12651278            True
    12661279        """
    1267         try:
    1268             return self._rays
    1269         except:
    1270             self._rays = [list(x) for x in self.ray_generator()]
    1271             return self._rays
    1272 
     1280        return [list(x) for x in self.ray_generator()]
    12731281
    12741282    def line_generator(self):
    12751283        """
     
    12851293            if V.is_line():
    12861294                yield V
    12871295
    1288 
     1296    @cached_method
    12891297    def lines(self):
    12901298        """
     1299        Return all lines of the polyhedron.
     1300       
     1301        OUTPUT:
     1302
     1303        A tuple of lines.
     1304
     1305        EXAMPLES::
     1306
     1307            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
     1308            sage: p.lines()
     1309            (A line in the direction (1, 0),)
     1310        """
     1311        return tuple(self.line_generator())
     1312
     1313    def lines_list(self):
     1314        """
    12911315        Return a list of lines of the polyhedron.  The line data is given
    12921316        as a list of coordinates rather than as a Hrepresentation object.
    12931317
     
    12991323        EXAMPLES::
    13001324
    13011325            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
    1302             sage: p.lines()
     1326            sage: p.lines_list()
    13031327            [[1, 0]]
    1304             sage: p.lines() == [list(x) for x in p.line_generator()]
     1328            sage: p.lines_list() == [list(x) for x in p.line_generator()]
    13051329            True
    13061330        """
    1307         try:
    1308             return self._lines
    1309         except:
    1310             self._lines = [list(x) for x in self.line_generator()]
    1311             return self._lines   
    1312 
     1331        return [list(x) for x in self.line_generator()]
    13131332               
    13141333    def bounded_edges(self):
    13151334        """
     
    13361355                if self.vertex_adjacency_matrix()[i,j] == 0: continue
    13371356                yield (obj[i], obj[j])
    13381357
    1339 
    1340     @cached_method
    1341     def ambient_space(self):
     1358    def Vrepresentation_space(self):
    13421359        r"""
    13431360        Return the ambient vector space.
    13441361       
     
    13491366        EXAMPLES::
    13501367
    13511368            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1352             sage: poly_test.ambient_space()
    1353             Vector space of dimension 4 over Rational Field
     1369            sage: poly_test.Vrepresentation_space()
     1370            Ambient free module of rank 4 over the principal ideal domain Integer Ring
     1371            sage: poly_test.ambient_space() is poly_test.Vrepresentation_space()
     1372            True
    13541373        """
    1355         from sage.modules.free_module import FreeModule
    1356         return FreeModule(self.base_ring(), self.ambient_dim())
    1357 
    1358     Vrepresentation_space = ambient_space
    1359 
    1360     @cached_method
     1374        return self.parent().Vrepresentation_space()
     1375
     1376    ambient_space = Vrepresentation_space
     1377
    13611378    def Hrepresentation_space(self):
    13621379        r"""
    13631380        Return the linear space containing the H-representation vectors.
     
    13691386        EXAMPLES::
    13701387       
    13711388            sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
    1372             sage: poly_test.ambient_space()
    1373             Vector space of dimension 4 over Rational Field
     1389            sage: poly_test.Hrepresentation_space()
     1390            Ambient free module of rank 5 over the principal ideal domain Integer Ring
    13741391        """
    1375         from sage.modules.free_module import VectorSpace
    1376         return VectorSpace(self.base_ring(), self.ambient_dim()+1)
    1377 
     1392        return self.parent().Hrepresentation_space()
    13781393
    13791394    def ambient_dim(self):
    13801395        r"""
     
    13861401            sage: poly_test.ambient_dim()
    13871402            4
    13881403        """
    1389         return self._ambient_dim
    1390 
    1391            
     1404        return self.parent().ambient_dim()
     1405
    13921406    def dim(self):
    13931407        """
    13941408        Return the dimension of the polyhedron.
     
    14031417       """
    14041418        return self.ambient_dim() - self.n_equations()
    14051419
    1406 
    1407     def adjacency_matrix(self):
    1408         """
    1409         This is an alias for :meth:`vertex_adjacency_matrix`
    1410 
    1411         EXAMPLES::
    1412 
    1413             sage: polytopes.n_cube(3).adjacency_matrix()
    1414             [0 1 1 0 1 0 0 0]
    1415             [1 0 0 1 0 1 0 0]
    1416             [1 0 0 1 0 0 1 0]
    1417             [0 1 1 0 0 0 0 1]
    1418             [1 0 0 0 0 1 1 0]
    1419             [0 1 0 0 1 0 0 1]
    1420             [0 0 1 0 1 0 0 1]
    1421             [0 0 0 1 0 1 1 0]
    1422         """
    1423         return self.vertex_adjacency_matrix()
    1424 
    1425 
     1420    @cached_method
    14261421    def vertex_adjacency_matrix(self):
    14271422        """
    14281423        Return the binary matrix of vertex adjacencies.
     
    14361431            [1 1 1 0 1]
    14371432            [1 1 1 1 0]
    14381433        """
    1439         if '_V_adjacency_matrix' not in self.__dict__:
    1440             self._init_vertex_adjacency_matrix()
    1441         return self._V_adjacency_matrix;
    1442 
    1443 
     1434        return self._vertex_adjacency_matrix()
     1435
     1436    adjacency_matrix = vertex_adjacency_matrix
     1437
     1438    @cached_method
    14441439    def facet_adjacency_matrix(self):
    14451440        """
    14461441        Return the adjacency matrix for the facets and hyperplanes.
     
    14541449            [1 1 1 0 1]
    14551450            [1 1 1 1 0]
    14561451        """
    1457         if '_H_adjacency_matrix' not in self.__dict__:
    1458             self._init_facet_adjacency_matrix()
    1459         return self._H_adjacency_matrix;
    1460 
    1461 
     1452        return self._facet_adjacency_matrix()
     1453
     1454    @cached_method
    14621455    def incidence_matrix(self):
    14631456        """
    14641457        Return the incidence matrix.
     
    15031496            sage: p.incidence_matrix() [2,0]   # note: not symmetric
    15041497            0
    15051498        """
    1506         try:
    1507             return self._incidence_matrix
    1508         except AttributeError:
    1509             self._incidence_matrix = matrix(ZZ, len(self.Vrepresentation()),
    1510                                                 len(self.Hrepresentation()), 0)
    1511             for V in self.Vrep_generator():
    1512                 for H in self.Hrep_generator():
    1513                     if self._is_zero(H*V):
    1514                         self._incidence_matrix[V.index(),H.index()] = 1
    1515 
    1516             return self._incidence_matrix
    1517 
     1499        incidence_matrix = matrix(ZZ, self.n_Vrepresentation(),
     1500                                  self.n_Hrepresentation(), 0)
     1501        for V in self.Vrep_generator():
     1502            for H in self.Hrep_generator():
     1503                if self._is_zero(H*V):
     1504                    incidence_matrix[V.index(),H.index()] = 1
     1505        return incidence_matrix
    15181506
    15191507    def base_ring(self):
    15201508        """
     
    15281516        EXAMPLES::
    15291517
    15301518            sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]])
    1531             sage: triangle.base_ring() == QQ
     1519            sage: triangle.base_ring() == ZZ
    15321520            True
    15331521        """
    1534         return self._base_ring
     1522        return self.parent().base_ring()
    15351523
    15361524    field = base_ring
    15371525
    15381526
    1539     def coerce_field(self, other):
    1540         """
    1541         Return the common field for both ``self`` and ``other``.
    1542 
    1543         INPUT:
    1544 
    1545         - ``other`` -- must be either:
    1546        
    1547             * another ``Polyhedron`` object
    1548        
    1549             * `\QQ` or `RDF`
    1550        
    1551             * a constant that can be coerced to `\QQ` or `RDF`
    1552 
    1553         OUTPUT:
    1554 
    1555         Either `\QQ` or `RDF`. Raises ``TypeError`` if ``other`` is not a
    1556         suitable input.
    1557 
    1558         .. NOTE::
    1559        
    1560             "Real" numbers in sage are not necessarily elements of
    1561             `RDF`. For example, the literal `1.0` is not.
    1562 
    1563         EXAMPLES::
    1564 
    1565             sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ)
    1566             sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF)
    1567             sage: triangle_QQ.coerce_field(QQ)
    1568             Rational Field
    1569             sage: triangle_QQ.coerce_field(triangle_RDF)
    1570             Real Double Field
    1571             sage: triangle_RDF.coerce_field(triangle_QQ)
    1572             Real Double Field
    1573             sage: triangle_QQ.coerce_field(RDF)
    1574             Real Double Field
    1575             sage: triangle_QQ.coerce_field(ZZ)
    1576             Rational Field
    1577             sage: triangle_QQ.coerce_field(1/2)
    1578             Rational Field
    1579             sage: triangle_QQ.coerce_field(0.5)
    1580             Real Double Field
    1581         """
    1582         try:
    1583             # other is a Polyhedron object?
    1584             other_field = other.field()
    1585         except AttributeError:
    1586 
    1587             try:
    1588                 # other is a constant?
    1589                 other_parent = other.parent()
    1590             except AttributeError:
    1591                 other_parent = other
    1592 
    1593             # other is a field?
    1594             if QQ.coerce_map_from(other_parent) != None:
    1595                 other_field = QQ
    1596             elif RDF.coerce_map_from(other_parent) != None:
    1597                 other_field = RDF
    1598             else:
    1599                 raise TypeError("cannot determine field from %s!" % other)
    1600 
    1601         assert other_field==QQ or other_field==RDF
    1602            
    1603         if self.field()==RDF or other_field==RDF:
    1604             return RDF
    1605         else:
    1606             return QQ
    1607 
    1608 
    16091527    @cached_method
    16101528    def center(self):
    16111529        """
     
    16691587        """
    16701588        return sqrt(self.radius_square())
    16711589
    1672 
    16731590    def is_compact(self):
    16741591        """
    16751592        Test for boundedness of the polytope.
     
    16851602        """
    16861603        return self.n_rays()==0 and self.n_lines()==0
    16871604
    1688 
    16891605    def is_simple(self):
    16901606        """
    16911607        Test for simplicity of a polytope.
     
    17091625            adj = [a for a in v.neighbors()]
    17101626            if len(adj) != self.dim():
    17111627                return False
    1712 
    17131628        return True
    17141629
     1630    @cached_method
    17151631    def gale_transform(self):
    17161632        """
    17171633        Return the Gale transform of a polytope as described in the
     
    17391655        if not self.is_compact(): raise ValueError('Not a polytope.')
    17401656
    17411657        A = matrix(self.n_vertices(),
    1742                    [ [1]+list(x) for x in self.vertex_generator()])
     1658                   [ [1]+x for x in self.vertex_generator()])
    17431659        A = A.transpose()
    17441660        A_ker = A.right_kernel()
    17451661        return A_ker.basis_matrix().transpose().rows()
     
    18091725            [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1),
    18101726             A vertex at (-1, 1, -1), A vertex at (1, 1, 1)]
    18111727            sage: Polyhedron(simplex_vertices)
    1812             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
     1728            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
    18131729        """
    18141730        if not self.is_compact():
    18151731            raise NotImplementedError('I can only triangulate compact polytopes.')
     
    18401756            ...             ).triangulated_facial_incidences()
    18411757            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18421758            This method is deprecated. Use triangulate() instead.
     1759            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1760            This method is deprecated. Use self.Hrepresentation(i).incident() instead.
    18431761            [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
    18441762                             
    18451763        Otherwise some faces get split up to triangles::
     
    18481766            ...       [1,1,0],[0,0,1]]).triangulated_facial_incidences()
    18491767            doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
    18501768            This method is deprecated. Use triangulate() instead.
     1769            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
     1770            This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.
    18511771            [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]],
    18521772             [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]]
    18531773        """
     
    19021822        self._triangulated_facial_incidences = t_fac_incs
    19031823        return t_fac_incs
    19041824
    1905 
    19061825    def simplicial_complex(self):
    19071826        """
    19081827        Return a simplicial complex from a triangulation of the polytope.
     
    19331852        return SimplicialComplex(vertex_set = self.n_vertices(),
    19341853                                 maximal_faces = [x[1] for x in self.triangulated_facial_incidences()])
    19351854
    1936     def __add__(self, other):
     1855    @coerce_binop
     1856    def Minkowski_sum(self, other):
    19371857        """
     1858        Return the Minkowski sum.
     1859
     1860        INPUT:
     1861
     1862        - ``other`` -- a :class:`Polyhedron_base`.
     1863
     1864        OUTPUT:
     1865       
    19381866        The Minkowski sum of ``self`` and ``other``.
    1939 
    1940         INPUT:
    1941 
    1942         - ``other`` -- a :class:`Polyhedron`.
    1943 
     1867       
    19441868        EXAMPLES::
    19451869
    19461870            sage: four_cube = polytopes.n_cube(4)
    19471871            sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
    1948             sage: unholy_union = four_cube + four_simplex
    1949             sage: unholy_union.dim()
    1950             4
    1951             sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]])
    1952             sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]])
    1953             sage: poly_spam_and_eggs = poly_spam + poly_spam + poly_eggs
    1954             sage: poly_spam_and_eggs.n_vertices()
    1955             12
     1872            sage: four_cube + four_simplex
     1873            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 36 vertices
     1874            sage: four_cube.Minkowski_sum(four_simplex) == four_cube + four_simplex
     1875            True
     1876
     1877            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)
     1878            sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ)
     1879            sage: poly_spam + poly_spam + poly_eggs
     1880            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 12 vertices
    19561881        """
    1957         if is_Polyhedron(other):
    1958             new_vertices = []
    1959             for v1 in self.vertex_generator():
    1960                 for v2 in other.vertex_generator():
    1961                     new_vertices.append(list(v1() + v2()))
     1882        new_vertices = []
     1883        for v1 in self.vertex_generator():
     1884            for v2 in other.vertex_generator():
     1885                new_vertices.append(list(v1() + v2()))
     1886        if new_vertices != []:
    19621887            new_rays = self.rays() + other.rays()
    19631888            new_lines = self.lines() + other.lines()
    1964             other_field = other.field()
    1965 
    1966         else:  # assume other is a vector and try to add vertices
    1967             displacement = vector(other)
    1968             new_vertices = [list(x() + displacement) for x in self.vertex_generator()]
    1969             new_rays = self.rays()
    1970             new_lines = self.lines()
    1971             other_field = displacement.base_ring()
    1972 
     1889            return self.parent().element_class(self.parent(), [new_vertices, new_rays, new_lines], None)
     1890        else:
     1891            return self.parent().element_class(self.parent(), None, None)
     1892
     1893    _add_ = Minkowski_sum
     1894
     1895    def translation(self, displacement):
     1896        """
     1897        Return the translated polyhedron.
     1898
     1899        INPUT:
     1900
     1901        - ``displacement`` -- a displacement vector or a list/tuple of
     1902          coordinates that determines a displacement vector.
     1903
     1904        OUTPUT:
     1905
     1906        The translated polyhedron.
     1907
     1908        EXAMPLES::
     1909       
     1910            sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ)
     1911            sage: P.translation([2,1])
     1912            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
     1913            sage: P.translation( vector(QQ,[2,1]) )
     1914            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     1915        """
     1916        displacement = vector(displacement)
     1917        new_vertices = [x.vector()+displacement for x in self.vertex_generator()]
     1918        new_rays = self.rays()
     1919        new_lines = self.lines()
     1920        new_ring = self.parent()._coerce_base_ring(displacement.base_ring())
     1921        return Polyhedron(vertices=new_vertices, rays=new_rays, lines=new_lines, base_ring=new_ring)
     1922
     1923    @coerce_binop
     1924    def product(self, other):
     1925        """
     1926        Return the cartesian product.
     1927
     1928        INPUT:
     1929       
     1930        - ``other`` -- a :class:`Polyhedron_base`.
     1931
     1932        OUTPUT:
     1933
     1934        The cartesian product of ``self`` and ``other`` with a
     1935        suitable base ring to encompass the two.
     1936
     1937        EXAMPLES::
     1938
     1939            sage: P1 = Polyhedron([[0],[1]], base_ring=ZZ)
     1940            sage: P2 = Polyhedron([[0],[1]], base_ring=QQ)
     1941            sage: P1.product(P2)
     1942            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1943
     1944        The cartesian product is the product in the semiring of polyhedra::
     1945
     1946            sage: P1 * P1
     1947            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     1948            sage: P1 * P2
     1949            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1950            sage: P2 * P2
     1951            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     1952            sage: 2 * P1
     1953            A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices
     1954            sage: P1 * 2.0
     1955            A 1-dimensional polyhedron in RDF^1 defined as the convex hull of 2 vertices
     1956        """
     1957        new_vertices = [ list(x)+list(y)
     1958                         for x in self.vertex_generator() for y in other.vertex_generator()]
     1959        new_rays = []
     1960        new_rays.extend( [ r+[0]*other.ambient_dim()
     1961                           for r in self.ray_generator() ] )
     1962        new_rays.extend( [ [0]*self.ambient_dim()+r
     1963                           for r in other.ray_generator() ] )
     1964        new_lines = []
     1965        new_lines.extend( [ l+[0]*other.ambient_dim()
     1966                            for l in self.line_generator() ] )
     1967        new_lines.extend( [ [0]*self.ambient_dim()+l
     1968                            for l in other.line_generator() ] )
    19731969        return Polyhedron(vertices=new_vertices,
    19741970                          rays=new_rays, lines=new_lines,
    1975                           base_ring=self.coerce_field(other_field))
    1976            
    1977 
    1978     def __mul__(self, other):
     1971                          base_ring=self.parent()._coerce_base_ring(other))
     1972
     1973    _mul_ = product
     1974   
     1975    def dilation(self, scalar):
    19791976        """
    1980         Multiplication by ``other``.
     1977        Return the dilated (uniformly stretched) polyhedron.
    19811978
    19821979        INPUT:
    19831980
    1984         - ``other`` -- A scalar, not necessarily in :meth:`field`, or
    1985           a :class:`Polyhedron`.
     1981        - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring`,
     1982          or a :class:`Polyhedron`.
    19861983
    19871984        OUTPUT:
    19881985
     
    19951992             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
    19961993             sage: p.vertex_generator().next()
    19971994             A vertex at (2, 4, 8)
    1998              sage: p2 = p*2
     1995             sage: p2 = p.dilation(2)
    19991996             sage: p2.vertex_generator().next()
    20001997             A vertex at (4, 8, 16)
     1998             sage: p.dilation(2) == p * 2
     1999             True
    20012000        """
    2002         if is_Polyhedron(other):
    2003             new_vertices = [ list(x)+list(y)
    2004                              for x in self.vertex_generator() for y in other.vertex_generator()]
    2005             new_rays = []
    2006             new_rays.extend( [ list(r)+[0]*other.ambient_dim()
    2007                                for r in self.ray_generator() ] )
    2008             new_rays.extend( [ [0]*self.ambient_dim()+list(r)
    2009                                for r in other.ray_generator() ] )
    2010             new_lines = []
    2011             new_lines.extend( [ list(l)+[0]*other.ambient_dim()
    2012                                 for l in self.line_generator() ] )
    2013             new_lines.extend( [ [0]*self.ambient_dim()+list(l)
    2014                                for l in other.line_generator() ] )
    2015         else:
    2016             new_vertices = [ list(other*v()) for v in self.vertex_generator()]
    2017             new_rays =  self.rays()
    2018             new_lines = self.lines()
    2019 
     2001        new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator()]
     2002        new_rays =  self.rays()
     2003        new_lines = self.lines()
    20202004        return Polyhedron(vertices=new_vertices,
    20212005                          rays=new_rays, lines=new_lines,
    2022                           base_ring=self.coerce_field(other))
    2023 
    2024 
    2025     def __rmul__(self,other):
     2006                          base_ring=self.parent()._coerce_base_ring(scalar.parent()))
     2007
     2008    def _acted_upon_(self, actor, self_on_left):
    20262009        """
    2027         Right multiplication.
    2028 
    2029         See :meth:`__mul__` for details.
     2010        Implement the multiplicative action by scalars or other polyhedra.
     2011
     2012        INPUT:
     2013
     2014        - ``actor`` -- A scalar, not necessarily in :meth:`base_ring`,
     2015          or a :class:`Polyhedron`.
     2016
     2017        OUTPUT:
     2018
     2019        Multiplication by another polyhedron returns the product
     2020        polytope. Multiplication by a scalar returns the polytope
     2021        dilated by that scalar, possibly coerced to the bigger field.
    20302022
    20312023        EXAMPLES::
    20322024
     2025             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
     2026             sage: p._acted_upon_(2, True) == p.dilation(2)
     2027             True
     2028             sage: p*2 == p.dilation(2)
     2029             True
     2030             sage: p*p == p.product(p)
     2031             True
     2032             sage: p + vector(ZZ,[1,2,3]) == p.translation([1,2,3])
     2033             True
     2034        """
     2035        if is_Polyhedron(actor):
     2036            return self.product(actor)
     2037        if is_Vector(actor):
     2038            return self.translation(actor)
     2039        else:
     2040            return self.dilation(actor)
     2041
     2042    def __div__(self, scalar):
     2043        """
     2044        Divide by a scalar factor.
     2045
     2046        See :meth:`dilation` for details.
     2047
     2048        EXAMPLES::
     2049
    20332050            sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,4)])
    2034             sage: p2 = 3*p + p
    2035             sage: p2.vertex_generator().next()
    2036             A vertex at (8, 16, 32)
     2051            sage: (p/5).Vrepresentation()
     2052            (A vertex at (2/5, 4/5, 8/5), A vertex at (3/5, 9/5, 27/5))
    20372053        """
    2038         return self.__mul__(other)
    2039 
    2040 
    2041     def union(self, other):
    2042         """
    2043         Deprecated.  Use ``self.convex_hull(other)`` instead.
    2044        
    2045         EXAMPLES::
    2046        
    2047             sage: Polyhedron(vertices=[[0]]).union( Polyhedron(vertices=[[1]]) )
    2048             doctest:...: DeprecationWarning: (Since Sage Version 4.4.4)
    2049             The function union is replaced by convex_hull.
    2050             A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices
    2051         """
    2052         from sage.misc.misc import deprecation
    2053         deprecation('The function union is replaced by convex_hull.', 'Sage Version 4.4.4')
    2054         return self.convex_hull(other)
    2055 
    2056 
     2054        return self.dilation(1/scalar)
     2055
     2056    @coerce_binop
    20572057    def convex_hull(self, other):
    20582058        """
    20592059        Return the convex hull of the set-theoretic union of the two
     
    20802080        hull_vertices = self.vertices() + other.vertices()
    20812081        hull_rays = self.rays() + other.rays()
    20822082        hull_lines = self.lines() + other.lines()
    2083         hull_field = self.coerce_field(other)
    2084         return Polyhedron(vertices=hull_vertices,
    2085                           rays=hull_rays, lines=hull_lines,
    2086                           base_ring=hull_field)
    2087 
    2088 
     2083        return self.parent().element_class(self.parent(), [hull_vertices, hull_rays, hull_lines], None)
     2084
     2085    @coerce_binop
    20892086    def intersection(self, other):
    20902087        """
    20912088        Return the intersection of one polyhedron with another.
     
    20962093
    20972094        OUTPUT:
    20982095
    2099         The intersection.
     2096        The intersection.
     2097
     2098        Note that the intersection of two `\ZZ`-polyhedra might not be
     2099        a `\ZZ`-polyhedron. In this case, a `\QQ`-polyhedron is
     2100        returned.
    21002101
    21012102        EXAMPLES::
    21022103
    21032104            sage: cube = polytopes.n_cube(3)
    21042105            sage: oct = polytopes.cross_polytope(3)
    2105             sage: cube_oct = cube.intersection(oct*2)
    2106             sage: len(list( cube_oct.vertex_generator() ))
    2107             12
    2108             sage: cube_oct
    2109             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
     2106            sage: cube.intersection(oct*2)
     2107            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 12 vertices
     2108
     2109       The intersection of two `\ZZ`-polyhedra is not necessarily a `\ZZ`-polyhedron::
     2110
     2111            sage: P = Polyhedron([(0,0),(1,1)], base_ring=ZZ)
     2112            sage: P.intersection(P)
     2113            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices
     2114            sage: Q = Polyhedron([(0,1),(1,0)], base_ring=ZZ)
     2115            sage: P.intersection(Q)
     2116            A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
     2117            sage: _.Vrepresentation()
     2118            (A vertex at (1/2, 1/2),)
    21102119        """
    2111         new_ieqs = []
    2112         new_ieqs.extend(self.inequalities())
    2113         new_ieqs.extend(other.inequalities())
    2114 
    2115         new_eqns = []
    2116         new_eqns.extend(self.equations())
    2117         new_eqns.extend(other.equations())
    2118 
    2119         return Polyhedron(ieqs = new_ieqs, eqns = new_eqns,
    2120                           base_ring=self.coerce_field(other))
    2121 
     2120        new_ieqs = self.inequalities() + other.inequalities()
     2121        new_eqns = self.equations() + other.equations()
     2122        parent = self.parent()
     2123        try:
     2124            return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2125        except TypeError,msg:
     2126            if self.base_ring() is ZZ:
     2127                parent = parent.base_extend(QQ)
     2128                return parent.element_class(parent, None, [new_ieqs, new_eqns])
     2129            else:
     2130                raise TypeError(msg)
    21222131
    21232132    def edge_truncation(self, cut_frac = Integer(1)/3):
    21242133        r"""
     
    21542163
    21552164        return Polyhedron(vertices=new_vertices, rays=new_rays,
    21562165                          lines=new_lines,
    2157                           base_ring=self.coerce_field(cut_frac))
    2158 
     2166                          base_ring=self.parent()._coerce_base_ring(cut_frac))
    21592167
    21602168    def _make_polyhedron_face(self, Vindices, Hindices):
    21612169        """
     
    21832191        """
    21842192        return PolyhedronFace_base(self, Vindices, Hindices)
    21852193
    2186 
     2194    @cached_method
    21872195    def face_lattice(self):
    21882196        """
    21892197        Return the face-lattice poset.
     
    23282336            http://portal.acm.org/citation.cfm?id=763203 and free of
    23292337            charge at http://arxiv.org/abs/math/0106043
    23302338        """
    2331         try:
    2332             return self._face_lattice
    2333         except AttributeError:
    2334             pass
    2335        
    23362339        coatom_to_Hindex = [ h.index() for h in self.inequality_generator() ]
    23372340        Hindex_to_coatom = [None] * self.n_Hrepresentation()
    23382341        for i in range(0,len(coatom_to_Hindex)):
     
    23642367            return self._make_polyhedron_face(Vindices, Hindices)
    23652368
    23662369        from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
    2367         self._face_lattice = Hasse_diagram_from_incidences\
     2370        return Hasse_diagram_from_incidences\
    23682371            (atoms_incidences, coatoms_incidences,
    23692372             face_constructor=face_constructor, required_atoms=atoms_vertices)
    2370         return self._face_lattice
    2371 
    2372 
     2373
     2374    @cached_method
    23732375    def f_vector(self):
    23742376        r"""
    23752377        Return the f-vector.
     
    23862388            sage: p.f_vector()
    23872389            (1, 7, 12, 7, 1)
    23882390        """
    2389         try:
    2390             return self._f_vector
    2391         except AttributeError:
    2392             self._f_vector = vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
    2393             return self._f_vector
    2394 
    2395 
     2391        return vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
     2392   
     2393    @cached_method
    23962394    def vertex_graph(self):
    23972395        """
    23982396        Return a graph in which the vertices correspond to vertices
     
    24072405            sage: s4.is_eulerian()
    24082406            True
    24092407        """
    2410         try:
    2411             return self._graph
    2412         except AttributeError:
    2413             self._graph = Graph(self.vertex_adjacency_matrix(), loops=True)
    2414             return self._graph
    2415 
     2408        return Graph(self.vertex_adjacency_matrix(), loops=True)
    24162409
    24172410    graph = vertex_graph
    24182411
    2419 
    24202412    def polar(self):
    24212413        """
    2422         Return the polar (dual) polytope.  The original vertices are
    2423         translated so that their barycenter is at the origin, and then
    2424         the vertices are used as the coefficients in the polar inequalities.
     2414        Return the polar (dual) polytope. 
     2415
     2416        The original vertices are translated so that their barycenter
     2417        is at the origin, and then the vertices are used as the
     2418        coefficients in the polar inequalities.
    24252419
    24262420        EXAMPLES::
    24272421
    2428             sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]])
     2422            sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]], base_ring=QQ)
    24292423            sage: p
    24302424            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices
    24312425            sage: p.polar()
     
    24332427        """
    24342428        assert self.is_compact(), "Not a polytope."
    24352429
    2436         verts = [list(v() - self.center()) for v in self.vertex_generator()]
    2437         return Polyhedron(ieqs=[[1] + list(v) for v in verts],
    2438                           base_ring=self.base_ring())
    2439 
     2430        verts = [list(v.vector() - self.center()) for v in self.vertex_generator()]
     2431        base_ring = self.parent()._coerce_base_ring(self.center().parent().base_ring())
     2432        return Polyhedron(ieqs=[[1] + list(v) for v in verts], base_ring=base_ring)
    24402433
    24412434    def pyramid(self):
    24422435        """
     
    24442437
    24452438        EXAMPLES::
    24462439
    2447             sage: square = polytopes.n_cube(2)
    2448             sage: egyptian_pyramid = square.pyramid()
     2440            sage: square = polytopes.n_cube(2);  square
     2441            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
     2442            sage: egyptian_pyramid = square.pyramid();  egyptian_pyramid
     2443            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices
    24492444            sage: egyptian_pyramid.n_vertices()
    24502445            5
    24512446            sage: for v in egyptian_pyramid.vertex_generator(): print v
     
    24562451            A vertex at (1, 0, 0)
    24572452        """
    24582453        new_verts = \
    2459             [[0] + list(x) for x in self.Vrep_generator()] + \
     2454            [[0] + x for x in self.Vrep_generator()] + \
    24602455            [[1] + list(self.center())]
    2461 
    2462         return Polyhedron(vertices = new_verts, base_ring=self.field())
    2463 
     2456        return Polyhedron(vertices=new_verts)
    24642457
    24652458    def bipyramid(self):
    24662459        """
     
    24952488            [[-1] + list(self.center())]
    24962489        new_rays = [[0] + r for r in self.rays()]
    24972490        new_lines = [[0] + list(l) for l in self.lines()]
    2498         return Polyhedron(vertices=new_verts,
    2499                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2500 
     2491        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines)
    25012492
    25022493    def prism(self):
    25032494        """
     
    25082499            sage: square = polytopes.n_cube(2)
    25092500            sage: cube = square.prism()
    25102501            sage: cube
    2511             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
     2502            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
    25122503            sage: hypercube = cube.prism()
    25132504            sage: hypercube.n_vertices()
    25142505            16
     
    25172508        new_verts.extend( [ [0] + v for v in self.vertices()] )
    25182509        new_verts.extend( [ [1] + v for v in self.vertices()] )
    25192510        new_rays =        [ [0] + r for r in self.rays()]
    2520         new_lines =       [ [0] + list(l) for l in self.lines()]
    2521         return Polyhedron(vertices=new_verts,
    2522                           rays=new_rays, lines=new_lines, base_ring=self.field())
    2523 
     2511        new_lines =       [ [0] + l for l in self.lines()]
     2512        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines,
     2513                          base_ring=self.base_ring())
    25242514
    25252515    def projection(self):
    25262516        """
     
    25372527        self.projection = Projection(self)
    25382528        return self.projection
    25392529
    2540 
    25412530    def render_solid(self, **kwds):
    25422531        """
    25432532        Return a solid rendering of a 2- or 3-d polytope.
     
    25562545            return proj.render_fill_2d(**kwds)
    25572546        raise ValueError, "render_solid is only defined for 2 and 3 dimensional polyhedra."
    25582547
    2559 
    25602548    def render_wireframe(self, **kwds):
    25612549        """
    25622550        For polytopes in 2 or 3 dimensions, return the edges
     
    25762564            return proj.render_outline_2d(**kwds)
    25772565        raise ValueError, "render_wireframe is only defined for 2 and 3 dimensional polyhedra."
    25782566
    2579 
    25802567    def schlegel_projection(self, projection_dir = None, height = 1.1):
    25812568        """
    25822569        Returns a projection object whose transformed coordinates are
     
    25932580        """
    25942581        proj = self.projection()
    25952582        if projection_dir == None:
    2596             v = self.vertices()
    2597             f0 = (self.facial_incidences()[0])[1]
    2598             projection_dir = [sum([v[f0[i]][j]/len(f0) for i in range(len(f0))])
    2599                               for j in range(len(v[0]))]
     2583            vertices = self.vertices()
     2584            facet = self.Hrepresentation(0)
     2585            f0 = [ v.index() for v in facet.incident() ]
     2586            projection_dir = [sum([vertices[f0[i]][j]/len(f0) for i in range(len(f0))])
     2587                              for j in range(self.ambient_dim())]
    26002588        return proj.schlegel(projection_direction = projection_dir, height = height)
    26012589       
    2602 
    26032590    def lrs_volume(self, verbose = False):
    26042591        """
    26052592        Computes the volume of a polytope.
     
    26502637
    26512638        raise ValueError, "lrs did not return a volume"
    26522639
    2653 
    26542640    def contains(self, point):
    26552641        """
    26562642        Test whether the polyhedron contains the given ``point``.
     
    26922678        The empty polyhedron needs extra care, see trac #10238::
    26932679
    26942680            sage: empty = Polyhedron(); empty
    2695             The empty polyhedron in QQ^0
     2681            The empty polyhedron in ZZ^0
    26962682            sage: empty.contains([])
    26972683            False
    26982684            sage: empty.contains([0])               # not a point in QQ^0
    26992685            False
    27002686            sage: full = Polyhedron(vertices=[()]); full
    2701             A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex
     2687            A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex
    27022688            sage: full.contains([])
    27032689            True
    27042690            sage: full.contains([0])
     
    27102696            if len(point)>0:
    27112697                return False
    27122698            else:
    2713                 p = vector(self.field(), [])
     2699                p = vector(self.base_ring(), [])
    27142700
    27152701        if len(p)!=self.ambient_dim():
    27162702            return False
     
    27202706                return False
    27212707        return True
    27222708
    2723 
    27242709    def interior_contains(self, point):
    27252710        """
    27262711        Test whether the interior of the polyhedron contains the
     
    27572742        The empty polyhedron needs extra care, see trac #10238::
    27582743
    27592744            sage: empty = Polyhedron(); empty
    2760             The empty polyhedron in QQ^0
     2745            The empty polyhedron in ZZ^0
    27612746            sage: empty.interior_contains([])
    27622747            False
    27632748        """
     
    27672752            if len(point)>0:
    27682753                return False
    27692754            else:
    2770                 p = vector(self.field(), [])
     2755                p = vector(self.base_ring(), [])
    27712756
    27722757        if len(p)!=self.ambient_dim():
    27732758            return False
     
    27772762                return False
    27782763        return True
    27792764
    2780 
    27812765    def relative_interior_contains(self, point):
    27822766        """
    27832767        Test whether the relative interior of the polyhedron
     
    28082792        The empty polyhedron needs extra care, see trac #10238::
    28092793
    28102794            sage: empty = Polyhedron(); empty
    2811             The empty polyhedron in QQ^0
     2795            The empty polyhedron in ZZ^0
    28122796            sage: empty.relative_interior_contains([])
    28132797            False
    28142798        """
     
    28182802            if len(point)>0:
    28192803                return False
    28202804            else:
    2821                 p = vector(self.field(), [])
     2805                p = vector(self.base_ring(), [])
    28222806
    28232807        if len(p)!=self.ambient_dim():
    28242808            return False
     
    28482832        """
    28492833        return self.is_compact() and (self.dim()+1==self.n_vertices())
    28502834
     2835    @cached_method
    28512836    def is_lattice_polytope(self):
    28522837        r"""
    28532838        Return whether the polyhedron is a lattice polytope.
     
    28642849            sage: polytopes.regular_polygon(5).is_lattice_polytope()
    28652850            False
    28662851        """
    2867         try:
    2868             return self._is_lattice_polytope
    2869         except AttributeError:
    2870             pass
    2871         self._is_lattice_polytope = self.is_compact() and \
    2872             all(v.is_integral() for v in self.vertex_generator())
    2873         return self._is_lattice_polytope
     2852        if not self.is_compact():
     2853            return False
     2854        if self.base_ring() is ZZ:
     2855            return True
     2856        return all(v.is_integral() for v in self.vertex_generator())
    28742857       
     2858    @cached_method
    28752859    def lattice_polytope(self, envelope=False):
    28762860        r"""
    28772861        Return an encompassing lattice polytope.
     
    29342918        if not self.is_compact():
    29352919            raise NotImplementedError, 'Only compact lattice polytopes are allowed.'
    29362920
    2937         def nonintegral_error():
    2938             raise ValueError, 'Some vertices are not integral. '+\
    2939                 'You probably want to add the argument '+\
    2940                 '"envelope=True" to compute an enveloping lattice polytope.'
    2941 
    2942         # try to make use of cached values, if possible
    2943         if envelope:
    2944             try:
    2945                 return self._lattice_polytope
    2946             except AttributeError:
    2947                 pass
    2948         else:
    2949             try:
    2950                 assert self._is_lattice_polytope
    2951                 return self._lattice_polytope
    2952             except AttributeError:
    2953                 pass
    2954             except AssertionError:
    2955                 nonintegral_error()
    2956 
    2957         # find the integral vertices
    29582921        try:
    2959             vertices = matrix(ZZ, self.vertices()).transpose()
    2960             self._is_lattice_polytope = True
     2922            vertices = self.vertices_matrix(ZZ)
    29612923        except TypeError:
    2962             self._is_lattice_polytope = False
    2963             if envelope==False: nonintegral_error()
     2924            if envelope==False:
     2925                raise ValueError, 'Some vertices are not integral. '+\
     2926                    'You probably want to add the argument '+\
     2927                    '"envelope=True" to compute an enveloping lattice polytope.'
    29642928            vertices = []
    29652929            for v in self.vertex_generator():
    29662930                vbox = [ set([floor(x),ceil(x)]) for x in v ]
     
    29692933
    29702934        # construct the (enveloping) lattice polytope
    29712935        from sage.geometry.lattice_polytope import LatticePolytope
    2972         self._lattice_polytope = LatticePolytope(vertices)
    2973         return self._lattice_polytope
     2936        return LatticePolytope(vertices)
    29742937
    29752938    def _integral_points_PALP(self):
    29762939        r"""
     
    30383001        box_max = []
    30393002        if self.n_vertices==0:
    30403003            raise ValueError('Empty polytope is not allowed')
     3004        if not self.is_compact():
     3005            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
    30413006        for i in range(0,self.ambient_dim()):
    3042             coords = [ v[i] for v in self.Vrep_generator() ]
     3007            coords = [ v[i] for v in self.vertex_generator() ]
    30433008            max_coord = max(coords)
    30443009            min_coord = min(coords)
    30453010            if integral:
     
    30963061
    30973062            sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
    30983063            sage: simplex = Polyhedron(v); simplex
    3099             A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
     3064            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
    31003065            sage: len(simplex.integral_points())
    31013066            49
    31023067
     
    31463111        # assert all(self.contains(p) for p in points)   # slow
    31473112        return tuple(points)
    31483113   
     3114    @cached_method
    31493115    def combinatorial_automorphism_group(self):
    31503116        """
    31513117        Computes the combinatorial automorphism group of the vertex
     
    31803146            sage: P.combinatorial_automorphism_group()
    31813147            Permutation Group with generators [(3,4)]
    31823148        """
    3183         if '_combinatorial_automorphism_group' in self.__dict__:
    3184             return self._combinatorial_automorphism_group
    3185 
    31863149        from sage.groups.perm_gps.permgroup import PermutationGroup
    3187 
    31883150        G = Graph()
    31893151        for edge in self.vertex_graph().edges():
    31903152            i = edge[0]
     
    32023164        self._combinatorial_automorphism_group = group
    32033165        return group
    32043166
    3205 
    32063167    def _affine_coordinates(self, Vrep_object):
    32073168        r"""
    32083169        Return affine coordinates for a V-representation object.
     
    32413202        if len(v) != self.ambient_dim():
    32423203            raise ValueError('Incorrect dimension: '+str(v))
    32433204
    3244         return vector(self.field(), [ v[i] for i in self._affine_coordinates_pivots ])
     3205        return vector(self.base_ring(), [ v[i] for i in self._affine_coordinates_pivots ])
    32453206       
    3246 
     3207    @cached_method
    32473208    def restricted_automorphism_group(self):
    32483209        r"""
    32493210        Return the restricted automorphism group.
     
    33913352            sage: p.restricted_automorphism_group()
    33923353            Permutation Group with generators [(2,3)]
    33933354        """
    3394         if '_restricted_automorphism_group' in self.__dict__:
    3395             return self._restricted_automorphism_group
    3396 
    33973355        from sage.groups.perm_gps.permgroup import PermutationGroup
    33983356
    3399         if self.field() is QQ:
     3357        if self.base_ring() is ZZ or self.base_ring() is QQ:
    34003358            def rational_approximation(c):
    34013359                return c
    34023360
    3403         else:  # self.field() is RDF
     3361        elif self.base_ring() is RDF:
    34043362            c_list = []
    34053363            def rational_approximation(c):
    34063364                # Implementation detail: Return unique integer if two
     
    34123370                        return i
    34133371                c_list.append(c)
    34143372                return len(c_list)-1
    3415        
     3373
    34163374        # The algorithm identifies the restricted automorphism group
    34173375        # with the automorphism group of a edge-colored graph. The
    34183376        # nodes of the graph are the V-representation objects. If all
     
    34693427
    34703428
    34713429
    3472 
    3473 
    3474 
    34753430#########################################################################
    3476 class PolyhedronFace_base(SageObject):
     3431class PolyhedronFace_base(Polyhedron_base):
    34773432    r"""
    34783433    A face of a polyhedron.
    34793434   
     
    35363491            sage: PolyhedronFace_base(Polyhedron(), [], [])   # indirect doctest
    35373492            <>
    35383493        """
     3494        Element.__init__(self, parent=polyhedron.parent())
    35393495        self._polyhedron = polyhedron
    35403496        self._ambient_Vrepresentation_indices = tuple(V_indices)
    35413497        self._ambient_Hrepresentation_indices = tuple(H_indices)
    35423498        self._ambient_Vrepresentation = tuple( polyhedron.Vrepresentation(i) for i in V_indices )
    35433499        self._ambient_Hrepresentation = tuple( polyhedron.Hrepresentation(i) for i in H_indices )
    3544         # self._Vrepresentation =
    3545         # self._Hrepresentation =
     3500        self._Vrepresentation = tuple()
     3501        self._Hrepresentation = tuple()
    35463502       
    3547 
    35483503    def ambient_Hrepresentation(self, index=None):
    35493504        r"""
    35503505        Return the H-representation objects of the ambient polytope
     
    35873542        else:
    35883543            return self._ambient_Hrepresentation[index]
    35893544       
    3590 
    35913545    def ambient_Vrepresentation(self, index=None):
    35923546        r"""
    35933547        Return the V-representation objects of the ambient polytope
     
    36303584        else:
    36313585            return self._ambient_Vrepresentation[index]
    36323586
    3633 
     3587    @cached_method
    36343588    def n_ambient_Hrepresentation(self):
    36353589        """
    36363590        Return the number of objects that make up the ambient
     
    36563610            sage: face.n_ambient_Hrepresentation()
    36573611            4
    36583612        """
    3659         return len(self._ambient_Hrepresentation)
    3660 
    3661 
     3613        return len(self.ambient_Hrepresentation())
     3614
     3615    @cached_method
    36623616    def n_ambient_Vrepresentation(self):
    36633617        """
    36643618        Return the number of objects that make up the ambient
     
    36813635            sage: face.n_ambient_Vrepresentation()
    36823636            2
    36833637        """
    3684         return len(self._ambient_Vrepresentation)
    3685 
    3686 
     3638        return len(self.ambient_Vrepresentation())
     3639
     3640    @cached_method
    36873641    def dim(self):
    36883642        """
    36893643        Return the dimension of the face.
     
    37003654              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    37013655              1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3]
    37023656        """
    3703         if '_dim' in self.__dict__:
    3704             return self._dim
    3705 
    37063657        if self.n_ambient_Vrepresentation()==0:
    3707             self._dim = -1
     3658            return -1
    37083659        else:
    37093660            origin = vector(self.ambient_Vrepresentation(0))
    37103661            v_list = [ vector(v)-origin for v in self.ambient_Vrepresentation() ]
    3711             self._dim = matrix(v_list).rank()
    3712         return self._dim
    3713 
     3662            return matrix(v_list).rank()
    37143663
    37153664    def _repr_(self):
    37163665        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        """
    78         return len(self._representation_data)
     66        return self._vector.degree()
    7967
    8068    def __getitem__(self, i):
    8169        """
     
    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.
     817        Initializes the PolyhedronRepresentation object.
     818       
     819        TESTS::
     820       
     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')
     826        """
     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.
    699846
    700847        TESTS::
    701        
    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')
     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')
    710852        """
    711         if len(data) != polyhedron.ambient_dim():
     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
     1021        -  ``polyhedral_data`` -- an object with 4d vertex and
    10231022           adjacency information
    10241023       
    1025        
    10261024        OUTPUT:
    10271025       
    10281026       
    1029         -  ``edges`` - a list of edges in 3d - each list item
     1027        -  ``edges`` -- a list of edges in 3d - each list item
    10301028           is a pair of points
    10311029       
    1032        
    10331030        EXAMPLES::
    10341031       
    10351032            sage: R4.<w,x,y,z> = PolynomialRing(QQ,4)
     
    10491046        """
    10501047        fpoints = polyhedral_data.vertices()
    10511048        tpoints = [self._embed_tetra(q) for q in fpoints]
    1052         adj_data = polyhedral_data.vertex_adjacencies()
    10531049        edges = []
    1054         for adj in adj_data:
    1055             for vert in adj[1]:
    1056                 if vert > adj[0]:
     1050        for vertex in polyhedral_data.vertices():
     1051            i = vertex.index()
     1052            for adjacent_vertex in vertex.adjacent():
     1053                j = adjacent_vertex.index()
     1054                if j>i:
    10571055                    try:
    1058                         edges.append([tpoints[adj[0]],tpoints[vert]])
     1056                        edges.append([tpoints[i],tpoints[j]])
    10591057                    except:
    10601058                        print adj
    10611059                        print 'tpoints: ' + str(tpoints)
    10621060                        print 'fpoints: ' + str(fpoints)
    1063                         print vert
     1061                        print adjacent_vertex
    10641062                        print polyhedral_data.ieqs()
    10651063                        raise RuntimeError, adj
    10661064        return edges
     
    11041102        #This is really just for debugging
    11051103        if verbose:
    11061104            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()
     1105                print x.inequalities() + ([1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1])
     1106                print x.equations()
    11091107                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]
     1108        cone_info = [Polyhedron(ieqs = x.inequalities() +
     1109                                ([1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]),
     1110                                eqns = x.equations()) for x in cone_info]
    11111111        all_lines = []
    11121112        for cone_data in cone_info:
    11131113            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
     
    862863            sage: f = 1 + x*y + x^3 + y^3
    863864            sage: P = f.newton_polytope()
    864865            sage: P
    865             A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
     866            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
    866867            sage: P.is_simple()
    867868            True
    868869
     
    870871
    871872            sage: R.<x,y> = QQ[]
    872873            sage: R(0).newton_polytope()
    873             The empty polyhedron in QQ^0
     874            The empty polyhedron in ZZ^0
    874875            sage: R(1).newton_polytope()
    875             A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
    876            
     876            A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex
     877            sage: R(x^2+y^2).newton_polytope().integral_points()
     878            ((0, 2), (1, 1), (2, 0))
    877879        """
    878880        from sage.geometry.polyhedron.constructor import Polyhedron
    879881        e = self.exponents()
    880         P = Polyhedron(vertices = e)
     882        P = Polyhedron(vertices=e, base_ring=ZZ)
    881883        return P
    882884
    883885    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.