another coercion question

4 views
Skip to first unread message

John H Palmieri

unread,
Jul 17, 2008, 6:30:11 PM7/17/08
to sage-devel
I have several different vector space bases for an algebra A, and I
have implemented this by having a class MyAlgebra, instances of which
have an attribute _basis_name which is a string naming the basis. I
have __cmp__ defined so that the basis is ignored: any two instances
are canonically isomorphic, and there is good coercion between them.

Now, the attribute _basis_name just affects the _repr_ and _latex_
methods for elements of the algebra; it has no other effect. My
question is this: when I multiply elements from algebras with two
different bases, I can't figure out how the parent of the result is
determined. Some documentation suggests that the parent should be
determined by the left factor, but that is not consistently what's
happening.

I think I would like to force the result to have the same parent as
the left-hand factor, but by the time elements get to the _mul_
method, their parents have been changed (via coercion), so I can't
find out what that parent is. (Perhaps something is getting cached in
the coercion process, so things are getting coerced to the cached
algebra, not the left-hand parent?) What should I do? Does it sound
like I'm doing something wrong, and if so, what should I investigate?

I can try to post some sample code somewhere, but that will take a bit
of work. Or I can post short snippets here, of course.


Carl Witty

unread,
Jul 17, 2008, 7:51:05 PM7/17/08
to sage-devel
Currently it's built-in to coercion that if two parents are equal,
then it doesn't matter which parent it picks. (And the decision is
baked into various caches, etc., so the decision can depend on the
previous history of commands in this session.)

I've raised this issue as a problem a few weeks ago (see
http://groups.google.com/group/sage-devel/browse_thread/thread/4520ed454e705ce1#),
but nothing came of it yet.

Even if this gets fixed, I don't think you can fix it so that coercion
uses the parent of the left-hand value by changing your code; this
would require changes inside the base coercion code.

Carl

John H Palmieri

unread,
Jul 17, 2008, 8:11:59 PM7/17/08
to sage-devel
> I've raised this issue as a problem a few weeks ago (seehttp://groups.google.com/group/sage-devel/browse_thread/thread/4520ed...),
> but nothing came of it yet.
>
> Even if this gets fixed, I don't think you can fix it so that coercion
> uses the parent of the left-hand value by changing your code; this
> would require changes inside the base coercion code.

Okay, thanks. Here's something from Section 2.8 of the Sage
Programming Guide:

ARITHMETIC __add__, __mul__, ...:: When doing a binary operation, if
the parents are not identical (in the sense of is ), determine if
precisely one _coerce_ map is defined; if so, apply it and do the
arithmetic operation. If both are defined, the parents are canonically
isomorphic, so use the left one. If neither are defined, raise a
TypeError. (Whether or not there is a coerce map between objects
should be cached for efficiency.)

I guess you're saying that this is wrong (the part that says "so use
the left one").

> Carl

William Stein

unread,
Jul 18, 2008, 1:31:45 AM7/18/08
to sage-...@googlegroups.com

Argh. It was right when I wrote that documentation and implemented
the second version of the coercion model. :-) Whoever implemented
the third/fourth version(s) of the coercion model will I hope also
update the programming guide with correct statements (hint, hint
Robertwb).

-- william

Robert Bradshaw

unread,
Jul 18, 2008, 2:23:31 AM7/18/08
to sage-...@googlegroups.com

Yep, sorry. Do we want this behavior? (This could be done without too
much trouble.)

- Robert

John H Palmieri

unread,
Jul 18, 2008, 11:05:48 AM7/18/08
to sage-devel


On Jul 17, 11:23 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:
Given my lack of understanding of the coercion model, I'm probably not
the right person to have an opinion, but here I go anyway. The
absolute most important thing is that it be correctly documented.
After that, I would like the behavior to be predictable -- maybe I'm
imagining it, but it seems that the current behavior might depend on
the order in which various parents get cached. Finally, I think that
having the parent default to be the parent of the left factor (in the
situation discussed in the documentation) seems pretty innocuous and
is reasonable behavior.

John


> - Robert

Robert Bradshaw

unread,
Jul 18, 2008, 12:13:57 PM7/18/08
to sage-...@googlegroups.com

I consider the input of those *not* familiar with the model essential
in judging whether or not we have done anything sane.

> The absolute most important thing is that it be correctly documented.

Yes, and I am working on this. I am also adding much more
introspection into the model itself, like an "explain" method among
other things.

