Dear David, dear Andrew,

Sorry, for having introduced confusion here by going straight to the
details without explaining the general structure. What you describe is
essentially what we want to achieve, though with a different layout.
And I am very glad to see that we agree on the fundamental principles.

This layout is at the core of MuPAD-Combinat, and has been used
intensively for eight years. It has proven to be robust and practical
there, so I am pretty confident in replicating it into Sage. My poll
is more about syntactical details within this layout.

Let me try to restate the layout, this time on symmetric functions
because this gives more bases to play with. Also they are more
familiar objects. Let me postpone the syntax details for the moment,
and just use one of the possible options.

David: please, let me know if there are some issues raised in your
e-mail which are not addressed below. I kepts a record of your +1 / -1
when they applied.


General layout:
---------------

So we have (or should have, since it is not yet implemented this way
in Sage):

        sage: S = SymmetricFunctions(QQ)
        The abstract ring of symmetric functions

This is a parent, though an abstract one which has no elements by
itself. From this you can construct:

    sage: S.schur()
    The ring of symmetric functions, with elements expanded in the
    Schur basis

    sage: S.powersum()
    The ring of symmetric functions, with elements expanded in the
    powersum basis

    sage: S.elementary()
    The ring of symmetric functions, with elements expanded in the
    elementary basis

    ...

Those are again parents. Each of them models a concrete representation
of the ring of symmetric functions. In particular they are (among
other things) free modules. So we have:

    sage: S.elementary().basis()
    A family of elements of S.elementary(), indexed by partitions

They are also algebras. So we have:

    sage: S.elementary().algebra_generators()
    A family of elements of S.elementary(), indexed by positive integers

> Or one can create a class of homomorphisms and set up an isomorphism
> between an Hecke algebra in one basis to one in the other.

Yes. All the concrete representations are connected by isomorphisms
(though one certainly does not want to implement all binomial(b,2)
isomorphisms, since the number b of basis is >> 10). Those
isomorphisms are handled by the coercion system, which takes care of
transitivity.

Note: if s is a symmetric function expanded in the powersum basis,
then s.parent() is S.powersum(), not S. Among other things, this is
necessary to give the appropriate information to the coercion system.


> The module basis is also a set of ring generators, hence there is
> some ambiguity which of these two roles the basis elements are
> playing.

Yes, having no ambiguity is essential. Note that, in the layout above,
all the roles are clearly distinguished:

 - abstract algebra
 - concrete algebra
 - canonical basis of a concrete algebra
 - canonical algebra generators of a concrete algebra


So, now on to the rationale for the layout. Why is it important to
have this abstract ring of symmetric function:

    sage: S = SymmetricFunctions()

rather than just creating each basis independently?

Essentially because this gives a name to the abstract ring of
symmetric functions. Naming something is taking power over it :-)
In particular:

(1)One can use introspection to get the list of available basis. Note
   that the existence of certain basis may depend on the actual ground
   ring for example.

(2)One can use S(something) to coerce something into a symmetric
   functions, when we just want the result to be a symmetric function,
   without caring 

(3)One can use S[x] to define univariate polynomials with mixed
   coefficients which are all symmetric functions, but possibly
   expressed in different bases.

(4)One can store common information (cache for example) about
   symmetric functions in S.

(5)One can query general information about S without creating concrete
   representations.

(6)S is a natural place to declare most of the isomorphisms between
   the different basis. In fact, with Florent, we view S essentially
   as a database of mathematical informations: what are the concrete
   representations, what are the canonical isomorphisms. And speaking
   of that, there is also a category behind the scene in which all the
   concrete representations are; whether S and this category should
   coincide or not is left for future discussions.

(7)The parameters (base ring, Cartan type for Hecke algebras,
   variables for symmetric polynomials) only need to be specified once
   at the creation of S (usual Don't Repeat Yourself principle which
   among other things guarantees that all the bases are created
   consistently).

(8)cross references: each basis just needs to be aware of S; then they
   can easily refer to each other.

Let me use this occasion to thank Teresa Gomez-Diaz for her brilliant
idea, in MuPAD-Combinat and in connection with (3), of upgrading S
from merely a parametrized library/module (i.e. a computer science
object) into a full featured algebra (i.e. a mathematical object).


> Mathematically one might consider A and H to be canonically equal
> (the object being independent of the definition).  This can be
> acknowledged by defining A == H to be True, and supporting canonical
> coercions from one to the other.

