passagemath-polyhedra 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-polyhedra might be problematic. Click here for more details.
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +208 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_polyhedra.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_polyhedra.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_polyhedra.libs/libgomp-1ede7ee7.so.1.0.0 +0 -0
- passagemath_polyhedra.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_polyhedra.py +50 -0
- sage/game_theory/all.py +8 -0
- sage/game_theory/catalog.py +6 -0
- sage/game_theory/catalog_normal_form_games.py +923 -0
- sage/game_theory/cooperative_game.py +844 -0
- sage/game_theory/matching_game.py +1181 -0
- sage/game_theory/normal_form_game.py +2697 -0
- sage/game_theory/parser.py +275 -0
- sage/geometry/all__sagemath_polyhedra.py +22 -0
- sage/geometry/cone.py +6940 -0
- sage/geometry/cone_catalog.py +847 -0
- sage/geometry/cone_critical_angles.py +1027 -0
- sage/geometry/convex_set.py +1119 -0
- sage/geometry/fan.py +3743 -0
- sage/geometry/fan_isomorphism.py +389 -0
- sage/geometry/fan_morphism.py +1884 -0
- sage/geometry/hasse_diagram.py +202 -0
- sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
- sage/geometry/hyperplane_arrangement/all.py +1 -0
- sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
- sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
- sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
- sage/geometry/hyperplane_arrangement/library.py +825 -0
- sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
- sage/geometry/hyperplane_arrangement/plot.py +520 -0
- sage/geometry/integral_points.py +35 -0
- sage/geometry/integral_points_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/integral_points_generic_dense.pyx +7 -0
- sage/geometry/lattice_polytope.py +5894 -0
- sage/geometry/linear_expression.py +773 -0
- sage/geometry/newton_polygon.py +767 -0
- sage/geometry/point_collection.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/point_collection.pyx +1008 -0
- sage/geometry/polyhedral_complex.py +2616 -0
- sage/geometry/polyhedron/all.py +8 -0
- sage/geometry/polyhedron/backend_cdd.py +460 -0
- sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
- sage/geometry/polyhedron/backend_field.py +347 -0
- sage/geometry/polyhedron/backend_normaliz.py +2503 -0
- sage/geometry/polyhedron/backend_number_field.py +168 -0
- sage/geometry/polyhedron/backend_polymake.py +765 -0
- sage/geometry/polyhedron/backend_ppl.py +582 -0
- sage/geometry/polyhedron/base.py +1206 -0
- sage/geometry/polyhedron/base0.py +1444 -0
- sage/geometry/polyhedron/base1.py +886 -0
- sage/geometry/polyhedron/base2.py +812 -0
- sage/geometry/polyhedron/base3.py +1845 -0
- sage/geometry/polyhedron/base4.py +1262 -0
- sage/geometry/polyhedron/base5.py +2700 -0
- sage/geometry/polyhedron/base6.py +1741 -0
- sage/geometry/polyhedron/base7.py +997 -0
- sage/geometry/polyhedron/base_QQ.py +1258 -0
- sage/geometry/polyhedron/base_RDF.py +98 -0
- sage/geometry/polyhedron/base_ZZ.py +934 -0
- sage/geometry/polyhedron/base_mutable.py +215 -0
- sage/geometry/polyhedron/base_number_field.py +122 -0
- sage/geometry/polyhedron/cdd_file_format.py +155 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
- sage/geometry/polyhedron/constructor.py +773 -0
- sage/geometry/polyhedron/double_description.py +753 -0
- sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
- sage/geometry/polyhedron/face.py +1060 -0
- sage/geometry/polyhedron/generating_function.py +1810 -0
- sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
- sage/geometry/polyhedron/library.py +3502 -0
- sage/geometry/polyhedron/misc.py +121 -0
- sage/geometry/polyhedron/modules/all.py +1 -0
- sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
- sage/geometry/polyhedron/palp_database.py +447 -0
- sage/geometry/polyhedron/parent.py +1279 -0
- sage/geometry/polyhedron/plot.py +1986 -0
- sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
- sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
- sage/geometry/polyhedron/representation.py +1723 -0
- sage/geometry/pseudolines.py +515 -0
- sage/geometry/relative_interior.py +445 -0
- sage/geometry/toric_plotter.py +1103 -0
- sage/geometry/triangulation/all.py +2 -0
- sage/geometry/triangulation/base.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/triangulation/base.pyx +963 -0
- sage/geometry/triangulation/data.h +147 -0
- sage/geometry/triangulation/data.pxd +4 -0
- sage/geometry/triangulation/element.py +914 -0
- sage/geometry/triangulation/functions.h +10 -0
- sage/geometry/triangulation/functions.pxd +4 -0
- sage/geometry/triangulation/point_configuration.py +2256 -0
- sage/geometry/triangulation/triangulations.h +49 -0
- sage/geometry/triangulation/triangulations.pxd +7 -0
- sage/geometry/voronoi_diagram.py +319 -0
- sage/interfaces/all__sagemath_polyhedra.py +1 -0
- sage/interfaces/polymake.py +2028 -0
- sage/numerical/all.py +13 -0
- sage/numerical/all__sagemath_polyhedra.py +11 -0
- sage/numerical/backends/all.py +1 -0
- sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
- sage/numerical/backends/cvxopt_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_backend.pyx +1006 -0
- sage/numerical/backends/cvxopt_backend_test.py +19 -0
- sage/numerical/backends/cvxopt_sdp_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
- sage/numerical/backends/cvxpy_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/cvxpy_backend.pxd +41 -0
- sage/numerical/backends/cvxpy_backend.pyx +934 -0
- sage/numerical/backends/cvxpy_backend_test.py +13 -0
- sage/numerical/backends/generic_backend_test.py +24 -0
- sage/numerical/backends/interactivelp_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/interactivelp_backend.pxd +36 -0
- sage/numerical/backends/interactivelp_backend.pyx +1231 -0
- sage/numerical/backends/interactivelp_backend_test.py +12 -0
- sage/numerical/backends/logging_backend.py +391 -0
- sage/numerical/backends/matrix_sdp_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
- sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
- sage/numerical/backends/ppl_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/ppl_backend.pyx +1126 -0
- sage/numerical/backends/ppl_backend_test.py +13 -0
- sage/numerical/backends/scip_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/scip_backend.pxd +22 -0
- sage/numerical/backends/scip_backend.pyx +1289 -0
- sage/numerical/backends/scip_backend_test.py +13 -0
- sage/numerical/interactive_simplex_method.py +5338 -0
- sage/numerical/knapsack.py +665 -0
- sage/numerical/linear_functions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/linear_functions.pxd +31 -0
- sage/numerical/linear_functions.pyx +1648 -0
- sage/numerical/linear_tensor.py +470 -0
- sage/numerical/linear_tensor_constraints.py +448 -0
- sage/numerical/linear_tensor_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/linear_tensor_element.pxd +6 -0
- sage/numerical/linear_tensor_element.pyx +459 -0
- sage/numerical/mip.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/mip.pxd +40 -0
- sage/numerical/mip.pyx +3667 -0
- sage/numerical/sdp.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/sdp.pxd +39 -0
- sage/numerical/sdp.pyx +1433 -0
- sage/rings/all__sagemath_polyhedra.py +3 -0
- sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
- sage/rings/polynomial/omega.py +982 -0
- sage/schemes/all__sagemath_polyhedra.py +2 -0
- sage/schemes/toric/all.py +10 -0
- sage/schemes/toric/chow_group.py +1248 -0
- sage/schemes/toric/divisor.py +2082 -0
- sage/schemes/toric/divisor_class.cpython-314-aarch64-linux-musl.so +0 -0
- sage/schemes/toric/divisor_class.pyx +322 -0
- sage/schemes/toric/fano_variety.py +1606 -0
- sage/schemes/toric/homset.py +650 -0
- sage/schemes/toric/ideal.py +451 -0
- sage/schemes/toric/library.py +1322 -0
- sage/schemes/toric/morphism.py +1958 -0
- sage/schemes/toric/points.py +1032 -0
- sage/schemes/toric/sheaf/all.py +1 -0
- sage/schemes/toric/sheaf/constructor.py +302 -0
- sage/schemes/toric/sheaf/klyachko.py +921 -0
- sage/schemes/toric/toric_subscheme.py +905 -0
- sage/schemes/toric/variety.py +3460 -0
- sage/schemes/toric/weierstrass.py +1078 -0
- sage/schemes/toric/weierstrass_covering.py +457 -0
- sage/schemes/toric/weierstrass_higher.py +288 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
|
@@ -0,0 +1,1008 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
r"""
|
|
3
|
+
Point collections
|
|
4
|
+
|
|
5
|
+
This module was designed as a part of framework for toric varieties
|
|
6
|
+
(:mod:`~sage.schemes.toric.variety`,
|
|
7
|
+
:mod:`~sage.schemes.toric.fano_variety`).
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Andrey Novoseltsev (2011-04-25): initial version, based on cone module.
|
|
12
|
+
|
|
13
|
+
- Andrey Novoseltsev (2012-03-06): additions and doctest changes while
|
|
14
|
+
switching cones to use point collections.
|
|
15
|
+
|
|
16
|
+
EXAMPLES:
|
|
17
|
+
|
|
18
|
+
The idea behind :class:`point collections <PointCollection>` is to have a
|
|
19
|
+
container for points of the same space that
|
|
20
|
+
|
|
21
|
+
* behaves like a tuple *without significant performance penalty*::
|
|
22
|
+
|
|
23
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
24
|
+
sage: c[1]
|
|
25
|
+
N(1, 0, 1)
|
|
26
|
+
sage: for point in c: point
|
|
27
|
+
N(0, 0, 1)
|
|
28
|
+
N(1, 0, 1)
|
|
29
|
+
N(0, 1, 1)
|
|
30
|
+
N(1, 1, 1)
|
|
31
|
+
|
|
32
|
+
* prints in a convenient way and with clear indication of the ambient space::
|
|
33
|
+
|
|
34
|
+
sage: c
|
|
35
|
+
N(0, 0, 1),
|
|
36
|
+
N(1, 0, 1),
|
|
37
|
+
N(0, 1, 1),
|
|
38
|
+
N(1, 1, 1)
|
|
39
|
+
in 3-d lattice N
|
|
40
|
+
|
|
41
|
+
* allows (cached) access to alternative representations::
|
|
42
|
+
|
|
43
|
+
sage: c.set()
|
|
44
|
+
frozenset({N(0, 0, 1), N(0, 1, 1), N(1, 0, 1), N(1, 1, 1)})
|
|
45
|
+
|
|
46
|
+
* allows introduction of additional methods::
|
|
47
|
+
|
|
48
|
+
sage: c.basis()
|
|
49
|
+
N(0, 0, 1),
|
|
50
|
+
N(1, 0, 1),
|
|
51
|
+
N(0, 1, 1)
|
|
52
|
+
in 3-d lattice N
|
|
53
|
+
|
|
54
|
+
Examples of natural point collections include ray and line generators of cones,
|
|
55
|
+
vertices and points of polytopes, normals to facets, their subcollections, etc.
|
|
56
|
+
|
|
57
|
+
Using this class for all of the above cases allows for unified interface *and*
|
|
58
|
+
cache sharing. Suppose that `\Delta` is a reflexive polytope. Then the same
|
|
59
|
+
point collection can be linked as
|
|
60
|
+
|
|
61
|
+
#. vertices of `\Delta`;
|
|
62
|
+
#. facet normals of its polar `\Delta^\circ`;
|
|
63
|
+
#. ray generators of the face fan of `\Delta`;
|
|
64
|
+
#. ray generators of the normal fan of `\Delta`.
|
|
65
|
+
|
|
66
|
+
If all these objects are in use and, say, a matrix representation was computed
|
|
67
|
+
for one of them, it becomes available to all others as well, eliminating the
|
|
68
|
+
need to spend time and memory four times.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
# ***************************************************************************
|
|
72
|
+
# Copyright (C) 2012 Andrey Novoseltsev <novoselt@gmail.com>
|
|
73
|
+
#
|
|
74
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
75
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
76
|
+
# the License, or (at your option) any later version.
|
|
77
|
+
# https://www.gnu.org/licenses/
|
|
78
|
+
# ***************************************************************************
|
|
79
|
+
|
|
80
|
+
from sage.structure.sage_object cimport SageObject
|
|
81
|
+
from sage.structure.richcmp cimport richcmp_not_equal, richcmp
|
|
82
|
+
|
|
83
|
+
from sage.geometry.toric_lattice import ToricLattice
|
|
84
|
+
from sage.matrix.constructor import matrix
|
|
85
|
+
from sage.misc.latex import latex
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def is_PointCollection(x):
|
|
89
|
+
r"""
|
|
90
|
+
Check if ``x`` is a :class:`point collection <PointCollection>`.
|
|
91
|
+
|
|
92
|
+
INPUT:
|
|
93
|
+
|
|
94
|
+
- ``x`` -- anything
|
|
95
|
+
|
|
96
|
+
OUTPUT: ``True`` if ``x`` is a point collection and ``False`` otherwise
|
|
97
|
+
|
|
98
|
+
EXAMPLES::
|
|
99
|
+
|
|
100
|
+
sage: from sage.geometry.point_collection import PointCollection
|
|
101
|
+
sage: isinstance(1, PointCollection)
|
|
102
|
+
False
|
|
103
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)])
|
|
104
|
+
sage: isinstance(c.rays(), PointCollection)
|
|
105
|
+
True
|
|
106
|
+
"""
|
|
107
|
+
from sage.misc.superseded import deprecation_cython
|
|
108
|
+
deprecation_cython(38126,
|
|
109
|
+
"The function is_PointCollection is deprecated; "
|
|
110
|
+
"use 'isinstance(..., PointCollection)' instead.")
|
|
111
|
+
return isinstance(x, PointCollection)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
_output_format = "default"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
cdef class PointCollection(SageObject):
|
|
118
|
+
r"""
|
|
119
|
+
Create a point collection.
|
|
120
|
+
|
|
121
|
+
.. WARNING::
|
|
122
|
+
|
|
123
|
+
No correctness check or normalization is performed on the input data.
|
|
124
|
+
This class is designed for internal operations and you probably should
|
|
125
|
+
not use it directly.
|
|
126
|
+
|
|
127
|
+
Point collections are immutable, but cache most of the returned values.
|
|
128
|
+
|
|
129
|
+
INPUT:
|
|
130
|
+
|
|
131
|
+
- ``points`` -- an iterable structure of immutable elements of ``module``,
|
|
132
|
+
if ``points`` are already accessible to you as a :class:`tuple`, it is
|
|
133
|
+
preferable to use it for speed and memory consumption reasons;
|
|
134
|
+
|
|
135
|
+
- ``module`` -- an ambient module for ``points``. If ``None`` (the default),
|
|
136
|
+
it will be determined as :func:`parent` of the first point. Of course, this
|
|
137
|
+
cannot be done if there are no points, so in this case you must give an
|
|
138
|
+
appropriate ``module`` directly.
|
|
139
|
+
|
|
140
|
+
OUTPUT:
|
|
141
|
+
|
|
142
|
+
- a point collection.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
cdef:
|
|
146
|
+
tuple _points
|
|
147
|
+
object _module
|
|
148
|
+
# cache attributes
|
|
149
|
+
PointCollection _basis
|
|
150
|
+
object _matrix
|
|
151
|
+
frozenset _set
|
|
152
|
+
|
|
153
|
+
def __init__(self, points, module=None):
|
|
154
|
+
r"""
|
|
155
|
+
See :class:`PointCollection` for documentation.
|
|
156
|
+
|
|
157
|
+
TESTS::
|
|
158
|
+
|
|
159
|
+
sage: from sage.geometry.point_collection import PointCollection
|
|
160
|
+
sage: v = vector([1,0])
|
|
161
|
+
sage: v.set_immutable()
|
|
162
|
+
sage: c = PointCollection([v], ZZ^2)
|
|
163
|
+
sage: c.module()
|
|
164
|
+
Ambient free module of rank 2
|
|
165
|
+
over the principal ideal domain Integer Ring
|
|
166
|
+
sage: c = PointCollection([v], None)
|
|
167
|
+
sage: c.module() # Determined automatically
|
|
168
|
+
Ambient free module of rank 2
|
|
169
|
+
over the principal ideal domain Integer Ring
|
|
170
|
+
sage: TestSuite(c).run()
|
|
171
|
+
"""
|
|
172
|
+
super().__init__()
|
|
173
|
+
self._points = tuple(points)
|
|
174
|
+
self._module = self._points[0].parent() if module is None else module
|
|
175
|
+
|
|
176
|
+
def _sage_input_(self, sib, coerced):
|
|
177
|
+
r"""
|
|
178
|
+
Return Sage command to reconstruct ``self``.
|
|
179
|
+
|
|
180
|
+
See :mod:`sage.misc.sage_input` for details.
|
|
181
|
+
|
|
182
|
+
EXAMPLES::
|
|
183
|
+
|
|
184
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
185
|
+
sage: sage_input(c, verify=True)
|
|
186
|
+
# Verified
|
|
187
|
+
sage.geometry.point_collection.PointCollection((vector(ZZ, [0, 0, 1]), vector(ZZ, [1, 0, 1]), vector(ZZ, [0, 1, 1]), vector(ZZ, [1, 1, 1])))
|
|
188
|
+
|
|
189
|
+
sage: c = sage.geometry.point_collection.PointCollection([], ToricLattice(2, 'U'))
|
|
190
|
+
sage: sage_input(c, verify=True)
|
|
191
|
+
# Verified
|
|
192
|
+
sage.geometry.point_collection.PointCollection((), ToricLattice(2, 'U', 'U*', 'U', 'U^*'))
|
|
193
|
+
"""
|
|
194
|
+
args = [sib(self._points)]
|
|
195
|
+
if not self._points or self._module is not self._points[0].parent():
|
|
196
|
+
args.append(sib(self._module))
|
|
197
|
+
return sib.name('sage.geometry.point_collection.PointCollection')(*args)
|
|
198
|
+
|
|
199
|
+
def __add__(left, right):
|
|
200
|
+
r"""
|
|
201
|
+
Return the joint point collection.
|
|
202
|
+
|
|
203
|
+
INPUT:
|
|
204
|
+
|
|
205
|
+
- ``left`` -- a :class:`PointCollection`;
|
|
206
|
+
|
|
207
|
+
- ``right`` -- a :class:`PointCollection`
|
|
208
|
+
|
|
209
|
+
OUTPUT: a :class:`PointCollection`
|
|
210
|
+
|
|
211
|
+
TESTS::
|
|
212
|
+
|
|
213
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
214
|
+
sage: c + c
|
|
215
|
+
N(0, 0, 1),
|
|
216
|
+
N(1, 0, 1),
|
|
217
|
+
N(0, 1, 1),
|
|
218
|
+
N(1, 1, 1),
|
|
219
|
+
N(0, 0, 1),
|
|
220
|
+
N(1, 0, 1),
|
|
221
|
+
N(0, 1, 1),
|
|
222
|
+
N(1, 1, 1)
|
|
223
|
+
in 3-d lattice N
|
|
224
|
+
"""
|
|
225
|
+
if not (isinstance(left, PointCollection) and
|
|
226
|
+
isinstance(right, PointCollection)):
|
|
227
|
+
raise NotImplementedError
|
|
228
|
+
cdef PointCollection left_pc = left
|
|
229
|
+
cdef PointCollection right_pc = right
|
|
230
|
+
if left_pc._module is not right_pc._module:
|
|
231
|
+
raise NotImplementedError
|
|
232
|
+
return PointCollection(left_pc._points + right_pc._points,
|
|
233
|
+
left_pc._module)
|
|
234
|
+
|
|
235
|
+
def __call__(self, *args):
|
|
236
|
+
r"""
|
|
237
|
+
Return a subcollection of ``self``.
|
|
238
|
+
|
|
239
|
+
INPUT:
|
|
240
|
+
|
|
241
|
+
- a list of integers (as a single or many arguments).
|
|
242
|
+
|
|
243
|
+
OUTPUT: a :class:`point collection <PointCollection>`
|
|
244
|
+
|
|
245
|
+
TESTS::
|
|
246
|
+
|
|
247
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
248
|
+
sage: c()
|
|
249
|
+
Empty collection
|
|
250
|
+
in 3-d lattice N
|
|
251
|
+
sage: c(2,1)
|
|
252
|
+
N(0, 1, 1),
|
|
253
|
+
N(1, 0, 1)
|
|
254
|
+
in 3-d lattice N
|
|
255
|
+
sage: c(range(4)) == c
|
|
256
|
+
True
|
|
257
|
+
"""
|
|
258
|
+
if len(args) == 1:
|
|
259
|
+
try:
|
|
260
|
+
args = tuple(args[0])
|
|
261
|
+
except TypeError:
|
|
262
|
+
pass
|
|
263
|
+
# Avoid creating a copy of self
|
|
264
|
+
if len(args) == len(self) and args == tuple(range(len(self))):
|
|
265
|
+
return self
|
|
266
|
+
else:
|
|
267
|
+
return PointCollection([self[i] for i in args], self._module)
|
|
268
|
+
|
|
269
|
+
def __richcmp__(self, right, op):
|
|
270
|
+
r"""
|
|
271
|
+
Compare ``self`` and ``right`` according to the operator ``op``.
|
|
272
|
+
|
|
273
|
+
INPUT:
|
|
274
|
+
|
|
275
|
+
- ``right`` -- another PointCollection
|
|
276
|
+
|
|
277
|
+
OUTPUT: boolean
|
|
278
|
+
|
|
279
|
+
First compare according to the underlying :meth:`module`
|
|
280
|
+
and then according to the list of points.
|
|
281
|
+
|
|
282
|
+
TESTS::
|
|
283
|
+
|
|
284
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
285
|
+
sage: d = Cone([(0,1,2), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
286
|
+
sage: c == c
|
|
287
|
+
True
|
|
288
|
+
sage: c == d
|
|
289
|
+
False
|
|
290
|
+
"""
|
|
291
|
+
cdef PointCollection left_pc, right_pc
|
|
292
|
+
try:
|
|
293
|
+
left_pc = <PointCollection?>self
|
|
294
|
+
right_pc = <PointCollection?>right
|
|
295
|
+
except TypeError:
|
|
296
|
+
return NotImplemented
|
|
297
|
+
|
|
298
|
+
left_m = left_pc._module
|
|
299
|
+
right_m = right_pc._module
|
|
300
|
+
if left_m != right_m:
|
|
301
|
+
return richcmp_not_equal(left_m, right_m, op)
|
|
302
|
+
return richcmp(left_pc._points, right_pc._points, op)
|
|
303
|
+
|
|
304
|
+
def __getitem__(self, n):
|
|
305
|
+
r"""
|
|
306
|
+
Return the ``n``-th point of ``self``.
|
|
307
|
+
|
|
308
|
+
INPUT:
|
|
309
|
+
|
|
310
|
+
- ``n`` -- integer
|
|
311
|
+
|
|
312
|
+
OUTPUT: a point, an element of the ambient :meth:`module` of ``self``
|
|
313
|
+
|
|
314
|
+
EXAMPLES::
|
|
315
|
+
|
|
316
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
317
|
+
sage: c[0]
|
|
318
|
+
N(0, 0, 1)
|
|
319
|
+
"""
|
|
320
|
+
return self._points[n]
|
|
321
|
+
|
|
322
|
+
def __hash__(self):
|
|
323
|
+
r"""
|
|
324
|
+
Return the hash of ``self``.
|
|
325
|
+
|
|
326
|
+
OUTPUT: integer
|
|
327
|
+
|
|
328
|
+
TESTS::
|
|
329
|
+
|
|
330
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
331
|
+
sage: hash(c) == hash(c)
|
|
332
|
+
True
|
|
333
|
+
"""
|
|
334
|
+
return hash(self._points)
|
|
335
|
+
|
|
336
|
+
def __iter__(self):
|
|
337
|
+
r"""
|
|
338
|
+
Return an iterator over points of ``self``.
|
|
339
|
+
|
|
340
|
+
OUTPUT: an iterator
|
|
341
|
+
|
|
342
|
+
TESTS::
|
|
343
|
+
|
|
344
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
345
|
+
sage: for point in c: print(point)
|
|
346
|
+
N(0, 0, 1)
|
|
347
|
+
N(1, 0, 1)
|
|
348
|
+
N(0, 1, 1)
|
|
349
|
+
N(1, 1, 1)
|
|
350
|
+
"""
|
|
351
|
+
return iter(self._points)
|
|
352
|
+
|
|
353
|
+
def __len__(self):
|
|
354
|
+
r"""
|
|
355
|
+
Return the number of points in ``self``.
|
|
356
|
+
|
|
357
|
+
OUTPUT: integer
|
|
358
|
+
|
|
359
|
+
EXAMPLES::
|
|
360
|
+
|
|
361
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
362
|
+
sage: len(c)
|
|
363
|
+
4
|
|
364
|
+
"""
|
|
365
|
+
return len(self._points)
|
|
366
|
+
|
|
367
|
+
def __list__(self):
|
|
368
|
+
r"""
|
|
369
|
+
Return a list of points of ``self``.
|
|
370
|
+
|
|
371
|
+
OUTPUT: list
|
|
372
|
+
|
|
373
|
+
TESTS::
|
|
374
|
+
|
|
375
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
376
|
+
sage: list(c)
|
|
377
|
+
[N(0, 0, 1), N(1, 0, 1), N(0, 1, 1), N(1, 1, 1)]
|
|
378
|
+
"""
|
|
379
|
+
return list(self._points)
|
|
380
|
+
|
|
381
|
+
def __mul__(left, right):
|
|
382
|
+
r"""
|
|
383
|
+
Return the product ``left * right``.
|
|
384
|
+
|
|
385
|
+
INPUT:
|
|
386
|
+
|
|
387
|
+
- a :class:`point collection <PointCollection>` and something that can
|
|
388
|
+
act both on ``self.module().zero()`` and either ``self.matrix()`` from
|
|
389
|
+
the right or ``self.column_matrix()`` from the left.
|
|
390
|
+
|
|
391
|
+
OUTPUT:
|
|
392
|
+
|
|
393
|
+
- the result of ``self.matrix() * right``, provided that
|
|
394
|
+
``self.module().zero() * right`` can be computed.
|
|
395
|
+
|
|
396
|
+
The idea of this method is to provide a shortcut for matrix
|
|
397
|
+
multiplication with appropriate type checks, in particular, it is not
|
|
398
|
+
possible to multiply by a point of the same toric lattice as elements of
|
|
399
|
+
``self``.
|
|
400
|
+
|
|
401
|
+
TESTS::
|
|
402
|
+
|
|
403
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
404
|
+
sage: c.matrix()
|
|
405
|
+
[0 0 1]
|
|
406
|
+
[1 0 1]
|
|
407
|
+
[0 1 1]
|
|
408
|
+
[1 1 1]
|
|
409
|
+
sage: c * c[0]
|
|
410
|
+
Traceback (most recent call last):
|
|
411
|
+
...
|
|
412
|
+
TypeError: elements of the same toric lattice cannot be multiplied!
|
|
413
|
+
|
|
414
|
+
If you really need such a product, state it explicitly::
|
|
415
|
+
|
|
416
|
+
sage: c.matrix() * c[0]
|
|
417
|
+
(1, 1, 1, 1)
|
|
418
|
+
|
|
419
|
+
Multiplication by matrices works as well::
|
|
420
|
+
|
|
421
|
+
sage: c * c.column_matrix()
|
|
422
|
+
[1 1 1 1]
|
|
423
|
+
[1 2 1 2]
|
|
424
|
+
[1 1 2 2]
|
|
425
|
+
[1 2 2 3]
|
|
426
|
+
"""
|
|
427
|
+
cdef PointCollection pc
|
|
428
|
+
if isinstance(left, PointCollection):
|
|
429
|
+
pc = left
|
|
430
|
+
# Check that it is possible to act on points.
|
|
431
|
+
pc._module.zero() * right
|
|
432
|
+
return pc.matrix() * right
|
|
433
|
+
if isinstance(right, PointCollection):
|
|
434
|
+
pc = right
|
|
435
|
+
# Check that it is possible to act on points.
|
|
436
|
+
left * pc._module.zero()
|
|
437
|
+
return left * pc.column_matrix()
|
|
438
|
+
raise NotImplementedError
|
|
439
|
+
|
|
440
|
+
def __reduce__(self):
|
|
441
|
+
r"""
|
|
442
|
+
Prepare ``self`` for pickling.
|
|
443
|
+
|
|
444
|
+
OUTPUT:
|
|
445
|
+
|
|
446
|
+
- a tuple, currently the class name and a tuple consisting of points
|
|
447
|
+
and the ambient module.
|
|
448
|
+
|
|
449
|
+
TESTS::
|
|
450
|
+
|
|
451
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
452
|
+
sage: loads(dumps(c))
|
|
453
|
+
N(0, 0, 1),
|
|
454
|
+
N(1, 0, 1),
|
|
455
|
+
N(0, 1, 1),
|
|
456
|
+
N(1, 1, 1)
|
|
457
|
+
in 3-d lattice N
|
|
458
|
+
sage: loads(dumps(c)) == c
|
|
459
|
+
True
|
|
460
|
+
"""
|
|
461
|
+
return (PointCollection, (self._points, self._module))
|
|
462
|
+
|
|
463
|
+
def __tuple__(self):
|
|
464
|
+
r"""
|
|
465
|
+
Return the tuple of points of ``self``.
|
|
466
|
+
|
|
467
|
+
OUTPUT: a tuple
|
|
468
|
+
|
|
469
|
+
TESTS::
|
|
470
|
+
|
|
471
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
472
|
+
sage: tuple(c)
|
|
473
|
+
(N(0, 0, 1), N(1, 0, 1), N(0, 1, 1), N(1, 1, 1))
|
|
474
|
+
"""
|
|
475
|
+
return self._points
|
|
476
|
+
|
|
477
|
+
def _latex_(self):
|
|
478
|
+
r"""
|
|
479
|
+
Return a LaTeX representation of ``self``.
|
|
480
|
+
|
|
481
|
+
OUTPUT: string
|
|
482
|
+
|
|
483
|
+
TESTS::
|
|
484
|
+
|
|
485
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
486
|
+
sage: print(c._latex_())
|
|
487
|
+
\left(\left(0,\,0,\,1\right)_{N}, \left(1,\,0,\,1\right)_{N},
|
|
488
|
+
\left(0,\,1,\,1\right)_{N}, \left(1,\,1,\,1\right)_{N}\right)_{N}
|
|
489
|
+
"""
|
|
490
|
+
global _output_format
|
|
491
|
+
if _output_format in ["default", "tuple"]:
|
|
492
|
+
r = latex(tuple(self))
|
|
493
|
+
elif _output_format == "matrix":
|
|
494
|
+
r = latex(self.matrix())
|
|
495
|
+
elif _output_format == "column matrix":
|
|
496
|
+
r = latex(self.column_matrix())
|
|
497
|
+
elif _output_format == "separated column matrix":
|
|
498
|
+
r = latex(self.column_matrix())
|
|
499
|
+
r = r.replace("r" * len(self), "|".join("r" * len(self)))
|
|
500
|
+
return r"%s_{%s}" % (r, latex(self.module()))
|
|
501
|
+
|
|
502
|
+
def _matrix_(self, ring=None):
|
|
503
|
+
r"""
|
|
504
|
+
Return a matrix whose rows are points of ``self``.
|
|
505
|
+
|
|
506
|
+
INPUT:
|
|
507
|
+
|
|
508
|
+
- ``ring`` -- a base ring for the returned matrix (default: base ring of
|
|
509
|
+
:meth:`module` of ``self``)
|
|
510
|
+
|
|
511
|
+
OUTPUT: a :class:`matrix <Matrix>`
|
|
512
|
+
|
|
513
|
+
EXAMPLES::
|
|
514
|
+
|
|
515
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
516
|
+
sage: matrix(c) # indirect doctest
|
|
517
|
+
[0 0 1]
|
|
518
|
+
[1 0 1]
|
|
519
|
+
[0 1 1]
|
|
520
|
+
[1 1 1]
|
|
521
|
+
"""
|
|
522
|
+
if ring is None:
|
|
523
|
+
return self.matrix()
|
|
524
|
+
else:
|
|
525
|
+
return self.matrix().change_ring(ring)
|
|
526
|
+
|
|
527
|
+
def _repr_(self):
|
|
528
|
+
r"""
|
|
529
|
+
Return a string representation of ``self``.
|
|
530
|
+
|
|
531
|
+
OUTPUT: string
|
|
532
|
+
|
|
533
|
+
TESTS::
|
|
534
|
+
|
|
535
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
536
|
+
sage: print(c._repr_())
|
|
537
|
+
N(0, 0, 1),
|
|
538
|
+
N(1, 0, 1),
|
|
539
|
+
N(0, 1, 1),
|
|
540
|
+
N(1, 1, 1)
|
|
541
|
+
in 3-d lattice N
|
|
542
|
+
"""
|
|
543
|
+
global _output_format
|
|
544
|
+
if _output_format == "default":
|
|
545
|
+
r = map(repr, self)
|
|
546
|
+
r = [point.split(",") for point in r]
|
|
547
|
+
if not r:
|
|
548
|
+
r = "Empty collection"
|
|
549
|
+
else:
|
|
550
|
+
if "(" in r[0][0]:
|
|
551
|
+
delimiter = "("
|
|
552
|
+
elif "[" in r[0][0]:
|
|
553
|
+
delimiter = "["
|
|
554
|
+
else:
|
|
555
|
+
raise ValueError("cannot parse point representation!")
|
|
556
|
+
heads = []
|
|
557
|
+
for point in r:
|
|
558
|
+
head, point[0] = point[0].rsplit(delimiter, 1)
|
|
559
|
+
heads.append(head + delimiter)
|
|
560
|
+
format = "{{:<{}}}".format(max(map(len, heads)))
|
|
561
|
+
widths = [0] * len(r[0])
|
|
562
|
+
for point in r:
|
|
563
|
+
for i, coordinate in enumerate(point):
|
|
564
|
+
widths[i] = max(widths[i], len(coordinate))
|
|
565
|
+
format += ",".join("{{:>{}}}".format(width) for width in widths)
|
|
566
|
+
r = ",\n".join(format.format(head, *point)
|
|
567
|
+
for head, point in zip(heads, r))
|
|
568
|
+
elif _output_format == "tuple":
|
|
569
|
+
r = tuple(self)
|
|
570
|
+
elif _output_format == "matrix":
|
|
571
|
+
r = self.matrix()
|
|
572
|
+
else:
|
|
573
|
+
r = self.column_matrix()
|
|
574
|
+
return "{}\nin {}".format(r, self.module())
|
|
575
|
+
|
|
576
|
+
def basis(self):
|
|
577
|
+
r"""
|
|
578
|
+
Return a linearly independent subset of points of ``self``.
|
|
579
|
+
|
|
580
|
+
OUTPUT:
|
|
581
|
+
|
|
582
|
+
- a :class:`point collection <PointCollection>` giving a random (but
|
|
583
|
+
fixed) choice of an `\RR`-basis for the vector space spanned by the
|
|
584
|
+
points of ``self``.
|
|
585
|
+
|
|
586
|
+
EXAMPLES::
|
|
587
|
+
|
|
588
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
589
|
+
sage: c.basis()
|
|
590
|
+
N(0, 0, 1),
|
|
591
|
+
N(1, 0, 1),
|
|
592
|
+
N(0, 1, 1)
|
|
593
|
+
in 3-d lattice N
|
|
594
|
+
|
|
595
|
+
Calling this method twice will always return *exactly the same* point
|
|
596
|
+
collection::
|
|
597
|
+
|
|
598
|
+
sage: c.basis().basis() is c.basis()
|
|
599
|
+
True
|
|
600
|
+
"""
|
|
601
|
+
if self._basis is None:
|
|
602
|
+
self._basis = self(self.matrix().pivot_rows())
|
|
603
|
+
return self._basis
|
|
604
|
+
|
|
605
|
+
def cardinality(self):
|
|
606
|
+
r"""
|
|
607
|
+
Return the number of points in ``self``.
|
|
608
|
+
|
|
609
|
+
OUTPUT: integer
|
|
610
|
+
|
|
611
|
+
EXAMPLES::
|
|
612
|
+
|
|
613
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
614
|
+
sage: c.cardinality()
|
|
615
|
+
4
|
|
616
|
+
"""
|
|
617
|
+
return len(self._points)
|
|
618
|
+
|
|
619
|
+
def cartesian_product(self, other, module=None):
|
|
620
|
+
r"""
|
|
621
|
+
Return the Cartesian product of ``self`` with ``other``.
|
|
622
|
+
|
|
623
|
+
INPUT:
|
|
624
|
+
|
|
625
|
+
- ``other`` -- a :class:`point collection <PointCollection>`;
|
|
626
|
+
|
|
627
|
+
- ``module`` -- (optional) the ambient module for the result. By
|
|
628
|
+
default, the direct sum of the ambient modules of ``self`` and
|
|
629
|
+
``other`` is constructed.
|
|
630
|
+
|
|
631
|
+
OUTPUT: a :class:`point collection <PointCollection>`
|
|
632
|
+
|
|
633
|
+
EXAMPLES::
|
|
634
|
+
|
|
635
|
+
sage: c = Cone([(0,0,1), (1,1,1)]).rays()
|
|
636
|
+
sage: c.cartesian_product(c)
|
|
637
|
+
N+N(0, 0, 1, 0, 0, 1),
|
|
638
|
+
N+N(1, 1, 1, 0, 0, 1),
|
|
639
|
+
N+N(0, 0, 1, 1, 1, 1),
|
|
640
|
+
N+N(1, 1, 1, 1, 1, 1)
|
|
641
|
+
in 6-d lattice N+N
|
|
642
|
+
"""
|
|
643
|
+
assert isinstance(other, PointCollection)
|
|
644
|
+
if module is None:
|
|
645
|
+
module = self._module.direct_sum(other.module())
|
|
646
|
+
P = [list(p) for p in self]
|
|
647
|
+
Q = [list(q) for q in other]
|
|
648
|
+
PQ = [module(p + q) for q in Q for p in P]
|
|
649
|
+
for pq in PQ:
|
|
650
|
+
pq.set_immutable()
|
|
651
|
+
return PointCollection(PQ, module)
|
|
652
|
+
|
|
653
|
+
def column_matrix(self):
|
|
654
|
+
r"""
|
|
655
|
+
Return a matrix whose columns are points of ``self``.
|
|
656
|
+
|
|
657
|
+
OUTPUT: a :class:`matrix <Matrix>`
|
|
658
|
+
|
|
659
|
+
EXAMPLES::
|
|
660
|
+
|
|
661
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
662
|
+
sage: c.column_matrix()
|
|
663
|
+
[0 1 0 1]
|
|
664
|
+
[0 0 1 1]
|
|
665
|
+
[1 1 1 1]
|
|
666
|
+
"""
|
|
667
|
+
return self.matrix().transpose()
|
|
668
|
+
|
|
669
|
+
def dimension(self):
|
|
670
|
+
r"""
|
|
671
|
+
Return the dimension of the space spanned by points of ``self``.
|
|
672
|
+
|
|
673
|
+
.. NOTE:: You can use either :meth:`dim` or :meth:`dimension`.
|
|
674
|
+
|
|
675
|
+
OUTPUT: integer
|
|
676
|
+
|
|
677
|
+
EXAMPLES::
|
|
678
|
+
|
|
679
|
+
sage: c = Cone([(0,0,1), (1,1,1)]).rays()
|
|
680
|
+
sage: c.dimension()
|
|
681
|
+
2
|
|
682
|
+
sage: c.dim()
|
|
683
|
+
2
|
|
684
|
+
"""
|
|
685
|
+
return self.matrix().rank()
|
|
686
|
+
|
|
687
|
+
dim = dimension
|
|
688
|
+
|
|
689
|
+
def dual_module(self):
|
|
690
|
+
r"""
|
|
691
|
+
Return the dual of the ambient module of ``self``.
|
|
692
|
+
|
|
693
|
+
OUTPUT:
|
|
694
|
+
|
|
695
|
+
- a :class:`module <FreeModule_generic>`. If possible (that is, if the
|
|
696
|
+
ambient :meth:`module` `M` of ``self`` has a ``dual()`` method), the
|
|
697
|
+
dual module is returned. Otherwise, `R^n` is returned, where `n` is
|
|
698
|
+
the dimension of `M` and `R` is its base ring.
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
703
|
+
sage: c.dual_module()
|
|
704
|
+
3-d lattice M
|
|
705
|
+
"""
|
|
706
|
+
M = self._module
|
|
707
|
+
try:
|
|
708
|
+
return M.dual()
|
|
709
|
+
except AttributeError:
|
|
710
|
+
# TODO: add support for torsion modules as well?
|
|
711
|
+
return M.base_ring() ** M.dimension()
|
|
712
|
+
|
|
713
|
+
def index(self, *args):
|
|
714
|
+
r"""
|
|
715
|
+
Return the index of the first occurrence of ``point`` in ``self``.
|
|
716
|
+
|
|
717
|
+
INPUT:
|
|
718
|
+
|
|
719
|
+
- ``point`` -- a point of ``self``
|
|
720
|
+
|
|
721
|
+
- ``start`` -- (optional) an integer, if given, the search will start
|
|
722
|
+
at this position
|
|
723
|
+
|
|
724
|
+
- ``stop`` -- (optional) an integer, if given, the search will stop
|
|
725
|
+
at this position
|
|
726
|
+
|
|
727
|
+
OUTPUT: an integer if ``point`` is in ``self[start:stop]``, otherwise a
|
|
728
|
+
:exc:`ValueError` exception is raised
|
|
729
|
+
|
|
730
|
+
EXAMPLES::
|
|
731
|
+
|
|
732
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
733
|
+
sage: c.index((0,1,1))
|
|
734
|
+
Traceback (most recent call last):
|
|
735
|
+
...
|
|
736
|
+
ValueError: tuple.index(x): x not in tuple
|
|
737
|
+
|
|
738
|
+
Note that this was not a mistake: the *tuple* ``(0,1,1)`` is *not* a
|
|
739
|
+
point of ``c``! We need to pass actual element of the ambient module of
|
|
740
|
+
``c`` to get their indices::
|
|
741
|
+
|
|
742
|
+
sage: N = c.module()
|
|
743
|
+
sage: c.index(N(0,1,1))
|
|
744
|
+
2
|
|
745
|
+
sage: c[2]
|
|
746
|
+
N(0, 1, 1)
|
|
747
|
+
"""
|
|
748
|
+
return self._points.index(*args)
|
|
749
|
+
|
|
750
|
+
def matrix(self):
|
|
751
|
+
r"""
|
|
752
|
+
Return a matrix whose rows are points of ``self``.
|
|
753
|
+
|
|
754
|
+
OUTPUT: a :class:`matrix <Matrix>`
|
|
755
|
+
|
|
756
|
+
EXAMPLES::
|
|
757
|
+
|
|
758
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
759
|
+
sage: c.matrix()
|
|
760
|
+
[0 0 1]
|
|
761
|
+
[1 0 1]
|
|
762
|
+
[0 1 1]
|
|
763
|
+
[1 1 1]
|
|
764
|
+
"""
|
|
765
|
+
if self._matrix is None:
|
|
766
|
+
M = matrix(self._module.base_ring(), len(self._points),
|
|
767
|
+
self._module.degree(), self._points)
|
|
768
|
+
M.set_immutable()
|
|
769
|
+
self._matrix = M
|
|
770
|
+
return self._matrix
|
|
771
|
+
|
|
772
|
+
def module(self):
|
|
773
|
+
r"""
|
|
774
|
+
Return the ambient module of ``self``.
|
|
775
|
+
|
|
776
|
+
OUTPUT: a :class:`module <FreeModule_generic>`
|
|
777
|
+
|
|
778
|
+
EXAMPLES::
|
|
779
|
+
|
|
780
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
781
|
+
sage: c.module()
|
|
782
|
+
3-d lattice N
|
|
783
|
+
"""
|
|
784
|
+
return self._module
|
|
785
|
+
|
|
786
|
+
@staticmethod
|
|
787
|
+
def output_format(format=None):
|
|
788
|
+
r"""
|
|
789
|
+
Return or set the output format for **ALL** point collections.
|
|
790
|
+
|
|
791
|
+
INPUT:
|
|
792
|
+
|
|
793
|
+
- ``format`` -- (optional) if given, must be one of the strings
|
|
794
|
+
* "default" -- output one point per line with vertical alignment of
|
|
795
|
+
coordinates in text mode, same as "tuple" for LaTeX;
|
|
796
|
+
* "tuple" -- output ``tuple(self)`` with lattice information;
|
|
797
|
+
* "matrix" -- output :meth:`matrix` with lattice information;
|
|
798
|
+
* "column matrix" -- output :meth:`column_matrix` with lattice
|
|
799
|
+
information;
|
|
800
|
+
* "separated column matrix" -- same as "column matrix" for text
|
|
801
|
+
mode, for LaTeX separate columns by lines (not shown by jsMath).
|
|
802
|
+
|
|
803
|
+
OUTPUT:
|
|
804
|
+
|
|
805
|
+
- a string with the current format (only if ``format`` was omitted).
|
|
806
|
+
|
|
807
|
+
This function affects both regular and LaTeX output.
|
|
808
|
+
|
|
809
|
+
EXAMPLES::
|
|
810
|
+
|
|
811
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
812
|
+
sage: c
|
|
813
|
+
N(0, 0, 1),
|
|
814
|
+
N(1, 0, 1),
|
|
815
|
+
N(0, 1, 1),
|
|
816
|
+
N(1, 1, 1)
|
|
817
|
+
in 3-d lattice N
|
|
818
|
+
sage: c.output_format()
|
|
819
|
+
'default'
|
|
820
|
+
sage: c.output_format("tuple")
|
|
821
|
+
sage: c
|
|
822
|
+
(N(0, 0, 1), N(1, 0, 1), N(0, 1, 1), N(1, 1, 1))
|
|
823
|
+
in 3-d lattice N
|
|
824
|
+
sage: c.output_format("matrix")
|
|
825
|
+
sage: c
|
|
826
|
+
[0 0 1]
|
|
827
|
+
[1 0 1]
|
|
828
|
+
[0 1 1]
|
|
829
|
+
[1 1 1]
|
|
830
|
+
in 3-d lattice N
|
|
831
|
+
sage: c.output_format("column matrix")
|
|
832
|
+
sage: c
|
|
833
|
+
[0 1 0 1]
|
|
834
|
+
[0 0 1 1]
|
|
835
|
+
[1 1 1 1]
|
|
836
|
+
in 3-d lattice N
|
|
837
|
+
sage: c.output_format("separated column matrix")
|
|
838
|
+
sage: c
|
|
839
|
+
[0 1 0 1]
|
|
840
|
+
[0 0 1 1]
|
|
841
|
+
[1 1 1 1]
|
|
842
|
+
in 3-d lattice N
|
|
843
|
+
|
|
844
|
+
Note that the last two outputs are identical, separators are only
|
|
845
|
+
inserted in the LaTeX mode::
|
|
846
|
+
|
|
847
|
+
sage: latex(c)
|
|
848
|
+
\left(\begin{array}{r|r|r|r}
|
|
849
|
+
0 & 1 & 0 & 1 \\
|
|
850
|
+
0 & 0 & 1 & 1 \\
|
|
851
|
+
1 & 1 & 1 & 1
|
|
852
|
+
\end{array}\right)_{N}
|
|
853
|
+
|
|
854
|
+
Since this is a static method, you can call it for the class directly::
|
|
855
|
+
|
|
856
|
+
sage: from sage.geometry.point_collection import PointCollection
|
|
857
|
+
sage: PointCollection.output_format("default")
|
|
858
|
+
sage: c
|
|
859
|
+
N(0, 0, 1),
|
|
860
|
+
N(1, 0, 1),
|
|
861
|
+
N(0, 1, 1),
|
|
862
|
+
N(1, 1, 1)
|
|
863
|
+
in 3-d lattice N
|
|
864
|
+
"""
|
|
865
|
+
global _output_format
|
|
866
|
+
if format is None:
|
|
867
|
+
return _output_format
|
|
868
|
+
assert format in ["default", "tuple", "matrix", "column matrix",
|
|
869
|
+
"separated column matrix"]
|
|
870
|
+
_output_format = format
|
|
871
|
+
|
|
872
|
+
def set(self):
|
|
873
|
+
r"""
|
|
874
|
+
Return points of ``self`` as a :class:`frozenset`.
|
|
875
|
+
|
|
876
|
+
OUTPUT: a :class:`frozenset`
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: c = Cone([(0,0,1), (1,0,1), (0,1,1), (1,1,1)]).rays()
|
|
881
|
+
sage: c.set()
|
|
882
|
+
frozenset({N(0, 0, 1), N(0, 1, 1), N(1, 0, 1), N(1, 1, 1)})
|
|
883
|
+
"""
|
|
884
|
+
if self._set is None:
|
|
885
|
+
self._set = frozenset(self._points)
|
|
886
|
+
return self._set
|
|
887
|
+
|
|
888
|
+
def write_for_palp(self, f):
|
|
889
|
+
r"""
|
|
890
|
+
Write ``self`` into an open file ``f`` in PALP format.
|
|
891
|
+
|
|
892
|
+
INPUT:
|
|
893
|
+
|
|
894
|
+
- ``f`` -- a file opened for writing
|
|
895
|
+
|
|
896
|
+
EXAMPLES::
|
|
897
|
+
|
|
898
|
+
sage: o = lattice_polytope.cross_polytope(3)
|
|
899
|
+
sage: from io import StringIO
|
|
900
|
+
sage: f = StringIO()
|
|
901
|
+
sage: o.vertices().write_for_palp(f)
|
|
902
|
+
sage: print(f.getvalue())
|
|
903
|
+
6 3
|
|
904
|
+
1 0 0
|
|
905
|
+
0 1 0
|
|
906
|
+
0 0 1
|
|
907
|
+
-1 0 0
|
|
908
|
+
0 -1 0
|
|
909
|
+
0 0 -1
|
|
910
|
+
"""
|
|
911
|
+
f.write('{} {}\n'.format(len(self), self._module.rank()))
|
|
912
|
+
f.write('\n'.join(' '.join(str(c) for c in p) for p in self))
|
|
913
|
+
f.write('\n')
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
def read_palp_point_collection(f, lattice=None, permutation=False):
|
|
917
|
+
r"""
|
|
918
|
+
Read and return a point collection from an opened file.
|
|
919
|
+
|
|
920
|
+
Data must be in PALP format:
|
|
921
|
+
|
|
922
|
+
* the first input line starts with two integers `m` and `n`, the number
|
|
923
|
+
of points and the number of components of each;
|
|
924
|
+
|
|
925
|
+
* the rest of the first line may contain a permutation;
|
|
926
|
+
|
|
927
|
+
* the next `m` lines contain `n` numbers each.
|
|
928
|
+
|
|
929
|
+
.. NOTE::
|
|
930
|
+
|
|
931
|
+
If `m` < `n`, it is assumed (for compatibility with PALP) that the
|
|
932
|
+
matrix is transposed, i.e. that each column is a point.
|
|
933
|
+
|
|
934
|
+
INPUT:
|
|
935
|
+
|
|
936
|
+
- ``f`` -- an opened file with PALP output
|
|
937
|
+
|
|
938
|
+
- ``lattice`` -- the lattice for points. If not given, the
|
|
939
|
+
:class:`toric lattice <sage.geometry.toric_lattice.ToricLatticeFactory>`
|
|
940
|
+
`M` of dimension `n` will be used.
|
|
941
|
+
|
|
942
|
+
- ``permutation`` -- boolean (default: ``False``); if ``True``, try to retrieve
|
|
943
|
+
the permutation. This parameter makes sense only when PALP computed the
|
|
944
|
+
normal form of a lattice polytope.
|
|
945
|
+
|
|
946
|
+
OUTPUT:
|
|
947
|
+
|
|
948
|
+
- a :class:`point collection <PointCollection>`, optionally followed by
|
|
949
|
+
a permutation. ``None`` if EOF is reached.
|
|
950
|
+
|
|
951
|
+
EXAMPLES::
|
|
952
|
+
|
|
953
|
+
sage: data = "3 2 regular\n1 2\n3 4\n5 6\n2 3 transposed\n1 2 3\n4 5 6"
|
|
954
|
+
sage: print(data)
|
|
955
|
+
3 2 regular
|
|
956
|
+
1 2
|
|
957
|
+
3 4
|
|
958
|
+
5 6
|
|
959
|
+
2 3 transposed
|
|
960
|
+
1 2 3
|
|
961
|
+
4 5 6
|
|
962
|
+
sage: from io import StringIO
|
|
963
|
+
sage: f = StringIO(data)
|
|
964
|
+
sage: from sage.geometry.point_collection \
|
|
965
|
+
....: import read_palp_point_collection
|
|
966
|
+
sage: read_palp_point_collection(f)
|
|
967
|
+
M(1, 2),
|
|
968
|
+
M(3, 4),
|
|
969
|
+
M(5, 6)
|
|
970
|
+
in 2-d lattice M
|
|
971
|
+
sage: read_palp_point_collection(f)
|
|
972
|
+
M(1, 4),
|
|
973
|
+
M(2, 5),
|
|
974
|
+
M(3, 6)
|
|
975
|
+
in 2-d lattice M
|
|
976
|
+
sage: read_palp_point_collection(f) is None
|
|
977
|
+
True
|
|
978
|
+
"""
|
|
979
|
+
cdef int i, j, m, n
|
|
980
|
+
first_line = f.readline()
|
|
981
|
+
if first_line == "":
|
|
982
|
+
return None
|
|
983
|
+
first_line = first_line.split()
|
|
984
|
+
m = int(first_line[0])
|
|
985
|
+
n = int(first_line[1])
|
|
986
|
+
if m >= n:
|
|
987
|
+
# Typical situation: a point on each line
|
|
988
|
+
lattice = lattice or ToricLattice(n).dual()
|
|
989
|
+
points = [lattice.element_class(lattice, f.readline().split())
|
|
990
|
+
for i in range(m)]
|
|
991
|
+
else:
|
|
992
|
+
# Also may appear as PALP output, e.g. points of 3-d polytopes
|
|
993
|
+
lattice = lattice or ToricLattice(m).dual()
|
|
994
|
+
data = [f.readline().split() for j in range(m)]
|
|
995
|
+
points = [lattice.element_class(lattice, [data[j][i] for j in range(m)])
|
|
996
|
+
for i in range(n)]
|
|
997
|
+
for p in points:
|
|
998
|
+
p.set_immutable()
|
|
999
|
+
pc = PointCollection(points, lattice)
|
|
1000
|
+
if permutation:
|
|
1001
|
+
last_piece = first_line[-1].split('=')
|
|
1002
|
+
if last_piece[0] != 'perm':
|
|
1003
|
+
raise ValueError('permutation was requested but not found')
|
|
1004
|
+
from sage.geometry.lattice_polytope import _palp_convert_permutation
|
|
1005
|
+
p = _palp_convert_permutation(last_piece[1])
|
|
1006
|
+
return (pc, p)
|
|
1007
|
+
else:
|
|
1008
|
+
return pc
|