Commits (1)
......@@ -24,10 +24,12 @@ from sage.geometry.polyhedron.backend_normaliz import Polyhedron_QQ_normaliz
from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd
from sage.geometry.polyhedron.backend_field import Polyhedron_field
from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake
from sage.geometry.polyhedron.parent import Polyhedra_QQ_ppl, Polyhedra_QQ_normaliz, Polyhedra_QQ_cdd, Polyhedra_polymake, Polyhedra_field
from sage.geometry.polyhedron.parent import Polyhedra, Polyhedra_base, Polyhedra_QQ_ppl, Polyhedra_QQ_normaliz, Polyhedra_QQ_cdd, Polyhedra_polymake, Polyhedra_field
from sage.combinat.root_system.cartan_type import CartanType
from sage.modules.free_module_element import vector
from sage.rings.all import QQ
from sage.rings.all import QQ, ZZ
ancestors_of_associahedron = [Polyhedron_QQ_ppl, Polyhedron_QQ_normaliz, Polyhedron_QQ_cdd, Polyhedron_field, Polyhedron_polymake]
def Associahedron(cartan_type, backend='ppl'):
......@@ -138,6 +140,82 @@ class Associahedron_class_base(object):
Generalized associahedron of type ['A', 2] with 5 vertices
sage: TestSuite(Asso).run()
"""
def __new__(typ, parent=None, Vrep=None, Hrep=None, cartan_type=None, **kwds):
r"""
Return instance of :class:`Assciahedron_class_base`, if ``cartan_type`` is provided
or object is being unpickled.
In other cases, this call is a result of a polyhedral construction with an associahedron.
Thus we return the corresponding instance of
:class:`sage.geometry.polyhedron.base.Polyhedron_base` (not an associahedron).
TESTS:
Check that faces of associahedra work::
sage: A = polytopes.associahedron(['A',3], backend='ppl'); A
Generalized associahedron of type ['A', 3] with 14 vertices
sage: face = A.faces(2)[3]
sage: P = face.as_polyhedron(); P
A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
sage: P.backend()
'ppl'
sage: A = polytopes.associahedron(['A',3], backend='field'); A
Generalized associahedron of type ['A', 3] with 14 vertices
sage: A.faces(2)[3].as_polyhedron().backend()
'field'
Check other polytopal constructions::
sage: A = polytopes.associahedron(['A',4], backend='ppl')
sage: A + A
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
sage: A - A
A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex
sage: A.intersection(A)
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
sage: A.translation(A.center())
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
sage: A.dilation(2)
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
sage: A.dilation(2.0)
A 4-dimensional polyhedron in RDF^4 defined as the convex hull of 42 vertices
sage: A.convex_hull(A)
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
sage: A.polar()
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 14 vertices
"""
if cartan_type or (parent is None and Vrep is None and Hrep is None):
# Called from element constructor in ``Associahedron_base``.
# Alternatively called from ``loads`` in in ``loads(dumps(...))``.
return super(Associahedron_class_base, typ).__new__(typ, parent, Vrep, Hrep, **kwds)
else:
# Not called from element constructor in ``Associahedron_base``.
# Return a polyhedron with proper backend (not an associahedron).
# Thus e.g. a face of an Associahedron can be initialized as a polyhedron.
mro = typ.mro()
for typ1 in ancestors_of_associahedron:
if typ1 in mro:
return typ1(parent, Vrep, Hrep, **kwds)
raise ValueError("could not determine a parent class")
def __init__(self, parent, Vrep, Hrep, cartan_type=None, **kwds):
r"""
Initialize an associahedron.
If ``'cartan_type'`` is ``None``, :meth:`Associahedron_class_base.__new__`
returns a (general) polyhedron instead.
TESTS::
sage: A = polytopes.associahedron(['A',3], backend='ppl'); A
Generalized associahedron of type ['A', 3] with 14 vertices
"""
if cartan_type:
self._cartan_type = cartan_type
super(Associahedron_class_base, self).__init__(parent, Vrep, Hrep, **kwds)
else:
raise ValueError("associahedron must be initialized with cartan type")
def _repr_(self):
r"""
......@@ -258,7 +336,6 @@ class Associahedra_base(object):
...
ValueError: V-representation data requires a list of length ambient_dim
"""
def _element_constructor_(self, cartan_type, **kwds):
"""
The element constructor.
......@@ -296,10 +373,75 @@ class Associahedra_base(object):
c = rhocheck.coefficient(orbit[0].leading_support())
for beta in orbit:
inequalities.append([c] + [beta.coefficient(i) for i in I])
associahedron = super(Associahedra_base, self)._element_constructor_(None, [inequalities, []])
associahedron._cartan_type = cartan_type
associahedron = super(Associahedra_base, self)._element_constructor_(None, [inequalities, []], cartan_type=cartan_type)
return associahedron
def _coerce_map_from_(self, X):
r"""
Return whether there is a coercion from ``X``
INPUT:
- ``X`` -- anything.
OUTPUT:
Boolean.
EXAMPLES::
sage: from sage.geometry.polyhedron.parent import Polyhedra
sage: from sage.combinat.root_system.associahedron import Associahedra
sage: Associahedra(QQ,3).has_coerce_map_from( Polyhedra(QQ,3) ) # indirect doctest
False
sage: Polyhedra(QQ,3).has_coerce_map_from( Associahedra(QQ,3) )
True
TESTS::
sage: A = polytopes.associahedron(['A',4], backend='ppl'); type(A.parent())
<class 'sage.combinat.root_system.associahedron.Associahedra_ppl_with_category'>
sage: B = polytopes.simplex().change_ring(QQ); type(B.parent())
<class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_ppl_with_category'>
sage: A + B
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 70 vertices
sage: A - B
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 24 vertices
sage: A.intersection(B)
A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices
sage: A.convex_hull(B)
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
"""
if not isinstance(X, Associahedra_base):
return False
return super(Associahedra_base, self)._coerce_map_from_(X)
def _pushout_(self, other):
r"""
The pushout of Polyhedra over ZZ and Associahedra over QQ is Polyhedra over QQ.
TESTS::
sage: A = polytopes.associahedron(['A',4], backend='ppl'); type(A.parent())
<class 'sage.combinat.root_system.associahedron.Associahedra_ppl_with_category'>
sage: B = polytopes.simplex(); type(B.parent())
<class 'sage.geometry.polyhedron.parent.Polyhedra_ZZ_ppl_with_category'>
sage: A + B
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 70 vertices
sage: A - B
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 24 vertices
sage: A.intersection(B)
A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices
sage: A.convex_hull(B)
A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 42 vertices
"""
if isinstance(other, Polyhedra_base) and other.base_ring() == ZZ:
return Polyhedra(QQ, self.ambient_dim(), self.backend())
# Call the overwritten pushout in case it exists.
if hasattr(super(Associahedra_base, self), '_pushout_'):
return super(Associahedra_base, self)._pushout_(other)
class Associahedra_ppl(Associahedra_base, Polyhedra_QQ_ppl):
Element = Associahedron_class_ppl
......
......@@ -629,7 +629,7 @@ class Polyhedra_base(UniqueRepresentation, Parent):
def _coerce_base_ring(self, other):
r"""
Return the common base rincg for both ``self`` and ``other``.
Return the common base ring for both ``self`` and ``other``.
This method is not part of the coercion framework, but only a
convenience function for :class:`Polyhedra_base`.
......