Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" MacMahon's Partition Analysis Omega Operator
This module implements :func:`MacMahon's Omega Operator <MacMahonOmega>` [Mac1915]_, which takes a quotient of Laurent polynomials and removes all negative exponents in the corresponding power series.
Examples ========
In the following example, all negative exponents of `\mu` are removed. The formula
.. MATH::
\Omega_{\ge} \frac{1}{(1 - x\mu) (1 - y/\mu)} = \frac{1}{(1 - x) (1 - xy)}
can be calculated and verified by ::
sage: L.<mu, x, y> = LaurentPolynomialRing(ZZ) sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu]) 1 * (-x + 1)^-1 * (-x*y + 1)^-1
Various =======
AUTHORS:
- Daniel Krenn (2016)
ACKNOWLEDGEMENT:
- Daniel Krenn is supported by the Austrian Science Fund (FWF): P 24644-N26.
Functions ========= """
#***************************************************************************** # Copyright (C) 2016 Daniel Krenn <dev@danielkrenn.at> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
Factorization_sort=False, Factorization_simplify=True): r""" Return `\Omega_{\mathrm{op}}` of ``expression`` with respect to ``var``.
To be more precise, calculate
.. MATH::
\Omega_{\mathrm{op}} \frac{n}{d_1 \dots d_n}
for the numerator `n` and the factors `d_1`, ..., `d_n` of the denominator, all of which are Laurent polynomials in ``var`` and return a (partial) factorization of the result.
INPUT:
- ``var`` -- a variable or a representation string of a variable
- ``expression`` -- a :class:`~sage.structure.factorization.Factorization` of Laurent polynomials or, if ``denominator`` is specified, a Laurent polynomial interpreted as the numerator of the expression
- ``denominator`` -- a Laurent polynomial or a :class:`~sage.structure.factorization.Factorization` (consisting of Laurent polynomial factors) or a tuple/list of factors (Laurent polynomials)
- ``op`` -- (default: ``operator.ge``) an operator
At the moment only ``operator.ge`` is implemented.
- ``Factorization_sort`` (default: ``False``) and ``Factorization_simplify`` (default: ``True``) -- are passed on to :class:`sage.structure.factorization.Factorization` when creating the result
OUTPUT:
A (partial) :class:`~sage.structure.factorization.Factorization` of the result whose factors are Laurent polynomials
.. NOTE::
The numerator of the result may not be factored.
REFERENCES:
- [Mac1915]_
- [APR2001]_
EXAMPLES::
sage: L.<mu, x, y, z, w> = LaurentPolynomialRing(ZZ)
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu]) 1 * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu, 1 - z/mu]) 1 * (-x + 1)^-1 * (-x*y + 1)^-1 * (-x*z + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu]) (-x*y*z + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x*z + 1)^-1 * (-y*z + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^2]) 1 * (-x + 1)^-1 * (-x^2*y + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y/mu]) (x*y + 1) * (-x + 1)^-1 * (-x*y^2 + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu^2]) (-x^2*y*z - x*y^2*z + x*y*z + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x^2*z + 1)^-1 * (-y^2*z + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^3]) 1 * (-x + 1)^-1 * (-x^3*y + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^4]) 1 * (-x + 1)^-1 * (-x^4*y + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu^3, 1 - y/mu]) (x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^3 + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu^4, 1 - y/mu]) (x*y^3 + x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^4 + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y/mu, 1 - z/mu]) (x*y*z + x*y + x*z + 1) * (-x + 1)^-1 * (-x*y^2 + 1)^-1 * (-x*z^2 + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y*mu, 1 - z/mu]) (-x*y*z^2 - x*y*z + x*z + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x*z^2 + 1)^-1 * (-y*z + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z*mu, 1 - w/mu]) (x*y*z*w^2 + x*y*z*w - x*y*w - x*z*w - y*z*w + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-z + 1)^-1 * (-x*w + 1)^-1 * (-y*w + 1)^-1 * (-z*w + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu, 1 - w/mu]) (x^2*y*z*w + x*y^2*z*w - x*y*z*w - x*y*z - x*y*w + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x*z + 1)^-1 * (-x*w + 1)^-1 * (-y*z + 1)^-1 * (-y*w + 1)^-1
sage: MacMahonOmega(mu, mu^-2, [1 - x*mu, 1 - y/mu]) x^2 * (-x + 1)^-1 * (-x*y + 1)^-1 sage: MacMahonOmega(mu, mu^-1, [1 - x*mu, 1 - y/mu]) x * (-x + 1)^-1 * (-x*y + 1)^-1 sage: MacMahonOmega(mu, mu, [1 - x*mu, 1 - y/mu]) (-x*y + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1 sage: MacMahonOmega(mu, mu^2, [1 - x*mu, 1 - y/mu]) (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
We demonstrate the different allowed input variants::
sage: MacMahonOmega(mu, ....: Factorization([(mu, 2), (1 - x*mu, -1), (1 - y/mu, -1)])) (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2, ....: Factorization([(1 - x*mu, 1), (1 - y/mu, 1)])) (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2, [1 - x*mu, 1 - y/mu]) (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2, (1 - x*mu)*(1 - y/mu)) # not tested because not fully implemented (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2 / ((1 - x*mu)*(1 - y/mu))) # not tested because not fully implemented (-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
TESTS::
sage: MacMahonOmega(mu, 1, [1 - x*mu]) 1 * (-x + 1)^-1 sage: MacMahonOmega(mu, 1, [1 - x/mu]) 1 sage: MacMahonOmega(mu, 0, [1 - x*mu]) 0 sage: MacMahonOmega(mu, L(1), []) 1 sage: MacMahonOmega(mu, L(0), []) 0 sage: MacMahonOmega(mu, 2, []) 2 sage: MacMahonOmega(mu, 2*mu, []) 2 sage: MacMahonOmega(mu, 2/mu, []) 0
::
sage: MacMahonOmega(mu, Factorization([(1/mu, 1), (1 - x*mu, -1), ....: (1 - y/mu, -2)], unit=2)) 2*x * (-x + 1)^-1 * (-x*y + 1)^-2 sage: MacMahonOmega(mu, Factorization([(mu, -1), (1 - x*mu, -1), ....: (1 - y/mu, -2)], unit=2)) 2*x * (-x + 1)^-1 * (-x*y + 1)^-2 sage: MacMahonOmega(mu, Factorization([(mu, -1), (1 - x, -1)])) 0 sage: MacMahonOmega(mu, Factorization([(2, -1)])) 1 * 2^-1
::
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - z, 1 - y/mu]) 1 * (-z + 1)^-1 * (-x + 1)^-1 * (-x*y + 1)^-1
::
sage: MacMahonOmega(mu, 1, [1 - x*mu], op=operator.lt) Traceback (most recent call last): ... NotImplementedError: At the moment, only Omega_ge is implemented.
sage: MacMahonOmega(mu, 1, Factorization([(1 - x*mu, -1)])) Traceback (most recent call last): ... ValueError: Factorization (-mu*x + 1)^-1 of the denominator contains negative exponents.
sage: MacMahonOmega(2*mu, 1, [1 - x*mu]) Traceback (most recent call last): ... ValueError: 2*mu is not a variable.
sage: MacMahonOmega(mu, 1, Factorization([(0, 2)])) Traceback (most recent call last): ... ZeroDivisionError: Denominator contains a factor 0.
sage: MacMahonOmega(mu, 1, [2 - x*mu]) Traceback (most recent call last): ... NotImplementedError: Factor 2 - x*mu is not normalized.
sage: MacMahonOmega(mu, 1, [1 - x*mu - mu^2]) Traceback (most recent call last): ... NotImplementedError: Cannot handle factor 1 - x*mu - mu^2.
::
sage: L.<mu, x, y, z, w> = LaurentPolynomialRing(QQ) sage: MacMahonOmega(mu, 1/mu, ....: Factorization([(1 - x*mu, 1), (1 - y/mu, 2)], unit=2)) 1/2*x * (-x + 1)^-1 * (-x*y + 1)^-2 """ import LaurentPolynomialRing, LaurentPolynomialRing_univariate
prod(f**e for f, e in expression if e > 0) for _ in range(-e)) else: numerator = expression.numerator() denominator = expression.denominator() else: # at this point we have numerator/denominator
else: denominator = factor(denominator) 'contains negative exponents.'.format(denominator)) for factor, exponent in denominator for _ in range(exponent)) # at this point we have numerator/factors_denominator
L = P L0 = L.base_ring() P.base_ring(), tuple(v for v in P.variable_names() if v != var)) else:
else: else:
_Omega_(numerator.dict(), decoded_factors)
list((f, -1) for f in other_factors) + list((1-f, -1) for f in result_factors_denominator), sort=Factorization_sort, simplify=Factorization_simplify)
r""" Cancels common factors of numerator and denominator.
INPUT:
- ``numerator`` -- a Laurent polynomial
- ``terms`` -- a tuple or other iterable of Laurent polynomials
The denominator is the product of factors `1 - t` for each `t` in ``terms``.
OUTPUT:
A pair of a Laurent polynomial and a tuple of Laurent polynomials representing numerator and denominator as described in the INPUT-section.
EXAMPLES::
sage: from sage.rings.polynomial.omega import _simplify_ sage: L.<x, y> = LaurentPolynomialRing(ZZ) sage: _simplify_(1-x^2, (x, y)) (x + 1, (y,))
TESTS::
sage: _simplify_(1-x^2, (x, -x)) (1, ()) sage: _simplify_(1-x^2, (y^2, y)) (-x^2 + 1, (y^2, y)) sage: _simplify_(1-x^2, (x, L(2))) (x + 1, (2,)) """
r""" Helper function for :func:`MacMahonOmega` which accesses the low level functions and does the substituting.
INPUT:
- ``A`` -- a dictionary mapping `a` to `c` representing a summand `c\mu^a` of the numerator
- ``decoded_factors`` -- a tuple or list of pairs `(z, e)` representing a factor `1 - z \mu^e`
OUTPUT:
A pair representing a quotient as follows: Its first component is the numerator as a Laurent polynomial, its second component a factorization of the denominator as a tuple of Laurent polynomials, where each Laurent polynomial `z` represents a factor `1 - z`.
TESTS:
Extensive testing of this function is done in :func:`MacMahonOmega`.
::
sage: L.<mu, x, y> = LaurentPolynomialRing(ZZ) sage: MacMahonOmega(mu, mu^-2, [1 - x*mu, 1 - y/mu]) x^2 * (-x + 1)^-1 * (-x*y + 1)^-1
internally calls ::
sage: from sage.rings.polynomial.omega import _Omega_ sage: _Omega_({-2: 1}, [(x, 1), (y, -1)]) (x^2, (x, x*y))
::
sage: _Omega_({0: 2, 1: 40, -1: -3}, []) (42, ()) sage: _Omega_({-1: 42}, []) (0, ())
::
sage: MacMahonOmega(mu, 1 - x^2, [1 - x*mu, 1 - y/mu]) (x + 1) * (-x*y + 1)^-1 """
# Below we sort to make the caching more efficient. Doing this here # (in contrast to directly in Omega_ge) results in much cleaner # code and prevents an additional substitution or passing of a permutation.
else: assert factors_denominator == fd
tuple(f.subs(rules) for f in factors_denominator))
def Omega_ge(a, exponents): r""" Return `\Omega_{\ge}` of the expression specified by the input.
To be more precise, calculate
.. MATH::
\Omega_{\ge} \frac{\mu^a}{ (1 - z_0 \mu^{e_0}) \dots (1 - z_{n-1} \mu^{e_{n-1}})}
and return its numerator and a factorization of its denominator. Note that `z_0`, ..., `z_{n-1}` only appear in the output, but not in the input.
INPUT:
- ``a`` -- an integer
- ``exponents`` -- a tuple of integers
OUTPUT:
A pair representing a quotient as follows: Its first component is the numerator as a Laurent polynomial, its second component a factorization of the denominator as a tuple of Laurent polynomials, where each Laurent polynomial `z` represents a factor `1 - z`.
The parents of these Laurent polynomials is always a Laurent polynomial ring in `z_0`, ..., `z_{n-1}` over `\ZZ`, where `n` is the length of ``exponents``.
EXAMPLES::
sage: from sage.rings.polynomial.omega import Omega_ge sage: Omega_ge(0, (1, -2)) (1, (z0, z0^2*z1)) sage: Omega_ge(0, (1, -3)) (1, (z0, z0^3*z1)) sage: Omega_ge(0, (1, -4)) (1, (z0, z0^4*z1))
sage: Omega_ge(0, (2, -1)) (z0*z1 + 1, (z0, z0*z1^2)) sage: Omega_ge(0, (3, -1)) (z0*z1^2 + z0*z1 + 1, (z0, z0*z1^3)) sage: Omega_ge(0, (4, -1)) (z0*z1^3 + z0*z1^2 + z0*z1 + 1, (z0, z0*z1^4))
sage: Omega_ge(0, (1, 1, -2)) (-z0^2*z1*z2 - z0*z1^2*z2 + z0*z1*z2 + 1, (z0, z1, z0^2*z2, z1^2*z2)) sage: Omega_ge(0, (2, -1, -1)) (z0*z1*z2 + z0*z1 + z0*z2 + 1, (z0, z0*z1^2, z0*z2^2)) sage: Omega_ge(0, (2, 1, -1)) (-z0*z1*z2^2 - z0*z1*z2 + z0*z2 + 1, (z0, z1, z0*z2^2, z1*z2))
::
sage: Omega_ge(0, (2, -2)) (-z0*z1 + 1, (z0, z0*z1, z0*z1)) sage: Omega_ge(0, (2, -3)) (z0^2*z1 + 1, (z0, z0^3*z1^2)) sage: Omega_ge(0, (3, 1, -3)) (-z0^3*z1^3*z2^3 + 2*z0^2*z1^3*z2^2 - z0*z1^3*z2 + z0^2*z2^2 - 2*z0*z2 + 1, (z0, z1, z0*z2, z0*z2, z0*z2, z1^3*z2))
::
sage: Omega_ge(0, (3, 6, -1)) (-z0*z1*z2^8 - z0*z1*z2^7 - z0*z1*z2^6 - z0*z1*z2^5 - z0*z1*z2^4 + z1*z2^5 - z0*z1*z2^3 + z1*z2^4 - z0*z1*z2^2 + z1*z2^3 - z0*z1*z2 + z0*z2^2 + z1*z2^2 + z0*z2 + z1*z2 + 1, (z0, z1, z0*z2^3, z1*z2^6))
TESTS::
sage: Omega_ge(0, (2, 2, 1, 1, 1, -1, -1))[0].number_of_terms() # long time 1695 sage: Omega_ge(0, (2, 2, 1, 1, 1, 1, 1, -1, -1))[0].number_of_terms() # not tested (too long, 1 min) 27837
::
sage: Omega_ge(1, (2,)) (1, (z0,)) """
raise NotImplementedError
(e, tuple(powers[abs(e)]**j * z for j in srange(abs(e)))) for z, e in zip(L.gens()[1:], exponents))
r""" Substitute ``var^exponent`` by ``var`` in ``expression``.
It is assumed that ``var`` only occurs with exponents divisible by ``exponent``. """
for factor in _Omega_factors_denominator_(x, y))
r""" Return the numerator of `\Omega_{\ge}` of the expression specified by the input.
To be more precise, calculate
.. MATH::
\Omega_{\ge} \frac{\mu^a}{ (1 - x_1 \mu) \dots (1 - x_n \mu) (1 - y_1 / \mu) \dots (1 - y_m / \mu)}
and return its numerator.
This function is meant to be a helper function of :func:`MacMahonOmega`.
INPUT:
- ``a`` -- an integer
- ``x`` and ``y`` -- a tuple of tuples of Laurent polynomials
The flattened ``x`` contains `x_1,...,x_n`, the flattened ``y`` the `y_1,...,y_m`. The non-flatness of these parameters is to be interface-consistent with :func:`_Omega_factors_denominator_`.
- ``t`` -- a temporary Laurent polynomial variable used for substituting
OUTPUT:
A Laurent polynomial
The output is normalized such that the corresponding denominator (:func:`_Omega_factors_denominator_`) has constant term `1`.
EXAMPLES::
sage: from sage.rings.polynomial.omega import _Omega_numerator_, _Omega_factors_denominator_
sage: L.<x0, x1, x2, x3, y0, y1, t> = LaurentPolynomialRing(ZZ) sage: _Omega_numerator_(0, ((x0,),), ((y0,),), t) 1 sage: _Omega_numerator_(0, ((x0,), (x1,)), ((y0,),), t) -x0*x1*y0 + 1 sage: _Omega_numerator_(0, ((x0,),), ((y0,), (y1,)), t) 1 sage: _Omega_numerator_(0, ((x0,), (x1,), (x2,)), ((y0,),), t) x0*x1*x2*y0^2 + x0*x1*x2*y0 - x0*x1*y0 - x0*x2*y0 - x1*x2*y0 + 1 sage: _Omega_numerator_(0, ((x0,), (x1,)), ((y0,), (y1,)), t) x0^2*x1*y0*y1 + x0*x1^2*y0*y1 - x0*x1*y0*y1 - x0*x1*y0 - x0*x1*y1 + 1
sage: _Omega_numerator_(-2, ((x0,),), ((y0,),), t) x0^2 sage: _Omega_numerator_(-1, ((x0,),), ((y0,),), t) x0 sage: _Omega_numerator_(1, ((x0,),), ((y0,),), t) -x0*y0 + y0 + 1 sage: _Omega_numerator_(2, ((x0,),), ((y0,),), t) -x0*y0^2 - x0*y0 + y0^2 + y0 + 1
TESTS::
sage: _Omega_factors_denominator_((), ()) () sage: _Omega_numerator_(0, (), (), t) 1 sage: _Omega_numerator_(+2, (), (), t) 1 sage: _Omega_numerator_(-2, (), (), t) 0
sage: _Omega_factors_denominator_(((x0,),), ()) (-x0 + 1,) sage: _Omega_numerator_(0, ((x0,),), (), t) 1 sage: _Omega_numerator_(+2, ((x0,),), (), t) 1 sage: _Omega_numerator_(-2, ((x0,),), (), t) x0^2
sage: _Omega_factors_denominator_((), ((y0,),)) () sage: _Omega_numerator_(0, (), ((y0,),), t) 1 sage: _Omega_numerator_(+2, (), ((y0,),), t) y0^2 + y0 + 1 sage: _Omega_numerator_(-2, (), ((y0,),), t) 0
::
sage: L.<X, Y, t> = LaurentPolynomialRing(ZZ) sage: _Omega_numerator_(2, ((X,),), ((Y,),), t) -X*Y^2 - X*Y + Y^2 + Y + 1 """
sum(homogenous_symmetric_function(j, xy) for j in srange(-a)) if a < 0 else 0) for j in srange(a+1)) else:
r""" Helper function for :func:`_Omega_numerator_`.
This is an implementation of the function `P` of [APR2001]_.
INPUT:
- ``a`` -- an integer
- ``x`` and ``y`` -- a tuple of Laurent polynomials
The tuple ``x`` here is the flattened ``x`` of :func:`_Omega_numerator_` but without its last entry.
- ``t`` -- a temporary Laurent polynomial variable
In the (final) result, ``t`` has to be substituted by the last entry of the flattened ``x`` of :func:`_Omega_numerator_`.
OUTPUT:
A Laurent polynomial
TESTS::
sage: from sage.rings.polynomial.omega import _Omega_numerator_P_ sage: L.<x0, x1, y0, y1, t> = LaurentPolynomialRing(ZZ) sage: _Omega_numerator_P_(0, (x0,), (y0,), t).subs({t: x1}) -x0*x1*y0 + 1 """ # This function takes Laurent polynomials as inputs. It would # be possible to input only the sizes of ``x`` and ``y`` and # perform a substitution afterwards; in this way caching of this # function would make sense. However, the way it is now allows # automatic collection and simplification of the summands, which # makes it more efficient for higher powers at the input of # :func:`Omega_ge`. # Caching occurs in :func:`Omega_ge`.
(prod(1 - x0*yy for yy in y) * sum(homogenous_symmetric_function(j, y) * (1-x0**(j-a)) for j in srange(a)) if a > 0 else 0) else: x2 * (1-x1) * prod(1 - x1*yy for yy in y) * p2
def _Omega_factors_denominator_(x, y): r""" Return the denominator of `\Omega_{\ge}` of the expression specified by the input.
To be more precise, calculate
.. MATH::
\Omega_{\ge} \frac{1}{ (1 - x_1 \mu) \dots (1 - x_n \mu) (1 - y_1 / \mu) \dots (1 - y_m / \mu)}
and return a factorization of its denominator.
This function is meant to be a helper function of :func:`MacMahonOmega`.
INPUT:
- ``x`` and ``y`` -- a tuple of tuples of Laurent polynomials
The flattened ``x`` contains `x_1,...,x_n`, the flattened ``y`` the `y_1,...,y_m`.
OUTPUT:
A factorization of the denominator as a tuple of Laurent polynomials
The output is normalized such that it has constant term `1`.
.. NOTE::
The assumption is that the ``x`` and ``y`` are collected in such a way that one entry of ``x`` corresponds to the orbit of some ``x_j`` under multiplication by `d`-th roots of unity and that the output is collected in a corresponding way.
EXAMPLES::
sage: from sage.rings.polynomial.omega import _Omega_factors_denominator_
sage: L.<x0, x1, x2, x3, y0, y1> = LaurentPolynomialRing(ZZ) sage: _Omega_factors_denominator_(((x0,),), ((y0,),)) (-x0 + 1, -x0*y0 + 1) sage: _Omega_factors_denominator_(((x0,),), ((y0,), (y1,))) (-x0 + 1, -x0*y0 + 1, -x0*y1 + 1) sage: _Omega_factors_denominator_(((x0,), (x1,)), ((y0,),)) (-x0 + 1, -x1 + 1, -x0*y0 + 1, -x1*y0 + 1) sage: _Omega_factors_denominator_(((x0,), (x1,), (x2,)), ((y0,),)) (-x0 + 1, -x1 + 1, -x2 + 1, -x0*y0 + 1, -x1*y0 + 1, -x2*y0 + 1) sage: _Omega_factors_denominator_(((x0,), (x1,)), ((y0,), (y1,))) (-x0 + 1, -x1 + 1, -x0*y0 + 1, -x0*y1 + 1, -x1*y0 + 1, -x1*y1 + 1)
::
sage: B.<zeta> = ZZ.extension(cyclotomic_polynomial(3)) sage: L.<x, y> = LaurentPolynomialRing(B) sage: _Omega_factors_denominator_(((x, -x),), ((y,),)) (-x^2 + 1, -x^2*y^2 + 1) sage: _Omega_factors_denominator_(((x, -x),), ((y, zeta*y, zeta^2*y),)) (-x^2 + 1, -x^6*y^6 + 1) sage: _Omega_factors_denominator_(((x, -x),), ((y, -y),)) (-x^2 + 1, -x^2*y^2 + 1, -x^2*y^2 + 1)
TESTS::
sage: L.<x0, y0> = LaurentPolynomialRing(ZZ) sage: _Omega_factors_denominator_((), ()) () sage: _Omega_factors_denominator_(((x0,),), ()) (-x0 + 1,) sage: _Omega_factors_denominator_((), ((y0,),)) () """
sum(((prod(1 - xx*yy for xx in gx for yy in gy),) if len(gx) != len(gy) else tuple(prod(1 - xx*yy for xx in gx) for yy in gy) for gx in x for gy in y), tuple())
r""" Split ``items`` into two parts by the given ``predicate``.
INPUT:
- ``item`` -- an iterator
- ``predicate`` -- a function
OUTPUT:
A pair of iterators; the first contains the elements not satisfying the ``predicate``, the second the elements satisfying the ``predicate``.
ALGORITHM:
Source of the code: `http://nedbatchelder.com/blog/201306/filter_a_list_into_two_parts.html <http://nedbatchelder.com/blog/201306/filter_a_list_into_two_parts.html>`_
EXAMPLES::
sage: from sage.rings.polynomial.omega import partition sage: E, O = partition(srange(10), is_odd) sage: tuple(E), tuple(O) ((0, 2, 4, 6, 8), (1, 3, 5, 7, 9)) """ (item for pred, item in b if pred))
r""" Return a complete homogeneous symmetric polynomial (:wikipedia:`Complete_homogeneous_symmetric_polynomial`).
INPUT:
- ``j`` -- the degree as a nonnegative integer
- ``x`` -- an iterable of variables
OUTPUT:
A polynomial of the common parent of all entries of ``x``
EXAMPLES::
sage: from sage.rings.polynomial.omega import homogenous_symmetric_function sage: P = PolynomialRing(ZZ, 'X', 3) sage: homogenous_symmetric_function(0, P.gens()) 1 sage: homogenous_symmetric_function(1, P.gens()) X0 + X1 + X2 sage: homogenous_symmetric_function(2, P.gens()) X0^2 + X0*X1 + X1^2 + X0*X2 + X1*X2 + X2^2 sage: homogenous_symmetric_function(3, P.gens()) X0^3 + X0^2*X1 + X0*X1^2 + X1^3 + X0^2*X2 + X0*X1*X2 + X1^2*X2 + X0*X2^2 + X1*X2^2 + X2^3 """
for p in IntegerVectors(j, length=len(x))) |