passagemath-polyhedra 10.6.31rc3__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.

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-0cd532bd.so.1 +0 -0
  7. passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  8. passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
  9. passagemath_polyhedra.libs/libstdc++-5d72f927.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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-linux-musl.so +0 -0
  131. sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
  132. sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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-x86_64-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,982 @@
1
+ # sage_setup: distribution = sagemath-polyhedra
2
+ # sage.doctest: needs sage.libs.singular
3
+ r"""
4
+ MacMahon's Partition Analysis Omega Operator
5
+
6
+ This module implements :func:`MacMahon's Omega Operator <MacMahonOmega>`
7
+ [Mac1915]_, which takes a quotient of Laurent polynomials and
8
+ removes all negative exponents in the corresponding power series.
9
+
10
+
11
+ Examples
12
+ ========
13
+
14
+ In the following example, all negative exponents of `\mu` are removed.
15
+ The formula
16
+
17
+ .. MATH::
18
+
19
+ \Omega_{\ge} \frac{1}{(1 - x\mu) (1 - y/\mu)}
20
+ = \frac{1}{(1 - x) (1 - xy)}
21
+
22
+ can be calculated and verified by
23
+ ::
24
+
25
+ sage: L.<mu, x, y> = LaurentPolynomialRing(ZZ)
26
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu])
27
+ 1 * (-x + 1)^-1 * (-x*y + 1)^-1
28
+
29
+
30
+ Various
31
+ =======
32
+
33
+ AUTHORS:
34
+
35
+ - Daniel Krenn (2016)
36
+
37
+ ACKNOWLEDGEMENT:
38
+
39
+ - Daniel Krenn is supported by the Austrian Science Fund (FWF): P 24644-N26.
40
+
41
+ Functions
42
+ =========
43
+ """
44
+ # ****************************************************************************
45
+ # Copyright (C) 2016 Daniel Krenn <dev@danielkrenn.at>
46
+ #
47
+ # This program is free software: you can redistribute it and/or modify
48
+ # it under the terms of the GNU General Public License as published by
49
+ # the Free Software Foundation, either version 2 of the License, or
50
+ # (at your option) any later version.
51
+ # https://www.gnu.org/licenses/
52
+ # ****************************************************************************
53
+ import operator
54
+
55
+ from sage.misc.cachefunc import cached_function
56
+
57
+
58
+ def MacMahonOmega(var, expression, denominator=None, op=operator.ge,
59
+ Factorization_sort=False, Factorization_simplify=True):
60
+ r"""
61
+ Return `\Omega_{\mathrm{op}}` of ``expression`` with respect to ``var``.
62
+
63
+ To be more precise, calculate
64
+
65
+ .. MATH::
66
+
67
+ \Omega_{\mathrm{op}} \frac{n}{d_1 \dots d_n}
68
+
69
+ for the numerator `n` and the factors `d_1`, ..., `d_n` of
70
+ the denominator, all of which are Laurent polynomials in ``var``
71
+ and return a (partial) factorization of the result.
72
+
73
+ INPUT:
74
+
75
+ - ``var`` -- a variable or a representation string of a variable
76
+
77
+ - ``expression`` -- a
78
+ :class:`~sage.structure.factorization.Factorization`
79
+ of Laurent polynomials or, if ``denominator`` is specified,
80
+ a Laurent polynomial interpreted as the numerator of the
81
+ expression
82
+
83
+ - ``denominator`` -- a Laurent polynomial or a
84
+ :class:`~sage.structure.factorization.Factorization` (consisting
85
+ of Laurent polynomial factors) or a tuple/list of factors (Laurent
86
+ polynomials)
87
+
88
+ - ``op`` -- (default: ``operator.ge``) an operator
89
+
90
+ At the moment only ``operator.ge`` is implemented.
91
+
92
+ - ``Factorization_sort`` (default: ``False``) and
93
+ ``Factorization_simplify`` (default: ``True``) -- are passed on to
94
+ :class:`sage.structure.factorization.Factorization` when creating
95
+ the result
96
+
97
+ OUTPUT:
98
+
99
+ A (partial) :class:`~sage.structure.factorization.Factorization`
100
+ of the result whose factors are Laurent polynomials
101
+
102
+ .. NOTE::
103
+
104
+ The numerator of the result may not be factored.
105
+
106
+ REFERENCES:
107
+
108
+ - [Mac1915]_
109
+
110
+ - [APR2001]_
111
+
112
+ EXAMPLES::
113
+
114
+ sage: L.<mu, x, y, z, w> = LaurentPolynomialRing(ZZ)
115
+
116
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu])
117
+ 1 * (-x + 1)^-1 * (-x*y + 1)^-1
118
+
119
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu, 1 - z/mu])
120
+ 1 * (-x + 1)^-1 * (-x*y + 1)^-1 * (-x*z + 1)^-1
121
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu])
122
+ (-x*y*z + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x*z + 1)^-1 * (-y*z + 1)^-1
123
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^2])
124
+ 1 * (-x + 1)^-1 * (-x^2*y + 1)^-1
125
+ sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y/mu])
126
+ (x*y + 1) * (-x + 1)^-1 * (-x*y^2 + 1)^-1
127
+
128
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu^2])
129
+ (-x^2*y*z - x*y^2*z + x*y*z + 1) *
130
+ (-x + 1)^-1 * (-y + 1)^-1 * (-x^2*z + 1)^-1 * (-y^2*z + 1)^-1
131
+
132
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^3])
133
+ 1 * (-x + 1)^-1 * (-x^3*y + 1)^-1
134
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^4])
135
+ 1 * (-x + 1)^-1 * (-x^4*y + 1)^-1
136
+ sage: MacMahonOmega(mu, 1, [1 - x*mu^3, 1 - y/mu])
137
+ (x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^3 + 1)^-1
138
+ sage: MacMahonOmega(mu, 1, [1 - x*mu^4, 1 - y/mu])
139
+ (x*y^3 + x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^4 + 1)^-1
140
+
141
+ sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y/mu, 1 - z/mu])
142
+ (x*y*z + x*y + x*z + 1) *
143
+ (-x + 1)^-1 * (-x*y^2 + 1)^-1 * (-x*z^2 + 1)^-1
144
+ sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y*mu, 1 - z/mu])
145
+ (-x*y*z^2 - x*y*z + x*z + 1) *
146
+ (-x + 1)^-1 * (-y + 1)^-1 * (-x*z^2 + 1)^-1 * (-y*z + 1)^-1
147
+
148
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z*mu, 1 - w/mu])
149
+ (x*y*z*w^2 + x*y*z*w - x*y*w - x*z*w - y*z*w + 1) *
150
+ (-x + 1)^-1 * (-y + 1)^-1 * (-z + 1)^-1 *
151
+ (-x*w + 1)^-1 * (-y*w + 1)^-1 * (-z*w + 1)^-1
152
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu, 1 - w/mu])
153
+ (x^2*y*z*w + x*y^2*z*w - x*y*z*w - x*y*z - x*y*w + 1) *
154
+ (-x + 1)^-1 * (-y + 1)^-1 *
155
+ (-x*z + 1)^-1 * (-x*w + 1)^-1 * (-y*z + 1)^-1 * (-y*w + 1)^-1
156
+
157
+ sage: MacMahonOmega(mu, mu^-2, [1 - x*mu, 1 - y/mu])
158
+ x^2 * (-x + 1)^-1 * (-x*y + 1)^-1
159
+ sage: MacMahonOmega(mu, mu^-1, [1 - x*mu, 1 - y/mu])
160
+ x * (-x + 1)^-1 * (-x*y + 1)^-1
161
+ sage: MacMahonOmega(mu, mu, [1 - x*mu, 1 - y/mu])
162
+ (-x*y + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
163
+ sage: MacMahonOmega(mu, mu^2, [1 - x*mu, 1 - y/mu])
164
+ (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
165
+
166
+ We demonstrate the different allowed input variants::
167
+
168
+ sage: MacMahonOmega(mu,
169
+ ....: Factorization([(mu, 2), (1 - x*mu, -1), (1 - y/mu, -1)]))
170
+ (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
171
+
172
+ sage: MacMahonOmega(mu, mu^2,
173
+ ....: Factorization([(1 - x*mu, 1), (1 - y/mu, 1)]))
174
+ (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
175
+
176
+ sage: MacMahonOmega(mu, mu^2, [1 - x*mu, 1 - y/mu])
177
+ (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
178
+
179
+ sage: MacMahonOmega(mu, mu^2, (1 - x*mu)*(1 - y/mu)) # not tested because not fully implemented
180
+ (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
181
+
182
+ sage: MacMahonOmega(mu, mu^2 / ((1 - x*mu)*(1 - y/mu))) # not tested because not fully implemented
183
+ (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
184
+
185
+ TESTS::
186
+
187
+ sage: MacMahonOmega(mu, 1, [1 - x*mu])
188
+ 1 * (-x + 1)^-1
189
+ sage: MacMahonOmega(mu, 1, [1 - x/mu])
190
+ 1
191
+ sage: MacMahonOmega(mu, 0, [1 - x*mu])
192
+ 0
193
+ sage: MacMahonOmega(mu, L(1), [])
194
+ 1
195
+ sage: MacMahonOmega(mu, L(0), [])
196
+ 0
197
+ sage: MacMahonOmega(mu, 2, [])
198
+ 2
199
+ sage: MacMahonOmega(mu, 2*mu, [])
200
+ 2
201
+ sage: MacMahonOmega(mu, 2/mu, [])
202
+ 0
203
+
204
+ ::
205
+
206
+ sage: MacMahonOmega(mu, Factorization([(1/mu, 1), (1 - x*mu, -1),
207
+ ....: (1 - y/mu, -2)], unit=2))
208
+ 2*x * (-x + 1)^-1 * (-x*y + 1)^-2
209
+ sage: MacMahonOmega(mu, Factorization([(mu, -1), (1 - x*mu, -1),
210
+ ....: (1 - y/mu, -2)], unit=2))
211
+ 2*x * (-x + 1)^-1 * (-x*y + 1)^-2
212
+ sage: MacMahonOmega(mu, Factorization([(mu, -1), (1 - x, -1)]))
213
+ 0
214
+ sage: MacMahonOmega(mu, Factorization([(2, -1)]))
215
+ 1 * 2^-1
216
+
217
+ ::
218
+
219
+ sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - z, 1 - y/mu])
220
+ 1 * (-z + 1)^-1 * (-x + 1)^-1 * (-x*y + 1)^-1
221
+
222
+ ::
223
+
224
+ sage: MacMahonOmega(mu, 1, [1 - x*mu], op=operator.lt)
225
+ Traceback (most recent call last):
226
+ ...
227
+ NotImplementedError: only Omega_ge is implemented
228
+
229
+ sage: MacMahonOmega(mu, 1, Factorization([(1 - x*mu, -1)]))
230
+ Traceback (most recent call last):
231
+ ...
232
+ ValueError: factorization (-mu*x + 1)^-1 of the denominator
233
+ contains negative exponents
234
+
235
+ sage: MacMahonOmega(2*mu, 1, [1 - x*mu])
236
+ Traceback (most recent call last):
237
+ ...
238
+ ValueError: 2*mu is not a variable
239
+
240
+ sage: MacMahonOmega(mu, 1, Factorization([(0, 2)]))
241
+ Traceback (most recent call last):
242
+ ...
243
+ ZeroDivisionError: denominator contains a factor 0
244
+
245
+ sage: MacMahonOmega(mu, 1, [2 - x*mu])
246
+ Traceback (most recent call last):
247
+ ...
248
+ NotImplementedError: factor 2 - x*mu is not normalized
249
+
250
+ sage: MacMahonOmega(mu, 1, [1 - x*mu - mu^2])
251
+ Traceback (most recent call last):
252
+ ...
253
+ NotImplementedError: cannot handle factor 1 - x*mu - mu^2
254
+
255
+ ::
256
+
257
+ sage: L.<mu, x, y, z, w> = LaurentPolynomialRing(QQ)
258
+ sage: MacMahonOmega(mu, 1/mu,
259
+ ....: Factorization([(1 - x*mu, 1), (1 - y/mu, 2)], unit=2))
260
+ 1/2*x * (-x + 1)^-1 * (-x*y + 1)^-2
261
+ """
262
+ from sage.arith.misc import factor
263
+ from sage.misc.misc_c import prod
264
+ from sage.rings.integer_ring import ZZ
265
+ from sage.rings.polynomial.laurent_polynomial_ring import (
266
+ LaurentPolynomialRing,
267
+ LaurentPolynomialRing_univariate,
268
+ )
269
+ from sage.structure.factorization import Factorization
270
+
271
+ if op != operator.ge:
272
+ raise NotImplementedError('only Omega_ge is implemented')
273
+
274
+ if denominator is None:
275
+ if isinstance(expression, Factorization):
276
+ numerator = expression.unit() * \
277
+ prod(f**e for f, e in expression if e > 0)
278
+ denominator = tuple(f for f, e in expression if e < 0
279
+ for _ in range(-e))
280
+ else:
281
+ numerator = expression.numerator()
282
+ denominator = expression.denominator()
283
+ else:
284
+ numerator = expression
285
+ # at this point we have numerator/denominator
286
+
287
+ if isinstance(denominator, (list, tuple)):
288
+ factors_denominator = denominator
289
+ else:
290
+ if not isinstance(denominator, Factorization):
291
+ denominator = factor(denominator)
292
+ if not denominator.is_integral():
293
+ raise ValueError(f'factorization {denominator} of '
294
+ 'the denominator contains negative exponents')
295
+ numerator *= ZZ.one() / denominator.unit()
296
+ factors_denominator = tuple(factor
297
+ for factor, exponent in denominator
298
+ for _ in range(exponent))
299
+ # at this point we have numerator/factors_denominator
300
+
301
+ P = var.parent()
302
+ if isinstance(P, LaurentPolynomialRing_univariate) and P.gen() == var:
303
+ L = P
304
+ L0 = L.base_ring()
305
+ elif var in P.gens():
306
+ var = repr(var)
307
+ L0 = LaurentPolynomialRing(
308
+ P.base_ring(), tuple(v for v in P.variable_names() if v != var))
309
+ L = LaurentPolynomialRing(L0, var)
310
+ var = L.gen()
311
+ else:
312
+ raise ValueError(f'{var} is not a variable')
313
+
314
+ other_factors = []
315
+ to_numerator = []
316
+ decoded_factors = []
317
+ for fact in factors_denominator:
318
+ fac = L(fact)
319
+ D = fac.monomial_coefficients()
320
+ if not D:
321
+ raise ZeroDivisionError('denominator contains a factor 0')
322
+ elif len(D) == 1:
323
+ exponent, coefficient = next(iter(D.items()))
324
+ if exponent == 0:
325
+ other_factors.append(L0(fac))
326
+ else:
327
+ to_numerator.append(fac)
328
+ elif len(D) == 2:
329
+ if D.get(0, 0) != 1:
330
+ raise NotImplementedError(f'factor {fac} is not normalized')
331
+ D.pop(0)
332
+ exponent, coefficient = next(iter(D.items()))
333
+ decoded_factors.append((-coefficient, exponent))
334
+ else:
335
+ raise NotImplementedError(f'cannot handle factor {fac}')
336
+ numerator = L(numerator) / prod(to_numerator)
337
+
338
+ result_numerator, result_factors_denominator = \
339
+ _Omega_(numerator.monomial_coefficients(), decoded_factors)
340
+ if result_numerator == 0:
341
+ return Factorization([], unit=result_numerator)
342
+
343
+ return Factorization([(result_numerator, 1)] +
344
+ [(f, -1) for f in other_factors] +
345
+ [(1 - f, -1) for f in result_factors_denominator],
346
+ sort=Factorization_sort,
347
+ simplify=Factorization_simplify)
348
+
349
+
350
+ def _simplify_(numerator, terms) -> tuple:
351
+ r"""
352
+ Cancels common factors of numerator and denominator.
353
+
354
+ INPUT:
355
+
356
+ - ``numerator`` -- a Laurent polynomial
357
+
358
+ - ``terms`` -- tuple or other iterable of Laurent polynomials
359
+
360
+ The denominator is the product of factors `1 - t` for each
361
+ `t` in ``terms``.
362
+
363
+ OUTPUT:
364
+
365
+ A pair of a Laurent polynomial and a tuple of Laurent polynomials
366
+ representing numerator and denominator as described in the INPUT-section.
367
+
368
+ EXAMPLES::
369
+
370
+ sage: from sage.rings.polynomial.omega import _simplify_
371
+ sage: L.<x, y> = LaurentPolynomialRing(ZZ)
372
+ sage: _simplify_(1-x^2, (x, y))
373
+ (x + 1, (y,))
374
+
375
+ TESTS::
376
+
377
+ sage: _simplify_(1-x^2, (x, -x))
378
+ (1, ())
379
+ sage: _simplify_(1-x^2, (y^2, y))
380
+ (-x^2 + 1, (y^2, y))
381
+ sage: _simplify_(1-x^2, (x, L(2)))
382
+ (x + 1, (2,))
383
+ """
384
+ new_terms = []
385
+ for t in terms:
386
+ if not t.is_constant():
387
+ quo, rem = numerator.quo_rem(1 - t)
388
+ if rem == 0:
389
+ numerator = quo
390
+ continue
391
+ new_terms.append(t)
392
+ return numerator, tuple(new_terms)
393
+
394
+
395
+ def _Omega_(A, decoded_factors):
396
+ r"""
397
+ Helper function for :func:`MacMahonOmega` which accesses the low level functions
398
+ and does the substituting.
399
+
400
+ INPUT:
401
+
402
+ - ``A`` -- dictionary mapping `a` to `c` representing a summand
403
+ `c\mu^a` of the numerator
404
+
405
+ - ``decoded_factors`` -- tuple or list of pairs `(z, e)` representing
406
+ a factor `1 - z \mu^e`
407
+
408
+ OUTPUT:
409
+
410
+ A pair representing a quotient as follows: Its first component is the
411
+ numerator as a Laurent polynomial, its second component a factorization
412
+ of the denominator as a tuple of Laurent polynomials, where each
413
+ Laurent polynomial `z` represents a factor `1 - z`.
414
+
415
+ TESTS:
416
+
417
+ Extensive testing of this function is done in :func:`MacMahonOmega`.
418
+
419
+ ::
420
+
421
+ sage: L.<mu, x, y> = LaurentPolynomialRing(ZZ)
422
+ sage: MacMahonOmega(mu, mu^-2, [1 - x*mu, 1 - y/mu])
423
+ x^2 * (-x + 1)^-1 * (-x*y + 1)^-1
424
+
425
+ internally calls
426
+ ::
427
+
428
+ sage: from sage.rings.polynomial.omega import _Omega_
429
+ sage: _Omega_({-2: 1}, [(x, 1), (y, -1)])
430
+ (x^2, (x, x*y))
431
+
432
+ ::
433
+
434
+ sage: _Omega_({0: 2, 1: 40, -1: -3}, [])
435
+ (42, ())
436
+ sage: _Omega_({-1: 42}, [])
437
+ (0, ())
438
+
439
+
440
+ ::
441
+
442
+ sage: MacMahonOmega(mu, 1 - x^2, [1 - x*mu, 1 - y/mu])
443
+ (x + 1) * (-x*y + 1)^-1
444
+ """
445
+ if not decoded_factors:
446
+ return sum(c for a, c in A.items() if a >= 0), ()
447
+
448
+ # Below we sort to make the caching more efficient. Doing this here
449
+ # (in contrast to directly in Omega_ge) results in much cleaner
450
+ # code and prevents an additional substitution or passing of a permutation.
451
+ values, exponents = zip(*sorted(decoded_factors, key=lambda k: -k[1]))
452
+
453
+ numerator = 0
454
+ factors_denominator = None
455
+ rules = None
456
+ for a, c in A.items():
457
+ n, fd = Omega_ge(a, exponents)
458
+ if factors_denominator is None:
459
+ factors_denominator = fd
460
+ else:
461
+ assert factors_denominator == fd
462
+ if rules is None:
463
+ rules = dict(zip(n.parent().gens(), values))
464
+ numerator += c * n.subs(rules)
465
+
466
+ if numerator == 0:
467
+ factors_denominator = ()
468
+ return _simplify_(numerator,
469
+ tuple(f.subs(rules) for f in factors_denominator))
470
+
471
+
472
+ @cached_function
473
+ def Omega_ge(a, exponents):
474
+ r"""
475
+ Return `\Omega_{\ge}` of the expression specified by the input.
476
+
477
+ To be more precise, calculate
478
+
479
+ .. MATH::
480
+
481
+ \Omega_{\ge} \frac{\mu^a}{
482
+ (1 - z_0 \mu^{e_0}) \dots (1 - z_{n-1} \mu^{e_{n-1}})}
483
+
484
+ and return its numerator and a factorization of its denominator.
485
+ Note that `z_0`, ..., `z_{n-1}` only appear in the output, but not in the
486
+ input.
487
+
488
+ INPUT:
489
+
490
+ - ``a`` -- integer
491
+
492
+ - ``exponents`` -- tuple of integers
493
+
494
+ OUTPUT:
495
+
496
+ A pair representing a quotient as follows: Its first component is the
497
+ numerator as a Laurent polynomial, its second component a factorization
498
+ of the denominator as a tuple of Laurent polynomials, where each
499
+ Laurent polynomial `z` represents a factor `1 - z`.
500
+
501
+ The parents of these Laurent polynomials is always a
502
+ Laurent polynomial ring in `z_0`, ..., `z_{n-1}` over `\ZZ`, where
503
+ `n` is the length of ``exponents``.
504
+
505
+ EXAMPLES::
506
+
507
+ sage: from sage.rings.polynomial.omega import Omega_ge
508
+ sage: Omega_ge(0, (1, -2))
509
+ (1, (z0, z0^2*z1))
510
+ sage: Omega_ge(0, (1, -3))
511
+ (1, (z0, z0^3*z1))
512
+ sage: Omega_ge(0, (1, -4))
513
+ (1, (z0, z0^4*z1))
514
+
515
+ sage: Omega_ge(0, (2, -1))
516
+ (z0*z1 + 1, (z0, z0*z1^2))
517
+ sage: Omega_ge(0, (3, -1))
518
+ (z0*z1^2 + z0*z1 + 1, (z0, z0*z1^3))
519
+ sage: Omega_ge(0, (4, -1))
520
+ (z0*z1^3 + z0*z1^2 + z0*z1 + 1, (z0, z0*z1^4))
521
+
522
+ sage: Omega_ge(0, (1, 1, -2))
523
+ (-z0^2*z1*z2 - z0*z1^2*z2 + z0*z1*z2 + 1, (z0, z1, z0^2*z2, z1^2*z2))
524
+ sage: Omega_ge(0, (2, -1, -1))
525
+ (z0*z1*z2 + z0*z1 + z0*z2 + 1, (z0, z0*z1^2, z0*z2^2))
526
+ sage: Omega_ge(0, (2, 1, -1))
527
+ (-z0*z1*z2^2 - z0*z1*z2 + z0*z2 + 1, (z0, z1, z0*z2^2, z1*z2))
528
+
529
+ ::
530
+
531
+ sage: Omega_ge(0, (2, -2))
532
+ (-z0*z1 + 1, (z0, z0*z1, z0*z1))
533
+ sage: Omega_ge(0, (2, -3))
534
+ (z0^2*z1 + 1, (z0, z0^3*z1^2))
535
+ sage: Omega_ge(0, (3, 1, -3))
536
+ (-z0^3*z1^3*z2^3 + 2*z0^2*z1^3*z2^2 - z0*z1^3*z2
537
+ + z0^2*z2^2 - 2*z0*z2 + 1,
538
+ (z0, z1, z0*z2, z0*z2, z0*z2, z1^3*z2))
539
+
540
+ ::
541
+
542
+ sage: Omega_ge(0, (3, 6, -1))
543
+ (-z0*z1*z2^8 - z0*z1*z2^7 - z0*z1*z2^6 - z0*z1*z2^5 - z0*z1*z2^4 +
544
+ z1*z2^5 - z0*z1*z2^3 + z1*z2^4 - z0*z1*z2^2 + z1*z2^3 -
545
+ z0*z1*z2 + z0*z2^2 + z1*z2^2 + z0*z2 + z1*z2 + 1,
546
+ (z0, z1, z0*z2^3, z1*z2^6))
547
+
548
+ TESTS::
549
+
550
+ sage: Omega_ge(0, (2, 2, 1, 1, 1, -1, -1))[0].number_of_terms() # long time
551
+ 1695
552
+ sage: Omega_ge(0, (2, 2, 1, 1, 1, 1, 1, -1, -1))[0].number_of_terms() # not tested (too long, 1 min)
553
+ 27837
554
+
555
+ ::
556
+
557
+ sage: Omega_ge(1, (2,))
558
+ (1, (z0,))
559
+ """
560
+ import logging
561
+ logger = logging.getLogger(__name__)
562
+ logger.info('Omega_ge: a=%s, exponents=%s', a, exponents)
563
+
564
+ from sage.arith.functions import lcm
565
+ from sage.rings.integer_ring import ZZ
566
+ from sage.rings.number_field.number_field import CyclotomicField
567
+ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
568
+
569
+ if not exponents or any(e == 0 for e in exponents):
570
+ raise NotImplementedError
571
+
572
+ rou = sorted({abse for e in exponents if (abse := abs(e)) != 1})
573
+ ellcm = lcm(rou)
574
+ B = CyclotomicField(ellcm, 'zeta')
575
+ zeta = B.gen()
576
+ z_names = tuple(f'z{i}' for i in range(len(exponents)))
577
+ L = LaurentPolynomialRing(B, ('t',) + z_names, len(z_names) + 1)
578
+ t = L.gens()[0]
579
+ Z = LaurentPolynomialRing(ZZ, z_names, len(z_names))
580
+ powers = {i: L(zeta**(ellcm//i)) for i in rou}
581
+ powers[2] = L(-1)
582
+ powers[1] = L(1)
583
+ exponents_and_values = tuple(
584
+ (e, tuple(powers[abs(e)]**j * z for j in range(abs(e))))
585
+ for z, e in zip(L.gens()[1:], exponents))
586
+ x = tuple(v for e, v in exponents_and_values if e > 0)
587
+ y = tuple(v for e, v in exponents_and_values if e < 0)
588
+
589
+ def subs_power(expression, var, exponent):
590
+ r"""
591
+ Substitute ``var^exponent`` by ``var`` in ``expression``.
592
+
593
+ It is assumed that ``var`` only occurs with exponents
594
+ divisible by ``exponent``.
595
+ """
596
+ p = tuple(var.monomial_coefficients().popitem()[0]).index(1) # var is the p-th generator
597
+
598
+ def subs_e(e):
599
+ e = list(e)
600
+ assert e[p] % exponent == 0
601
+ e[p] = e[p] // exponent
602
+ return tuple(e)
603
+ parent = expression.parent()
604
+ return parent({subs_e(e): c
605
+ for e, c in expression.monomial_coefficients().items()})
606
+
607
+ def de_power(expression):
608
+ expression = Z(expression)
609
+ for e, var in zip(exponents, Z.gens()):
610
+ if abs(e) == 1:
611
+ continue
612
+ expression = subs_power(expression, var, abs(e))
613
+ return expression
614
+
615
+ logger.debug('Omega_ge: preparing denominator')
616
+ factors_denominator = tuple(de_power(1 - factor)
617
+ for factor in _Omega_factors_denominator_(x, y))
618
+
619
+ logger.debug('Omega_ge: preparing numerator')
620
+ numerator = de_power(_Omega_numerator_(a, x, y, t))
621
+
622
+ logger.info('Omega_ge: completed')
623
+ return numerator, factors_denominator
624
+
625
+
626
+ def _Omega_numerator_(a, x, y, t):
627
+ r"""
628
+ Return the numerator of `\Omega_{\ge}` of the expression
629
+ specified by the input.
630
+
631
+ To be more precise, calculate
632
+
633
+ .. MATH::
634
+
635
+ \Omega_{\ge} \frac{\mu^a}{
636
+ (1 - x_1 \mu) \dots (1 - x_n \mu)
637
+ (1 - y_1 / \mu) \dots (1 - y_m / \mu)}
638
+
639
+ and return its numerator.
640
+
641
+ This function is meant to be a helper function of :func:`MacMahonOmega`.
642
+
643
+ INPUT:
644
+
645
+ - ``a`` -- integer
646
+
647
+ - ``x``, ``y`` -- tuple of tuples of Laurent polynomials
648
+
649
+ The
650
+ flattened ``x`` contains `x_1,...,x_n`, the flattened ``y`` the
651
+ `y_1,...,y_m`.
652
+ The non-flatness of these parameters is to be interface-consistent
653
+ with :func:`_Omega_factors_denominator_`.
654
+
655
+ - ``t`` -- a temporary Laurent polynomial variable used for substituting
656
+
657
+ OUTPUT: a Laurent polynomial
658
+
659
+ The output is normalized such that the corresponding denominator
660
+ (:func:`_Omega_factors_denominator_`) has constant term `1`.
661
+
662
+ EXAMPLES::
663
+
664
+ sage: from sage.rings.polynomial.omega import _Omega_numerator_, _Omega_factors_denominator_
665
+
666
+ sage: L.<x0, x1, x2, x3, y0, y1, t> = LaurentPolynomialRing(ZZ)
667
+ sage: _Omega_numerator_(0, ((x0,),), ((y0,),), t)
668
+ 1
669
+ sage: _Omega_numerator_(0, ((x0,), (x1,)), ((y0,),), t)
670
+ -x0*x1*y0 + 1
671
+ sage: _Omega_numerator_(0, ((x0,),), ((y0,), (y1,)), t)
672
+ 1
673
+ sage: _Omega_numerator_(0, ((x0,), (x1,), (x2,)), ((y0,),), t)
674
+ x0*x1*x2*y0^2 + x0*x1*x2*y0 - x0*x1*y0 - x0*x2*y0 - x1*x2*y0 + 1
675
+ sage: _Omega_numerator_(0, ((x0,), (x1,)), ((y0,), (y1,)), t)
676
+ x0^2*x1*y0*y1 + x0*x1^2*y0*y1 - x0*x1*y0*y1 - x0*x1*y0 - x0*x1*y1 + 1
677
+
678
+ sage: _Omega_numerator_(-2, ((x0,),), ((y0,),), t)
679
+ x0^2
680
+ sage: _Omega_numerator_(-1, ((x0,),), ((y0,),), t)
681
+ x0
682
+ sage: _Omega_numerator_(1, ((x0,),), ((y0,),), t)
683
+ -x0*y0 + y0 + 1
684
+ sage: _Omega_numerator_(2, ((x0,),), ((y0,),), t)
685
+ -x0*y0^2 - x0*y0 + y0^2 + y0 + 1
686
+
687
+ TESTS::
688
+
689
+ sage: _Omega_factors_denominator_((), ())
690
+ ()
691
+ sage: _Omega_numerator_(0, (), (), t)
692
+ 1
693
+ sage: _Omega_numerator_(+2, (), (), t)
694
+ 1
695
+ sage: _Omega_numerator_(-2, (), (), t)
696
+ 0
697
+
698
+ sage: _Omega_factors_denominator_(((x0,),), ())
699
+ (-x0 + 1,)
700
+ sage: _Omega_numerator_(0, ((x0,),), (), t)
701
+ 1
702
+ sage: _Omega_numerator_(+2, ((x0,),), (), t)
703
+ 1
704
+ sage: _Omega_numerator_(-2, ((x0,),), (), t)
705
+ x0^2
706
+
707
+ sage: _Omega_factors_denominator_((), ((y0,),))
708
+ ()
709
+ sage: _Omega_numerator_(0, (), ((y0,),), t)
710
+ 1
711
+ sage: _Omega_numerator_(+2, (), ((y0,),), t)
712
+ y0^2 + y0 + 1
713
+ sage: _Omega_numerator_(-2, (), ((y0,),), t)
714
+ 0
715
+
716
+ ::
717
+
718
+ sage: L.<X, Y, t> = LaurentPolynomialRing(ZZ)
719
+ sage: _Omega_numerator_(2, ((X,),), ((Y,),), t)
720
+ -X*Y^2 - X*Y + Y^2 + Y + 1
721
+ """
722
+ from sage.arith.srange import srange
723
+ from sage.misc.misc_c import prod
724
+
725
+ x_flat = sum(x, ())
726
+ y_flat = sum(y, ())
727
+ n = len(x_flat)
728
+ m = len(y_flat)
729
+ xy = x_flat + y_flat
730
+
731
+ import logging
732
+ logger = logging.getLogger(__name__)
733
+ logger.info('Omega_numerator: a=%s, n=%s, m=%s', a, n, m)
734
+
735
+ if m == 0:
736
+ result = 1 - (prod(_Omega_factors_denominator_(x, y)) *
737
+ sum(homogeneous_symmetric_function(j, xy)
738
+ for j in srange(-a))
739
+ if a < 0 else 0)
740
+ elif n == 0:
741
+ result = sum(homogeneous_symmetric_function(j, xy)
742
+ for j in srange(a+1))
743
+ else:
744
+ result = _Omega_numerator_P_(a, x_flat[:-1], y_flat, t).subs({t: x_flat[-1]})
745
+ L = t.parent()
746
+ result = L(result)
747
+
748
+ logger.info('_Omega_numerator_: %s terms', result.number_of_terms())
749
+ return result
750
+
751
+
752
+ def _Omega_numerator_P_(a, x, y, t):
753
+ r"""
754
+ Helper function for :func:`_Omega_numerator_`.
755
+
756
+ This is an implementation of the function `P` of [APR2001]_.
757
+
758
+ INPUT:
759
+
760
+ - ``a`` -- integer
761
+
762
+ - ``x``, ``y`` -- tuple of Laurent polynomials
763
+
764
+ The tuple ``x`` here is the flattened ``x`` of :func:`_Omega_numerator_`
765
+ but without its last entry.
766
+
767
+ - ``t`` -- a temporary Laurent polynomial variable
768
+
769
+ In the (final) result, ``t`` has to be substituted by the last
770
+ entry of the flattened ``x`` of :func:`_Omega_numerator_`.
771
+
772
+ OUTPUT: a Laurent polynomial
773
+
774
+ TESTS::
775
+
776
+ sage: from sage.rings.polynomial.omega import _Omega_numerator_P_
777
+ sage: L.<x0, x1, y0, y1, t> = LaurentPolynomialRing(ZZ)
778
+ sage: _Omega_numerator_P_(0, (x0,), (y0,), t).subs({t: x1})
779
+ -x0*x1*y0 + 1
780
+ """
781
+ # This function takes Laurent polynomials as inputs. It would
782
+ # be possible to input only the sizes of ``x`` and ``y`` and
783
+ # perform a substitution afterwards; in this way caching of this
784
+ # function would make sense. However, the way it is now allows
785
+ # automatic collection and simplification of the summands, which
786
+ # makes it more efficient for higher powers at the input of
787
+ # :func:`Omega_ge`.
788
+ # Caching occurs in :func:`Omega_ge`.
789
+
790
+ import logging
791
+ logger = logging.getLogger(__name__)
792
+
793
+ from sage.arith.srange import srange
794
+ from sage.misc.misc_c import prod
795
+
796
+ n = len(x)
797
+ if n == 0:
798
+ x0 = t
799
+ result = x0**(-a) + \
800
+ (prod(1 - x0*yy for yy in y) *
801
+ sum(homogeneous_symmetric_function(j, y) * (1-x0**(j-a))
802
+ for j in srange(a))
803
+ if a > 0 else 0)
804
+ else:
805
+ Pprev = _Omega_numerator_P_(a, x[:n-1], y, t)
806
+ x2 = x[n-1]
807
+ logger.debug('Omega_numerator: P(%s): substituting...', n)
808
+ x1 = t
809
+ p1 = Pprev
810
+ p2 = Pprev.subs({t: x2})
811
+ logger.debug('Omega_numerator: P(%s): preparing...', n)
812
+ dividend = x1 * (1-x2) * prod(1 - x2*yy for yy in y) * p1 - \
813
+ x2 * (1-x1) * prod(1 - x1*yy for yy in y) * p2
814
+ logger.debug('Omega_numerator: P(%s): dividing...', n)
815
+ q, r = dividend.quo_rem(x1 - x2)
816
+ assert r == 0
817
+ result = q
818
+ logger.debug('Omega_numerator: P(%s) has %s terms', n,
819
+ result.number_of_terms())
820
+ return result
821
+
822
+
823
+ @cached_function
824
+ def _Omega_factors_denominator_(x, y):
825
+ r"""
826
+ Return the denominator of `\Omega_{\ge}` of the expression
827
+ specified by the input.
828
+
829
+ To be more precise, calculate
830
+
831
+ .. MATH::
832
+
833
+ \Omega_{\ge} \frac{1}{
834
+ (1 - x_1 \mu) \dots (1 - x_n \mu)
835
+ (1 - y_1 / \mu) \dots (1 - y_m / \mu)}
836
+
837
+ and return a factorization of its denominator.
838
+
839
+ This function is meant to be a helper function of :func:`MacMahonOmega`.
840
+
841
+ INPUT:
842
+
843
+ - ``x``, ``y`` -- tuple of tuples of Laurent polynomials
844
+
845
+ The
846
+ flattened ``x`` contains `x_1,...,x_n`, the flattened ``y`` the
847
+ `y_1,...,y_m`.
848
+
849
+ OUTPUT:
850
+
851
+ A factorization of the denominator as
852
+ a tuple of Laurent polynomials
853
+
854
+ The output is normalized such that it has constant term `1`.
855
+
856
+ .. NOTE::
857
+
858
+ The assumption is that the ``x`` and ``y`` are collected in
859
+ such a way that one entry of ``x`` corresponds to the orbit of
860
+ some ``x_j`` under multiplication by `d`-th roots of unity and that
861
+ the output is collected in a corresponding way.
862
+
863
+ EXAMPLES::
864
+
865
+ sage: from sage.rings.polynomial.omega import _Omega_factors_denominator_
866
+
867
+ sage: L.<x0, x1, x2, x3, y0, y1> = LaurentPolynomialRing(ZZ)
868
+ sage: _Omega_factors_denominator_(((x0,),), ((y0,),))
869
+ (-x0 + 1, -x0*y0 + 1)
870
+ sage: _Omega_factors_denominator_(((x0,),), ((y0,), (y1,)))
871
+ (-x0 + 1, -x0*y0 + 1, -x0*y1 + 1)
872
+ sage: _Omega_factors_denominator_(((x0,), (x1,)), ((y0,),))
873
+ (-x0 + 1, -x1 + 1, -x0*y0 + 1, -x1*y0 + 1)
874
+ sage: _Omega_factors_denominator_(((x0,), (x1,), (x2,)), ((y0,),))
875
+ (-x0 + 1, -x1 + 1, -x2 + 1, -x0*y0 + 1, -x1*y0 + 1, -x2*y0 + 1)
876
+ sage: _Omega_factors_denominator_(((x0,), (x1,)), ((y0,), (y1,)))
877
+ (-x0 + 1, -x1 + 1, -x0*y0 + 1, -x0*y1 + 1, -x1*y0 + 1, -x1*y1 + 1)
878
+
879
+ ::
880
+
881
+ sage: # needs sage.rings.number_field
882
+ sage: B.<zeta> = ZZ.extension(cyclotomic_polynomial(3))
883
+ sage: L.<x, y> = LaurentPolynomialRing(B)
884
+ sage: _Omega_factors_denominator_(((x, -x),), ((y,),))
885
+ (-x^2 + 1, -x^2*y^2 + 1)
886
+ sage: _Omega_factors_denominator_(((x, -x),), ((y, zeta*y, zeta^2*y),))
887
+ (-x^2 + 1, -x^6*y^6 + 1)
888
+ sage: _Omega_factors_denominator_(((x, -x),), ((y, -y),))
889
+ (-x^2 + 1, -x^2*y^2 + 1, -x^2*y^2 + 1)
890
+
891
+ TESTS::
892
+
893
+ sage: L.<x0, y0> = LaurentPolynomialRing(ZZ)
894
+ sage: _Omega_factors_denominator_((), ())
895
+ ()
896
+ sage: _Omega_factors_denominator_(((x0,),), ())
897
+ (-x0 + 1,)
898
+ sage: _Omega_factors_denominator_((), ((y0,),))
899
+ ()
900
+ """
901
+ import logging
902
+ logger = logging.getLogger(__name__)
903
+
904
+ from sage.misc.misc_c import prod
905
+
906
+ result = tuple(prod(1 - xx for xx in gx) for gx in x) + \
907
+ sum(((prod(1 - xx*yy for xx in gx for yy in gy),)
908
+ if len(gx) != len(gy)
909
+ else tuple(prod(1 - xx*yy for xx in gx) for yy in gy)
910
+ for gx in x for gy in y),
911
+ ())
912
+
913
+ logger.info('Omega_denominator: %s factors', len(result))
914
+ return result
915
+
916
+
917
+ def partition(items, predicate=bool):
918
+ r"""
919
+ Split ``items`` into two parts by the given ``predicate``.
920
+
921
+ INPUT:
922
+
923
+ - ``item`` -- an iterator
924
+
925
+ - ``predicate`` -- a function
926
+
927
+ OUTPUT:
928
+
929
+ A pair of iterators; the first contains the elements not satisfying
930
+ the ``predicate``, the second the elements satisfying the ``predicate``.
931
+
932
+ ALGORITHM:
933
+
934
+ Source of the code:
935
+ `http://nedbatchelder.com/blog/201306/filter_a_list_into_two_parts.html
936
+ <http://nedbatchelder.com/blog/201306/filter_a_list_into_two_parts.html>`_
937
+
938
+ EXAMPLES::
939
+
940
+ sage: from sage.rings.polynomial.omega import partition
941
+ sage: E, O = partition(srange(10), is_odd)
942
+ sage: tuple(E), tuple(O)
943
+ ((0, 2, 4, 6, 8), (1, 3, 5, 7, 9))
944
+ """
945
+ from itertools import tee
946
+ a, b = tee((predicate(item), item) for item in items)
947
+ return ((item for pred, item in a if not pred),
948
+ (item for pred, item in b if pred))
949
+
950
+
951
+ def homogeneous_symmetric_function(j, x):
952
+ r"""
953
+ Return a complete homogeneous symmetric polynomial
954
+ (:wikipedia:`Complete_homogeneous_symmetric_polynomial`).
955
+
956
+ INPUT:
957
+
958
+ - ``j`` -- the degree as a nonnegative integer
959
+
960
+ - ``x`` -- an iterable of variables
961
+
962
+ OUTPUT: a polynomial of the common parent of all entries of ``x``
963
+
964
+ EXAMPLES::
965
+
966
+ sage: from sage.rings.polynomial.omega import homogeneous_symmetric_function
967
+ sage: P = PolynomialRing(ZZ, 'X', 3)
968
+ sage: homogeneous_symmetric_function(0, P.gens())
969
+ 1
970
+ sage: homogeneous_symmetric_function(1, P.gens())
971
+ X0 + X1 + X2
972
+ sage: homogeneous_symmetric_function(2, P.gens())
973
+ X0^2 + X0*X1 + X1^2 + X0*X2 + X1*X2 + X2^2
974
+ sage: homogeneous_symmetric_function(3, P.gens())
975
+ X0^3 + X0^2*X1 + X0*X1^2 + X1^3 + X0^2*X2 +
976
+ X0*X1*X2 + X1^2*X2 + X0*X2^2 + X1*X2^2 + X2^3
977
+ """
978
+ from sage.combinat.integer_vector import IntegerVectors
979
+ from sage.misc.misc_c import prod
980
+
981
+ return sum(prod(xx**pp for xx, pp in zip(x, p))
982
+ for p in IntegerVectors(j, length=len(x)))