Skip to content

Commit

Permalink
Trac #22552: 2 bugs creating a simple 2-point Polytope
Browse files Browse the repository at this point in the history
Sara Billey (of Univ of Washington) reported these.
{{{
~/Sara$ sage-develop
┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 7.6.beta5, Release Date: 2017-02-26               │
│ Type "notebook()" for the browser-based notebook interface.        │
│ Type "help()" for help.                                            │
└────────────────────────────────────────────────────────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Warning: this is a prerelease version, and it may be unstable.     ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
sage: P=Polyhedron(vertices =[(8.3319544851638732, 7.0567045956967727),
(6.4876921900819049, 4.8435898415984129)])
sage: P
The empty polyhedron in (Real Field with 57 bits of precision)^2
sage: # WRONG!  It should not be empty.  Indeed, look:
sage: P=Polyhedron(vertices =[(8.3319544851638732, 7.0567045956967727),
(6.4876921900819049, 4.84358984159841)])
sage: P
A 1-dimensional polyhedron in RDF^2 defined as the convex hull of 2
vertices
sage: # Also, here's a hub traceback for no reason (as a second but
maybe related bug):
sage: P=Polyhedron(vertices =[(8.3319544851638732, 7.0567045956967727),
(6.4876921900819049, 4.8435898415984129)], base_ring=RealField(40))
sage: P.plot()
------------------------------------------------------------------------
---
KeyError                                  Traceback (most recent call
last)
<ipython-input-8-d297b4e23e6b> in <module>()
----> 1 P.plot()

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/base.pyc in plot(self, point, line,
polygon, wireframe, fill, projection_direction, **kwds)
    694                 return polyhedron.projection()
    695
--> 696         projection = project(self)
    697         try:
    698             plot_method = projection.plot

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/base.pyc in project(polyhedron)
    692                 return polyhedron.schlegel_projection()
    693             else:
--> 694                 return polyhedron.projection()
    695
    696         projection = project(self)

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/base.pyc in projection(self)
   3759         """
   3760         from .plot import Projection
-> 3761         self.projection = Projection(self)
   3762         return self.projection
   3763

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/plot.py in __init__(self, polyhedron,
proj)
    492
    493         if polyhedron.ambient_dim() == 2:
--> 494             self._init_from_2d(polyhedron)
    495         elif polyhedron.ambient_dim() == 3:
    496             self._init_from_3d(polyhedron)

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/plot.py in _init_from_2d(self,
polyhedron)
    748         self.dimension = 2
    749         self._init_points(polyhedron)
--> 750         self._init_lines_arrows(polyhedron)
    751         self._init_area_2d(polyhedron)
    752

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/plot.py in _init_lines_arrows(self,
polyhedron)
    812             if not obj[i].is_vertex(): continue
    813             for j in range(len(obj)):
--> 814                 if polyhedron.vertex_adjacency_matrix()[i,j] ==
0: continue
    815                 if i < j and obj[j].is_vertex():
    816                     l = [obj[i].vector(), obj[j].vector()]

/projects/sage/sage-dev/src/sage/misc/cachefunc.pyx in
sage.misc.cachefunc.CachedMethodCallerNoArgs.__call__ (/projects/sage
/sage-dev/src/build/cythonized/sage/misc/cachefunc.c:13453)()
   2399         if self.cache is None:
   2400             f = self.f
-> 2401             self.cache = f(self._instance)
   2402         return self.cache
   2403

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/base.pyc in
vertex_adjacency_matrix(self)
   1933             (0, 0, 1, 1, 0) A vertex at (3, 0)
   1934         """
-> 1935         return self._vertex_adjacency_matrix()
   1936
   1937     adjacency_matrix = vertex_adjacency_matrix

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/base.pyc in
_vertex_adjacency_matrix(self)
    318             M[j, i] = 1
    319
--> 320         face_lattice = self.face_lattice()
    321         for face in face_lattice:
    322             Vrep = face.ambient_Vrepresentation()

/projects/sage/sage-dev/src/sage/misc/cachefunc.pyx in
sage.misc.cachefunc.CachedMethodCallerNoArgs.__call__ (/projects/sage
/sage-dev/src/build/cythonized/sage/misc/cachefunc.c:13453)()
   2399         if self.cache is None:
   2400             f = self.f
-> 2401             self.cache = f(self._instance)
   2402         return self.cache
   2403

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/polyhedron/base.pyc in face_lattice(self)
   3408         return Hasse_diagram_from_incidences\
   3409             (atoms_incidences, coatoms_incidences,
-> 3410              face_constructor=face_constructor,
required_atoms=atoms_vertices)
   3411
   3412     def faces(self, face_dimension):

/projects/sage/sage-dev/local/lib/python2.7/site-
packages/sage/geometry/hasse_diagram.pyc in
Hasse_diagram_from_incidences(atom_to_coatoms, coatom_to_atoms,
face_constructor, required_atoms, key, **kwds)
    180     # Make sure that coatoms are in the end in proper order
    181     tail = [faces[atoms, frozenset([coatom])]
--> 182             for coatom, atoms in enumerate(coatom_to_atoms)]
    183     tail.append(faces[A, frozenset()])
    184     new_order = [n for n in new_order if n not in tail] + tail

KeyError: (frozenset([]), frozenset([0]))
sage:
}}}