> After that, I would like the behavior to be predictable -- maybe I'm
> imagining it, but it seems that the current behavior might depend on
> the order in which various parents get cached.

Yes, that is correct. When it discovers the correct common parent for
a+b, it stores the result for b+a as well to save it work next time.
The only case where this may be ambiguous is if there is a map both
directions.

> Finally, I think that
> having the parent default to be the parent of the left factor (in the
> situation discussed in the documentation) seems pretty innocuous and
> is reasonable behavior.

Yes, I'll change this. I think the coercion model should act as if it
has no history (though it must cache things for speed), and this
seems like the most reasonable way to break symmetry.

- Robert


Dan Christensen

unread,
Jul 21, 2008, 3:06:06 PM7/21/08
to sage-...@googlegroups.com
John H Palmieri <jhpalm...@gmail.com> writes:

> I have several different vector space bases for an algebra A, and I
> have implemented this by having a class MyAlgebra, instances of which
> have an attribute _basis_name which is a string naming the basis. I
> have __cmp__ defined so that the basis is ignored: any two instances
> are canonically isomorphic, and there is good coercion between them.
>
> Now, the attribute _basis_name just affects the _repr_ and _latex_
> methods for elements of the algebra; it has no other effect.

I'd like to question this design. It seems odd to me to have two
different algebras which are identical except for how elements are
printed. In a sense, it would be like having different types
"int-base-10", "int-base-2", etc. for each way of printing an integer.

If I have an element of an algebra, I should request at the time I
convert to a string, which method of printing to use.

I realize that the attribute _basis_name is supposed to be a
convenience, but it does seem odd to have it.

Getting to your specific question about coercion, it appears that
this has to do with the difference between "is" and "==". And one
could argue that you shouldn't make things "==" if you care about
the differences between them.

Dan

John H Palmieri

unread,
Jul 21, 2008, 4:36:11 PM7/21/08
to sage-devel
On Jul 21, 12:06 pm, Dan Christensen <j...@uwo.ca> wrote:
> John H Palmieri <jhpalmier...@gmail.com> writes:
>
> > I have several different vector space bases for an algebra A, and I
> > have implemented this by having a class MyAlgebra, instances of which
> > have an attribute _basis_name which is a string naming the basis.  I
> > have __cmp__ defined so that the basis is ignored: any two instances
> > are canonically isomorphic, and there is good coercion between them.
>
> > Now, the attribute _basis_name just affects the _repr_ and _latex_
> > methods for elements of the algebra; it has no other effect.
>
> I'd like to question this design.  It seems odd to me to have two
> different algebras which are identical except for how elements are
> printed.  In a sense, it would be like having different types
> "int-base-10", "int-base-2", etc. for each way of printing an integer.

Hi Dan,

As you probably guessed, I'm talking about the Steenrod algebra here.
Suppose you like the Serre-Cartan basis, and I like the Wall basis.
Then you can always work with A = SteenrodAlgebra(p=2, basis='serre-
cartan'), while I can use B = SteenrodAlgebra(2, 'wall'). Then given
some calculation like 'x = Sq(6) * Sq(8)', you can do A(x) to see x in
your basis, and I can B(x) to see x in mine. Or you can just type 'x'
to see x in the default basis, the Milnor basis.

(One other issue with the Steenrod algebra is that there is no
standard way to represent elements, as opposed to the situation with
integers. The Milnor basis is the default in my package.)

By the way, I haven't implemented this, but the algebra defined at
different bases could differ in other ways, like ways of defining
elements of them. (For instance, A.Sq(3,1) could mean different
things depending on whether the basis for A was 'milnor' or 'serre-
cartan'. More likely, if A._basis_name were 'serre-cartan', then A
could have a different method, A.Sq_sc or A.admissible or something,
for defining elements of A in the Serre-Cartan basis.) Right now,
A.basis(n) gives a vector space basis for A in dimension n, in terms
of the basis which defines A; this is another small difference (which
has been implemented).

> If I have an element of an algebra, I should request at the time I
> convert to a string, which method of printing to use.

First, you can do this. You can evaluate 'x = Sq(2,2) * Sq(4)' --
these are Milnor basis elements, and an unadorned Sq is an element of
SteenrodAlgebra(2, 'milnor') -- and then you can evaluate 'x' (which
prints x in the Milnor basis), or 'x.basis('serre-cartan')' or
'x.basis('wall')' or 'x.basis(BASIS)' for any string BASIS which has
been implemented. For a few of these, there are other ways of calling
the method, like 'x.adem()' or 'x.serre_cartan()' instead of
'x.basis('serre-cartan'). Internally, this defines an algebra B to be
SteenrodAlgebra(2, BASIS), then evaluates B(x), the __call__method for
B, which does the basis conversion.

In other words, you can ignore the basis business for the
SteenrodAlgebra class, just use Sq to define elements, and use the
basis method to print it how you want.

Second, I tried doing this other ways, but without doing something
like this, my previous version of the basis method printed a string
and had a return value of None -- I couldn't figure out how to
actually return a meaningful value (like the original element) and
have it print the element in something other than the basis at which
the element was defined.

> I realize that the attribute _basis_name is supposed to be a
> convenience, but it does seem odd to have it.
>
> Getting to your specific question about coercion, it appears that
> this has to do with the difference between "is" and "==".  And one
> could argue that you shouldn't make things "==" if you care about
> the differences between them.

In this situation, I'm viewing == as meaning 'canonically isomorphic',
or something like that. If the only differences between two of these
algebras are the input and output formats for elements, I think it's
reasonable for them to be ==. That is, I'm viewing == as meaning that
the only differences between them are not mathematical, but
typographical. (Given my design choice, I suppose I can make the
different algebras fail to be ==, but I must still have them coerce to
each other, because that is mathematically what makes the most sense.
If the coercion model worked as documented -- see the rest of the
posts in the thread -- then the user could also predict the basis in
which the answer is printed.)

John

> Dan

Robert Bradshaw

unread,
Jul 23, 2008, 12:42:27 AM7/23/08
to sage-...@googlegroups.com

Different ways of printing stuff is a common issue in Sage, and there
has been talk of creating a more unified framework to deal with this.
(David Roe has a lot of ideas, but I don't think he's had the time to
implement anything along these lines yet...) Of course sometimes
there's the question of different internal representations as well,
which probably merit different parents.

>> I realize that the attribute _basis_name is supposed to be a
>> convenience, but it does seem odd to have it.
>>
>> Getting to your specific question about coercion, it appears that
>> this has to do with the difference between "is" and "==". And one
>> could argue that you shouldn't make things "==" if you care about
>> the differences between them.
>
> In this situation, I'm viewing == as meaning 'canonically isomorphic',
> or something like that. If the only differences between two of these
> algebras are the input and output formats for elements, I think it's
> reasonable for them to be ==. That is, I'm viewing == as meaning that
> the only differences between them are not mathematical, but
> typographical. (Given my design choice, I suppose I can make the
> different algebras fail to be ==, but I must still have them coerce to
> each other, because that is mathematically what makes the most sense.

I think the default will be that there is an assumed coercion if two
objects are ==, but perhaps this should be overrideable? One must
also remember that == is used, for instance, for stuff like keys in
hash tables.

> If the coercion model worked as documented -- see the rest of the
> posts in the thread -- then the user could also predict the basis in
> which the answer is printed.)

Yep, it will...

- Robert

John H Palmieri

unread,
Jul 23, 2008, 5:09:46 PM7/23/08
to sage-devel


On Jul 22, 9:42 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:
Well then, in case it helps convince anyone that my current
implementation is not unreasonable, David Roe actually suggested this
implementation -- using different parents for different output format
-- after looking at my older Steenrod algebra code.

William Stein

unread,
Jul 24, 2008, 4:32:07 AM7/24/08
to sage-...@googlegroups.com
>> Different ways of printing stuff is a common issue in Sage, and there
>> has been talk of creating a more unified framework to deal with this.
>> (David Roe has a lot of ideas, but I don't think he's had the time to
>> implement anything along these lines yet...) Of course sometimes
>> there's the question of different internal representations as well,
>> which probably merit different parents.
>
> Well then, in case it helps convince anyone that my current
> implementation is not unreasonable, David Roe actually suggested this
> implementation -- using different parents for different output format
> -- after looking at my older Steenrod algebra code

I like your current implementation too.

By the way, I'm really sorry it's taking so long for your code to get
fully refereed. I would just do it right now, to get it done, but I've
been so crazy busy this summer. I did install it into a branch on
my laptop though, so maybe I'll find time soon.

-- William

David Roe

unread,
Jul 24, 2008, 2:43:36 PM7/24/08
to sage-...@googlegroups.com

As am I (the person who was supposed to be doing it). Sorry it's been
so long. After this weekend I will have enough time to referee it.
David

Robert Bradshaw

unread,
Jul 30, 2008, 1:01:27 AM7/30/08
to sage-...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages