Discussion board for the specifications of the category Cat::ModuleWithSeveralBases.

Last time I meet non virtually with Jean-Christophe, he told me that he will need to implement in the near future a new combinatorial algebra. We spent some time with Nicolas to try to design a standard interface for combinatorial Hopf algebra on several basis. I've written this week-end an implementation for the algebraic part (addition and products are dealt with, but co-product are not supported, for the moment). Here is a short description. Please do beta-tests and comments.

I've created a new category Cat::ModuleWithSeveralBases.

Basis Changes

This category provide a simple way to declare bases change. Here is a excerpt from the code

/////////////////////////////////////////////////////////////////////////
// Basis change control
//////
    tableBasisChanges := toBeDefined; // The table of the changes of basis.
//  tableBasisChanges is an hash table of associations of the type
//      (basSource, basTarget) = basSourceTobasTargetChange
//  where basSourceTobasTargetChange is of the type
//      proc(x : basSource::basisIndices) : basTarget
//  and returns the image of the element basSource(x) expressed in basTarget.
//  * WARNING: to quickly take care of linearity, x is an *index* whereas
//    basSourceTobasTargetChange(x) is and *element* of the domain basTarget.
//  * Only the explicit change of basis must be declared here,
//    those who are computed by transitivity are being take care of
//    by the overloading mechanism.
//  * These functions can be built using the following default implementation
//    dom::invertBasisChange      // invert a change of basis
//    dom::transposeBasisChange   // transpose a change of basis
//////
    autoDefineBasisChanges := TRUE;
//  If autoDefineBasisChanges is TRUE, the system defines automatically the
//  inverse basis changes of each given basis changes and the transpose of
//  all basis changes for dual bases.
/////////////////////////////////////////////////////////////////////////

This later feature is particularly nice for experimental code. For production code, I prefer to set explicitly all needed basis change.

I've also done the necessary job so that there is nothing more to do if we want to define not only modules but algebras. So for the moment there is no need for a category Cat::?AlgebraWithSeveralBases. Does anybody see any usage ?

NicolasThiéry: not me, at least not yet

We will most likely encounter situations where it will be easier to define a basis change directly, and not by linearity (i.e. as a function dom1 -> dom2 instead of dom1::basis -> dom2). Think about basis change defined by some elimination process. What about having two tables, say tableBasisChanges and tableBasisChangesBasis?

FlorentHivert: Yes, I was thinking about something like that. Note that in my opinion, the two table should be filled coherently, for example this is needed for tensor product of bases changes.

What about basisChanges instead of tableBasisChanges? why not.

About transposeBasisChange: maybe this utility should be extended to deal with the dual of a linear map between any two domains? Typical application: define a coproduct A -> (A tensor A) by transposing a product mu: (A tensor A) -> A.

FlorentHivert: I think it works as such with the current implementation !!!

Duality and scalar product

I've also tried to deal with duality. This is done in several step:

All these entries can be set once for all automatically by providing to ModuleWithSeveralBases the two following entries:

    dual := ???; // dual ModuleWithSeveralBases.
    dualBasesPairs := {[base1,baseDual1]};

Moreover, all these can be set "at run time" with the following three methods:

(NicolasThiéry: what about declareBasis instead of addBasis? this sounds more uniform with the declare* functions from the operators library). Ok done...

It is a little bit tricky, but this will allow in the future for automatically defining bases by specifying the scalar product with a known basis, like macdonald functions defined in Stembridge SF package with a command dual_basis(newBasis, oldBasis, salarProduct)). Any comment about this particular point ? I insist that I modify some entries of some domain from the outside, after the domain has been created... Do you consider it as a good programming technique ?

NicolasThiéry: I try to avoid doing this technique, but there are cases where it's so much practical that it's worth using it, instead of some ugly contorsioning. What do you think of the following rule of thumb?

Example of usage

This provides highly configurable modules. I've written a full example which is in

   lib/EXAMPLE/SubsetsSpace.mu -> example::SubsetsSpace.

I manage to define a full algebra with 3 bases and a scalar product in a highly commented code ;-) in less than 100 lines !!!

Here Is the full code for further comments:

//////////////////////////////////////////////////////////////////////////
// This file demonstrate how to build a free module with several bases. //
//////////////////////////////////////////////////////////////////////////

// First we define some shortcut :
alias(SubSp  = examples::SubsetsSpace);      // The name of the space itself.
alias(SubSpT = examples::SubsetsSpaceTools); // The name of the tools placeholder.

// The domain SubSpt=examples::SubsetsSpaceTools is just a placeholder
// for containing the different bases. For technical reasons, these bases
// must be created *before* the module SubsetsSpace itself. So they cannot
// simply be placed in it.
// SubSpt can also be used to store other utilities, such as the combinatorial
// class of the indices, if it's not really useful outside of the definition of
// this free module (this is not the case here).
domain SubSpT
    info := "Helper tools for the domain 'examples::SubsetsSpace'";
end_domain:

// We define now the module expanded on its the different bases.
// The fundamental basis. It will be declared as Self Dual.
domain SubSpT::Fundamental(TheSet, Ring)
    category Cat::AlgebraWithBasis(Ring);
    inherits Dom::FreeModule(Ring,
                             combinat::subClass(combinat::subsets, TheSet));
// Put here the methods particular to this basis.
    info := "Domain for the subset space on the fundamental basis";
    basisName := hold(F);

    mult2Basis :=
    proc(s1: dom::basisIndices, s2: dom::basisIndices)
    begin
        dom::term(s1 intersect s2);
    end_proc;
end_domain:


// Another basis. We will furter declare the following basis change :
//   In_Set = \sum_{X \subset Set} F_X
domain SubSpT::In(TheSet, Ring)
    category Cat::AlgebraWithBasis(Ring);
    inherits Dom::FreeModule(Ring,
                             combinat::subClass(combinat::subsets, TheSet));
    info := "Domain for the subset space on the 'In' basis";
    basisName := hold(In);
// The product is computed by overloading so there is nothing to do.
end_domain:


// The dual basis of In. The basis change is
//    Out_Set = \sum_{Set\subset X} (-1)^(nops(X)-nops(Set)) F_X
// It will be computed automatically.
domain SubSpT::Out(TheSet, Ring)
    category Cat::AlgebraWithBasis(Ring);
    inherits Dom::FreeModule(Ring,
                             combinat::subClass(combinat::subsets, TheSet));
    info := "Domain for the subset space on the 'Out' basis";
    basisName := hold(Out);
//  The product is computed by overloading so there is nothing to do.
end_domain:


// The definition of the module itself.
///////////////////////////////////////
// We now place all these bases together, and declare the basis changes.
domain SubSp(TheSet : DOM_SET, Ring = Dom::Rational : DOM_DOMAIN)
    category Cat::ModuleWithSeveralBases(Ring);
    inherits Dom::BaseDomain;

    info := "examples::SubsetsSpace -- Example of use of ModuleWithSeveralBases";

// ut here the bases.
    Fundamental := SubSpT::Fundamental(TheSet, Ring);
    In          := SubSpT::In(TheSet, Ring);
    Out         := SubSpT::Out(TheSet, Ring);
// some useful shortcuts for bases.
    F           := dom::Fundamental;

// We declare the known basis changes.
    autoDefineBasisChanges := TRUE; // The undefined basis change are computed by
        // tansposition or inversion of matrices. For experimental purposes.

    tableBasisChanges := table(
        (dom::In, dom::F) = // subsetInABC(Set) = \sum_{X \subset Set} X
            proc(set : dom::In::basisIndices) : dom::F
                local xSet;
            begin
                dom::F::plus(dom::F::term(xSet) $
                                xSet in combinat::subsets::list(set));
            end_proc);

// We deal now with the duality scalar product.
    dual := dom; // The dual of this space.
// The pairs of dual bases.
// The pair [dom::Out, dom::In] will be automatically declared.
    dualBasesPairs := {[dom::F, dom::F], [dom::In, dom::Out]};

end_domain:

/////////////////////////
// Thats all folks !!! //
/////////////////////////

Todo and further improvement

What remains to do is :

As an improvement, I realize that if the user provide an entry called form example

   basesShortcut = {"s", "h", "p"};

it is possible using DOM::s::domainWrapper to allow very simply the creation of element with such command

    SymmetricFunction(s[1,3] + p[2]*p[2]).

And thus allow partially for copy paste. Note that this shortcut can be directly extracted out from the entry basisName of all the bases. Do you think this is a good idea ?

NicolasThiéry: YES, even if this won't work very well with non commutative algebras, and with fields which cannot be embeded into Dom::?ExpressionField (say Dom::?IntegerMod(3)).

It might be a good idea as well to provide a way for the user to define automatically the variables s, p, ... at the toplevel as the corresponding domainWrappers. Maybe export(?SymmetricFunctions) should do this?

Valid XHTML 1.0! Valid CSS!
Page Execution took real: 5.069, user: 2.110, sys: 0.280 seconds