Skip to content

Commit ebd2c00

Browse files
Release Managervbraun
Release Manager
authored andcommitted
Trac #15331: Do not try to create embedded number field morphisms for non-embedded number fields
The attempt to create an embedded number field morphisms for non- embedded number fields currently fails (and should of course fail). {{{ sage: L.<i> = NumberField(x^2 + 1) sage: K = NumberField(L(i/2+3).minpoly(), names=('i0',), embedding=L(i/2+3)) sage: from sage.rings.number_field import number_field_morphisms sage: number_field_morphisms.EmbeddedNumberFieldMorphism(R, self) Traceback (most recent call last): ... RuntimeError: maximum recursion depth exceeded in __instancecheck__ }}} However, instead of running into an infinite recursion, a quick and simple `ValueError` (or perhaps `TypeError`) should be raised. URL: http://trac.sagemath.org/15331 Reported by: SimonKing Ticket author(s): Simon King, Marc Mezzarobba, Jean-Pierre Flori Reviewer(s): Marc Mezzarobba, Jean-Pierre Flori
2 parents 5e64ce2 + 2bedaa1 commit ebd2c00

File tree

2 files changed

+60
-31
lines changed

2 files changed

+60
-31
lines changed

src/sage/rings/number_field/number_field.py

+11-23
Original file line numberDiff line numberDiff line change
@@ -6168,30 +6168,18 @@ def _coerce_map_from_(self, R):
61686168
from sage.rings.number_field.order import is_NumberFieldOrder
61696169
if is_NumberFieldOrder(R) and self.has_coerce_map_from(R.number_field()):
61706170
return self._generic_convert_map(R)
6171-
if is_NumberField(R) and R != QQ:
6172-
if R.coerce_embedding() is not None:
6173-
if self.coerce_embedding() is not None:
6174-
try:
6175-
from sage.categories.pushout import pushout
6176-
ambient_field = pushout(R.coerce_embedding().codomain(), self.coerce_embedding().codomain())
6177-
if ambient_field is not None:
6178-
try:
6179-
# the original ambient field
6180-
return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self, ambient_field)
6181-
except ValueError: # no embedding found
6182-
# there might be one in the alg. completion
6183-
return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self, ambient_field.algebraic_closure() if hasattr(ambient_field,'algebraic_closure') else ambient_field)
6184-
except (ValueError, TypeError, NotImplementedError, sage.structure.coerce_exceptions.CoercionException),msg:
6185-
# no success with the pushout
6186-
try:
6187-
return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self)
6188-
except (TypeError, ValueError):
6189-
pass
6190-
else:
6191-
# R is embedded, self isn't. So, we could only have
6192-
# the forgetful coercion. But this yields to non-commuting
6193-
# coercions, as was pointed out at ticket #8800
6171+
# R is not QQ by the above tests
6172+
if is_NumberField(R) and R.coerce_embedding() is not None:
6173+
if self.coerce_embedding() is not None:
6174+
try:
6175+
return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self)
6176+
except ValueError: # no common embedding found
61946177
return None
6178+
else:
6179+
# R is embedded, self isn't. So, we could only have
6180+
# the forgetful coercion. But this yields to non-commuting
6181+
# coercions, as was pointed out at ticket #8800
6182+
return None
61956183

61966184
def base_field(self):
61976185
"""

src/sage/rings/number_field/number_field_morphisms.pyx

+49-8
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ fields (generally `\RR` or `\CC`).
2020
# http://www.gnu.org/licenses/
2121
#*****************************************************************************
2222

23+
import sage.rings.complex_double
2324

2425
from sage.structure.element cimport Element
2526
from sage.categories.morphism cimport Morphism
2627
from sage.categories.map cimport Map
28+
from sage.categories.pushout import pushout
2729

2830
from sage.rings.real_mpfr import RealField, mpfr_prec_min
2931
from sage.rings.complex_field import ComplexField
@@ -107,8 +109,16 @@ cdef class NumberFieldEmbedding(Morphism):
107109
cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding):
108110
r"""
109111
This allows one to go from one number field in another consistently,
110-
assuming they both have specified embeddings into an ambient field
111-
(by default it looks for an embedding into `\CC`).
112+
assuming they both have specified embeddings into an ambient field.
113+
114+
If no ambient field is supplied, then the following ambient fields are
115+
tried:
116+
117+
* the pushout of the fields where the number fields are embedded;
118+
119+
* the algebraic closure of the previous pushout;
120+
121+
* `\CC`.
112122
113123
EXAMPLES::
114124
@@ -161,15 +171,46 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding):
161171
Traceback (most recent call last):
162172
...
163173
TypeError: unsupported operand parent(s) for '+': 'Number Field in a with defining polynomial x^3 + 2' and 'Number Field in a with defining polynomial x^3 + 2'
174+
175+
The following was fixed to raise a ``TypeError`` in :trac:`15331`::
176+
177+
sage: L.<i> = NumberField(x^2 + 1)
178+
sage: K = NumberField(L(i/2+3).minpoly(), names=('i0',), embedding=L(i/2+3))
179+
sage: EmbeddedNumberFieldMorphism(K, L)
180+
Traceback (most recent call last):
181+
...
182+
TypeError: No embedding available for Number Field in i with defining polynomial x^2 + 1
183+
164184
"""
165185
if ambient_field is None:
166-
from sage.rings.complex_double import CDF
167-
ambient_field = CDF
168-
gen_image = matching_root(K.polynomial().change_ring(L), K.gen(), ambient_field=ambient_field, margin=2)
169-
if gen_image is None:
186+
if K.coerce_embedding() is None:
187+
raise TypeError("No embedding available for %s"%K)
188+
Kemb = K
189+
while Kemb.coerce_embedding() is not None:
190+
Kemb = Kemb.coerce_embedding().codomain()
191+
if L.coerce_embedding() is None:
192+
raise TypeError("No embedding available for %s"%L)
193+
Lemb = L
194+
while Lemb.coerce_embedding() is not None:
195+
Lemb = Lemb.coerce_embedding().codomain()
196+
ambient_field = pushout(Kemb, Lemb)
197+
candidate_ambient_fields = [ambient_field]
198+
try:
199+
candidate_ambient_fields.append(ambient_field.algebraic_closure())
200+
except NotImplementedError:
201+
pass
202+
candidate_ambient_fields.append(sage.rings.complex_double.CDF)
203+
else:
204+
candidate_ambient_fields = [ambient_field]
205+
206+
for ambient_field in candidate_ambient_fields:
207+
gen_image = matching_root(K.polynomial().change_ring(L), K.gen(), ambient_field=ambient_field, margin=2)
208+
if gen_image is not None:
209+
NumberFieldEmbedding.__init__(self, K, L, gen_image)
210+
self.ambient_field = ambient_field
211+
return
212+
else:
170213
raise ValueError, "No consistent embedding of all of %s into %s." % (K, L)
171-
NumberFieldEmbedding.__init__(self, K, L, gen_image)
172-
self.ambient_field = ambient_field
173214

174215
def section(self):
175216
"""

0 commit comments

Comments
 (0)