1. Using predefined combinatorial algebras
We now demonstrate how to do sample computations with predefined combinatorial algebras, starting with the algebra of symmetric functions. Note that we really consider those predefined algebras as mere examples of use of this package; important and useful examples of course, but just examples.
We define the ring of symmetric functions over the rational numbers:
S := examples::SymmetricFunctions(Dom::Rational);
This ring has several remarkable families like the symmetric power-sums: recall that the symmetric power-sum expands on any given specified alphabet (i.e. set of variables) as the sum of all the variables elevated to the power ; furthermore, given a partition , the product of is denoted by :
p1 := S::p([1]);
p1([x, y, z]);
p2 := S::p([2]);
p2([x, y, z])
p421 := S::p([4, 2, 1]);
p421([x,y,z])
Note: the product being commutative, the order in which the terms appear in the expansion above depends on MuPAD internal order, and is mathematically irrelevant.
Actually, the ring of symmetric functions is the free commutative algebra on the symmetric power-sums:
p2 * p1 * p2 * p421
Note that any expression is immediately expanded by the system:
(p421 + 3*p2)*(1/4*p1 - p2)
This happens because the call S::p([1]) returns a typed object, for which the standard arithmetic operators are overloaded:
domtype(p1);
S::p
That is, S::powersum (or S::p for short) really represents the domain of symmetric functions expanded on the power-sums basis. If at some time you do not want the expansion to take place, the object can always be converted to an expression:
f := (expr(p421) + 3*expr(p2))*(1/4*expr(p1) - expr(p2))
This expression can be converted back to a symmetric function:
S(f);
To do this we use the following small trick because of the indexed notation for the basis elements.
eval(subs(f, p = S::p::domainWrapper))
The explanation of the trick is that S::p::domainWrapper is a special MuPAD object which, when used as S::p::domainWrapper[3,2], returns a call to S::p([3,2]).
Of course, examples::SymmetricFunctions provides the other classical bases of symmetric functions, like the elementary symmetric functions S::e, the monomial symmetric functions S::m, the homogeneous symmetric functions S::h, the Schur functions S::s, etc.:
expand(S::e([2])([x,y,z]))
expand(S::m([2, 1])([x,y,z]))
expand(S::h([2])([x,y,z]))
expand(S::s([2])([x,y,z]))
Here is how to convert from one basis to the other
:
f := S::p([4]);
S::e(f);
S::h(f);
S::s(f);
S::m(f)
When multiplying two symmetric functions which are not expressed in the same basis, the system makes an implicit conversion, and returns the result in the basis where the product has been computed:
S::p([2]) * S::s([2])
- s[2, 1, 1] + s[4] + s[2, 2]
A similar effect may occur when an operation is not available for a given basis. For example, the coproduct is not yet implemented for monomial functions. So, in the following, an implicit conversion occurs, and the computation is done within powersum functions:
S::coproduct(S::m([1, 1]))
If you want to force an operation to be computed or returned in a given basis, you can call the proper conversions explicitly before or after the operation:
S::p([2]) * S::p(S::s([2]));
S::s(S::p([2])) * S::s([2]) ;
S::p(S::p([2]) * S::s([2]))
Now, we combine everything, and do some complicated calculation:
S::p( S::m([1]) * ( S::e([3])*S::s([2]) + 1 ))
With most of the bases, the constructor accepts an argument which is not right away a partition, and does the natural straightening. For example, with a multiplicative basis the argument can be a composition, which will be sorted appropriately by commutativity:
S::e([2, 1, 3])
In the same vein, for the Schur basis, the argument can be either an integer vector (extension of the definition of Schur functions by the Jacobi formula to integer vectors), or a skew partition (to represent the corresponding skew Schur function):
S::s([[3, 3, 1], [2]])
S::s([7, 3, 0, 9, 4])
Finally, there is some support for Hall-Littlewood functions, in the and basis as well as for Mac Donald functions, which we demonstrate now. We need to take some ground field which contains the parameters and of those functions, and where those parameters are degree elements (in lambda-ring parlance). The easiest way (and actually the most efficient one with the current MuPAD version), is to take the following variation on MuPAD's field of expressions:
K := Dom::ExpressionFieldWithDegreeOneElements([t, q]):
S := examples::SymmetricFunctions(K, vHL=t, vMcd=q):
Here is the Hall-Littlewood function :
el := S::QP([3, 2, 1, 1])
The expansion of el in terms of Schur functions reads as:
S::s(el)
The expansion of el on the alphabet reads as:
expand(el([q, q*t]))