Hmmm. Whether we should have

        S == S.elementary() == S.powersum() == ...

is an open question. My feeling is no. But most likely we do not
really care for now, and can postpone this decision until some
practical experience/application tells us what's right.



About short/long notations:
---------------------------

The examples above illustrate that the plan is to have long explicit
names for everything, including the various representations of an
algebra. This was not apparent in my example with the Hecke algebra
because, as far as I know, the (long) mathematical name for the T
basis is ... T. Yeah, that's bad, but that's how it is, and users will
be looking for this name.


About shorthands:
-----------------

> >      (4) Define a shorthand gadget, so that the user can do something like:
> >
> >              sage: H = HeckeAlgebra(...).shorthand
> >              sage: H.T( 3 + (2 * H.KL[2,1,2] + H.C[w]))
> >
> >          A variant for symmetric functions:
> >
> >              sage: S = SymmetricFunctions(QQ).shorthand
> >              sage: h = S.h; e = S.e
> >              sage: e( S.s[3] * S.m[3,1] ) + 3*h[4,1]
> >
> >          Such gadgets have full freedom to do play all the dirty
> >          tricks they wants, leaving the main code clean and robust.
> >
> >          Votes:
> 
> -1 -- shorthand notation should be long (enough to read).

Let me be precise. The purpose here is to support the analogue of what
we do everyday when writing mathematics, namely explicitly defining
shorthand notations before a calculation in order to have concise and
readable formulas:

    Using the notations of Macdonald, one has:
         s[3,2] = p( 1 + e[2,2,1] + ...).


> Instead, the user can do:
> 
> ss = S.symmetric_sum
> pp = S.power_sum
> for n in range(16):
>     for m in range(n):
>         sum([ (-1)**k*pp(n,k)*ss(n,m-k) for k in range(m+1)  ]) == 0

-1

We have had repeated (and strong!) requests from users of symmetric
functions for a one liner for getting the usual shortcuts for all the
classical bases. For once, the mathematical notations are quite
standardized in the community, and we ourselves found this very
practical: there are 5/10 of them, so redefining them all each time is
a pain.

In fact, I'd love to be able to do:

        from SymmetricFunctions(QQ).shorthands import *

Furthermore, providing the user with (optional but easy to load)
shorthands promotes their standardization among all users. This makes
it much easier for them to share worksheets / little calculations / ...

We could even have alternative sets of shorthands:

        from SymmetricFunctions(QQ).macdonald_shorthands import *
or:
        from SymmetricFunctions(QQ).lascoux_shorthands import *

Again in mathematics, one often writes "by abuse of notation, we
denote by T both the family (T_i)_{i=1,...,n} of generators and the
basis (T_w)_{w\in W}". This is quite essential to get concise
notations without too many symbols. And this is perfectly safe when
done in a well defined context. Of course, the user wants to do the
same when interactively typing in formulas into Sage. Implementing
such magical shorthands can be a bit tricky, if not treacherous, and
is certainly not a one-liner. So we want to make them available, upon
request, to the user.


About the syntactical details:
------------------------------

Accessing the generators of an algebra/module. Here are some options,
taking for example A = S.elementary():

(1)A.gens(ModulesWithBasis(QQ))         # module generators
   A.gens(Algebras(QQ))                 # algebra generators
   A.gens()                             # algebra generators by default?

(2)A.basis()                            # module generators
   A.algebra_generators()               # algebra generators

I actually would vote for combining the two. That is implementing (2),
and having A.gens(category) call them.

Indeed (2) is much more practical to implement: in particular it
allows for subclasses to easily override one of them without touching
(or not even being aware of) the other. Also, that's where the user
will most likely find them when there are standard mathematical names
like basis. On the other hand, it is nice to be able to ask
generically for the generators of A for a given category.

Oh, by the way: I never answered your e-mail about standardizing the
return type when querying for generators. ++1 on the principle.



> I write i as tuples (1,2,1) or (3,2,3,1) since they are immutable,

Yes, you are perfectly right. We should be using tuples
systematically. Sorry, I am still under the influence of MuPAD there :-)

Cheers,
                                Nicolas
--
Nicolas M. Thiéry "Isil" <nthi...@users.sf.net>
http://Nicolas.Thiery.name/

--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to 
sage-devel-unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to