1. Combinatorial Hopf Algebras
Let us finish this tour by showing a small example of Hopf algebra: the free algebra over the integers, those being primitive for the coproduct (non commutative symmetric functions on one of the powersum bases):
domain FreeAlgebraInteger
inherits Dom::FreeModule(Dom::Rational,
combinat::compositions);
category Cat::GradedHopfAlgebraWithBasis(Dom::Rational);
basisName := hold(P);
exprTerm := dom::exprTermIndex;
one := dom::term([]);
mult2Basis := dom::term @ _concat;
coproductBasis :=
proc(compo : dom::basisIndices)
local i, tens;
begin
tens := dom::tensorSquare;
tens::mult(tens::plus2(tens::term([[i], []]),
tens::term([[], [i]]))
$ i in compo);
end_proc;
end_domain:
alias(NCSF = FreeAlgebraInteger):
Here is a sample coproduct computation:
tens := operators::coproduct(NCSF([2, 1, 3]))
To improve the readability, we use # (iso-latin-1 character of code 248) as symbol for the tensor product:
operators::setTensorSymbol("#"):
tens
P([2, 3]) # P([1]) + P([1, 3]) # P([2]) + P([2, 1]) # P([3]) +
P([3]) # P([2, 1]) + P([1]) # P([2, 3]) + P([2]) # P([1, 3]) +
P([]) # P([2, 1, 3]) + P([2, 1, 3]) # P([])
# can be used as well to type in tensor products:
NCSF([1,2]) # NCSF([1])
P([1, 2]) # P([1])
The product of NCSF is naturally extended to , so that we can compute expressions such as:
tens * (NCSF([1,2]) # NCSF([1]))
P([2, 1, 3, 1, 2]) # P([1]) + P([2, 1, 2]) # P([1, 3, 1]) +
P([1, 1, 2]) # P([2, 3, 1]) + P([3, 1, 2]) # P([2, 1, 1]) +
P([2, 1, 1, 2]) # P([3, 1]) + P([1, 3, 1, 2]) # P([2, 1]) +
P([2, 3, 1, 2]) # P([1, 1]) + P([1, 2]) # P([2, 1, 3, 1])
Note that a new domain representing the tensor square has been automatically created:
domtype(tens)
Dom::TensorProductOfFreeModules([FreeAlgebraInteger, FreeAlgebraInteger])
Since NCSF is a graded connected bi-algebra, it is automatically a Hopf algebra, whose antipode can be computed recursively (in a slow way):
operators::antipode(NCSF([2, 1, 3]))
Of course, in the case of NCSF, it would have been much more efficient to implement the direct combinatorial formula for the antipode:
antipodeBasis :=
comp -> dom::monomial(-1^nops(comp), revert(comp)):
Another very useful feature is the possibility to define tensor product of maps:
idTensorAntipode := operators::tensorProductOfMaps(
[id, NCSF::antipode],
NCSF::tensorSquare,
NCSF::tensorSquare):
idTensorAntipode(tens)
- P([2, 3]) # P([1]) - P([1, 3]) # P([2]) - P([2, 1]) # P([3]) +
P([3]) # P([1, 2]) + P([1]) # P([3, 2]) + P([2]) # P([3, 1]) -
P([]) # P([3, 1, 2]) + P([2, 1, 3]) # P([])
We conclude by using this feature to check, on some examples, that the antipode is correct:
es := NCSF::mu @ idTensorAntipode @ NCSF::coproduct:
es(NCSF([2, 1]));
es(NCSF([]));