Ejemplo n.º 1
0
    def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbose=False):
        r"""
        Construct polyhedron from V-representation data.

        INPUT:

        - ``vertices`` -- list of point; each point can be specified
           as any iterable container of
           :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``rays`` -- list of rays; each ray can be specified as any
          iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``lines`` -- list of lines; each line can be specified as
          any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``verbose`` -- boolean (default: ``False``); whether to print
          verbose output for debugging purposes

        EXAMPLES::

            sage: p = Polyhedron(backend='polymake')                       # optional - polymake
            sage: from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake   # optional - polymake
            sage: Polyhedron_polymake._init_from_Vrepresentation(p, [], [], [])   # optional - polymake
        """
        from sage.interfaces.polymake import polymake
        polymake_field = polymake(self.base_ring().fraction_field())
        p = polymake.new_object("Polytope<{}>".format(polymake_field),
                                CONE_AMBIENT_DIM=1+self.parent().ambient_dim(),
                                POINTS=  [ [1] + v for v in vertices ] \
                                       + [ [0] + r for r in rays ],
                                INPUT_LINEALITY=[ [0] + l for l in lines ])
        self._init_from_polymake_polytope(p)
Ejemplo n.º 2
0
    def _init_from_Hrepresentation(self,
                                   ieqs,
                                   eqns,
                                   minimize=True,
                                   verbose=False):
        r"""
        Construct polyhedron from H-representation data.

        INPUT:

        - ``ieqs`` -- list of inequalities; each line can be specified
          as any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``eqns`` -- list of equalities; each line can be specified
          as any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``minimize`` -- boolean (default: ``True``); ignored

        - ``verbose`` -- boolean (default: ``False``); whether to print
          verbose output for debugging purposes

        EXAMPLES::

            sage: p = Polyhedron(backend='polymake')                       # optional - polymake
            sage: from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake   # optional - polymake
            sage: Polyhedron_polymake._init_from_Hrepresentation(p, [], [])   # optional - polymake
        """
        from sage.interfaces.polymake import polymake
        data = self._polymake_Hrepresentation_data(ieqs, eqns)
        polymake_field = polymake(self.base_ring().fraction_field())
        p = polymake.new_object("Polytope<{}>".format(polymake_field), **data)
        self._init_from_polymake_polytope(p)
Ejemplo n.º 3
0
    def _init_from_Hrepresentation(self,
                                   ieqs,
                                   eqns,
                                   minimize=True,
                                   verbose=False):
        r"""
        Construct polyhedron from H-representation data.

        INPUT:

        - ``ieqs`` -- list of inequalities; each line can be specified
          as any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``eqns`` -- list of equalities; each line can be specified
          as any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``minimize`` -- boolean (default: ``True``); ignored

        - ``verbose`` -- boolean (default: ``False``); whether to print
          verbose output for debugging purposes

        EXAMPLES::

            sage: p = Polyhedron(backend='polymake')                       # optional - polymake
            sage: from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake   # optional - polymake
            sage: Polyhedron_polymake._init_from_Hrepresentation(p, [], [])   # optional - polymake
        """
        from sage.interfaces.polymake import polymake
        if ieqs is None: ieqs = []
        if eqns is None: eqns = []
        # Polymake 3.0r2 and 3.1 crash with a segfault for a test case
        # using QuadraticExtension, when some all-zero inequalities are input.
        # https://forum.polymake.org/viewtopic.php?f=8&t=547
        # Filter them out.
        ieqs = [v for v in ieqs if not all(self._is_zero(x) for x in v)]
        # We do a similar filtering for equations.
        # Since Polymake 3.2, we can not give all zero vectors in equations
        eqns = [v for v in eqns if not all(self._is_zero(x) for x in v)]
        if not ieqs:
            # Put in one trivial (all-zero) inequality.  This is so that
            # the ambient dimension is set correctly.
            # Since Polymake 3.2, the constant should not be zero.
            ieqs.append([1] + [0] * self.ambient_dim())
        polymake_field = polymake(self.base_ring().fraction_field())
        p = polymake.new_object("Polytope<{}>".format(polymake_field),
                                EQUATIONS=eqns,
                                INEQUALITIES=ieqs)
        self._init_from_polymake_polytope(p)
Ejemplo n.º 4
0
    def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True, verbose=False):
        r"""
        Construct polyhedron from H-representation data.

        INPUT:

        - ``ieqs`` -- list of inequalities; each line can be specified
          as any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``eqns`` -- list of equalities; each line can be specified
          as any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``minimize`` -- boolean (default: ``True``); ignored

        - ``verbose`` -- boolean (default: ``False``); whether to print
          verbose output for debugging purposes

        EXAMPLES::

            sage: p = Polyhedron(backend='polymake')                       # optional - polymake
            sage: from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake   # optional - polymake
            sage: Polyhedron_polymake._init_from_Hrepresentation(p, [], [])   # optional - polymake
        """
        from sage.interfaces.polymake import polymake
        if ieqs is None: ieqs = []
        if eqns is None: eqns = []
        # Polymake 3.0r2 and 3.1 crash with a segfault for a test case
        # using QuadraticExtension, when some all-zero inequalities are input.
        # https://forum.polymake.org/viewtopic.php?f=8&t=547
        # Filter them out.
        ieqs = [ v for v in ieqs if not all(self._is_zero(x) for x in v) ]
        if not ieqs:
            # Put in one trivial (all-zero) inequality.  This is so that
            # the ambient dimension is set correctly.
            ieqs.append([0] + [0]*self.ambient_dim())
        polymake_field = polymake(self.base_ring().fraction_field())
        p = polymake.new_object("Polytope<{}>".format(polymake_field),
                                EQUATIONS=eqns,
                                INEQUALITIES=ieqs)
        self._init_from_polymake_polytope(p)
