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]))

math

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 math, 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]))

math

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([]));

math

math