Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coercion and conversion for absolute_field #12269

Open
mstreng opened this issue Jan 6, 2012 · 22 comments
Open

coercion and conversion for absolute_field #12269

mstreng opened this issue Jan 6, 2012 · 22 comments

Comments

@mstreng
Copy link

mstreng commented Jan 6, 2012

sage: x = var('x')
sage: K1.<a1> = CyclotomicField(11)
sage: K2.<a2> = K1.extension(x^2 - 3)
sage: K3.<a3> = K2.extension(x^2 + 1) # Let's make a big relative number field
sage: t=a1+6*a2+a3*a1                 # with a complicated element.
sage: L = K3.absolute_field('b')
sage: L(t)
# The code at #11869 takes 12 seconds to compute roots of a
# polynomial, and then doesn't use them.
# TypeError: No compatible natural embeddings found for Number Field in b with .... and Complex Lazy Field
sage: L.structure()                   # However, the correct conversion map is available and works almost instantly
#(Isomorphism map:... , Isomorphism map: ...)
sage: L.structure()[1](t)
# big output
sage: L.gen() + t                     # It would be good if one of the structure maps is a coercion, but they aren't at the moment
# TypeError: unsupported operand parent(s) for '+': ....
sage: K3(L.gen())                     # There are similar problems in the other direction
# TypeError: Cannot coerce element into this number field
sage: L.structure()[0](L.gen())       # for which the structure maps also work.
# a3 - a2 + a1

So this ticket is meant to:

  • make both structure maps into conversions
  • maybe make one or both of the structure maps into a coercion

Speeding up #11869 is not really related and is #12270.

CC: @jdemeyer @simon-king-jena @dansme

Component: number fields

Keywords: coercion conversion absolute_field number field structure relative absolute

Issue created by migration from https://trac.sagemath.org/ticket/12269

@mstreng

This comment has been minimized.

@mstreng

This comment has been minimized.

@mstreng
Copy link
Author

mstreng commented Jan 6, 2012

comment:2

Sorry, I'm messing up the patch numbers. I mean #11869 everywhere.

@mstreng
Copy link
Author

mstreng commented Jan 6, 2012

shows where long calculations are done in #11869

@mstreng
Copy link
Author

mstreng commented Jan 6, 2012

comment:3

Attachment: 11800-indicator.patch.gz

@mstreng

This comment has been minimized.

@mstreng
Copy link
Author

mstreng commented Jan 6, 2012

comment:4

See also #12271 (which is the same, but for relativize)

@jdemeyer
Copy link

jdemeyer commented Jan 6, 2012

comment:5

I believe a solution similar to #11876 is in order: make absolute_field store an embedding (in this case an isomorphism) to the starting field.

@mstreng
Copy link
Author

mstreng commented Jan 6, 2012

comment:6

Replying to @jdemeyer:

I believe a solution similar to #11876 is in order: make absolute_field store an embedding (in this case an isomorphism) to the starting field.

That would fix it, but I don't think it would be very fast, as it would still use .roots() / #11869.

Wouldn't it be better to use the category/coercion framework here? I suppose all that is needed it to store the .structure() homomorphisms in the appropriate place (wherever that is, cc: Simon) as conversion maps. The structure homomorphisms are computed already, and using them is very fast.

Still, inheriting embeddings as in #11876 is certainly useful, so I think it is best to do both.

@mstreng
Copy link
Author

mstreng commented Jan 9, 2012

comment:7

The map absolute_field().structure()[1] (from relative to absolute) cannot be a coercion, because it would lead to non-commuting diagrams of coercions. In sage-4.8.alpha4:

sage: K.<a> = NumberField(x^2-2, embedding=-1)
sage: L.<b> = NumberField(x^2-2, embedding=1)
sage: xK = K['x'].gen()
sage: xL = L['x'].gen()
sage: M.<c> = NumberField(xK^2-3)
sage: N.<d> = NumberField(xL^2-3)
sage: O = M.absolute_field('e')
sage: P = N.absolute_field('e')
sage: b_in_a = K(0)+b
sage: map1 = O.structure()[1]
sage: map2 = P.structure()[1]
sage: b_in_a in map1.domain()
# True
sage: b in map2.domain()
# True
sage: map1(b_in_a) - map2(b)
# e^3 - 9*e, which is non-zero, so the diagrams don't commute!

Fast conversions in both directions would be very useful though. And maybe coercion from absolute to relative?

@simon-king-jena
Copy link
Member

comment:8

Sorry, I did not answer Marco's question yet.

Is it the case that the map is already known at initialisation time? Then, you could use (depending on whether you want a conversion or a coercion or an action) sage.structure.parent.Parent.register_conversion(...) or ...register_coercion(...) or ...register_action(...). But note that it might be tricky to find the right moment for using these methods: They raise an error if the coercion framework was used before invoking the methods.

If the maps are not available at initialisation time (or if otherwise initialisation takes too much time), you could implement either _convert_map_from_ or _coerce_map_from_ -- see the documentation of both methods in sage.structure.parent.Parent for the expected return values. The advantage is that the map would only be constructed when needed.

Concerning "coercion or conversion between relative and absolute number fields", I think there has been at least one thread on sage-nt and also a trac ticket devoted to that subject.

@mstreng
Copy link
Author

mstreng commented Jan 10, 2012

comment:9

Replying to @simon-king-jena:

Sorry, I did not answer Marco's question yet.

No problem, it wasn't a very direct question.

Is it the case that the map is already known at initialisation time?

Don't know, I'll have to dig through the code some more.

Concerning "coercion or conversion between relative and absolute number fields", I think there has been at least one thread on sage-nt and also a trac ticket devoted to that subject.

Thanks, I don't know that ticket/thread. I have found

The first two are about coercions between number fields, but don't say anything about relative versus absolute. The third is about conversions, again no relative versus absolute.

I also did another search on trac, and could only find the tickets I created last week: #12269 (this ticket) and #12271 (same, but for relativize).

@mstreng
Copy link
Author

mstreng commented Jan 10, 2012

comment:10

Replying to @mstreng:

structure()[1] cannot be a coercion, because it would lead to non-commuting diagrams of coercions.

Actually, maybe it is the coercion between O to P that shouldn't be there! All of the following maps are natural
O <--> M <-- K <--> L --> N <--> P
and a map between O and P sending generator to generator does not commute with the abovementioned natural maps.

Some more about O and P:

sage: O
Number Field in e with defining polynomial x^4 - 10*x^2 + 1
sage: P
Number Field in e with defining polynomial x^4 - 10*x^2 + 1
sage: O is P
False
sage: O == P
True
sage: RR(O.structure()[1].domain().base_field().gen())
-1.41421356237309
sage: RR(P.structure()[1].domain().base_field().gen())
1.41421356237309

O and P are really different, I don't understand True for "==" here. Is that a bug?

sage: K is L
False
sage: K == L
False

@mstreng

This comment has been minimized.

@lftabera
Copy link
Contributor

comment:11

Hi, I agree that the error here is that O and P should not be given a coercion. Note that the code above does not work if P is given another generator name. On this example I would not expect a canonical isomorphism from O to P.

@lftabera
Copy link
Contributor

comment:12

Forcing coercions exposes other errors in the coercion model:

K = NumberField([x^2-2, x^2-3], 'a,b')
M = K.absolute_field('c')
M_to_K, K_to_M = M.structure()
M.register_coercion(K_to_M)
K.register_coercion(M_to_K)
M.coerce_map_from(QQ)
...
UnboundLocalError: local variable 'connecting' referenced before assignment

@simon-king-jena
Copy link
Member

comment:13

Replying to @lftabera:

Forcing coercions exposes other errors in the coercion model:

Right. And here it is (in sage.structure.parent, lines 2300-2303):

                connection = None
                if EltPair(mor._domain, S, "coerce") not in _coerce_test_dict:
                    connecting = mor._domain.coerce_map_from(S)
                if connecting is not None:

So, apparently someone intended to write "connecting = None", but wrote "connection = None". Can you try whether writing "connecting = None" fixes the problem?

K = NumberField([x^2-2, x^2-3], 'a,b')
M = K.absolute_field('c')
M_to_K, K_to_M = M.structure()
M.register_coercion(K_to_M)
K.register_coercion(M_to_K)
M.coerce_map_from(QQ)
...
UnboundLocalError: local variable 'connecting' referenced before assignment

@mstreng
Copy link
Author

mstreng commented Jan 30, 2012

comment:14

Replying to @lftabera:

Hi, I agree that the error here is that O and P should not be given a coercion. Note that the code above does not work if P is given another generator name. On this example I would not expect a canonical isomorphism from O to P.

This can be fixed by making O == P be False by letting O.__cmp__(P) compare structure maps.

@lftabera
Copy link
Contributor

lftabera commented Feb 8, 2012

comment:15

Replying to @simon-king-jena:

Replying to @lftabera:

Forcing coercions exposes other errors in the coercion model:

Right. And here it is (in sage.structure.parent, lines 2300-2303):

                connection = None
                if EltPair(mor._domain, S, "coerce") not in _coerce_test_dict:
                    connecting = mor._domain.coerce_map_from(S)
                if connecting is not None:

So, apparently someone intended to write "connecting = None", but wrote "connection = None". Can you try whether writing "connecting = None" fixes the problem?

Yes, this solves the problem. I guess that this fix should go to a new ticket.

@simon-king-jena
Copy link
Member

comment:16

Replying to @lftabera:

Yes, this solves the problem. I guess that this fix should go to a new ticket.

OK, but I couldn't do it right now. I am in quite a mess with my good old group cohomology spkg, which wouldn't work in the latest Sage version for at least three independent reasons.

@mstreng
Copy link
Author

mstreng commented Feb 8, 2012

comment:17

Replying to @lftabera:

Yes, this solves the problem. I guess that this fix should go to a new ticket.

Yes, that makes sense. It is a bugfix of 2 characters, so doesn't have to wait for all of #12269 to be fixed.

@lftabera
Copy link
Contributor

comment:18

For the typo in parent.pyx I have added a patch in #12990

@jdemeyer jdemeyer modified the milestones: sage-5.11, sage-5.12 Aug 13, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@mkoeppe mkoeppe removed this from the sage-6.4 milestone Dec 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants