(I forgot to cc my response to sage-combinat-devel.)

---------- Forwarded message ----------
From: John H Palmieri <jhpalmier...@gmail.com>
Date: Jun 23, 12:39 pm
Subject: an example of a graded algebra with basis
To: sage-algebra


On Jun 23, 12:06 pm, Florent Hivert <florent.hiv...@univ-rouen.fr>
wrote:





>       Hi John,

> > > 1. Your choice of using ``A[n]`` to return the degree `n` piece of `A` is
> > > not consistent with other "graded" algebras in Sage.

> > And given the lack of formal development of graded objects in Sage,
> > maybe now is the time to settle on a convention.

> > > For example:

> > > sage: sf = SymmetricFunctions(QQ)
> > > sage: s = sf.schur()
> > > sage: s[3]
> > > s[3]

> > > This returns an element of the algebra, and not the degree 3 homogoneous
> > > component. I wrote "graded" because the algebra is indeed graded, but Sage
> > > does not currently know about the grading.

> > > Personally, I strongly prefer the idea of using __getitem__ to access
> > > elements of the algebra, by passing data to construct an element of the
> > > indexing set. I really don't like to write

> > > sage: s.basis()(Partition([3]))

> > > to construct an element of the algebra.

> > > Instead, I suggest a method called homogeneous_component(n) that returns
> > > the degree n component. (This should be generic and pushed up to every
> > > GradedAlgebraWithBasis, and so you don't need to define it in your case.
> > > It would also have the benefit of showing up in tab completion.)

> > I would instead use _element_constructor_ to construct elements of the
> > algebra, so you would call A(data) instead of A[data].  This is
> > consistent with the coercion framework: you should use A(...) to
> > construct elements of A.

> > In mathematical notation, if I have a graded object M, then I would
> > write M_n or M^n to get the graded pieces, so in Sage, M[n] seems like
> > a reasonable approximation.

> I usually use M^{(n)} because the other notations conflict with power or any
> useful indexing. See my comments below.

(In homotopy theory, M^{(n)} can mean something else (the nth smash
power of M).)





> > If list[n] gives me the nth term of the
> > list, it feels natural that M[n] should give me the nth homogeneous
> > piece of a graded object.  I happen to think that M[n] returning the
> > nth homogeneous piece feels more natural than M[n] returning an
> > element of M.  In the case of an integer grading, there is also the
> > possibility of implementing M[m:n] to return the sum of several graded
> > pieces, or M[1:] or M[1:Infinity] to return the positively graded
> > part.  This notation just feels right to me.  Does anyone else have an
> > opinion?

> Yes, I have ! Object construction must be something different to
> coercion. Object construction is a kind of conversion which must be
> explicitely called whereas coercion can be implicit. If you don't make the
> difference you'll run into problems. Here is an example:

> Suppose that you have a ZZ-algebra A whose basis is indexed by ZZ+. You can
> imagine for example something isomorphic to ZZ[X]. The the implicit coercion
> which is equivalent to the call ZZ(2) returns the canonical embeding of ZZ
> into A. In the example of A=ZZ[X] you'll get 2*X^0 which is quite different to
> X^2. The construction 2 -> X^2 must be something explicit and use a different
> syntax from conversion.

Absolutely A(2) should be the coercion of the integer 2 into A.  For
the construction 2 -> x^2, I think that something like A((2,)) or
A([2]) is not so bad: in the _element_constructor_ method, test
whether the input is a list or tuple and act accordingly.  (The
_element_constructor_ method gets used in coercion, but it doesn't
itself implement coercion.  That is, if you allow a tuple as an input
to this method, you won't suddenly be able to multiply tuples by
algebra elements.  I think of _element_constructor_ as a replacement
for __call__, one which is automatically plugged into the coercion
framework.  As such, _element_constructor_ can take lots of different
kinds of input, like tuples or dictionaries, with no repercussions on
coercion.) Also, A.term((2,)) is an easy and relatively painless way
to do it, as long as A is constructed as a CombinatorialFreeModule.
Or define a method with a new name and do A.new(2).

