Path: blob/master/src/sage/geometry/polyhedron/palp_database.py
8817 views
"""1Access the PALP database(s) of reflexive lattice polytopes23EXAMPLES::45sage: from sage.geometry.polyhedron.palp_database import PALPreader6sage: for lp in PALPreader(2):7... cone = Cone([(1,r[0],r[1]) for r in lp.vertices()])8... fan = Fan([cone])9... X = ToricVariety(fan)10... ideal = X.affine_algebraic_patch(cone).defining_ideal()11... print lp.n_vertices(), ideal.hilbert_series()123 (-t^2 - 7*t - 1)/(t^3 - 3*t^2 + 3*t - 1)133 (-t^2 - t - 1)/(t^3 - 3*t^2 + 3*t - 1)143 (t^2 + 6*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)153 (t^2 + 2*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)163 (t^2 + 4*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)174 (-t^2 - 5*t - 1)/(t^3 - 3*t^2 + 3*t - 1)184 (-t^2 - 3*t - 1)/(t^3 - 3*t^2 + 3*t - 1)194 (t^2 + 2*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)204 (t^2 + 6*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)214 (t^2 + 6*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)224 (t^2 + 2*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)234 (t^2 + 4*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)245 (-t^2 - 3*t - 1)/(t^3 - 3*t^2 + 3*t - 1)255 (-t^2 - 5*t - 1)/(t^3 - 3*t^2 + 3*t - 1)265 (t^2 + 4*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)276 (t^2 + 4*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)28"""2930from subprocess import Popen, PIPE3132from sage.structure.sage_object import SageObject33from sage.matrix.all import matrix34from sage.rings.all import Integer, ZZ3536from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL37from sage.geometry.polyhedron.constructor import Polyhedron38394041#########################################################################42class PALPreader(SageObject):43"""44Read PALP database of polytopes.454647INPUT:4849- ``dim`` -- integer. The dimension of the poylhedra5051- ``data_basename`` -- string or ``None`` (default). The directory52and database base filename (PALP usually uses ``'zzdb'``) name53containing the PALP database to read. Defaults to the built-in54database location.5556- ``output`` -- string. How to return the reflexive polyhedron57data. Allowed values = ``'list'``, ``'Polyhedron'`` (default),58``'pointcollection'``, and ``'PPL'``. Case is ignored.5960EXAMPLES::6162sage: from sage.geometry.polyhedron.palp_database import PALPreader63sage: polygons = PALPreader(2)64sage: [ (p.n_Vrepresentation(), len(p.integral_points())) for p in polygons ]65[(3, 4), (3, 10), (3, 5), (3, 9), (3, 7), (4, 6), (4, 8), (4, 9),66(4, 5), (4, 5), (4, 9), (4, 7), (5, 8), (5, 6), (5, 7), (6, 7)]6768sage: iter(PALPreader(2, output='list')).next()69[[1, 0], [0, 1], [-1, -1]]70sage: type(_)71<type 'list'>7273sage: iter(PALPreader(2, output='Polyhedron')).next()74A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices75sage: type(_)76<class 'sage.geometry.polyhedron.backend_ppl.Polyhedra_ZZ_ppl_with_category.element_class'>7778sage: iter(PALPreader(2, output='PPL')).next()79A 2-dimensional lattice polytope in ZZ^2 with 3 vertices80sage: type(_)81<class 'sage.geometry.polyhedron.ppl_lattice_polygon.LatticePolygon_PPL_class'>8283sage: iter(PALPreader(2, output='PointCollection')).next()84[ 1, 0],85[ 0, 1],86[-1, -1]87in Ambient free module of rank 2 over the principal ideal domain Integer Ring88sage: type(_)89<type 'sage.geometry.point_collection.PointCollection'>90"""9192def __init__(self, dim, data_basename=None, output='Polyhedron'):93"""94The Python constructor9596See :class:`PALPreader` for documentation.9798TESTS::99100sage: from sage.geometry.polyhedron.palp_database import PALPreader101sage: polygons = PALPreader(2)102"""103self._dim = dim104if data_basename is not None:105self._data_basename = data_basename106else:107import os108from sage.env import SAGE_SHARE109self._data_basename = os.path.join(SAGE_SHARE, 'reflexive_polytopes',110'Full'+str(dim)+'d', 'zzdb')111info = self._data_basename + '.info'112if not os.path.exists(info):113raise ValueError('Cannot find PALP database: '+info)114from sage.geometry.polyhedron.parent import Polyhedra115self._polyhedron_parent = Polyhedra(ZZ, dim)116self._output = output.lower()117118def _palp_Popen(self):119"""120Open PALP.121122OUTPUT:123124A PALP subprocess.125126EXAMPLES::127128sage: from sage.geometry.polyhedron.palp_database import PALPreader129sage: polygons = PALPreader(2)130sage: polygons._palp_Popen()131<subprocess.Popen object at 0x...>132"""133return Popen(["class.x", "-b2a", "-di", self._data_basename], stdout=PIPE)134135def _read_vertices(self, stdout, rows, cols):136"""137Read vertex data from the PALP output pipe.138139OUTPUT:140141A list of lists.142143EXAMPLES::144145sage: from sage.geometry.polyhedron.palp_database import PALPreader146sage: polygons = PALPreader(2)147sage: palp = polygons._palp_Popen()148sage: palp.stdout.readline()149'2 3 \n'150sage: polygons._read_vertices(palp.stdout, 2, 3)151[[1, 0], [0, 1], [-1, -1]]152"""153m = [ [] for col in range(0,cols) ]154for row in range(0,rows):155for col,x in enumerate(stdout.readline().split()):156m[col].append(ZZ(x))157return m158159def _read_vertices_transposed(self, stdout, rows, cols):160"""161Read vertex data from the PALP output pipe.162163OUTPUT:164165A list of lists.166167EXAMPLES::168169sage: from sage.geometry.polyhedron.palp_database import PALPreader170sage: polygons = PALPreader(2)171sage: palp = polygons._palp_Popen()172sage: palp.stdout.readline()173'2 3 \n'174sage: polygons._read_vertices_transposed(palp.stdout, 2, 3)175[[1, 0, -1], [0, 1, -1]]176"""177m = []178for row in range(0,rows):179m.append( [ ZZ(x) for x in stdout.readline().split() ] )180return m181182def _iterate_list(self, start, stop, step):183"""184Iterate over the reflexive polytopes.185186INPUT:187188- ``start``, ``stop``, ``step`` -- integers specifying the189range to iterate over.190191OUTPUT:192193A generator for vertex data as a list of lists.194195EXAMPLES::196197sage: from sage.geometry.polyhedron.palp_database import PALPreader198sage: polygons = PALPreader(2)199sage: iter = polygons._iterate_list(0,4,2)200sage: iter.next()201[[1, 0], [0, 1], [-1, -1]]202"""203if start is None:204start = 0205if step is None:206step = 1207palp = self._palp_Popen()208try:209palp_out = palp.stdout210i = 0211while True:212l = palp_out.readline().strip()213if l=='' or l.startswith('#'):214return # EOF215l=l.split()216dim = ZZ(l[0]); # dimension217n = ZZ(l[1]); # number of vertices218if i>=start and (i-start) % step == 0:219if dim == self._dim:220vertices = self._read_vertices(palp_out, dim, n)221elif n == self._dim: # PALP sometimes returns transposed data #@!#@222vertices = self._read_vertices_transposed(palp_out, dim, n)223else:224raise ValueError('PALP output dimension mismatch.')225yield vertices226else:227for row in range(0,dim):228palp_out.readline()229i += 1230if stop is not None and i>=stop:231return232finally:233palp.poll()234if palp.returncode is None:235palp.terminate()236palp.poll()237if palp.returncode is None:238palp.kill()239240241def _iterate_Polyhedron(self, start, stop, step):242"""243Iterate over the reflexive polytopes.244245INPUT:246247- ``start``, ``stop``, ``step`` -- integers specifying the248range to iterate over.249250OUTPUT:251252A generator for lattice polyhedra.253254EXAMPLES::255256sage: from sage.geometry.polyhedron.palp_database import PALPreader257sage: polygons = PALPreader(2)258sage: iter = polygons._iterate_Polyhedron(0,4,2)259sage: iter.next()260A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices261"""262parent = self._polyhedron_parent263for vertices in self._iterate_list(start, stop, step):264p = parent.element_class(parent, [vertices,[],[]], None)265yield p266267def _iterate_PPL(self, start, stop, step):268"""269Iterate over the reflexive polytopes.270271INPUT:272273- ``start``, ``stop``, ``step`` -- integers specifying the274range to iterate over.275276OUTPUT:277278A generator for PPL-based lattice polyhedra.279280EXAMPLES::281282sage: from sage.geometry.polyhedron.palp_database import PALPreader283sage: polygons = PALPreader(2)284sage: iter = polygons._iterate_PPL(0,4,2)285sage: iter.next()286A 2-dimensional lattice polytope in ZZ^2 with 3 vertices287"""288for vertices in self._iterate_list(start, stop, step):289yield LatticePolytope_PPL(*vertices)290291def _iterate_PointCollection(self, start, stop, step):292"""293Iterate over the reflexive polytopes.294295INPUT:296297- ``start``, ``stop``, ``step`` -- integers specifying the298range to iterate over.299300OUTPUT:301302A generator for PPL-based lattice polyhedra.303304EXAMPLES::305306sage: from sage.geometry.polyhedron.palp_database import PALPreader307sage: polygons = PALPreader(2)308sage: iter = polygons._iterate_PointCollection(0,4,2)309sage: iter.next()310[ 1, 0],311[ 0, 1],312[-1, -1]313in Ambient free module of rank 2 over the principal ideal domain Integer Ring314"""315from sage.modules.free_module import FreeModule316N = FreeModule(ZZ, self._dim)317from sage.geometry.point_collection import PointCollection318for vertices in self._iterate_list(start, stop, step):319yield PointCollection(vertices, module=N)320321def _iterate(self, output=None):322"""323Iterate over the reflexive polytopes.324325INPUT:326327- ``output`` -- as in the :class:`PALPreader` constructor.328329OUTPUT:330331A function generating lattice polytopes in the specified output format.332333EAMPLES::334335sage: from sage.geometry.polyhedron.palp_database import PALPreader336sage: polygons = PALPreader(2)337sage: func = polygons._iterate(output='list')338sage: func339<bound method PALPreader._iterate_list of <class 'sage.geometry.polyhedron.palp_database.PALPreader'>>340sage: iter = func(0,1,1)341sage: iter.next()342[[1, 0], [0, 1], [-1, -1]]343"""344if output is None:345output = self._output346if output == 'polyhedron':347return self._iterate_Polyhedron348elif output == 'ppl':349return self._iterate_PPL350elif output == 'pointcollection':351return self._iterate_PointCollection352elif output == 'list':353return self._iterate_list354else:355raise TypeError('Unknown output format (='+str(self._output)+').')356357def __iter__(self):358"""359Iterate over all polytopes.360361OUTPUT:362363An iterator for all polytopes.364365TESTS::366367sage: from sage.geometry.polyhedron.palp_database import PALPreader368sage: polygons = PALPreader(2)369sage: polygons.__iter__()370<generator object _iterate_Polyhedron at 0x...>371"""372iterator = self._iterate()373return iterator(None, None, None)374375def __getitem__(self, item):376"""377Return the polytopes(s) indexed by ``item``.378379EXAMPLES::380381sage: from sage.geometry.polyhedron.palp_database import PALPreader382sage: palp = PALPreader(3)383sage: list(palp[10:30:10])384[A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices,385A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices]386"""387iterator = self._iterate()388if isinstance(item, slice):389return iterator(item.start, item.stop, item.step)390else:391try:392return iterator(item, item+1, 1).next()393except StopIteration:394raise IndexError('Index out of range.')395396397398#########################################################################399class Reflexive4dHodge(PALPreader):400"""401Read the PALP database for Hodge numbers of 4d polytopes.402403The database is very large and not installed by default. You can404install it with the command ``install_package('polytopes_db_4d')``.405406INPUT:407408- ``h11``, ``h21`` -- Integers. The Hodge numbers of the reflexive409polytopes to list.410411Any additional keyword arguments are passed to412:class:`PALPreader`.413414EXAMPLES::415416sage: from sage.geometry.polyhedron.palp_database import Reflexive4dHodge417sage: ref = Reflexive4dHodge(1,101) # optional - polytopes_db_4d418sage: iter(ref).next().Vrepresentation() # optional - polytopes_db_4d419(A vertex at (-1, -1, -1, -1), A vertex at (0, 0, 0, 1),420A vertex at (0, 0, 1, 0), A vertex at (0, 1, 0, 0), A vertex at (1, 0, 0, 0))421"""422def __init__(self, h11, h21, data_basename=None, **kwds):423"""424The Python constructor.425426See :class:`Reflexive4dHodge` for documentation.427428TESTS::429430sage: from sage.geometry.polyhedron.palp_database import Reflexive4dHodge431sage: Reflexive4dHodge(1,101) # optional - polytopes_db_4d432<class 'sage.geometry.polyhedron.palp_database.Reflexive4dHodge'>433"""434dim = 4435if data_basename is None:436import os437from sage.env import SAGE_SHARE438data_basename = os.path.join(SAGE_SHARE, 'reflexive_polytopes',439'Hodge4d', 'all')440info = data_basename + '.vinfo'441if not os.path.exists(info):442raise ValueError('Cannot find PALP database: '+info+443'. Did you install the polytopes_db_4d optional spkg?')444PALPreader.__init__(self, dim, data_basename=data_basename, **kwds)445self._h11 = h11446self._h21 = h21447448def _palp_Popen(self):449"""450Open PALP.451452OUTPUT:453454A PALP subprocess.455456EXAMPLES::457458sage: from sage.geometry.polyhedron.palp_database import Reflexive4dHodge459sage: polygons = Reflexive4dHodge(1, 101) # optional - polytopes_db_4d460sage: polygons._palp_Popen() # optional - polytopes_db_4d461<subprocess.Popen object at 0x...>462"""463return Popen(['class-4d.x', '-He',464'H'+str(self._h21)+':'+str(self._h11)+'L100000000',465'-di', self._data_basename], stdout=PIPE)466467468469470471