Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding alias in polytope, plus doc formatting #39810

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 48 additions & 45 deletions src/sage/geometry/lattice_polytope.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@

.. NOTE::

IMPORTANT: PALP requires some parameters to be determined during
compilation time, i.e., the maximum dimension of polytopes, the
maximum number of points, etc. These limitations may lead to errors
during calls to different functions of these module. Currently, a
:exc:`ValueError` exception will be raised if the output of ``poly.x``
or ``nef.x`` is empty or contains the exclamation mark. The error
message will contain the exact command that caused an error, the
description and vertices of the polytope, and the obtained output.
IMPORTANT: PALP requires some parameters to be determined during
compilation time, i.e., the maximum dimension of polytopes, the
maximum number of points, etc. These limitations may lead to errors
during calls to different functions of these module. Currently, a
:exc:`ValueError` exception will be raised if the output of ``poly.x``
or ``nef.x`` is empty or contains the exclamation mark. The error
message will contain the exact command that caused an error, the
description and vertices of the polytope, and the obtained output.

Data obtained from PALP and some other data is cached and most
returned values are immutable. In particular, you cannot change the
Expand Down Expand Up @@ -360,16 +360,16 @@ def ReflexivePolytope(dim, n):

.. NOTE::

#. Numeration starts with zero: `0 \leq n \leq 15` for `{\rm dim} = 2`
and `0 \leq n \leq 4318` for `{\rm dim} = 3`.
#. Numeration starts with zero: `0 \leq n \leq 15` for `{\rm dim} = 2`
and `0 \leq n \leq 4318` for `{\rm dim} = 3`.

#. During the first call, all reflexive polytopes of requested
dimension are loaded and cached for future use, so the first
call for 3-dimensional polytopes can take several seconds,
but all consecutive calls are fast.
#. During the first call, all reflexive polytopes of requested
dimension are loaded and cached for future use, so the first
call for 3-dimensional polytopes can take several seconds,
but all consecutive calls are fast.

#. Equivalent to ``ReflexivePolytopes(dim)[n]`` but checks bounds
first.
#. Equivalent to ``ReflexivePolytopes(dim)[n]`` but checks bounds
first.

EXAMPLES:

Expand Down Expand Up @@ -420,9 +420,9 @@ def ReflexivePolytopes(dim):

.. NOTE::

During the first call the database is loaded and cached for
future use, so repetitive calls will return the same object in
memory.
During the first call the database is loaded and cached for
future use, so repetitive calls will return the same object in
memory.

INPUT:

Expand Down Expand Up @@ -970,14 +970,14 @@ def _palp(self, command, reduce_dimension=False):
r"""
Run ``command`` on vertices of this polytope.

Returns the output of ``command`` as a string.
This returns the output of ``command`` as a string.

.. NOTE::

PALP cannot be called for polytopes that do not span the ambient space.
If you specify ``reduce_dimension=True`` argument, PALP will be
called for vertices of this polytope in some basis of the affine space
it spans.
PALP cannot be called for polytopes that do not span the
ambient space. If you specify ``reduce_dimension=True``
argument, PALP will be called for vertices of this
polytope in some basis of the affine space it spans.

TESTS::

Expand Down Expand Up @@ -1409,13 +1409,14 @@ def affine_transform(self, a=1, b=0):

.. NOTE::

#. While ``a`` and ``b`` may be rational, the final result must be a
lattice polytope, i.e. all vertices must be integral.
#. While ``a`` and ``b`` may be rational, the final result
must be a lattice polytope, i.e. all vertices must be integral.

#. If the transform (restricted to this polytope) is bijective, facial
structure will be preserved, e.g. the first facet of the image will
be spanned by the images of vertices which span the first facet of
the original polytope.
#. If the transform (restricted to this polytope) is
bijective, facial structure will be preserved, e.g. the
first facet of the image will be spanned by the images
of vertices which span the first facet of the original
polytope.

INPUT:

Expand Down Expand Up @@ -1496,6 +1497,8 @@ def affine_transform(self, a=1, b=0):
r._original = self
return r

linear_transformation = affine_transform

def ambient(self):
r"""
Return the ambient structure of ``self``.
Expand Down Expand Up @@ -2396,10 +2399,10 @@ def incidence_matrix(self):

.. NOTE::

The columns correspond to facets/facet normals
in the order of :meth:`facet_normals`, the rows
correspond to the vertices in the order of
:meth:`vertices`.
The columns correspond to facets/facet normals
in the order of :meth:`facet_normals`, the rows
correspond to the vertices in the order of
:meth:`vertices`.

EXAMPLES::