Ejemplo n.º 5
0
    def _init_from_Vrepresentation(self,
                                   vertices,
                                   rays,
                                   lines,
                                   minimize=True,
                                   verbose=False):
        r"""
        Construct polyhedron from V-representation data.

        INPUT:

        - ``vertices`` -- list of point; each point can be specified
           as any iterable container of
           :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``rays`` -- list of rays; each ray can be specified as any
          iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``lines`` -- list of lines; each line can be specified as
          any iterable container of
          :meth:`~sage.geometry.polyhedron.base.base_ring` elements

        - ``verbose`` -- boolean (default: ``False``); whether to print
          verbose output for debugging purposes

        EXAMPLES::

            sage: p = Polyhedron(backend='polymake')                       # optional - polymake
            sage: from sage.geometry.polyhedron.backend_polymake import Polyhedron_polymake   # optional - polymake
            sage: Polyhedron_polymake._init_from_Vrepresentation(p, [], [], [])   # optional - polymake
        """
        from sage.interfaces.polymake import polymake
        polymake_field = polymake(self.base_ring().fraction_field())
        p = polymake.new_object("Polytope<{}>".format(polymake_field),
                                CONE_AMBIENT_DIM=1+self.parent().ambient_dim(),
                                POINTS=  [ [1] + v for v in vertices ] \
                                       + [ [0] + r for r in rays ],
                                INPUT_LINEALITY=[ [0] + l for l in lines ])
        self._init_from_polymake_polytope(p)
Ejemplo n.º 6
0
    def _polymake_polytope_from_Vrepresentation_and_Hrepresentation(
            self, Vrep, Hrep):
        if not any(Vrep):
            # The empty polyhedron.
            return

        from sage.interfaces.polymake import polymake
        data = self._polymake_Vrepresentation_data(*Vrep, minimal=True)

        if any(Vrep[1:]):
            from sage.matrix.constructor import Matrix
            polymake_rays = [r for r in data['VERTICES'] if r[0] == 0]
            if Matrix(data['VERTICES']).rank(
            ) == Matrix(polymake_rays).rank() + 1:
                # The recession cone is full-dimensional.
                # In this case the homogenized inequalities
                # do not ensure nonnegativy in the last coordinate.
                # In the homogeneous cone the far face is a facet.
                Hrep[0] += [[1] + [0] * self.ambient_dim()]
        data.update(self._polymake_Hrepresentation_data(*Hrep, minimal=True))

        polymake_field = polymake(self.base_ring().fraction_field())
        return polymake.new_object("Polytope<{}>".format(polymake_field),
                                   **data)
