1. Algebras with several bases

We start with an example of algebra with several bases. Let math be a finite set, and consider the free module math over the subsets of math. It is endowed with an algebra structure by extending the intersection operation by linearity. Implementing this algebra in MuPAD requires some helper tools; we put them inside a dummy domain called SubsetsSpaceTools to avoid polluting the global name space:

domain SubsetsSpaceTools

    info_str := "Helper tools for the domain 'SubsetsSpace'";

end_domain:

We now implement the module math with elements expanded on the fundamental basis denoted by math. There are two parameters: the set S and, as usual, the coefficient ring Ring. Note the use of combinat::subClass to define the combinatorial class of the subsets of S:

domain SubsetsSpaceTools::Fundamental(S, Ring)

    category Cat::AlgebraWithBasis(Ring);

    inherits Dom::FreeModule(Ring,

                 combinat::subClass(combinat::subsets,

                                    Parameters = S));

    info_str := "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:

Let us just recall that, in a free module, the entry dom::basisIndices contains the combinatorial class that indexes the bases of the module. Here, this is a shortcut for the combinatorial class:

  combinat::subClass(combinat::subsets, Parameters = S)

The module math has two other bases math and math that we describe below. We just declare them to MuPAD, without implementing the product:

domain SubsetsSpaceTools::In(S, Ring)

    category Cat::AlgebraWithBasis(Ring);

    inherits Dom::FreeModule(Ring,

                 combinat::subClass(combinat::subsets,

                                    Parameters = S));

    info_str := "The subset space on the 'In' basis";

    basisName := hold(In);

end_domain:

 

domain SubsetsSpaceTools::Out(S, Ring)

    category Cat::AlgebraWithBasis(Ring);

    inherits Dom::FreeModule(Ring,

                 combinat::subClass(combinat::subsets,

                                    Parameters = S));

    info_str := "The subset space on the 'Out' basis";

    basisName := hold(Out);

end_domain:

The module math is endowed with a scalar product which makes the fundamental basis math orthonormal. The math basis is then defined by the rule

math,

and the math basis is the dual basis of math with respect to the scalar product. This information is sufficient to define mathematically all the bases change in between math, math, and math by transposing and inverting matrices. The implementation follows the same compact line:

domain SubsetsSpace(S : DOM_SET,

             Ring = Dom::Rational : DOM_DOMAIN)

    category Cat::ModuleWithSeveralBases(Ring);

    inherits Dom::BaseDomain;

 

     info_str := "The subsets space on various bases";

 

     Fundamental := SubsetsSpaceTools::Fundamental(S, Ring);

    F           := dom::Fundamental; // a shortcut

    In          := SubsetsSpaceTools::In(S, Ring);

    Out         := SubsetsSpaceTools::Out(S, Ring);

 

     // When possible, define automatically basis changes by

    // transposition or inversion of matrices.

    autoDefineBasisChanges := TRUE;

 

     basisChangesBasis := table(

        (dom::In, dom::F) =

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

 

     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:

   The crucial line of the preceding code is the declaration of SubsetsSpace as a Cat::ModuleWithSeveralBases. This category provides helper tools for implementing modules which are represented on several modules. We just need to supply the basis changes from In to F (see basisChangesBasis) and to declare which bases are in duality (see dual and basisChangesBasis). The system then provides default implementations for the scalar products and the other changes of bases (see autoDefineBasisChanges), and provides the standard free module entries testtype and coeffRing together with the set of bases bases.

We define the free module spanned by the subsets of math and build some of its elements:

M1234 := SubsetsSpace({1, 2, 3, 4}):

el1   := M1234::F({1, 2});

el2   := M1234::In({1, 2})

math

math

The type checking works as usual:

testtype(el1, M1234), testtype(el2, M1234)

math

as well as the bases changes:

M1234::In(el1)

math

 

M1234::Out(el2)

math

The required matrix inversions are computed only once and remembered, so that later basis changes are considerably faster, at some memory cost.

Finally we check that algebra products and scalar products are handled correctly:

el1*el2

math

 

operators::scalar(el1, el2)

math

Products of Out elements are actually computed and returned in the F basis. As usual, an explicit conversion can be used to force the result back in the Out basis:

M1234::Out({1, 3, 4})*M1234::Out({2, 3});

math

 

M1234::Out(last(1))

math