115115 3.146264369941973?
116116 sage: QQbar(I)
117117 I
118- sage: AA(I)
119- Traceback (most recent call last):
120- ...
121- ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real
122118 sage: QQbar(I * golden_ratio)
123119 1.618033988749895?*I
124120 sage: AA(golden_ratio)^2 - AA(golden_ratio)
150146 sage: QQbar(-1)^(1/3)
151147 0.500000000000000? + 0.866025403784439?*I
152148
153- We can explicitly coerce from `\QQ[I]`. (Technically, this is not quite
154- kosher, since `\QQ[I]` does not come with an embedding; we do not know
155- whether the field generator is supposed to map to `+I` or `-I`. We assume
156- that for any quadratic field with polynomial `x^2+1`, the generator maps
157- to `+I`.)::
158-
159- sage: K.<im> = QQ[I]
160- sage: pythag = QQbar(3/5 + 4*im/5); pythag
161- 4/5*I + 3/5
162- sage: pythag.abs() == 1
163- True
149+ However, implicit coercion from `\QQ[I]` is only allowed when it is equipped
150+ with a complex embedding::
164151
165- However, implicit coercion from `\QQ[I]` is not allowed::
152+ sage: i.parent()
153+ Number Field in I with defining polynomial x^2 + 1 with I = 1*I
154+ sage: QQbar(1) + i
155+ I + 1
166156
157+ sage: K.<im> = QuadraticField(-1, embedding=None)
167158 sage: QQbar(1) + im
168159 Traceback (most recent call last):
169160 ...
170- TypeError: unsupported operand parent(s) for +: 'Algebraic Field' and 'Number Field in I with defining polynomial x^2 + 1 with I = 1*I'
161+ TypeError: unsupported operand parent(s) for +: 'Algebraic Field' and
162+ 'Number Field in im with defining polynomial x^2 + 1'
163+
164+ However, we can explicitly coerce from the abstract number field `\QQ[I]`.
165+ (Technically, this is not quite kosher, since we do not know whether the field
166+ generator is supposed to map to `+I` or `-I`. We assume that for any quadratic
167+ field with polynomial `x^2+1`, the generator maps to `+I`.)::
168+
169+ sage: pythag = QQbar(3/5 + 4*im/5); pythag
170+ 4/5*I + 3/5
171+ sage: pythag.abs() == 1
172+ True
171173
172174We can implicitly coerce from algebraic reals to algebraic numbers::
173175
553555import operator
554556
555557import sage .rings .ring
558+ import sage .rings .number_field .number_field_base
556559from sage .misc .fast_methods import Singleton
557560from sage .misc .cachefunc import cached_method
561+ from sage .structure .coerce import parent_is_numerical , parent_is_real_numerical
558562from sage .structure .sage_object import SageObject
559563from sage .structure .richcmp import (richcmp , richcmp_method ,
560564 rich_to_bool , richcmp_not_equal ,
@@ -1063,9 +1067,17 @@ def __init__(self):
10631067
10641068 sage: QQbar.category() # indirect doctest
10651069 Category of infinite fields
1070+
1071+ Coercions::
1072+
1073+ sage: AA.has_coerce_map_from(ZZ)
1074+ True
1075+ sage: AA.has_coerce_map_from(int)
1076+ True
10661077 """
10671078 from sage .categories .fields import Fields
10681079 AlgebraicField_common .__init__ (self , self , ('x' ,), normalize = False , category = Fields ().Infinite ())
1080+ self ._populate_coercion_lists_ ([ZZ , QQ ])
10691081
10701082 def _element_constructor_ (self , x ):
10711083 r"""
@@ -1157,8 +1169,6 @@ def _coerce_map_from_(self, from_par):
11571169
11581170 TESTS::
11591171
1160- sage: AA.has_coerce_map_from(ZZ) # indirect doctest
1161- True
11621172 sage: K.<a> = QuadraticField(7, embedding=AA(7).sqrt()); AA.has_coerce_map_from(K)
11631173 True
11641174 sage: a in AA
@@ -1167,9 +1177,20 @@ def _coerce_map_from_(self, from_par):
11671177 5.645751311064590?
11681178 sage: AA.has_coerce_map_from(SR)
11691179 False
1180+
1181+ sage: K.<s> = QuadraticField(3, embedding=-2.)
1182+ sage: s + AA(1)
1183+ -0.732050807568878?
1184+ sage: K.<s> = QuadraticField(3, embedding=2.)
1185+ sage: s + AA(1)
1186+ 2.732050807568878?
1187+ sage: K.<s> = QuadraticField(-5)
1188+ sage: AA.has_coerce_map_from(K)
1189+ False
11701190 """
1171- return (from_par is ZZ or from_par is QQ
1172- or from_par is AA )
1191+ if isinstance (from_par , sage .rings .number_field .number_field_base .NumberField ):
1192+ emb = from_par .coerce_embedding ()
1193+ return emb is not None and parent_is_real_numerical (emb .codomain ())
11731194
11741195 def completion (self , p , prec , extras = {}):
11751196 r"""
@@ -1497,9 +1518,15 @@ def __init__(self):
14971518
14981519 sage: QQbar._repr_option('element_is_atomic')
14991520 False
1521+
1522+ sage: QQbar.has_coerce_map_from(ZZ)
1523+ True
1524+ sage: QQbar.has_coerce_map_from(int)
1525+ True
15001526 """
15011527 from sage .categories .fields import Fields
15021528 AlgebraicField_common .__init__ (self , AA , ('I' ,), normalize = False , category = Fields ().Infinite ())
1529+ self ._populate_coercion_lists_ ([ZZ , QQ ])
15031530
15041531 def _element_constructor_ (self , x ):
15051532 """
@@ -1565,17 +1592,28 @@ def _coerce_map_from_(self, from_par):
15651592
15661593 TESTS::
15671594
1568- sage: QQbar.has_coerce_map_from(ZZ) # indirect doctest
1569- True
15701595 sage: QQbar.has_coerce_map_from(AA)
15711596 True
15721597 sage: QQbar.has_coerce_map_from(CC)
15731598 False
15741599 sage: QQbar.has_coerce_map_from(SR)
15751600 False
1601+
1602+ sage: i + QQbar(2)
1603+ I + 2
1604+ sage: K.<ii> = QuadraticField(-1, embedding=ComplexField(13)(0,-1))
1605+ sage: ii + QQbar(2)
1606+ -I + 2
1607+
1608+ sage: L.<a> = QuadraticField(-1, embedding=Zp(5).teichmuller(2))
1609+ sage: QQbar.has_coerce_map_from(L)
1610+ False
15761611 """
1577- return (from_par is ZZ or from_par is QQ
1578- or from_par is AA or from_par is QQbar )
1612+ if from_par is AA :
1613+ return True
1614+ if isinstance (from_par , sage .rings .number_field .number_field_base .NumberField ):
1615+ emb = from_par .coerce_embedding ()
1616+ return emb is not None and parent_is_numerical (emb .codomain ())
15791617
15801618 def completion (self , p , prec , extras = {}):
15811619 r"""
0 commit comments