Ejemplo n.º 7
0
def Polyhedra(ambient_space_or_base_ring=None,
              ambient_dim=None,
              backend=None,
              *,
              ambient_space=None,
              base_ring=None):
    r"""
    Construct a suitable parent class for polyhedra

    INPUT:

    - ``base_ring`` -- A ring. Currently there are backends for `\ZZ`,
      `\QQ`, and `\RDF`.

    - ``ambient_dim`` -- integer. The ambient space dimension.

    - ``ambient_space`` -- A free module.

    - ``backend`` -- string. The name of the backend for computations. There are
       several backends implemented:

         * ``backend="ppl"`` uses the Parma Polyhedra Library

         * ``backend="cdd"`` uses CDD

         * ``backend="normaliz"`` uses normaliz

         * ``backend="polymake"`` uses polymake

         * ``backend="field"`` a generic Sage implementation

    OUTPUT:

    A parent class for polyhedra over the given base ring if the
    backend supports it. If not, the parent base ring can be larger
    (for example, `\QQ` instead of `\ZZ`). If there is no
    implementation at all, a ``ValueError`` is raised.

    EXAMPLES::

        sage: from sage.geometry.polyhedron.parent import Polyhedra
        sage: Polyhedra(AA, 3)
        Polyhedra in AA^3
        sage: Polyhedra(ZZ, 3)
        Polyhedra in ZZ^3
        sage: type(_)
        <class 'sage.geometry.polyhedron.parent.Polyhedra_ZZ_ppl_with_category'>
        sage: Polyhedra(QQ, 3, backend='cdd')
        Polyhedra in QQ^3
        sage: type(_)
        <class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_cdd_with_category'>

    CDD does not support integer polytopes directly::

        sage: Polyhedra(ZZ, 3, backend='cdd')
        Polyhedra in QQ^3

    Using a more general form of the constructor::

        sage: V = VectorSpace(QQ, 3)
        sage: Polyhedra(V) is Polyhedra(QQ, 3)
        True
        sage: Polyhedra(V, backend='field') is Polyhedra(QQ, 3, 'field')
        True
        sage: Polyhedra(backend='field', ambient_space=V) is Polyhedra(QQ, 3, 'field')
        True

        sage: M = FreeModule(ZZ, 2)
        sage: Polyhedra(M, backend='ppl') is Polyhedra(ZZ, 2, 'ppl')
        True

    TESTS::

        sage: Polyhedra(RR, 3, backend='field')
        Traceback (most recent call last):
        ...
        ValueError: the 'field' backend for polyhedron cannot be used with non-exact fields
        sage: Polyhedra(RR, 3)
        Traceback (most recent call last):
        ...
        ValueError: no default backend for computations with Real Field with 53 bits of precision
        sage: Polyhedra(QQ[I], 2)
        Traceback (most recent call last):
        ...
        ValueError: invalid base ring: Number Field in I with defining polynomial x^2 + 1 with I = 1*I cannot be coerced to a real field
        sage: Polyhedra(AA, 3, backend='polymake')  # optional - polymake
        Traceback (most recent call last):
        ...
        ValueError: the 'polymake' backend for polyhedron cannot be used with Algebraic Real Field

        sage: Polyhedra(QQ, 2, backend='normaliz')   # optional - pynormaliz
        Polyhedra in QQ^2
        sage: Polyhedra(SR, 2, backend='normaliz')   # optional - pynormaliz  # optional - sage.symbolic
        Polyhedra in (Symbolic Ring)^2
        sage: SCR = SR.subring(no_variables=True)                             # optional - sage.symbolic
        sage: Polyhedra(SCR, 2, backend='normaliz')  # optional - pynormaliz  # optional - sage.symbolic
        Polyhedra in (Symbolic Constants Subring)^2
    """
    if ambient_space_or_base_ring is not None:
        if ambient_space_or_base_ring in Rings():
            base_ring = ambient_space_or_base_ring
        else:
            ambient_space = ambient_space_or_base_ring
    if ambient_space is not None:
        if ambient_space not in Modules:
            # There is no category of free modules, unfortunately
            # (see https://trac.sagemath.org/ticket/30164)...
            raise ValueError('ambient_space must be a free module')
        if base_ring is None:
            base_ring = ambient_space.base_ring()
        if ambient_dim is None:
            try:
                ambient_dim = ambient_space.rank()
            except AttributeError:
                # ... so we test whether it is free using the existence of
                # a rank method
                raise ValueError('ambient_space must be a free module')
        if ambient_space is not FreeModule(base_ring, ambient_dim):
            raise NotImplementedError(
                'ambient_space must be a standard free module')
    if backend is None:
        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: {} cannot be coerced to a real field".
                    format(base_ring))
            backend = 'field'
        else:
            raise ValueError(
                "no default backend for computations with {}".format(
                    base_ring))

    try:
        from sage.symbolic.ring import SR
    except ImportError:
        SR = None
    if backend == 'ppl' and base_ring is QQ:
        return Polyhedra_QQ_ppl(base_ring, ambient_dim, backend)
    elif backend == 'ppl' and base_ring is ZZ:
        return Polyhedra_ZZ_ppl(base_ring, ambient_dim, backend)
    elif backend == 'normaliz' and base_ring is QQ:
        return Polyhedra_QQ_normaliz(base_ring, ambient_dim, backend)
    elif backend == 'normaliz' and base_ring is ZZ:
        return Polyhedra_ZZ_normaliz(base_ring, ambient_dim, backend)
    elif backend == 'normaliz' and (isinstance(
            base_ring, sage.rings.abc.SymbolicRing) or base_ring.is_exact()):
        return Polyhedra_normaliz(base_ring, ambient_dim, backend)
    elif backend == 'cdd' and base_ring in (ZZ, QQ):
        return Polyhedra_QQ_cdd(QQ, ambient_dim, backend)
    elif backend == 'cdd' and base_ring is RDF:
        return Polyhedra_RDF_cdd(RDF, ambient_dim, backend)
    elif backend == 'polymake':
        base_field = base_ring.fraction_field()
        try:
            from sage.interfaces.polymake import polymake
            polymake_base_field = polymake(base_field)
        except TypeError:
            raise ValueError(
                f"the 'polymake' backend for polyhedron cannot be used with {base_field}"
            )
        return Polyhedra_polymake(base_field, ambient_dim, backend)
    elif backend == 'field':
        if not base_ring.is_exact():
            raise ValueError(
                "the 'field' backend for polyhedron cannot be used with non-exact fields"
            )
        return Polyhedra_field(base_ring.fraction_field(), ambient_dim,
                               backend)
    else:
        raise ValueError('No such backend (=' + str(backend) +
                         ') implemented for given basering (=' +
                         str(base_ring) + ').')