Quasisymmetric functions¶
REFERENCES:
I. Gessel, Multipartite P-partitions and inner products of skew Schur functions, Contemp. Math. 34 (1984), 289-301. http://people.brandeis.edu/~gessel/homepage/papers/multipartite.pdf
C. Malvenuto and C. Reutenauer, Duality between quasi-symmetric functions and the Solomon descent algebra, J. Algebra 177 (1995), no. 3, 967-982. http://www.mat.uniroma1.it/people/malvenuto/Duality.pdf
Claudia Malvenuto, Produits et coproduits des fonctions quasi-symétriques et de l’algèbre des descentes, thesis, November 1993. http://www1.mat.uniroma1.it/people/malvenuto/Thesis.pdf
Michiel Hazewinkel, Explicit polynomial generators for the ring of quasisymmetric functions over the integers. arXiv math/0410366v1
David E. Radford, A natural ring basis for the shuffle algebra and an application to group schemes, J. Algebra 58 (1979), 432-454.
Israel Gelfand, D. Krob, Alain Lascoux, B. Leclerc, V. S. Retakh, J.-Y. Thibon, Noncommutative symmetric functions. arXiv hep-th/9407124v1
D. Krob, B. Leclerc, J.-Y. Thibon, Noncommutative symmetric functions II: Transformations of alphabets. http://www-igm.univ-mlv.fr/~jyt/ARTICLES/NCSF2.ps
F. Hivert, J.-G. Luque, J.-C. Novelli, J.-Y. Thibon, The (1-E)-transform in combinatorial Hopf algebras. arXiv math/0912.0184v2
Kurt Luoto, Stefan Mykytiuk and Stephanie van Willigenburg, An introduction to quasisymmetric Schur functions – Hopf algebras, quasisymmetric functions, and Young composition tableaux, May 23, 2013, Springer. http://www.math.ubc.ca/%7Esteph/papers/QuasiSchurBook.pdf
Chris Berg, Nantel Bergeron, Franco Saliola, Luis Serrano, Mike Zabrocki, A lift of the Schur and Hall-Littlewood bases to non-commutative symmetric functions, arXiv 1208.5191v3.
Michael Hoffman. Quasi-symmetric functions and mod \(p\) multiple harmonic sums. Kyushu J. Math. 69 (2015), pp. 345-366. doi:10.2206/kyushujm.69.345, arXiv math/0401319v3.
Cristina Ballantine, Zajj Daugherty, Angela Hicks, Sarah Mason, Elizabeth Niese. Quasisymmetric power sums. arXiv 1710.11613.
Edward Allen, Joshua Hallam, Sarah Mason, Dual Immaculate Quasisymmetric Functions Expand Positively into Young Quasisymmetric Schur Functions. arXiv 1606.03519
John Shareshian and Michelle Wachs. Eulerian quasisymmetric functions. (2010). arXiv 0812.0764v2
AUTHOR:
Jason Bandlow
Franco Saliola
Chris Berg
Darij Grinberg
- class sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions(R)[source]¶
Bases:
UniqueRepresentation
,Parent
The Hopf algebra of quasisymmetric functions.
Let \(R\) be a commutative ring with unity. The \(R\)-algebra of quasi-symmetric functions may be realized as an \(R\)-subalgebra of the ring of power series in countably many variables \(R[[x_1, x_2, x_3, \ldots]]\). It consists of those formal power series \(p\) which are degree-bounded (i. e., the degrees of all monomials occurring with nonzero coefficient in \(p\) are bounded from above, although the bound can depend on \(p\)) and satisfy the following condition: For every tuple \((a_1, a_2, \ldots, a_m)\) of positive integers, the coefficient of the monomial \(x_{i_1}^{a_1} x_{i_2}^{a_2} \cdots x_{i_m}^{a_m}\) in \(p\) is the same for all strictly increasing sequences \((i_1 < i_2 < \cdots < i_m)\) of positive integers. (In other words, the coefficient of a monomial in \(p\) depends only on the sequence of nonzero exponents in the monomial. If “sequence” were to be replaced by “multiset” here, we would obtain the definition of a symmetric function.)
The \(R\)-algebra of quasi-symmetric functions is commonly called \(\mathrm{QSym}_R\) or occasionally just \(\mathrm{QSym}\) (when \(R\) is clear from the context or \(\ZZ\) or \(\QQ\)). It is graded by the total degree of the power series. Its homogeneous elements of degree \(k\) form a free \(R\)-submodule of rank equal to the number of compositions of \(k\) (that is, \(2^{k-1}\) if \(k \geq 1\), else \(1\)).
The two classical bases of \(\mathrm{QSym}\), the monomial basis \((M_I)_I\) and the fundamental basis \((F_I)_I\), are indexed by compositions \(I = (I_1, I_2, \cdots, I_\ell )\) and defined by the formulas:
\[M_I = \sum_{1 \leq i_1 < i_2 < \cdots < i_\ell} x_{i_1}^{I_1} x_{i_2}^{I_2} \cdots x_{i_\ell}^{I_\ell}\]and
\[F_I = \sum_{(j_1, j_2, \ldots, j_n)} x_{j_1} x_{j_2} \cdots x_{j_n}\]where in the second equation the sum runs over all weakly increasing \(n\)-tuples \((j_1, j_2, \ldots, j_n)\) of positive integers (where \(n\) is the size of \(I\)) which increase strictly from \(j_r\) to \(j_{r+1}\) if \(r\) is a descent of the composition \(I\).
These bases are related by the formula
\(F_I = \sum_{J \leq I} M_J\)
where the inequality \(J \leq I\) indicates that \(J\) is finer than \(I\).
The \(R\)-algebra of quasi-symmetric functions is a Hopf algebra, with the coproduct satisfying
\[\Delta M_I = \sum_{k=0}^{\ell} M_{(I_1, I_2, \cdots, I_k)} \otimes M_{(I_{k+1}, I_{k+2}, \cdots , I_{\ell})}\]for every composition \(I = (I_1, I_2, \cdots , I_\ell )\).
It is possible to define an \(R\)-algebra of quasi-symmetric functions in a finite number of variables as well (but it is not a bialgebra). These quasi-symmetric functions are actual polynomials then, not just power series.
Chapter 5 of [GriRei18] and Section 11 of [HazWitt1] are devoted to quasi-symmetric functions, as are Malvenuto’s thesis [Mal1993] and part of Chapter 7 of [Sta-EC2].
The implementation of the quasi-symmetric function Hopf algebra
We realize the \(R\)-algebra of quasi-symmetric functions in Sage as a graded Hopf algebra with basis elements indexed by compositions:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: QSym.category() Join of Category of Hopf algebras over Rational Field and Category of graded algebras over Rational Field and Category of commutative algebras over Rational Field and Category of monoids with realizations and Category of graded coalgebras over Rational Field and Category of coalgebras over Rational Field with realizations
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> QSym.category() Join of Category of Hopf algebras over Rational Field and Category of graded algebras over Rational Field and Category of commutative algebras over Rational Field and Category of monoids with realizations and Category of graded coalgebras over Rational Field and Category of coalgebras over Rational Field with realizations
The most standard two bases for this \(R\)-algebra are the monomial and fundamental bases, and are accessible by the
M()
andF()
methods:sage: M = QSym.M() sage: F = QSym.F() sage: M(F[2,1,2]) M[1, 1, 1, 1, 1] + M[1, 1, 1, 2] + M[2, 1, 1, 1] + M[2, 1, 2] sage: F(M[2,1,2]) F[1, 1, 1, 1, 1] - F[1, 1, 1, 2] - F[2, 1, 1, 1] + F[2, 1, 2]
>>> from sage.all import * >>> M = QSym.M() >>> F = QSym.F() >>> M(F[Integer(2),Integer(1),Integer(2)]) M[1, 1, 1, 1, 1] + M[1, 1, 1, 2] + M[2, 1, 1, 1] + M[2, 1, 2] >>> F(M[Integer(2),Integer(1),Integer(2)]) F[1, 1, 1, 1, 1] - F[1, 1, 1, 2] - F[2, 1, 1, 1] + F[2, 1, 2]
The product on this space is commutative and is inherited from the product on the realization within the ring of power series:
sage: M[3]*M[1,1] == M[1,1]*M[3] True sage: M[3]*M[1,1] M[1, 1, 3] + M[1, 3, 1] + M[1, 4] + M[3, 1, 1] + M[4, 1] sage: F[3]*F[1,1] F[1, 1, 3] + F[1, 2, 2] + F[1, 3, 1] + F[1, 4] + F[2, 1, 2] + F[2, 2, 1] + F[2, 3] + F[3, 1, 1] + F[3, 2] + F[4, 1] sage: M[3]*F[2] M[1, 1, 3] + M[1, 3, 1] + M[1, 4] + M[2, 3] + M[3, 1, 1] + M[3, 2] + M[4, 1] + M[5] sage: F[2]*M[3] F[1, 1, 1, 2] - F[1, 2, 2] + F[2, 1, 1, 1] - F[2, 1, 2] - F[2, 2, 1] + F[5]
>>> from sage.all import * >>> M[Integer(3)]*M[Integer(1),Integer(1)] == M[Integer(1),Integer(1)]*M[Integer(3)] True >>> M[Integer(3)]*M[Integer(1),Integer(1)] M[1, 1, 3] + M[1, 3, 1] + M[1, 4] + M[3, 1, 1] + M[4, 1] >>> F[Integer(3)]*F[Integer(1),Integer(1)] F[1, 1, 3] + F[1, 2, 2] + F[1, 3, 1] + F[1, 4] + F[2, 1, 2] + F[2, 2, 1] + F[2, 3] + F[3, 1, 1] + F[3, 2] + F[4, 1] >>> M[Integer(3)]*F[Integer(2)] M[1, 1, 3] + M[1, 3, 1] + M[1, 4] + M[2, 3] + M[3, 1, 1] + M[3, 2] + M[4, 1] + M[5] >>> F[Integer(2)]*M[Integer(3)] F[1, 1, 1, 2] - F[1, 2, 2] + F[2, 1, 1, 1] - F[2, 1, 2] - F[2, 2, 1] + F[5]
There is a coproduct on \(\mathrm{QSym}\) as well, which in the Monomial basis acts by cutting the composition into a left half and a right half. The coproduct is not co-commutative:
sage: M[1,3,1].coproduct() M[] # M[1, 3, 1] + M[1] # M[3, 1] + M[1, 3] # M[1] + M[1, 3, 1] # M[] sage: F[1,3,1].coproduct() F[] # F[1, 3, 1] + F[1] # F[3, 1] + F[1, 1] # F[2, 1] + F[1, 2] # F[1, 1] + F[1, 3] # F[1] + F[1, 3, 1] # F[]
>>> from sage.all import * >>> M[Integer(1),Integer(3),Integer(1)].coproduct() M[] # M[1, 3, 1] + M[1] # M[3, 1] + M[1, 3] # M[1] + M[1, 3, 1] # M[] >>> F[Integer(1),Integer(3),Integer(1)].coproduct() F[] # F[1, 3, 1] + F[1] # F[3, 1] + F[1, 1] # F[2, 1] + F[1, 2] # F[1, 1] + F[1, 3] # F[1] + F[1, 3, 1] # F[]
The duality pairing with non-commutative symmetric functions
These two operations endow the quasi-symmetric functions \(\mathrm{QSym}\) with the structure of a Hopf algebra. It is the graded dual Hopf algebra of the non-commutative symmetric functions \(NCSF\). Under this duality, the Monomial basis of \(\mathrm{QSym}\) is dual to the Complete basis of \(NCSF\), and the Fundamental basis of \(\mathrm{QSym}\) is dual to the Ribbon basis of \(NCSF\) (see [MR]).
sage: S = M.dual(); S Non-Commutative Symmetric Functions over the Rational Field in the Complete basis sage: M[1,3,1].duality_pairing( S[1,3,1] ) 1 sage: M.duality_pairing_matrix( S, degree=4 ) [1 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1] sage: F.duality_pairing_matrix( S, degree=4 ) [1 0 0 0 0 0 0 0] [1 1 0 0 0 0 0 0] [1 0 1 0 0 0 0 0] [1 1 1 1 0 0 0 0] [1 0 0 0 1 0 0 0] [1 1 0 0 1 1 0 0] [1 0 1 0 1 0 1 0] [1 1 1 1 1 1 1 1] sage: NCSF = M.realization_of().dual() sage: R = NCSF.Ribbon() sage: F.duality_pairing_matrix( R, degree=4 ) [1 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1] sage: M.duality_pairing_matrix( R, degree=4 ) [ 1 0 0 0 0 0 0 0] [-1 1 0 0 0 0 0 0] [-1 0 1 0 0 0 0 0] [ 1 -1 -1 1 0 0 0 0] [-1 0 0 0 1 0 0 0] [ 1 -1 0 0 -1 1 0 0] [ 1 0 -1 0 -1 0 1 0] [-1 1 1 -1 1 -1 -1 1]
>>> from sage.all import * >>> S = M.dual(); S Non-Commutative Symmetric Functions over the Rational Field in the Complete basis >>> M[Integer(1),Integer(3),Integer(1)].duality_pairing( S[Integer(1),Integer(3),Integer(1)] ) 1 >>> M.duality_pairing_matrix( S, degree=Integer(4) ) [1 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1] >>> F.duality_pairing_matrix( S, degree=Integer(4) ) [1 0 0 0 0 0 0 0] [1 1 0 0 0 0 0 0] [1 0 1 0 0 0 0 0] [1 1 1 1 0 0 0 0] [1 0 0 0 1 0 0 0] [1 1 0 0 1 1 0 0] [1 0 1 0 1 0 1 0] [1 1 1 1 1 1 1 1] >>> NCSF = M.realization_of().dual() >>> R = NCSF.Ribbon() >>> F.duality_pairing_matrix( R, degree=Integer(4) ) [1 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1] >>> M.duality_pairing_matrix( R, degree=Integer(4) ) [ 1 0 0 0 0 0 0 0] [-1 1 0 0 0 0 0 0] [-1 0 1 0 0 0 0 0] [ 1 -1 -1 1 0 0 0 0] [-1 0 0 0 1 0 0 0] [ 1 -1 0 0 -1 1 0 0] [ 1 0 -1 0 -1 0 1 0] [-1 1 1 -1 1 -1 -1 1]
Let \(H\) and \(G\) be elements of \(\mathrm{QSym}\), and \(h\) an element of \(NCSF\). Then, if we represent the duality pairing with the mathematical notation \([ \cdot, \cdot ]\),
\([H G, h] = [H \otimes G, \Delta(h)]~.\)
For example, the coefficient of
M[2,1,4,1]
inM[1,3]*M[2,1,1]
may be computed with the duality pairing:sage: I, J = Composition([1,3]), Composition([2,1,1]) sage: (M[I]*M[J]).duality_pairing(S[2,1,4,1]) 1
>>> from sage.all import * >>> I, J = Composition([Integer(1),Integer(3)]), Composition([Integer(2),Integer(1),Integer(1)]) >>> (M[I]*M[J]).duality_pairing(S[Integer(2),Integer(1),Integer(4),Integer(1)]) 1
And the coefficient of
S[1,3] # S[2,1,1]
inS[2,1,4,1].coproduct()
is equal to this result:sage: S[2,1,4,1].coproduct() S[] # S[2, 1, 4, 1] + ... + S[1, 3] # S[2, 1, 1] + ... + S[4, 1] # S[2, 1]
>>> from sage.all import * >>> S[Integer(2),Integer(1),Integer(4),Integer(1)].coproduct() S[] # S[2, 1, 4, 1] + ... + S[1, 3] # S[2, 1, 1] + ... + S[4, 1] # S[2, 1]
The duality pairing on the tensor space is another way of getting this coefficient, but currently the method
duality_pairing
is not defined on the tensor squared space. However, we can extend this functionality by applying a linear morphism to the terms in the coproduct, as follows:sage: X = S[2,1,4,1].coproduct() sage: def linear_morphism(x, y): ....: return x.duality_pairing(M[1,3]) * y.duality_pairing(M[2,1,1]) sage: X.apply_multilinear_morphism(linear_morphism, codomain=ZZ) 1
>>> from sage.all import * >>> X = S[Integer(2),Integer(1),Integer(4),Integer(1)].coproduct() >>> def linear_morphism(x, y): ... return x.duality_pairing(M[Integer(1),Integer(3)]) * y.duality_pairing(M[Integer(2),Integer(1),Integer(1)]) >>> X.apply_multilinear_morphism(linear_morphism, codomain=ZZ) 1
Similarly, if \(H\) is an element of \(\mathrm{QSym}\) and \(g\) and \(h\) are elements of \(NCSF\), then
\[[ H, g h ] = [ \Delta(H), g \otimes h ].\]For example, the coefficient of
R[2,3,1]
inR[2,1]*R[2,1]
is computed with the duality pairing by the following command:sage: (R[2,1]*R[2,1]).duality_pairing(F[2,3,1]) 1 sage: R[2,1]*R[2,1] R[2, 1, 2, 1] + R[2, 3, 1]
>>> from sage.all import * >>> (R[Integer(2),Integer(1)]*R[Integer(2),Integer(1)]).duality_pairing(F[Integer(2),Integer(3),Integer(1)]) 1 >>> R[Integer(2),Integer(1)]*R[Integer(2),Integer(1)] R[2, 1, 2, 1] + R[2, 3, 1]
This coefficient should then be equal to the coefficient of
F[2,1] # F[2,1]
inF[2,3,1].coproduct()
:sage: F[2,3,1].coproduct() F[] # F[2, 3, 1] + ... + F[2, 1] # F[2, 1] + ... + F[2, 3, 1] # F[]
>>> from sage.all import * >>> F[Integer(2),Integer(3),Integer(1)].coproduct() F[] # F[2, 3, 1] + ... + F[2, 1] # F[2, 1] + ... + F[2, 3, 1] # F[]
This can also be computed by the duality pairing on the tensor space, as above:
sage: X = F[2,3,1].coproduct() sage: def linear_morphism(x, y): ....: return x.duality_pairing(R[2,1]) * y.duality_pairing(R[2,1]) sage: X.apply_multilinear_morphism(linear_morphism, codomain=ZZ) 1
>>> from sage.all import * >>> X = F[Integer(2),Integer(3),Integer(1)].coproduct() >>> def linear_morphism(x, y): ... return x.duality_pairing(R[Integer(2),Integer(1)]) * y.duality_pairing(R[Integer(2),Integer(1)]) >>> X.apply_multilinear_morphism(linear_morphism, codomain=ZZ) 1
The operation dual to multiplication by a non-commutative symmetric function
Let \(g \in NCSF\) and consider the linear endomorphism of \(NCSF\) defined by left (respectively, right) multiplication by \(g\). Since there is a duality between \(\mathrm{QSym}\) and \(NCSF\), this linear transformation induces an operator \(g^{\perp}\) on \(\mathrm{QSym}\) satisfying
\[[ g^{\perp}(H), h ] = [ H, gh ].\]for any non-commutative symmetric function \(h\).
This is implemented by the method
skew_by()
. Explicitly, ifH
is a quasi-symmetric function andg
a non-commutative symmetric function, thenH.skew_by(g)
andH.skew_by(g, side='right')
are expressions that satisfy, for any non-commutative symmetric functionh
, the following equalities:H.skew_by(g).duality_pairing(h) == H.duality_pairing(g*h) H.skew_by(g, side='right').duality_pairing(h) == H.duality_pairing(h*g)
For example,
M[J].skew_by(S[I])
is \(0\) unless the compositionJ
begins withI
andM(J).skew_by(S(I), side='right')
is \(0\) unless the compositionJ
ends withI
. For example:sage: M[3,2,2].skew_by(S[3]) M[2, 2] sage: M[3,2,2].skew_by(S[2]) 0 sage: M[3,2,2].coproduct().apply_multilinear_morphism( lambda x,y: x.duality_pairing(S[3])*y ) M[2, 2] sage: M[3,2,2].skew_by(S[3], side='right') 0 sage: M[3,2,2].skew_by(S[2], side='right') M[3, 2]
>>> from sage.all import * >>> M[Integer(3),Integer(2),Integer(2)].skew_by(S[Integer(3)]) M[2, 2] >>> M[Integer(3),Integer(2),Integer(2)].skew_by(S[Integer(2)]) 0 >>> M[Integer(3),Integer(2),Integer(2)].coproduct().apply_multilinear_morphism( lambda x,y: x.duality_pairing(S[Integer(3)])*y ) M[2, 2] >>> M[Integer(3),Integer(2),Integer(2)].skew_by(S[Integer(3)], side='right') 0 >>> M[Integer(3),Integer(2),Integer(2)].skew_by(S[Integer(2)], side='right') M[3, 2]
The counit
The counit is defined by sending all elements of positive degree to zero:
sage: M[3].degree(), M[3,1,2].degree(), M.one().degree() (3, 6, 0) sage: M[3].counit() 0 sage: M[3,1,2].counit() 0 sage: M.one().counit() 1 sage: (M[3] - 2*M[3,1,2] + 7).counit() 7 sage: (F[3] - 2*F[3,1,2] + 7).counit() 7
>>> from sage.all import * >>> M[Integer(3)].degree(), M[Integer(3),Integer(1),Integer(2)].degree(), M.one().degree() (3, 6, 0) >>> M[Integer(3)].counit() 0 >>> M[Integer(3),Integer(1),Integer(2)].counit() 0 >>> M.one().counit() 1 >>> (M[Integer(3)] - Integer(2)*M[Integer(3),Integer(1),Integer(2)] + Integer(7)).counit() 7 >>> (F[Integer(3)] - Integer(2)*F[Integer(3),Integer(1),Integer(2)] + Integer(7)).counit() 7
The antipode
The antipode sends the Fundamental basis element indexed by the composition \(I\) to \((-1)^{|I|}\) times the Fundamental basis element indexed by the conjugate composition to \(I\) (where \(|I|\) stands for the size of \(I\), that is, the sum of all entries of \(I\)).
sage: F[3,2,2].antipode() -F[1, 2, 2, 1, 1] sage: Composition([3,2,2]).conjugate() [1, 2, 2, 1, 1]
>>> from sage.all import * >>> F[Integer(3),Integer(2),Integer(2)].antipode() -F[1, 2, 2, 1, 1] >>> Composition([Integer(3),Integer(2),Integer(2)]).conjugate() [1, 2, 2, 1, 1]
The antipodes of the Monomial quasisymmetric functions can also be computed easily: Every composition \(I\) satisfies
\[\omega(M_I) = (-1)^{\ell(I)} \sum M_J,\]where the sum ranges over all compositions \(J\) of \(|I|\) which are coarser than the reversed composition \(I^r\) of \(I\). Here, \(\ell(I)\) denotes the length of the composition \(I\) (that is, the number of its parts).
sage: M[3,2,1].antipode() -M[1, 2, 3] - M[1, 5] - M[3, 3] - M[6] sage: M[3,2,2].antipode() -M[2, 2, 3] - M[2, 5] - M[4, 3] - M[7]
>>> from sage.all import * >>> M[Integer(3),Integer(2),Integer(1)].antipode() -M[1, 2, 3] - M[1, 5] - M[3, 3] - M[6] >>> M[Integer(3),Integer(2),Integer(2)].antipode() -M[2, 2, 3] - M[2, 5] - M[4, 3] - M[7]
We demonstrate here the defining relation of the antipode:
sage: X = F[3,2,2].coproduct() sage: X.apply_multilinear_morphism(lambda x,y: x*y.antipode()) 0 sage: X.apply_multilinear_morphism(lambda x,y: x.antipode()*y) 0
>>> from sage.all import * >>> X = F[Integer(3),Integer(2),Integer(2)].coproduct() >>> X.apply_multilinear_morphism(lambda x,y: x*y.antipode()) 0 >>> X.apply_multilinear_morphism(lambda x,y: x.antipode()*y) 0
The relation with symmetric functions
The quasi-symmetric functions are a ring which contain the symmetric functions as a subring. The Monomial quasi-symmetric functions are related to the monomial symmetric functions by
\[m_\lambda = \sum_{\operatorname{sort}(I) = \lambda} M_I\](where \(\operatorname{sort}(I)\) denotes the result of sorting the entries of \(I\) in decreasing order).
There are methods to test if an expression in the quasi-symmetric functions is a symmetric function and, if it is, send it to an expression in the symmetric functions:
sage: f = M[1,1,2] + M[1,2,1] sage: f.is_symmetric() False sage: g = M[3,1] + M[1,3] sage: g.is_symmetric() True sage: g.to_symmetric_function() m[3, 1]
>>> from sage.all import * >>> f = M[Integer(1),Integer(1),Integer(2)] + M[Integer(1),Integer(2),Integer(1)] >>> f.is_symmetric() False >>> g = M[Integer(3),Integer(1)] + M[Integer(1),Integer(3)] >>> g.is_symmetric() True >>> g.to_symmetric_function() m[3, 1]
The expansion of the Schur function in terms of the Fundamental quasi-symmetric functions is due to [Ges]. There is one term in the expansion for each standard tableau of shape equal to the partition indexing the Schur function.
sage: f = F[3,2] + F[2,2,1] + F[2,3] + F[1,3,1] + F[1,2,2] sage: f.is_symmetric() True sage: f.to_symmetric_function() 5*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + 2*m[2, 2, 1] + m[3, 1, 1] + m[3, 2] sage: s = SymmetricFunctions(QQ).s() sage: s(f.to_symmetric_function()) s[3, 2]
>>> from sage.all import * >>> f = F[Integer(3),Integer(2)] + F[Integer(2),Integer(2),Integer(1)] + F[Integer(2),Integer(3)] + F[Integer(1),Integer(3),Integer(1)] + F[Integer(1),Integer(2),Integer(2)] >>> f.is_symmetric() True >>> f.to_symmetric_function() 5*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + 2*m[2, 2, 1] + m[3, 1, 1] + m[3, 2] >>> s = SymmetricFunctions(QQ).s() >>> s(f.to_symmetric_function()) s[3, 2]
It is also possible to convert a symmetric function to a quasi-symmetric function:
sage: m = SymmetricFunctions(QQ).m() sage: M( m[3,1,1] ) M[1, 1, 3] + M[1, 3, 1] + M[3, 1, 1] sage: F( s[2,2,1] ) F[1, 1, 2, 1] + F[1, 2, 1, 1] + F[1, 2, 2] + F[2, 1, 2] + F[2, 2, 1]
>>> from sage.all import * >>> m = SymmetricFunctions(QQ).m() >>> M( m[Integer(3),Integer(1),Integer(1)] ) M[1, 1, 3] + M[1, 3, 1] + M[3, 1, 1] >>> F( s[Integer(2),Integer(2),Integer(1)] ) F[1, 1, 2, 1] + F[1, 2, 1, 1] + F[1, 2, 2] + F[2, 1, 2] + F[2, 2, 1]
It is possible to experiment with the quasi-symmetric function expansion of other bases, but it is important that the base ring be the same for both algebras.
sage: R = QQ['t'] sage: Qp = SymmetricFunctions(R).hall_littlewood().Qp() sage: QSymt = QuasiSymmetricFunctions(R) sage: Ft = QSymt.F() sage: Ft( Qp[2,2] ) F[1, 2, 1] + t*F[1, 3] + (t+1)*F[2, 2] + t*F[3, 1] + t^2*F[4]
>>> from sage.all import * >>> R = QQ['t'] >>> Qp = SymmetricFunctions(R).hall_littlewood().Qp() >>> QSymt = QuasiSymmetricFunctions(R) >>> Ft = QSymt.F() >>> Ft( Qp[Integer(2),Integer(2)] ) F[1, 2, 1] + t*F[1, 3] + (t+1)*F[2, 2] + t*F[3, 1] + t^2*F[4]
sage: K = QQ['q','t'].fraction_field() sage: Ht = SymmetricFunctions(K).macdonald().Ht() sage: Fqt = QuasiSymmetricFunctions(Ht.base_ring()).F() sage: Fqt(Ht[2,1]) q*t*F[1, 1, 1] + (q+t)*F[1, 2] + (q+t)*F[2, 1] + F[3]
>>> from sage.all import * >>> K = QQ['q','t'].fraction_field() >>> Ht = SymmetricFunctions(K).macdonald().Ht() >>> Fqt = QuasiSymmetricFunctions(Ht.base_ring()).F() >>> Fqt(Ht[Integer(2),Integer(1)]) q*t*F[1, 1, 1] + (q+t)*F[1, 2] + (q+t)*F[2, 1] + F[3]
The following will raise an error because the base ring of
F
is not equal to the base ring ofHt
:sage: F(Ht[2,1]) Traceback (most recent call last): ... TypeError: do not know how to make x (= McdHt[2, 1]) an element of self (=Quasisymmetric functions over the Rational Field in the Fundamental basis)
>>> from sage.all import * >>> F(Ht[Integer(2),Integer(1)]) Traceback (most recent call last): ... TypeError: do not know how to make x (= McdHt[2, 1]) an element of self (=Quasisymmetric functions over the Rational Field in the Fundamental basis)
The map to the ring of polynomials
The quasi-symmetric functions can be seen as an inverse limit of a subring of a polynomial ring as the number of variables increases. Indeed, there exists a projection from the quasi-symmetric functions onto the polynomial ring \(R[x_1, x_2, \ldots, x_n]\). This projection is defined by sending the variables \(x_{n+1}, x_{n+2}, \cdots\) to \(0\), while the remaining \(n\) variables remain fixed. Note that this projection sends \(M_I\) to \(0\) if the length of the composition \(I\) is higher than \(n\).
sage: M[1,3,1].expand(4) x0*x1^3*x2 + x0*x1^3*x3 + x0*x2^3*x3 + x1*x2^3*x3 sage: F[1,3,1].expand(4) x0*x1^3*x2 + x0*x1^3*x3 + x0*x1^2*x2*x3 + x0*x1*x2^2*x3 + x0*x2^3*x3 + x1*x2^3*x3 sage: M[1,3,1].expand(2) 0
>>> from sage.all import * >>> M[Integer(1),Integer(3),Integer(1)].expand(Integer(4)) x0*x1^3*x2 + x0*x1^3*x3 + x0*x2^3*x3 + x1*x2^3*x3 >>> F[Integer(1),Integer(3),Integer(1)].expand(Integer(4)) x0*x1^3*x2 + x0*x1^3*x3 + x0*x1^2*x2*x3 + x0*x1*x2^2*x3 + x0*x2^3*x3 + x1*x2^3*x3 >>> M[Integer(1),Integer(3),Integer(1)].expand(Integer(2)) 0
- class Bases(parent_with_realization)[source]¶
Bases:
Category_realization_of_parent
Category of bases of quasi-symmetric functions.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: QSym.Bases() Category of bases of Quasisymmetric functions over the Rational Field
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> QSym.Bases() Category of bases of Quasisymmetric functions over the Rational Field
- class ElementMethods[source]¶
Bases:
object
Methods common to all elements of
QuasiSymmetricFunctions
.- adams_operator(n)[source]¶
Return the image of the quasi-symmetric function
self
under the \(n\)-th Adams operator.The \(n\)-th Adams operator \(\mathbf{f}_n\) is defined to be the map from the \(R\)-algebra of quasi-symmetric functions to itself that sends every symmetric function \(P(x_1, x_2, x_3, \ldots)\) to \(P(x_1^n, x_2^n, x_3^n, \ldots)\). This operator \(\mathbf{f}_n\) is a Hopf algebra endomorphism, and satisfies
\[f_n M_{(i_1, i_2, i_3, \ldots)} = M_{(ni_1, ni_2, ni_3, \ldots)}\]for every composition \((i_1, i_2, i_3, \ldots)\) (where \(M\) means the monomial basis).
The \(n\)-th Adams operator is also called the \(n\)-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 \(n\)-th Adams operator is the \(n\)-th Adams operator of the \(\Lambda\)-ring of quasi-symmetric functions over the integers.
The restriction of the \(n\)-th Adams operator to the subring formed by all symmetric functions is, not unexpectedly, the \(n\)-th Adams operator of the ring of symmetric functions.
See also
INPUT:
n
– positive integer
OUTPUT:
The result of applying the \(n\)-th Adams operator (on the ring of quasi-symmetric functions) to
self
.EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: M = QSym.M() sage: F = QSym.F() sage: M[3,2].adams_operator(2) M[6, 4] sage: (M[2,1] - 2*M[3]).adams_operator(4) M[8, 4] - 2*M[12] sage: M([]).adams_operator(3) M[] sage: F[1,1].adams_operator(2) F[1, 1, 1, 1] - F[1, 1, 2] - F[2, 1, 1] + F[2, 2]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> M = QSym.M() >>> F = QSym.F() >>> M[Integer(3),Integer(2)].adams_operator(Integer(2)) M[6, 4] >>> (M[Integer(2),Integer(1)] - Integer(2)*M[Integer(3)]).adams_operator(Integer(4)) M[8, 4] - 2*M[12] >>> M([]).adams_operator(Integer(3)) M[] >>> F[Integer(1),Integer(1)].adams_operator(Integer(2)) F[1, 1, 1, 1] - F[1, 1, 2] - F[2, 1, 1] + F[2, 2]
The Adams endomorphisms are multiplicative:
sage: all( all( M(I).adams_operator(3) * M(J).adams_operator(3) ....: == (M(I) * M(J)).adams_operator(3) ....: for I in Compositions(3) ) ....: for J in Compositions(2) ) True
>>> from sage.all import * >>> all( all( M(I).adams_operator(Integer(3)) * M(J).adams_operator(Integer(3)) ... == (M(I) * M(J)).adams_operator(Integer(3)) ... for I in Compositions(Integer(3)) ) ... for J in Compositions(Integer(2)) ) True
Being Hopf algebra endomorphisms, the Adams operators commute with the antipode:
sage: all( M(I).adams_operator(4).antipode() ....: == M(I).antipode().adams_operator(4) ....: for I in Compositions(3) ) True
>>> from sage.all import * >>> all( M(I).adams_operator(Integer(4)).antipode() ... == M(I).antipode().adams_operator(Integer(4)) ... for I in Compositions(Integer(3)) ) True
The restriction of the Adams operators to the subring of symmetric functions are the Adams operators of the latter:
sage: e = SymmetricFunctions(ZZ).e() sage: all( M(e(lam)).adams_operator(3) ....: == M(e(lam).adams_operator(3)) ....: for lam in Partitions(3) ) True
>>> from sage.all import * >>> e = SymmetricFunctions(ZZ).e() >>> all( M(e(lam)).adams_operator(Integer(3)) ... == M(e(lam).adams_operator(Integer(3))) ... for lam in Partitions(Integer(3)) ) True
- dendriform_leq(other)[source]¶
Return the result of applying the dendriform smaller-or-equal operation to the two quasi-symmetric functions
self
andother
.The dendriform smaller-or-equal operation is a binary operation, denoted by \(\preceq\) and written infix, on the ring of quasi-symmetric functions. It can be defined as a restriction of a binary operation (denoted by \(\preceq\) and written infix as well) on the ring of formal power series \(R[[x_1, x_2, x_3, \ldots]]\), which is defined as follows: If \(m\) and \(n\) are two monomials in \(x_1, x_2, x_3, \ldots\), then we let \(m \preceq n\) be the product \(mn\) if the smallest positive integer \(i\) for which \(x_i\) occurs in \(m\) is smaller or equal to the smallest positive integer \(j\) for which \(x_j\) occurs in \(n\) (this is understood to be false when \(m = 1\) and \(n \neq 1\), and true when \(n = 1\)), and we let \(m \preceq n\) be \(0\) otherwise. Having thus defined \(\preceq\) on monomials, we extend \(\preceq\) to a binary operation on \(R[[x_1, x_2, x_3, \ldots]]\) by requiring it to be continuous (in both inputs) and \(R\)-bilinear. It is easily seen that \(QSym \preceq QSym \subseteq QSym\), so that \(\preceq\) restricts to a binary operation on \(QSym\).
This operation \(\preceq\) is related to the dendriform smaller relation \(\prec\) (
dendriform_less()
). Namely, if we define a binary operation \(\succ\) on \(QSym\) by \(a \succ b = b \prec a\), then \((QSym, \preceq, \succ)\) is a dendriform \(R\)-algebra. Thus, any \(a, b \in QSym\) satisfy \(a \preceq b = ab - b \prec a\).See also
INPUT:
other
– a quasi-symmetric function over the same base ring asself
OUTPUT:
The quasi-symmetric function
self
\(\preceq\)other
, written in the basis ofself
.EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: M = QSym.M() sage: M[2, 1].dendriform_leq(M[1, 2]) 2*M[2, 1, 1, 2] + M[2, 1, 2, 1] + M[2, 1, 3] + M[2, 2, 2] + M[3, 1, 2] + M[3, 2, 1] + M[3, 3] sage: F = QSym.F() sage: F[2, 1].dendriform_leq(F[1, 2]) F[2, 1, 1, 2] + F[2, 1, 2, 1] + F[2, 1, 3] + F[2, 2, 1, 1] + 2*F[2, 2, 2] + F[2, 3, 1] + F[3, 1, 2] + F[3, 2, 1] + F[3, 3]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> M = QSym.M() >>> M[Integer(2), Integer(1)].dendriform_leq(M[Integer(1), Integer(2)]) 2*M[2, 1, 1, 2] + M[2, 1, 2, 1] + M[2, 1, 3] + M[2, 2, 2] + M[3, 1, 2] + M[3, 2, 1] + M[3, 3] >>> F = QSym.F() >>> F[Integer(2), Integer(1)].dendriform_leq(F[Integer(1), Integer(2)]) F[2, 1, 1, 2] + F[2, 1, 2, 1] + F[2, 1, 3] + F[2, 2, 1, 1] + 2*F[2, 2, 2] + F[2, 3, 1] + F[3, 1, 2] + F[3, 2, 1] + F[3, 3]
- dendriform_less(other)[source]¶
Return the result of applying the dendriform smaller operation to the two quasi-symmetric functions
self
andother
.The dendriform smaller operation is a binary operation, denoted by \(\prec\) and written infix, on the ring of quasi-symmetric functions. It can be defined as a restriction of a binary operation (denoted by \(\prec\) and written infix as well) on the ring of formal power series \(R[[x_1, x_2, x_3, \ldots]]\), which is defined as follows: If \(m\) and \(n\) are two monomials in \(x_1, x_2, x_3, \ldots\), then we let \(m \prec n\) be the product \(mn\) if the smallest positive integer \(i\) for which \(x_i\) occurs in \(m\) is smaller than the smallest positive integer \(j\) for which \(x_j\) occurs in \(n\) (this is understood to be false when \(m = 1\), and true when \(m \neq 1\) and \(n = 1\)), and we let \(m \prec n\) be \(0\) otherwise. Having thus defined \(\prec\) on monomials, we extend \(\prec\) to a binary operation on \(R[[x_1, x_2, x_3, \ldots]]\) by requiring it to be continuous (in both inputs) and \(R\)-bilinear. It is easily seen that \(QSym \prec QSym \subseteq QSym\), so that \(\prec\) restricts to a binary operation on \(QSym\).
See also
INPUT:
other
– a quasi-symmetric function over the same base ring asself
OUTPUT:
The quasi-symmetric function
self
\(\prec\)other
, written in the basis ofself
.EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: M = QSym.M() sage: M[2, 1].dendriform_less(M[1, 2]) 2*M[2, 1, 1, 2] + M[2, 1, 2, 1] + M[2, 1, 3] + M[2, 2, 2] sage: F = QSym.F() sage: F[2, 1].dendriform_less(F[1, 2]) F[1, 1, 2, 1, 1] + F[1, 1, 2, 2] + F[1, 1, 3, 1] + F[1, 2, 1, 2] + F[1, 2, 2, 1] + F[1, 2, 3] + F[2, 1, 1, 2] + F[2, 1, 2, 1] + F[2, 1, 3] + F[2, 2, 2]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> M = QSym.M() >>> M[Integer(2), Integer(1)].dendriform_less(M[Integer(1), Integer(2)]) 2*M[2, 1, 1, 2] + M[2, 1, 2, 1] + M[2, 1, 3] + M[2, 2, 2] >>> F = QSym.F() >>> F[Integer(2), Integer(1)].dendriform_less(F[Integer(1), Integer(2)]) F[1, 1, 2, 1, 1] + F[1, 1, 2, 2] + F[1, 1, 3, 1] + F[1, 2, 1, 2] + F[1, 2, 2, 1] + F[1, 2, 3] + F[2, 1, 1, 2] + F[2, 1, 2, 1] + F[2, 1, 3] + F[2, 2, 2]
The operation \(\prec\) can be used to recursively construct the dual immaculate basis: For every positive integer \(m\) and every composition \(I\), the dual immaculate function \(\operatorname{dI}_{[m, I]}\) of the composition \([m, I]\) (this composition is \(I\) with \(m\) prepended to it) is \(F_{[m]} \prec \operatorname{dI}_I\).
sage: dI = QSym.dI() sage: dI(F[2]).dendriform_less(dI[1, 2]) dI[2, 1, 2]
>>> from sage.all import * >>> dI = QSym.dI() >>> dI(F[Integer(2)]).dendriform_less(dI[Integer(1), Integer(2)]) dI[2, 1, 2]
We check with the identity element:
sage: M.one().dendriform_less(M[1,2]) 0 sage: M[1,2].dendriform_less(M.one()) M[1, 2]
>>> from sage.all import * >>> M.one().dendriform_less(M[Integer(1),Integer(2)]) 0 >>> M[Integer(1),Integer(2)].dendriform_less(M.one()) M[1, 2]
The operation \(\prec\) is not symmetric, nor if \(a \prec b \neq 0\), then \(b \prec a = 0\) (as it would be for a single monomial):
sage: M[1,2,1].dendriform_less(M[1,2]) M[1, 1, 2, 1, 2] + 2*M[1, 1, 2, 2, 1] + M[1, 1, 2, 3] + M[1, 1, 4, 1] + 2*M[1, 2, 1, 1, 2] + M[1, 2, 1, 2, 1] + M[1, 2, 1, 3] + M[1, 2, 2, 2] + M[1, 3, 1, 2] + M[1, 3, 2, 1] + M[1, 3, 3] sage: M[1,2].dendriform_less(M[1,2,1]) M[1, 1, 2, 1, 2] + 2*M[1, 1, 2, 2, 1] + M[1, 1, 2, 3] + M[1, 1, 4, 1] + M[1, 2, 1, 2, 1] + M[1, 3, 2, 1]
>>> from sage.all import * >>> M[Integer(1),Integer(2),Integer(1)].dendriform_less(M[Integer(1),Integer(2)]) M[1, 1, 2, 1, 2] + 2*M[1, 1, 2, 2, 1] + M[1, 1, 2, 3] + M[1, 1, 4, 1] + 2*M[1, 2, 1, 1, 2] + M[1, 2, 1, 2, 1] + M[1, 2, 1, 3] + M[1, 2, 2, 2] + M[1, 3, 1, 2] + M[1, 3, 2, 1] + M[1, 3, 3] >>> M[Integer(1),Integer(2)].dendriform_less(M[Integer(1),Integer(2),Integer(1)]) M[1, 1, 2, 1, 2] + 2*M[1, 1, 2, 2, 1] + M[1, 1, 2, 3] + M[1, 1, 4, 1] + M[1, 2, 1, 2, 1] + M[1, 3, 2, 1]
- expand(n, alphabet='x')[source]¶
Expand the quasi-symmetric function into
n
variables in an alphabet, which by default is'x'
.INPUT:
n
– nonnegative integer; the number of variables in the expansionalphabet
– (default:'x'
) the alphabet in whichself
is to be expanded
OUTPUT: an expansion of
self
into then
variables specified byalphabet
EXAMPLES:
sage: F = QuasiSymmetricFunctions(QQ).Fundamental() sage: F[3].expand(3) x0^3 + x0^2*x1 + x0*x1^2 + x1^3 + x0^2*x2 + x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x2^3 sage: F[2,1].expand(3) x0^2*x1 + x0^2*x2 + x0*x1*x2 + x1^2*x2
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(QQ).Fundamental() >>> F[Integer(3)].expand(Integer(3)) x0^3 + x0^2*x1 + x0*x1^2 + x1^3 + x0^2*x2 + x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x2^3 >>> F[Integer(2),Integer(1)].expand(Integer(3)) x0^2*x1 + x0^2*x2 + x0*x1*x2 + x1^2*x2
One can use a different set of variable by adding an optional argument
alphabet=...
sage: F = QuasiSymmetricFunctions(QQ).Fundamental() sage: F[3].expand(2,alphabet='y') y0^3 + y0^2*y1 + y0*y1^2 + y1^3
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(QQ).Fundamental() >>> F[Integer(3)].expand(Integer(2),alphabet='y') y0^3 + y0^2*y1 + y0*y1^2 + y1^3
- frobenius(*args, **kwds)[source]¶
Deprecated: Use
adams_operator()
instead. See Issue #36396 for details.
- internal_coproduct()[source]¶
Return the inner coproduct of
self
in the basis ofself
.The inner coproduct (also known as the Kronecker coproduct, or as the second comultiplication on the \(R\)-algebra of quasi-symmetric functions) is an \(R\)-algebra homomorphism \(\Delta^{\times}\) from the \(R\)-algebra of quasi-symmetric functions to the tensor square (over \(R\)) of quasi-symmetric functions. It can be defined in the following two ways:
If \(I\) is a composition, then a \((0, I)\)-matrix will mean a matrix whose entries are nonnegative integers such that no row and no column of this matrix is zero, and such that if all the nonzero entries of the matrix are read (row by row, starting at the topmost row, reading every row from left to right), then the reading word obtained is \(I\). If \(A\) is a \((0, I)\)-matrix, then \(\mathrm{row}(A)\) will denote the vector of row sums of \(A\) (regarded as a composition), and \(\mathrm{column}(A)\) will denote the vector of column sums of \(A\) (regarded as a composition).
For every composition \(I\), the internal coproduct \(\Delta^{\times}(M_I)\) of the \(I\)-th monomial quasisymmetric function \(M_I\) is the sum
\[\sum_{A \hbox{ is a } (0, I) \text{-matrix}} M_{\mathrm{row}(A)} \otimes M_{\mathrm{column}(A)}.\]See Section 11.39 of [HazWitt1].
For every permutation \(w\), let \(C(w)\) denote the descent composition of \(w\). Then, for any composition \(I\) of size \(n\), the internal coproduct \(\Delta^{\times}(F_I)\) of the \(I\)-th fundamental quasisymmetric function \(F_I\) is the sum
\[\begin{split}\sum_{\substack{\sigma \in S_n,\\ \tau \in S_n,\\ \tau \sigma = \pi}} F_{C(\sigma)} \otimes F_{C(\tau)},\end{split}\]where \(\pi\) is any permutation in \(S_n\) having descent composition \(I\) and where permutations act from the left and multiply accordingly, so \(\tau \sigma\) means first applying \(\sigma\) and then \(\tau\). See Theorem 4.23 in [Mal1993], but beware of the notations which are apparently different from those in [HazWitt1].
The restriction of the internal coproduct to the \(R\)-algebra of symmetric functions is the well-known internal coproduct on the symmetric functions.
The method
kronecker_coproduct()
is a synonym of this one.EXAMPLES:
Let us compute the internal coproduct of \(M_{21}\) (which is short for \(M_{[2, 1]}\)). The \((0, [2,1])\)-matrices are
\[\begin{split}\begin{bmatrix} 2 & 1 \end{bmatrix}, \begin{bmatrix} 2 \\ 1 \end{bmatrix}, \begin{bmatrix} 2 & 0 \\ 0 & 1 \end{bmatrix}, \hbox{ and } \begin{bmatrix} 0 & 2 \\ 1 & 0 \end{bmatrix}\end{split}\]so
\[\Delta^\times(M_{21}) = M_{3} \otimes M_{21} + M_{21} \otimes M_3 + M_{21} \otimes M_{21} + M_{21} \otimes M_{12}.\]This is confirmed by the following Sage computation (incidentally demonstrating the non-cocommutativity of the internal coproduct):
sage: M = QuasiSymmetricFunctions(ZZ).M() sage: a = M([2,1]) sage: a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(ZZ).M() >>> a = M([Integer(2),Integer(1)]) >>> a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
Further examples:
sage: all( M([i]).internal_coproduct() == tensor([M([i]), M([i])]) ....: for i in range(1, 4) ) True sage: M([1, 2]).internal_coproduct() M[1, 2] # M[1, 2] + M[1, 2] # M[2, 1] + M[1, 2] # M[3] + M[3] # M[1, 2]
>>> from sage.all import * >>> all( M([i]).internal_coproduct() == tensor([M([i]), M([i])]) ... for i in range(Integer(1), Integer(4)) ) True >>> M([Integer(1), Integer(2)]).internal_coproduct() M[1, 2] # M[1, 2] + M[1, 2] # M[2, 1] + M[1, 2] # M[3] + M[3] # M[1, 2]
The definition of \(\Delta^{\times}(M_I)\) in terms of \((0, I)\)-matrices is not suitable for computation in cases where the length of \(I\) is large, but we can use it as a doctest. Here is a naive implementation:
sage: def naive_internal_coproduct_on_M(I): ....: # INPUT: composition I ....: # (not quasi-symmetric function) ....: # OUTPUT: interior coproduct of M_I ....: M = QuasiSymmetricFunctions(ZZ).M() ....: M2 = M.tensor(M) ....: res = M2.zero() ....: l = len(I) ....: n = I.size() ....: for S in Subsets(range(l**2), l): ....: M_list = sorted(S) ....: row_M = [sum([I[M_list.index(l * i + j)] ....: for j in range(l) if ....: l * i + j in S]) ....: for i in range(l)] ....: col_M = [sum([I[M_list.index(l * i + j)] ....: for i in range(l) if ....: l * i + j in S]) ....: for j in range(l)] ....: if 0 in row_M: ....: first_zero = row_M.index(0) ....: row_M = row_M[:first_zero] ....: if sum(row_M) != n: ....: continue ....: if 0 in col_M: ....: first_zero = col_M.index(0) ....: col_M = col_M[:first_zero] ....: if sum(col_M) != n: ....: continue ....: res += tensor([M(Compositions(n)(row_M)), ....: M(Compositions(n)(col_M))]) ....: return res sage: all( naive_internal_coproduct_on_M(I) ....: == M(I).internal_coproduct() ....: for I in Compositions(3) ) True
>>> from sage.all import * >>> def naive_internal_coproduct_on_M(I): ... # INPUT: composition I ... # (not quasi-symmetric function) ... # OUTPUT: interior coproduct of M_I ... M = QuasiSymmetricFunctions(ZZ).M() ... M2 = M.tensor(M) ... res = M2.zero() ... l = len(I) ... n = I.size() ... for S in Subsets(range(l**Integer(2)), l): ... M_list = sorted(S) ... row_M = [sum([I[M_list.index(l * i + j)] ... for j in range(l) if ... l * i + j in S]) ... for i in range(l)] ... col_M = [sum([I[M_list.index(l * i + j)] ... for i in range(l) if ... l * i + j in S]) ... for j in range(l)] ... if Integer(0) in row_M: ... first_zero = row_M.index(Integer(0)) ... row_M = row_M[:first_zero] ... if sum(row_M) != n: ... continue ... if Integer(0) in col_M: ... first_zero = col_M.index(Integer(0)) ... col_M = col_M[:first_zero] ... if sum(col_M) != n: ... continue ... res += tensor([M(Compositions(n)(row_M)), ... M(Compositions(n)(col_M))]) ... return res >>> all( naive_internal_coproduct_on_M(I) ... == M(I).internal_coproduct() ... for I in Compositions(Integer(3)) ) True
Todo
Implement this directly on the monomial basis maybe? The \((0, I)\)-matrices are a pain to generate from their definition, but maybe there is a good algorithm. If so, the above “further examples” should be moved to the M-method.
- is_symmetric()[source]¶
Return
True
ifself
is an element of the symmetric functions.This is being tested by looking at the expansion in the Monomial basis and checking if the coefficients are the same if the indexing compositions are permutations of each other.
OUTPUT:
True
ifself
is symmetric.False
ifself
is not symmetric.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: F = QSym.Fundamental() sage: (F[3,2] + F[2,3]).is_symmetric() False sage: (F[1, 1, 1, 2] + F[1, 1, 3] + F[1, 3, 1] + F[2, 1, 1, 1] + F[3, 1, 1]).is_symmetric() True sage: F([]).is_symmetric() True
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> F = QSym.Fundamental() >>> (F[Integer(3),Integer(2)] + F[Integer(2),Integer(3)]).is_symmetric() False >>> (F[Integer(1), Integer(1), Integer(1), Integer(2)] + F[Integer(1), Integer(1), Integer(3)] + F[Integer(1), Integer(3), Integer(1)] + F[Integer(2), Integer(1), Integer(1), Integer(1)] + F[Integer(3), Integer(1), Integer(1)]).is_symmetric() True >>> F([]).is_symmetric() True
- kronecker_coproduct()[source]¶
Return the inner coproduct of
self
in the basis ofself
.The inner coproduct (also known as the Kronecker coproduct, or as the second comultiplication on the \(R\)-algebra of quasi-symmetric functions) is an \(R\)-algebra homomorphism \(\Delta^{\times}\) from the \(R\)-algebra of quasi-symmetric functions to the tensor square (over \(R\)) of quasi-symmetric functions. It can be defined in the following two ways:
If \(I\) is a composition, then a \((0, I)\)-matrix will mean a matrix whose entries are nonnegative integers such that no row and no column of this matrix is zero, and such that if all the nonzero entries of the matrix are read (row by row, starting at the topmost row, reading every row from left to right), then the reading word obtained is \(I\). If \(A\) is a \((0, I)\)-matrix, then \(\mathrm{row}(A)\) will denote the vector of row sums of \(A\) (regarded as a composition), and \(\mathrm{column}(A)\) will denote the vector of column sums of \(A\) (regarded as a composition).
For every composition \(I\), the internal coproduct \(\Delta^{\times}(M_I)\) of the \(I\)-th monomial quasisymmetric function \(M_I\) is the sum
\[\sum_{A \hbox{ is a } (0, I) \text{-matrix}} M_{\mathrm{row}(A)} \otimes M_{\mathrm{column}(A)}.\]See Section 11.39 of [HazWitt1].
For every permutation \(w\), let \(C(w)\) denote the descent composition of \(w\). Then, for any composition \(I\) of size \(n\), the internal coproduct \(\Delta^{\times}(F_I)\) of the \(I\)-th fundamental quasisymmetric function \(F_I\) is the sum
\[\begin{split}\sum_{\substack{\sigma \in S_n,\\ \tau \in S_n,\\ \tau \sigma = \pi}} F_{C(\sigma)} \otimes F_{C(\tau)},\end{split}\]where \(\pi\) is any permutation in \(S_n\) having descent composition \(I\) and where permutations act from the left and multiply accordingly, so \(\tau \sigma\) means first applying \(\sigma\) and then \(\tau\). See Theorem 4.23 in [Mal1993], but beware of the notations which are apparently different from those in [HazWitt1].
The restriction of the internal coproduct to the \(R\)-algebra of symmetric functions is the well-known internal coproduct on the symmetric functions.
The method
kronecker_coproduct()
is a synonym of this one.EXAMPLES:
Let us compute the internal coproduct of \(M_{21}\) (which is short for \(M_{[2, 1]}\)). The \((0, [2,1])\)-matrices are
\[\begin{split}\begin{bmatrix} 2 & 1 \end{bmatrix}, \begin{bmatrix} 2 \\ 1 \end{bmatrix}, \begin{bmatrix} 2 & 0 \\ 0 & 1 \end{bmatrix}, \hbox{ and } \begin{bmatrix} 0 & 2 \\ 1 & 0 \end{bmatrix}\end{split}\]so
\[\Delta^\times(M_{21}) = M_{3} \otimes M_{21} + M_{21} \otimes M_3 + M_{21} \otimes M_{21} + M_{21} \otimes M_{12}.\]This is confirmed by the following Sage computation (incidentally demonstrating the non-cocommutativity of the internal coproduct):
sage: M = QuasiSymmetricFunctions(ZZ).M() sage: a = M([2,1]) sage: a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(ZZ).M() >>> a = M([Integer(2),Integer(1)]) >>> a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
Further examples:
sage: all( M([i]).internal_coproduct() == tensor([M([i]), M([i])]) ....: for i in range(1, 4) ) True sage: M([1, 2]).internal_coproduct() M[1, 2] # M[1, 2] + M[1, 2] # M[2, 1] + M[1, 2] # M[3] + M[3] # M[1, 2]
>>> from sage.all import * >>> all( M([i]).internal_coproduct() == tensor([M([i]), M([i])]) ... for i in range(Integer(1), Integer(4)) ) True >>> M([Integer(1), Integer(2)]).internal_coproduct() M[1, 2] # M[1, 2] + M[1, 2] # M[2, 1] + M[1, 2] # M[3] + M[3] # M[1, 2]
The definition of \(\Delta^{\times}(M_I)\) in terms of \((0, I)\)-matrices is not suitable for computation in cases where the length of \(I\) is large, but we can use it as a doctest. Here is a naive implementation:
sage: def naive_internal_coproduct_on_M(I): ....: # INPUT: composition I ....: # (not quasi-symmetric function) ....: # OUTPUT: interior coproduct of M_I ....: M = QuasiSymmetricFunctions(ZZ).M() ....: M2 = M.tensor(M) ....: res = M2.zero() ....: l = len(I) ....: n = I.size() ....: for S in Subsets(range(l**2), l): ....: M_list = sorted(S) ....: row_M = [sum([I[M_list.index(l * i + j)] ....: for j in range(l) if ....: l * i + j in S]) ....: for i in range(l)] ....: col_M = [sum([I[M_list.index(l * i + j)] ....: for i in range(l) if ....: l * i + j in S]) ....: for j in range(l)] ....: if 0 in row_M: ....: first_zero = row_M.index(0) ....: row_M = row_M[:first_zero] ....: if sum(row_M) != n: ....: continue ....: if 0 in col_M: ....: first_zero = col_M.index(0) ....: col_M = col_M[:first_zero] ....: if sum(col_M) != n: ....: continue ....: res += tensor([M(Compositions(n)(row_M)), ....: M(Compositions(n)(col_M))]) ....: return res sage: all( naive_internal_coproduct_on_M(I) ....: == M(I).internal_coproduct() ....: for I in Compositions(3) ) True
>>> from sage.all import * >>> def naive_internal_coproduct_on_M(I): ... # INPUT: composition I ... # (not quasi-symmetric function) ... # OUTPUT: interior coproduct of M_I ... M = QuasiSymmetricFunctions(ZZ).M() ... M2 = M.tensor(M) ... res = M2.zero() ... l = len(I) ... n = I.size() ... for S in Subsets(range(l**Integer(2)), l): ... M_list = sorted(S) ... row_M = [sum([I[M_list.index(l * i + j)] ... for j in range(l) if ... l * i + j in S]) ... for i in range(l)] ... col_M = [sum([I[M_list.index(l * i + j)] ... for i in range(l) if ... l * i + j in S]) ... for j in range(l)] ... if Integer(0) in row_M: ... first_zero = row_M.index(Integer(0)) ... row_M = row_M[:first_zero] ... if sum(row_M) != n: ... continue ... if Integer(0) in col_M: ... first_zero = col_M.index(Integer(0)) ... col_M = col_M[:first_zero] ... if sum(col_M) != n: ... continue ... res += tensor([M(Compositions(n)(row_M)), ... M(Compositions(n)(col_M))]) ... return res >>> all( naive_internal_coproduct_on_M(I) ... == M(I).internal_coproduct() ... for I in Compositions(Integer(3)) ) True
Todo
Implement this directly on the monomial basis maybe? The \((0, I)\)-matrices are a pain to generate from their definition, but maybe there is a good algorithm. If so, the above “further examples” should be moved to the M-method.
- omega_involution()[source]¶
Return the image of the quasisymmetric function
self
under the omega involution.The omega involution is defined as the linear map \(QSym \to QSym\) which, for every composition \(I\), sends the fundamental quasisymmetric function \(F_I\) to \(F_{I^t}\), where \(I^t\) denotes the conjugate (
conjugate()
) of the composition \(I\). This map is commonly denoted by \(\omega\). It is an algebra homomorphism and a coalgebra antihomomorphism; it also is an involution and an automorphism of the graded vector space \(QSym\). Also, every composition \(I\) satisfies\[\omega(M_I) = (-1)^{|I|-\ell(I)} \sum M_J,\]where the sum ranges over all compositions \(J\) of \(|I|\) which are coarser than the reversed composition \(I^r\) of \(I\). Here, \(\ell(I)\) denotes the length of the composition \(I\) (that is, the number of parts of \(I\)).
If \(f\) is a homogeneous element of \(NCSF\) of degree \(n\), then
\[\omega(f) = (-1)^n S(f),\]where \(S\) denotes the antipode of \(QSym\).
The restriction of \(\omega\) to the ring of symmetric functions (which is a subring of \(QSym\)) is precisely the omega involution (
omega()
) of said ring.The omega involution on \(QSym\) is adjoint to the omega involution on \(NCSF\) by the standard adjunction between \(NCSF\) and \(QSym\).
The omega involution has been denoted by \(\omega\) in [LMvW13], section 3.6.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: F = QSym.F() sage: F[3,2].omega_involution() F[1, 2, 1, 1] sage: F[6,3].omega_involution() F[1, 1, 2, 1, 1, 1, 1, 1] sage: (F[9,1] - F[8,2] + 2*F[2,4] - 3*F[3] + 4*F[[]]).omega_involution() 4*F[] - 3*F[1, 1, 1] + 2*F[1, 1, 1, 2, 1] - F[1, 2, 1, 1, 1, 1, 1, 1, 1] + F[2, 1, 1, 1, 1, 1, 1, 1, 1] sage: (F[3,3] - 2*F[2]).omega_involution() -2*F[1, 1] + F[1, 1, 2, 1, 1] sage: F([2,1,1]).omega_involution() F[3, 1] sage: M = QSym.M() sage: M([2,1]).omega_involution() -M[1, 2] - M[3] sage: M.zero().omega_involution() 0
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> F = QSym.F() >>> F[Integer(3),Integer(2)].omega_involution() F[1, 2, 1, 1] >>> F[Integer(6),Integer(3)].omega_involution() F[1, 1, 2, 1, 1, 1, 1, 1] >>> (F[Integer(9),Integer(1)] - F[Integer(8),Integer(2)] + Integer(2)*F[Integer(2),Integer(4)] - Integer(3)*F[Integer(3)] + Integer(4)*F[[]]).omega_involution() 4*F[] - 3*F[1, 1, 1] + 2*F[1, 1, 1, 2, 1] - F[1, 2, 1, 1, 1, 1, 1, 1, 1] + F[2, 1, 1, 1, 1, 1, 1, 1, 1] >>> (F[Integer(3),Integer(3)] - Integer(2)*F[Integer(2)]).omega_involution() -2*F[1, 1] + F[1, 1, 2, 1, 1] >>> F([Integer(2),Integer(1),Integer(1)]).omega_involution() F[3, 1] >>> M = QSym.M() >>> M([Integer(2),Integer(1)]).omega_involution() -M[1, 2] - M[3] >>> M.zero().omega_involution() 0
Testing the fact that the restriction of \(\omega\) to \(Sym\) is the omega automorphism of \(Sym\):
sage: Sym = SymmetricFunctions(ZZ) sage: e = Sym.e() sage: all( F(e[lam]).omega_involution() == F(e[lam].omega()) ....: for lam in Partitions(4) ) True
>>> from sage.all import * >>> Sym = SymmetricFunctions(ZZ) >>> e = Sym.e() >>> all( F(e[lam]).omega_involution() == F(e[lam].omega()) ... for lam in Partitions(Integer(4)) ) True
- psi_involution()[source]¶
Return the image of the quasisymmetric function
self
under the involution \(\psi\).The involution \(\psi\) is defined as the linear map \(QSym \to QSym\) which, for every composition \(I\), sends the fundamental quasisymmetric function \(F_I\) to \(F_{I^c}\), where \(I^c\) denotes the complement of the composition \(I\). The map \(\psi\) is an involution and a graded Hopf algebra automorphism of \(QSym\). Its restriction to the ring of symmetric functions coincides with the omega automorphism of the latter ring.
The involution \(\psi\) of \(QSym\) is adjoint to the involution \(\psi\) of \(NCSF\) by the standard adjunction between \(NCSF\) and \(QSym\).
The involution \(\psi\) has been denoted by \(\psi\) in [LMvW13], section 3.6.
See also
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: F = QSym.F() sage: F[3,2].psi_involution() F[1, 1, 2, 1] sage: F[6,3].psi_involution() F[1, 1, 1, 1, 1, 2, 1, 1] sage: (F[9,1] - F[8,2] + 2*F[2,4] - 3*F[3] + 4*F[[]]).psi_involution() 4*F[] - 3*F[1, 1, 1] + F[1, 1, 1, 1, 1, 1, 1, 1, 2] - F[1, 1, 1, 1, 1, 1, 1, 2, 1] + 2*F[1, 2, 1, 1, 1] sage: (F[3,3] - 2*F[2]).psi_involution() -2*F[1, 1] + F[1, 1, 2, 1, 1] sage: F([2,1,1]).psi_involution() F[1, 3] sage: M = QSym.M() sage: M([2,1]).psi_involution() -M[2, 1] - M[3] sage: M.zero().psi_involution() 0
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> F = QSym.F() >>> F[Integer(3),Integer(2)].psi_involution() F[1, 1, 2, 1] >>> F[Integer(6),Integer(3)].psi_involution() F[1, 1, 1, 1, 1, 2, 1, 1] >>> (F[Integer(9),Integer(1)] - F[Integer(8),Integer(2)] + Integer(2)*F[Integer(2),Integer(4)] - Integer(3)*F[Integer(3)] + Integer(4)*F[[]]).psi_involution() 4*F[] - 3*F[1, 1, 1] + F[1, 1, 1, 1, 1, 1, 1, 1, 2] - F[1, 1, 1, 1, 1, 1, 1, 2, 1] + 2*F[1, 2, 1, 1, 1] >>> (F[Integer(3),Integer(3)] - Integer(2)*F[Integer(2)]).psi_involution() -2*F[1, 1] + F[1, 1, 2, 1, 1] >>> F([Integer(2),Integer(1),Integer(1)]).psi_involution() F[1, 3] >>> M = QSym.M() >>> M([Integer(2),Integer(1)]).psi_involution() -M[2, 1] - M[3] >>> M.zero().psi_involution() 0
The involution \(\psi\) commutes with the antipode:
sage: all( F(I).psi_involution().antipode() ....: == F(I).antipode().psi_involution() ....: for I in Compositions(4) ) True
>>> from sage.all import * >>> all( F(I).psi_involution().antipode() ... == F(I).antipode().psi_involution() ... for I in Compositions(Integer(4)) ) True
Testing the fact that the restriction of \(\psi\) to \(Sym\) is the omega automorphism of \(Sym\):
sage: Sym = SymmetricFunctions(ZZ) sage: e = Sym.e() sage: all( F(e[lam]).psi_involution() == F(e[lam].omega()) ....: for lam in Partitions(4) ) True
>>> from sage.all import * >>> Sym = SymmetricFunctions(ZZ) >>> e = Sym.e() >>> all( F(e[lam]).psi_involution() == F(e[lam].omega()) ... for lam in Partitions(Integer(4)) ) True
- star_involution()[source]¶
Return the image of the quasisymmetric function
self
under the star involution.The star involution is defined as the linear map \(QSym \to QSym\) which, for every composition \(I\), sends the monomial quasisymmetric function \(M_I\) to \(M_{I^r}\). Here, if \(I\) is a composition, we denote by \(I^r\) the reversed composition of \(I\). Denoting by \(f^{\ast}\) the image of an element \(f \in QSym\) under the star involution, it can be shown that every composition \(I\) satisfies
\[(M_I)^{\ast} = M_{I^r}, \quad (F_I)^{\ast} = F_{I^r},\]where \(F_I\) denotes the fundamental quasisymmetric function corresponding to the composition \(I\). The star involution is an involution, an algebra automorphism and a coalgebra anti-automorphism of \(QSym\). It also is an automorphism of the graded vector space \(QSym\), and is the identity on the subspace \(Sym\) of \(QSym\). It is adjoint to the star involution on \(NCSF\) by the standard adjunction between \(NCSF\) and \(QSym\).
The star involution has been denoted by \(\rho\) in [LMvW13], section 3.6.
See also
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: M = QSym.M() sage: M[3,2].star_involution() M[2, 3] sage: M[6,3].star_involution() M[3, 6] sage: (M[9,1] - M[6,2] + 2*M[6,4] - 3*M[3] + 4*M[[]]).star_involution() 4*M[] + M[1, 9] - M[2, 6] - 3*M[3] + 2*M[4, 6] sage: (M[3,3] - 2*M[2]).star_involution() -2*M[2] + M[3, 3] sage: M([4,2]).star_involution() M[2, 4] sage: dI = QSym.dI() sage: dI([1,2]).star_involution() -dI[1, 2] + dI[2, 1] sage: dI.zero().star_involution() 0
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> M = QSym.M() >>> M[Integer(3),Integer(2)].star_involution() M[2, 3] >>> M[Integer(6),Integer(3)].star_involution() M[3, 6] >>> (M[Integer(9),Integer(1)] - M[Integer(6),Integer(2)] + Integer(2)*M[Integer(6),Integer(4)] - Integer(3)*M[Integer(3)] + Integer(4)*M[[]]).star_involution() 4*M[] + M[1, 9] - M[2, 6] - 3*M[3] + 2*M[4, 6] >>> (M[Integer(3),Integer(3)] - Integer(2)*M[Integer(2)]).star_involution() -2*M[2] + M[3, 3] >>> M([Integer(4),Integer(2)]).star_involution() M[2, 4] >>> dI = QSym.dI() >>> dI([Integer(1),Integer(2)]).star_involution() -dI[1, 2] + dI[2, 1] >>> dI.zero().star_involution() 0
The star involution commutes with the antipode:
sage: all( M(I).star_involution().antipode() ....: == M(I).antipode().star_involution() ....: for I in Compositions(4) ) True
>>> from sage.all import * >>> all( M(I).star_involution().antipode() ... == M(I).antipode().star_involution() ... for I in Compositions(Integer(4)) ) True
The star involution is the identity on \(Sym\):
sage: Sym = SymmetricFunctions(ZZ) sage: e = Sym.e() sage: all( M(e(lam)).star_involution() == M(e(lam)) ....: for lam in Partitions(4) ) True
>>> from sage.all import * >>> Sym = SymmetricFunctions(ZZ) >>> e = Sym.e() >>> all( M(e(lam)).star_involution() == M(e(lam)) ... for lam in Partitions(Integer(4)) ) True
- to_symmetric_function()[source]¶
Convert a quasi-symmetric function to a symmetric function.
OUTPUT:
If
self
is a symmetric function, then return the expansion in the monomial basis. Otherwise raise an error.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: F = QSym.Fundamental() sage: (F[3,2] + F[2,3]).to_symmetric_function() Traceback (most recent call last): ... ValueError: F[2, 3] + F[3, 2] is not a symmetric function sage: m = SymmetricFunctions(QQ).m() sage: s = SymmetricFunctions(QQ).s() sage: F(s[3,1,1]).to_symmetric_function() 6*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + m[2, 2, 1] + m[3, 1, 1] sage: m(s[3,1,1]) 6*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + m[2, 2, 1] + m[3, 1, 1]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> F = QSym.Fundamental() >>> (F[Integer(3),Integer(2)] + F[Integer(2),Integer(3)]).to_symmetric_function() Traceback (most recent call last): ... ValueError: F[2, 3] + F[3, 2] is not a symmetric function >>> m = SymmetricFunctions(QQ).m() >>> s = SymmetricFunctions(QQ).s() >>> F(s[Integer(3),Integer(1),Integer(1)]).to_symmetric_function() 6*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + m[2, 2, 1] + m[3, 1, 1] >>> m(s[Integer(3),Integer(1),Integer(1)]) 6*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + m[2, 2, 1] + m[3, 1, 1]
- class ParentMethods[source]¶
Bases:
object
Methods common to all bases of
QuasiSymmetricFunctions
.- Eulerian(n, j, k=None)[source]¶
Return the Eulerian (quasi)symmetric function \(Q_{n,j}\) in terms of
self
.INPUT:
n
– the value \(n\) or a partitionj
– the number of excedancesk
– (optional) if specified, determines the number of fixed points of the permutation
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: M = QSym.M() sage: M.Eulerian(3, 1) 4*M[1, 1, 1] + 3*M[1, 2] + 3*M[2, 1] + 2*M[3] sage: M.Eulerian(4, 1, 2) 6*M[1, 1, 1, 1] + 4*M[1, 1, 2] + 4*M[1, 2, 1] + 2*M[1, 3] + 4*M[2, 1, 1] + 3*M[2, 2] + 2*M[3, 1] + M[4] sage: QS = QSym.QS() sage: QS.Eulerian(4, 2) 2*QS[1, 3] + QS[2, 2] + 2*QS[3, 1] + 3*QS[4] sage: QS.Eulerian([2, 2, 1], 2) QS[1, 2, 2] + QS[1, 4] + QS[2, 1, 2] + QS[2, 2, 1] + QS[2, 3] + QS[3, 2] + QS[4, 1] + QS[5] sage: dI = QSym.dI() sage: dI.Eulerian(5, 2) -dI[1, 3, 1] - 5*dI[1, 4] + dI[2, 2, 1] + dI[3, 1, 1] + 5*dI[3, 2] + 6*dI[4, 1] + 6*dI[5]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> M = QSym.M() >>> M.Eulerian(Integer(3), Integer(1)) 4*M[1, 1, 1] + 3*M[1, 2] + 3*M[2, 1] + 2*M[3] >>> M.Eulerian(Integer(4), Integer(1), Integer(2)) 6*M[1, 1, 1, 1] + 4*M[1, 1, 2] + 4*M[1, 2, 1] + 2*M[1, 3] + 4*M[2, 1, 1] + 3*M[2, 2] + 2*M[3, 1] + M[4] >>> QS = QSym.QS() >>> QS.Eulerian(Integer(4), Integer(2)) 2*QS[1, 3] + QS[2, 2] + 2*QS[3, 1] + 3*QS[4] >>> QS.Eulerian([Integer(2), Integer(2), Integer(1)], Integer(2)) QS[1, 2, 2] + QS[1, 4] + QS[2, 1, 2] + QS[2, 2, 1] + QS[2, 3] + QS[3, 2] + QS[4, 1] + QS[5] >>> dI = QSym.dI() >>> dI.Eulerian(Integer(5), Integer(2)) -dI[1, 3, 1] - 5*dI[1, 4] + dI[2, 2, 1] + dI[3, 1, 1] + 5*dI[3, 2] + 6*dI[4, 1] + 6*dI[5]
- from_polynomial(f, check=True)[source]¶
The quasi-symmetric function expanded in this basis corresponding to the quasi-symmetric polynomial
f
.This is a default implementation that computes the expansion in the Monomial basis and converts to this basis.
INPUT:
f
– a polynomial in finitely many variables over the same base ring asself
. It is assumed that this polynomial is quasi-symmetric.check
– boolean (default:True
); checks whether the polynomial is indeed quasi-symmetric
OUTPUT: quasi-symmetric function
EXAMPLES:
sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: F = QuasiSymmetricFunctions(QQ).Fundamental() sage: P = PolynomialRing(QQ, 'x', 3) sage: x = P.gens() sage: f = x[0] + x[1] + x[2] sage: M.from_polynomial(f) M[1] sage: F.from_polynomial(f) F[1] sage: f = x[0]**2+x[1]**2+x[2]**2 sage: M.from_polynomial(f) M[2] sage: F.from_polynomial(f) -F[1, 1] + F[2]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).Monomial() >>> F = QuasiSymmetricFunctions(QQ).Fundamental() >>> P = PolynomialRing(QQ, 'x', Integer(3)) >>> x = P.gens() >>> f = x[Integer(0)] + x[Integer(1)] + x[Integer(2)] >>> M.from_polynomial(f) M[1] >>> F.from_polynomial(f) F[1] >>> f = x[Integer(0)]**Integer(2)+x[Integer(1)]**Integer(2)+x[Integer(2)]**Integer(2) >>> M.from_polynomial(f) M[2] >>> F.from_polynomial(f) -F[1, 1] + F[2]
If the polynomial is not quasi-symmetric, an error is raised:
sage: f = x[0]^2+x[1] sage: M.from_polynomial(f) Traceback (most recent call last): ... ValueError: x0^2 + x1 is not a quasi-symmetric polynomial sage: F.from_polynomial(f) Traceback (most recent call last): ... ValueError: x0^2 + x1 is not a quasi-symmetric polynomial
>>> from sage.all import * >>> f = x[Integer(0)]**Integer(2)+x[Integer(1)] >>> M.from_polynomial(f) Traceback (most recent call last): ... ValueError: x0^2 + x1 is not a quasi-symmetric polynomial >>> F.from_polynomial(f) Traceback (most recent call last): ... ValueError: x0^2 + x1 is not a quasi-symmetric polynomial
- class Essential(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric functions in the Essential basis.
The Essential quasi-symmetric functions are defined by
\[E_I = \sum_{J \geq I} M_J = \sum_{i_1 \leq \cdots \leq i_k} x_{i_1}^{I_1} \cdots x_{i_k}^{I_k},\]where \(I = (I_1, \ldots, I_k)\).
Note
Our convention of \(\leq\) and \(\geq\) of compositions is opposite that of [Hoff2015].
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: E = QSym.E() sage: M = QSym.M() sage: E(M[2,2]) E[2, 2] - E[4] sage: s = SymmetricFunctions(QQ).s() sage: E(s[3,2]) 5*E[1, 1, 1, 1, 1] - 2*E[1, 1, 1, 2] - 2*E[1, 1, 2, 1] - 2*E[1, 2, 1, 1] + E[1, 2, 2] - 2*E[2, 1, 1, 1] + E[2, 1, 2] + E[2, 2, 1] sage: (1 + E[1])^3 E[] + 3*E[1] + 6*E[1, 1] + 6*E[1, 1, 1] - 3*E[1, 2] - 3*E[2] - 3*E[2, 1] + E[3] sage: E[1,2,1].coproduct() E[] # E[1, 2, 1] + E[1] # E[2, 1] + E[1, 2] # E[1] + E[1, 2, 1] # E[]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> E = QSym.E() >>> M = QSym.M() >>> E(M[Integer(2),Integer(2)]) E[2, 2] - E[4] >>> s = SymmetricFunctions(QQ).s() >>> E(s[Integer(3),Integer(2)]) 5*E[1, 1, 1, 1, 1] - 2*E[1, 1, 1, 2] - 2*E[1, 1, 2, 1] - 2*E[1, 2, 1, 1] + E[1, 2, 2] - 2*E[2, 1, 1, 1] + E[2, 1, 2] + E[2, 2, 1] >>> (Integer(1) + E[Integer(1)])**Integer(3) E[] + 3*E[1] + 6*E[1, 1] + 6*E[1, 1, 1] - 3*E[1, 2] - 3*E[2] - 3*E[2, 1] + E[3] >>> E[Integer(1),Integer(2),Integer(1)].coproduct() E[] # E[1, 2, 1] + E[1] # E[2, 1] + E[1, 2] # E[1] + E[1, 2, 1] # E[]
The following is an alias for this basis:
sage: QSym.Essential() Quasisymmetric functions over the Rational Field in the Essential basis
>>> from sage.all import * >>> QSym.Essential() Quasisymmetric functions over the Rational Field in the Essential basis
- antipode_on_basis(compo)[source]¶
Return the result of the antipode applied to a quasi-symmetric Essential basis element.
INPUT:
compo
– composition
OUTPUT:
The result of the antipode applied to the composition
compo
, expressed in the Essential basis.
EXAMPLES:
sage: E = QuasiSymmetricFunctions(QQ).E() sage: E.antipode_on_basis(Composition([2,1])) E[1, 2] - E[3] sage: E.antipode_on_basis(Composition([])) E[]
>>> from sage.all import * >>> E = QuasiSymmetricFunctions(QQ).E() >>> E.antipode_on_basis(Composition([Integer(2),Integer(1)])) E[1, 2] - E[3] >>> E.antipode_on_basis(Composition([])) E[]
- coproduct_on_basis(compo)[source]¶
Return the coproduct of a Essential basis element.
Combinatorial rule: deconcatenation.
INPUT:
compo
– composition
OUTPUT:
The coproduct applied to the Essential quasi-symmetric function indexed by
compo
, expressed in the Essential basis.
EXAMPLES:
sage: E = QuasiSymmetricFunctions(QQ).Essential() sage: E[4,2,3].coproduct() E[] # E[4, 2, 3] + E[4] # E[2, 3] + E[4, 2] # E[3] + E[4, 2, 3] # E[] sage: E.coproduct_on_basis(Composition([])) E[] # E[]
>>> from sage.all import * >>> E = QuasiSymmetricFunctions(QQ).Essential() >>> E[Integer(4),Integer(2),Integer(3)].coproduct() E[] # E[4, 2, 3] + E[4] # E[2, 3] + E[4, 2] # E[3] + E[4, 2, 3] # E[] >>> E.coproduct_on_basis(Composition([])) E[] # E[]
- product_on_basis(I, J)[source]¶
The product on Essential basis elements.
The product of the basis elements indexed by two compositions \(I\) and \(J\) is the sum of the basis elements indexed by compositions \(K\) in the stuffle product (also called the overlapping shuffle product) of \(I\) and \(J\) with a coefficient of \((-1)^{\ell(I) + \ell(J) - \ell(K)}\), where \(\ell(C)\) is the length of the composition \(C\).
INPUT:
I
,J
– compositions
OUTPUT:
The product of the Essential quasi-symmetric functions indexed by
I
andJ
, expressed in the Essential basis.
EXAMPLES:
sage: E = QuasiSymmetricFunctions(QQ).E() sage: c1 = Composition([2]) sage: c2 = Composition([1,3]) sage: E.product_on_basis(c1, c2) E[1, 2, 3] + E[1, 3, 2] - E[1, 5] + E[2, 1, 3] - E[3, 3] sage: E.product_on_basis(c1, Composition([])) E[2] sage: E.product_on_basis(c1, Composition([3])) E[2, 3] + E[3, 2] - E[5]
>>> from sage.all import * >>> E = QuasiSymmetricFunctions(QQ).E() >>> c1 = Composition([Integer(2)]) >>> c2 = Composition([Integer(1),Integer(3)]) >>> E.product_on_basis(c1, c2) E[1, 2, 3] + E[1, 3, 2] - E[1, 5] + E[2, 1, 3] - E[3, 3] >>> E.product_on_basis(c1, Composition([])) E[2] >>> E.product_on_basis(c1, Composition([Integer(3)])) E[2, 3] + E[3, 2] - E[5]
- F[source]¶
alias of
Fundamental
- class Fundamental(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric functions in the Fundamental basis.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: F = QSym.F() sage: M = QSym.M() sage: F(M[2,2]) F[1, 1, 1, 1] - F[1, 1, 2] - F[2, 1, 1] + F[2, 2] sage: s = SymmetricFunctions(QQ).s() sage: F(s[3,2]) F[1, 2, 2] + F[1, 3, 1] + F[2, 2, 1] + F[2, 3] + F[3, 2] sage: (1+F[1])^3 F[] + 3*F[1] + 3*F[1, 1] + F[1, 1, 1] + 2*F[1, 2] + 3*F[2] + 2*F[2, 1] + F[3] sage: F[1,2,1].coproduct() F[] # F[1, 2, 1] + F[1] # F[2, 1] + F[1, 1] # F[1, 1] + F[1, 2] # F[1] + F[1, 2, 1] # F[]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> F = QSym.F() >>> M = QSym.M() >>> F(M[Integer(2),Integer(2)]) F[1, 1, 1, 1] - F[1, 1, 2] - F[2, 1, 1] + F[2, 2] >>> s = SymmetricFunctions(QQ).s() >>> F(s[Integer(3),Integer(2)]) F[1, 2, 2] + F[1, 3, 1] + F[2, 2, 1] + F[2, 3] + F[3, 2] >>> (Integer(1)+F[Integer(1)])**Integer(3) F[] + 3*F[1] + 3*F[1, 1] + F[1, 1, 1] + 2*F[1, 2] + 3*F[2] + 2*F[2, 1] + F[3] >>> F[Integer(1),Integer(2),Integer(1)].coproduct() F[] # F[1, 2, 1] + F[1] # F[2, 1] + F[1, 1] # F[1, 1] + F[1, 2] # F[1] + F[1, 2, 1] # F[]
The following is an alias for this basis:
sage: QSym.Fundamental() Quasisymmetric functions over the Rational Field in the Fundamental basis
>>> from sage.all import * >>> QSym.Fundamental() Quasisymmetric functions over the Rational Field in the Fundamental basis
- class Element[source]¶
Bases:
IndexedFreeModuleElement
- internal_coproduct()[source]¶
Return the inner coproduct of
self
in the Fundamental basis.The inner coproduct (also known as the Kronecker coproduct, or as the second comultiplication on the \(R\)-algebra of quasi-symmetric functions) is an \(R\)-algebra homomorphism \(\Delta^{\times}\) from the \(R\)-algebra of quasi-symmetric functions to the tensor square (over \(R\)) of quasi-symmetric functions. It can be defined in the following two ways:
If \(I\) is a composition, then a \((0, I)\)-matrix will mean a matrix whose entries are nonnegative integers such that no row and no column of this matrix is zero, and such that if all the nonzero entries of the matrix are read (row by row, starting at the topmost row, reading every row from left to right), then the reading word obtained is \(I\). If \(A\) is a \((0, I)\)-matrix, then \(\mathrm{row}(A)\) will denote the vector of row sums of \(A\) (regarded as a composition), and \(\mathrm{column}(A)\) will denote the vector of column sums of \(A\) (regarded as a composition).
For every composition \(I\), the internal coproduct \(\Delta^{\times}(M_I)\) of the \(I\)-th monomial quasisymmetric function \(M_I\) is the sum
\[\sum_{A \hbox{ is a } (0, I) \text{-matrix}} M_{\mathrm{row}(A)} \otimes M_{\mathrm{column}(A)}.\]See Section 11.39 of [HazWitt1].
For every permutation \(w\), let \(C(w)\) denote the descent composition of \(w\). Then, for any composition \(I\) of size \(n\), the internal coproduct \(\Delta^{\times}(F_I)\) of the \(I\)-th fundamental quasisymmetric function \(F_I\) is the sum
\[\begin{split}\sum_{\substack{\sigma \in S_n,\\ \tau \in S_n,\\ \tau \sigma = \pi}} F_{C(\sigma)} \otimes F_{C(\tau)},\end{split}\]where \(\pi\) is any permutation in \(S_n\) having descent composition \(I\) and where permutations act from the left and multiply accordingly, so \(\tau \sigma\) means first applying \(\sigma\) and then \(\tau\). See Theorem 4.23 in [Mal1993], but beware of the notations which are apparently different from those in [HazWitt1].
The restriction of the internal coproduct to the \(R\)-algebra of symmetric functions is the well-known internal coproduct on the symmetric functions.
The method
kronecker_coproduct()
is a synonym of this one.EXAMPLES:
Let us compute the internal coproduct of \(M_{21}\) (which is short for \(M_{[2, 1]}\)). The \((0, [2,1])\)-matrices are
\[\begin{split}\begin{bmatrix}2& 1\end{bmatrix}, \begin{bmatrix}2\\1\end{bmatrix}, \begin{bmatrix}2& 0\\0& 1\end{bmatrix}, \hbox{ and } \begin{bmatrix}0&2\\1&0\end{bmatrix}\end{split}\]so
\[\Delta^\times(M_{21}) = M_{3} \otimes M_{21} + M_{21} \otimes M_3 + M_{21} \otimes M_{21} + M_{21} \otimes M_{12}.\]This is confirmed by the following Sage computation (incidentally demonstrating the non-cocommutativity of the internal coproduct):
sage: M = QuasiSymmetricFunctions(ZZ).M() sage: a = M([2,1]) sage: a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(ZZ).M() >>> a = M([Integer(2),Integer(1)]) >>> a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
Some examples on the Fundamental basis:
sage: F = QuasiSymmetricFunctions(ZZ).F() sage: F([1,1]).internal_coproduct() F[1, 1] # F[2] + F[2] # F[1, 1] sage: F([2]).internal_coproduct() F[1, 1] # F[1, 1] + F[2] # F[2] sage: F([3]).internal_coproduct() F[1, 1, 1] # F[1, 1, 1] + F[1, 2] # F[1, 2] + F[1, 2] # F[2, 1] + F[2, 1] # F[1, 2] + F[2, 1] # F[2, 1] + F[3] # F[3] sage: F([1,2]).internal_coproduct() F[1, 1, 1] # F[1, 2] + F[1, 2] # F[2, 1] + F[1, 2] # F[3] + F[2, 1] # F[1, 1, 1] + F[2, 1] # F[2, 1] + F[3] # F[1, 2]
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(ZZ).F() >>> F([Integer(1),Integer(1)]).internal_coproduct() F[1, 1] # F[2] + F[2] # F[1, 1] >>> F([Integer(2)]).internal_coproduct() F[1, 1] # F[1, 1] + F[2] # F[2] >>> F([Integer(3)]).internal_coproduct() F[1, 1, 1] # F[1, 1, 1] + F[1, 2] # F[1, 2] + F[1, 2] # F[2, 1] + F[2, 1] # F[1, 2] + F[2, 1] # F[2, 1] + F[3] # F[3] >>> F([Integer(1),Integer(2)]).internal_coproduct() F[1, 1, 1] # F[1, 2] + F[1, 2] # F[2, 1] + F[1, 2] # F[3] + F[2, 1] # F[1, 1, 1] + F[2, 1] # F[2, 1] + F[3] # F[1, 2]
- kronecker_coproduct()[source]¶
Return the inner coproduct of
self
in the Fundamental basis.The inner coproduct (also known as the Kronecker coproduct, or as the second comultiplication on the \(R\)-algebra of quasi-symmetric functions) is an \(R\)-algebra homomorphism \(\Delta^{\times}\) from the \(R\)-algebra of quasi-symmetric functions to the tensor square (over \(R\)) of quasi-symmetric functions. It can be defined in the following two ways:
If \(I\) is a composition, then a \((0, I)\)-matrix will mean a matrix whose entries are nonnegative integers such that no row and no column of this matrix is zero, and such that if all the nonzero entries of the matrix are read (row by row, starting at the topmost row, reading every row from left to right), then the reading word obtained is \(I\). If \(A\) is a \((0, I)\)-matrix, then \(\mathrm{row}(A)\) will denote the vector of row sums of \(A\) (regarded as a composition), and \(\mathrm{column}(A)\) will denote the vector of column sums of \(A\) (regarded as a composition).
For every composition \(I\), the internal coproduct \(\Delta^{\times}(M_I)\) of the \(I\)-th monomial quasisymmetric function \(M_I\) is the sum
\[\sum_{A \hbox{ is a } (0, I) \text{-matrix}} M_{\mathrm{row}(A)} \otimes M_{\mathrm{column}(A)}.\]See Section 11.39 of [HazWitt1].
For every permutation \(w\), let \(C(w)\) denote the descent composition of \(w\). Then, for any composition \(I\) of size \(n\), the internal coproduct \(\Delta^{\times}(F_I)\) of the \(I\)-th fundamental quasisymmetric function \(F_I\) is the sum
\[\begin{split}\sum_{\substack{\sigma \in S_n,\\ \tau \in S_n,\\ \tau \sigma = \pi}} F_{C(\sigma)} \otimes F_{C(\tau)},\end{split}\]where \(\pi\) is any permutation in \(S_n\) having descent composition \(I\) and where permutations act from the left and multiply accordingly, so \(\tau \sigma\) means first applying \(\sigma\) and then \(\tau\). See Theorem 4.23 in [Mal1993], but beware of the notations which are apparently different from those in [HazWitt1].
The restriction of the internal coproduct to the \(R\)-algebra of symmetric functions is the well-known internal coproduct on the symmetric functions.
The method
kronecker_coproduct()
is a synonym of this one.EXAMPLES:
Let us compute the internal coproduct of \(M_{21}\) (which is short for \(M_{[2, 1]}\)). The \((0, [2,1])\)-matrices are
\[\begin{split}\begin{bmatrix}2& 1\end{bmatrix}, \begin{bmatrix}2\\1\end{bmatrix}, \begin{bmatrix}2& 0\\0& 1\end{bmatrix}, \hbox{ and } \begin{bmatrix}0&2\\1&0\end{bmatrix}\end{split}\]so
\[\Delta^\times(M_{21}) = M_{3} \otimes M_{21} + M_{21} \otimes M_3 + M_{21} \otimes M_{21} + M_{21} \otimes M_{12}.\]This is confirmed by the following Sage computation (incidentally demonstrating the non-cocommutativity of the internal coproduct):
sage: M = QuasiSymmetricFunctions(ZZ).M() sage: a = M([2,1]) sage: a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(ZZ).M() >>> a = M([Integer(2),Integer(1)]) >>> a.internal_coproduct() M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
Some examples on the Fundamental basis:
sage: F = QuasiSymmetricFunctions(ZZ).F() sage: F([1,1]).internal_coproduct() F[1, 1] # F[2] + F[2] # F[1, 1] sage: F([2]).internal_coproduct() F[1, 1] # F[1, 1] + F[2] # F[2] sage: F([3]).internal_coproduct() F[1, 1, 1] # F[1, 1, 1] + F[1, 2] # F[1, 2] + F[1, 2] # F[2, 1] + F[2, 1] # F[1, 2] + F[2, 1] # F[2, 1] + F[3] # F[3] sage: F([1,2]).internal_coproduct() F[1, 1, 1] # F[1, 2] + F[1, 2] # F[2, 1] + F[1, 2] # F[3] + F[2, 1] # F[1, 1, 1] + F[2, 1] # F[2, 1] + F[3] # F[1, 2]
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(ZZ).F() >>> F([Integer(1),Integer(1)]).internal_coproduct() F[1, 1] # F[2] + F[2] # F[1, 1] >>> F([Integer(2)]).internal_coproduct() F[1, 1] # F[1, 1] + F[2] # F[2] >>> F([Integer(3)]).internal_coproduct() F[1, 1, 1] # F[1, 1, 1] + F[1, 2] # F[1, 2] + F[1, 2] # F[2, 1] + F[2, 1] # F[1, 2] + F[2, 1] # F[2, 1] + F[3] # F[3] >>> F([Integer(1),Integer(2)]).internal_coproduct() F[1, 1, 1] # F[1, 2] + F[1, 2] # F[2, 1] + F[1, 2] # F[3] + F[2, 1] # F[1, 1, 1] + F[2, 1] # F[2, 1] + F[3] # F[1, 2]
- star_involution()[source]¶
Return the image of the quasisymmetric function
self
under the star involution.The star involution is defined as the linear map \(QSym \to QSym\) which, for every composition \(I\), sends the monomial quasisymmetric function \(M_I\) to \(M_{I^r}\). Here, if \(I\) is a composition, we denote by \(I^r\) the reversed composition of \(I\). Denoting by \(f^{\ast}\) the image of an element \(f \in QSym\) under the star involution, it can be shown that every composition \(I\) satisfies
\[(M_I)^{\ast} = M_{I^r}, \quad (F_I)^{\ast} = F_{I^r},\]where \(F_I\) denotes the fundamental quasisymmetric function corresponding to the composition \(I\). The star involution is an involution, an algebra automorphism and a coalgebra anti-automorphism of \(QSym\). It also is an automorphism of the graded vector space \(QSym\), and is the identity on the subspace \(Sym\) of \(QSym\). It is adjoint to the star involution on \(NCSF\) by the standard adjunction between \(NCSF\) and \(QSym\).
The star involution has been denoted by \(\rho\) in [LMvW13], section 3.6.
See also
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: F = QSym.F() sage: F[3,1].star_involution() F[1, 3] sage: F[5,3].star_involution() F[3, 5] sage: (F[9,1] - F[6,2] + 2*F[6,4] - 3*F[3] + 4*F[[]]).star_involution() 4*F[] + F[1, 9] - F[2, 6] - 3*F[3] + 2*F[4, 6] sage: (F[3,3] - 2*F[2]).star_involution() -2*F[2] + F[3, 3] sage: F([4,2]).star_involution() F[2, 4] sage: dI = QSym.dI() sage: dI([1,2]).star_involution() -dI[1, 2] + dI[2, 1] sage: dI.zero().star_involution() 0
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> F = QSym.F() >>> F[Integer(3),Integer(1)].star_involution() F[1, 3] >>> F[Integer(5),Integer(3)].star_involution() F[3, 5] >>> (F[Integer(9),Integer(1)] - F[Integer(6),Integer(2)] + Integer(2)*F[Integer(6),Integer(4)] - Integer(3)*F[Integer(3)] + Integer(4)*F[[]]).star_involution() 4*F[] + F[1, 9] - F[2, 6] - 3*F[3] + 2*F[4, 6] >>> (F[Integer(3),Integer(3)] - Integer(2)*F[Integer(2)]).star_involution() -2*F[2] + F[3, 3] >>> F([Integer(4),Integer(2)]).star_involution() F[2, 4] >>> dI = QSym.dI() >>> dI([Integer(1),Integer(2)]).star_involution() -dI[1, 2] + dI[2, 1] >>> dI.zero().star_involution() 0
- Eulerian(n, j, k=None)[source]¶
Return the Eulerian (quasi)symmetric function \(Q_{n,j}\) (with \(n\) either an integer or a partition) defined in [SW2010] in terms of the fundamental quasisymmetric functions. Or, if the optional argument
k
is specified, return the function \(Q_{n,j,k}\) defined ibidem.If \(n\) and \(j\) are nonnegative integers, then the Eulerian quasisymmetric function \(Q_{n,j}\) is defined as
\[Q_{n,j} := \sum_{\sigma} F_{\mathrm{Dex}(\sigma)},\]where we sum over all permutations \(\sigma \in S_n\) such that the number of excedances of \(\sigma\) is \(j\), and where \(\mathrm{Dex}(\sigma)\) is a composition of \(n\) defined as follows: Let \(S\) be the set of all \(i \in \{ 1, 2, \ldots, n-1 \}\) such that either \(\sigma_i > \sigma_{i+1} > i+1\) or \(i \geq \sigma_i > \sigma_{i+1}\) or \(\sigma_{i+1} > i + 1 > \sigma_i\). Then, \(\mathrm{Dex}(\sigma)\) is set to be the composition of \(n\) whose descent set is \(S\).
Here, an excedance of a permutation \(\sigma \in S_n\) means an element \(i \in \{ 1, 2, \ldots, n-1 \}\) satisfying \(\sigma_i > i\).
Similarly we can define a quasisymmetric function \(Q_{\lambda, j}\) for every partition \(\lambda\) and every nonnegative integer \(j\). This differs from \(Q_{n,j}\) only in that the sum is restricted to all permutations \(\sigma \in S_n\) whose cycle type is \(\lambda\) (where \(n = |\lambda|\), and where we still require the number of excedances to be \(j\)). The method at hand allows computing these functions by passing \(\lambda\) as the
n
parameter.Analogously we can define a quasisymmetric function \(Q_{n,j,k}\) for any nonnegative integers \(n\), \(j\) and \(k\) by restricting the sum to all permutations \(\sigma \in S_n\) that have exactly \(k\) fixed points (and \(j\) excedances). This can be obtained by specifying the optional
k
argument in this method.All three versions of Eulerian quasisymmetric functions (\(Q_{n,j}\), \(Q_{\lambda,j}\) and \(Q_{n,j,k}\)) are actually symmetric functions. See
Eulerian()
.INPUT:
n
– the nonnegative integer \(n\) or a partitionj
– the number of excedancesk
– (optional) if specified, determines the number of fixed points of the permutations which are being summed over
EXAMPLES:
sage: F = QuasiSymmetricFunctions(QQ).F() sage: F.Eulerian(3, 1) F[1, 2] + F[2, 1] + 2*F[3] sage: F.Eulerian(4, 2) F[1, 2, 1] + 2*F[1, 3] + 3*F[2, 2] + 2*F[3, 1] + 3*F[4] sage: F.Eulerian(5, 2) F[1, 1, 2, 1] + F[1, 1, 3] + F[1, 2, 1, 1] + 7*F[1, 2, 2] + 6*F[1, 3, 1] + 6*F[1, 4] + 2*F[2, 1, 2] + 7*F[2, 2, 1] + 11*F[2, 3] + F[3, 1, 1] + 11*F[3, 2] + 6*F[4, 1] + 6*F[5] sage: F.Eulerian(4, 0) F[4] sage: F.Eulerian(4, 3) F[4] sage: F.Eulerian(4, 1, 2) F[1, 2, 1] + F[1, 3] + 2*F[2, 2] + F[3, 1] + F[4] sage: F.Eulerian(Partition([2, 2, 1]), 2) F[1, 1, 2, 1] + F[1, 2, 1, 1] + 2*F[1, 2, 2] + F[1, 3, 1] + F[1, 4] + F[2, 1, 2] + 2*F[2, 2, 1] + 2*F[2, 3] + 2*F[3, 2] + F[4, 1] + F[5] sage: F.Eulerian(0, 0) F[] sage: F.Eulerian(0, 1) 0 sage: F.Eulerian(1, 0) F[1] sage: F.Eulerian(1, 1) 0
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(QQ).F() >>> F.Eulerian(Integer(3), Integer(1)) F[1, 2] + F[2, 1] + 2*F[3] >>> F.Eulerian(Integer(4), Integer(2)) F[1, 2, 1] + 2*F[1, 3] + 3*F[2, 2] + 2*F[3, 1] + 3*F[4] >>> F.Eulerian(Integer(5), Integer(2)) F[1, 1, 2, 1] + F[1, 1, 3] + F[1, 2, 1, 1] + 7*F[1, 2, 2] + 6*F[1, 3, 1] + 6*F[1, 4] + 2*F[2, 1, 2] + 7*F[2, 2, 1] + 11*F[2, 3] + F[3, 1, 1] + 11*F[3, 2] + 6*F[4, 1] + 6*F[5] >>> F.Eulerian(Integer(4), Integer(0)) F[4] >>> F.Eulerian(Integer(4), Integer(3)) F[4] >>> F.Eulerian(Integer(4), Integer(1), Integer(2)) F[1, 2, 1] + F[1, 3] + 2*F[2, 2] + F[3, 1] + F[4] >>> F.Eulerian(Partition([Integer(2), Integer(2), Integer(1)]), Integer(2)) F[1, 1, 2, 1] + F[1, 2, 1, 1] + 2*F[1, 2, 2] + F[1, 3, 1] + F[1, 4] + F[2, 1, 2] + 2*F[2, 2, 1] + 2*F[2, 3] + 2*F[3, 2] + F[4, 1] + F[5] >>> F.Eulerian(Integer(0), Integer(0)) F[] >>> F.Eulerian(Integer(0), Integer(1)) 0 >>> F.Eulerian(Integer(1), Integer(0)) F[1] >>> F.Eulerian(Integer(1), Integer(1)) 0
- antipode_on_basis(compo)[source]¶
Return the antipode to a Fundamental quasi-symmetric basis element.
INPUT:
compo
– composition
OUTPUT:
The result of the antipode applied to the quasi-symmetric Fundamental basis element indexed by
compo
.
EXAMPLES:
sage: F = QuasiSymmetricFunctions(QQ).F() sage: F.antipode_on_basis(Composition([2,1])) -F[2, 1]
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(QQ).F() >>> F.antipode_on_basis(Composition([Integer(2),Integer(1)])) -F[2, 1]
- coproduct_on_basis(compo)[source]¶
Return the coproduct to a Fundamental quasi-symmetric basis element.
Combinatorial rule: quasi-deconcatenation.
INPUT:
compo
– composition
OUTPUT:
The application of the coproduct to the Fundamental quasi-symmetric function indexed by the composition
compo
.
EXAMPLES:
sage: F = QuasiSymmetricFunctions(QQ).Fundamental() sage: F[4].coproduct() F[] # F[4] + F[1] # F[3] + F[2] # F[2] + F[3] # F[1] + F[4] # F[] sage: F[2,1,3].coproduct() F[] # F[2, 1, 3] + F[1] # F[1, 1, 3] + F[2] # F[1, 3] + F[2, 1] # F[3] + F[2, 1, 1] # F[2] + F[2, 1, 2] # F[1] + F[2, 1, 3] # F[]
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(QQ).Fundamental() >>> F[Integer(4)].coproduct() F[] # F[4] + F[1] # F[3] + F[2] # F[2] + F[3] # F[1] + F[4] # F[] >>> F[Integer(2),Integer(1),Integer(3)].coproduct() F[] # F[2, 1, 3] + F[1] # F[1, 1, 3] + F[2] # F[1, 3] + F[2, 1] # F[3] + F[2, 1, 1] # F[2] + F[2, 1, 2] # F[1] + F[2, 1, 3] # F[]
- dual()[source]¶
Return the dual basis to the Fundamental basis. This is the ribbon basis of the non-commutative symmetric functions.
OUTPUT: the ribbon basis of the non-commutative symmetric functions
EXAMPLES:
sage: F = QuasiSymmetricFunctions(QQ).F() sage: F.dual() Non-Commutative Symmetric Functions over the Rational Field in the Ribbon basis
>>> from sage.all import * >>> F = QuasiSymmetricFunctions(QQ).F() >>> F.dual() Non-Commutative Symmetric Functions over the Rational Field in the Ribbon basis
- class HazewinkelLambda(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hazewinkel lambda basis of the quasi-symmetric functions.
This basis goes back to [Haz2004], albeit it is indexed in a different way here. It is a multiplicative basis in a weak sense of this word (the product of any two basis elements is a basis element, but of course not the one obtained by concatenating the indexing compositions).
In [Haz2004], Hazewinkel showed that the \(\mathbf{k}\)-algebra \(\mathrm{QSym}\) is a polynomial algebra. (The proof is correct but rests upon an unproven claim that the lexicographically largest term of the \(n\)-th shuffle power of a Lyndon word is the \(n\)-fold concatenation of this Lyndon word with itself, occurring \(n!\) times in that shuffle power. But this can be deduced from Section 2 of [Rad1979]. See also Chapter 6 of [GriRei18], specifically Theorem 6.5.13, for a complete proof.) More precisely, he showed that \(\mathrm{QSym}\) is generated, as a free commutative \(\mathbf{k}\)-algebra, by the elements \(\lambda^n(M_I)\), where \(n\) ranges over the positive integers, and \(I\) ranges over all compositions which are Lyndon words and whose entries have gcd \(1\). Here, \(\lambda^n\) denotes the \(n\)-th lambda operation as explained in
lambda_of_monomial()
.Thus, products of these generators form a \(\mathbf{k}\)-module basis of \(\mathrm{QSym}\). We index this basis by compositions here. More precisely, we define the Hazewinkel lambda basis \((\mathrm{HWL}_I)_I\) (with \(I\) ranging over all compositions) as follows:
Let \(I\) be a composition. Let \(I = I_1 I_2 \ldots I_k\) be the Chen-Fox-Lyndon factorization of \(I\) (see
lyndon_factorization()
). For every \(j \in \{1, 2, \ldots , k\}\), let \(g_j\) be the gcd of the entries of the Lyndon word \(I_j\), and let \(J_j\) be the result of dividing the entries of \(I_j\) by this gcd. Then, \(\mathrm{HWL}_I\) is defined to be \(\prod_{j=1}^{k} \lambda^{g_j} (M_{J_j})\).Todo
The conversion from the M basis to the HWL basis is currently implemented in the naive way (inverting the base-change matrix in the other direction). This matrix is not triangular (not even after any permutations of the bases), and there could very well be a faster method (the one given by Hazewinkel?).
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: HWL = QSym.HazewinkelLambda() sage: M = QSym.M() sage: M(HWL([2])) M[1, 1] sage: M(HWL([1,1])) 2*M[1, 1] + M[2] sage: M(HWL([1,2])) M[1, 2] sage: M(HWL([2,1])) 3*M[1, 1, 1] + M[1, 2] + M[2, 1] sage: M(HWL(Composition([]))) M[] sage: HWL(M([1,1])) HWL[2] sage: HWL(M(Composition([2]))) HWL[1, 1] - 2*HWL[2] sage: HWL(M([1])) HWL[1]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> HWL = QSym.HazewinkelLambda() >>> M = QSym.M() >>> M(HWL([Integer(2)])) M[1, 1] >>> M(HWL([Integer(1),Integer(1)])) 2*M[1, 1] + M[2] >>> M(HWL([Integer(1),Integer(2)])) M[1, 2] >>> M(HWL([Integer(2),Integer(1)])) 3*M[1, 1, 1] + M[1, 2] + M[2, 1] >>> M(HWL(Composition([]))) M[] >>> HWL(M([Integer(1),Integer(1)])) HWL[2] >>> HWL(M(Composition([Integer(2)]))) HWL[1, 1] - 2*HWL[2] >>> HWL(M([Integer(1)])) HWL[1]
- product_on_basis(I, J)[source]¶
The product on Hazewinkel Lambda basis elements.
The product of the basis elements indexed by two compositions \(I\) and \(J\) is the basis element obtained by concatenating the Lyndon factorizations of the words \(I\) and \(J\), then reordering the Lyndon factors in nonincreasing order, and finally concatenating them in this order (giving a new composition).
INPUT:
I
,J
– compositions
OUTPUT:
The product of the Hazewinkel Lambda quasi-symmetric functions indexed by
I
andJ
, expressed in the Hazewinkel Lambda basis.
EXAMPLES:
sage: HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda() sage: c1 = Composition([1, 2, 1]) sage: c2 = Composition([2, 1, 3, 2]) sage: HWL.product_on_basis(c1, c2) HWL[2, 1, 3, 2, 1, 2, 1] sage: HWL.product_on_basis(c1, Composition([])) HWL[1, 2, 1] sage: HWL.product_on_basis(Composition([]), Composition([])) HWL[]
>>> from sage.all import * >>> HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda() >>> c1 = Composition([Integer(1), Integer(2), Integer(1)]) >>> c2 = Composition([Integer(2), Integer(1), Integer(3), Integer(2)]) >>> HWL.product_on_basis(c1, c2) HWL[2, 1, 3, 2, 1, 2, 1] >>> HWL.product_on_basis(c1, Composition([])) HWL[1, 2, 1] >>> HWL.product_on_basis(Composition([]), Composition([])) HWL[]
- class Monomial(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric function in the Monomial basis.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: M = QSym.M() sage: F = QSym.F() sage: M(F[2,2]) M[1, 1, 1, 1] + M[1, 1, 2] + M[2, 1, 1] + M[2, 2] sage: m = SymmetricFunctions(QQ).m() sage: M(m[3,1,1]) M[1, 1, 3] + M[1, 3, 1] + M[3, 1, 1] sage: (1+M[1])^3 M[] + 3*M[1] + 6*M[1, 1] + 6*M[1, 1, 1] + 3*M[1, 2] + 3*M[2] + 3*M[2, 1] + M[3] sage: M[1,2,1].coproduct() M[] # M[1, 2, 1] + M[1] # M[2, 1] + M[1, 2] # M[1] + M[1, 2, 1] # M[]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> M = QSym.M() >>> F = QSym.F() >>> M(F[Integer(2),Integer(2)]) M[1, 1, 1, 1] + M[1, 1, 2] + M[2, 1, 1] + M[2, 2] >>> m = SymmetricFunctions(QQ).m() >>> M(m[Integer(3),Integer(1),Integer(1)]) M[1, 1, 3] + M[1, 3, 1] + M[3, 1, 1] >>> (Integer(1)+M[Integer(1)])**Integer(3) M[] + 3*M[1] + 6*M[1, 1] + 6*M[1, 1, 1] + 3*M[1, 2] + 3*M[2] + 3*M[2, 1] + M[3] >>> M[Integer(1),Integer(2),Integer(1)].coproduct() M[] # M[1, 2, 1] + M[1] # M[2, 1] + M[1, 2] # M[1] + M[1, 2, 1] # M[]
The following is an alias for this basis:
sage: QSym.Monomial() Quasisymmetric functions over the Rational Field in the Monomial basis
>>> from sage.all import * >>> QSym.Monomial() Quasisymmetric functions over the Rational Field in the Monomial basis
- class Element[source]¶
Bases:
IndexedFreeModuleElement
Element methods of the
Monomial
basis ofQuasiSymmetricFunctions
.- expand(n, alphabet='x')[source]¶
Expand the quasi-symmetric function written in the monomial basis in \(n\) variables.
INPUT:
n
– integeralphabet
– string (default:'x'
)
OUTPUT: the quasi-symmetric function
self
expressed in the \(n\) variables described byalphabet
Todo
accept an alphabet as input
EXAMPLES:
sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: M[4,2].expand(3) x0^4*x1^2 + x0^4*x2^2 + x1^4*x2^2
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).Monomial() >>> M[Integer(4),Integer(2)].expand(Integer(3)) x0^4*x1^2 + x0^4*x2^2 + x1^4*x2^2
One can use a different set of variables by using the optional argument
alphabet
:sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: M[2,1,1].expand(4,alphabet='y') y0^2*y1*y2 + y0^2*y1*y3 + y0^2*y2*y3 + y1^2*y2*y3
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).Monomial() >>> M[Integer(2),Integer(1),Integer(1)].expand(Integer(4),alphabet='y') y0^2*y1*y2 + y0^2*y1*y3 + y0^2*y2*y3 + y1^2*y2*y3
- is_symmetric()[source]¶
Determine if a quasi-symmetric function, written in the Monomial basis, is symmetric.
This is being tested by looking at the expansion in the Monomial basis and checking if the coefficients are the same if the indexing compositions are permutations of each other.
OUTPUT:
True
ifself
is an element of the symmetric functions andFalse
otherwise.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: M = QSym.Monomial() sage: (M[3,2] + M[2,3] + M[4,1]).is_symmetric() False sage: (M[3,2] + M[2,3]).is_symmetric() True sage: (M[1,2,1] + M[1,1,2]).is_symmetric() False sage: (M[1,2,1] + M[1,1,2] + M[2,1,1]).is_symmetric() True
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> M = QSym.Monomial() >>> (M[Integer(3),Integer(2)] + M[Integer(2),Integer(3)] + M[Integer(4),Integer(1)]).is_symmetric() False >>> (M[Integer(3),Integer(2)] + M[Integer(2),Integer(3)]).is_symmetric() True >>> (M[Integer(1),Integer(2),Integer(1)] + M[Integer(1),Integer(1),Integer(2)]).is_symmetric() False >>> (M[Integer(1),Integer(2),Integer(1)] + M[Integer(1),Integer(1),Integer(2)] + M[Integer(2),Integer(1),Integer(1)]).is_symmetric() True
- psi_involution()[source]¶
Return the image of the quasisymmetric function
self
under the involution \(\psi\).The involution \(\psi\) is defined as the linear map \(QSym \to QSym\) which, for every composition \(I\), sends the fundamental quasisymmetric function \(F_I\) to \(F_{I^c}\), where \(I^c\) denotes the complement of the composition \(I\). The map \(\psi\) is an involution and a graded Hopf algebra automorphism of \(QSym\). Its restriction to the ring of symmetric functions coincides with the omega automorphism of the latter ring.
The involution \(\psi\) of \(QSym\) is adjoint to the involution \(\psi\) of \(NCSF\) by the standard adjunction between \(NCSF\) and \(QSym\).
The involution \(\psi\) has been denoted by \(\psi\) in [LMvW13], section 3.6.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(ZZ) sage: M = QSym.M() sage: M[3,2].psi_involution() -M[3, 2] - M[5] sage: M[3,1].psi_involution() M[3, 1] + M[4] sage: M[3,1,1].psi_involution() M[3, 1, 1] + M[3, 2] + M[4, 1] + M[5] sage: M[1,1,1].psi_involution() M[1, 1, 1] + M[1, 2] + M[2, 1] + M[3] sage: M[[]].psi_involution() M[] sage: M(0).psi_involution() 0 sage: (2*M[[]] - M[3,1] + 4*M[2]).psi_involution() 2*M[] - 4*M[2] - M[3, 1] - M[4]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(ZZ) >>> M = QSym.M() >>> M[Integer(3),Integer(2)].psi_involution() -M[3, 2] - M[5] >>> M[Integer(3),Integer(1)].psi_involution() M[3, 1] + M[4] >>> M[Integer(3),Integer(1),Integer(1)].psi_involution() M[3, 1, 1] + M[3, 2] + M[4, 1] + M[5] >>> M[Integer(1),Integer(1),Integer(1)].psi_involution() M[1, 1, 1] + M[1, 2] + M[2, 1] + M[3] >>> M[[]].psi_involution() M[] >>> M(Integer(0)).psi_involution() 0 >>> (Integer(2)*M[[]] - M[Integer(3),Integer(1)] + Integer(4)*M[Integer(2)]).psi_involution() 2*M[] - 4*M[2] - M[3, 1] - M[4]
This particular implementation is tailored to the monomial basis. It is semantically equivalent to the generic implementation it overshadows:
sage: F = QSym.F() sage: all( F(M[I].psi_involution()) == F(M[I]).psi_involution() ....: for I in Compositions(3) ) True sage: F = QSym.F() sage: all( F(M[I].psi_involution()) == F(M[I]).psi_involution() ....: for I in Compositions(4) ) True
>>> from sage.all import * >>> F = QSym.F() >>> all( F(M[I].psi_involution()) == F(M[I]).psi_involution() ... for I in Compositions(Integer(3)) ) True >>> F = QSym.F() >>> all( F(M[I].psi_involution()) == F(M[I]).psi_involution() ... for I in Compositions(Integer(4)) ) True
- to_symmetric_function()[source]¶
Take a quasi-symmetric function, expressed in the monomial basis, and return its symmetric realization, when possible, expressed in the monomial basis of symmetric functions.
OUTPUT:
If
self
is a symmetric function, then the expansion in the monomial basis of the symmetric functions is returned. Otherwise an error is raised.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: M = QSym.Monomial() sage: (M[3,2] + M[2,3] + M[4,1]).to_symmetric_function() Traceback (most recent call last): ... ValueError: M[2, 3] + M[3, 2] + M[4, 1] is not a symmetric function sage: (M[3,2] + M[2,3] + 2*M[4,1] + 2*M[1,4]).to_symmetric_function() m[3, 2] + 2*m[4, 1] sage: m = SymmetricFunctions(QQ).m() sage: M(m[3,1,1]).to_symmetric_function() m[3, 1, 1] sage: (M(m[2,1])*M(m[2,1])).to_symmetric_function()-m[2,1]*m[2,1] 0
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> M = QSym.Monomial() >>> (M[Integer(3),Integer(2)] + M[Integer(2),Integer(3)] + M[Integer(4),Integer(1)]).to_symmetric_function() Traceback (most recent call last): ... ValueError: M[2, 3] + M[3, 2] + M[4, 1] is not a symmetric function >>> (M[Integer(3),Integer(2)] + M[Integer(2),Integer(3)] + Integer(2)*M[Integer(4),Integer(1)] + Integer(2)*M[Integer(1),Integer(4)]).to_symmetric_function() m[3, 2] + 2*m[4, 1] >>> m = SymmetricFunctions(QQ).m() >>> M(m[Integer(3),Integer(1),Integer(1)]).to_symmetric_function() m[3, 1, 1] >>> (M(m[Integer(2),Integer(1)])*M(m[Integer(2),Integer(1)])).to_symmetric_function()-m[Integer(2),Integer(1)]*m[Integer(2),Integer(1)] 0
- antipode_on_basis(compo)[source]¶
Return the result of the antipode applied to a quasi-symmetric Monomial basis element.
INPUT:
compo
– composition
OUTPUT:
The result of the antipode applied to the composition
compo
, expressed in the Monomial basis.
EXAMPLES:
sage: M = QuasiSymmetricFunctions(QQ).M() sage: M.antipode_on_basis(Composition([2,1])) M[1, 2] + M[3] sage: M.antipode_on_basis(Composition([])) M[]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).M() >>> M.antipode_on_basis(Composition([Integer(2),Integer(1)])) M[1, 2] + M[3] >>> M.antipode_on_basis(Composition([])) M[]
- coproduct_on_basis(compo)[source]¶
Return the coproduct of a Monomial basis element.
Combinatorial rule: deconcatenation.
INPUT:
compo
– composition
OUTPUT:
The coproduct applied to the Monomial quasi-symmetric function indexed by
compo
, expressed in the Monomial basis.
EXAMPLES:
sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: M[4,2,3].coproduct() M[] # M[4, 2, 3] + M[4] # M[2, 3] + M[4, 2] # M[3] + M[4, 2, 3] # M[] sage: M.coproduct_on_basis(Composition([])) M[] # M[]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).Monomial() >>> M[Integer(4),Integer(2),Integer(3)].coproduct() M[] # M[4, 2, 3] + M[4] # M[2, 3] + M[4, 2] # M[3] + M[4, 2, 3] # M[] >>> M.coproduct_on_basis(Composition([])) M[] # M[]
- dual()[source]¶
Return the dual basis to the Monomial basis. This is the complete basis of the non-commutative symmetric functions.
OUTPUT: the complete basis of the non-commutative symmetric functions
EXAMPLES:
sage: M = QuasiSymmetricFunctions(QQ).M() sage: M.dual() Non-Commutative Symmetric Functions over the Rational Field in the Complete basis
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).M() >>> M.dual() Non-Commutative Symmetric Functions over the Rational Field in the Complete basis
- lambda_of_monomial(I, n)[source]¶
Return the image of the monomial quasi-symmetric function \(M_I\) under the lambda-map \(\lambda^n\), expanded in the monomial basis.
The ring of quasi-symmetric functions over the integers, \(\mathrm{QSym}_{\ZZ}\) (and more generally, the ring of quasi-symmetric functions over any binomial ring) becomes a \(\lambda\)-ring (with the \(\lambda\)-structure inherited from the ring of formal power series, so that \(\lambda^i(x_j)\) is \(x_j\) if \(i = 1\) and \(0\) if \(i > 1\)).
The Adams operations of this \(\lambda\)-ring are the Adams endomorphisms \(\mathbf{f}_n\) (see
adams_operator()
for their definition). Using these endomorphisms, the \(\lambda\)-operations can be explicitly computed via the formula\[\exp \left(- \sum_{n=1}^{\infty} \frac{1}{n} \mathbf{f}_n(x) t^n \right) = \sum_{j=0}^{\infty} (-1)^j \lambda^j(x) t^j\]in the ring of formal power series in a variable \(t\) over the ring of quasi-symmetric functions. In particular, every composition \(I = (I_1, I_2, \cdots, I_\ell )\) satisfies
\[\exp \left(- \sum_{n=1}^{\infty} \frac{1}{n} M_{(nI_1, nI_2, \cdots, nI_\ell )} t^n \right) = \sum_{j=0}^{\infty} (-1)^j \lambda^j(M_I) t^j\](corrected version of Remark 2.4 in [Haz2004]).
The quasi-symmetric functions \(\lambda^i(M_I)\) with \(n\) ranging over the positive integers and \(I\) ranging over the reduced Lyndon compositions (i. e., compositions which are Lyndon words and have the gcd of their entries equal to \(1\)) form a set of free polynomial generators for \(\mathrm{QSym}\). See [GriRei18], Chapter 6, for the proof, and [Haz2004] for a major part of it.
INPUT:
I
– compositionn
– nonnegative integer
OUTPUT:
The quasi-symmetric function \(\lambda^n(M_I)\), expanded in the monomial basis over the ground ring of
self
.EXAMPLES:
sage: M = QuasiSymmetricFunctions(CyclotomicField()).Monomial() sage: M.lambda_of_monomial([1, 2], 2) 2*M[1, 1, 2, 2] + M[1, 1, 4] + M[1, 2, 1, 2] + M[1, 3, 2] + M[2, 2, 2] sage: M.lambda_of_monomial([1, 1], 2) 3*M[1, 1, 1, 1] + M[1, 1, 2] + M[1, 2, 1] + M[2, 1, 1] sage: M = QuasiSymmetricFunctions(Integers(19)).Monomial() sage: M.lambda_of_monomial([1, 2], 3) 6*M[1, 1, 1, 2, 2, 2] + 3*M[1, 1, 1, 2, 4] + 3*M[1, 1, 1, 4, 2] + M[1, 1, 1, 6] + 4*M[1, 1, 2, 1, 2, 2] + 2*M[1, 1, 2, 1, 4] + 2*M[1, 1, 2, 2, 1, 2] + 2*M[1, 1, 2, 3, 2] + 4*M[1, 1, 3, 2, 2] + 2*M[1, 1, 3, 4] + M[1, 1, 4, 1, 2] + M[1, 1, 5, 2] + 2*M[1, 2, 1, 1, 2, 2] + M[1, 2, 1, 1, 4] + M[1, 2, 1, 2, 1, 2] + M[1, 2, 1, 3, 2] + 4*M[1, 2, 2, 2, 2] + M[1, 2, 2, 4] + M[1, 2, 4, 2] + 2*M[1, 3, 1, 2, 2] + M[1, 3, 1, 4] + M[1, 3, 2, 1, 2] + M[1, 3, 3, 2] + M[1, 4, 2, 2] + 3*M[2, 1, 2, 2, 2] + M[2, 1, 2, 4] + M[2, 1, 4, 2] + 2*M[2, 2, 1, 2, 2] + M[2, 2, 1, 4] + M[2, 2, 2, 1, 2] + M[2, 2, 3, 2] + 2*M[2, 3, 2, 2] + M[2, 3, 4] + M[3, 2, 2, 2]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(CyclotomicField()).Monomial() >>> M.lambda_of_monomial([Integer(1), Integer(2)], Integer(2)) 2*M[1, 1, 2, 2] + M[1, 1, 4] + M[1, 2, 1, 2] + M[1, 3, 2] + M[2, 2, 2] >>> M.lambda_of_monomial([Integer(1), Integer(1)], Integer(2)) 3*M[1, 1, 1, 1] + M[1, 1, 2] + M[1, 2, 1] + M[2, 1, 1] >>> M = QuasiSymmetricFunctions(Integers(Integer(19))).Monomial() >>> M.lambda_of_monomial([Integer(1), Integer(2)], Integer(3)) 6*M[1, 1, 1, 2, 2, 2] + 3*M[1, 1, 1, 2, 4] + 3*M[1, 1, 1, 4, 2] + M[1, 1, 1, 6] + 4*M[1, 1, 2, 1, 2, 2] + 2*M[1, 1, 2, 1, 4] + 2*M[1, 1, 2, 2, 1, 2] + 2*M[1, 1, 2, 3, 2] + 4*M[1, 1, 3, 2, 2] + 2*M[1, 1, 3, 4] + M[1, 1, 4, 1, 2] + M[1, 1, 5, 2] + 2*M[1, 2, 1, 1, 2, 2] + M[1, 2, 1, 1, 4] + M[1, 2, 1, 2, 1, 2] + M[1, 2, 1, 3, 2] + 4*M[1, 2, 2, 2, 2] + M[1, 2, 2, 4] + M[1, 2, 4, 2] + 2*M[1, 3, 1, 2, 2] + M[1, 3, 1, 4] + M[1, 3, 2, 1, 2] + M[1, 3, 3, 2] + M[1, 4, 2, 2] + 3*M[2, 1, 2, 2, 2] + M[2, 1, 2, 4] + M[2, 1, 4, 2] + 2*M[2, 2, 1, 2, 2] + M[2, 2, 1, 4] + M[2, 2, 2, 1, 2] + M[2, 2, 3, 2] + 2*M[2, 3, 2, 2] + M[2, 3, 4] + M[3, 2, 2, 2]
The map \(\lambda^0\) sends everything to \(1\):
sage: M = QuasiSymmetricFunctions(ZZ).Monomial() sage: all( M.lambda_of_monomial(I, 0) == M.one() ....: for I in Compositions(3) ) True
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(ZZ).Monomial() >>> all( M.lambda_of_monomial(I, Integer(0)) == M.one() ... for I in Compositions(Integer(3)) ) True
The map \(\lambda^1\) is the identity map:
sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: all( M.lambda_of_monomial(I, 1) == M(I) ....: for I in Compositions(3) ) True sage: M = QuasiSymmetricFunctions(Integers(5)).Monomial() sage: all( M.lambda_of_monomial(I, 1) == M(I) ....: for I in Compositions(3) ) True sage: M = QuasiSymmetricFunctions(ZZ).Monomial() sage: all( M.lambda_of_monomial(I, 1) == M(I) ....: for I in Compositions(3) ) True
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).Monomial() >>> all( M.lambda_of_monomial(I, Integer(1)) == M(I) ... for I in Compositions(Integer(3)) ) True >>> M = QuasiSymmetricFunctions(Integers(Integer(5))).Monomial() >>> all( M.lambda_of_monomial(I, Integer(1)) == M(I) ... for I in Compositions(Integer(3)) ) True >>> M = QuasiSymmetricFunctions(ZZ).Monomial() >>> all( M.lambda_of_monomial(I, Integer(1)) == M(I) ... for I in Compositions(Integer(3)) ) True
- product_on_basis(I, J)[source]¶
The product on Monomial basis elements.
The product of the basis elements indexed by two compositions \(I\) and \(J\) is the sum of the basis elements indexed by compositions in the stuffle product (also called the overlapping shuffle product) of \(I\) and \(J\).
INPUT:
I
,J
– compositions
OUTPUT:
The product of the Monomial quasi-symmetric functions indexed by
I
andJ
, expressed in the Monomial basis.
EXAMPLES:
sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: c1 = Composition([2]) sage: c2 = Composition([1,3]) sage: M.product_on_basis(c1, c2) M[1, 2, 3] + M[1, 3, 2] + M[1, 5] + M[2, 1, 3] + M[3, 3] sage: M.product_on_basis(c1, Composition([])) M[2]
>>> from sage.all import * >>> M = QuasiSymmetricFunctions(QQ).Monomial() >>> c1 = Composition([Integer(2)]) >>> c2 = Composition([Integer(1),Integer(3)]) >>> M.product_on_basis(c1, c2) M[1, 2, 3] + M[1, 3, 2] + M[1, 5] + M[2, 1, 3] + M[3, 3] >>> M.product_on_basis(c1, Composition([])) M[2]
- QS[source]¶
alias of
Quasisymmetric_Schur
- class Quasisymmetric_Schur(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric function in the Quasisymmetric Schur basis.
The basis of Quasisymmetric Schur functions is defined in [QSCHUR] and in Definition 5.1.1 of [LMvW13]. Don’t mistake them for the completely unrelated quasi-Schur functions of [NCSF1]!
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: QS = QSym.QS() sage: F = QSym.F() sage: M = QSym.M() sage: F(QS[1,2]) F[1, 2] sage: M(QS[1,2]) M[1, 1, 1] + M[1, 2] sage: s = SymmetricFunctions(QQ).s() sage: QS(s[2,1,1]) QS[1, 1, 2] + QS[1, 2, 1] + QS[2, 1, 1]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> QS = QSym.QS() >>> F = QSym.F() >>> M = QSym.M() >>> F(QS[Integer(1),Integer(2)]) F[1, 2] >>> M(QS[Integer(1),Integer(2)]) M[1, 1, 1] + M[1, 2] >>> s = SymmetricFunctions(QQ).s() >>> QS(s[Integer(2),Integer(1),Integer(1)]) QS[1, 1, 2] + QS[1, 2, 1] + QS[2, 1, 1]
- dual()[source]¶
The dual basis to the Quasisymmetric Schur basis.
The dual basis to the Quasisymmetric Schur basis is implemented as dual.
OUTPUT:
the dual Quasisymmetric Schur basis of the non-commutative symmetric functions
EXAMPLES:
sage: QS = QuasiSymmetricFunctions(QQ).Quasisymmetric_Schur() sage: QS.dual() Non-Commutative Symmetric Functions over the Rational Field in the dual Quasisymmetric-Schur basis
>>> from sage.all import * >>> QS = QuasiSymmetricFunctions(QQ).Quasisymmetric_Schur() >>> QS.dual() Non-Commutative Symmetric Functions over the Rational Field in the dual Quasisymmetric-Schur basis
- YQS[source]¶
alias of
Young_Quasisymmetric_Schur
- class Young_Quasisymmetric_Schur(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric functions in the Young Quasisymmetric Schur basis.
The basis of Young Quasisymmetric Schur functions is from Definition 5.2.1 of [LMvW13].
This basis is related to the Quasisymmetric Schur basis
QS
byQS(alpha.reversed()) == YQS(alpha).star_involution()
.EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: YQS = QSym.YQS() sage: F = QSym.F() sage: QS = QSym.QS() sage: F(YQS[1,2]) F[1, 2] sage: all(QS(al.reversed())==YQS(al).star_involution() for al in Compositions(5)) True sage: s = SymmetricFunctions(QQ).s() sage: YQS(s[2,1,1]) YQS[1, 1, 2] + YQS[1, 2, 1] + YQS[2, 1, 1]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> YQS = QSym.YQS() >>> F = QSym.F() >>> QS = QSym.QS() >>> F(YQS[Integer(1),Integer(2)]) F[1, 2] >>> all(QS(al.reversed())==YQS(al).star_involution() for al in Compositions(Integer(5))) True >>> s = SymmetricFunctions(QQ).s() >>> YQS(s[Integer(2),Integer(1),Integer(1)]) YQS[1, 1, 2] + YQS[1, 2, 1] + YQS[2, 1, 1]
- a_realization()[source]¶
Return the realization of the Monomial basis of the ring of quasi-symmetric functions.
OUTPUT: the Monomial basis of quasi-symmetric functions
EXAMPLES:
sage: QuasiSymmetricFunctions(QQ).a_realization() Quasisymmetric functions over the Rational Field in the Monomial basis
>>> from sage.all import * >>> QuasiSymmetricFunctions(QQ).a_realization() Quasisymmetric functions over the Rational Field in the Monomial basis
- dI[source]¶
alias of
dualImmaculate
- dual()[source]¶
Return the dual Hopf algebra of the quasi-symmetric functions, which is the non-commutative symmetric functions.
OUTPUT: the non-commutative symmetric functions
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: QSym.dual() Non-Commutative Symmetric Functions over the Rational Field
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> QSym.dual() Non-Commutative Symmetric Functions over the Rational Field
- class dualImmaculate(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The dual immaculate basis of the quasi-symmetric functions.
This basis first appears in [BBSSZ2012].
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: dI = QSym.dI() sage: dI([1,3,2])*dI([1]) # long time (6s on sage.math, 2013) dI[1, 1, 3, 2] + dI[2, 3, 2] sage: dI([1,3])*dI([1,1]) dI[1, 1, 1, 3] + dI[1, 1, 4] + dI[1, 2, 3] - dI[1, 3, 2] - dI[1, 4, 1] - dI[1, 5] + dI[2, 3, 1] + dI[2, 4] sage: dI([3,1])*dI([2,1]) # long time (7s on sage.math, 2013) dI[1, 1, 5] - dI[1, 4, 1, 1] - dI[1, 4, 2] - 2*dI[1, 5, 1] - dI[1, 6] - dI[2, 4, 1] - dI[2, 5] - dI[3, 1, 3] + dI[3, 2, 1, 1] + dI[3, 2, 2] + dI[3, 3, 1] + dI[4, 1, 1, 1] + 2*dI[4, 2, 1] + dI[4, 3] + dI[5, 1, 1] + dI[5, 2] sage: F = QSym.F() sage: dI(F[1,3,1]) -dI[1, 1, 1, 2] + dI[1, 1, 2, 1] - dI[1, 2, 2] + dI[1, 3, 1] sage: F(dI(F([2,1,3]))) F[2, 1, 3]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> dI = QSym.dI() >>> dI([Integer(1),Integer(3),Integer(2)])*dI([Integer(1)]) # long time (6s on sage.math, 2013) dI[1, 1, 3, 2] + dI[2, 3, 2] >>> dI([Integer(1),Integer(3)])*dI([Integer(1),Integer(1)]) dI[1, 1, 1, 3] + dI[1, 1, 4] + dI[1, 2, 3] - dI[1, 3, 2] - dI[1, 4, 1] - dI[1, 5] + dI[2, 3, 1] + dI[2, 4] >>> dI([Integer(3),Integer(1)])*dI([Integer(2),Integer(1)]) # long time (7s on sage.math, 2013) dI[1, 1, 5] - dI[1, 4, 1, 1] - dI[1, 4, 2] - 2*dI[1, 5, 1] - dI[1, 6] - dI[2, 4, 1] - dI[2, 5] - dI[3, 1, 3] + dI[3, 2, 1, 1] + dI[3, 2, 2] + dI[3, 3, 1] + dI[4, 1, 1, 1] + 2*dI[4, 2, 1] + dI[4, 3] + dI[5, 1, 1] + dI[5, 2] >>> F = QSym.F() >>> dI(F[Integer(1),Integer(3),Integer(1)]) -dI[1, 1, 1, 2] + dI[1, 1, 2, 1] - dI[1, 2, 2] + dI[1, 3, 1] >>> F(dI(F([Integer(2),Integer(1),Integer(3)]))) F[2, 1, 3]
- from_polynomial(f, check=True)[source]¶
Return the quasi-symmetric function in the Monomial basis corresponding to the quasi-symmetric polynomial
f
.INPUT:
f
– a polynomial in finitely many variables over the same base ring asself
. It is assumed that this polynomial is quasi-symmetric.check
– boolean (default:True
); checks whether the polynomial is indeed quasi-symmetric
OUTPUT: quasi-symmetric function in the Monomial basis
EXAMPLES:
sage: P = PolynomialRing(QQ, 'x', 3) sage: x = P.gens() sage: f = x[0] + x[1] + x[2] sage: QSym = QuasiSymmetricFunctions(QQ) sage: QSym.from_polynomial(f) M[1]
>>> from sage.all import * >>> P = PolynomialRing(QQ, 'x', Integer(3)) >>> x = P.gens() >>> f = x[Integer(0)] + x[Integer(1)] + x[Integer(2)] >>> QSym = QuasiSymmetricFunctions(QQ) >>> QSym.from_polynomial(f) M[1]
Beware of setting
check=False
:sage: f = x[0] + 2*x[1] + x[2] sage: QSym.from_polynomial(f, check=True) Traceback (most recent call last): ... ValueError: x0 + 2*x1 + x2 is not a quasi-symmetric polynomial sage: QSym.from_polynomial(f, check=False) M[1]
>>> from sage.all import * >>> f = x[Integer(0)] + Integer(2)*x[Integer(1)] + x[Integer(2)] >>> QSym.from_polynomial(f, check=True) Traceback (most recent call last): ... ValueError: x0 + 2*x1 + x2 is not a quasi-symmetric polynomial >>> QSym.from_polynomial(f, check=False) M[1]
To expand the quasi-symmetric function in a basis other than the Monomial basis, the following shorthands are provided:
sage: M = QSym.Monomial() sage: f = x[0]**2+x[1]**2+x[2]**2 sage: g = M.from_polynomial(f); g M[2] sage: F = QSym.Fundamental() sage: F(g) -F[1, 1] + F[2] sage: F.from_polynomial(f) -F[1, 1] + F[2]
>>> from sage.all import * >>> M = QSym.Monomial() >>> f = x[Integer(0)]**Integer(2)+x[Integer(1)]**Integer(2)+x[Integer(2)]**Integer(2) >>> g = M.from_polynomial(f); g M[2] >>> F = QSym.Fundamental() >>> F(g) -F[1, 1] + F[2] >>> F.from_polynomial(f) -F[1, 1] + F[2]
- class phi(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric functions in the \(\phi\) basis.
The \(\phi\) basis is defined as a rescaled Hopf dual of the \(\Phi\) basis of the non-commutative symmetric functions (see Section 3.1 of [BDHMN2017]), where the pairing is
\[(\phi_I, \Phi_J) = z_I \delta_{I,J},\]where \(z_I = 1^{m_1} m_1! 2^{m_2} m_2! \cdots\) with \(m_i\) being the multiplicity of \(i\) in the composition \(I\). Therefore, we call these the quasi-symmetric power sums of the second kind.
Using the duality, we can directly define the \(\phi\) basis by
\[\phi_I = \sum_{J \succ I} z_I / sp_{I,J} M_J,\]where \(sp_{I,J}\) is as defined in [NCSF].
The \(\phi\)-basis is well-defined only when the base ring is a \(\QQ\)-algebra.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: phi = QSym.phi(); phi Quasisymmetric functions over the Rational Field in the phi basis sage: phi.an_element() 2*phi[] + 2*phi[1] + 3*phi[1, 1] sage: p = SymmetricFunctions(QQ).p() sage: phi(p[2,2,1]) phi[1, 2, 2] + phi[2, 1, 2] + phi[2, 2, 1] sage: all(sum(phi(list(al)) for al in Permutations(la))==phi(p(la)) for la in Partitions(6)) True sage: p = SymmetricFunctions(QQ).p() sage: phi(p[3,2,2]) phi[2, 2, 3] + phi[2, 3, 2] + phi[3, 2, 2]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> phi = QSym.phi(); phi Quasisymmetric functions over the Rational Field in the phi basis >>> phi.an_element() 2*phi[] + 2*phi[1] + 3*phi[1, 1] >>> p = SymmetricFunctions(QQ).p() >>> phi(p[Integer(2),Integer(2),Integer(1)]) phi[1, 2, 2] + phi[2, 1, 2] + phi[2, 2, 1] >>> all(sum(phi(list(al)) for al in Permutations(la))==phi(p(la)) for la in Partitions(Integer(6))) True >>> p = SymmetricFunctions(QQ).p() >>> phi(p[Integer(3),Integer(2),Integer(2)]) phi[2, 2, 3] + phi[2, 3, 2] + phi[3, 2, 2]
Checking the equivalent definition of \(\phi_n\):
sage: def test_phi(n): ....: phi = QuasiSymmetricFunctions(QQ).phi() ....: Phi = NonCommutativeSymmetricFunctions(QQ).Phi() ....: M = matrix([[phi[I].duality_pairing(Phi[J]) ....: for I in Compositions(n)] ....: for J in Compositions(n)]) ....: def z(J): return J.to_partition().centralizer_size() ....: return M == matrix.diagonal([z(I) for I in Compositions(n)]) sage: all(test_phi(k) for k in range(1,5)) True
>>> from sage.all import * >>> def test_phi(n): ... phi = QuasiSymmetricFunctions(QQ).phi() ... Phi = NonCommutativeSymmetricFunctions(QQ).Phi() ... M = matrix([[phi[I].duality_pairing(Phi[J]) ... for I in Compositions(n)] ... for J in Compositions(n)]) ... def z(J): return J.to_partition().centralizer_size() ... return M == matrix.diagonal([z(I) for I in Compositions(n)]) >>> all(test_phi(k) for k in range(Integer(1),Integer(5))) True
- class psi(QSym)[source]¶
Bases:
CombinatorialFreeModule
,BindableClass
The Hopf algebra of quasi-symmetric functions in the \(\psi\) basis.
The \(\psi\) basis is defined as a rescaled Hopf dual of the \(\Psi\) basis of the non-commutative symmetric functions (see Section 3.1 of [BDHMN2017]), where the pairing is
\[(\psi_I, \Psi_J) = z_I \delta_{I,J},\]where \(z_I = 1^{m_1} m_1! 2^{m_2} m_2! \cdots\) with \(m_i\) being the multiplicity of \(i\) in the composition \(I\). Therefore, we call these the quasi-symmetric power sums of the first kind.
Using the duality, we can directly define the \(\psi\) basis by
\[\psi_I = \sum_{J \succ I} z_I / \pi_{I,J} M_J,\]where \(\pi_{I,J}\) is as defined in [NCSF].
The \(\psi\)-basis is well-defined only when the base ring is a \(\QQ\)-algebra.
EXAMPLES:
sage: QSym = QuasiSymmetricFunctions(QQ) sage: psi = QSym.psi(); psi Quasisymmetric functions over the Rational Field in the psi basis sage: psi.an_element() 2*psi[] + 2*psi[1] + 3*psi[1, 1] sage: p = SymmetricFunctions(QQ).p() sage: psi(p[2,2,1]) psi[1, 2, 2] + psi[2, 1, 2] + psi[2, 2, 1] sage: all(sum(psi(list(al)) for al in Permutations(la))==psi(p(la)) for la in Partitions(6)) True sage: p = SymmetricFunctions(QQ).p() sage: psi(p[3,2,2]) psi[2, 2, 3] + psi[2, 3, 2] + psi[3, 2, 2]
>>> from sage.all import * >>> QSym = QuasiSymmetricFunctions(QQ) >>> psi = QSym.psi(); psi Quasisymmetric functions over the Rational Field in the psi basis >>> psi.an_element() 2*psi[] + 2*psi[1] + 3*psi[1, 1] >>> p = SymmetricFunctions(QQ).p() >>> psi(p[Integer(2),Integer(2),Integer(1)]) psi[1, 2, 2] + psi[2, 1, 2] + psi[2, 2, 1] >>> all(sum(psi(list(al)) for al in Permutations(la))==psi(p(la)) for la in Partitions(Integer(6))) True >>> p = SymmetricFunctions(QQ).p() >>> psi(p[Integer(3),Integer(2),Integer(2)]) psi[2, 2, 3] + psi[2, 3, 2] + psi[3, 2, 2]
Checking the equivalent definition of \(\psi_n\):
sage: def test_psi(n): ....: psi = QuasiSymmetricFunctions(QQ).psi() ....: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() ....: M = matrix([[psi[I].duality_pairing(Psi[J]) ....: for I in Compositions(n)] ....: for J in Compositions(n)]) ....: def z(J): return J.to_partition().centralizer_size() ....: return M == matrix.diagonal([z(I) for I in Compositions(n)]) sage: all(test_psi(k) for k in range(1,5)) True
>>> from sage.all import * >>> def test_psi(n): ... psi = QuasiSymmetricFunctions(QQ).psi() ... Psi = NonCommutativeSymmetricFunctions(QQ).Psi() ... M = matrix([[psi[I].duality_pairing(Psi[J]) ... for I in Compositions(n)] ... for J in Compositions(n)]) ... def z(J): return J.to_partition().centralizer_size() ... return M == matrix.diagonal([z(I) for I in Compositions(n)]) >>> all(test_psi(k) for k in range(Integer(1),Integer(5))) True