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.

Files changed (208) hide show
  1. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
  2. passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
  3. passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +208 -0
  4. passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +5 -0
  5. passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
  6. passagemath_polyhedra.libs/libgcc_s-2d945d6c.so.1 +0 -0
  7. passagemath_polyhedra.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  8. passagemath_polyhedra.libs/libgomp-1ede7ee7.so.1.0.0 +0 -0
  9. passagemath_polyhedra.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  10. sage/all__sagemath_polyhedra.py +50 -0
  11. sage/game_theory/all.py +8 -0
  12. sage/game_theory/catalog.py +6 -0
  13. sage/game_theory/catalog_normal_form_games.py +923 -0
  14. sage/game_theory/cooperative_game.py +844 -0
  15. sage/game_theory/matching_game.py +1181 -0
  16. sage/game_theory/normal_form_game.py +2697 -0
  17. sage/game_theory/parser.py +275 -0
  18. sage/geometry/all__sagemath_polyhedra.py +22 -0
  19. sage/geometry/cone.py +6940 -0
  20. sage/geometry/cone_catalog.py +847 -0
  21. sage/geometry/cone_critical_angles.py +1027 -0
  22. sage/geometry/convex_set.py +1119 -0
  23. sage/geometry/fan.py +3743 -0
  24. sage/geometry/fan_isomorphism.py +389 -0
  25. sage/geometry/fan_morphism.py +1884 -0
  26. sage/geometry/hasse_diagram.py +202 -0
  27. sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
  28. sage/geometry/hyperplane_arrangement/all.py +1 -0
  29. sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
  30. sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
  31. sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
  32. sage/geometry/hyperplane_arrangement/library.py +825 -0
  33. sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
  34. sage/geometry/hyperplane_arrangement/plot.py +520 -0
  35. sage/geometry/integral_points.py +35 -0
  36. sage/geometry/integral_points_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
  37. sage/geometry/integral_points_generic_dense.pyx +7 -0
  38. sage/geometry/lattice_polytope.py +5894 -0
  39. sage/geometry/linear_expression.py +773 -0
  40. sage/geometry/newton_polygon.py +767 -0
  41. sage/geometry/point_collection.cpython-314-aarch64-linux-musl.so +0 -0
  42. sage/geometry/point_collection.pyx +1008 -0
  43. sage/geometry/polyhedral_complex.py +2616 -0
  44. sage/geometry/polyhedron/all.py +8 -0
  45. sage/geometry/polyhedron/backend_cdd.py +460 -0
  46. sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
  47. sage/geometry/polyhedron/backend_field.py +347 -0
  48. sage/geometry/polyhedron/backend_normaliz.py +2503 -0
  49. sage/geometry/polyhedron/backend_number_field.py +168 -0
  50. sage/geometry/polyhedron/backend_polymake.py +765 -0
  51. sage/geometry/polyhedron/backend_ppl.py +582 -0
  52. sage/geometry/polyhedron/base.py +1206 -0
  53. sage/geometry/polyhedron/base0.py +1444 -0
  54. sage/geometry/polyhedron/base1.py +886 -0
  55. sage/geometry/polyhedron/base2.py +812 -0
  56. sage/geometry/polyhedron/base3.py +1845 -0
  57. sage/geometry/polyhedron/base4.py +1262 -0
  58. sage/geometry/polyhedron/base5.py +2700 -0
  59. sage/geometry/polyhedron/base6.py +1741 -0
  60. sage/geometry/polyhedron/base7.py +997 -0
  61. sage/geometry/polyhedron/base_QQ.py +1258 -0
  62. sage/geometry/polyhedron/base_RDF.py +98 -0
  63. sage/geometry/polyhedron/base_ZZ.py +934 -0
  64. sage/geometry/polyhedron/base_mutable.py +215 -0
  65. sage/geometry/polyhedron/base_number_field.py +122 -0
  66. sage/geometry/polyhedron/cdd_file_format.py +155 -0
  67. sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
  68. sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-aarch64-linux-musl.so +0 -0
  69. sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
  70. sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
  71. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-aarch64-linux-musl.so +0 -0
  72. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
  73. sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
  74. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-aarch64-linux-musl.so +0 -0
  75. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
  76. sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
  77. sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
  78. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-aarch64-linux-musl.so +0 -0
  79. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
  80. sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
  81. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-aarch64-linux-musl.so +0 -0
  82. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
  83. sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
  84. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-aarch64-linux-musl.so +0 -0
  85. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
  86. sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
  87. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-aarch64-linux-musl.so +0 -0
  88. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
  89. sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
  90. sage/geometry/polyhedron/constructor.py +773 -0
  91. sage/geometry/polyhedron/double_description.py +753 -0
  92. sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
  93. sage/geometry/polyhedron/face.py +1060 -0
  94. sage/geometry/polyhedron/generating_function.py +1810 -0
  95. sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
  96. sage/geometry/polyhedron/library.py +3502 -0
  97. sage/geometry/polyhedron/misc.py +121 -0
  98. sage/geometry/polyhedron/modules/all.py +1 -0
  99. sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
  100. sage/geometry/polyhedron/palp_database.py +447 -0
  101. sage/geometry/polyhedron/parent.py +1279 -0
  102. sage/geometry/polyhedron/plot.py +1986 -0
  103. sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
  104. sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
  105. sage/geometry/polyhedron/representation.py +1723 -0
  106. sage/geometry/pseudolines.py +515 -0
  107. sage/geometry/relative_interior.py +445 -0
  108. sage/geometry/toric_plotter.py +1103 -0
  109. sage/geometry/triangulation/all.py +2 -0
  110. sage/geometry/triangulation/base.cpython-314-aarch64-linux-musl.so +0 -0
  111. sage/geometry/triangulation/base.pyx +963 -0
  112. sage/geometry/triangulation/data.h +147 -0
  113. sage/geometry/triangulation/data.pxd +4 -0
  114. sage/geometry/triangulation/element.py +914 -0
  115. sage/geometry/triangulation/functions.h +10 -0
  116. sage/geometry/triangulation/functions.pxd +4 -0
  117. sage/geometry/triangulation/point_configuration.py +2256 -0
  118. sage/geometry/triangulation/triangulations.h +49 -0
  119. sage/geometry/triangulation/triangulations.pxd +7 -0
  120. sage/geometry/voronoi_diagram.py +319 -0
  121. sage/interfaces/all__sagemath_polyhedra.py +1 -0
  122. sage/interfaces/polymake.py +2028 -0
  123. sage/numerical/all.py +13 -0
  124. sage/numerical/all__sagemath_polyhedra.py +11 -0
  125. sage/numerical/backends/all.py +1 -0
  126. sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
  127. sage/numerical/backends/cvxopt_backend.cpython-314-aarch64-linux-musl.so +0 -0
  128. sage/numerical/backends/cvxopt_backend.pyx +1006 -0
  129. sage/numerical/backends/cvxopt_backend_test.py +19 -0
  130. sage/numerical/backends/cvxopt_sdp_backend.cpython-314-aarch64-linux-musl.so +0 -0
  131. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  132. sage/numerical/backends/cvxpy_backend.cpython-314-aarch64-linux-musl.so +0 -0
  133. sage/numerical/backends/cvxpy_backend.pxd +41 -0
  134. sage/numerical/backends/cvxpy_backend.pyx +934 -0
  135. sage/numerical/backends/cvxpy_backend_test.py +13 -0
  136. sage/numerical/backends/generic_backend_test.py +24 -0
  137. sage/numerical/backends/interactivelp_backend.cpython-314-aarch64-linux-musl.so +0 -0
  138. sage/numerical/backends/interactivelp_backend.pxd +36 -0
  139. sage/numerical/backends/interactivelp_backend.pyx +1231 -0
  140. sage/numerical/backends/interactivelp_backend_test.py +12 -0
  141. sage/numerical/backends/logging_backend.py +391 -0
  142. sage/numerical/backends/matrix_sdp_backend.cpython-314-aarch64-linux-musl.so +0 -0
  143. sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
  144. sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
  145. sage/numerical/backends/ppl_backend.cpython-314-aarch64-linux-musl.so +0 -0
  146. sage/numerical/backends/ppl_backend.pyx +1126 -0
  147. sage/numerical/backends/ppl_backend_test.py +13 -0
  148. sage/numerical/backends/scip_backend.cpython-314-aarch64-linux-musl.so +0 -0
  149. sage/numerical/backends/scip_backend.pxd +22 -0
  150. sage/numerical/backends/scip_backend.pyx +1289 -0
  151. sage/numerical/backends/scip_backend_test.py +13 -0
  152. sage/numerical/interactive_simplex_method.py +5338 -0
  153. sage/numerical/knapsack.py +665 -0
  154. sage/numerical/linear_functions.cpython-314-aarch64-linux-musl.so +0 -0
  155. sage/numerical/linear_functions.pxd +31 -0
  156. sage/numerical/linear_functions.pyx +1648 -0
  157. sage/numerical/linear_tensor.py +470 -0
  158. sage/numerical/linear_tensor_constraints.py +448 -0
  159. sage/numerical/linear_tensor_element.cpython-314-aarch64-linux-musl.so +0 -0
  160. sage/numerical/linear_tensor_element.pxd +6 -0
  161. sage/numerical/linear_tensor_element.pyx +459 -0
  162. sage/numerical/mip.cpython-314-aarch64-linux-musl.so +0 -0
  163. sage/numerical/mip.pxd +40 -0
  164. sage/numerical/mip.pyx +3667 -0
  165. sage/numerical/sdp.cpython-314-aarch64-linux-musl.so +0 -0
  166. sage/numerical/sdp.pxd +39 -0
  167. sage/numerical/sdp.pyx +1433 -0
  168. sage/rings/all__sagemath_polyhedra.py +3 -0
  169. sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
  170. sage/rings/polynomial/omega.py +982 -0
  171. sage/schemes/all__sagemath_polyhedra.py +2 -0
  172. sage/schemes/toric/all.py +10 -0
  173. sage/schemes/toric/chow_group.py +1248 -0
  174. sage/schemes/toric/divisor.py +2082 -0
  175. sage/schemes/toric/divisor_class.cpython-314-aarch64-linux-musl.so +0 -0
  176. sage/schemes/toric/divisor_class.pyx +322 -0
  177. sage/schemes/toric/fano_variety.py +1606 -0
  178. sage/schemes/toric/homset.py +650 -0
  179. sage/schemes/toric/ideal.py +451 -0
  180. sage/schemes/toric/library.py +1322 -0
  181. sage/schemes/toric/morphism.py +1958 -0
  182. sage/schemes/toric/points.py +1032 -0
  183. sage/schemes/toric/sheaf/all.py +1 -0
  184. sage/schemes/toric/sheaf/constructor.py +302 -0
  185. sage/schemes/toric/sheaf/klyachko.py +921 -0
  186. sage/schemes/toric/toric_subscheme.py +905 -0
  187. sage/schemes/toric/variety.py +3460 -0
  188. sage/schemes/toric/weierstrass.py +1078 -0
  189. sage/schemes/toric/weierstrass_covering.py +457 -0
  190. sage/schemes/toric/weierstrass_higher.py +288 -0
  191. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
  192. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
  193. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
  194. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
  195. sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
  196. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
  197. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
  198. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
  199. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
  200. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
  201. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
  202. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
  203. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
  204. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
  205. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
  206. sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
  207. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
  208. sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