See public worksheet:
https://cloud.sagemath.com/projects/53b9d6b6-ce2c-4007-843a-
257cc01bf65b/files/Sara/Polygon%20Bug.sagews

URL: https://trac.sagemath.org/22552
Reported by: was
Ticket author(s): Jean-Philippe Labbé
Reviewer(s): Vincent Delecroix
  • Loading branch information
Release Manager authored and vbraun committed Sep 7, 2017
2 parents f6f2427 + 150c7df commit 52425f5
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 14 deletions.
70 changes: 60 additions & 10 deletions src/sage/geometry/polyhedron/constructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@
sage: Polyhedron([(0,0), (1,0), (1/2, sqrt(3)/2)])
Traceback (most recent call last):
...
ValueError: invalid base ring
ValueError: for polyhedra with floating point numbers, the only allowed ring is RDF with backend 'cdd'
sage: SR.is_exact()
False
Expand All @@ -199,6 +200,36 @@
A 2-dimensional polyhedron in (Number Field in sqrt3 with defining
polynomial x^2 - 3)^2 defined as the convex hull of 3 vertices
.. WARNING::
Be careful when you construct polyhedra with floating point numbers. The only
available backend for such computation is `cdd` which uses machine floating
point numbers which have have limited precision. If the input consists of
floating point numbers and the `base_ring` is not specified, the base ring is
set to be the `RealField` with the precision given by the minimal bit precision
of the input. Then, if the obtained minimum is 53 bits of precision, the
constructor converts automatically the base ring to `RDF`. Otherwise,
it returns an error::
sage: Polyhedron(vertices = [[1.12345678901234, 2.12345678901234]])
A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex
sage: Polyhedron(vertices = [[1.12345678901234, 2.123456789012345]])
A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex
sage: Polyhedron(vertices = [[1.123456789012345, 2.123456789012345]])
Traceback (most recent call last):
...
ValueError: for polyhedra with floating point numbers, the only allowed ring is RDF with backend 'cdd'
The strongly suggested method to input floating point numbers is to specify the
`base_ring` to be `RDF`::
sage: Polyhedron(vertices = [[1.123456789012345, 2.123456789012345]], base_ring=RDF)
A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex
.. SEEALSO::
:mod:`Parents for polyhedra <sage.geometry.polyhedron.parent.Polyhedra>`
Base classes
------------
Expand Down Expand Up @@ -443,6 +474,25 @@ def Polyhedron(vertices=None, rays=None, lines=None,
sage: f = Fraction(int(6), int(8))
sage: Polyhedron(vertices=[[f]])
A 0-dimensional polyhedron in QQ^1 defined as the convex hull of 1 vertex
Check that input with too many bits of precision returns an error (see
:trac:`22552`)::
sage: Polyhedron(vertices=[(8.3319544851638732, 7.0567045956967727), (6.4876921900819049, 4.8435898415984129)])
Traceback (most recent call last):
...
ValueError: for polyhedra with floating point numbers, the only allowed ring is RDF with backend 'cdd'
Check that setting ``base_ring`` to a ``RealField`` returns an error (see :trac:`22552`)::
sage: Polyhedron(vertices =[(8.3, 7.0), (6.4, 4.8)], base_ring=RealField(40))
Traceback (most recent call last):
...
ValueError: no appropriate backend for computations with Real Field with 40 bits of precision
sage: Polyhedron(vertices =[(8.3, 7.0), (6.4, 4.8)], base_ring=RealField(53))
Traceback (most recent call last):
...
ValueError: no appropriate backend for computations with Real Field with 53 bits of precision
"""
# Clean up the arguments
vertices = _make_listlist(vertices)
Expand Down Expand Up @@ -504,15 +554,16 @@ def Polyhedron(vertices=None, rays=None, lines=None,
base_ring = base_ring.fraction_field()
convert = True

# TODO: find a more robust way of checking that the coefficients are indeed
# real numbers
if base_ring not in Rings() or not RDF.has_coerce_map_from(base_ring):
raise ValueError("invalid base ring")
if base_ring not in Rings():
raise ValueError('invalid base ring')

# TODO: remove this hack
if base_ring is RR:
base_ring = RDF
convert = True
if not base_ring.is_exact():
# TODO: remove this hack?
if base_ring is RR:
base_ring = RDF
convert = True
elif base_ring is not RDF:
raise ValueError("for polyhedra with floating point numbers, the only allowed ring is RDF with backend 'cdd'")

# Add the origin if necessary
if got_Vrep and len(vertices)==0:
Expand All @@ -523,7 +574,6 @@ def Polyhedron(vertices=None, rays=None, lines=None,
parent = Polyhedra(base_ring, ambient_dim, backend=backend)
base_ring = parent.base_ring()


# finally, construct the Polyhedron
Hrep = Vrep = None
if got_Hrep:
Expand Down
10 changes: 6 additions & 4 deletions src/sage/geometry/polyhedron/parent.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,15 @@ def Polyhedra(base_ring, ambient_dim, backend=None):
ValueError: no appropriate backend for computations with Real Field with 53 bits of precision
"""
if backend is None:
if base_ring is ZZ:
backend = 'ppl'
elif base_ring is QQ:
if base_ring is ZZ or base_ring is QQ:
backend = 'ppl'
elif base_ring is RDF:
backend = 'cdd'
elif base_ring.is_exact():
# TODO: find a more robust way of checking that the coefficients are indeed
# real numbers
if not RDF.has_coerce_map_from(base_ring):
raise ValueError("invalid base ring")
backend = 'field'
else:
raise ValueError("no appropriate backend for computations with {}".format(base_ring))
Expand Down Expand Up @@ -378,7 +380,7 @@ def _repr_ambient_module(self):
sage: from sage.geometry.polyhedron.parent import Polyhedra
sage: Polyhedra(QQ, 3)._repr_ambient_module()
'QQ^3'
sage: K.<sqrt3> = NumberField(x^2-3)
sage: K.<sqrt3> = NumberField(x^2 - 3, embedding=AA(3).sqrt())
sage: Polyhedra(K, 4)._repr_ambient_module()
'(Number Field in sqrt3 with defining polynomial x^2 - 3)^4'
"""
Expand Down

0 comments on commit 52425f5

Please sign in to comment.