Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Read/write PointCollection in PALP format directly
Browse files Browse the repository at this point in the history
  • Loading branch information
novoselt committed Mar 6, 2017
1 parent 0d734aa commit e56ec40
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 28 deletions.
56 changes: 28 additions & 28 deletions src/sage/geometry/lattice_polytope.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
from sage.env import POLYTOPE_DATA_DIR
from sage.geometry.cone import _ambient_space_point, integral_length
from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
from sage.geometry.point_collection import PointCollection, is_PointCollection
from sage.geometry.point_collection import PointCollection,\
is_PointCollection, read_palp_point_collection
from sage.geometry.toric_lattice import ToricLattice, is_ToricLattice
from sage.graphs.graph import DiGraph, Graph
from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
Expand Down Expand Up @@ -184,8 +185,9 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None):
* a file with matrix data, opened for reading, or
* a filename of such a file, see :func:`read_palp_matrix` for the
file format;
* a filename of such a file, see
:func:`~sage.geometry.point_collection.read_palp_point_collection`
for the file format;
- ``compute_vertices`` -- boolean (default: ``True``). If ``True``, the
convex hull of the given points will be computed for
Expand Down Expand Up @@ -290,10 +292,10 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None):
if isinstance(data, str):
f = open(data)
skip_palp_matrix(f, n)
data = read_palp_matrix(data)
data = read_palp_point_collection(data)
f.close()
if isinstance(data, (file, StringIO)):
data = read_palp_matrix(data)
data = read_palp_point_collection(data)
if not is_PointCollection(data) and not isinstance(data, (list, tuple)):
try:
data = list(data)
Expand Down Expand Up @@ -1127,8 +1129,8 @@ def _read_equations(self, data):
N = self.dual_lattice()
if self.is_reflexive():
data.seek(pos)
polar = LatticePolytope(read_palp_matrix(data).columns(),
compute_vertices=False, lattice=N)
polar = LatticePolytope(
read_palp_point_collection(data, N), compute_vertices=False)
polar.dim.set_cache(self.dim())
polar.is_reflexive.set_cache(True)
polar._constructed_as_polar = True
Expand Down Expand Up @@ -1205,8 +1207,8 @@ def _read_nef_partitions(self, data):
return
nvertices = self.nvertices()
data.readline() # Skip M/N information
nef_vertices = read_palp_matrix(data)
if self.vertices().column_matrix() != nef_vertices:
nef_vertices = read_palp_point_collection(data, self.lattice())
if self.vertices() != nef_vertices:
raise RuntimeError("nef.x changed the order of vertices!")
line = data.readline()
if line == "":
Expand Down Expand Up @@ -2895,8 +2897,8 @@ def normal_form(self, algorithm="palp", permutation=False):
if self.dim() < self.lattice_dim():
raise ValueError("normal form is not defined for %s" % self)
if algorithm == "palp":
result = read_palp_matrix(self.poly_x("N"),
permutation=permutation)
result = read_palp_point_collection(
self.poly_x("N"), self.lattice(), permutation=permutation)
elif algorithm == "palp_native":
result = self._palp_native_normal_form(permutation=permutation)
elif algorithm == "palp_modified":
Expand Down Expand Up @@ -4955,10 +4957,13 @@ def _palp(command, polytopes, reduce_dimension=False):
if p.dim() == 0:
raise ValueError(("Cannot run \"%s\" for the zero-dimensional "
+ "polytope!\nPolytope: %s") % (command, p))
if p.dim() < p.lattice_dim() and not reduce_dimension:
raise ValueError(("Cannot run PALP for a %d-dimensional polytope " +
"in a %d-dimensional space!") % (p.dim(), p.lattice_dim()))
write_palp_matrix(p._pullback(p._vertices), input_file)
if p.dim() < p.lattice_dim():
if not reduce_dimension:
raise ValueError(("Cannot run PALP for a %d-dimensional polytope " +
"in a %d-dimensional space!") % (p.dim(), p.lattice_dim()))
write_palp_matrix(p._pullback(p._vertices), input_file)
else:
p._vertices.write_for_palp(input_file)
input_file.close()
output_file_name = tmp_filename()
c = "%s <%s >%s" % (command, input_file_name, output_file_name)
Expand Down Expand Up @@ -5594,21 +5599,16 @@ def read_all_polytopes(file_name):
-1 1 -1
1 1 -1
sage: lattice_polytope.read_all_polytopes(result_name)
[
2-d reflexive polytope #14 in 2-d lattice M,
3-d reflexive polytope in 3-d lattice M
]
[2-d reflexive polytope #14 in 2-d lattice M,
3-d reflexive polytope in 3-d lattice M]
sage: os.remove(result_name)
"""
polytopes = Sequence([], LatticePolytope, cr=True)
f = open(file_name)
n = 0
m = read_palp_matrix(f)
while m.nrows() != 0:
polytopes.append(LatticePolytope(m.columns(), compute_vertices=False))
n += 1
m = read_palp_matrix(f)
f.close()
polytopes = []
with open(file_name) as f:
pc = read_palp_point_collection(f)
while pc is not None:
polytopes.append(LatticePolytope(pc, compute_vertices=False))
pc = read_palp_point_collection(f)
return polytopes


Expand Down
130 changes: 130 additions & 0 deletions src/sage/geometry/point_collection.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ from __future__ import print_function
from sage.structure.sage_object cimport SageObject
from sage.structure.sage_object cimport richcmp_not_equal, richcmp

from sage.geometry.toric_lattice import ToricLattice
from sage.matrix.all import matrix
from sage.misc.all import latex

Expand Down Expand Up @@ -900,3 +901,132 @@ cdef class PointCollection(SageObject):
if self._set is None:
self._set = frozenset(self._points)
return self._set

def write_for_palp(self, f):
r"""
Write ``self`` into an open file ``f`` in PALP format.
INPUT:
- ``f`` -- a file opened for writing.
EXAMPLES::
sage: o = lattice_polytope.cross_polytope(3)
sage: from six import StringIO
sage: f = StringIO()
sage: o.vertices().write_for_palp(f)
sage: print f.getvalue()
6 3
1 0 0
0 1 0
0 0 1
-1 0 0
0 -1 0
0 0 -1
"""
f.write('{} {}\n'.format(len(self), self._module.rank()))
f.write('\n'.join(' '.join(str(c) for c in p) for p in self))
f.write('\n')


def read_palp_point_collection(f, lattice=None, permutation=False):
r"""
Read and return a point collection from an opened file.
Data must be in PALP format:
* the first input line starts with two integers `m` and `n`, the number
of points and the number of components of each;
* the rest of the first line may contain a permutation;
* the next `m` lines contain `n` numbers each.
.. NOTE::
If `m` < `n`, it is assumed (for compatibility with PALP) that the
matrix is transposed, i.e. that each column is a point.
INPUT:
- ``f`` -- an opened file with PALP output.
- ``lattice`` -- the lattice for points. If not given, the
:class:`toric lattice <sage.geometry.toric_lattice.ToricLatticeFactory>`
`M` of dimension `n` will be used.
- ``permutation`` -- (default: ``False``) if ``True``, try to retrieve
the permutation. This parameter makes sense only when PALP computed the
normal form of a lattice polytope.
OUTPUT:
- a :class:`point collection <PointCollection>`, optionally followed by
a permutation. ``None`` if EOF is reached.
EXAMPLES::
sage: data = "3 2 regular\n1 2\n3 4\n5 6\n2 3 transposed\n1 2 3\n4 5 6"
sage: print data
3 2 regular
1 2
3 4
5 6
2 3 transposed
1 2 3
4 5 6
sage: from six import StringIO
sage: f = StringIO(data)
sage: from sage.geometry.point_collection \
....: import read_palp_point_collection
sage: read_palp_point_collection(f)
M(1, 2),
M(3, 4),
M(5, 6)
in 2-d lattice M
sage: read_palp_point_collection(f)
M(1, 4),
M(2, 5),
M(3, 6)
in 2-d lattice M
sage: read_palp_point_collection(f) is None
True
"""
cdef int i, j, m, n
first_line = f.readline()
if first_line == "":
return None
first_line = first_line.split()
m = int(first_line[0])
n = int(first_line[1])
points = []
if m >= n:
# Typical situation: a point on each line
if lattice is None:
lattice = ToricLattice(n).dual()
for i in range(m):
p = lattice.zero_vector()
for j, e in enumerate(f.readline().split()):
p[j] = int(e)
points.append(p)
else:
if lattice is None:
lattice = ToricLattice(m).dual()
for i in range(n):
points.append(lattice.zero_vector())
for j in range(m):
for i, e in enumerate(f.readline().split()):
points[i][j] = int(e)
for p in points:
p.set_immutable()
pc = PointCollection(points, lattice)
if permutation:
last_piece = first_line[-1].split('=')
if last_piece[0] != 'perm':
raise ValueError('permutation was requested but not found')
from sage.geometry.lattice_polytope import _palp_convert_permutation
p = _palp_convert_permutation(last_piece[1])
return (pc, p)
else:
return pc

0 comments on commit e56ec40

Please sign in to comment.