passagemath-polyhedra 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-polyhedra might be problematic. Click here for more details.
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +208 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_polyhedra.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_polyhedra.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_polyhedra.libs/libgomp-1ede7ee7.so.1.0.0 +0 -0
- passagemath_polyhedra.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_polyhedra.py +50 -0
- sage/game_theory/all.py +8 -0
- sage/game_theory/catalog.py +6 -0
- sage/game_theory/catalog_normal_form_games.py +923 -0
- sage/game_theory/cooperative_game.py +844 -0
- sage/game_theory/matching_game.py +1181 -0
- sage/game_theory/normal_form_game.py +2697 -0
- sage/game_theory/parser.py +275 -0
- sage/geometry/all__sagemath_polyhedra.py +22 -0
- sage/geometry/cone.py +6940 -0
- sage/geometry/cone_catalog.py +847 -0
- sage/geometry/cone_critical_angles.py +1027 -0
- sage/geometry/convex_set.py +1119 -0
- sage/geometry/fan.py +3743 -0
- sage/geometry/fan_isomorphism.py +389 -0
- sage/geometry/fan_morphism.py +1884 -0
- sage/geometry/hasse_diagram.py +202 -0
- sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
- sage/geometry/hyperplane_arrangement/all.py +1 -0
- sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
- sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
- sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
- sage/geometry/hyperplane_arrangement/library.py +825 -0
- sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
- sage/geometry/hyperplane_arrangement/plot.py +520 -0
- sage/geometry/integral_points.py +35 -0
- sage/geometry/integral_points_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/integral_points_generic_dense.pyx +7 -0
- sage/geometry/lattice_polytope.py +5894 -0
- sage/geometry/linear_expression.py +773 -0
- sage/geometry/newton_polygon.py +767 -0
- sage/geometry/point_collection.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/point_collection.pyx +1008 -0
- sage/geometry/polyhedral_complex.py +2616 -0
- sage/geometry/polyhedron/all.py +8 -0
- sage/geometry/polyhedron/backend_cdd.py +460 -0
- sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
- sage/geometry/polyhedron/backend_field.py +347 -0
- sage/geometry/polyhedron/backend_normaliz.py +2503 -0
- sage/geometry/polyhedron/backend_number_field.py +168 -0
- sage/geometry/polyhedron/backend_polymake.py +765 -0
- sage/geometry/polyhedron/backend_ppl.py +582 -0
- sage/geometry/polyhedron/base.py +1206 -0
- sage/geometry/polyhedron/base0.py +1444 -0
- sage/geometry/polyhedron/base1.py +886 -0
- sage/geometry/polyhedron/base2.py +812 -0
- sage/geometry/polyhedron/base3.py +1845 -0
- sage/geometry/polyhedron/base4.py +1262 -0
- sage/geometry/polyhedron/base5.py +2700 -0
- sage/geometry/polyhedron/base6.py +1741 -0
- sage/geometry/polyhedron/base7.py +997 -0
- sage/geometry/polyhedron/base_QQ.py +1258 -0
- sage/geometry/polyhedron/base_RDF.py +98 -0
- sage/geometry/polyhedron/base_ZZ.py +934 -0
- sage/geometry/polyhedron/base_mutable.py +215 -0
- sage/geometry/polyhedron/base_number_field.py +122 -0
- sage/geometry/polyhedron/cdd_file_format.py +155 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
- sage/geometry/polyhedron/constructor.py +773 -0
- sage/geometry/polyhedron/double_description.py +753 -0
- sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
- sage/geometry/polyhedron/face.py +1060 -0
- sage/geometry/polyhedron/generating_function.py +1810 -0
- sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
- sage/geometry/polyhedron/library.py +3502 -0
- sage/geometry/polyhedron/misc.py +121 -0
- sage/geometry/polyhedron/modules/all.py +1 -0
- sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
- sage/geometry/polyhedron/palp_database.py +447 -0
- sage/geometry/polyhedron/parent.py +1279 -0
- sage/geometry/polyhedron/plot.py +1986 -0
- sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
- sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
- sage/geometry/polyhedron/representation.py +1723 -0
- sage/geometry/pseudolines.py +515 -0
- sage/geometry/relative_interior.py +445 -0
- sage/geometry/toric_plotter.py +1103 -0
- sage/geometry/triangulation/all.py +2 -0
- sage/geometry/triangulation/base.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/triangulation/base.pyx +963 -0
- sage/geometry/triangulation/data.h +147 -0
- sage/geometry/triangulation/data.pxd +4 -0
- sage/geometry/triangulation/element.py +914 -0
- sage/geometry/triangulation/functions.h +10 -0
- sage/geometry/triangulation/functions.pxd +4 -0
- sage/geometry/triangulation/point_configuration.py +2256 -0
- sage/geometry/triangulation/triangulations.h +49 -0
- sage/geometry/triangulation/triangulations.pxd +7 -0
- sage/geometry/voronoi_diagram.py +319 -0
- sage/interfaces/all__sagemath_polyhedra.py +1 -0
- sage/interfaces/polymake.py +2028 -0
- sage/numerical/all.py +13 -0
- sage/numerical/all__sagemath_polyhedra.py +11 -0
- sage/numerical/backends/all.py +1 -0
- sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
- sage/numerical/backends/cvxopt_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_backend.pyx +1006 -0
- sage/numerical/backends/cvxopt_backend_test.py +19 -0
- sage/numerical/backends/cvxopt_sdp_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
- sage/numerical/backends/cvxpy_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/cvxpy_backend.pxd +41 -0
- sage/numerical/backends/cvxpy_backend.pyx +934 -0
- sage/numerical/backends/cvxpy_backend_test.py +13 -0
- sage/numerical/backends/generic_backend_test.py +24 -0
- sage/numerical/backends/interactivelp_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/interactivelp_backend.pxd +36 -0
- sage/numerical/backends/interactivelp_backend.pyx +1231 -0
- sage/numerical/backends/interactivelp_backend_test.py +12 -0
- sage/numerical/backends/logging_backend.py +391 -0
- sage/numerical/backends/matrix_sdp_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
- sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
- sage/numerical/backends/ppl_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/ppl_backend.pyx +1126 -0
- sage/numerical/backends/ppl_backend_test.py +13 -0
- sage/numerical/backends/scip_backend.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/scip_backend.pxd +22 -0
- sage/numerical/backends/scip_backend.pyx +1289 -0
- sage/numerical/backends/scip_backend_test.py +13 -0
- sage/numerical/interactive_simplex_method.py +5338 -0
- sage/numerical/knapsack.py +665 -0
- sage/numerical/linear_functions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/linear_functions.pxd +31 -0
- sage/numerical/linear_functions.pyx +1648 -0
- sage/numerical/linear_tensor.py +470 -0
- sage/numerical/linear_tensor_constraints.py +448 -0
- sage/numerical/linear_tensor_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/linear_tensor_element.pxd +6 -0
- sage/numerical/linear_tensor_element.pyx +459 -0
- sage/numerical/mip.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/mip.pxd +40 -0
- sage/numerical/mip.pyx +3667 -0
- sage/numerical/sdp.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/sdp.pxd +39 -0
- sage/numerical/sdp.pyx +1433 -0
- sage/rings/all__sagemath_polyhedra.py +3 -0
- sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
- sage/rings/polynomial/omega.py +982 -0
- sage/schemes/all__sagemath_polyhedra.py +2 -0
- sage/schemes/toric/all.py +10 -0
- sage/schemes/toric/chow_group.py +1248 -0
- sage/schemes/toric/divisor.py +2082 -0
- sage/schemes/toric/divisor_class.cpython-314-aarch64-linux-musl.so +0 -0
- sage/schemes/toric/divisor_class.pyx +322 -0
- sage/schemes/toric/fano_variety.py +1606 -0
- sage/schemes/toric/homset.py +650 -0
- sage/schemes/toric/ideal.py +451 -0
- sage/schemes/toric/library.py +1322 -0
- sage/schemes/toric/morphism.py +1958 -0
- sage/schemes/toric/points.py +1032 -0
- sage/schemes/toric/sheaf/all.py +1 -0
- sage/schemes/toric/sheaf/constructor.py +302 -0
- sage/schemes/toric/sheaf/klyachko.py +921 -0
- sage/schemes/toric/toric_subscheme.py +905 -0
- sage/schemes/toric/variety.py +3460 -0
- sage/schemes/toric/weierstrass.py +1078 -0
- sage/schemes/toric/weierstrass_covering.py +457 -0
- sage/schemes/toric/weierstrass_higher.py +288 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
|
@@ -0,0 +1,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)))
|