> So my opinion is: due to the rigidity of Python's syntax (which is probably a
> good thing) there are very few short notation such as () []. The meaning you
> want to have largely depends on the point of view you have on the objects and
> the usage you'll have. So when designing generic interface, I'd rather being
> very explicit and leave it to the user to define or not those kinds of
> shorthand.

Okay.  I may very well leave it in the example, with appropriate
comments...

> So if it feel right in the context of symmetric function to use
> them as element construction, let's use it but I'd rather not making a rule
> and making it very easy for the user to define such shorthand. For John: in
> this context, we most of the tim deals with homogeneous element, so that it
> will really be a waste to reserve the shorthand notation [.] for something
> never used.

For situations I deal with, I want to deal with homogeneous pieces
frequently, so being able to use A[n] is useful.

> In short:

> +1 to have s[1] construction a symmetric function but this shouldn't be a
> general rule

> -1 to have s[n] generically return the n-th homogeneous component.

I think I also hear you say

-1 to have s[n] generically return an element of the algebra.

Is that right?

> +1 for x.homogeneous_component(n)

> > > 2. I wonder if your method basis_in_degree should be merged with basis: if
> > > no argument is specified, then default to the current behaviour (return a
> > > basis of the algebra); otherwise, return a basis of the degree n 
> > > component.

> > That seems like a good idea, although the printing of bases when
> > they're produced from infinite lazy families is perhaps less than
> > ideal.  We're overriding the basis method for a
> > CombinatorialFreeModule, but I guess with no arguments it should
> > return the old value, so it shouldn't break anything.

> It should be trivial to inherits from family and overload printing if
> needed.

Right now (using DisjointUnion...) it says something like

sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"),
degrees=(2, 3))
sage: A.basis()
Lazy family (Term map from Disjoint union of Lazy family
(<lambda>(i))_{i in Non negative integers} to An example of a graded
algebra with basis: the polynomial algebra on generators ('x', 'y') of
degrees (2, 3) over Rational Field(i))_{i in Disjoint union of Lazy
family (<lambda>(i))_{i in Non negative integers}}

or without DisjointUnion..., the output would be

Lazy family (Term map from Lazy family (<lambda>(i))_{i in Non
negative integer semiring} to Free module generated by Lazy family
(<lambda>(i))_{i in Non negative integer semiring} over Rational
Field(i))_{i in Lazy family (<lambda>(i))_{i in Non negative integer
semiring}}

I don't find this very helpful.





> +1 to standardize this mantra ie:
>   CFM.basis() returns the full basis
>   CFM.basis(args) can return parts of the basis (whatever it means)

>   GradedCFM.basis(deg) returns the basis for the deg-th graded component.

> > > 3. Right now, you are starting with a DisjointUnionEnumeratedSets
> > > constructed from a family:

> > > DisjointUnionEnumeratedSets(Family(NN, self._basis_fcn))

> > This choice was based on some discussions over the past few months in
> > sage-algebra and sage-combinat-devel.  I tried changing this to
> > Family(NN, self._basis_fcn) and got some weird doctest errors about
> > pickling, causing the TestSuite to fail.  So while what you say makes
> > sense, it causes problems for me.

> I'm quite interested to see that. If it's a problem with
> DisjointUnionEnumeratedSets, I really like to know about it and volunteering
> to fix it. Can you send an example of the problem (but maybe you already did
> and I don't remember).

If you apply the patch that I mentioned at the start of the thread and
then delete the use of DisjointUnionEnumeratedSets, that is, replace

  DisjointUnionEnumeratedSets(Family(NN, self._basis_fcn)),

with

  Family(NN, self._basis_fcn),

in the __init__ method, then you get doctest failures.  I haven't
tried to track it down.

--
John

-- 
You received this message because you are subscribed to the Google Groups 
"sage-combinat-devel" group.
To post to this group, send email to sage-combinat-de...@googlegroups.com.
To unsubscribe from this group, send email to 
sage-combinat-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sage-combinat-devel?hl=en.

Reply via email to