Bidirectional coercions?

7 views
Skip to first unread message

Simon King

unread,
Nov 27, 2010, 4:15:11 AM11/27/10
to sage-algebra
Hi!

Sometimes I am not sure where to post my questions - I think there are
too many Sage lists.

Anyway. On sage-nt, I asked about coercions of number fields. In a not-
yet-published version of my patch for #8800, I arranged coercion of
"number fields with prescribed embeddings" so that there may both be a
coercion from L1 to L2 and from L2 to L1, where L1 and L2 are both
embedded into a common ambient field, K.

David Roe commented: "I think we should avoid coercion maps going in
both directions when possible."

This is certainly something that is not restricted to number theory
but concerns algebra in general. So, I hope here is the right list to
raise the question:

Let L1 and L2 be two parents that aren't equal. Assume that there is a
canonical parent K that may be used as a pushout. Assume further that
in principle one could define a coercion both from L1 to L2 and from
L2 to L1, but there is no canonical way to pick only one of the two
directions.

What do you think?
(1) Should one define coercions in both directions? Then, arithmetic
between elements of L1 and L2 would take place in the parent of the
left operand, IIRC.
Or
(2) Should one have coercion neither from L1 to L2 nor from L2 to L1,
but have K as the pushout of L1 and L2? Then, arithmetic between
elements of L1 and L2 would take place in K.

I am in favour of (1). Namely, with (2), it could happen that L1 is a
"number field with embedding", L2 is a cyclotomic field (which is a
special case of a number field with embedding), and K is the complex
double field; and arithmetic involving three different fields that are
even of different types seems complicated and should be avoided, IMO.

Cheers,
Simon

Nicolas M. Thiery

unread,
Nov 27, 2010, 5:48:49 AM11/27/10
to sage-a...@googlegroups.com, sage-comb...@googlegroups.com
Hi Simon!

(for Sage-Combinat folks: this e-mail is mostly about our beloved
cycles in the coercion graph; see below)

On Sat, Nov 27, 2010 at 01:15:11AM -0800, Simon King wrote:
> Sometimes I am not sure where to post my questions - I think there
> are too many Sage lists.

Yes. In a perfect world, there would be a single sage list, and
threads would be tagged by keywords so that people interested in just
a few topics would ask to follow only the matching threads.

> Anyway. On sage-nt, I asked about coercions of number fields. In a not-
> yet-published version of my patch for #8800, I arranged coercion of
> "number fields with prescribed embeddings" so that there may both be a
> coercion from L1 to L2 and from L2 to L1, where L1 and L2 are both
> embedded into a common ambient field, K.
>
> David Roe commented: "I think we should avoid coercion maps going in
> both directions when possible."

I can't comment on the use case at hand. But in Sage-Combinat we do
have a lot of use cases where we really want to have coercion maps in
both directions; more generally, we have large strongly connected
components in the coercion graph. That happens when we have several
implementations of the same algebra, typically depending on which
basis the elements are expanded on; see:

sage: S = Sets()
sage: S.WithRealizations?

There is a single caveat: namely that the current coercion
implementation does not handle those well (see #8878). It's been on my
todo list for a long time, and I spent a hard week of work last spring
implementing this; the patch is in the Sage-Combinat queue, but
guarded out since it is not yet fully ready for general use: coercion
is used throughout the Sage library and is a pretty sensitive point;
there are still a couple issues that need to be fixed. It's my plan to
work on this early next year when my teaching load will be down. I
could use a hand discussing a couple fine technical points and fixing
the remaining issues.

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

Mike Hansen

unread,
Nov 27, 2010, 2:09:39 PM11/27/10
to sage-a...@googlegroups.com, sage-comb...@googlegroups.com
On Sat, Nov 27, 2010 at 2:48 AM, Nicolas M. Thiery
<Nicolas...@u-psud.fr> wrote:
> I can't comment on the use case at hand. But in Sage-Combinat we do
> have a lot of use cases where we really want to have coercion maps in
> both directions; more generally, we have large strongly connected
> components in the coercion graph.

Do you really want to have coercion maps in both directions, or rather
just conversion maps?

> There is a single caveat: namely that the current coercion
> implementation does not handle those well (see #8878).

The examples there are conversion than coercion.

--Mike

Simon King

unread,
Nov 27, 2010, 2:20:48 PM11/27/10
to sage-algebra
Hi Mike!

On 27 Nov., 20:09, Mike Hansen <mhan...@gmail.com> wrote:
> On Sat, Nov 27, 2010 at 2:48 AM, Nicolas M. Thiery <Nicolas.Thi...@u-psud.fr> wrote:
> ...
> > There is a single caveat: namely that the current coercion
> > implementation does not handle those well (see #8878).
>
> The examples there are conversion than coercion.

Re conversion: Actually conversion of number fields produces errors
far too often. Essentially, conversion for number fields only works if
there is a coercion. But that's a different problem.

Note that http://www.sagemath.org/doc/reference/coercion.html
explicitly states (explaining what happens if a+b is evaluated, with a
in A and b in B): "These rules are evaluated in order; therefore if
there are coercions in both directions, then the parent of a._add_b is
A – the parent of the left-hand operand is used in such cases."

So, the inventors of Sage's coercion model explicitly thought about
the case of bidirectional coercion. But is there a "canonical" example
in Sage of two parents that have coercions in both directions? If such
example is already in use, I would not hesitate to introduce
bidirectional coercion for embedded number fields as well.

Cheers,
Simon

Nicolas M. Thiery

unread,
Nov 27, 2010, 3:43:20 PM11/27/10
to sage-comb...@googlegroups.com, sage-a...@googlegroups.com
On Sat, Nov 27, 2010 at 11:22:40AM -0800, Anne Schilling wrote:
> On 11/27/10 11:09 AM, Mike Hansen wrote:
> >>I can't comment on the use case at hand. But in Sage-Combinat we do
> >>have a lot of use cases where we really want to have coercion maps in
> >>both directions; more generally, we have large strongly connected
> >>components in the coercion graph.
> >
> >Do you really want to have coercion maps in both directions, or rather
> >just conversion maps?

coercion, so that mixed arithmetic works smoothly.

> >>There is a single caveat: namely that the current coercion
> >>implementation does not handle those well (see #8878).
> >
> >The examples there are conversion than coercion.

Ok, I should add a test there with a coercion :-)

> I remember that we ran into trouble with the coercion maps at Sage Days 20.5
> for symmetric functions subspaces/quotients. But as far as I remember in that
> setting only conversions were needed in principle.
>
> But perhaps Nicolas could confirm?

Yes, and it was an instance of #8878. I don't remember if we ran into
problem with coercion or conversion, but in any cases we want both.

Nicolas M. Thiery

unread,
Nov 27, 2010, 3:46:38 PM11/27/10
to sage-a...@googlegroups.com, sage-comb...@googlegroups.com
On Sat, Nov 27, 2010 at 11:20:48AM -0800, Simon King wrote:
> So, the inventors of Sage's coercion model explicitly thought about
> the case of bidirectional coercion. But is there a "canonical"
> example in Sage of two parents that have coercions in both
> directions? If such example is already in use, I would not hesitate
> to introduce bidirectional coercion for embedded number fields as
> well.

SymmetricFunctions.

That use case was also at the root of the design of the coercion model
I wrote for MuPAD (back in 2003).

Simon King

unread,
Nov 27, 2010, 4:44:49 PM11/27/10
to sage-algebra
Hi Nicolas,

On 27 Nov., 21:46, "Nicolas M. Thiery" <Nicolas.Thi...@u-psud.fr>
wrote:
> On Sat, Nov 27, 2010 at 11:20:48AM -0800, Simon King wrote:
> > So, the inventors of Sage's coercion model explicitly thought about
> > the case of bidirectional coercion.  But is there a "canonical"
> > example in Sage of two parents that have coercions in both
> > directions? If such example is already in use, I would not hesitate
> > to introduce bidirectional coercion for embedded number fields as
> > well.
>
> SymmetricFunctions.

The documentation of SymmetricFunctions has a lot of "todo" and "not
implemented", which gives the impression that it is not really ready
to be used. And, as I mentioned in a different thread a couple of
months ago, I don't understand how one really works with these
"algebras with basis". But anyway.

Do you think of an example like this one?

sage: Sym = SymmetricFunctions(QQ)
sage: p = Sym.powersum()
sage: e = Sym.elementary()
sage: p.one()+e.one()
2*p[]
sage: e.one()+p.one()
2*e[]

So, we have two copies of "the same" algebra with two different bases.
That is certainly a setting where coercions in both directions should
exist (after all, coercion is here just a basis change), and, as one
sees above, indeed the left summand determines the parent of the sum.

The question is whether two number fields with different embeddings
are to be treated like an algebra with different bases.

To give you a concrete example:
sage: P.<x> = QQ[]
sage: K.<r4> = NumberField(x^4-2)
sage: L1.<r2_1> = NumberField(x^2-2, embedding = r4**2)
sage: L2.<r2_2> = NumberField(x^2-2, embedding = -r4**2)

There are canonical maps from L1 to L2 and from L2 to L1 compatible
with the given embeddings into K, namely:
sage: from sage.rings.number_field.number_field_morphisms import
EmbeddedNumberFieldMorphism
sage: EmbeddedNumberFieldMorphism(L1,L2,K)
Generic morphism:
From: Number Field in r2_1 with defining polynomial x^2 - 2
To: Number Field in r2_2 with defining polynomial x^2 - 2
Defn: r2_1 -> -r2_2
sage: EmbeddedNumberFieldMorphism(L2,L1,K)
Generic morphism:
From: Number Field in r2_2 with defining polynomial x^2 - 2
To: Number Field in r2_1 with defining polynomial x^2 - 2
Defn: r2_2 -> -r2_1

So, should we have
sage: L1.has_coerce_map_from(L2)
True
sage: L2.has_coerce_map_from(L1)
True
sage: r2_1+r2_2
0
sage: parent(r2_1+r2_2) is L1
True
sage: parent(r2_2+r2_1) is L2
True
?

Or should we use the embeddings into K in order to produce a pushout?
That's to say, should we better have
sage: parent(r2_1+r2_2) is K
True
?

Best regards,
Simon

Nicolas M. Thiery

unread,
Nov 27, 2010, 5:03:11 PM11/27/10
to sage-a...@googlegroups.com, sage-comb...@googlegroups.com
On Sat, Nov 27, 2010 at 01:44:49PM -0800, Simon King wrote:
> The documentation of SymmetricFunctions has a lot of "todo" and "not
> implemented", which gives the impression that it is not really ready
> to be used.

It is actually used intensively by quite a few people around. But
precisely because it is such a central tool for us, there are a lot of
features (Hopf structure) that we want to have. Hopefully soon ...

> And, as I mentioned in a different thread a couple of
> months ago, I don't understand how one really works with these
> "algebras with basis". But anyway.

> Do you think of an example like this one?
>
> sage: Sym = SymmetricFunctions(QQ)
> sage: p = Sym.powersum()
> sage: e = Sym.elementary()
> sage: p.one()+e.one()
> 2*p[]
> sage: e.one()+p.one()
> 2*e[]

Precisely.

> So, we have two copies of "the same" algebra with two different bases.
> That is certainly a setting where coercions in both directions should
> exist (after all, coercion is here just a basis change), and, as one
> sees above, indeed the left summand determines the parent of the sum.

Yup.

> The question is whether two number fields with different embeddings
> are to be treated like an algebra with different bases.

The key point is: are the two algebraic structures canonically isomorphic?

"canonically isomorphic" means in particular that the coercion graph
shall be a commutative diagram. I don't have a good view on your
specific problem, but it sounds like this is not the case
(L1 -> L2 -> C does not do the same as L1 -> C).

Simon King

unread,
Nov 27, 2010, 5:18:32 PM11/27/10
to sage-algebra
Hi Nicolas,

On 27 Nov., 23:03, "Nicolas M. Thiery" <Nicolas.Thi...@u-psud.fr>
wrote:
> > The question is whether two number fields with different embeddings
> > are to be treated like an algebra with different bases.
>
> The key point is: are the two algebraic structures canonically isomorphic?
>
> "canonically isomorphic" means in particular that the coercion graph
> shall be a commutative diagram. I don't have a good view on your
> specific problem, but it sounds like this is not the case
> (L1 -> L2 -> C does not do the same as L1 -> C).

No, it does do the same: The map from L1 to L2 sends r2_1 to -r2_2,
and the map from L2 to K sends this to r4^2. But the map from L1 to K
sends r2_1 to r4^2 as well.

So, EmbeddedNumberFieldMorphism does form a commutative diagram with
the embeddings. That's is why I thought that it is the right tool to
construct a coercion.

Cheers,
Simon

David R. Kohel

unread,
Nov 27, 2010, 5:55:03 PM11/27/10
to sage-a...@googlegroups.com, sag...@googlegroups.com
Hi,

I should just emphasize that coercions (applied automatically) must
be canonical. There were some coercion problems in Magma precisely
with number fields K, L, with K a subfield of L, and K', isomorphic
to K, which created non-commuting coercion diagrams by "recognizing"
K' as "equal" to K (same defining polynomial), then using K' -> K
and K -> L for the coercion.

In general, if two non-equal fields have not been constructed with
a coercion between then then no choice should be made. I don't
see how one can choose any coercion between a cyclotomic field with
embedding and another number field which does not come equipped
with an embedding in a common field.

Thus for Simon's question 1, I agree (with Sage) that there should
be no coercion. For question 2, I wouldn't want or expect coercion
to move outside of the given parents (and certainly not outside of
the domain of number fields). For question 3, I would only return
something which is categorically defined -- the pushout of (K,K->F)
and (L,L->F) should be again a minimal field M with embedding M->F
whose image contains the images of K and L, right? Returning
(F, id:F->F) would be mathematically wrong. Most likely the
determination of such a field would be expensive and not something
that one would to be invoked by automatic coercion.

Cheers,

David

Simon King

unread,
Nov 28, 2010, 3:40:58 AM11/28/10
to sage-algebra
Hi David,

On 27 Nov., 23:55, "David R. Kohel" <ko...@iml.univ-mrs.fr> wrote:
> I should just emphasize that coercions (applied automatically) must
> be canonical.

Agreed. But, see below, there is "mathematically canonical" and
"computationally canonical".

And keep in mind that my original question was a "social" (i.e., not a
mathematical) question, namely if you agree with David Roe's
statement: "I think we should avoid coercion maps going in both
directions when possible." I do not agree with that statement.

Now for mathematics/computer algebra:

PART 1: Coercion for embedded number fields

1.(a) Both number fields are embedded

>  There were some coercion problems in Magma precisely
> with number fields K, L, with K a subfield of L, and K', isomorphic
> to K, which created non-commuting coercion diagrams by "recognizing"
> K' as "equal" to K (same defining polynomial), then using K' -> K
> and K -> L for the coercion.  

Hang on, it seems that you misunderstood my example.

In the situation I was exposing in my post, we have
* L1 is given with an embedding into K
* L2 is given with an embedding into K
So, these embeddings are not chosen by the coercion system: They are
part of the definition.

And then I suggested to consider EmbeddedNumberFieldMorphism. The
documentation says:
"""
This allows one to go from one number field in another
consistently, assuming they both have specified embeddings into
an
ambient field (by default it looks for an embedding into CC).
"""

> In general, if two non-equal fields have not been constructed with
> a coercion between then then no choice should be made.

It depends on how serious we can take the statement "This allows one
to go from one number field in another consistently".

Has EmbeddedNumberFieldMorphism the property that the composition of
the map from (K1->L) to (K2->L) with the map from (K2->L) to (K3->L)
is the same as the map from (K1->L) to (K3->L), and of course the map
from (K->L) to itself is the identity?
If "yes" then what I suggest is not only structure preserving (the
maps commute with the embeddings of K1 and K2), but it is even
computationally consistent.

I should ask on sage-nt if EmbeddedNumberFieldMorphism really is
transitive. If it is, then I think there is no objection against using
it for coercion, unless one says that having coercion in both
directions is generally a bad idea.

1.(b) Only one of the fields has an embedding

>  I don't
> see how one can choose any coercion between a cyclotomic field with
> embedding and another number field which does not come equipped
> with an embedding in a common field.

I do not claim that there should be a coercion from the non-embedded
field to the cyclotomic field.

But I do claim that it would be mathematically consistent to have a
coercion from the cyclotomic field to the non-embedded field, of
course provided that sending generator to generator creates an
isomorphism: This would be the forgetful functor, and the forgetful
functor is canonical.

> Thus for Simon's question 1, I agree (with Sage) that there should
> be no coercion.

Do you say "There is no way to define coercion consistently in the
situation Simon described" (which may be wrong, depending on what
EmbeddedNumberFieldMorphism is doing), or do you say "Sometimes it is
better to have no coercion, even though one *could* do it" (which I
would accept as an answer to my social question)?

PART 2: Sage's pushout versus mathematical pushout.

> For question 2, I wouldn't want or expect coercion
> to move outside of the given parents (and certainly not outside of
> the domain of number fields).

That's my feeling as well. Of course, if both K and K' have an
embedding into L, it would be a canonical choice to use the embeddings
in order to do arithmetic between elements of K and K'; but it somehow
feels wrong, in particular if L is no number field.

>  For question 3, I would only return
> something which is categorically defined -- the pushout of (K,K->F)
> and (L,L->F) should be again a minimal field M with embedding M->F
> whose image contains the images of K and L, right?

A minimal field M containing the images is certainly the right thing
to do in an ideal world. But I expect that it would be too difficult
to find M algorithmically. Or is it implemented in Sage? Perhaps I'll
ask on sage-nt.

> Returning
> (F, id:F->F) would be mathematically wrong.

Why? How could that yield to inconsistent results?

Actually I considered the following (slightly more general):
We start with two embedded number fields, (K,K->F) and (K',K'->F').
Then, it should be fine to define pushout(K,K') := pushout(F,F'),
which is not given with an embedding in a bigger field (it is
trivially embedded in itself...). Reason: We have a canonical
embedding of F and of F' into pushout(F,F'), and hence the given
embeddings of K in F and K' in F' extend to a canonical embedding of K
and K' into pushout(F,F').

So, I think it makes sense to do arithmetic between elements of K and
K' in pushout(F,F'), of course unless there is a direct coercion
between K and K'. The question is again: Do we *want* to do arithmetic
in pushout(F,F')?

> Most likely the
> determination of such a field would be expensive and not something
> that one would to be invoked by automatic coercion.

Finding the minimal field might be too difficult.

But I think one should keep in mind that Sage's pushout is not a
pushout in the mathematical sense. It does rely on choices:
pushout(QQ,ZZ['x']) returning QQ['x'] and not Frac(ZZ['x']) does
involve a choice.
However, these choices are consistent thorought Sage. Hence, it is
computationally canonical, even if it is not mathematically canonical.

3. CONCLUSION

Perhaps I can now reformulate my "real" questions:
1. If there are computationally canonical isomorphisms (structure
preserving) between K and K', should they always be used as
bidirectional coercions between K and K'? Or do you agree with David
Roe that having coercions in both directions should be a rare
exception?
2. Given K and K': If there is a computationally canonical parent
structure L so that there is a coercion from both K and K' to L,
should L be used as pushout(K,K'), even though it is not a pushout in
the mathematical sense? Do you even think that the current behaviour
"pushout(QQ,ZZ['x'])==QQ['x']" is bad? Or do you think that one can
not paint the mathematical world black and white, and one has to admit
that sometimes a "computational pushout" is good enough and sometimes
it isn't?

Sorry for using so many words.

Cheers,
Simon

Burcin Erocal

unread,
Nov 28, 2010, 6:06:50 AM11/28/10
to sage-a...@googlegroups.com
Hi Simon,

On Sun, 28 Nov 2010 00:40:58 -0800 (PST)
Simon King <simon...@uni-jena.de> wrote:

> 3. CONCLUSION
>
> Perhaps I can now reformulate my "real" questions:
> 1. If there are computationally canonical isomorphisms (structure
> preserving) between K and K', should they always be used as
> bidirectional coercions between K and K'? Or do you agree with David
> Roe that having coercions in both directions should be a rare
> exception?

I really think having bidirectional coercions would be very confusing
for users in the long term. I can imagine long, frustrating debugging
sessions where people are bitten by the fact that a + b doesn't have
the same parent as b + a in Sage.

IMHO, this discussion also goes against several principles from the Zen
of Python.

sage: import this
The Zen of Python, by Tim Peters

...
Explicit is better than implicit.
Simple is better than complex.
...
Readability counts.
...
In the face of ambiguity, refuse the temptation to guess.
...
If the implementation is hard to explain, it's a bad idea.
...

Especially in Nicolas Thiery's examples with symmetric functions, using
an explicit conversion is definitely the best way to go. How hard is it
to use the conversion in the following example?

sage: Sym = SymmetricFunctions(QQ)
sage: P = Sym.powersum()
sage: E = Sym.elementary()
sage: P.one()+ P(E.one())
2*p[]
sage: E.one()+ E(P.one())
2*e[]

This way the user (or Sage) doesn't have to guess what the result will be. It's explicit, clear and easy to read.


Cheers,
Burcin

Simon King

unread,
Nov 28, 2010, 7:17:29 AM11/28/10
to sage-algebra
Hi Burcin,

On 28 Nov., 12:06, Burcin Erocal <bur...@erocal.org> wrote:
> I really think having bidirectional coercions would be very confusing
> for users in the long term. I can imagine long, frustrating debugging
> sessions where people are bitten by the fact that a + b doesn't have
> the same parent as b + a in Sage.

Indeed.

> IMHO, this discussion also goes against several principles from the Zen
> of Python.
> ...
>
> Especially in Nicolas Thiery's examples with symmetric functions, using
> an explicit conversion is definitely the best way to go.

OK, but where should one draw the line?

<advocatus_diaboli>
The some criticism also holds (with slightly less intensity) in the
classical case "rational number plus polynomial over the integers
results in a polynomial over the rationals". I remember some people
posting to sage-support who found it confusing as well and expected an
error to be raised.

And if one accepts that, in general, coercion is good, then why should
one ban it for those parents that are particularly similar?

I.e., why would you allow to add 1/2 and x+1 *without* explicit
conversion, while you ask for an explicit conversion in the case of
two fields that are both sub-fields of a third field (so that the
third field is the "obvious" place for arithmetic) and so that
moreover there is an isomorphism that commutes with the embeddings?
</advocatus_diaboly>

Actually I don't have a clear opinion, myself. That's why I ask here,
before posting a patch that won't be accepted.

I acknowledge that parent(a+b)!=parent(b+a) is confusing (perhaps one
could have "parent(a+b)==parent(b+a) and (parent(a+b) is not parent(b
+a)", accepting a violation to the "unique parents" paradigm), and I
also acknowledge that it is confusing if a and b are elements of a
number field, but a+b is in CDF.
But I also appreciate coercion.

Cheers,
Simon

Jason Bandlow

unread,
Nov 28, 2010, 8:35:48 AM11/28/10
to sage-a...@googlegroups.com
Hi Burcin,

On 11/28/2010 06:06 AM, Burcin Erocal wrote:
> Especially in Nicolas Thiery's examples with symmetric functions, using
> an explicit conversion is definitely the best way to go. How hard is it
> to use the conversion in the following example?
>
> sage: Sym = SymmetricFunctions(QQ)
> sage: P = Sym.powersum()
> sage: E = Sym.elementary()
> sage: P.one()+ P(E.one())
> 2*p[]
> sage: E.one()+ E(P.one())
> 2*e[]
>
> This way the user (or Sage) doesn't have to guess what the result will be. It's explicit, clear and easy to read.

I apologize for drifting away from the main thread, but I do want to
address this point. The problem is that I often work with ~8 bases of
this space simultaneously, and perhaps close to 20 bases are defined
within sage. I am also frequently adding a new basis and playing with
it. The coercion graph is connected, but not every edge is implemented
explicitly. When I implement a new basis, I certainly don't want to
have to explicitly define 20 conversions; I only want to define one
change of basis matrix, so that my basis is connected by some path to
all the others. (This is often all I know explicitly, anyway).

Since every conversion has to be made explicit (as opposed to coercions,
which will traverse the whole graph), the user would have to know the
path of change of basis matrices which have been implemented. So one
would have to write something like:

sage: S, J, s, P = # various bases of Sym
sage: S( s( P( J[2,1] ) ) )

instead of

sage: S, J = # bases
sage: S( J[2,1] )

The former seems practically unusable to me to anyone who is not an
expert with the implementation details.

Perhaps, in an ideal world, we would have another system (distinct from
conversion and coercion) that would handle this case of vector spaces or
algebras with multiple bases. But until someone implements such a
thing, we have to choose between conversion and coercion as they
currently exist, and the coercion system is the one which does what we need.

Cheers,
Jason

Simon King

unread,
Nov 28, 2010, 9:35:54 AM11/28/10
to sage-algebra
Hi Jason!

On 28 Nov., 14:35, Jason Bandlow <jband...@gmail.com> wrote:
> I apologize for drifting away from the main thread, but I do want to
> address this point.

What you address is, IMO, the main point of this thread.

Thank you,
Simon

Simon King

unread,
Nov 28, 2010, 11:36:05 AM11/28/10
to sage-algebra
Hi all!

On 28 Nov., 14:35, Jason Bandlow <jband...@gmail.com> wrote:
> Since every conversion has to be made explicit (as opposed to coercions,
> which will traverse the whole graph), the user would have to know the
> path of change of basis matrices which have been implemented.  So one
> would have to write something like:
>
> sage: S, J, s, P = # various bases of Sym
> sage: S( s( P( J[2,1] ) ) )

Or one can use register_as_coercion() in order to customise coercion.
In your situation, you could register some base changes, and could
then rely on automatic coercion. Burcin would perhaps not use
register_as_coercion(), as he seems to prefer explicit conversion.

From the answers in this thread, it seems to me that people have
different expectations on the necessary level of explicity.

My impression is that Nicolas and Jason would like that Sage tries to
make sense of any arithmetic expression that the user presents: Hence,
Sage should infer a suitable common parent whenever it seems possible,
of course as long as choices (that certainly can't be avoided, see
QQ['x'] versus Frac(ZZ['x'])) are consistent.

Burcin seems to propose the other extremal position: Arithmetic should
not take place between different parents at all, unless explicitly
requested by the user (via explicit conversion or probably via
register_as_coercion()).

David Roe and David Kohel seem to be somewhere in between. David Roe
does not like to have coercion in both directions (probably since
parent(a+b)!=parent(b+a)), but does not argue against infering a
pushout. David Kohel does not argue against bidirectional coercions,
but he seems in doubt that it is possible to keep Sage's coercion
system consistent if one does not follow rigorous and well-established
mathematical notions (i.e., choices necessary in explicit computations
can not be done consistently).

Correct me if my impression is wrong.

> Perhaps, in an ideal world, we would have another system (distinct from
> conversion and coercion) that would handle this case of vector spaces or
> algebras with multiple bases.

To me, a basis is not part of the algebraic structure, but is just a
tool to represent elements of a parent. In particular, I believe that
a basis change should not be thought of as a coercion.

Hence, in analogy to Nicolas' example, I would expect
sage: Sym = SymmetricFunctions(QQ)
sage: x = Sym.one()
sage: Sym.powersum() # this just changes the representation
sage: x
p[]
sage: Sym.elementary() # again, just changing the representation
sage: x
e[]

"Changing the representation" would also change the behaviour of
x.list() and similar methods. Here, I think about polynomials:
sage: P.<x,y> = QQ[]
sage: p = x+y^2
sage: QQ.lex_order()
sage: p
x + y^2
sage: QQ.degrevlex_order()
sage: p
y^2 + x

So, I would expect that it is not necessary to have different parents
(hence, not necessary to use coercion!) for different bases, term
orders etc. Instead, there should be an "active basis", "active term
order" etc, that determines how a morphism is represented by a matrix
(linear algebra) or a Gröbner basis is computed (polynomials).

Caveat: I am talking about an ideal world -- I guess a dynamical
choice of term order would not be supported in libsingular.

Cheers,
Simon

Burcin Erocal

unread,
Nov 29, 2010, 8:53:47 AM11/29/10
to sage-a...@googlegroups.com
Hi Simon,

On Sun, 28 Nov 2010 08:36:05 -0800 (PST)
Simon King <simon...@uni-jena.de> wrote:

> On 28 Nov., 14:35, Jason Bandlow <jband...@gmail.com> wrote:
> > Since every conversion has to be made explicit (as opposed to
> > coercions, which will traverse the whole graph), the user would
> > have to know the path of change of basis matrices which have been
> > implemented.  So one would have to write something like:
> >
> > sage: S, J, s, P = # various bases of Sym
> > sage: S( s( P( J[2,1] ) ) )
>
> Or one can use register_as_coercion() in order to customise coercion.
> In your situation, you could register some base changes, and could
> then rely on automatic coercion. Burcin would perhaps not use
> register_as_coercion(), as he seems to prefer explicit conversion.

I prefer explicit conversion _in this case_. My point was about
allowing bidirectional coercions, and violating the condition that
parent(a + b) is parent(b + a).

I agree that in Jason's example expecting the user to write

sage: S( s( P( J[2,1] ) ) )

is absurd.

Your suggestion is a good short term solution to Jason's problem. In
the long term, we should take the code for graph traversal out of the
coercion system and make it an independent class which we can query for
maps/morphisms in the transitive closure of a given set of
maps/morphisms. Of course this will open a whole new can of worms, like
what is the most efficient path between two parents, etc.

> From the answers in this thread, it seems to me that people have
> different expectations on the necessary level of explicity.
>
> My impression is that Nicolas and Jason would like that Sage tries to
> make sense of any arithmetic expression that the user presents: Hence,
> Sage should infer a suitable common parent whenever it seems possible,
> of course as long as choices (that certainly can't be avoided, see
> QQ['x'] versus Frac(ZZ['x'])) are consistent.
>
> Burcin seems to propose the other extremal position: Arithmetic should
> not take place between different parents at all, unless explicitly
> requested by the user (via explicit conversion or probably via
> register_as_coercion()).

No, this is not what I meant. I don't see anything wrong with the
result of an addition with an element of QQ and ZZ['x'] returning an
element from QQ['x']. I think the coercion model is one of the features
(along with the category framework) that make Sage a great platform to
implement mathematical algorithms. My objection was to adding
bidirectional coercions only.


Cheers,
Burcin

Simon King

unread,
Nov 29, 2010, 9:22:00 AM11/29/10
to sage-algebra
Hi Burcin,

On 29 Nov., 14:53, Burcin Erocal <bur...@erocal.org> wrote:
> > Burcin seems to propose the other extremal position: Arithmetic should
> > not take place between different parents at all, unless explicitly
> > requested by the user (via explicit conversion or probably via
> > register_as_coercion()).
>
> No, this is not what I meant. I don't see anything wrong with the
> result of an addition with an element of QQ and ZZ['x'] returning an
> element from QQ['x']. I think the coercion model is one of the features
> (along with the category framework) that make Sage a great platform to
> implement mathematical algorithms. My objection was to adding
> bidirectional coercions only.

Thanks for clarification.

Since it seems to be the opinion of most of you, I'll try to avoid
bidirectional coercions in my soon-to-be-posted update of my patch for
#8800.
* I will not use EmbeddedNumberFieldMorphism to construct coercions
between embedded number fields, since it would produce bidirectional
coercions.
* There will be a coercion from an embedded number field to the
corresponding non-embedded number field, by forgetfulness.
* Arithmetic between two embedded number fields (K1->L1) and (K2->L2)
will happen in pushout(L1,L2), since there does not seem to be an easy
computational way to find the minimal subfield of pushout(L1,L2)
containing the images of K1 and K2, since I still think it is a
consistent definition, and since it would be a shame to not use the
embeddings for arithmetic.

I am not sure yet if I will be able to achieve
pushout(K1['x'],K2['x'])==pushout(K1,K2)['x'] (this can be implemented
using the 'merge()' method of AlgebraicExtensionFunctor, but looks a
bit tricky).

Cheers,
Simon

Simon King

unread,
Nov 29, 2010, 10:57:33 AM11/29/10
to sage-algebra, sag...@googlegroups.com
Cc to sage-nt, since it also concerns number fields.

On 29 Nov., 15:22, Simon King <simon.k...@uni-jena.de> wrote:
> Since it seems to be the opinion of most of you, I'll try to avoid
> bidirectional coercions in my soon-to-be-posted update of my patch for
> #8800.
>  * I will not use EmbeddedNumberFieldMorphism to construct coercions
> between embedded number fields, since it would produce bidirectional
> coercions.

Ouch. I just found that having bidirectional coercions for embedded
number fields was not my idea: It was already implemented!

Example *without* my patch:
sage: L1.<r2_1> = NumberField(x^2-2, embedding = 1)
sage: L2.<r2_2> = NumberField(x^2-2, embedding =-1)
sage: L1==L2
False
sage: L1.has_coerce_map_from(L2)
True
sage: L2.has_coerce_map_from(L1)
True

So, I think we should make a poll:

(A) Shall I remove the existing bidirectional coercion of number
fields from Sage?

(B) Shall I improve the existing code for bidirectional coercion?
Namely, the following example fails with an error that was reported at
sage-devel or sage-support (don't remember which one, sorry):
sage: K.<r4> = NumberField(x^4-2)
sage: L1.<r2_1> = NumberField(x^2-2, embedding = r4**2)
sage: L2.<r2_2> = NumberField(x^2-2, embedding = -r4**2)
sage: L1.has_coerce_map_from(L2)
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (1109, 0))

ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (1109, 0))

...

One of the reasons for the above error is the fact that the pushout of
the codomains of the two embeddings is constructed, but not used in
EmbeddedNumberFieldMorphism in _coerce_map_from_.

Looking forward to a democratic decision...

Simon

John Cremona

unread,
Nov 29, 2010, 11:56:22 AM11/29/10
to sage-a...@googlegroups.com, sag...@googlegroups.com
My vote is not to remove something that's in there and not causing
trouble; and yes, please improve it since you seem quite competent to
do it properly!

John

David R. Kohel

unread,
Nov 29, 2010, 12:26:56 PM11/29/10
to sage-a...@googlegroups.com, sag...@googlegroups.com
Hi,

I would be concerned if in general the determination of an isomorphism
would invoke an expensive computation (before either succeeding or
failing) outside of the user's control.

It might be fast for quadratic fields, for cyclotomic fields (defined
by cyclotomic polynomials). Note that more extensive isomorphism
testing (polynomial factorization) is invoked as well:

sage: P.<x> = PolynomialRing(QQ)
sage: f = x^7 + x + 1
sage: r = [ r[0] for r in f.roots(CC) ]
sage: L1.<r1> = NumberField(f, embedding = r[1])
sage: L2.<r2> = NumberField(f(x+1), embedding = r[1]-1)
sage: L1(r2)
r1 - 1
sage: L2(r1)
r2 + 1
sage: g = f(1/x).numerator()
sage: L3.<r3> = NumberField(g, embedding = 1/r[1])
sage: L3(r1)
-r3^6 - r3^5
sage: L1(r3)
-r1^6 - 1

But if the risks and advantages are well-documented as a feature of
embedded fields, this should not affect number fields without embedding,
hence is harmless if the user doesn't specifically request an embedding.
Assuming there is no impact on unembedded number fields and such are
the default, then I have no objection to leaving this feature.

Does this work for p-adic embeddings as well?

Cheers,

David

Simon King

unread,
Nov 29, 2010, 2:42:53 PM11/29/10
to sage-nt, sage-a...@googlegroups.com
Hi David,

On 29 Nov., 18:26, "David R. Kohel" <ko...@iml.univ-mrs.fr> wrote:
> I would be concerned if in general the determination of an isomorphism
> would invoke an expensive computation (before either succeeding or
> failing) outside of the user's control.  

This is the reason why currently we get "ERROR: An unexpected error
occurred while tokenizing input" in the example above: By oversight,
the ambient field is constructed but not passed as an argument to
EmbeddedNumberFieldMorphism, so that it assumes embedding in CDF,
which takes too long.

> Assuming there is no impact on unembedded number fields and such are
> the default, then I have no objection to leaving this feature.

Yes, EmbeddedNumberFieldMorphism is only invoked (and can only be
invoked) if there is an embedding.

> Does this work for p-adic embeddings as well?

How would one construt a p-adic example? Then I can try (and perhaps
make it another doctest).

Cheers,
Simon

John Cremona

unread,
Nov 29, 2010, 2:53:18 PM11/29/10
to sage-a...@googlegroups.com


sage: Q5 = Qp(5)
sage: iQ5 = Q5(-1).sqrt(); iQ5
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + 2*5^10 +
2*5^11 + 4*5^13 + 5^14 + 3*5^15 + 2*5^16 + 4*5^17 + 4*5^19 + O(5^20)
sage: K.<i> = NumberField(x^2+1, embedding=iQ5)
sage: K
Number Field in i with defining polynomial x^2 + 1
sage: Q5(i)
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + 2*5^10 +
2*5^11 + 4*5^13 + 5^14 + 3*5^15 + 2*5^16 + 4*5^17 + 4*5^19 + O(5^20)

John

>
> Cheers,
> Simon
>

Simon King

unread,
Nov 29, 2010, 3:04:23 PM11/29/10
to sage-algebra
On 29 Nov., 20:53, John Cremona <john.crem...@gmail.com> wrote:
> > How would one construt a p-adic example? Then I can try (and perhaps
> > make it another doctest).
>
> sage: Q5 = Qp(5)
> sage: iQ5 = Q5(-1).sqrt(); iQ5

Thank you!

But coercion is already working without my patch:

sage: Q5 = Qp(5)
sage: iQ5 = Q5(-1).sqrt()
sage: K.<i> = NumberField(x^2+1, embedding=iQ5)
sage: L.<j> = NumberField(x^2+1, embedding=-iQ5)
sage: i+j
2*i
sage: j+i
2*j
sage: from sage.categories.pushout import pushout
sage: pushout(K['t'],L['t'])
Univariate Polynomial Ring in t over Number Field in j with defining
polynomial x^2 + 1

However, EmbeddedNumberFieldMorphism(K,L,Q5) fails with an attribute
error (hence, there is another bug to fix).

Cheers,
Simon

David R. Kohel

unread,
Nov 30, 2010, 5:26:46 AM11/30/10
to sag...@googlegroups.com, sage-a...@googlegroups.com
Hi,

On Tue, Nov 30, 2010 at 01:28:03AM -0800, Simon King wrote:
> Hi Robert,
>
> On 30 Nov., 05:26, Robert Bradshaw <rober...@math.washington.edu>
> wrote:
> > > Part 2: Only one number field is embedded
> > > I think David misunderstood: I did not state that there should be a
> > > coercion from a non-embedded to an embedded field. The opposite
> > > coercion (by forgetful functor) should be fine, though. I suppose that
> > > David and I agree here.
> >
> > Yep, it's fine if the forgetful functor is applied. Actually, I might
> > add that I'd probably only want this if the defining polynomials
> > agree, mapping generator to generator, otherwise an arbitrary choice
> > would have to be made.
>
> Sure, that was the idea.

This David was me, right?

I still see a potential problem. The forgetful functor would map from
(K,K->F) to K. If K is a "new" object, then there is no problem, since
no choice of isomorphism with an existing object has been made.

But given (K,K->F) and L (containing isomorphic image of K), there is still
an arbitrary choice of embedding K -> L to be made. If now L1 and L2 are
two such fields then can we be sure that (as unembedded number fields) there
can never be any coercion relation between L1 and L2 (which could give rise
to non-commuting coercion diagrams)? If an embedding can only be installed
at creation, then maybe this is impossible.

If Sage doesn't know a relation, a user might intend some relation between
L1 and L2, then automatic coercion could violate the intended relation.

CC.<i> = ComplexField()
L1.<i_1> = NumberField(x^2+1) # intended embedding=+i
L2.<i_2> = NumberField(x^2+1) # intended embedding=-i
H12 = Hom(L1,L2)
h12 = H12(-i_2)
K0.<i_0> = CyclotomicField(4) # embedding=+i

A user might prefer to work with explicit homomorphisms, and get burned by
automatic coercion from some embedded field. Arguably this will involve
a user error in mixing embedded an non-embedded fields, but this could be
very subtle to debug.

Currently no such forgetful coercion exists, right?

However, I find this problematic (in Sage 4.3.1):

sage: CC(i_0)
6.12323399573677e-17 + 1.00000000000000*I
sage: CC(i_1)
1.00000000000000*I
sage: CC(i_2)
1.00000000000000*I

since i_1 and i_2 are not supposed to be embedded.

Cheers,

David

Reply all
Reply to author
Forward
0 new messages