Expand Down Expand Up @@ -2450,9 +2453,9 @@ def index(self):

.. NOTE::

The first call to this function for each dimension can take
a few seconds while the dictionary of all polytopes is
constructed, but after that it is cached and fast.
The first call to this function for each dimension can take
a few seconds while the dictionary of all polytopes is
constructed, but after that it is cached and fast.

:rtype: integer

Expand Down Expand Up @@ -4972,15 +4975,15 @@ def _palp(command, polytopes, reduce_dimension=False):
Run ``command`` on vertices of given
``polytopes``.

Returns the name of the file containing the output of
This returns the name of the file containing the output of
``command``. You should delete it after using.

.. NOTE::

PALP cannot be called for polytopes that do not span the ambient space.
If you specify ``reduce_dimension=True`` argument, PALP will be
called for vertices of this polytope in some basis of the affine space
it spans.
PALP cannot be called for polytopes that do not span the
ambient space. If you specify ``reduce_dimension=True``
argument, PALP will be called for vertices of this polytope in
some basis of the affine space it spans.

TESTS::

Expand Down Expand Up @@ -5436,8 +5439,8 @@ def convex_hull(points):

.. NOTE::

``points`` might not span the space. Also, it fails for large
numbers of vertices in dimensions 4 or greater
``points`` might not span the space. Also, it fails for large
numbers of vertices in dimensions 4 or greater

INPUT:

Expand Down Expand Up @@ -5511,7 +5514,7 @@ def minkowski_sum(points1, points2):

.. NOTE::

Polytopes might not be of maximal dimension.
Polytopes might not be of maximal dimension.

INPUT:

Expand Down
27 changes: 20 additions & 7 deletions src/sage/geometry/polyhedron/base5.py
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,8 @@ def _test_dilation(self, tester=None, **options):
p = self.change_ring(new_ring)
tester.assertIsInstance(scalar*p, Polyhedron_base)

def linear_transformation(self, linear_transf, new_base_ring=None):
def linear_transformation(self, linear_transf,
new_base_ring=None):
"""
Return the linear transformation of ``self``.

Expand Down Expand Up @@ -1807,6 +1808,12 @@ def linear_transformation(self, linear_transf, new_base_ring=None):

TESTS:

One can scale by a scalar as follows::

sage: P = polytopes.simplex()
sage: P.linear_transformation(2)
A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices

Linear transformation respects backend::

sage: P = polytopes.simplex(backend='field')
Expand Down Expand Up @@ -1862,6 +1869,11 @@ def linear_transformation(self, linear_transf, new_base_ring=None):
True
"""
is_injective = False

if linear_transf in self.base_ring():
# allow for scalar input
linear_transf = linear_transf * self.ambient_vector_space().matrix()

if linear_transf.nrows() != 0:
if new_base_ring:
R = new_base_ring
Expand All @@ -1870,17 +1882,18 @@ def linear_transformation(self, linear_transf, new_base_ring=None):

# Multiplying a matrix with a vector is slow.
# So we multiply the entire vertex matrix etc.
# Still we create generators, as possibly the Vrepresentation will be discarded later on.
# Still we create generators, as possibly the Vrepresentation
# will be discarded later on.
if self.n_vertices():
new_vertices = ( v for v in ((linear_transf*self.vertices_matrix(R)).transpose()) )
new_vertices = iter((linear_transf*self.vertices_matrix(R)).transpose())
else:
new_vertices = ()
if self.n_rays():
new_rays = ( r for r in matrix(R, self.rays())*linear_transf.transpose() )
new_rays = iter(matrix(R, self.rays())*linear_transf.transpose())
else:
new_rays = ()
if self.n_lines():
new_lines = ( l for l in matrix(R, self.lines())*linear_transf.transpose() )
new_lines = iter(matrix(R, self.lines())*linear_transf.transpose())
else:
new_lines = ()

Expand All @@ -1906,14 +1919,14 @@ def linear_transformation(self, linear_transf, new_base_ring=None):
# Note that such N must exist, as our map is injective on the polytope.
# It is uniquely defined by considering a basis of the homogeneous vertices.
N = new_homogeneous_basis.solve_left(homogeneous_basis)
new_inequalities = ( h for h in matrix(R, self.inequalities())*N )
new_inequalities = iter(matrix(R, self.inequalities())*N)

# The equations are the left kernel matrix of the homogeneous vertices
# or equivalently a basis thereof.
new_equations = (new_homogeneous_basis.transpose()).right_kernel_matrix()

else:
new_vertices = [[] for v in self.vertex_generator() ]
new_vertices = [[] for v in self.vertex_generator()]
new_rays = []
new_lines = []

Expand Down
Loading