Opened 10 years ago
Last modified 7 years ago
#12269 new enhancement
coercion and conversion for absolute_field
Reported by: | mstreng | Owned by: | davidloeffler |
---|---|---|---|
Priority: | major | Milestone: | sage-6.4 |
Component: | number fields | Keywords: | coercion conversion absolute_field number field structure relative absolute |
Cc: | jdemeyer, SimonKing, daniels | Merged in: | |
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description (last modified by )
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
Attachments (1)
Change History (24)
comment:1 Changed 10 years ago by
- Description modified (diff)
comment:2 Changed 10 years ago by
- Description modified (diff)
comment:3 Changed 10 years ago by
- Description modified (diff)
comment:4 Changed 10 years ago by
See also #12271 (which is the same, but for relativize)
comment:5 follow-up: ↓ 6 Changed 10 years ago by
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.
comment:6 in reply to: ↑ 5 Changed 10 years ago by
- Cc SimonKing added
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.
comment:7 follow-up: ↓ 10 Changed 10 years ago by
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?
comment:8 follow-up: ↓ 9 Changed 10 years ago by
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.
comment:9 in reply to: ↑ 8 Changed 10 years ago by
- Type changed from defect to enhancement
Replying to SimonKing:
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
- https://groups.google.com/group/sage-nt/browse_thread/thread/5c376dbf7e99ea97/
- https://groups.google.com/group/sage-nt/browse_thread/thread/32b65a5173f43267/
- https://groups.google.com/group/sage-nt/browse_thread/thread/9108218411e7f0a6/
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).
comment:10 in reply to: ↑ 7 Changed 10 years ago by
- Description modified (diff)
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
comment:11 follow-up: ↓ 14 Changed 10 years ago by
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.
comment:12 follow-up: ↓ 13 Changed 10 years ago by
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
comment:13 in reply to: ↑ 12 ; follow-up: ↓ 15 Changed 10 years ago by
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
comment:14 in reply to: ↑ 11 Changed 10 years ago by
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.
comment:15 in reply to: ↑ 13 ; follow-ups: ↓ 16 ↓ 17 Changed 10 years ago by
Replying to SimonKing:
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.
comment:16 in reply to: ↑ 15 Changed 10 years ago by
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.
comment:17 in reply to: ↑ 15 Changed 10 years ago by
comment:18 Changed 10 years ago by
For the typo in parent.pyx I have added a patch in #12990
comment:19 Changed 9 years ago by
- Cc daniels added
comment:20 Changed 8 years ago by
- Milestone changed from sage-5.11 to sage-5.12
comment:21 Changed 8 years ago by
- Milestone changed from sage-6.1 to sage-6.2
comment:22 Changed 8 years ago by
- Milestone changed from sage-6.2 to sage-6.3
comment:23 Changed 7 years ago by
- Milestone changed from sage-6.3 to sage-6.4
Sorry, I'm messing up the patch numbers. I mean #11869 everywhere.