passagemath-polyhedra 10.6.37__cp314-cp314-musllinux_1_2_x86_64.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.
- passagemath_polyhedra/__init__.py +3 -0
- passagemath_polyhedra-10.6.37.dist-info/METADATA +367 -0
- passagemath_polyhedra-10.6.37.dist-info/METADATA.bak +369 -0
- passagemath_polyhedra-10.6.37.dist-info/RECORD +209 -0
- passagemath_polyhedra-10.6.37.dist-info/WHEEL +5 -0
- passagemath_polyhedra-10.6.37.dist-info/top_level.txt +3 -0
- passagemath_polyhedra.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
- passagemath_polyhedra.libs/libstdc++-5d72f927.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 +3905 -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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
- sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/numerical/mip.pxd +40 -0
- sage/numerical/mip.pyx +3667 -0
- sage/numerical/sdp.cpython-314-x86_64-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-x86_64-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,963 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
# distutils: sources = sage/geometry/triangulation/functions.cc sage/geometry/triangulation/data.cc sage/geometry/triangulation/triangulations.cc
|
|
3
|
+
# distutils: depends = sage/geometry/triangulation/functions.h sage/geometry/triangulation/data.h sage/geometry/triangulation/triangulations.h
|
|
4
|
+
# distutils: language = c++
|
|
5
|
+
|
|
6
|
+
r"""
|
|
7
|
+
Base classes for triangulations
|
|
8
|
+
|
|
9
|
+
We provide (fast) cython implementations here.
|
|
10
|
+
|
|
11
|
+
AUTHORS:
|
|
12
|
+
|
|
13
|
+
- Volker Braun (2010-09-14): initial version.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
########################################################################
|
|
18
|
+
# Copyright (C) 2010 Volker Braun <vbraun.name@gmail.com>
|
|
19
|
+
#
|
|
20
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
21
|
+
#
|
|
22
|
+
# https://www.gnu.org/licenses/
|
|
23
|
+
########################################################################
|
|
24
|
+
|
|
25
|
+
from sage.misc.fast_methods cimport hash_by_id
|
|
26
|
+
from sage.structure.sage_object cimport SageObject
|
|
27
|
+
from sage.structure.parent cimport Parent
|
|
28
|
+
from sage.categories.sets_cat import Sets
|
|
29
|
+
from sage.matrix.constructor import matrix
|
|
30
|
+
|
|
31
|
+
from sage.geometry.triangulation.functions cimport binomial
|
|
32
|
+
from sage.geometry.triangulation.triangulations cimport \
|
|
33
|
+
triangulations_ptr, init_triangulations, next_triangulation, delete_triangulations
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
########################################################################
|
|
37
|
+
cdef class Point(SageObject):
|
|
38
|
+
r"""
|
|
39
|
+
A point of a point configuration.
|
|
40
|
+
|
|
41
|
+
Note that the coordinates of the points of a point configuration
|
|
42
|
+
are somewhat arbitrary. What counts are the abstract linear
|
|
43
|
+
relations between the points, for example encoded by the
|
|
44
|
+
:meth:`~sage.geometry.triangulation.point_configuration.PointConfiguration.circuits`.
|
|
45
|
+
|
|
46
|
+
.. WARNING::
|
|
47
|
+
|
|
48
|
+
You should not create :class:`Point` objects manually. The
|
|
49
|
+
constructor of :class:`PointConfiguration_base` takes care of
|
|
50
|
+
this for you.
|
|
51
|
+
|
|
52
|
+
INPUT:
|
|
53
|
+
|
|
54
|
+
- ``point_configuration`` -- :class:`PointConfiguration_base`; the
|
|
55
|
+
point configuration to which the point belongs
|
|
56
|
+
|
|
57
|
+
- ``i`` -- integer; the index of the point in the point
|
|
58
|
+
configuration
|
|
59
|
+
|
|
60
|
+
- ``projective`` -- the projective coordinates of the point
|
|
61
|
+
|
|
62
|
+
- ``affine`` -- the affine coordinates of the point
|
|
63
|
+
|
|
64
|
+
- ``reduced`` -- the reduced (with linearities removed)
|
|
65
|
+
coordinates of the point
|
|
66
|
+
|
|
67
|
+
EXAMPLES::
|
|
68
|
+
|
|
69
|
+
sage: pc = PointConfiguration([(0,0)])
|
|
70
|
+
sage: from sage.geometry.triangulation.base import Point
|
|
71
|
+
sage: Point(pc, 123, (0,0,1), (0,0), ())
|
|
72
|
+
P(0, 0)
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
cdef int _index
|
|
76
|
+
cdef tuple _projective, _affine, _reduced_affine
|
|
77
|
+
cdef object _point_configuration
|
|
78
|
+
cdef object _reduced_affine_vector, _reduced_projective_vector
|
|
79
|
+
|
|
80
|
+
def __init__(self, point_configuration, i, projective, affine, reduced):
|
|
81
|
+
r"""
|
|
82
|
+
Construct a :class:`Point`.
|
|
83
|
+
|
|
84
|
+
EXAMPLES::
|
|
85
|
+
|
|
86
|
+
sage: pc = PointConfiguration([(0,0)])
|
|
87
|
+
sage: from sage.geometry.triangulation.base import Point
|
|
88
|
+
sage: Point(pc, 123, (0,0,1), (0,0), ()) # indirect doctest
|
|
89
|
+
P(0, 0)
|
|
90
|
+
"""
|
|
91
|
+
self._index = i
|
|
92
|
+
self._projective = tuple(projective)
|
|
93
|
+
self._affine = tuple(affine)
|
|
94
|
+
self._reduced_affine = tuple(reduced)
|
|
95
|
+
self._point_configuration = point_configuration
|
|
96
|
+
V = point_configuration.reduced_affine_vector_space()
|
|
97
|
+
self._reduced_affine_vector = V(self._reduced_affine)
|
|
98
|
+
P = point_configuration.reduced_projective_vector_space()
|
|
99
|
+
self._reduced_projective_vector = P(self.reduced_projective())
|
|
100
|
+
|
|
101
|
+
def __hash__(self):
|
|
102
|
+
r"""
|
|
103
|
+
Hash value for a point in a point configuration.
|
|
104
|
+
|
|
105
|
+
EXAMPLES::
|
|
106
|
+
|
|
107
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,1]])
|
|
108
|
+
sage: hash(p[0]) # random
|
|
109
|
+
35822008390213632
|
|
110
|
+
"""
|
|
111
|
+
return hash(self._point_configuration) ^ (<long>self._index)
|
|
112
|
+
|
|
113
|
+
cpdef point_configuration(self):
|
|
114
|
+
r"""
|
|
115
|
+
Return the point configuration to which the point belongs.
|
|
116
|
+
|
|
117
|
+
OUTPUT: a :class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`
|
|
118
|
+
|
|
119
|
+
EXAMPLES::
|
|
120
|
+
|
|
121
|
+
sage: pc = PointConfiguration([ (0,0), (1,0), (0,1) ])
|
|
122
|
+
sage: p = pc.point(0)
|
|
123
|
+
sage: p is pc.point(0)
|
|
124
|
+
True
|
|
125
|
+
sage: p.point_configuration() is pc
|
|
126
|
+
True
|
|
127
|
+
"""
|
|
128
|
+
return self._point_configuration
|
|
129
|
+
|
|
130
|
+
def __iter__(self):
|
|
131
|
+
r"""
|
|
132
|
+
Iterate through the affine ambient space coordinates of the point.
|
|
133
|
+
|
|
134
|
+
EXAMPLES::
|
|
135
|
+
|
|
136
|
+
sage: pc = PointConfiguration([(0,0)])
|
|
137
|
+
sage: from sage.geometry.triangulation.base import Point
|
|
138
|
+
sage: p = Point(pc, 123, (1,2,1), (3,4), ())
|
|
139
|
+
sage: list(p) # indirect doctest
|
|
140
|
+
[3, 4]
|
|
141
|
+
"""
|
|
142
|
+
return iter(self._affine)
|
|
143
|
+
|
|
144
|
+
def __len__(self):
|
|
145
|
+
r"""
|
|
146
|
+
Return the affine ambient space dimension.
|
|
147
|
+
|
|
148
|
+
EXAMPLES::
|
|
149
|
+
|
|
150
|
+
sage: pc = PointConfiguration([(0,0)])
|
|
151
|
+
sage: from sage.geometry.triangulation.base import Point
|
|
152
|
+
sage: p = Point(pc, 123, (1,2,1), (3,4), ())
|
|
153
|
+
sage: len(p)
|
|
154
|
+
2
|
|
155
|
+
sage: p.__len__()
|
|
156
|
+
2
|
|
157
|
+
"""
|
|
158
|
+
return len(self._affine)
|
|
159
|
+
|
|
160
|
+
cpdef index(self):
|
|
161
|
+
"""
|
|
162
|
+
Return the index of the point in the point configuration.
|
|
163
|
+
|
|
164
|
+
EXAMPLES::
|
|
165
|
+
|
|
166
|
+
sage: pc = PointConfiguration([[0, 1], [0, 0], [1, 0]])
|
|
167
|
+
sage: p = pc.point(2); p
|
|
168
|
+
P(1, 0)
|
|
169
|
+
sage: p.index()
|
|
170
|
+
2
|
|
171
|
+
"""
|
|
172
|
+
return self._index
|
|
173
|
+
|
|
174
|
+
cpdef projective(self):
|
|
175
|
+
r"""
|
|
176
|
+
Return the projective coordinates of the point in the ambient space.
|
|
177
|
+
|
|
178
|
+
OUTPUT: a tuple containing the coordinates
|
|
179
|
+
|
|
180
|
+
EXAMPLES::
|
|
181
|
+
|
|
182
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0], [10, 2, 3]])
|
|
183
|
+
sage: p = pc.point(2); p
|
|
184
|
+
P(10, 2, 3)
|
|
185
|
+
sage: p.affine()
|
|
186
|
+
(10, 2, 3)
|
|
187
|
+
sage: p.projective()
|
|
188
|
+
(10, 2, 3, 1)
|
|
189
|
+
sage: p.reduced_affine()
|
|
190
|
+
(2, 2)
|
|
191
|
+
sage: p.reduced_projective()
|
|
192
|
+
(2, 2, 1)
|
|
193
|
+
sage: p.reduced_affine_vector()
|
|
194
|
+
(2, 2)
|
|
195
|
+
"""
|
|
196
|
+
return self._projective
|
|
197
|
+
|
|
198
|
+
cpdef affine(self):
|
|
199
|
+
r"""
|
|
200
|
+
Return the affine coordinates of the point in the ambient space.
|
|
201
|
+
|
|
202
|
+
OUTPUT: a tuple containing the coordinates
|
|
203
|
+
|
|
204
|
+
EXAMPLES::
|
|
205
|
+
|
|
206
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0], [10, 2, 3]])
|
|
207
|
+
sage: p = pc.point(2); p
|
|
208
|
+
P(10, 2, 3)
|
|
209
|
+
sage: p.affine()
|
|
210
|
+
(10, 2, 3)
|
|
211
|
+
sage: p.projective()
|
|
212
|
+
(10, 2, 3, 1)
|
|
213
|
+
sage: p.reduced_affine()
|
|
214
|
+
(2, 2)
|
|
215
|
+
sage: p.reduced_projective()
|
|
216
|
+
(2, 2, 1)
|
|
217
|
+
sage: p.reduced_affine_vector()
|
|
218
|
+
(2, 2)
|
|
219
|
+
"""
|
|
220
|
+
return self._affine
|
|
221
|
+
|
|
222
|
+
cpdef reduced_affine(self):
|
|
223
|
+
r"""
|
|
224
|
+
Return the affine coordinates of the point on the hyperplane
|
|
225
|
+
spanned by the point configuration.
|
|
226
|
+
|
|
227
|
+
OUTPUT: a tuple containing the coordinates
|
|
228
|
+
|
|
229
|
+
EXAMPLES::
|
|
230
|
+
|
|
231
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0], [10, 2, 3]])
|
|
232
|
+
sage: p = pc.point(2); p
|
|
233
|
+
P(10, 2, 3)
|
|
234
|
+
sage: p.affine()
|
|
235
|
+
(10, 2, 3)
|
|
236
|
+
sage: p.projective()
|
|
237
|
+
(10, 2, 3, 1)
|
|
238
|
+
sage: p.reduced_affine()
|
|
239
|
+
(2, 2)
|
|
240
|
+
sage: p.reduced_projective()
|
|
241
|
+
(2, 2, 1)
|
|
242
|
+
sage: p.reduced_affine_vector()
|
|
243
|
+
(2, 2)
|
|
244
|
+
"""
|
|
245
|
+
return self._reduced_affine
|
|
246
|
+
|
|
247
|
+
cpdef reduced_projective(self):
|
|
248
|
+
r"""
|
|
249
|
+
Return the projective coordinates of the point on the hyperplane
|
|
250
|
+
spanned by the point configuration.
|
|
251
|
+
|
|
252
|
+
OUTPUT: a tuple containing the coordinates
|
|
253
|
+
|
|
254
|
+
EXAMPLES::
|
|
255
|
+
|
|
256
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0], [10, 2, 3]])
|
|
257
|
+
sage: p = pc.point(2); p
|
|
258
|
+
P(10, 2, 3)
|
|
259
|
+
sage: p.affine()
|
|
260
|
+
(10, 2, 3)
|
|
261
|
+
sage: p.projective()
|
|
262
|
+
(10, 2, 3, 1)
|
|
263
|
+
sage: p.reduced_affine()
|
|
264
|
+
(2, 2)
|
|
265
|
+
sage: p.reduced_projective()
|
|
266
|
+
(2, 2, 1)
|
|
267
|
+
sage: p.reduced_affine_vector()
|
|
268
|
+
(2, 2)
|
|
269
|
+
"""
|
|
270
|
+
return tuple(self._reduced_affine)+(1,)
|
|
271
|
+
|
|
272
|
+
cpdef reduced_affine_vector(self):
|
|
273
|
+
"""
|
|
274
|
+
Return the affine coordinates of the point on the hyperplane
|
|
275
|
+
spanned by the point configuration.
|
|
276
|
+
|
|
277
|
+
OUTPUT: a tuple containing the coordinates
|
|
278
|
+
|
|
279
|
+
EXAMPLES::
|
|
280
|
+
|
|
281
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0], [10, 2, 3]])
|
|
282
|
+
sage: p = pc.point(2); p
|
|
283
|
+
P(10, 2, 3)
|
|
284
|
+
sage: p.affine()
|
|
285
|
+
(10, 2, 3)
|
|
286
|
+
sage: p.projective()
|
|
287
|
+
(10, 2, 3, 1)
|
|
288
|
+
sage: p.reduced_affine()
|
|
289
|
+
(2, 2)
|
|
290
|
+
sage: p.reduced_projective()
|
|
291
|
+
(2, 2, 1)
|
|
292
|
+
sage: p.reduced_affine_vector()
|
|
293
|
+
(2, 2)
|
|
294
|
+
"""
|
|
295
|
+
return self._reduced_affine_vector
|
|
296
|
+
|
|
297
|
+
cpdef reduced_projective_vector(self):
|
|
298
|
+
"""
|
|
299
|
+
Return the affine coordinates of the point on the hyperplane
|
|
300
|
+
spanned by the point configuration.
|
|
301
|
+
|
|
302
|
+
OUTPUT: a tuple containing the coordinates
|
|
303
|
+
|
|
304
|
+
EXAMPLES::
|
|
305
|
+
|
|
306
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0], [10, 2, 3]])
|
|
307
|
+
sage: p = pc.point(2); p
|
|
308
|
+
P(10, 2, 3)
|
|
309
|
+
sage: p.affine()
|
|
310
|
+
(10, 2, 3)
|
|
311
|
+
sage: p.projective()
|
|
312
|
+
(10, 2, 3, 1)
|
|
313
|
+
sage: p.reduced_affine()
|
|
314
|
+
(2, 2)
|
|
315
|
+
sage: p.reduced_projective()
|
|
316
|
+
(2, 2, 1)
|
|
317
|
+
sage: p.reduced_affine_vector()
|
|
318
|
+
(2, 2)
|
|
319
|
+
sage: type(p.reduced_affine_vector())
|
|
320
|
+
<class 'sage.modules.vector_rational_dense.Vector_rational_dense'>
|
|
321
|
+
"""
|
|
322
|
+
return self._reduced_projective_vector
|
|
323
|
+
|
|
324
|
+
cpdef _repr_(self):
|
|
325
|
+
"""
|
|
326
|
+
Return a string representation of the point.
|
|
327
|
+
|
|
328
|
+
OUTPUT: string
|
|
329
|
+
|
|
330
|
+
EXAMPLES::
|
|
331
|
+
|
|
332
|
+
sage: pc = PointConfiguration([[10, 0, 1], [10, 0, 0]])
|
|
333
|
+
sage: from sage.geometry.triangulation.base import Point
|
|
334
|
+
sage: p = Point(pc, 123, (0,0,1), (0,0), (0,))
|
|
335
|
+
sage: p._repr_()
|
|
336
|
+
'P(0, 0)'
|
|
337
|
+
"""
|
|
338
|
+
return 'P' + str(self._affine)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
########################################################################
|
|
342
|
+
cdef class PointConfiguration_base(Parent):
|
|
343
|
+
r"""
|
|
344
|
+
The cython abstract base class for
|
|
345
|
+
:class:`~sage.geometry.triangulation.PointConfiguration`.
|
|
346
|
+
|
|
347
|
+
.. WARNING::
|
|
348
|
+
|
|
349
|
+
You should not instantiate this base class, but only its
|
|
350
|
+
derived class
|
|
351
|
+
:class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`.
|
|
352
|
+
"""
|
|
353
|
+
|
|
354
|
+
def __init__(self, points, defined_affine):
|
|
355
|
+
r"""
|
|
356
|
+
Construct a :class:`PointConfiguration_base`.
|
|
357
|
+
|
|
358
|
+
INPUT:
|
|
359
|
+
|
|
360
|
+
- ``points`` -- tuple of tuples of projective coordinates
|
|
361
|
+
with ``1`` as the final coordinate
|
|
362
|
+
|
|
363
|
+
- ``defined_affine`` -- boolean; whether the point
|
|
364
|
+
configuration is defined as a configuration of affine (as
|
|
365
|
+
opposed to projective) points
|
|
366
|
+
|
|
367
|
+
TESTS::
|
|
368
|
+
|
|
369
|
+
sage: from sage.geometry.triangulation.base import PointConfiguration_base
|
|
370
|
+
sage: PointConfiguration_base(((1,2,1),(2,3,1),(3,4,1)), False)
|
|
371
|
+
<sage.geometry.triangulation.base.PointConfiguration_base object at ...>
|
|
372
|
+
"""
|
|
373
|
+
Parent.__init__(self, category = Sets())
|
|
374
|
+
self._init_points(points)
|
|
375
|
+
self._is_affine = defined_affine
|
|
376
|
+
|
|
377
|
+
cdef tuple _pts
|
|
378
|
+
cdef int _ambient_dim
|
|
379
|
+
cdef int _dim
|
|
380
|
+
cdef object _base_ring
|
|
381
|
+
cdef bint _is_affine
|
|
382
|
+
cdef object _reduced_affine_vector_space, _reduced_projective_vector_space
|
|
383
|
+
|
|
384
|
+
cdef _init_points(self, tuple projective_points):
|
|
385
|
+
"""
|
|
386
|
+
Internal method to determine coordinates of points.
|
|
387
|
+
|
|
388
|
+
EXAMPLES::
|
|
389
|
+
|
|
390
|
+
sage: p = PointConfiguration([[0, 1], [0, 0], [1, 0]]) # indirect doctest
|
|
391
|
+
sage: p.points()
|
|
392
|
+
(P(0, 1), P(0, 0), P(1, 0))
|
|
393
|
+
|
|
394
|
+
Special cases::
|
|
395
|
+
|
|
396
|
+
sage: PointConfiguration([])
|
|
397
|
+
The pointless empty configuration
|
|
398
|
+
sage: PointConfiguration([(1,2,3)])
|
|
399
|
+
A point configuration in affine 3-space over Integer Ring
|
|
400
|
+
consisting of 1 point. The triangulations of this point
|
|
401
|
+
configuration are assumed to be connected, not necessarily
|
|
402
|
+
fine, not necessarily regular.
|
|
403
|
+
"""
|
|
404
|
+
if not projective_points:
|
|
405
|
+
self._ambient_dim = 0
|
|
406
|
+
self._dim = -1
|
|
407
|
+
self._pts = tuple()
|
|
408
|
+
return
|
|
409
|
+
|
|
410
|
+
# We now are sure that projective_points is not empty
|
|
411
|
+
n = len(projective_points)
|
|
412
|
+
self._ambient_dim = len(projective_points[0]) - 1
|
|
413
|
+
assert all(len(p) == self._ambient_dim+1 for p in projective_points), \
|
|
414
|
+
'The given point coordinates must all have the same length.'
|
|
415
|
+
assert len(set(projective_points)) == len(projective_points), \
|
|
416
|
+
'Not all points are pairwise distinct.'
|
|
417
|
+
|
|
418
|
+
proj = matrix(projective_points).transpose()
|
|
419
|
+
self._base_ring = proj.base_ring()
|
|
420
|
+
|
|
421
|
+
if all(x == 1 for x in proj.row(self.ambient_dim())):
|
|
422
|
+
aff = proj.submatrix(0, 0, nrows=self.ambient_dim())
|
|
423
|
+
else:
|
|
424
|
+
raise NotImplementedError # TODO
|
|
425
|
+
|
|
426
|
+
if n > 1:
|
|
427
|
+
# shift first point to origin
|
|
428
|
+
red = matrix([aff.column(i)-aff.column(0) for i in range(n)]).transpose()
|
|
429
|
+
# pick linearly independent rows
|
|
430
|
+
red = matrix([red.row(i) for i in red.pivot_rows()])
|
|
431
|
+
else:
|
|
432
|
+
red = matrix(0, 1)
|
|
433
|
+
self._dim = red.nrows()
|
|
434
|
+
|
|
435
|
+
from sage.modules.free_module import VectorSpace
|
|
436
|
+
self._reduced_affine_vector_space = VectorSpace(self._base_ring.fraction_field(), self._dim)
|
|
437
|
+
self._reduced_projective_vector_space = VectorSpace(self._base_ring.fraction_field(), self._dim+1)
|
|
438
|
+
self._pts = tuple([Point(self, i, proj.column(i),
|
|
439
|
+
aff.column(i), red.column(i))
|
|
440
|
+
for i in range(n)])
|
|
441
|
+
|
|
442
|
+
def __hash__(self):
|
|
443
|
+
r"""
|
|
444
|
+
Hash function.
|
|
445
|
+
|
|
446
|
+
TESTS::
|
|
447
|
+
|
|
448
|
+
sage: p = PointConfiguration([[0,0],[0,1]])
|
|
449
|
+
sage: hash(p) # random
|
|
450
|
+
8746748042501
|
|
451
|
+
"""
|
|
452
|
+
return hash_by_id(<void *> self)
|
|
453
|
+
|
|
454
|
+
cpdef reduced_affine_vector_space(self):
|
|
455
|
+
"""
|
|
456
|
+
Return the vector space that contains the affine points.
|
|
457
|
+
|
|
458
|
+
OUTPUT: a vector space over the fraction field of :meth:`base_ring`
|
|
459
|
+
|
|
460
|
+
EXAMPLES::
|
|
461
|
+
|
|
462
|
+
sage: p = PointConfiguration([[0,0,0], [1,2,3]])
|
|
463
|
+
sage: p.base_ring()
|
|
464
|
+
Integer Ring
|
|
465
|
+
sage: p.reduced_affine_vector_space()
|
|
466
|
+
Vector space of dimension 1 over Rational Field
|
|
467
|
+
sage: p.reduced_projective_vector_space()
|
|
468
|
+
Vector space of dimension 2 over Rational Field
|
|
469
|
+
"""
|
|
470
|
+
return self._reduced_affine_vector_space
|
|
471
|
+
|
|
472
|
+
cpdef reduced_projective_vector_space(self):
|
|
473
|
+
"""
|
|
474
|
+
Return the vector space that is spanned by the homogeneous
|
|
475
|
+
coordinates.
|
|
476
|
+
|
|
477
|
+
OUTPUT: a vector space over the fraction field of :meth:`base_ring`
|
|
478
|
+
|
|
479
|
+
EXAMPLES::
|
|
480
|
+
|
|
481
|
+
sage: p = PointConfiguration([[0,0,0], [1,2,3]])
|
|
482
|
+
sage: p.base_ring()
|
|
483
|
+
Integer Ring
|
|
484
|
+
sage: p.reduced_affine_vector_space()
|
|
485
|
+
Vector space of dimension 1 over Rational Field
|
|
486
|
+
sage: p.reduced_projective_vector_space()
|
|
487
|
+
Vector space of dimension 2 over Rational Field
|
|
488
|
+
"""
|
|
489
|
+
return self._reduced_projective_vector_space
|
|
490
|
+
|
|
491
|
+
cpdef ambient_dim(self):
|
|
492
|
+
"""
|
|
493
|
+
Return the dimension of the ambient space of the point
|
|
494
|
+
configuration.
|
|
495
|
+
|
|
496
|
+
See also :meth:`dimension`
|
|
497
|
+
|
|
498
|
+
EXAMPLES::
|
|
499
|
+
|
|
500
|
+
sage: p = PointConfiguration([[0,0,0]])
|
|
501
|
+
sage: p.ambient_dim()
|
|
502
|
+
3
|
|
503
|
+
sage: p.dim()
|
|
504
|
+
0
|
|
505
|
+
"""
|
|
506
|
+
return self._ambient_dim
|
|
507
|
+
|
|
508
|
+
cpdef dim(self):
|
|
509
|
+
"""
|
|
510
|
+
Return the actual dimension of the point configuration.
|
|
511
|
+
|
|
512
|
+
See also :meth:`ambient_dim`
|
|
513
|
+
|
|
514
|
+
EXAMPLES::
|
|
515
|
+
|
|
516
|
+
sage: p = PointConfiguration([[0,0,0]])
|
|
517
|
+
sage: p.ambient_dim()
|
|
518
|
+
3
|
|
519
|
+
sage: p.dim()
|
|
520
|
+
0
|
|
521
|
+
"""
|
|
522
|
+
return self._dim
|
|
523
|
+
|
|
524
|
+
cpdef base_ring(self):
|
|
525
|
+
r"""
|
|
526
|
+
Return the base ring, that is, the ring containing the
|
|
527
|
+
coordinates of the points.
|
|
528
|
+
|
|
529
|
+
OUTPUT: a ring
|
|
530
|
+
|
|
531
|
+
EXAMPLES::
|
|
532
|
+
|
|
533
|
+
sage: p = PointConfiguration([(0,0)])
|
|
534
|
+
sage: p.base_ring()
|
|
535
|
+
Integer Ring
|
|
536
|
+
|
|
537
|
+
sage: p = PointConfiguration([(1/2,3)])
|
|
538
|
+
sage: p.base_ring()
|
|
539
|
+
Rational Field
|
|
540
|
+
|
|
541
|
+
sage: p = PointConfiguration([(0.2, 5)])
|
|
542
|
+
sage: p.base_ring()
|
|
543
|
+
Real Field with 53 bits of precision
|
|
544
|
+
"""
|
|
545
|
+
return self._base_ring
|
|
546
|
+
|
|
547
|
+
cpdef bint is_affine(self) noexcept:
|
|
548
|
+
"""
|
|
549
|
+
Return whether the configuration is defined by affine points.
|
|
550
|
+
|
|
551
|
+
OUTPUT: boolean; if true, the homogeneous coordinates all have `1` as
|
|
552
|
+
their last entry
|
|
553
|
+
|
|
554
|
+
EXAMPLES::
|
|
555
|
+
|
|
556
|
+
sage: p = PointConfiguration([(0.2, 5), (3, 0.1)])
|
|
557
|
+
sage: p.is_affine()
|
|
558
|
+
True
|
|
559
|
+
|
|
560
|
+
sage: p = PointConfiguration([(0.2, 5, 1), (3, 0.1, 1)], projective=True)
|
|
561
|
+
sage: p.is_affine()
|
|
562
|
+
False
|
|
563
|
+
"""
|
|
564
|
+
return self._is_affine
|
|
565
|
+
|
|
566
|
+
def _assert_is_affine(self):
|
|
567
|
+
"""
|
|
568
|
+
Raise a :exc:`ValueError` if the point configuration is not
|
|
569
|
+
defined by affine points.
|
|
570
|
+
|
|
571
|
+
EXAMPLES::
|
|
572
|
+
|
|
573
|
+
sage: p = PointConfiguration([(0.2, 5), (3, 0.1)])
|
|
574
|
+
sage: p._assert_is_affine()
|
|
575
|
+
sage: p = PointConfiguration([(0.2, 5, 1), (3, 0.1, 1)], projective=True)
|
|
576
|
+
sage: p._assert_is_affine()
|
|
577
|
+
Traceback (most recent call last):
|
|
578
|
+
...
|
|
579
|
+
ValueError: The point configuration contains projective points.
|
|
580
|
+
"""
|
|
581
|
+
if not self.is_affine():
|
|
582
|
+
raise ValueError('The point configuration contains projective points.')
|
|
583
|
+
|
|
584
|
+
def __getitem__(self, i):
|
|
585
|
+
"""
|
|
586
|
+
Return the ``i``-th point.
|
|
587
|
+
|
|
588
|
+
Same as :meth:`point`.
|
|
589
|
+
|
|
590
|
+
INPUT:
|
|
591
|
+
|
|
592
|
+
- ``i`` -- integer
|
|
593
|
+
|
|
594
|
+
OUTPUT: the ``i``-th point of the point configuration
|
|
595
|
+
|
|
596
|
+
EXAMPLES::
|
|
597
|
+
|
|
598
|
+
sage: p = PointConfiguration([[1,0], [2,3], [3,2]])
|
|
599
|
+
sage: [p[i] for i in range(p.n_points())]
|
|
600
|
+
[P(1, 0), P(2, 3), P(3, 2)]
|
|
601
|
+
sage: list(p)
|
|
602
|
+
[P(1, 0), P(2, 3), P(3, 2)]
|
|
603
|
+
sage: list(p.points())
|
|
604
|
+
[P(1, 0), P(2, 3), P(3, 2)]
|
|
605
|
+
sage: [p.point(i) for i in range(p.n_points())]
|
|
606
|
+
[P(1, 0), P(2, 3), P(3, 2)]
|
|
607
|
+
"""
|
|
608
|
+
return self._pts[i]
|
|
609
|
+
|
|
610
|
+
cpdef n_points(self):
|
|
611
|
+
"""
|
|
612
|
+
Return the number of points.
|
|
613
|
+
|
|
614
|
+
Same as ``len(self)``.
|
|
615
|
+
|
|
616
|
+
EXAMPLES::
|
|
617
|
+
|
|
618
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
619
|
+
sage: p
|
|
620
|
+
A point configuration in affine 2-space over Integer Ring
|
|
621
|
+
consisting of 5 points. The triangulations of this point
|
|
622
|
+
configuration are assumed to be connected, not necessarily
|
|
623
|
+
fine, not necessarily regular.
|
|
624
|
+
sage: len(p)
|
|
625
|
+
5
|
|
626
|
+
sage: p.n_points()
|
|
627
|
+
5
|
|
628
|
+
"""
|
|
629
|
+
return len(self._pts)
|
|
630
|
+
|
|
631
|
+
cpdef points(self):
|
|
632
|
+
"""
|
|
633
|
+
Return a list of the points.
|
|
634
|
+
|
|
635
|
+
OUTPUT:
|
|
636
|
+
|
|
637
|
+
A list of the points. See also the :meth:`__iter__`
|
|
638
|
+
method, which returns the corresponding generator.
|
|
639
|
+
|
|
640
|
+
EXAMPLES::
|
|
641
|
+
|
|
642
|
+
sage: pconfig = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
643
|
+
sage: list(pconfig)
|
|
644
|
+
[P(0, 0), P(0, 1), P(1, 0), P(1, 1), P(-1, -1)]
|
|
645
|
+
sage: [ p for p in pconfig.points() ]
|
|
646
|
+
[P(0, 0), P(0, 1), P(1, 0), P(1, 1), P(-1, -1)]
|
|
647
|
+
sage: pconfig.point(0)
|
|
648
|
+
P(0, 0)
|
|
649
|
+
sage: pconfig.point(1)
|
|
650
|
+
P(0, 1)
|
|
651
|
+
sage: pconfig.point( pconfig.n_points()-1 )
|
|
652
|
+
P(-1, -1)
|
|
653
|
+
"""
|
|
654
|
+
return self._pts
|
|
655
|
+
|
|
656
|
+
def point(self, i):
|
|
657
|
+
"""
|
|
658
|
+
Return the `i`-th point of the configuration.
|
|
659
|
+
|
|
660
|
+
Same as :meth:`__getitem__`
|
|
661
|
+
|
|
662
|
+
INPUT:
|
|
663
|
+
|
|
664
|
+
- ``i`` -- integer
|
|
665
|
+
|
|
666
|
+
OUTPUT: a point of the point configuration
|
|
667
|
+
|
|
668
|
+
EXAMPLES::
|
|
669
|
+
|
|
670
|
+
sage: pconfig = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
671
|
+
sage: list(pconfig)
|
|
672
|
+
[P(0, 0), P(0, 1), P(1, 0), P(1, 1), P(-1, -1)]
|
|
673
|
+
sage: [ p for p in pconfig.points() ]
|
|
674
|
+
[P(0, 0), P(0, 1), P(1, 0), P(1, 1), P(-1, -1)]
|
|
675
|
+
sage: pconfig.point(0)
|
|
676
|
+
P(0, 0)
|
|
677
|
+
sage: pconfig[0]
|
|
678
|
+
P(0, 0)
|
|
679
|
+
sage: pconfig.point(1)
|
|
680
|
+
P(0, 1)
|
|
681
|
+
sage: pconfig.point( pconfig.n_points()-1 )
|
|
682
|
+
P(-1, -1)
|
|
683
|
+
"""
|
|
684
|
+
return self._pts[i]
|
|
685
|
+
|
|
686
|
+
def __len__(self):
|
|
687
|
+
"""
|
|
688
|
+
Return the number of points.
|
|
689
|
+
|
|
690
|
+
Same as :meth:`n_points`
|
|
691
|
+
|
|
692
|
+
EXAMPLES::
|
|
693
|
+
|
|
694
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
695
|
+
sage: p
|
|
696
|
+
A point configuration in affine 2-space over Integer Ring
|
|
697
|
+
consisting of 5 points. The triangulations of this point
|
|
698
|
+
configuration are assumed to be connected, not necessarily
|
|
699
|
+
fine, not necessarily regular.
|
|
700
|
+
sage: len(p)
|
|
701
|
+
5
|
|
702
|
+
sage: p.n_points()
|
|
703
|
+
5
|
|
704
|
+
"""
|
|
705
|
+
return len(self._pts)
|
|
706
|
+
|
|
707
|
+
cpdef simplex_to_int(self, simplex):
|
|
708
|
+
r"""
|
|
709
|
+
Return an integer that uniquely identifies the given simplex.
|
|
710
|
+
|
|
711
|
+
See also the inverse method :meth:`int_to_simplex`.
|
|
712
|
+
|
|
713
|
+
The enumeration is compatible with [PUNTOS]_.
|
|
714
|
+
|
|
715
|
+
INPUT:
|
|
716
|
+
|
|
717
|
+
- ``simplex`` -- iterable, for example a list. The elements
|
|
718
|
+
are the vertex indices of the simplex
|
|
719
|
+
|
|
720
|
+
OUTPUT: integer that uniquely specifies the simplex
|
|
721
|
+
|
|
722
|
+
EXAMPLES::
|
|
723
|
+
|
|
724
|
+
sage: U=matrix([
|
|
725
|
+
....: [ 0, 0, 0, 0, 0, 2, 4,-1, 1, 1, 0, 0, 1, 0],
|
|
726
|
+
....: [ 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0],
|
|
727
|
+
....: [ 0, 2, 0, 0, 0, 0,-1, 0, 1, 0, 1, 0, 0, 1],
|
|
728
|
+
....: [ 0, 1, 1, 0, 0, 1, 0,-2, 1, 0, 0,-1, 1, 1],
|
|
729
|
+
....: [ 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, 0, 0]
|
|
730
|
+
....: ])
|
|
731
|
+
sage: pc = PointConfiguration(U.columns())
|
|
732
|
+
sage: pc.simplex_to_int([1,3,4,7,10,13])
|
|
733
|
+
1678
|
|
734
|
+
sage: pc.int_to_simplex(1678)
|
|
735
|
+
(1, 3, 4, 7, 10, 13)
|
|
736
|
+
"""
|
|
737
|
+
cdef int s = 1
|
|
738
|
+
cdef int k = 1
|
|
739
|
+
cdef int n = self.n_points()
|
|
740
|
+
cdef int d = len(simplex)
|
|
741
|
+
assert d == self.dim()+1
|
|
742
|
+
cdef int i, j
|
|
743
|
+
for i in range(1, d+1):
|
|
744
|
+
l = simplex[i-1]+1
|
|
745
|
+
for j in range(k, l):
|
|
746
|
+
s += binomial(n-j, d-i)
|
|
747
|
+
k = l+1
|
|
748
|
+
return s
|
|
749
|
+
|
|
750
|
+
cpdef int_to_simplex(self, int s):
|
|
751
|
+
r"""
|
|
752
|
+
Reverse the enumeration of possible simplices in
|
|
753
|
+
:meth:`simplex_to_int`.
|
|
754
|
+
|
|
755
|
+
The enumeration is compatible with [PUNTOS]_.
|
|
756
|
+
|
|
757
|
+
INPUT:
|
|
758
|
+
|
|
759
|
+
- ``s`` -- integer that uniquely specifies a simplex
|
|
760
|
+
|
|
761
|
+
OUTPUT:
|
|
762
|
+
|
|
763
|
+
An ordered tuple consisting of the indices of the vertices of
|
|
764
|
+
the simplex.
|
|
765
|
+
|
|
766
|
+
EXAMPLES::
|
|
767
|
+
|
|
768
|
+
sage: U=matrix([
|
|
769
|
+
....: [ 0, 0, 0, 0, 0, 2, 4,-1, 1, 1, 0, 0, 1, 0],
|
|
770
|
+
....: [ 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0],
|
|
771
|
+
....: [ 0, 2, 0, 0, 0, 0,-1, 0, 1, 0, 1, 0, 0, 1],
|
|
772
|
+
....: [ 0, 1, 1, 0, 0, 1, 0,-2, 1, 0, 0,-1, 1, 1],
|
|
773
|
+
....: [ 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, 0, 0]
|
|
774
|
+
....: ])
|
|
775
|
+
sage: pc = PointConfiguration(U.columns())
|
|
776
|
+
sage: pc.simplex_to_int([1,3,4,7,10,13])
|
|
777
|
+
1678
|
|
778
|
+
sage: pc.int_to_simplex(1678)
|
|
779
|
+
(1, 3, 4, 7, 10, 13)
|
|
780
|
+
"""
|
|
781
|
+
simplex = []
|
|
782
|
+
cdef int l = 0
|
|
783
|
+
cdef int n = self.n_points()
|
|
784
|
+
cdef int d = self.dim() + 1
|
|
785
|
+
cdef int k, b
|
|
786
|
+
for k in range(1, d):
|
|
787
|
+
l += 1
|
|
788
|
+
j = 1
|
|
789
|
+
b = binomial(n - l, d - k)
|
|
790
|
+
while s > b > 0:
|
|
791
|
+
j += 1
|
|
792
|
+
l += 1
|
|
793
|
+
s -= b
|
|
794
|
+
b = binomial(n - l, d - k)
|
|
795
|
+
simplex.append(l - 1)
|
|
796
|
+
simplex.append(s + l - 1)
|
|
797
|
+
assert len(simplex) == d
|
|
798
|
+
return tuple(simplex)
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
########################################################################
|
|
802
|
+
cdef class ConnectedTriangulationsIterator(SageObject):
|
|
803
|
+
r"""
|
|
804
|
+
A Python shim for the C++-class 'triangulations'.
|
|
805
|
+
|
|
806
|
+
INPUT:
|
|
807
|
+
|
|
808
|
+
- ``point_configuration`` -- a
|
|
809
|
+
:class:`~sage.geometry.triangulation.point_configuration.PointConfiguration`
|
|
810
|
+
|
|
811
|
+
- ``seed`` -- a regular triangulation or ``None`` (default). In
|
|
812
|
+
the latter case, a suitable triangulation is generated
|
|
813
|
+
automatically. Otherwise, you can explicitly specify the seed
|
|
814
|
+
triangulation as
|
|
815
|
+
|
|
816
|
+
* A
|
|
817
|
+
:class:`~sage.geometry.triangulation.element.Triangulation`
|
|
818
|
+
object, or
|
|
819
|
+
|
|
820
|
+
* an iterable of iterables specifying the vertices of the simplices, or
|
|
821
|
+
|
|
822
|
+
* an iterable of integers, which are then considered the
|
|
823
|
+
enumerated simplices (see
|
|
824
|
+
:meth:`~PointConfiguration_base.simplex_to_int`.
|
|
825
|
+
|
|
826
|
+
- ``star`` -- either ``None`` (default) or an integer. If an
|
|
827
|
+
integer is passed, all returned triangulations will be star with
|
|
828
|
+
respect to the
|
|
829
|
+
|
|
830
|
+
- ``fine`` -- boolean (default: ``False``); whether to return only
|
|
831
|
+
fine triangulations, that is, simplicial decompositions that
|
|
832
|
+
make use of all the points of the configuration.
|
|
833
|
+
|
|
834
|
+
OUTPUT:
|
|
835
|
+
|
|
836
|
+
An iterator. The generated values are tuples of
|
|
837
|
+
integers, which encode simplices of the triangulation. The output
|
|
838
|
+
is a suitable input to
|
|
839
|
+
:class:`~sage.geometry.triangulation.element.Triangulation`.
|
|
840
|
+
|
|
841
|
+
EXAMPLES::
|
|
842
|
+
|
|
843
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
844
|
+
sage: from sage.geometry.triangulation.base import ConnectedTriangulationsIterator
|
|
845
|
+
sage: ci = ConnectedTriangulationsIterator(p)
|
|
846
|
+
sage: next(ci)
|
|
847
|
+
(9, 10)
|
|
848
|
+
sage: next(ci)
|
|
849
|
+
(2, 3, 4, 5)
|
|
850
|
+
sage: next(ci)
|
|
851
|
+
(7, 8)
|
|
852
|
+
sage: next(ci)
|
|
853
|
+
(1, 3, 5, 7)
|
|
854
|
+
sage: next(ci)
|
|
855
|
+
Traceback (most recent call last):
|
|
856
|
+
...
|
|
857
|
+
StopIteration
|
|
858
|
+
|
|
859
|
+
You can reconstruct the triangulation from the compressed output via::
|
|
860
|
+
|
|
861
|
+
sage: from sage.geometry.triangulation.element import Triangulation
|
|
862
|
+
sage: Triangulation((2, 3, 4, 5), p)
|
|
863
|
+
(<0,1,3>, <0,1,4>, <0,2,3>, <0,2,4>)
|
|
864
|
+
|
|
865
|
+
How to use the restrictions::
|
|
866
|
+
|
|
867
|
+
sage: ci = ConnectedTriangulationsIterator(p, fine=True)
|
|
868
|
+
sage: list(ci)
|
|
869
|
+
[(2, 3, 4, 5), (1, 3, 5, 7)]
|
|
870
|
+
sage: ci = ConnectedTriangulationsIterator(p, star=1)
|
|
871
|
+
sage: list(ci)
|
|
872
|
+
[(7, 8)]
|
|
873
|
+
sage: ci = ConnectedTriangulationsIterator(p, star=1, fine=True)
|
|
874
|
+
sage: list(ci)
|
|
875
|
+
[]
|
|
876
|
+
"""
|
|
877
|
+
|
|
878
|
+
cdef triangulations_ptr _tp
|
|
879
|
+
|
|
880
|
+
def __cinit__(self):
|
|
881
|
+
"""
|
|
882
|
+
The Cython constructor.
|
|
883
|
+
|
|
884
|
+
TESTS::
|
|
885
|
+
|
|
886
|
+
sage: from sage.geometry.triangulation.base import ConnectedTriangulationsIterator
|
|
887
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
888
|
+
sage: ConnectedTriangulationsIterator(p, fine=True) # indirect doctest
|
|
889
|
+
<sage.geometry.triangulation.base.ConnectedTriangulationsIterator object at ...>
|
|
890
|
+
"""
|
|
891
|
+
self._tp = NULL
|
|
892
|
+
|
|
893
|
+
def __init__(self, point_configuration, seed=None, star=None, fine=False):
|
|
894
|
+
r"""
|
|
895
|
+
The Python constructor.
|
|
896
|
+
|
|
897
|
+
See :class:`ConnectedTriangulationsIterator` for a description
|
|
898
|
+
of the arguments.
|
|
899
|
+
|
|
900
|
+
TESTS::
|
|
901
|
+
|
|
902
|
+
sage: p = PointConfiguration([[0,4],[2,3],[3,2],[4,0],[3,-2],[2,-3],[0,-4],[-2,-3],[-3,-2],[-4,0],[-3,2],[-2,3]])
|
|
903
|
+
sage: from sage.geometry.triangulation.base import ConnectedTriangulationsIterator
|
|
904
|
+
sage: ci = ConnectedTriangulationsIterator(p)
|
|
905
|
+
sage: len(list(ci)) # long time (26s on sage.math, 2012)
|
|
906
|
+
16796
|
|
907
|
+
sage: ci = ConnectedTriangulationsIterator(p, star=3)
|
|
908
|
+
sage: len(list(ci)) # long time (26s on sage.math, 2012)
|
|
909
|
+
1
|
|
910
|
+
"""
|
|
911
|
+
if star is None:
|
|
912
|
+
star = -1
|
|
913
|
+
if seed is None:
|
|
914
|
+
seed = point_configuration.lexicographic_triangulation().enumerate_simplices()
|
|
915
|
+
try:
|
|
916
|
+
enumerated_simplices_seed = seed.enumerated_simplices()
|
|
917
|
+
except AttributeError:
|
|
918
|
+
enumerated_simplices_seed = tuple([int(t) for t in seed])
|
|
919
|
+
assert self._tp == NULL
|
|
920
|
+
self._tp = init_triangulations(point_configuration.n_points(),
|
|
921
|
+
point_configuration.dim()+1,
|
|
922
|
+
star, fine,
|
|
923
|
+
enumerated_simplices_seed,
|
|
924
|
+
point_configuration.bistellar_flips())
|
|
925
|
+
|
|
926
|
+
def __dealloc__(self):
|
|
927
|
+
r"""
|
|
928
|
+
The Cython destructor.
|
|
929
|
+
"""
|
|
930
|
+
delete_triangulations(self._tp)
|
|
931
|
+
|
|
932
|
+
def __iter__(self):
|
|
933
|
+
r"""
|
|
934
|
+
The iterator interface: Start iterating.
|
|
935
|
+
|
|
936
|
+
TESTS::
|
|
937
|
+
|
|
938
|
+
sage: from sage.geometry.triangulation.base import ConnectedTriangulationsIterator
|
|
939
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
940
|
+
sage: ci = ConnectedTriangulationsIterator(p, fine=True)
|
|
941
|
+
sage: ci.__iter__()
|
|
942
|
+
<sage.geometry.triangulation.base.ConnectedTriangulationsIterator object at ...>
|
|
943
|
+
sage: ci.__iter__() is ci
|
|
944
|
+
True
|
|
945
|
+
"""
|
|
946
|
+
return self
|
|
947
|
+
|
|
948
|
+
def __next__(self):
|
|
949
|
+
r"""
|
|
950
|
+
The iterator interface: Next iteration.
|
|
951
|
+
|
|
952
|
+
EXAMPLES::
|
|
953
|
+
|
|
954
|
+
sage: from sage.geometry.triangulation.base import ConnectedTriangulationsIterator
|
|
955
|
+
sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]])
|
|
956
|
+
sage: ci = ConnectedTriangulationsIterator(p)
|
|
957
|
+
sage: ci.__next__()
|
|
958
|
+
(9, 10)
|
|
959
|
+
"""
|
|
960
|
+
t = next_triangulation(self._tp)
|
|
961
|
+
if not t:
|
|
962
|
+
raise StopIteration
|
|
963
|
+
return t
|