For a comprehensive tutorial on how to use symmetric functions in Sage
See also
We define the algebra of symmetric functions in the Schur and elementary bases:
sage: s = SymmetricFunctions(QQ).schur()
sage: e = SymmetricFunctions(QQ).elementary()
Each is actually a graded Hopf algebra whose basis is indexed by integer partitions:
sage: s.category()
Category of bases of Symmetric Functions over Rational Field
sage: s.basis().keys()
Partitions
Let us compute with some elements in different bases:
sage: f1 = s([2,1]); f1
s[2, 1]
sage: f2 = e(f1); f2 # basis conversion
e[2, 1] - e[3]
sage: f1 == f2
True
sage: f1.expand(3, alphabet=['x','y','z'])
x^2*y + x*y^2 + x^2*z + 2*x*y*z + y^2*z + x*z^2 + y*z^2
sage: f2.expand(3, alphabet=['x','y','z'])
x^2*y + x*y^2 + x^2*z + 2*x*y*z + y^2*z + x*z^2 + y*z^2
sage: m = SymmetricFunctions(QQ).monomial()
sage: m([3,1])
m[3, 1]
sage: m(4) # This is the constant 4, not the partition 4.
4*m[]
sage: m([4]) # This is the partition 4.
m[4]
sage: 3*m([3,1])-1/2*m([4])
3*m[3, 1] - 1/2*m[4]
sage: p = SymmetricFunctions(QQ).power()
sage: f = p(3)
sage: f
3*p[]
sage: f.parent()
Symmetric Functions over Rational Field in the powersum basis
sage: f + p([3,2])
3*p[] + p[3, 2]
One can convert symmetric functions to symmetric polynomials and vice versa:
sage: Sym = SymmetricFunctions(QQ)
sage: p = Sym.powersum()
sage: h = Sym.homogeneous()
sage: f = h[2,1] + 2*p[3,1]
sage: poly = f.expand(3); poly
2*x0^4 + 2*x0^3*x1 + 2*x0*x1^3 + 2*x1^4 + 2*x0^3*x2 + 2*x1^3*x2 + 2*x0*x2^3 + 2*x1*x2^3 + 2*x2^4
+ x0^3 + 2*x0^2*x1 + 2*x0*x1^2 + x1^3 + 2*x0^2*x2 + 3*x0*x1*x2 + 2*x1^2*x2 + 2*x0*x2^2 + 2*x1*x2^2 + x2^3
sage: Sym.from_polynomial(poly)
3*m[1, 1, 1] + 2*m[2, 1] + m[3] + 2*m[3, 1] + 2*m[4]
sage: Sym.from_polynomial(poly) == f
True
sage: g = h[1,1,1,1]
sage: poly = g.expand(3)
sage: Sym.from_polynomial(poly) == g
False
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: h = Sym.h()
sage: p = Sym.p()
sage: e = Sym.e()
sage: m = Sym.m()
sage: a = s([3,1])
sage: s(a)
s[3, 1]
sage: h(a)
h[3, 1] - h[4]
sage: p(a)
1/8*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] - 1/8*p[2, 2] - 1/4*p[4]
sage: e(a)
e[2, 1, 1] - e[2, 2] - e[3, 1] + e[4]
sage: m(a)
3*m[1, 1, 1, 1] + 2*m[2, 1, 1] + m[2, 2] + m[3, 1]
sage: a.expand(4)
x0^3*x1 + x0^2*x1^2 + x0*x1^3 + x0^3*x2 + 2*x0^2*x1*x2 + 2*x0*x1^2*x2 + x1^3*x2 + x0^2*x2^2 + 2*x0*x1*x2^2 + x1^2*x2^2 + x0*x2^3 + x1*x2^3 + x0^3*x3 + 2*x0^2*x1*x3 + 2*x0*x1^2*x3 + x1^3*x3 + 2*x0^2*x2*x3 + 3*x0*x1*x2*x3 + 2*x1^2*x2*x3 + 2*x0*x2^2*x3 + 2*x1*x2^2*x3 + x2^3*x3 + x0^2*x3^2 + 2*x0*x1*x3^2 + x1^2*x3^2 + 2*x0*x2*x3^2 + 2*x1*x2*x3^2 + x2^2*x3^2 + x0*x3^3 + x1*x3^3 + x2*x3^3
Here are further examples:
sage: h(m([1]))
h[1]
sage: h( m([2]) +m([1,1]) )
h[2]
sage: h( m([3]) + m([2,1]) + m([1,1,1]) )
h[3]
sage: h( m([4]) + m([3,1]) + m([2,2]) + m([2,1,1]) + m([1,1,1,1]) )
h[4]
sage: k = 5
sage: h( sum([ m(part) for part in Partitions(k)]) )
h[5]
sage: k = 10
sage: h( sum([ m(part) for part in Partitions(k)]) )
h[10]
sage: P3 = Partitions(3)
sage: P3.list()
[[3], [2, 1], [1, 1, 1]]
sage: m = SymmetricFunctions(QQ).monomial()
sage: f = sum([m(p) for p in P3])
sage: m.get_print_style()
'lex'
sage: f
m[1, 1, 1] + m[2, 1] + m[3]
sage: m.set_print_style('length')
sage: f
m[3] + m[2, 1] + m[1, 1, 1]
sage: m.set_print_style('maximal_part')
sage: f
m[1, 1, 1] + m[2, 1] + m[3]
sage: m.set_print_style('lex')
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: m = Sym.m()
sage: m([3])*s([2,1])
2*m[3, 1, 1, 1] + m[3, 2, 1] + 2*m[4, 1, 1] + m[4, 2] + m[5, 1]
sage: s(m([3])*s([2,1]))
s[2, 1, 1, 1, 1] - s[2, 2, 2] - s[3, 3] + s[5, 1]
sage: s(s([2,1])*m([3]))
s[2, 1, 1, 1, 1] - s[2, 2, 2] - s[3, 3] + s[5, 1]
sage: e = Sym.e()
sage: e([4])*e([3])*e([1])
e[4, 3, 1]
sage: s = SymmetricFunctions(QQ).s()
sage: z = s([2,1]) + s([1,1,1])
sage: z.coefficient([2,1])
1
sage: z.length()
2
sage: z.support()
[[1, 1, 1], [2, 1]]
sage: z.degree()
3
TESTS:
Check that we can handle large integers properly (trac ticket #13413):
sage: s = SymmetricFunctions(QQ).s()
sage: p = SymmetricFunctions(QQ).p()
sage: max(s(p([1]*36)).coefficients()) # long time (4s on sage.math, 2013)
40971642983700000000
BACKWARD INCOMPATIBLE CHANGES (trac ticket #5457):
The symmetric functions code has been refactored to take advantage of the coercion systems. This introduced a couple of glitches:
On some bases changes, coefficients in Jack polynomials are not normalized
Except in a few cases, conversions and coercions are only defined between symmetric functions over the same coefficient ring. E.g. the following does not work anymore:
sage: s = SymmetricFunctions(QQ)
sage: s2 = SymmetricFunctions(QQ['t'])
sage: s([1]) + s2([2]) # todo: not implemented
This feature will probably come back at some point through improvements to the Sage coercion system.
Backward compatibility should be essentially retained.
AUTHORS:
This is deprecated in trac ticket #15473. Use instead SymmetricFunctions as SymmetricFunctions(R).basis()
INPUT:
OUTPUT: A SymmetricFunctionAlgebra
EXAMPLES:
sage: SymmetricFunctionAlgebra(QQ)
doctest:...: DeprecationWarning: this function is deprecated. Use SymmetricFunctions(R).basis()
See http://trac.sagemath.org/15473 for details.
Symmetric Functions over Rational Field in the Schur basis
Bases: sage.combinat.free_module.CombinatorialFreeModule
Abstract base class for symmetric function algebras.
Todo
Most of the methods in this class are generic (manipulations of morphisms, ...) and should be generalized (or removed)
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: m = SymmetricFunctions(ZZ).m()
sage: s(m([2,1]))
-2*s[1, 1, 1] + s[2, 1]
Return the name of the basis of self.
This is used for output and, for the classical bases of symmetric functions, to connect this basis with Symmetrica.
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: s.basis_name()
'Schur'
sage: p = Sym.p()
sage: p.basis_name()
'powersum'
sage: h = Sym.h()
sage: h.basis_name()
'homogeneous'
sage: e = Sym.e()
sage: e.basis_name()
'elementary'
sage: m = Sym.m()
sage: m.basis_name()
'monomial'
sage: f = Sym.f()
sage: f.basis_name()
'forgotten'
Return the coproduct of the element elt by coercion to the Schur basis.
INPUT:
OUTPUT:
EXAMPLES:
sage: m = SymmetricFunctions(QQ).m()
sage: m[3,1,1].coproduct()
m[] # m[3, 1, 1] + m[1] # m[3, 1] + m[1, 1] # m[3] + m[3] # m[1, 1] + m[3, 1] # m[1] + m[3, 1, 1] # m[]
sage: m.coproduct_by_coercion(m[2,1])
m[] # m[2, 1] + m[1] # m[2] + m[2] # m[1] + m[2, 1] # m[]
sage: m.coproduct_by_coercion(m[2,1]) == m([2,1]).coproduct()
True
sage: McdH = SymmetricFunctions(QQ['q','t'].fraction_field()).macdonald().H()
sage: McdH[2,1].coproduct()
McdH[] # McdH[2, 1] + ((q^2*t-1)/(q*t-1))*McdH[1] # McdH[1, 1] + ((q*t^2-1)/(q*t-1))*McdH[1] # McdH[2] + ((q^2*t-1)/(q*t-1))*McdH[1, 1] # McdH[1] + ((q*t^2-1)/(q*t-1))*McdH[2] # McdH[1] + McdH[2, 1] # McdH[]
sage: HLQp = SymmetricFunctions(QQ['t'].fraction_field()).hall_littlewood().Qp()
sage: HLQp[2,1].coproduct()
HLQp[] # HLQp[2, 1] + HLQp[1] # HLQp[1, 1] + HLQp[1] # HLQp[2] + HLQp[1, 1] # HLQp[1] + HLQp[2] # HLQp[1] + HLQp[2, 1] # HLQp[]
sage: Sym = SymmetricFunctions(FractionField(QQ['t']))
sage: LLT = Sym.llt(3)
sage: LLT.cospin([3,2,1]).coproduct()
(t+1)*m[] # m[1, 1] + m[] # m[2] + (t+1)*m[1] # m[1] + (t+1)*m[1, 1] # m[] + m[2] # m[]
sage: f = SymmetricFunctions(ZZ).f()
sage: f[3].coproduct()
f[] # f[3] + f[3] # f[]
sage: f[3,2,1].coproduct()
f[] # f[3, 2, 1] + f[1] # f[3, 2] + f[2] # f[3, 1] + f[2, 1] # f[3] + f[3] # f[2, 1] + f[3, 1] # f[2] + f[3, 2] # f[1] + f[3, 2, 1] # f[]
Return the dual basis of self with respect to the scalar product scalar.
INPUT:
EXAMPLES:
The duals of the elementary symmetric functions with respect to the Hall scalar product are the forgotten symmetric functions.
sage: e = SymmetricFunctions(QQ).e()
sage: f = e.dual_basis(prefix='f'); f
Dual basis to Symmetric Functions over Rational Field in the elementary basis with respect to the Hall scalar product
sage: f([2,1])^2
4*f[2, 2, 1, 1] + 6*f[2, 2, 2] + 2*f[3, 2, 1] + 2*f[3, 3] + 2*f[4, 1, 1] + f[4, 2]
sage: f([2,1]).scalar(e([2,1]))
1
sage: f([2,1]).scalar(e([1,1,1]))
0
Since the power-sum symmetric functions are orthogonal, their duals with respect to the Hall scalar product are scalar multiples of themselves.
sage: p = SymmetricFunctions(QQ).p()
sage: q = p.dual_basis(prefix='q'); q
Dual basis to Symmetric Functions over Rational Field in the powersum basis with respect to the Hall scalar product
sage: q([2,1])^2
4*q[2, 2, 1, 1]
sage: p([2,1]).scalar(q([2,1]))
1
sage: p([2,1]).scalar(q([1,1,1]))
0
Convert polynomial to a symmetric function in the monomial basis and then to the basis self.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: h = Sym.homogeneous()
sage: f = (h([]) + h([2,1]) + h([3])).expand(3)
sage: h.from_polynomial(f)
h[] + h[2, 1] + h[3]
sage: s = Sym.s()
sage: g = (s([]) + s([2,1])).expand(3); g
x0^2*x1 + x0*x1^2 + x0^2*x2 + 2*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + 1
sage: s.from_polynomial(g)
s[] + s[2, 1]
Return the value of the current print style for self.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s.get_print_style()
'lex'
sage: s.set_print_style('length')
sage: s.get_print_style()
'length'
sage: s.set_print_style('lex')
Return the prefix on the elements of self.
EXAMPLES:
sage: schur = SymmetricFunctions(QQ).schur()
sage: schur([3,2,1])
s[3, 2, 1]
sage: schur.prefix()
's'
Set the value of the current print style to ps.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s.get_print_style()
'lex'
sage: s.set_print_style('length')
sage: s.get_print_style()
'length'
sage: s.set_print_style('lex')
Return the family of symmetric functions associated to the basis self.
OUTPUT:
EXAMPLES:
sage: schur = SymmetricFunctions(QQ).schur()
sage: schur.symmetric_function_ring()
Symmetric Functions over Rational Field
sage: power = SymmetricFunctions(QQ['t']).power()
sage: power.symmetric_function_ring()
Symmetric Functions over Univariate Polynomial Ring in t over Rational Field
Return the transition matrix between self and basis for the homogeneous component of degree n.
INPUT:
OUTPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: m = SymmetricFunctions(QQ).m()
sage: s.transition_matrix(m,5)
[1 1 1 1 1 1 1]
[0 1 1 2 2 3 4]
[0 0 1 1 2 3 5]
[0 0 0 1 1 3 6]
[0 0 0 0 1 2 5]
[0 0 0 0 0 1 4]
[0 0 0 0 0 0 1]
sage: s.transition_matrix(m,1)
[1]
sage: s.transition_matrix(m,0)
[1]
sage: p = SymmetricFunctions(QQ).p()
sage: s.transition_matrix(p, 4)
[ 1/4 1/3 1/8 1/4 1/24]
[-1/4 0 -1/8 1/4 1/8]
[ 0 -1/3 1/4 0 1/12]
[ 1/4 0 -1/8 -1/4 1/8]
[-1/4 1/3 1/8 -1/4 1/24]
sage: StoP = s.transition_matrix(p,4)
sage: a = s([3,1])+5*s([1,1,1,1])-s([4])
sage: a
5*s[1, 1, 1, 1] + s[3, 1] - s[4]
sage: mon = a.support()
sage: coeffs = a.coefficients()
sage: coeffs
[5, 1, -1]
sage: mon
[[1, 1, 1, 1], [3, 1], [4]]
sage: cm = matrix([[-1,1,0,0,5]])
sage: cm * StoP
[-7/4 4/3 3/8 -5/4 7/24]
sage: p(a)
7/24*p[1, 1, 1, 1] - 5/4*p[2, 1, 1] + 3/8*p[2, 2] + 4/3*p[3, 1] - 7/4*p[4]
sage: h = SymmetricFunctions(QQ).h()
sage: e = SymmetricFunctions(QQ).e()
sage: s.transition_matrix(m,7) == h.transition_matrix(s,7).transpose()
True
sage: h.transition_matrix(m, 7) == h.transition_matrix(m, 7).transpose()
True
sage: h.transition_matrix(e, 7) == e.transition_matrix(h, 7)
True
sage: p.transition_matrix(s, 5)
[ 1 -1 0 1 0 -1 1]
[ 1 0 -1 0 1 0 -1]
[ 1 -1 1 0 -1 1 -1]
[ 1 1 -1 0 -1 1 1]
[ 1 0 1 -2 1 0 1]
[ 1 2 1 0 -1 -2 -1]
[ 1 4 5 6 5 4 1]
sage: e.transition_matrix(m,7) == e.transition_matrix(m,7).transpose()
True
Bases: sage.combinat.free_module.CombinatorialFreeModuleElement
Class of generic elements for the symmetric function algebra.
TESTS:
sage: m = SymmetricFunctions(QQ).m()
sage: f = sum([m(p) for p in Partitions(3)])
sage: m.set_print_style('lex')
sage: f
m[1, 1, 1] + m[2, 1] + m[3]
sage: m.set_print_style('length')
sage: f
m[3] + m[2, 1] + m[1, 1, 1]
sage: m.set_print_style('maximal_part')
sage: f
m[1, 1, 1] + m[2, 1] + m[3]
sage: m.set_print_style('lex')
Return the image of the symmetric function self under the
-th Frobenius operator.
The -th Frobenius operator
is defined to be the
map from the ring of symmetric functions to itself that sends
every symmetric function
to
. This operator
is a Hopf algebra endomorphism, and satisfies
for every partition
(where
means the monomial basis). Moreover,
for every positive integer
(where
denotes the
-th powersum symmetric function).
The -th Frobenius operator is also called the
-th
Frobenius endomorphism. It is not related to the Frobenius map
which connects the ring of symmetric functions with the
representation theory of the symmetric group.
The -th Frobenius operator is also the
-th Adams operator
of the
-ring of symmetric functions over the integers.
The -th Frobenius operator can also be described via plethysm:
Every symmetric function
satisfies
,
where
is the
-th powersum symmetric function, and
denotes (outer) plethysm.
adams_operation() serves as alias for frobenius(), since the
Frobenius operators are the Adams operations of the -ring
of symmetric functions.
INPUT:
OUTPUT:
The result of applying the -th Frobenius operator (on the ring of
symmetric functions) to self.
EXAMPLES:
sage: Sym = SymmetricFunctions(ZZ)
sage: p = Sym.p()
sage: h = Sym.h()
sage: s = Sym.s()
sage: m = Sym.m()
sage: s[3].frobenius(2)
-s[3, 3] + s[4, 2] - s[5, 1] + s[6]
sage: m[4,2,1].frobenius(3)
m[12, 6, 3]
sage: p[4,2,1].frobenius(3)
p[12, 6, 3]
sage: h[4].frobenius(2)
h[4, 4] - 2*h[5, 3] + 2*h[6, 2] - 2*h[7, 1] + 2*h[8]
The Frobenius endomorphisms are multiplicative:
sage: all( all( s(lam).frobenius(3) * s(mu).frobenius(3) # long time
....: == (s(lam) * s(mu)).frobenius(3)
....: for mu in Partitions(3) )
....: for lam in Partitions(3) )
True
sage: all( all( m(lam).frobenius(2) * m(mu).frobenius(2)
....: == (m(lam) * m(mu)).frobenius(2)
....: for mu in Partitions(4) )
....: for lam in Partitions(4) )
True
sage: all( all( p(lam).frobenius(2) * p(mu).frobenius(2)
....: == (p(lam) * p(mu)).frobenius(2)
....: for mu in Partitions(3) )
....: for lam in Partitions(4) )
True
Being Hopf algebra endomorphisms, the Frobenius operators commute with the antipode:
sage: all( p(lam).frobenius(4).antipode()
....: == p(lam).antipode().frobenius(4)
....: for lam in Partitions(3) )
True
Testing the
equality (over
, since plethysm is currently not
defined over
in Sage):
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: p = Sym.p()
sage: all( s(lam).frobenius(3) == s(lam).plethysm(p[3])
....: == s(p[3].plethysm(s(lam)))
....: for lam in Partitions(4) )
True
By Exercise 7.61 in Stanley’s EC2 [STA] (see the errata on his
website), is a linear combination of
Schur polynomials (of straight shapes) using coefficients
,
and
only; moreover, all partitions whose Schur
polynomials occur with coefficient
in this
combination have empty
-cores. Let us check this on
examples:
sage: all( all( all( (coeff == -1 or coeff == 1)
....: and lam.core(n) == Partition([])
....: for lam, coeff in s([m]).frobenius(n) )
....: for n in range(2, 4) )
....: for m in range(4) )
True
See also
Todo
This method is fast on the monomial and the powersum bases, while all other bases get converted to the monomial basis. For most bases, this is probably the quickest way to do, but at least the Schur basis should have a better option. (Quoting from Stanley’s EC2 [STA]: “D. G. Duncan, J. London Math. Soc. 27 (1952), 235-236, or Y. M. Chen, A. M. Garsia, and J. B. Remmel, Contemp. Math. 34 (1984), 109-153”.)
Return the arithmetic product of self and x in the basis of self.
The arithmetic product is a binary operation on the
ring of symmetric functions which is bilinear in its two
arguments and satisfies
for any two partitions and
(where
denotes the power-sum symmetric function indexed by the partition
, and
denotes the
-th power-sum symmetric function).
This is enough to define the arithmetic product if the base ring
is torsion-free as a
-module; for all other cases the
arithmetic product is uniquely determined by requiring it to be
functorial in the base ring. See
http://mathoverflow.net/questions/138148/ for a discussion of
this arithmetic product.
If and
are two symmetric functions which are homogeneous
of degrees
and
, respectively, then
is
homogeneous of degree
.
The arithmetic product is commutative and associative and has
unity .
INPUT:
OUTPUT:
Arithmetic product of self with x; this is a symmetric function over the same base ring as self.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s([2]).arithmetic_product(s([2]))
s[1, 1, 1, 1] + 2*s[2, 2] + s[4]
sage: s([2]).arithmetic_product(s([1,1]))
s[2, 1, 1] + s[3, 1]
The symmetric function e[1] is the unity for the arithmetic product:
sage: e = SymmetricFunctions(ZZ).e()
sage: all( e([1]).arithmetic_product(e(q)) == e(q) for q in Partitions(4) )
True
The arithmetic product is commutative:
sage: e = SymmetricFunctions(FiniteField(19)).e()
sage: m = SymmetricFunctions(FiniteField(19)).m()
sage: all( all( e(p).arithmetic_product(m(q)) == m(q).arithmetic_product(e(p)) # long time (26s on sage.math, 2013)
....: for q in Partitions(4) )
....: for p in Partitions(4) )
True
Note
The currently existing implementation of this function is
technically unsatisfactory. It distinguishes the case when the
base ring is a -algebra (in which case the arithmetic product
can be easily computed using the power sum basis) from the case
where it isn’t. In the latter, it does a computation using
universal coefficients, again distinguishing the case when it is
able to compute the “corresponding” basis of the symmetric function
algebra over
(using the corresponding_basis_over hack)
from the case when it isn’t (in which case it transforms everything
into the Schur basis, which is slow).
Return the image of self under the -th Bernstein creation
operator.
Let be an integer. The
-th Bernstein creation operator
is defined as the endomorphism of the space
of symmetric functions which sends every
to
where usual notations are in place ( stands for the complete
homogeneous symmetric functions,
for the elementary ones,
and
means skewing (skew_by()) by
).
This has been studied in [BBSSZ2012], section 2.2, where the
following rule is given for computing on a
Schur function: If
is
an
-tuple of integers (positive or not), then
Here, is the
“Schur function” associated to the
-tuple
, and defined by
literally applying the Jacobi-Trudi identity, i.e., by
This notion of a Schur function clearly extends the classical
notion of Schur function corresponding to a partition, but is
easily reduced to the latter (in fact, for any -tuple
of integers, one easily sees that
is
either
or minus-plus a Schur function corresponding to a
partition; and it is easy to determine which of these is the
case and find the partition by a combinatorial algorithm).
EXAMPLES:
Let us check that what this method computes agrees with the definition:
sage: Sym = SymmetricFunctions(ZZ)
sage: e = Sym.e()
sage: h = Sym.h()
sage: s = Sym.s()
sage: def bernstein_creation_by_def(n, f):
....: # `n`-th Bernstein creation operator applied to `f`
....: # computed according to its definition.
....: res = f.parent().zero()
....: if not f:
....: return res
....: max_degree = max(sum(m) for m, c in f)
....: for i in range(max_degree + 1):
....: if n + i >= 0:
....: res += (-1) ** i * h[n + i] * f.skew_by(e[i])
....: return res
sage: all( bernstein_creation_by_def(n, s[l]) == s[l].bernstein_creation_operator(n)
....: for n in range(-2, 3) for l in Partitions(4) )
True
sage: all( bernstein_creation_by_def(n, s[l]) == s[l].bernstein_creation_operator(n)
....: for n in range(-3, 4) for l in Partitions(3) )
True
sage: all( bernstein_creation_by_def(n, e[l]) == e[l].bernstein_creation_operator(n)
....: for n in range(-3, 4) for k in range(3) for l in Partitions(k) )
True
Some examples:
sage: s[3,2].bernstein_creation_operator(3)
s[3, 3, 2]
sage: s[3,2].bernstein_creation_operator(1)
-s[2, 2, 2]
sage: h[3,2].bernstein_creation_operator(-2)
h[2, 1]
sage: h[3,2].bernstein_creation_operator(-1)
h[2, 1, 1] - h[2, 2] - h[3, 1]
sage: h[3,2].bernstein_creation_operator(0)
-h[3, 1, 1] + h[3, 2]
sage: h[3,2].bernstein_creation_operator(1)
-h[2, 2, 2] + h[3, 2, 1]
sage: h[3,2].bernstein_creation_operator(2)
-h[3, 3, 1] + h[4, 2, 1]
Return the degree of self (which is defined to be
for the zero element).
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) + 3
sage: z.degree()
4
sage: s(1).degree()
0
sage: s(0).degree()
0
Return the symmetric function obtained by taking the derivative of
self with respect to the power-sum symmetric function
when the expansion of self in the power-sum basis is considered
as a polynomial in
‘s (with
).
This is the same as skewing self by the first power-sum symmetric
function .
INPUT:
EXAMPLES:
sage: p = SymmetricFunctions(QQ).p()
sage: a = p([1,1,1])
sage: a.derivative_with_respect_to_p1()
3*p[1, 1]
sage: a.derivative_with_respect_to_p1(1)
3*p[1, 1]
sage: a.derivative_with_respect_to_p1(2)
6*p[1]
sage: a.derivative_with_respect_to_p1(3)
6*p[]
sage: s = SymmetricFunctions(QQ).s()
sage: s([3]).derivative_with_respect_to_p1()
s[2]
sage: s([2,1]).derivative_with_respect_to_p1()
s[1, 1] + s[2]
sage: s([1,1,1]).derivative_with_respect_to_p1()
s[1, 1]
sage: s(0).derivative_with_respect_to_p1()
0
sage: s(1).derivative_with_respect_to_p1()
0
sage: s([1]).derivative_with_respect_to_p1()
s[]
Let us check that taking the derivative with respect to p[1] is equivalent to skewing by p[1]:
sage: p1 = s([1])
sage: all( s(lam).derivative_with_respect_to_p1()
....: == s(lam).skew_by(p1) for lam in Partitions(4) )
True
Expand the symmetric function self as a symmetric polynomial in n variables.
INPUT:
OUTPUT:
A monomial expansion of self in the variables
labelled x0, x1, ..., x{n-1} (or just x
if
), where x is alphabet.
EXAMPLES:
sage: J = SymmetricFunctions(QQ).jack(t=2).J()
sage: J([2,1]).expand(3)
4*x0^2*x1 + 4*x0*x1^2 + 4*x0^2*x2 + 6*x0*x1*x2 + 4*x1^2*x2 + 4*x0*x2^2 + 4*x1*x2^2
sage: (2*J([2])).expand(0)
0
sage: (3*J([])).expand(0)
3
Return the image of the symmetric function self under the
-th Frobenius operator.
The -th Frobenius operator
is defined to be the
map from the ring of symmetric functions to itself that sends
every symmetric function
to
. This operator
is a Hopf algebra endomorphism, and satisfies
for every partition
(where
means the monomial basis). Moreover,
for every positive integer
(where
denotes the
-th powersum symmetric function).
The -th Frobenius operator is also called the
-th
Frobenius endomorphism. It is not related to the Frobenius map
which connects the ring of symmetric functions with the
representation theory of the symmetric group.
The -th Frobenius operator is also the
-th Adams operator
of the
-ring of symmetric functions over the integers.
The -th Frobenius operator can also be described via plethysm:
Every symmetric function
satisfies
,
where
is the
-th powersum symmetric function, and
denotes (outer) plethysm.
adams_operation() serves as alias for frobenius(), since the
Frobenius operators are the Adams operations of the -ring
of symmetric functions.
INPUT:
OUTPUT:
The result of applying the -th Frobenius operator (on the ring of
symmetric functions) to self.
EXAMPLES:
sage: Sym = SymmetricFunctions(ZZ)
sage: p = Sym.p()
sage: h = Sym.h()
sage: s = Sym.s()
sage: m = Sym.m()
sage: s[3].frobenius(2)
-s[3, 3] + s[4, 2] - s[5, 1] + s[6]
sage: m[4,2,1].frobenius(3)
m[12, 6, 3]
sage: p[4,2,1].frobenius(3)
p[12, 6, 3]
sage: h[4].frobenius(2)
h[4, 4] - 2*h[5, 3] + 2*h[6, 2] - 2*h[7, 1] + 2*h[8]
The Frobenius endomorphisms are multiplicative:
sage: all( all( s(lam).frobenius(3) * s(mu).frobenius(3) # long time
....: == (s(lam) * s(mu)).frobenius(3)
....: for mu in Partitions(3) )
....: for lam in Partitions(3) )
True
sage: all( all( m(lam).frobenius(2) * m(mu).frobenius(2)
....: == (m(lam) * m(mu)).frobenius(2)
....: for mu in Partitions(4) )
....: for lam in Partitions(4) )
True
sage: all( all( p(lam).frobenius(2) * p(mu).frobenius(2)
....: == (p(lam) * p(mu)).frobenius(2)
....: for mu in Partitions(3) )
....: for lam in Partitions(4) )
True
Being Hopf algebra endomorphisms, the Frobenius operators commute with the antipode:
sage: all( p(lam).frobenius(4).antipode()
....: == p(lam).antipode().frobenius(4)
....: for lam in Partitions(3) )
True
Testing the
equality (over
, since plethysm is currently not
defined over
in Sage):
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: p = Sym.p()
sage: all( s(lam).frobenius(3) == s(lam).plethysm(p[3])
....: == s(p[3].plethysm(s(lam)))
....: for lam in Partitions(4) )
True
By Exercise 7.61 in Stanley’s EC2 [STA] (see the errata on his
website), is a linear combination of
Schur polynomials (of straight shapes) using coefficients
,
and
only; moreover, all partitions whose Schur
polynomials occur with coefficient
in this
combination have empty
-cores. Let us check this on
examples:
sage: all( all( all( (coeff == -1 or coeff == 1)
....: and lam.core(n) == Partition([])
....: for lam, coeff in s([m]).frobenius(n) )
....: for n in range(2, 4) )
....: for m in range(4) )
True
See also
Todo
This method is fast on the monomial and the powersum bases, while all other bases get converted to the monomial basis. For most bases, this is probably the quickest way to do, but at least the Schur basis should have a better option. (Quoting from Stanley’s EC2 [STA]: “D. G. Duncan, J. London Math. Soc. 27 (1952), 235-236, or Y. M. Chen, A. M. Garsia, and J. B. Remmel, Contemp. Math. 34 (1984), 109-153”.)
This is the vertex operator that generalizes Jing’s operator.
It is a linear operator that raises the degree by
. This creation operator is a t-analogue of
multiplication by s(nu) .
See also
Proposition 5 in [SZ2001].
INPUT:
REFERENCES:
[SZ2001] | M. Shimozono, M. Zabrocki, Hall-Littlewood vertex operators and generalized Kostka polynomials. Adv. Math. 158 (2001), no. 1, 66-85. |
EXAMPLES:
sage: s = SymmetricFunctions(QQ['t']).s()
sage: s([2]).hl_creation_operator([3,2])
s[3, 2, 2] + t*s[3, 3, 1] + t*s[4, 2, 1] + t^2*s[4, 3] + t^2*s[5, 2]
sage: Sym = SymmetricFunctions(FractionField(QQ['t']))
sage: HLQp = Sym.hall_littlewood().Qp()
sage: s = Sym.s()
sage: HLQp(s([2]).hl_creation_operator([2]).hl_creation_operator([3]))
HLQp[3, 2, 2]
sage: s([2,2]).hl_creation_operator([2,1])
t*s[2, 2, 2, 1] + t^2*s[3, 2, 1, 1] + t^2*s[3, 2, 2] + t^3*s[3, 3, 1] + t^3*s[4, 2, 1] + t^4*s[4, 3]
sage: s(1).hl_creation_operator([2,1,1])
s[2, 1, 1]
sage: s(0).hl_creation_operator([2,1,1])
0
sage: s([3,2]).hl_creation_operator([2,1,1])
(t^2-t)*s[2, 2, 2, 2, 1] + t^3*s[3, 2, 2, 1, 1] + (t^3-t^2)*s[3, 2, 2, 2] + t^3*s[3, 3, 1, 1, 1] + t^4*s[3, 3, 2, 1] + t^3*s[4, 2, 1, 1, 1] + t^4*s[4, 2, 2, 1] + 2*t^4*s[4, 3, 1, 1] + t^5*s[4, 3, 2] + t^5*s[4, 4, 1] + t^4*s[5, 2, 1, 1] + t^5*s[5, 3, 1]
TESTS:
sage: s(0).hl_creation_operator([1])
0
Return the inner plethysm of self with x.
Whenever is a
-algebra, and
and
are two
symmetric functions over
such that the constant term of
is zero, the inner plethysm of
with
is a symmetric
function over
, and the degree of this symmetric function is
the same as the degree of
. We will denote the inner plethysm
of
with
by
(in contrast to the notation of
outer plethysm which is generally denoted
); in Sage
syntax, it is f.inner_plethysm(g).
First we describe the axiomatic definition of the operation; see
below for a representation-theoretic interpretation.
In the following equations, we denote the outer product
(i.e., the standard product on the ring of symmetric functions,
product())
by and the Kronecker product (itensor()) by
).
where is the
-th power-sum symmetric function for every
.
Let be a permutation of cycle type
and let
be the cycle type of
. Then,
Since is a basis for the symmetric
functions, these four formulas define the symmetric function
operation
for any symmetric functions
and
(where
has constant term
) by expanding
in the
power sum basis and
in the dual basis
.
See also
itensor(), partition_power(), plethysm()
This operation admits a representation-theoretic interpretation
in the case where is a Schur function
and
is a homogeneous degree
symmetric function with
nonnegative integral coefficients in the Schur basis.
The symmetric function
is the Frobenius
image of the
-representation constructed as follows.
The assumptions on imply that
is the Frobenius image of a
representation
of the symmetric group
:
If the degree of this representation is greater than or equal
to the number of parts of
, then
, which denotes
,
corresponds to the character of some irreducible
-representation, say
The composition is a representation
of
whose Frobenius image is precisely
.
If is less than the number of parts of
,
then
is
by definition.
When is a symmetric function with constant term
, the
inner plethysm
isn’t well-defined in the ring of
symmetric functions. Indeed, it is not clear how to define
. The most sensible way to get around this probably is
defining it as the infinite sum
(where
means the
-th complete homogeneous symmetric function)
in the completion of this ring with respect to its grading. This is
how [SchaThi1994] defines
. The present method,
however, sets it to be the sum of
over all
for which the
-th homogeneous component of
is nonzero. This is rather a
hack than a reasonable definition. Use with caution!
Note
If a symmetric function is written in the form
with each
homogeneous
of degree
, then
for every
with constant term
. But in general, inner
plethysm is not linear in the second variable.
REFERENCES:
[King] | King, R. Branching rules for ![]() |
[SchaThi1994] | Thomas Scharf, Jean-Yves Thibon. A Hopf-algebra approach to inner plethysm. Advances in Mathematics 104 (1994), pp. 30-58. ftp://ftp.mathe2.uni-bayreuth.de/axel/papers/scharf:a_hopf_algebra_approach_to_inner_plethysm.ps.gz |
INPUT:
OUTPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.schur()
sage: p = Sym.power()
sage: h = Sym.complete()
sage: s([2,1]).inner_plethysm(s([1,1,1]))
0
sage: s([2]).inner_plethysm(s([2,1]))
s[2, 1] + s[3]
sage: s([1,1]).inner_plethysm(s([2,1]))
s[1, 1, 1]
sage: s[2,1].inner_tensor(s[2,1])
s[1, 1, 1] + s[2, 1] + s[3]
sage: f = s([2,1]) + 2*s([3,1])
sage: f.itensor(f)
s[1, 1, 1] + s[2, 1] + 4*s[2, 1, 1] + 4*s[2, 2] + s[3] + 4*s[3, 1] + 4*s[4]
sage: s( h([1,1]).inner_plethysm(f) )
s[1, 1, 1] + s[2, 1] + 4*s[2, 1, 1] + 4*s[2, 2] + s[3] + 4*s[3, 1] + 4*s[4]
sage: s([]).inner_plethysm(s([1,1]) + 2*s([2,1])+s([3]))
s[2] + s[3]
sage: [s([]).inner_plethysm(s(la)) for la in Partitions(4)]
[s[4], s[4], s[4], s[4], s[4]]
sage: s([3]).inner_plethysm(s([]))
s[]
sage: s[1,1,1,1].inner_plethysm(s[2,1])
0
sage: s[1,1,1,1].inner_plethysm(2*s[2,1])
s[3]
sage: p[3].inner_plethysm(p[3])
0
sage: p[3,3].inner_plethysm(p[3])
0
sage: p[3].inner_plethysm(p[1,1,1])
p[1, 1, 1] + 2*p[3]
sage: p[4].inner_plethysm(p[1,1,1,1]/24)
1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/4*p[4]
sage: p[3,3].inner_plethysm(p[1,1,1])
6*p[1, 1, 1] + 12*p[3]
TESTS:
sage: s(0).inner_plethysm(s(0))
0
sage: s(1).inner_plethysm(s(0))
0
sage: s(0).inner_plethysm(s(1))
0
sage: s(1).inner_plethysm(s(1))
s[]
sage: s(2).inner_plethysm(s(1))
2*s[]
sage: s(1).inner_plethysm(s(2))
s[]
Return the internal (tensor) product of self and x in the basis of self.
The internal tensor product can be defined as the linear extension
of the definition on power sums
, where
for
and where
denotes the internal tensor product.
The internal tensor product is also known as the Kronecker product,
or as the second multiplication on the ring of symmetric functions.
Note that the internal product of any two homogeneous symmetric
functions of equal degrees is a homogeneous symmetric function of the
same degree. On the other hand, the internal product of two homogeneous
symmetric functions of distinct degrees is .
Note
The internal product is sometimes referred to as “inner product” in the literature, but unfortunately this name is shared by a different operation, namely the Hall inner product (see scalar()).
INPUT:
OUTPUT:
The methods itensor(), internal_product(), kronecker_product(), inner_tensor() are all synonyms.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: b = s([3])
sage: a.itensor(b)
s[2, 1]
sage: c = s([3,2,1])
sage: c.itensor(c)
s[1, 1, 1, 1, 1, 1] + 2*s[2, 1, 1, 1, 1] + 3*s[2, 2, 1, 1] + 2*s[2, 2, 2]
+ 4*s[3, 1, 1, 1] + 5*s[3, 2, 1] + 2*s[3, 3] + 4*s[4, 1, 1]
+ 3*s[4, 2] + 2*s[5, 1] + s[6]
There are few quantitative results pertaining to Kronecker products in general, which makes their computation so difficult. Let us test a few of them in different bases.
The Kronecker product of any homogeneous symmetric function of
degree
with the
-th complete homogeneous symmetric function
h[n] (a.k.a. s[n]) is
:
sage: h = SymmetricFunctions(ZZ).h()
sage: all( h([5]).itensor(h(p)) == h(p) for p in Partitions(5) )
True
The Kronecker product of a Schur function with the
-th
elementary symmetric function e[n], where
, is
(where
is the conjugate
partition of
):
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: all( e([5]).itensor(s(p)) == s(p.conjugate()) for p in Partitions(5) )
True
The Kronecker product is commutative:
sage: e = SymmetricFunctions(FiniteField(19)).e()
sage: m = SymmetricFunctions(FiniteField(19)).m()
sage: all( all( e(p).itensor(m(q)) == m(q).itensor(e(p)) for q in Partitions(4) )
....: for p in Partitions(4) )
True
sage: F = FractionField(QQ['q','t'])
sage: mq = SymmetricFunctions(F).macdonald().Q()
sage: mh = SymmetricFunctions(F).macdonald().H()
sage: all( all( mq(p).itensor(mh(r)) == mh(r).itensor(mq(p)) # long time
....: for r in Partitions(4) )
....: for p in Partitions(3) )
True
Let us check (on examples) Proposition 5.2 of Gelfand, Krob, Lascoux, Leclerc,
Retakh, Thibon, “Noncommutative symmetric functions”, Arxiv hep-th/9407124, for
:
sage: e = SymmetricFunctions(FiniteField(29)).e()
sage: s = SymmetricFunctions(FiniteField(29)).s()
sage: m = SymmetricFunctions(FiniteField(29)).m()
sage: def tensor_copr(u, v, w): # computes \mu ((u \otimes v) * \Delta(w)) with
....: # * meaning Kronecker product and \mu meaning the
....: # usual multiplication.
....: result = w.parent().zero()
....: for partition_pair, coeff in w.coproduct():
....: result += coeff * w.parent()(u).itensor(partition_pair[0]) * w.parent()(v).itensor(partition_pair[1])
....: return result
sage: all( all( all( tensor_copr(e[u], s[v], m[w]) # long time
....: == (e[u] * s[v]).itensor(m[w])
....: for w in Partitions(5) )
....: for v in Partitions(2) )
....: for u in Partitions(3) )
True
Some examples from Briand, Orellana, Rosas, “The stability of the Kronecker products of Schur functions.” Arxiv 0907.4652:
sage: s = SymmetricFunctions(ZZ).s()
sage: s[2,2].itensor(s[2,2])
s[1, 1, 1, 1] + s[2, 2] + s[4]
sage: s[3,2].itensor(s[3,2])
s[2, 1, 1, 1] + s[2, 2, 1] + s[3, 1, 1] + s[3, 2] + s[4, 1] + s[5]
sage: s[4,2].itensor(s[4,2])
s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + s[4, 1, 1] + 2*s[4, 2] + s[5, 1] + s[6]
An example from p. 220 of Thibon, “Hopf algebras of symmetric functions and tensor products of symmetric group representations”, International Journal of Algebra and Computation, 1991:
sage: s = SymmetricFunctions(QQbar).s()
sage: s[2,1].itensor(s[2,1])
s[1, 1, 1] + s[2, 1] + s[3]
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Same over the ring of integers:
sage: s = SymmetricFunctions(ZZ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Theorem 2.1 in Bessenrodt, van Willigenburg, Arxiv 1105.3170v2:
sage: s = SymmetricFunctions(ZZ).s()
sage: all( all( max( r[0] for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
sage: all( all( max( len(r) for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.conjugate().get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
Check that the basis and ground ring of self are preserved:
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: e[3].itensor(s[3])
e[3]
sage: s[3].itensor(e[3])
s[1, 1, 1]
sage: parent(e[3].itensor(s[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the elementary basis
sage: parent(s[3].itensor(e[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the Schur basis
Note
The currently existing implementation of this function is
technically unsatisfactory. It distinguishes the case when the
base ring is a -algebra (in which case the Kronecker product
can be easily computed using the power sum basis) from the case
where it isn’t. In the latter, it does a computation using
universal coefficients, again distinguishing the case when it is
able to compute the “corresponding” basis of the symmetric function
algebra over
(using the corresponding_basis_over hack)
from the case when it isn’t (in which case it transforms everything
into the Schur basis, which is slow).
Return the inner coproduct of self in the basis of self.
The inner coproduct (also known as the Kronecker coproduct, as the
internal coproduct, or as the second comultiplication on the ring of
symmetric functions) is a ring homomorphism from the
ring of symmetric functions to the tensor product (over the base
ring) of this ring with itself. It is uniquely characterized by the
formula
where means
is a partition of
, and
is any nonnegative integer. It also satisfies
for any positive integer . If the base ring is a
-algebra, it
also satisfies
where
with meaning the number of appearances of
in
(see zee()).
The method kronecker_coproduct() is a synonym of internal_coproduct().
EXAMPLES:
sage: s = SymmetricFunctions(ZZ).s()
sage: a = s([2,1])
sage: a.internal_coproduct()
s[1, 1, 1] # s[2, 1] + s[2, 1] # s[1, 1, 1] + s[2, 1] # s[2, 1] + s[2, 1] # s[3] + s[3] # s[2, 1]
sage: e = SymmetricFunctions(QQ).e()
sage: b = e([2])
sage: b.internal_coproduct()
e[1, 1] # e[2] + e[2] # e[1, 1] - 2*e[2] # e[2]
The internal coproduct is adjoint to the internal product with respect
to the Hall inner product: Any three symmetric functions ,
and
satisfy
, where we write
as
. Let us check this in degree
:
sage: e = SymmetricFunctions(FiniteField(29)).e()
sage: s = SymmetricFunctions(FiniteField(29)).s()
sage: m = SymmetricFunctions(FiniteField(29)).m()
sage: def tensor_incopr(f, g, h): # computes \sum_i \left< f, h'_i \right> \left< g, h''_i \right>
....: result = h.base_ring().zero()
....: for partition_pair, coeff in h.internal_coproduct():
....: result += coeff * h.parent()(f).scalar(partition_pair[0]) * h.parent()(g).scalar(partition_pair[1])
....: return result
sage: all( all( all( tensor_incopr(e[u], s[v], m[w]) == (e[u].itensor(s[v])).scalar(m[w]) # long time (10s on sage.math, 2013)
....: for w in Partitions(5) )
....: for v in Partitions(2) )
....: for u in Partitions(3) )
True
Let us check the formulas for and
given in the description of this method:
sage: e = SymmetricFunctions(QQ).e()
sage: p = SymmetricFunctions(QQ).p()
sage: h = SymmetricFunctions(QQ).h()
sage: s = SymmetricFunctions(QQ).s()
sage: all( s(h([n])).internal_coproduct() == sum([tensor([s(lam), s(lam)]) for lam in Partitions(n)])
....: for n in range(6) )
True
sage: all( h([n]).internal_coproduct() == sum([tensor([h(lam), h(m(lam))]) for lam in Partitions(n)])
....: for n in range(6) )
True
sage: all( factorial(n) * h([n]).internal_coproduct()
....: == sum([lam.conjugacy_class_size() * tensor([h(p(lam)), h(p(lam))])
....: for lam in Partitions(n)])
....: for n in range(6) )
True
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: s([]).internal_coproduct()
s[] # s[]
Return the internal (tensor) product of self and x in the basis of self.
The internal tensor product can be defined as the linear extension
of the definition on power sums
, where
for
and where
denotes the internal tensor product.
The internal tensor product is also known as the Kronecker product,
or as the second multiplication on the ring of symmetric functions.
Note that the internal product of any two homogeneous symmetric
functions of equal degrees is a homogeneous symmetric function of the
same degree. On the other hand, the internal product of two homogeneous
symmetric functions of distinct degrees is .
Note
The internal product is sometimes referred to as “inner product” in the literature, but unfortunately this name is shared by a different operation, namely the Hall inner product (see scalar()).
INPUT:
OUTPUT:
The methods itensor(), internal_product(), kronecker_product(), inner_tensor() are all synonyms.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: b = s([3])
sage: a.itensor(b)
s[2, 1]
sage: c = s([3,2,1])
sage: c.itensor(c)
s[1, 1, 1, 1, 1, 1] + 2*s[2, 1, 1, 1, 1] + 3*s[2, 2, 1, 1] + 2*s[2, 2, 2]
+ 4*s[3, 1, 1, 1] + 5*s[3, 2, 1] + 2*s[3, 3] + 4*s[4, 1, 1]
+ 3*s[4, 2] + 2*s[5, 1] + s[6]
There are few quantitative results pertaining to Kronecker products in general, which makes their computation so difficult. Let us test a few of them in different bases.
The Kronecker product of any homogeneous symmetric function of
degree
with the
-th complete homogeneous symmetric function
h[n] (a.k.a. s[n]) is
:
sage: h = SymmetricFunctions(ZZ).h()
sage: all( h([5]).itensor(h(p)) == h(p) for p in Partitions(5) )
True
The Kronecker product of a Schur function with the
-th
elementary symmetric function e[n], where
, is
(where
is the conjugate
partition of
):
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: all( e([5]).itensor(s(p)) == s(p.conjugate()) for p in Partitions(5) )
True
The Kronecker product is commutative:
sage: e = SymmetricFunctions(FiniteField(19)).e()
sage: m = SymmetricFunctions(FiniteField(19)).m()
sage: all( all( e(p).itensor(m(q)) == m(q).itensor(e(p)) for q in Partitions(4) )
....: for p in Partitions(4) )
True
sage: F = FractionField(QQ['q','t'])
sage: mq = SymmetricFunctions(F).macdonald().Q()
sage: mh = SymmetricFunctions(F).macdonald().H()
sage: all( all( mq(p).itensor(mh(r)) == mh(r).itensor(mq(p)) # long time
....: for r in Partitions(4) )
....: for p in Partitions(3) )
True
Let us check (on examples) Proposition 5.2 of Gelfand, Krob, Lascoux, Leclerc,
Retakh, Thibon, “Noncommutative symmetric functions”, Arxiv hep-th/9407124, for
:
sage: e = SymmetricFunctions(FiniteField(29)).e()
sage: s = SymmetricFunctions(FiniteField(29)).s()
sage: m = SymmetricFunctions(FiniteField(29)).m()
sage: def tensor_copr(u, v, w): # computes \mu ((u \otimes v) * \Delta(w)) with
....: # * meaning Kronecker product and \mu meaning the
....: # usual multiplication.
....: result = w.parent().zero()
....: for partition_pair, coeff in w.coproduct():
....: result += coeff * w.parent()(u).itensor(partition_pair[0]) * w.parent()(v).itensor(partition_pair[1])
....: return result
sage: all( all( all( tensor_copr(e[u], s[v], m[w]) # long time
....: == (e[u] * s[v]).itensor(m[w])
....: for w in Partitions(5) )
....: for v in Partitions(2) )
....: for u in Partitions(3) )
True
Some examples from Briand, Orellana, Rosas, “The stability of the Kronecker products of Schur functions.” Arxiv 0907.4652:
sage: s = SymmetricFunctions(ZZ).s()
sage: s[2,2].itensor(s[2,2])
s[1, 1, 1, 1] + s[2, 2] + s[4]
sage: s[3,2].itensor(s[3,2])
s[2, 1, 1, 1] + s[2, 2, 1] + s[3, 1, 1] + s[3, 2] + s[4, 1] + s[5]
sage: s[4,2].itensor(s[4,2])
s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + s[4, 1, 1] + 2*s[4, 2] + s[5, 1] + s[6]
An example from p. 220 of Thibon, “Hopf algebras of symmetric functions and tensor products of symmetric group representations”, International Journal of Algebra and Computation, 1991:
sage: s = SymmetricFunctions(QQbar).s()
sage: s[2,1].itensor(s[2,1])
s[1, 1, 1] + s[2, 1] + s[3]
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Same over the ring of integers:
sage: s = SymmetricFunctions(ZZ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Theorem 2.1 in Bessenrodt, van Willigenburg, Arxiv 1105.3170v2:
sage: s = SymmetricFunctions(ZZ).s()
sage: all( all( max( r[0] for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
sage: all( all( max( len(r) for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.conjugate().get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
Check that the basis and ground ring of self are preserved:
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: e[3].itensor(s[3])
e[3]
sage: s[3].itensor(e[3])
s[1, 1, 1]
sage: parent(e[3].itensor(s[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the elementary basis
sage: parent(s[3].itensor(e[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the Schur basis
Note
The currently existing implementation of this function is
technically unsatisfactory. It distinguishes the case when the
base ring is a -algebra (in which case the Kronecker product
can be easily computed using the power sum basis) from the case
where it isn’t. In the latter, it does a computation using
universal coefficients, again distinguishing the case when it is
able to compute the “corresponding” basis of the symmetric function
algebra over
(using the corresponding_basis_over hack)
from the case when it isn’t (in which case it transforms everything
into the Schur basis, which is slow).
Return True if and only if self is Schur positive.
If is the space of Schur functions over self‘s base ring, then
this is the same as self._is_positive(s).
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1]) + s([3])
sage: a.is_schur_positive()
True
sage: a = s([2,1]) - s([3])
sage: a.is_schur_positive()
False
sage: QQx = QQ['x']
sage: s = SymmetricFunctions(QQx).s()
sage: x = QQx.gen()
sage: a = (1+x)*s([2,1])
sage: a.is_schur_positive()
True
sage: a = (1-x)*s([2,1])
sage: a.is_schur_positive()
False
sage: s(0).is_schur_positive()
True
sage: s(1+x).is_schur_positive()
True
Return the internal (tensor) product of self and x in the basis of self.
The internal tensor product can be defined as the linear extension
of the definition on power sums
, where
for
and where
denotes the internal tensor product.
The internal tensor product is also known as the Kronecker product,
or as the second multiplication on the ring of symmetric functions.
Note that the internal product of any two homogeneous symmetric
functions of equal degrees is a homogeneous symmetric function of the
same degree. On the other hand, the internal product of two homogeneous
symmetric functions of distinct degrees is .
Note
The internal product is sometimes referred to as “inner product” in the literature, but unfortunately this name is shared by a different operation, namely the Hall inner product (see scalar()).
INPUT:
OUTPUT:
The methods itensor(), internal_product(), kronecker_product(), inner_tensor() are all synonyms.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: b = s([3])
sage: a.itensor(b)
s[2, 1]
sage: c = s([3,2,1])
sage: c.itensor(c)
s[1, 1, 1, 1, 1, 1] + 2*s[2, 1, 1, 1, 1] + 3*s[2, 2, 1, 1] + 2*s[2, 2, 2]
+ 4*s[3, 1, 1, 1] + 5*s[3, 2, 1] + 2*s[3, 3] + 4*s[4, 1, 1]
+ 3*s[4, 2] + 2*s[5, 1] + s[6]
There are few quantitative results pertaining to Kronecker products in general, which makes their computation so difficult. Let us test a few of them in different bases.
The Kronecker product of any homogeneous symmetric function of
degree
with the
-th complete homogeneous symmetric function
h[n] (a.k.a. s[n]) is
:
sage: h = SymmetricFunctions(ZZ).h()
sage: all( h([5]).itensor(h(p)) == h(p) for p in Partitions(5) )
True
The Kronecker product of a Schur function with the
-th
elementary symmetric function e[n], where
, is
(where
is the conjugate
partition of
):
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: all( e([5]).itensor(s(p)) == s(p.conjugate()) for p in Partitions(5) )
True
The Kronecker product is commutative:
sage: e = SymmetricFunctions(FiniteField(19)).e()
sage: m = SymmetricFunctions(FiniteField(19)).m()
sage: all( all( e(p).itensor(m(q)) == m(q).itensor(e(p)) for q in Partitions(4) )
....: for p in Partitions(4) )
True
sage: F = FractionField(QQ['q','t'])
sage: mq = SymmetricFunctions(F).macdonald().Q()
sage: mh = SymmetricFunctions(F).macdonald().H()
sage: all( all( mq(p).itensor(mh(r)) == mh(r).itensor(mq(p)) # long time
....: for r in Partitions(4) )
....: for p in Partitions(3) )
True
Let us check (on examples) Proposition 5.2 of Gelfand, Krob, Lascoux, Leclerc,
Retakh, Thibon, “Noncommutative symmetric functions”, Arxiv hep-th/9407124, for
:
sage: e = SymmetricFunctions(FiniteField(29)).e()
sage: s = SymmetricFunctions(FiniteField(29)).s()
sage: m = SymmetricFunctions(FiniteField(29)).m()
sage: def tensor_copr(u, v, w): # computes \mu ((u \otimes v) * \Delta(w)) with
....: # * meaning Kronecker product and \mu meaning the
....: # usual multiplication.
....: result = w.parent().zero()
....: for partition_pair, coeff in w.coproduct():
....: result += coeff * w.parent()(u).itensor(partition_pair[0]) * w.parent()(v).itensor(partition_pair[1])
....: return result
sage: all( all( all( tensor_copr(e[u], s[v], m[w]) # long time
....: == (e[u] * s[v]).itensor(m[w])
....: for w in Partitions(5) )
....: for v in Partitions(2) )
....: for u in Partitions(3) )
True
Some examples from Briand, Orellana, Rosas, “The stability of the Kronecker products of Schur functions.” Arxiv 0907.4652:
sage: s = SymmetricFunctions(ZZ).s()
sage: s[2,2].itensor(s[2,2])
s[1, 1, 1, 1] + s[2, 2] + s[4]
sage: s[3,2].itensor(s[3,2])
s[2, 1, 1, 1] + s[2, 2, 1] + s[3, 1, 1] + s[3, 2] + s[4, 1] + s[5]
sage: s[4,2].itensor(s[4,2])
s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + s[4, 1, 1] + 2*s[4, 2] + s[5, 1] + s[6]
An example from p. 220 of Thibon, “Hopf algebras of symmetric functions and tensor products of symmetric group representations”, International Journal of Algebra and Computation, 1991:
sage: s = SymmetricFunctions(QQbar).s()
sage: s[2,1].itensor(s[2,1])
s[1, 1, 1] + s[2, 1] + s[3]
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Same over the ring of integers:
sage: s = SymmetricFunctions(ZZ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Theorem 2.1 in Bessenrodt, van Willigenburg, Arxiv 1105.3170v2:
sage: s = SymmetricFunctions(ZZ).s()
sage: all( all( max( r[0] for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
sage: all( all( max( len(r) for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.conjugate().get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
Check that the basis and ground ring of self are preserved:
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: e[3].itensor(s[3])
e[3]
sage: s[3].itensor(e[3])
s[1, 1, 1]
sage: parent(e[3].itensor(s[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the elementary basis
sage: parent(s[3].itensor(e[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the Schur basis
Note
The currently existing implementation of this function is
technically unsatisfactory. It distinguishes the case when the
base ring is a -algebra (in which case the Kronecker product
can be easily computed using the power sum basis) from the case
where it isn’t. In the latter, it does a computation using
universal coefficients, again distinguishing the case when it is
able to compute the “corresponding” basis of the symmetric function
algebra over
(using the corresponding_basis_over hack)
from the case when it isn’t (in which case it transforms everything
into the Schur basis, which is slow).
Return the inner coproduct of self in the basis of self.
The inner coproduct (also known as the Kronecker coproduct, as the
internal coproduct, or as the second comultiplication on the ring of
symmetric functions) is a ring homomorphism from the
ring of symmetric functions to the tensor product (over the base
ring) of this ring with itself. It is uniquely characterized by the
formula
where means
is a partition of
, and
is any nonnegative integer. It also satisfies
for any positive integer . If the base ring is a
-algebra, it
also satisfies
where
with meaning the number of appearances of
in
(see zee()).
The method kronecker_coproduct() is a synonym of internal_coproduct().
EXAMPLES:
sage: s = SymmetricFunctions(ZZ).s()
sage: a = s([2,1])
sage: a.internal_coproduct()
s[1, 1, 1] # s[2, 1] + s[2, 1] # s[1, 1, 1] + s[2, 1] # s[2, 1] + s[2, 1] # s[3] + s[3] # s[2, 1]
sage: e = SymmetricFunctions(QQ).e()
sage: b = e([2])
sage: b.internal_coproduct()
e[1, 1] # e[2] + e[2] # e[1, 1] - 2*e[2] # e[2]
The internal coproduct is adjoint to the internal product with respect
to the Hall inner product: Any three symmetric functions ,
and
satisfy
, where we write
as
. Let us check this in degree
:
sage: e = SymmetricFunctions(FiniteField(29)).e()
sage: s = SymmetricFunctions(FiniteField(29)).s()
sage: m = SymmetricFunctions(FiniteField(29)).m()
sage: def tensor_incopr(f, g, h): # computes \sum_i \left< f, h'_i \right> \left< g, h''_i \right>
....: result = h.base_ring().zero()
....: for partition_pair, coeff in h.internal_coproduct():
....: result += coeff * h.parent()(f).scalar(partition_pair[0]) * h.parent()(g).scalar(partition_pair[1])
....: return result
sage: all( all( all( tensor_incopr(e[u], s[v], m[w]) == (e[u].itensor(s[v])).scalar(m[w]) # long time (10s on sage.math, 2013)
....: for w in Partitions(5) )
....: for v in Partitions(2) )
....: for u in Partitions(3) )
True
Let us check the formulas for and
given in the description of this method:
sage: e = SymmetricFunctions(QQ).e()
sage: p = SymmetricFunctions(QQ).p()
sage: h = SymmetricFunctions(QQ).h()
sage: s = SymmetricFunctions(QQ).s()
sage: all( s(h([n])).internal_coproduct() == sum([tensor([s(lam), s(lam)]) for lam in Partitions(n)])
....: for n in range(6) )
True
sage: all( h([n]).internal_coproduct() == sum([tensor([h(lam), h(m(lam))]) for lam in Partitions(n)])
....: for n in range(6) )
True
sage: all( factorial(n) * h([n]).internal_coproduct()
....: == sum([lam.conjugacy_class_size() * tensor([h(p(lam)), h(p(lam))])
....: for lam in Partitions(n)])
....: for n in range(6) )
True
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: s([]).internal_coproduct()
s[] # s[]
Return the internal (tensor) product of self and x in the basis of self.
The internal tensor product can be defined as the linear extension
of the definition on power sums
, where
for
and where
denotes the internal tensor product.
The internal tensor product is also known as the Kronecker product,
or as the second multiplication on the ring of symmetric functions.
Note that the internal product of any two homogeneous symmetric
functions of equal degrees is a homogeneous symmetric function of the
same degree. On the other hand, the internal product of two homogeneous
symmetric functions of distinct degrees is .
Note
The internal product is sometimes referred to as “inner product” in the literature, but unfortunately this name is shared by a different operation, namely the Hall inner product (see scalar()).
INPUT:
OUTPUT:
The methods itensor(), internal_product(), kronecker_product(), inner_tensor() are all synonyms.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: b = s([3])
sage: a.itensor(b)
s[2, 1]
sage: c = s([3,2,1])
sage: c.itensor(c)
s[1, 1, 1, 1, 1, 1] + 2*s[2, 1, 1, 1, 1] + 3*s[2, 2, 1, 1] + 2*s[2, 2, 2]
+ 4*s[3, 1, 1, 1] + 5*s[3, 2, 1] + 2*s[3, 3] + 4*s[4, 1, 1]
+ 3*s[4, 2] + 2*s[5, 1] + s[6]
There are few quantitative results pertaining to Kronecker products in general, which makes their computation so difficult. Let us test a few of them in different bases.
The Kronecker product of any homogeneous symmetric function of
degree
with the
-th complete homogeneous symmetric function
h[n] (a.k.a. s[n]) is
:
sage: h = SymmetricFunctions(ZZ).h()
sage: all( h([5]).itensor(h(p)) == h(p) for p in Partitions(5) )
True
The Kronecker product of a Schur function with the
-th
elementary symmetric function e[n], where
, is
(where
is the conjugate
partition of
):
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: all( e([5]).itensor(s(p)) == s(p.conjugate()) for p in Partitions(5) )
True
The Kronecker product is commutative:
sage: e = SymmetricFunctions(FiniteField(19)).e()
sage: m = SymmetricFunctions(FiniteField(19)).m()
sage: all( all( e(p).itensor(m(q)) == m(q).itensor(e(p)) for q in Partitions(4) )
....: for p in Partitions(4) )
True
sage: F = FractionField(QQ['q','t'])
sage: mq = SymmetricFunctions(F).macdonald().Q()
sage: mh = SymmetricFunctions(F).macdonald().H()
sage: all( all( mq(p).itensor(mh(r)) == mh(r).itensor(mq(p)) # long time
....: for r in Partitions(4) )
....: for p in Partitions(3) )
True
Let us check (on examples) Proposition 5.2 of Gelfand, Krob, Lascoux, Leclerc,
Retakh, Thibon, “Noncommutative symmetric functions”, Arxiv hep-th/9407124, for
:
sage: e = SymmetricFunctions(FiniteField(29)).e()
sage: s = SymmetricFunctions(FiniteField(29)).s()
sage: m = SymmetricFunctions(FiniteField(29)).m()
sage: def tensor_copr(u, v, w): # computes \mu ((u \otimes v) * \Delta(w)) with
....: # * meaning Kronecker product and \mu meaning the
....: # usual multiplication.
....: result = w.parent().zero()
....: for partition_pair, coeff in w.coproduct():
....: result += coeff * w.parent()(u).itensor(partition_pair[0]) * w.parent()(v).itensor(partition_pair[1])
....: return result
sage: all( all( all( tensor_copr(e[u], s[v], m[w]) # long time
....: == (e[u] * s[v]).itensor(m[w])
....: for w in Partitions(5) )
....: for v in Partitions(2) )
....: for u in Partitions(3) )
True
Some examples from Briand, Orellana, Rosas, “The stability of the Kronecker products of Schur functions.” Arxiv 0907.4652:
sage: s = SymmetricFunctions(ZZ).s()
sage: s[2,2].itensor(s[2,2])
s[1, 1, 1, 1] + s[2, 2] + s[4]
sage: s[3,2].itensor(s[3,2])
s[2, 1, 1, 1] + s[2, 2, 1] + s[3, 1, 1] + s[3, 2] + s[4, 1] + s[5]
sage: s[4,2].itensor(s[4,2])
s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + s[4, 1, 1] + 2*s[4, 2] + s[5, 1] + s[6]
An example from p. 220 of Thibon, “Hopf algebras of symmetric functions and tensor products of symmetric group representations”, International Journal of Algebra and Computation, 1991:
sage: s = SymmetricFunctions(QQbar).s()
sage: s[2,1].itensor(s[2,1])
s[1, 1, 1] + s[2, 1] + s[3]
TESTS:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Same over the ring of integers:
sage: s = SymmetricFunctions(ZZ).s()
sage: a = s([8,8])
sage: a.itensor(a) # long time
s[4, 4, 4, 4] + s[5, 5, 3, 3] + s[5, 5, 5, 1] + s[6, 4, 4, 2]
+ s[6, 6, 2, 2] + s[6, 6, 4] + s[7, 3, 3, 3] + s[7, 5, 3, 1]
+ s[7, 7, 1, 1] + s[8, 4, 2, 2] + s[8, 4, 4] + s[8, 6, 2]
+ s[8, 8] + s[9, 3, 3, 1] + s[9, 5, 1, 1] + s[10, 2, 2, 2]
+ s[10, 4, 2] + s[10, 6] + s[11, 3, 1, 1] + s[12, 2, 2]
+ s[12, 4] + s[13, 1, 1, 1] + s[14, 2] + s[16]
sage: s[8].itensor(s[7])
0
sage: s(0).itensor(s(0))
0
sage: s(1).itensor(s(0))
0
sage: s(0).itensor(s(1))
0
sage: s(1).itensor(s(1))
s[]
Theorem 2.1 in Bessenrodt, van Willigenburg, Arxiv 1105.3170v2:
sage: s = SymmetricFunctions(ZZ).s()
sage: all( all( max( r[0] for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
sage: all( all( max( len(r) for r in s(p).itensor(s(q)).monomial_coefficients().keys() )
....: == sum( min(p[i], q.conjugate().get_part(i)) for i in range(len(p)) )
....: for p in Partitions(4) )
....: for q in Partitions(4) )
True
Check that the basis and ground ring of self are preserved:
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: e[3].itensor(s[3])
e[3]
sage: s[3].itensor(e[3])
s[1, 1, 1]
sage: parent(e[3].itensor(s[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the elementary basis
sage: parent(s[3].itensor(e[3]))
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the Schur basis
Note
The currently existing implementation of this function is
technically unsatisfactory. It distinguishes the case when the
base ring is a -algebra (in which case the Kronecker product
can be easily computed using the power sum basis) from the case
where it isn’t. In the latter, it does a computation using
universal coefficients, again distinguishing the case when it is
able to compute the “corresponding” basis of the symmetric function
algebra over
(using the corresponding_basis_over hack)
from the case when it isn’t (in which case it transforms everything
into the Schur basis, which is slow).
Return the left-padded Kronecker product of self and x in the basis of self.
The left-padded Kronecker product is a bilinear map mapping two
symmetric functions to another, not necessarily preserving degree.
It can be defined as follows: Let denote the Kronecker product
(itensor()) on the space of symmetric functions. For any
partitions
,
,
, let
denote the coefficient of the
complete homogeneous symmetric function
in the
Kronecker product
.
For every partition
and every integer
, let
denote the
-completion of
(this is the
partition
;
see t_completion()).
Then, for any partitions
and
and every integer
,
we can write the Kronecker product
in the form
with ranging over all partitions. The
coefficients
are independent on
. These coefficients
are denoted by
, and the symmetric
function
is said to be the left-padded Kronecker product of
and
. By bilinearity, this extends to a definition of a
left-padded Kronecker product of any two symmetric functions.
This notion of left-padded Kronecker product can be lifted to the non-commutative symmetric functions (left_padded_kronecker_product()).
Warning
Don’t mistake this product for the reduced Kronecker product (reduced_kronecker_product()), which uses the Schur functions instead of the complete homogeneous functions in its definition.
INPUT:
OUTPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: h = Sym.h()
sage: h[2,1].left_padded_kronecker_product(h[3])
h[1, 1, 1, 1] + h[2, 1] + h[2, 1, 1] + h[2, 1, 1, 1] + h[2, 2, 1] + h[3, 2, 1]
sage: h[2,1].left_padded_kronecker_product(h[1])
h[1, 1, 1] + h[2, 1] + h[2, 1, 1]
sage: h[1].left_padded_kronecker_product(h[2,1])
h[1, 1, 1] + h[2, 1] + h[2, 1, 1]
sage: h[1,1].left_padded_kronecker_product(h[2])
h[1, 1] + 2*h[1, 1, 1] + h[2, 1, 1]
sage: h[1].left_padded_kronecker_product(h[2,1,1])
h[1, 1, 1, 1] + 2*h[2, 1, 1] + h[2, 1, 1, 1]
sage: h[2].left_padded_kronecker_product(h[3])
h[2, 1] + h[2, 1, 1] + h[3, 2]
Taking the left-padded Kronecker product with is
the identity map on the ring of symmetric functions:
sage: all( h[Partition([])].left_padded_kronecker_product(h[lam])
....: == h[lam] for i in range(4)
....: for lam in Partitions(i) )
True
Here is a rule for the left-padded Kronecker product of
(this is the same as
) with any complete homogeneous
function: Let
be a partition. Then, the left-padded
Kronecker product of
and
is
, where the sum runs over all
partitions
, and the coefficient
is defined as the
number of ways to obtain
from
by one of the
following two operations:
We check this for partitions of size :
sage: def mults1(I):
....: # Left-padded Kronecker multiplication by h[1].
....: res = h[I[:] + [1]]
....: for k in range(len(I)):
....: I2 = I[:]
....: if I2[k] == 1:
....: I2 = I2[:k] + I2[k+1:]
....: else:
....: I2[k] -= 1
....: res += h[sorted(I2 + [1], reverse=True)]
....: return res
sage: all( mults1(I) == h[1].left_padded_kronecker_product(h[I])
....: == h[I].left_padded_kronecker_product(h[1])
....: for i in range(5) for I in Partitions(i) )
True
The left-padded Kronecker product is commutative:
sage: all( h[lam].left_padded_kronecker_product(h[mu])
....: == h[mu].left_padded_kronecker_product(h[lam])
....: for lam in Partitions(3) for mu in Partitions(3) )
True
TESTS:
sage: h = SymmetricFunctions(QQ).h()
sage: (2*h([])).left_padded_kronecker_product(3*h([]))
6*h[]
Different bases and base rings:
sage: h = SymmetricFunctions(ZZ).h()
sage: e = SymmetricFunctions(ZZ).e()
sage: h(e[2].left_padded_kronecker_product(h[2]))
h[1, 1] + h[1, 1, 1] - h[2] + h[2, 1, 1] - h[2, 2]
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: v = e[2].left_padded_kronecker_product(e[2]); v
e[1, 1] + e[1, 1, 1] + (-1)*e[2] + e[2, 2]
sage: parent(v)
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the elementary basis
sage: s = SymmetricFunctions(ZZ).s()
sage: v = s[1].left_padded_kronecker_product(s[1]); parent(v)
Symmetric Functions over Integer Ring in the Schur basis
Return the value of the nabla operator applied to self.
The eigenvectors of the nabla operator are the Macdonald polynomials in the Ht basis.
If the parameter power is an integer then it calculates nabla to that integer. The default value of power is 1.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(FractionField(QQ['q','t']))
sage: p = Sym.power()
sage: p([1,1]).nabla()
(-1/2*q*t+1/2*q+1/2*t+1/2)*p[1, 1] + (1/2*q*t-1/2*q-1/2*t+1/2)*p[2]
sage: p([2,1]).nabla(q=1)
(-t-1)*p[1, 1, 1] + t*p[2, 1]
sage: p([2]).nabla(q=1)*p([1]).nabla(q=1)
(-t-1)*p[1, 1, 1] + t*p[2, 1]
sage: s = Sym.schur()
sage: s([2,1]).nabla()
(-q^3*t-q^2*t^2-q*t^3)*s[1, 1, 1] + (-q^2*t-q*t^2)*s[2, 1]
sage: s([1,1,1]).nabla()
(q^3+q^2*t+q*t^2+t^3+q*t)*s[1, 1, 1] + (q^2+q*t+t^2+q+t)*s[2, 1] + s[3]
sage: s([1,1,1]).nabla(t=1)
(q^3+q^2+2*q+1)*s[1, 1, 1] + (q^2+2*q+2)*s[2, 1] + s[3]
sage: s(0).nabla()
0
sage: s(1).nabla()
s[]
sage: s([2,1]).nabla(power=-1)
((-q-t)/(q^2*t^2))*s[2, 1] + ((-q^2-q*t-t^2)/(q^3*t^3))*s[3]
sage: (s([2])+s([3])).nabla()
(-q*t)*s[1, 1] + (q^3*t^2+q^2*t^3)*s[1, 1, 1] + q^2*t^2*s[2, 1]
Return the image of self under the omega automorphism.
The omega automorphism is defined to be the unique algebra
endomorphism of the ring of symmetric functions that
satisfies
for all positive integers
(where
stands for the
-th elementary symmetric
function, and
stands for the
-th complete homogeneous
symmetric function). It furthermore is a Hopf algebra
endomorphism and an involution, and it is also known as the
omega involution. It sends the power-sum symmetric function
to
for every positive integer
.
The images of some bases under the omega automorphism are given by
where is any partition, where
denotes
the length (length())
of the partition
, where
denotes the
conjugate partition
(conjugate()) of
, and where the usual notations for bases are used
(
= elementary,
= complete homogeneous,
= powersum,
= Schur).
The default implementation converts to the Schur basis, then performs the automorphism and changes back.
omega_involution() is a synonym for the omega() method.
EXAMPLES:
sage: J = SymmetricFunctions(QQ).jack(t=1).P()
sage: a = J([2,1]) + J([1,1,1])
sage: a.omega()
JackP[2, 1] + JackP[3]
sage: J(0).omega()
0
sage: J(1).omega()
JackP[]
The forgotten symmetric functions are the images of the monomial symmetric functions under omega:
sage: Sym = SymmetricFunctions(ZZ)
sage: m = Sym.m()
sage: f = Sym.f()
sage: all( f(lam) == m(lam).omega() for lam in Partitions(3) )
True
sage: all( m(lam) == f(lam).omega() for lam in Partitions(3) )
True
Return the image of self under the omega automorphism.
The omega automorphism is defined to be the unique algebra
endomorphism of the ring of symmetric functions that
satisfies
for all positive integers
(where
stands for the
-th elementary symmetric
function, and
stands for the
-th complete homogeneous
symmetric function). It furthermore is a Hopf algebra
endomorphism and an involution, and it is also known as the
omega involution. It sends the power-sum symmetric function
to
for every positive integer
.
The images of some bases under the omega automorphism are given by
where is any partition, where
denotes
the length (length())
of the partition
, where
denotes the
conjugate partition
(conjugate()) of
, and where the usual notations for bases are used
(
= elementary,
= complete homogeneous,
= powersum,
= Schur).
The default implementation converts to the Schur basis, then performs the automorphism and changes back.
omega_involution() is a synonym for the omega() method.
EXAMPLES:
sage: J = SymmetricFunctions(QQ).jack(t=1).P()
sage: a = J([2,1]) + J([1,1,1])
sage: a.omega()
JackP[2, 1] + JackP[3]
sage: J(0).omega()
0
sage: J(1).omega()
JackP[]
The forgotten symmetric functions are the images of the monomial symmetric functions under omega:
sage: Sym = SymmetricFunctions(ZZ)
sage: m = Sym.m()
sage: f = Sym.f()
sage: all( f(lam) == m(lam).omega() for lam in Partitions(3) )
True
sage: all( m(lam) == f(lam).omega() for lam in Partitions(3) )
True
Return the image of self under the -deformed omega
automorphism which sends
to
for all positive
integers
.
In general, this is well-defined outside of the powersum basis only
if the base ring is a -algebra.
If , then this is the omega automorphism (omega()).
INPUT:
EXAMPLES:
sage: QQqt = QQ['q,t'].fraction_field()
sage: q,t = QQqt.gens()
sage: p = SymmetricFunctions(QQqt).p()
sage: p[5].omega_qt()
((-q^5+1)/(-t^5+1))*p[5]
sage: p[5].omega_qt(q,t)
((-q^5+1)/(-t^5+1))*p[5]
sage: p([2]).omega_qt(q,t)
((q^2-1)/(-t^2+1))*p[2]
sage: p([2,1]).omega_qt(q,t)
((-q^3+q^2+q-1)/(t^3-t^2-t+1))*p[2, 1]
sage: p([3,2]).omega_qt(5,q)
-(2976/(q^5-q^3-q^2+1))*p[3, 2]
sage: p(0).omega_qt()
0
sage: p(1).omega_qt()
p[]
sage: H = SymmetricFunctions(QQqt).macdonald().H()
sage: H([1,1]).omega_qt()
((2*q^2-2*q*t-2*q+2*t)/(t^3-t^2-t+1))*McdH[1, 1] + ((q-1)/(t-1))*McdH[2]
sage: H([1,1]).omega_qt(q,t)
((2*q^2-2*q*t-2*q+2*t)/(t^3-t^2-t+1))*McdH[1, 1] + ((q-1)/(t-1))*McdH[2]
sage: H([1,1]).omega_qt(t,q)
((t^3-t^2-t+1)/(q^3-q^2-q+1))*McdH[2]
sage: Sym = SymmetricFunctions(FractionField(QQ['q','t']))
sage: S = Sym.macdonald().S()
sage: S([1,1]).omega_qt()
((q^2-q*t-q+t)/(t^3-t^2-t+1))*McdS[1, 1] + ((-q^2*t+q*t+q-1)/(-t^3+t^2+t-1))*McdS[2]
sage: s = Sym.schur()
sage: s(S([1,1]).omega_qt())
s[2]
Return the outer plethysm of self with x. This is
implemented only over base rings which are -algebras.
(To compute outer plethysms over general binomial rings, change
bases to the fraction field.)
The outer plethysm of with
is commonly denoted by
or by
. It is an algebra map
in
, but not (generally) in
.
By default, the degree one elements are taken to be the generators for the self‘s base ring. This setting can be modified by specifying the include and exclude keywords.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: h = Sym.h()
sage: s ( h([3])( h([2]) ) )
s[2, 2, 2] + s[4, 2] + s[6]
sage: p = Sym.p()
sage: p([3])( s([2,1]) )
1/3*p[3, 3, 3] - 1/3*p[9]
sage: e = Sym.e()
sage: e([3])( e([2]) )
e[3, 3] + e[4, 1, 1] - 2*e[4, 2] - e[5, 1] + e[6]
sage: R.<t> = QQ[]
sage: s = SymmetricFunctions(R).s()
sage: a = s([3])
sage: f = t*s([2])
sage: a(f)
t^3*s[2, 2, 2] + t^3*s[4, 2] + t^3*s[6]
sage: f(a)
t*s[4, 2] + t*s[6]
sage: s(0).plethysm(s[1])
0
sage: s(1).plethysm(s[1])
s[]
sage: s(1).plethysm(s(0))
s[]
See also
Return the reduced Kronecker product of self and x in the basis of self.
The reduced Kronecker product is a bilinear map mapping two
symmetric functions to another, not necessarily preserving degree.
It can be defined as follows: Let denote the Kronecker product
(itensor()) on the space of symmetric functions. For any
partitions
,
,
, let
denote the coefficient of the Schur
function
in the Kronecker product
(this is called a Kronecker coefficient).
For every partition
and every integer
, let
denote the
-completion of
(this is the
partition
;
see t_completion()).
Then, Theorem 1.2 of [BOR09] shows that for any partitions
and
and every integer
,
we can write the Kronecker product
in the form
with ranging over all partitions. The
coefficients
are independent on
. These coefficients
are denoted by
, and the symmetric
function
is said to be the reduced Kronecker product of and
. By bilinearity, this extends to a definition of a
reduced Kronecker product of any two symmetric functions.
The definition of the reduced Kronecker product goes back to
Murnaghan, and has recently been studied in [BOR09], [BdVO12]
and other places (our notation
appears in these two
sources).
INPUT:
OUTPUT:
EXAMPLES:
The example from page 2 of [BOR09]:
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.schur()
sage: s[2].reduced_kronecker_product(s[2])
s[] + s[1] + s[1, 1] + s[1, 1, 1] + 2*s[2] + 2*s[2, 1] + s[2, 2] + s[3] + s[3, 1] + s[4]
Taking the reduced Kronecker product with is the
identity map on the ring of symmetric functions:
sage: all( s[Partition([])].reduced_kronecker_product(s[lam])
....: == s[lam] for i in range(4)
....: for lam in Partitions(i) )
True
While reduced Kronecker products are hard to compute in general,
there is a rule for taking reduced Kronecker products with
. Namely, for every partition
, the reduced
Kronecker product of
with
is
, where the sum runs over all
partitions
, and the coefficient
is defined as the
number of ways to obtain
from
by one of the
following three operations:
This is, in fact, Proposition 5.15 of [CO10] in an elementary
wording. We check this for partitions of size :
sage: def mults1(lam):
....: # Reduced Kronecker multiplication by s[1], according
....: # to [CO10]_.
....: res = s.zero()
....: for mu in lam.up_list():
....: res += s(mu)
....: for mu in lam.down_list():
....: res += s(mu)
....: for nu in mu.up_list():
....: res += s(nu)
....: return res
sage: all( mults1(lam) == s[1].reduced_kronecker_product(s[lam])
....: for i in range(5) for lam in Partitions(i) )
True
Here is the example on page 3 of Christian Gutschwager’s Arxiv 0912.4411v3:
sage: s[1,1].reduced_kronecker_product(s[2])
s[1] + 2*s[1, 1] + s[1, 1, 1] + s[2] + 2*s[2, 1] + s[2, 1, 1] + s[3] + s[3, 1]
Example 39 from F. D. Murnaghan, “The analysis of the Kronecker product of irreducible representations of the symmetric group”, American Journal of Mathematics, Vol. 60, No. 3, Jul. 1938:
sage: s[3].reduced_kronecker_product(s[2,1])
s[1] + 2*s[1, 1] + 2*s[1, 1, 1] + s[1, 1, 1, 1] + 2*s[2] + 5*s[2, 1] + 4*s[2, 1, 1]
+ s[2, 1, 1, 1] + 3*s[2, 2] + 2*s[2, 2, 1] + 2*s[3] + 5*s[3, 1] + 3*s[3, 1, 1]
+ 3*s[3, 2] + s[3, 2, 1] + 2*s[4] + 3*s[4, 1] + s[4, 1, 1] + s[4, 2] + s[5]
+ s[5, 1]
TESTS:
sage: h = SymmetricFunctions(QQ).h()
sage: (2*h([])).reduced_kronecker_product(3*h([]))
6*h[]
Different bases and base rings:
sage: h = SymmetricFunctions(ZZ).h()
sage: e = SymmetricFunctions(ZZ).e()
sage: h(e[2].reduced_kronecker_product(h[2]))
h[1] + 2*h[1, 1] + h[1, 1, 1] - h[2] + h[2, 1, 1] - h[2, 2]
sage: F = CyclotomicField(12)
sage: s = SymmetricFunctions(F).s()
sage: e = SymmetricFunctions(F).e()
sage: v = e[2].reduced_kronecker_product(e[2]); v
e[] + e[1] + 2*e[1, 1] + e[1, 1, 1] + (-1)*e[2] + e[2, 2]
sage: parent(v)
Symmetric Functions over Cyclotomic Field of order 12 and degree 4 in the elementary basis
sage: s = SymmetricFunctions(ZZ).s()
sage: v = s[1].reduced_kronecker_product(s[1]); parent(v)
Symmetric Functions over Integer Ring in the Schur basis
Todo
This implementation of the reduced Kronecker product is painfully slow.
Return the degree d component of self.
INPUT:
OUTPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
sage: z.restrict_degree(2)
0
sage: z.restrict_degree(1)
s[1]
sage: z.restrict_degree(3)
s[1, 1, 1] + s[2, 1]
sage: z.restrict_degree(3, exact=False)
s[1] + s[1, 1, 1] + s[2, 1]
sage: z.restrict_degree(0)
0
Return the terms of self labelled by partitions of length l.
INPUT:
OUTPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
sage: z.restrict_partition_lengths(2)
s[2, 1]
sage: z.restrict_partition_lengths(0)
0
sage: z.restrict_partition_lengths(2, exact = False)
s[1] + s[2, 1] + s[4]
Return the terms of self labelled by partitions with
.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1])
sage: z.restrict_parts(2)
s[1] + s[1, 1, 1] + s[2, 1]
sage: z.restrict_parts(1)
s[1] + s[1, 1, 1]
Return the standard scalar product between self and x.
INPUT:
This is the default implementation that converts both self and x into either Schur functions (if zee is not specified) or power-sum functions (if zee is specified) and performs the scalar product in that basis.
EXAMPLES:
sage: e = SymmetricFunctions(QQ).e()
sage: h = SymmetricFunctions(QQ).h()
sage: m = SymmetricFunctions(QQ).m()
sage: p4 = Partitions(4)
sage: matrix([ [e(a).scalar(h(b)) for a in p4] for b in p4])
[ 0 0 0 0 1]
[ 0 0 0 1 4]
[ 0 0 1 2 6]
[ 0 1 2 5 12]
[ 1 4 6 12 24]
sage: matrix([ [h(a).scalar(e(b)) for a in p4] for b in p4])
[ 0 0 0 0 1]
[ 0 0 0 1 4]
[ 0 0 1 2 6]
[ 0 1 2 5 12]
[ 1 4 6 12 24]
sage: matrix([ [m(a).scalar(e(b)) for a in p4] for b in p4])
[-1 2 1 -3 1]
[ 0 1 0 -2 1]
[ 0 0 1 -2 1]
[ 0 0 0 -1 1]
[ 0 0 0 0 1]
sage: matrix([ [m(a).scalar(h(b)) for a in p4] for b in p4])
[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]
sage: p = SymmetricFunctions(QQ).p()
sage: m(p[3,2]).scalar(p[3,2], zee=lambda mu: 2**mu.length())
4
sage: m(p[3,2]).scalar(p[2,2,1], lambda mu: 1)
0
sage: m[3,2].scalar(h[3,2], zee=lambda mu: 2**mu.length())
2/3
TESTS:
sage: m(1).scalar(h(1))
1
sage: m(0).scalar(h(1))
0
sage: m(1).scalar(h(0))
0
sage: m(0).scalar(h(0))
0
Over the integers, too (as long as zee is not set):
sage: Sym = SymmetricFunctions(ZZ)
sage: m = Sym.m()
sage: m([2]).scalar(m([2]))
2
Return the -deformed standard Hall-Littlewood scalar product of
self and x.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: sp = a.scalar_t(a); sp
(-t^2 - 1)/(t^5 - 2*t^4 + t^3 - t^2 + 2*t - 1)
sage: sp.parent()
Fraction Field of Univariate Polynomial Ring in t over Rational Field
Return the Jack-scalar product beween self and x.
This scalar product is defined so that the power sum elements
are orthogonal and
, where
denotes the length of
.
INPUT:
EXAMPLES:
sage: p = SymmetricFunctions(QQ['t']).power()
sage: matrix([[p(mu).scalar_jack(p(nu)) for nu in Partitions(4)] for mu in Partitions(4)])
[ 4*t 0 0 0 0]
[ 0 3*t^2 0 0 0]
[ 0 0 8*t^2 0 0]
[ 0 0 0 4*t^3 0]
[ 0 0 0 0 24*t^4]
sage: matrix([[p(mu).scalar_jack(p(nu),2) for nu in Partitions(4)] for mu in Partitions(4)])
[ 8 0 0 0 0]
[ 0 12 0 0 0]
[ 0 0 32 0 0]
[ 0 0 0 32 0]
[ 0 0 0 0 384]
sage: JQ = SymmetricFunctions(QQ['t'].fraction_field()).jack().Q()
sage: matrix([[JQ(mu).scalar_jack(JQ(nu)) for nu in Partitions(3)] for mu in Partitions(3)])
[(2*t^2 + 3*t + 1)/(6*t^3) 0 0]
[ 0 (t + 2)/(2*t^3 + t^2) 0]
[ 0 0 6/(t^3 + 3*t^2 + 2*t)]
Returns the -deformed standard Hall-Littlewood scalar product of
self and x.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: sp = a.scalar_qt(a); factor(sp)
(t - 1)^-3 * (q - 1) * (t^2 + t + 1)^-1 * (q^2*t^2 - q*t^2 + q^2 - 2*q*t + t^2 - q + 1)
sage: sp.parent()
Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field
sage: a.scalar_qt(a,q=0)
(-t^2 - 1)/(t^5 - 2*t^4 + t^3 - t^2 + 2*t - 1)
sage: a.scalar_qt(a,t=0)
-q^3 + 2*q^2 - 2*q + 1
sage: a.scalar_qt(a,5,7) # q=5 and t=7
490/1539
sage: (x,y) = var('x,y')
sage: a.scalar_qt(a,q=x,t=y)
1/3*(x^3 - 1)/(y^3 - 1) + 2/3*(x - 1)^3/(y - 1)^3
sage: Rn = QQ['q','t','y','z'].fraction_field()
sage: (q,t,y,z) = Rn.gens()
sage: Mac = SymmetricFunctions(Rn).macdonald(q=y,t=z)
sage: a = Mac._sym.schur()([2,1])
sage: factor(Mac.P()(a).scalar_qt(Mac.Q()(a),q,t))
(t - 1)^-3 * (q - 1) * (t^2 + t + 1)^-1 * (q^2*t^2 - q*t^2 + q^2 - 2*q*t + t^2 - q + 1)
sage: factor(Mac.P()(a).scalar_qt(Mac.Q()(a)))
(z - 1)^-3 * (y - 1) * (z^2 + z + 1)^-1 * (y^2*z^2 - y*z^2 + y^2 - 2*y*z + z^2 - y + 1)
Return the -deformed standard Hall-Littlewood scalar product of
self and x.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: a = s([2,1])
sage: sp = a.scalar_t(a); sp
(-t^2 - 1)/(t^5 - 2*t^4 + t^3 - t^2 + 2*t - 1)
sage: sp.parent()
Fraction Field of Univariate Polynomial Ring in t over Rational Field
Return the result of skewing self by x. (Skewing by x is the endomorphism (as additive group) of the ring of symmetric functions adjoint to multiplication by x with respect to the Hall inner product.)
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s([3,2]).skew_by(s([2]))
s[2, 1] + s[3]
sage: s([3,2]).skew_by(s([1,1,1]))
0
sage: s([3,2,1]).skew_by(s([2,1]))
s[1, 1, 1] + 2*s[2, 1] + s[3]
sage: p = SymmetricFunctions(QQ).powersum()
sage: p([4,3,3,2,2,1]).skew_by(p([2,1]))
4*p[4, 3, 3, 2]
sage: zee = sage.combinat.sf.sfa.zee
sage: zee([4,3,3,2,2,1])/zee([4,3,3,2])
4
sage: s(0).skew_by(s([1]))
0
sage: s(1).skew_by(s([1]))
0
sage: s([]).skew_by(s([]))
s[]
sage: s([]).skew_by(s[1])
0
TESTS:
sage: f=s[3,2]
sage: f.skew_by([1])
Traceback (most recent call last):
...
ValueError: x needs to be a symmetric function
Return the image of self under the theta endomorphism which sends
to
for every positive integer
.
In general, this is well-defined outside of the powersum basis only
if the base ring is a -algebra.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s([2,1]).theta(2)
2*s[1, 1, 1] + 6*s[2, 1] + 2*s[3]
sage: p = SymmetricFunctions(QQ).p()
sage: p([2]).theta(2)
2*p[2]
sage: p(0).theta(2)
0
sage: p(1).theta(2)
p[]
Return the image of self under the -deformed theta
endomorphism which sends
to
for all positive integers
.
In general, this is well-defined outside of the powersum basis only
if the base ring is a -algebra.
INPUT:
EXAMPLES:
sage: QQqt = QQ['q,t'].fraction_field()
sage: q,t = QQqt.gens()
sage: p = SymmetricFunctions(QQqt).p()
sage: p([2]).theta_qt(q,t)
((-q^2+1)/(-t^2+1))*p[2]
sage: p([2,1]).theta_qt(q,t)
((q^3-q^2-q+1)/(t^3-t^2-t+1))*p[2, 1]
sage: p(0).theta_qt(q=1,t=3)
0
sage: p([2,1]).theta_qt(q=2,t=3)
3/16*p[2, 1]
sage: s = p.realization_of().schur()
sage: s([3]).theta_qt(q=0)*(1-t)*(1-t^2)*(1-t^3)
t^3*s[1, 1, 1] + (t^2+t)*s[2, 1] + s[3]
sage: p(1).theta_qt()
p[]
Return the image of the symmetric function self under the
-th Verschiebung operator.
The -th Verschiebung operator
is defined to be
the unique algebra endomorphism
of the ring of symmetric
functions that satisfies
for every positive
integer
divisible by
, and satisfies
for
every positive integer
not divisible by
. This operator
is a Hopf algebra endomorphism. For every
nonnegative integer
with
, it satisfies
(where is the complete homogeneous basis,
is the
powersum basis, and
is the elementary basis). For every
nonnegative integer
with
, it satisfes
The -th Verschiebung operator is also called the
-th
Verschiebung endomorphism. Its name derives from the Verschiebung
(German for “shift”) endomorphism of the Witt vectors.
The -th Verschiebung operator is adjoint to the
-th
Frobenius operator (see frobenius() for its definition)
with respect to the Hall scalar product (scalar()).
The action of the -th Verschiebung operator on the Schur basis
can also be computed explicitly. The following (probably clumsier
than necessary) description can be obtained by solving exercise
7.61 in Stanley’s [STA].
Let be a partition. Let
be a positive integer. If
the
-core of
is nonempty, then
. Otherwise, the following method
computes
: Write the partition
in the form
for some
nonnegative integer
. (If
does not divide the length of
, then this is achieved by adding trailing zeroes to
.) Set
for every
. Then,
is a strictly decreasing
sequence of nonnegative integers. Stably sort the list
in order of (weakly) increasing remainder of
modulo
. Let
be the sign of the
permutation that is used for this sorting. Let
be the sign
of the permutation that is used to stably sort the list
in order of (weakly) increasing remainder of
modulo
. (Notice that
.)
Then,
, where
is the
-quotient of
.
INPUT:
OUTPUT:
The result of applying the -th Verschiebung operator (on the ring of
symmetric functions) to self.
EXAMPLES:
sage: Sym = SymmetricFunctions(ZZ)
sage: p = Sym.p()
sage: h = Sym.h()
sage: s = Sym.s()
sage: m = Sym.m()
sage: s[3].verschiebung(2)
0
sage: s[3].verschiebung(3)
s[1]
sage: p[3].verschiebung(3)
3*p[1]
sage: m[3,2,1].verschiebung(3)
-18*m[1, 1] - 3*m[2]
sage: p[3,2,1].verschiebung(3)
0
sage: h[4].verschiebung(2)
h[2]
sage: p[2].verschiebung(2)
2*p[1]
sage: m[3,2,1].verschiebung(6)
12*m[1]
The Verschiebung endomorphisms are multiplicative:
sage: all( all( s(lam).verschiebung(2) * s(mu).verschiebung(2)
....: == (s(lam) * s(mu)).verschiebung(2)
....: for mu in Partitions(4) )
....: for lam in Partitions(4) )
True
Being Hopf algebra endomorphisms, the Verschiebung operators commute with the antipode:
sage: all( p(lam).verschiebung(3).antipode()
....: == p(lam).antipode().verschiebung(3)
....: for lam in Partitions(6) )
True
Testing the adjointness between the Frobenius operators
and the Verschiebung operators
:
sage: Sym = SymmetricFunctions(QQ)
sage: s = Sym.s()
sage: p = Sym.p()
sage: all( all( s(lam).verschiebung(2).scalar(p(mu))
....: == s(lam).scalar(p(mu).frobenius(2))
....: for mu in Partitions(3) )
....: for lam in Partitions(6) )
True
Bases: sage.categories.realizations.Category_realization_of_parent
The category of bases of the ring of symmetric functions.
Return the image of self under the degree negation automorphism of the ring of symmetric functions.
The degree negation is the automorphism which scales every
homogeneous element of degree by
(for all
).
Calling degree_negation(self) is equivalent to calling self.parent().degree_negation(self).
EXAMPLES:
sage: Sym = SymmetricFunctions(ZZ)
sage: m = Sym.monomial()
sage: f = 2*m[2,1] + 4*m[1,1] - 5*m[1] - 3*m[[]]
sage: f.degree_negation()
-3*m[] + 5*m[1] + 4*m[1, 1] - 2*m[2, 1]
sage: x = m.zero().degree_negation(); x
0
sage: parent(x) is m
True
Returns the degree zero coefficient of self.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: m = Sym.monomial()
sage: f = 2*m[2,1] + 3*m[[]]
sage: f.degree_zero_coefficient()
3
Return the Eulerian symmetric function (with
either an integer or a partition) or
(if the
optional argument k is specified) in terms of the basis
self.
It is known that the Eulerian quasisymmetric functions are in fact symmetric functions [SW2010]. For more information, see QuasiSymmetricFunctions.Fundamental.Eulerian(), which accepts the same syntax as this method.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: m = Sym.m()
sage: m.Eulerian(3, 1)
4*m[1, 1, 1] + 3*m[2, 1] + 2*m[3]
sage: h = Sym.h()
sage: h.Eulerian(4, 2)
h[2, 2] + h[3, 1] + h[4]
sage: s = Sym.s()
sage: s.Eulerian(5, 2)
s[2, 2, 1] + s[3, 1, 1] + 5*s[3, 2] + 6*s[4, 1] + 6*s[5]
sage: s.Eulerian([2,2,1], 2)
s[2, 2, 1] + s[3, 2] + s[4, 1] + s[5]
sage: s.Eulerian(5, 2, 2)
s[3, 2] + s[4, 1] + s[5]
We check Equation (5.4) in [SW2010]:
sage: h.Eulerian([6], 3)
h[3, 2, 1] - h[4, 1, 1] + 2*h[4, 2] + h[5, 1]
sage: s.Eulerian([6], 3)
s[3, 2, 1] + s[3, 3] + 3*s[4, 2] + 3*s[5, 1] + 3*s[6]
The antipode of element.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: p = Sym.p()
sage: s = Sym.s()
sage: e = Sym.e()
sage: h = Sym.h()
sage: (h([]) + h([1])).antipode() # indirect doctest
h[] - h[1]
sage: (s([]) + s([1]) + s[2]).antipode()
s[] - s[1] + s[1, 1]
sage: (p([2]) + p([3])).antipode()
-p[2] - p[3]
sage: (e([2]) + e([3])).antipode()
e[1, 1] - e[1, 1, 1] - e[2] + 2*e[2, 1] - e[3]
sage: f = Sym.f()
sage: f([3,2,1]).antipode()
-f[3, 2, 1] - 4*f[3, 3] - 2*f[4, 2] - 2*f[5, 1] - 6*f[6]
The antipode is an involution:
sage: Sym = SymmetricFunctions(ZZ)
sage: s = Sym.s()
sage: all( s[u].antipode().antipode() == s[u] for u in Partitions(4) )
True
The antipode is an algebra homomorphism:
sage: Sym = SymmetricFunctions(FiniteField(23))
sage: h = Sym.h()
sage: all( all( (s[u] * s[v]).antipode() == s[u].antipode() * s[v].antipode()
....: for u in Partitions(3) )
....: for v in Partitions(3) )
True
TESTS:
Everything works over :
sage: Sym = SymmetricFunctions(ZZ)
sage: p = Sym.p()
sage: s = Sym.s()
sage: e = Sym.e()
sage: h = Sym.h()
sage: (h([]) + h([1])).antipode() # indirect doctest
h[] - h[1]
sage: (s([]) + s([1]) + s[2]).antipode()
s[] - s[1] + s[1, 1]
sage: (p([2]) + p([3])).antipode()
-p[2] - p[3]
sage: (e([2]) + e([3])).antipode()
e[1, 1] - e[1, 1, 1] - e[2] + 2*e[2, 1] - e[3]
Return the Carlitz-Shareshian-Wachs symmetric function
(if comparison is None), or
(if comparison is -1), or
(if comparison is 0), or
(if comparison is 1) written in the
basis self. These functions are defined below.
The Carlitz-Shareshian-Wachs symmetric functions have been introduced in [GriRei2014], Exercise 2.84, as refinements of a certain particular case of chromatic quasisymmetric functions defined by Shareshian and Wachs. Their definitions are as follows:
Let ,
and
be three nonnegative integers. Let
denote the set of all
-tuples
of positive integers having the
property that there exist precisely
elements
of
satisfying
, and precisely
elements
of
satisfying
. For every
, let
be the monomial
. We then
define the power series
by
This is a symmetric function (according to
[GriRei2014], Exercise 2.84(b)), and for equals
the
-coefficient of the descent enumerator of Smirnov
words of length
(an example of a chromatic
quasisymmetric function which happens to be symmetric –
see [ShaWach2014], Example 2.5).
Assume that . Then, we can define three further
power series as follows:
where all three sums range over
. These
three power series
,
and
are symmetric functions as well
([GriRei2014], Exercise 2.84(c)). Their sum is
.
REFERENCES:
[ShaWach2014] | John Shareshian, Michelle L. Wachs. Chromatic quasisymmetric functions. Arxiv 1405.4629v1. |
INPUT:
OUTPUT:
The Carlitz-Shareshian-Wachs symmetric function
(if comparison is None), or
(if comparison is -1), or
(if comparison is 0), or
(if comparison is 1) written in the
basis self.
EXAMPLES:
The power series :
sage: Sym = SymmetricFunctions(ZZ)
sage: m = Sym.m()
sage: m.carlitz_shareshian_wachs(3, 2, 1)
0
sage: m.carlitz_shareshian_wachs(3, 1, 1)
m[2, 1]
sage: m.carlitz_shareshian_wachs(3, 2, 0)
m[1, 1, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 2)
m[3]
sage: m.carlitz_shareshian_wachs(3, 1, 0)
4*m[1, 1, 1] + m[2, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 1)
m[2, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 0)
m[1, 1, 1]
sage: m.carlitz_shareshian_wachs(5, 2, 2)
m[2, 2, 1] + m[3, 1, 1]
sage: m.carlitz_shareshian_wachs(1, 0, 0)
m[1]
sage: m.carlitz_shareshian_wachs(0, 0, 0)
m[]
The power series :
sage: m.carlitz_shareshian_wachs(3, 2, 1, comparison=-1)
0
sage: m.carlitz_shareshian_wachs(3, 1, 1, comparison=-1)
0
sage: m.carlitz_shareshian_wachs(3, 2, 0, comparison=-1)
0
sage: m.carlitz_shareshian_wachs(3, 0, 2, comparison=-1)
0
sage: m.carlitz_shareshian_wachs(3, 1, 0, comparison=-1)
2*m[1, 1, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 1, comparison=-1)
m[2, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 0, comparison=-1)
m[1, 1, 1]
sage: m.carlitz_shareshian_wachs(5, 2, 2, comparison=-1)
0
sage: m.carlitz_shareshian_wachs(4, 2, 0, comparison=-1)
3*m[1, 1, 1, 1]
sage: m.carlitz_shareshian_wachs(1, 0, 0, comparison=-1)
0
The power series :
sage: m.carlitz_shareshian_wachs(3, 2, 1, comparison=0)
0
sage: m.carlitz_shareshian_wachs(3, 1, 1, comparison=0)
0
sage: m.carlitz_shareshian_wachs(3, 2, 0, comparison=0)
0
sage: m.carlitz_shareshian_wachs(3, 0, 2, comparison=0)
m[3]
sage: m.carlitz_shareshian_wachs(3, 1, 0, comparison=0)
m[2, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 1, comparison=0)
0
sage: m.carlitz_shareshian_wachs(3, 0, 0, comparison=0)
0
sage: m.carlitz_shareshian_wachs(5, 2, 2, comparison=0)
0
sage: m.carlitz_shareshian_wachs(4, 2, 0, comparison=0)
m[2, 1, 1]
sage: m.carlitz_shareshian_wachs(1, 0, 0, comparison=0)
m[1]
The power series :
sage: m.carlitz_shareshian_wachs(3, 2, 1, comparison=1)
0
sage: m.carlitz_shareshian_wachs(3, 1, 1, comparison=1)
m[2, 1]
sage: m.carlitz_shareshian_wachs(3, 2, 0, comparison=1)
m[1, 1, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 2, comparison=1)
0
sage: m.carlitz_shareshian_wachs(3, 1, 0, comparison=1)
2*m[1, 1, 1]
sage: m.carlitz_shareshian_wachs(3, 0, 1, comparison=1)
0
sage: m.carlitz_shareshian_wachs(3, 0, 0, comparison=1)
0
sage: m.carlitz_shareshian_wachs(5, 2, 2, comparison=1)
m[2, 2, 1] + m[3, 1, 1]
sage: m.carlitz_shareshian_wachs(4, 2, 0, comparison=1)
8*m[1, 1, 1, 1] + 2*m[2, 1, 1] + m[2, 2]
sage: m.carlitz_shareshian_wachs(1, 0, 0, comparison=1)
0
TESTS:
This works fine over other base rings:
sage: Sym = SymmetricFunctions(FractionField(QQ['q','t']))
sage: P = Sym.macdonald().P()
sage: m = Sym.m()
sage: m.carlitz_shareshian_wachs(4, 1, 1)
4*m[2, 1, 1] + 2*m[2, 2] + 2*m[3, 1]
sage: P.carlitz_shareshian_wachs(4, 1, 1) == P(m.carlitz_shareshian_wachs(4, 1, 1))
True
Return the realization of symmetric functions corresponding to
self but over the base ring R. Only works when self
is one of the classical bases, not one of the -dependent
ones. In the latter case, None is returned instead.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: m = Sym.monomial()
sage: m.corresponding_basis_over(ZZ)
Symmetric Functions over Integer Ring in the monomial basis
sage: Sym = SymmetricFunctions(CyclotomicField())
sage: s = Sym.schur()
sage: s.corresponding_basis_over(Integers(13))
Symmetric Functions over Ring of integers modulo 13 in the Schur basis
sage: P = ZZ['q','t']
sage: Sym = SymmetricFunctions(P)
sage: mj = Sym.macdonald().J()
sage: mj.corresponding_basis_over(Integers(13))
TESTS:
Let’s check that this handles each of the bases properly:
sage: P = QQ['q','t']
sage: Sym = SymmetricFunctions(P)
sage: Q = CyclotomicField()['q','t']
sage: Sym.s().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the Schur basis
sage: Sym.p().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the powersum basis
sage: Sym.m().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the monomial basis
sage: Sym.e().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the elementary basis
sage: Sym.h().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the homogeneous basis
sage: Sym.f().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the forgotten basis
sage: Sym.w().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the Witt basis
sage: Sym.macdonald().P().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald().Q().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald().J().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald().H().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald().Ht().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald().S().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald(q=1).S().corresponding_basis_over(CyclotomicField())
sage: Sym.macdonald(q=1,t=3).P().corresponding_basis_over(CyclotomicField())
sage: Sym.hall_littlewood().P().corresponding_basis_over(CyclotomicField())
sage: Sym.hall_littlewood().Q().corresponding_basis_over(CyclotomicField())
sage: Sym.hall_littlewood().Qp().corresponding_basis_over(CyclotomicField())
sage: Sym.hall_littlewood(t=1).P().corresponding_basis_over(CyclotomicField())
sage: Sym.jack().J().corresponding_basis_over(CyclotomicField())
sage: Sym.jack().P().corresponding_basis_over(CyclotomicField())
sage: Sym.jack().Q().corresponding_basis_over(CyclotomicField())
sage: Sym.jack().Qp().corresponding_basis_over(CyclotomicField())
sage: Sym.jack(t=1).J().corresponding_basis_over(CyclotomicField())
sage: Sym.zonal().corresponding_basis_over(CyclotomicField())
Symmetric Functions over Universal Cyclotomic Field in the zonal basis
sage: Sym.llt(3).hspin().corresponding_basis_over(CyclotomicField())
sage: Sym.llt(3).hcospin().corresponding_basis_over(CyclotomicField())
sage: Sym.llt(3, t=1).hspin().corresponding_basis_over(CyclotomicField())
sage: Sym.llt(3, t=1).hcospin().corresponding_basis_over(CyclotomicField())
Todo
This function is an ugly hack using strings. It should be rewritten as soon as the bases of SymmetricFunctions are put on a more robust and systematic footing.
Return the counit of element.
The counit is the constant term of element.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ)
sage: m = Sym.monomial()
sage: f = 2*m[2,1] + 3*m[[]]
sage: f.counit()
3
Return the image of element under the degree negation automorphism of the ring of symmetric functions.
The degree negation is the automorphism which scales every
homogeneous element of degree by
(for all
).
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(ZZ)
sage: m = Sym.monomial()
sage: f = 2*m[2,1] + 4*m[1,1] - 5*m[1] - 3*m[[]]
sage: m.degree_negation(f)
-3*m[] + 5*m[1] + 4*m[1, 1] - 2*m[2, 1]
TESTS:
Using degree_negation() on an element of a different basis works correctly:
sage: e = Sym.elementary()
sage: m.degree_negation(e[3])
-m[1, 1, 1]
sage: m.degree_negation(m(e[3]))
-m[1, 1, 1]
Return the degree of the basis element indexed by b.
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ['q,t'].fraction_field())
sage: m = Sym.monomial()
sage: m.degree_on_basis(Partition([3,2]))
5
sage: P = Sym.macdonald().P()
sage: P.degree_on_basis(Partition([]))
0
Return the Gessel-Reutenauer symmetric function corresponding to the partition lam written in the basis self.
Let be a partition. The Gessel-Reutenauer
symmetric function
corresponding to
is the symmetric function denoted
in
[GR1993] and in Exercise 7.89 of [STA]. It can be defined
in several ways:
It is the sum of the monomials over all
words
over the alphabet
which have CFL type
. Here, the monomial
for a word
is defined as
, and the CFL type of
a word
is defined as the partition obtained by
sorting (in decreasing order) the lengths of the factors
in the Lyndon factorization
(lyndon_factorization())
of
. The fact that this power series
is symmetric is not obvious.
It is the sum of the fundamental quasisymmetric
functions over all
permutations
which have cycle type
. See
sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Fundamental
for the definition of fundamental quasisymmetric functions,
and cycle_type()
for that of cycle type. For a permutation
, we use
to denote the descent composition
(descents_composition())
of
. Again, this definition makes the symmetry
of
far from obvious.
For every positive integer , we have
where denotes the
-th power-sum symmetric
function. This
is also
denoted by
. Now,
is defined
as the product:
where denotes the multiplicity of the part
in
, and where the square brackets stand for
plethysm (plethysm()). This definition makes
the symmetry (but not the integrality!) of
obvious.
The equivalences of these three definitions are proven in [GR1993] Sections 2-3.
INPUT:
OUTPUT:
The Gessel-Reutenauer symmetric function
, where
is lam,
expanded in the basis self.
REFERENCES:
[GR1993] | (1, 2, 3) Ira M. Gessel, Christophe Reutenauer. Counting Permutations with Given Cycle Structure and Descent Set. Journal of Combinatorial Theory, Series A, 64 (1993), pp. 189–215. |
EXAMPLES:
The first few values of :
sage: Sym = SymmetricFunctions(ZZ)
sage: h = Sym.h()
sage: h.gessel_reutenauer(1)
h[1]
sage: h.gessel_reutenauer(2)
h[1, 1] - h[2]
sage: h.gessel_reutenauer(3)
h[2, 1] - h[3]
sage: h.gessel_reutenauer(4)
h[2, 1, 1] - h[2, 2]
sage: h.gessel_reutenauer(5)
h[2, 1, 1, 1] - h[2, 2, 1] - h[3, 1, 1] + h[3, 2] + h[4, 1] - h[5]
sage: h.gessel_reutenauer(6)
h[2, 1, 1, 1, 1] - h[2, 2, 1, 1] - h[2, 2, 2]
- 2*h[3, 1, 1, 1] + 5*h[3, 2, 1] - 2*h[3, 3] + h[4, 1, 1]
- h[4, 2] - h[5, 1] + h[6]
Gessel-Reutenauer functions indexed by partitions:
sage: h.gessel_reutenauer([2, 1])
h[1, 1, 1] - h[2, 1]
sage: h.gessel_reutenauer([2, 2])
h[1, 1, 1, 1] - 3*h[2, 1, 1] + 2*h[2, 2] + h[3, 1] - h[4]
The Gessel-Reutenauer functions are Schur-postive:
sage: s = Sym.s()
sage: s.gessel_reutenauer([2, 1])
s[1, 1, 1] + s[2, 1]
sage: s.gessel_reutenauer([2, 2, 1])
s[1, 1, 1, 1, 1] + s[2, 1, 1, 1] + s[2, 2, 1] + s[3, 2]
They do not form a basis, as the following example (from [GR1993] p. 201) shows:
sage: s.gessel_reutenauer([4]) == s.gessel_reutenauer([2, 1, 1])
True
Of the above three equivalent definitions of
, we use the third one for
computations. Let us check that the second one gives the
same results:
sage: QSym = QuasiSymmetricFunctions(ZZ)
sage: F = QSym.F() # fundamental basis
sage: def GR_def2(lam): # `\mathbf{GR}_\lambda`
....: n = lam.size()
....: r = F.sum_of_monomials([sigma.descents_composition()
....: for sigma in Permutations(n)
....: if sigma.cycle_type() == lam])
....: return r.to_symmetric_function()
sage: all( GR_def2(lam) == h.gessel_reutenauer(lam)
....: for n in range(5) for lam in Partitions(n) )
True
And the first one, too (assuming symmetry):
sage: m = Sym.m()
sage: def GR_def1(lam): # `\mathbf{GR}_\lambda`
....: n = lam.size()
....: Permus_mset = sage.combinat.permutation.Permutations_mset
....: def coeff_of_m_mu_in_result(mu):
....: words_to_check = Permus_mset([i for (i, l) in enumerate(mu)
....: for _ in range(l)])
....: return sum((1 for w in words_to_check if
....: Partition(list(reversed(sorted([len(v) for v in Word(w).lyndon_factorization()]))))
....: == lam))
....: r = m.sum_of_terms([(mu, coeff_of_m_mu_in_result(mu))
....: for mu in Partitions(n)],
....: distinct=True)
....: return r
sage: all( GR_def1(lam) == h.gessel_reutenauer(lam)
....: for n in range(5) for lam in Partitions(n) )
True
TESTS:
This works fine over other base rings:
sage: Sym = SymmetricFunctions(FractionField(QQ['q','t']))
sage: P = Sym.macdonald().P()
sage: h = Sym.h()
sage: P.gessel_reutenauer(3) == P(h.gessel_reutenauer(3))
True
Note
The currently existing implementation of this function is
technically unsatisfactory. It distinguishes the case when the
base ring is a -algebra from the case
where it isn’t. In the latter, it does a computation using
universal coefficients, again distinguishing the case when it is
able to compute the “corresponding” basis of the symmetric function
algebra over
(using the corresponding_basis_over hack)
from the case when it isn’t (in which case it transforms everything
into the Schur basis, which is slow).
Returns whether this symmetric function algebra is commutative.
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s.is_commutative()
True
Return whether self is a field. (It is not.)
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s.is_field()
False
Return whether self is an integral domain. (It is if and only if the base ring is an integral domain.)
INPUT:
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s()
sage: s.is_integral_domain()
True
The following doctest is disabled pending trac ticket #15475:
sage: s = SymmetricFunctions(Zmod(14)).s() # not tested
sage: s.is_integral_domain() # not tested
False
Returns the empty partition, as per AlgebrasWithBasis.ParentMethods.one_basis
INPUT:
EXAMPLES:
sage: Sym = SymmetricFunctions(QQ['t'].fraction_field())
sage: s = Sym.s()
sage: s.one_basis()
[]
sage: Q = Sym.hall_littlewood().Q()
sage: Q.one_basis()
[]
Todo
generalize to Modules.Graded.Connected.ParentMethods
The super categories of self.
INPUT:
EXAMPLES:
sage: from sage.combinat.sf.sfa import SymmetricFunctionsBases
sage: Sym = SymmetricFunctions(QQ)
sage: bases = SymmetricFunctionsBases(Sym)
sage: bases.super_categories()
[Category of commutative graded hopf algebras with basis over Rational Field,
Category of realizations of Symmetric Functions over Rational Field]
Checks whether x is a symmetric function.
EXAMPLES:
sage: from sage.combinat.sf.sfa import is_SymmetricFunction
sage: s = SymmetricFunctions(QQ).s()
sage: is_SymmetricFunction(2)
False
sage: is_SymmetricFunction(s(2))
True
sage: is_SymmetricFunction(s([2,1]))
True
Checks whether x is a symmetric function algebra.
EXAMPLES:
sage: from sage.combinat.sf.sfa import is_SymmetricFunctionAlgebra
sage: is_SymmetricFunctionAlgebra(5)
False
sage: is_SymmetricFunctionAlgebra(ZZ)
False
sage: is_SymmetricFunctionAlgebra(SymmetricFunctions(ZZ).schur())
True
sage: is_SymmetricFunctionAlgebra(SymmetricFunctions(QQ).e())
True
sage: is_SymmetricFunctionAlgebra(SymmetricFunctions(QQ).macdonald(q=1,t=1).P())
True
sage: is_SymmetricFunctionAlgebra(SymmetricFunctions(FractionField(QQ['q','t'])).macdonald().P())
True
Return the size of the centralizer of any permutation of cycle type part.
Note that the size of the centralizer is the inner product between
p(part) and itself, where is the power-sum symmetric
functions.
INPUT:
OUTPUT:
EXAMPLES:
sage: from sage.combinat.sf.sfa import zee
sage: zee([2,1,1])
4