@@ -0,0 +1,389 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ """
3
+ Find isomorphisms between fans
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2012 Volker Braun <vbraun.name@gmail.com>
7
+ #
8
+ # Distributed under the terms of the GNU General Public License (GPL)
9
+ # as published by the Free Software Foundation; either version 2 of
10
+ # the License, or (at your option) any later version.
11
+ # https://www.gnu.org/licenses/
12
+ # ****************************************************************************
13
+ from sage.rings.integer_ring import ZZ
14
+ from sage.matrix.constructor import column_matrix, matrix
15
+ from sage.geometry.cone import Cone
16
+
17
+
18
+ class FanNotIsomorphicError(Exception):
19
+ """
20
+ Exception to return if there is no fan isomorphism
21
+ """
22
+ pass
23
+
24
+
25
+ def fan_isomorphic_necessary_conditions(fan1, fan2):
26
+ """
27
+ Check necessary (but not sufficient) conditions for the fans to be isomorphic.
28
+
29
+ INPUT:
30
+
31
+ - ``fan1``, ``fan2`` -- two fans
32
+
33
+ OUTPUT: boolean; ``False`` if the two fans cannot be isomorphic. ``True``
34
+ if the two fans may be isomorphic.
35
+
36
+ EXAMPLES::
37
+
38
+ sage: fan1 = toric_varieties.P2().fan() # needs palp sage.graphs
39
+ sage: fan2 = toric_varieties.dP8().fan() # needs palp sage.graphs
40
+ sage: from sage.geometry.fan_isomorphism import fan_isomorphic_necessary_conditions
41
+ sage: fan_isomorphic_necessary_conditions(fan1, fan2) # needs palp sage.graphs
42
+ False
43
+ """
44
+ if fan1.lattice_dim() != fan2.lattice_dim():
45
+ return False
46
+ if fan1.dim() != fan2.dim():
47
+ return False
48
+ if fan1.nrays() != fan2.nrays():
49
+ return False
50
+ if fan1.ngenerating_cones() != fan2.ngenerating_cones():
51
+ return False
52
+ if fan1.is_complete() != fan2.is_complete():
53
+ return False
54
+ return True
55
+
56
+
57
+ def fan_isomorphism_generator(fan1, fan2):
58
+ """
59
+ Iterate over the isomorphisms from ``fan1`` to ``fan2``.
60
+
61
+ ALGORITHM:
62
+
63
+ The :meth:`sage.geometry.fan.Fan.vertex_graph` of the two fans is
64
+ compared. For each graph isomorphism, we attempt to lift it to an
65
+ actual isomorphism of fans.
66
+
67
+ INPUT:
68
+
69
+ - ``fan1``, ``fan2`` -- two fans
70
+
71
+ OUTPUT:
72
+
73
+ Yields the fan isomorphisms as matrices acting from the right on
74
+ rays.
75
+
76
+ EXAMPLES::
77
+
78
+ sage: fan = toric_varieties.P2().fan() # needs palp sage.graphs
79
+ sage: from sage.geometry.fan_isomorphism import fan_isomorphism_generator
80
+ sage: sorted(fan_isomorphism_generator(fan, fan)) # needs palp sage.graphs
81
+ [
82
+ [-1 -1] [-1 -1] [ 0 1] [0 1] [ 1 0] [1 0]
83
+ [ 0 1], [ 1 0], [-1 -1], [1 0], [-1 -1], [0 1]
84
+ ]
85
+ sage: m1 = matrix([(1, 0), (0, -5), (-3, 4)])
86
+ sage: m2 = matrix([(3, 0), (1, 0), (-2, 1)])
87
+ sage: m1.elementary_divisors() == m2.elementary_divisors() == [1,1,0]
88
+ True
89
+ sage: fan1 = Fan([Cone([m1*vector([23, 14]), m1*vector([ 3,100])]),
90
+ ....: Cone([m1*vector([-1,-14]), m1*vector([-100, -5])])])
91
+ sage: fan2 = Fan([Cone([m2*vector([23, 14]), m2*vector([ 3,100])]),
92
+ ....: Cone([m2*vector([-1,-14]), m2*vector([-100, -5])])])
93
+ sage: sorted(fan_isomorphism_generator(fan1, fan2)) # needs sage.graphs
94
+ [
95
+ [-12 1 -5]
96
+ [ -4 0 -1]
97
+ [ -5 0 -1]
98
+ ]
99
+
100
+ sage: m0 = identity_matrix(ZZ, 2)
101
+ sage: m1 = matrix([(1, 0), (0, -5), (-3, 4)])
102
+ sage: m2 = matrix([(3, 0), (1, 0), (-2, 1)])
103
+ sage: m1.elementary_divisors() == m2.elementary_divisors() == [1,1,0]
104
+ True
105
+ sage: fan0 = Fan([Cone([m0*vector([1,0]), m0*vector([1,1])]),
106
+ ....: Cone([m0*vector([1,1]), m0*vector([0,1])])])
107
+ sage: fan1 = Fan([Cone([m1*vector([1,0]), m1*vector([1,1])]),
108
+ ....: Cone([m1*vector([1,1]), m1*vector([0,1])])])
109
+ sage: fan2 = Fan([Cone([m2*vector([1,0]), m2*vector([1,1])]),
110
+ ....: Cone([m2*vector([1,1]), m2*vector([0,1])])])
111
+ sage: sorted(fan_isomorphism_generator(fan0, fan0)) # needs sage.graphs
112
+ [
113
+ [0 1] [1 0]
114
+ [1 0], [0 1]
115
+ ]
116
+ sage: sorted(fan_isomorphism_generator(fan1, fan1)) # needs sage.graphs
117
+ [
118
+ [ -3 -20 28] [1 0 0]
119
+ [ -1 -4 7] [0 1 0]
120
+ [ -1 -5 8], [0 0 1]
121
+ ]
122
+ sage: sorted(fan_isomorphism_generator(fan1, fan2)) # needs sage.graphs
123
+ [
124
+ [-24 -3 7] [-12 1 -5]
125
+ [ -7 -1 2] [ -4 0 -1]
126
+ [ -8 -1 2], [ -5 0 -1]
127
+ ]
128
+ sage: sorted(fan_isomorphism_generator(fan2, fan1)) # needs sage.graphs
129
+ [
130
+ [ 0 1 -1] [ 0 1 -1]
131
+ [ 1 -13 8] [ 2 -8 1]
132
+ [ 0 -5 4], [ 1 0 -3]
133
+ ]
134
+ """
135
+ if not fan_isomorphic_necessary_conditions(fan1, fan2):
136
+ return
137
+
138
+ graph1 = fan1.vertex_graph()
139
+ graph2 = fan2.vertex_graph()
140
+ graph_iso = graph1.is_isomorphic(graph2, edge_labels=True, certificate=True)
141
+ if not graph_iso[0]:
142
+ return
143
+ graph_iso = graph_iso[1]
144
+
145
+ # Pick a basis of rays in fan1
146
+ max_cone = fan1(fan1.dim())[0]
147
+ fan1_pivot_rays = max_cone.rays()
148
+ fan1_basis = fan1_pivot_rays + fan1.virtual_rays() # A QQ-basis for N_1
149
+ fan1_pivot_cones = [ fan1.embed(Cone([r])) for r in fan1_pivot_rays ]
150
+
151
+ # The fan2 cones as set(set(ray indices))
152
+ fan2_cones = frozenset(
153
+ frozenset(cone.ambient_ray_indices())
154
+ for cone in fan2.generating_cones() )
155
+
156
+ # iterate over all graph isomorphisms graph1 -> graph2
157
+ for perm in graph2.automorphism_group(edge_labels=True):
158
+ # find a candidate m that maps fan1_basis to the image rays under the graph isomorphism
159
+ fan2_pivot_cones = [ perm(graph_iso[c]) for c in fan1_pivot_cones ]
160
+ fan2_pivot_rays = fan2.rays([ c.ambient_ray_indices()[0] for c in fan2_pivot_cones ])
161
+ fan2_basis = fan2_pivot_rays + fan2.virtual_rays()
162
+ try:
163
+ m = matrix(ZZ, fan1_basis).solve_right(matrix(ZZ, fan2_basis))
164
+ m = m.change_ring(ZZ)
165
+ except (ValueError, TypeError):
166
+ continue # no solution
167
+
168
+ # check that the candidate m lifts the vertex graph homomorphism
169
+ graph_image_ray_indices = [ perm(graph_iso[c]).ambient_ray_indices()[0] for c in fan1(1) ]
170
+ try:
171
+ matrix_image_ray_indices = [ fan2.rays().index(r*m) for r in fan1.rays() ]
172
+ except ValueError:
173
+ continue
174
+ if graph_image_ray_indices != matrix_image_ray_indices:
175
+ continue
176
+
177
+ # check that the candidate m maps generating cone to generating cone
178
+ image_cones = frozenset( # The image(fan1) cones as set(set(integers)
179
+ frozenset(graph_image_ray_indices[i]
180
+ for i in cone.ambient_ray_indices())
181
+ for cone in fan1.generating_cones() )
182
+ if image_cones == fan2_cones:
183
+ m.set_immutable()
184
+ yield m
185
+
186
+
187
+ def find_isomorphism(fan1, fan2, check=False):
188
+ """
189
+ Find an isomorphism of the two fans.
190
+
191
+ INPUT:
192
+
193
+ - ``fan1``, ``fan2`` -- two fans
194
+
195
+ - ``check`` -- boolean (default: ``False``); passed to the fan
196
+ morphism constructor, see
197
+ :func:`~sage.geometry.fan_morphism.FanMorphism`
198
+
199
+ OUTPUT:
200
+
201
+ A fan isomorphism. If the fans are not isomorphic, a
202
+ :exc:`FanNotIsomorphicError` is raised.
203
+
204
+ EXAMPLES::
205
+
206
+ sage: rays = ((1, 1), (0, 1), (-1, -1), (3, 1))
207
+ sage: cones = [(0,1), (1,2), (2,3), (3,0)]
208
+ sage: fan1 = Fan(cones, rays)
209
+
210
+ sage: m = matrix([[-2,3],[1,-1]])
211
+ sage: m.det() == -1
212
+ True
213
+ sage: fan2 = Fan(cones, [vector(r)*m for r in rays])
214
+
215
+ sage: from sage.geometry.fan_isomorphism import find_isomorphism
216
+ sage: find_isomorphism(fan1, fan2, check=True) # needs sage.graphs
217
+ Fan morphism defined by the matrix
218
+ [-2 3]
219
+ [ 1 -1]
220
+ Domain fan: Rational polyhedral fan in 2-d lattice N
221
+ Codomain fan: Rational polyhedral fan in 2-d lattice N
222
+
223
+ sage: find_isomorphism(fan1, toric_varieties.P2().fan()) # needs palp sage.graphs
224
+ Traceback (most recent call last):
225
+ ...
226
+ FanNotIsomorphicError
227
+
228
+ sage: fan1 = Fan(cones=[[1,3,4,5],[0,1,2,3],[2,3,4],[0,1,5]],
229
+ ....: rays=[(-1,-1,0),(-1,-1,3),(-1,1,-1),(-1,3,-1),(0,2,-1),(1,-1,1)])
230
+ sage: fan2 = Fan(cones=[[0,2,3,5],[0,1,4,5],[0,1,2],[3,4,5]],
231
+ ....: rays=[(-1,-1,-1),(-1,-1,0),(-1,1,-1),(0,2,-1),(1,-1,1),(3,-1,-1)])
232
+ sage: fan1.is_isomorphic(fan2) # needs sage.graphs
233
+ True
234
+ """
235
+ generator = fan_isomorphism_generator(fan1, fan2)
236
+ try:
237
+ m = next(generator)
238
+ except StopIteration:
239
+ raise FanNotIsomorphicError
240
+
241
+ from sage.geometry.fan_morphism import FanMorphism
242
+ return FanMorphism(m, domain_fan=fan1, codomain=fan2, check=check)
243
+
244
+
245
+ def fan_2d_cyclically_ordered_rays(fan):
246
+ """
247
+ Return the rays of a 2-dimensional ``fan`` in cyclic order.
248
+
249
+ INPUT:
250
+
251
+ - ``fan`` -- a 2-dimensional fan
252
+
253
+ OUTPUT:
254
+
255
+ A :class:`~sage.geometry.point_collection.PointCollection`
256
+ containing the rays in one particular cyclic order.
257
+
258
+ EXAMPLES::
259
+
260
+ sage: rays = ((1, 1), (-1, -1), (-1, 1), (1, -1))
261
+ sage: cones = [(0,2), (2,1), (1,3), (3,0)]
262
+ sage: fan = Fan(cones, rays)
263
+ sage: fan.rays()
264
+ N( 1, 1),
265
+ N(-1, -1),
266
+ N(-1, 1),
267
+ N( 1, -1)
268
+ in 2-d lattice N
269
+ sage: from sage.geometry.fan_isomorphism import fan_2d_cyclically_ordered_rays
270
+ sage: fan_2d_cyclically_ordered_rays(fan)
271
+ N(-1, -1),
272
+ N(-1, 1),
273
+ N( 1, 1),
274
+ N( 1, -1)
275
+ in 2-d lattice N
276
+
277
+ TESTS::
278
+
279
+ sage: fan = Fan(cones=[], rays=[], lattice=ZZ^2)
280
+ sage: from sage.geometry.fan_isomorphism import fan_2d_cyclically_ordered_rays
281
+ sage: fan_2d_cyclically_ordered_rays(fan)
282
+ Empty collection
283
+ in Ambient free module of rank 2 over the principal ideal domain Integer Ring
284
+ """
285
+ assert fan.lattice_dim() == 2
286
+ import math
287
+ rays = [ (math.atan2(r[0],r[1]), r) for r in fan.rays() ]
288
+ rays = [ r[1] for r in sorted(rays) ]
289
+ from sage.geometry.point_collection import PointCollection
290
+ return PointCollection(rays, fan.lattice())
291
+
292
+
293
+ def fan_2d_echelon_forms(fan):
294
+ """
295
+ Return echelon forms of all cyclically ordered ray matrices.
296
+
297
+ Note that the echelon form of the ordered ray matrices are unique
298
+ up to different cyclic orderings.
299
+
300
+ INPUT:
301
+
302
+ - ``fan`` -- a fan
303
+
304
+ OUTPUT:
305
+
306
+ A set of matrices. The set of all echelon forms for all different
307
+ cyclic orderings.
308
+
309
+ EXAMPLES::
310
+
311
+ sage: fan = toric_varieties.P2().fan() # needs palp sage.graphs
312
+ sage: from sage.geometry.fan_isomorphism import fan_2d_echelon_forms
313
+ sage: fan_2d_echelon_forms(fan) # needs palp sage.graphs
314
+ frozenset({[ 1 0 -1]
315
+ [ 0 1 -1]})
316
+
317
+ sage: fan = toric_varieties.dP7().fan() # needs palp sage.graphs
318
+ sage: sorted(fan_2d_echelon_forms(fan)) # needs palp sage.graphs
319
+ [
320
+ [ 1 0 -1 -1 0] [ 1 0 -1 -1 0] [ 1 0 -1 -1 1] [ 1 0 -1 0 1]
321
+ [ 0 1 0 -1 -1], [ 0 1 1 0 -1], [ 0 1 1 0 -1], [ 0 1 0 -1 -1],
322
+ <BLANKLINE>
323
+ [ 1 0 -1 0 1]
324
+ [ 0 1 1 -1 -1]
325
+ ]
326
+
327
+ TESTS::
328
+
329
+ sage: rays = [(1, 1), (-1, -1), (-1, 1), (1, -1)]
330
+ sage: cones = [(0,2), (2,1), (1,3), (3,0)]
331
+ sage: fan1 = Fan(cones, rays)
332
+ sage: from sage.geometry.fan_isomorphism import fan_2d_echelon_form, fan_2d_echelon_forms
333
+ sage: echelon_forms = fan_2d_echelon_forms(fan1)
334
+ sage: S4 = CyclicPermutationGroup(4) # needs sage.groups
335
+ sage: rays.reverse()
336
+ sage: cones = [(3,1), (1,2), (2,0), (0,3)]
337
+ sage: for i in range(100): # needs sage.groups
338
+ ....: m = random_matrix(ZZ,2,2)
339
+ ....: if abs(det(m)) != 1: continue
340
+ ....: perm = S4.random_element()
341
+ ....: perm_cones = [ (perm(c[0]+1)-1, perm(c[1]+1)-1) for c in cones ]
342
+ ....: perm_rays = [ rays[perm(i+1)-1] for i in range(len(rays)) ]
343
+ ....: fan2 = Fan(perm_cones, rays=[m*vector(r) for r in perm_rays])
344
+ ....: assert fan_2d_echelon_form(fan2) in echelon_forms
345
+
346
+ The trivial case was fixed in :issue:`18613`::
347
+
348
+ sage: fan = Fan([], lattice=ToricLattice(2))
349
+ sage: fan_2d_echelon_forms(fan)
350
+ frozenset({[]})
351
+ sage: parent(list(_)[0])
352
+ Full MatrixSpace of 2 by 0 dense matrices over Integer Ring
353
+ """
354
+ if fan.nrays() == 0:
355
+ return frozenset([fan_2d_echelon_form(fan)])
356
+ rays = list(fan_2d_cyclically_ordered_rays(fan))
357
+ echelon_forms = []
358
+ for i in range(2):
359
+ for j in range(len(rays)):
360
+ echelon_forms.append(column_matrix(rays).echelon_form())
361
+ first = rays.pop(0)
362
+ rays.append(first)
363
+ rays.reverse()
364
+ return frozenset(echelon_forms)
365
+
366
+
367
+ def fan_2d_echelon_form(fan):
368
+ """
369
+ Return echelon form of a cyclically ordered ray matrix.
370
+
371
+ INPUT:
372
+
373
+ - ``fan`` -- a fan
374
+
375
+ OUTPUT:
376
+
377
+ A matrix. The echelon form of the rays in one particular cyclic
378
+ order.
379
+
380
+ EXAMPLES::
381
+
382
+ sage: fan = toric_varieties.P2().fan() # needs palp sage.graphs
383
+ sage: from sage.geometry.fan_isomorphism import fan_2d_echelon_form
384
+ sage: fan_2d_echelon_form(fan) # needs palp sage.graphs
385
+ [ 1 0 -1]
386
+ [ 0 1 -1]
387
+ """
388
+ ray_matrix = fan_2d_cyclically_ordered_rays(fan).column_matrix()
389
+ return ray_matrix.echelon_form()