passagemath-flint 10.6.1rc10__cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
  2. passagemath_flint-10.6.1rc10.dist-info/RECORD +361 -0
  3. passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
  4. passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
  5. passagemath_flint.libs/libflint-aecb9cc5.so.21.0.0 +0 -0
  6. passagemath_flint.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  7. passagemath_flint.libs/libgfortran-8f1e9814.so.5.0.0 +0 -0
  8. passagemath_flint.libs/libgmp-6e109695.so.10.5.0 +0 -0
  9. passagemath_flint.libs/libgsl-cda90e79.so.28.0.0 +0 -0
  10. passagemath_flint.libs/libmpfi-e3c25853.so.0.0.0 +0 -0
  11. passagemath_flint.libs/libmpfr-82690d50.so.6.2.1 +0 -0
  12. passagemath_flint.libs/libntl-74e7d9a3.so.44.0.1 +0 -0
  13. passagemath_flint.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
  14. passagemath_flint.libs/libquadmath-828275a7.so.0.0.0 +0 -0
  15. sage/all__sagemath_flint.py +29 -0
  16. sage/combinat/all__sagemath_flint.py +1 -0
  17. sage/combinat/posets/all__sagemath_flint.py +1 -0
  18. sage/combinat/posets/hasse_cython_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  19. sage/combinat/posets/hasse_cython_flint.pyx +194 -0
  20. sage/data_structures/all__sagemath_flint.py +1 -0
  21. sage/data_structures/bounded_integer_sequences.cpython-310-x86_64-linux-gnu.so +0 -0
  22. sage/data_structures/bounded_integer_sequences.pxd +62 -0
  23. sage/data_structures/bounded_integer_sequences.pyx +1418 -0
  24. sage/graphs/all__sagemath_flint.py +1 -0
  25. sage/graphs/chrompoly.cpython-310-x86_64-linux-gnu.so +0 -0
  26. sage/graphs/chrompoly.pyx +555 -0
  27. sage/graphs/matchpoly.cpython-310-x86_64-linux-gnu.so +0 -0
  28. sage/graphs/matchpoly.pyx +412 -0
  29. sage/libs/all__sagemath_flint.py +17 -0
  30. sage/libs/arb/__init__.py +1 -0
  31. sage/libs/arb/acb.pxd +154 -0
  32. sage/libs/arb/acb_calc.pxd +9 -0
  33. sage/libs/arb/acb_elliptic.pxd +25 -0
  34. sage/libs/arb/acb_hypgeom.pxd +74 -0
  35. sage/libs/arb/acb_mat.pxd +62 -0
  36. sage/libs/arb/acb_modular.pxd +17 -0
  37. sage/libs/arb/acb_poly.pxd +216 -0
  38. sage/libs/arb/arb.pxd +240 -0
  39. sage/libs/arb/arb_fmpz_poly.pxd +21 -0
  40. sage/libs/arb/arb_hypgeom.pxd +83 -0
  41. sage/libs/arb/arb_wrap.h +34 -0
  42. sage/libs/arb/arf.pxd +131 -0
  43. sage/libs/arb/arith.cpython-310-x86_64-linux-gnu.so +0 -0
  44. sage/libs/arb/arith.pyx +87 -0
  45. sage/libs/arb/bernoulli.pxd +6 -0
  46. sage/libs/arb/mag.pxd +77 -0
  47. sage/libs/arb/types.pxd +37 -0
  48. sage/libs/flint/__init__.py +1 -0
  49. sage/libs/flint/acb.pxd +270 -0
  50. sage/libs/flint/acb_calc.pxd +22 -0
  51. sage/libs/flint/acb_dft.pxd +51 -0
  52. sage/libs/flint/acb_dirichlet.pxd +112 -0
  53. sage/libs/flint/acb_elliptic.pxd +42 -0
  54. sage/libs/flint/acb_hypgeom.pxd +169 -0
  55. sage/libs/flint/acb_macros.pxd +9 -0
  56. sage/libs/flint/acb_mat.pxd +136 -0
  57. sage/libs/flint/acb_mat_macros.pxd +10 -0
  58. sage/libs/flint/acb_modular.pxd +62 -0
  59. sage/libs/flint/acb_poly.pxd +251 -0
  60. sage/libs/flint/acb_poly_macros.pxd +8 -0
  61. sage/libs/flint/acb_theta.pxd +124 -0
  62. sage/libs/flint/acf.pxd +32 -0
  63. sage/libs/flint/aprcl.pxd +84 -0
  64. sage/libs/flint/arb.pxd +382 -0
  65. sage/libs/flint/arb_calc.pxd +31 -0
  66. sage/libs/flint/arb_fmpz_poly.pxd +34 -0
  67. sage/libs/flint/arb_fpwrap.pxd +215 -0
  68. sage/libs/flint/arb_hypgeom.pxd +147 -0
  69. sage/libs/flint/arb_macros.pxd +9 -0
  70. sage/libs/flint/arb_mat.pxd +140 -0
  71. sage/libs/flint/arb_mat_macros.pxd +10 -0
  72. sage/libs/flint/arb_poly.pxd +237 -0
  73. sage/libs/flint/arf.pxd +167 -0
  74. sage/libs/flint/arith.cpython-310-x86_64-linux-gnu.so +0 -0
  75. sage/libs/flint/arith.pxd +76 -0
  76. sage/libs/flint/arith.pyx +77 -0
  77. sage/libs/flint/arith_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  78. sage/libs/flint/arith_sage.pyx +308 -0
  79. sage/libs/flint/bernoulli.pxd +28 -0
  80. sage/libs/flint/bool_mat.pxd +52 -0
  81. sage/libs/flint/ca.pxd +203 -0
  82. sage/libs/flint/ca_ext.pxd +34 -0
  83. sage/libs/flint/ca_field.pxd +32 -0
  84. sage/libs/flint/ca_mat.pxd +117 -0
  85. sage/libs/flint/ca_poly.pxd +104 -0
  86. sage/libs/flint/ca_vec.pxd +46 -0
  87. sage/libs/flint/calcium.pxd +27 -0
  88. sage/libs/flint/d_mat.pxd +39 -0
  89. sage/libs/flint/d_vec.pxd +32 -0
  90. sage/libs/flint/dirichlet.pxd +57 -0
  91. sage/libs/flint/dlog.pxd +53 -0
  92. sage/libs/flint/double_extras.pxd +24 -0
  93. sage/libs/flint/double_interval.pxd +36 -0
  94. sage/libs/flint/fexpr.pxd +104 -0
  95. sage/libs/flint/fexpr_builtin.pxd +20 -0
  96. sage/libs/flint/fft.pxd +66 -0
  97. sage/libs/flint/flint.pxd +36 -0
  98. sage/libs/flint/flint_ntl_wrap.h +35 -0
  99. sage/libs/flint/flint_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  100. sage/libs/flint/flint_sage.pyx +163 -0
  101. sage/libs/flint/flint_wrap.h +190 -0
  102. sage/libs/flint/fmpq.pxd +137 -0
  103. sage/libs/flint/fmpq_mat.pxd +105 -0
  104. sage/libs/flint/fmpq_mat_macros.pxd +10 -0
  105. sage/libs/flint/fmpq_mpoly.pxd +165 -0
  106. sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
  107. sage/libs/flint/fmpq_poly.pxd +241 -0
  108. sage/libs/flint/fmpq_poly_macros.pxd +9 -0
  109. sage/libs/flint/fmpq_poly_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  110. sage/libs/flint/fmpq_poly_sage.pxd +31 -0
  111. sage/libs/flint/fmpq_poly_sage.pyx +48 -0
  112. sage/libs/flint/fmpq_vec.pxd +27 -0
  113. sage/libs/flint/fmpz.pxd +256 -0
  114. sage/libs/flint/fmpz_extras.pxd +32 -0
  115. sage/libs/flint/fmpz_factor.pxd +42 -0
  116. sage/libs/flint/fmpz_factor_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  117. sage/libs/flint/fmpz_factor_sage.pxd +4 -0
  118. sage/libs/flint/fmpz_factor_sage.pyx +29 -0
  119. sage/libs/flint/fmpz_lll.pxd +49 -0
  120. sage/libs/flint/fmpz_macros.pxd +8 -0
  121. sage/libs/flint/fmpz_mat.pxd +184 -0
  122. sage/libs/flint/fmpz_mat_macros.pxd +10 -0
  123. sage/libs/flint/fmpz_mod.pxd +46 -0
  124. sage/libs/flint/fmpz_mod_mat.pxd +71 -0
  125. sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
  126. sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
  127. sage/libs/flint/fmpz_mod_poly.pxd +249 -0
  128. sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
  129. sage/libs/flint/fmpz_mod_vec.pxd +27 -0
  130. sage/libs/flint/fmpz_mpoly.pxd +224 -0
  131. sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
  132. sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
  133. sage/libs/flint/fmpz_poly.cpython-310-x86_64-linux-gnu.so +0 -0
  134. sage/libs/flint/fmpz_poly.pxd +407 -0
  135. sage/libs/flint/fmpz_poly.pyx +19 -0
  136. sage/libs/flint/fmpz_poly_factor.pxd +33 -0
  137. sage/libs/flint/fmpz_poly_macros.pxd +8 -0
  138. sage/libs/flint/fmpz_poly_mat.pxd +71 -0
  139. sage/libs/flint/fmpz_poly_q.pxd +55 -0
  140. sage/libs/flint/fmpz_poly_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  141. sage/libs/flint/fmpz_poly_sage.pxd +20 -0
  142. sage/libs/flint/fmpz_poly_sage.pyx +500 -0
  143. sage/libs/flint/fmpz_vec.pxd +80 -0
  144. sage/libs/flint/fmpzi.pxd +52 -0
  145. sage/libs/flint/fq.pxd +97 -0
  146. sage/libs/flint/fq_default.pxd +84 -0
  147. sage/libs/flint/fq_default_mat.pxd +70 -0
  148. sage/libs/flint/fq_default_poly.pxd +97 -0
  149. sage/libs/flint/fq_default_poly_factor.pxd +39 -0
  150. sage/libs/flint/fq_embed.pxd +28 -0
  151. sage/libs/flint/fq_mat.pxd +83 -0
  152. sage/libs/flint/fq_nmod.pxd +95 -0
  153. sage/libs/flint/fq_nmod_embed.pxd +28 -0
  154. sage/libs/flint/fq_nmod_mat.pxd +83 -0
  155. sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
  156. sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
  157. sage/libs/flint/fq_nmod_poly.pxd +202 -0
  158. sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
  159. sage/libs/flint/fq_nmod_vec.pxd +33 -0
  160. sage/libs/flint/fq_poly.pxd +204 -0
  161. sage/libs/flint/fq_poly_factor.pxd +47 -0
  162. sage/libs/flint/fq_vec.pxd +33 -0
  163. sage/libs/flint/fq_zech.pxd +99 -0
  164. sage/libs/flint/fq_zech_embed.pxd +28 -0
  165. sage/libs/flint/fq_zech_mat.pxd +78 -0
  166. sage/libs/flint/fq_zech_poly.pxd +198 -0
  167. sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
  168. sage/libs/flint/fq_zech_vec.pxd +33 -0
  169. sage/libs/flint/gr.pxd +174 -0
  170. sage/libs/flint/gr_generic.pxd +215 -0
  171. sage/libs/flint/gr_mat.pxd +161 -0
  172. sage/libs/flint/gr_mpoly.pxd +68 -0
  173. sage/libs/flint/gr_poly.pxd +276 -0
  174. sage/libs/flint/gr_special.pxd +237 -0
  175. sage/libs/flint/gr_vec.pxd +120 -0
  176. sage/libs/flint/hypgeom.pxd +24 -0
  177. sage/libs/flint/long_extras.pxd +23 -0
  178. sage/libs/flint/mag.pxd +131 -0
  179. sage/libs/flint/mag_macros.pxd +8 -0
  180. sage/libs/flint/mpf_mat.pxd +36 -0
  181. sage/libs/flint/mpf_vec.pxd +34 -0
  182. sage/libs/flint/mpfr_mat.pxd +27 -0
  183. sage/libs/flint/mpfr_vec.pxd +25 -0
  184. sage/libs/flint/mpn_extras.pxd +41 -0
  185. sage/libs/flint/mpoly.pxd +72 -0
  186. sage/libs/flint/nf.pxd +19 -0
  187. sage/libs/flint/nf_elem.pxd +74 -0
  188. sage/libs/flint/nmod.pxd +35 -0
  189. sage/libs/flint/nmod_mat.pxd +104 -0
  190. sage/libs/flint/nmod_mpoly.pxd +144 -0
  191. sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
  192. sage/libs/flint/nmod_poly.pxd +339 -0
  193. sage/libs/flint/nmod_poly_factor.pxd +44 -0
  194. sage/libs/flint/nmod_poly_linkage.pxi +710 -0
  195. sage/libs/flint/nmod_poly_mat.pxd +76 -0
  196. sage/libs/flint/nmod_vec.pxd +40 -0
  197. sage/libs/flint/ntl_interface.pxd +17 -0
  198. sage/libs/flint/padic.pxd +93 -0
  199. sage/libs/flint/padic_mat.pxd +64 -0
  200. sage/libs/flint/padic_poly.pxd +88 -0
  201. sage/libs/flint/partitions.pxd +23 -0
  202. sage/libs/flint/perm.pxd +26 -0
  203. sage/libs/flint/profiler.pxd +24 -0
  204. sage/libs/flint/qadic.pxd +77 -0
  205. sage/libs/flint/qfb.pxd +44 -0
  206. sage/libs/flint/qqbar.pxd +172 -0
  207. sage/libs/flint/qsieve.cpython-310-x86_64-linux-gnu.so +0 -0
  208. sage/libs/flint/qsieve.pxd +41 -0
  209. sage/libs/flint/qsieve.pyx +21 -0
  210. sage/libs/flint/qsieve_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  211. sage/libs/flint/qsieve_sage.pyx +67 -0
  212. sage/libs/flint/thread_pool.pxd +25 -0
  213. sage/libs/flint/types.pxd +2076 -0
  214. sage/libs/flint/ulong_extras.cpython-310-x86_64-linux-gnu.so +0 -0
  215. sage/libs/flint/ulong_extras.pxd +141 -0
  216. sage/libs/flint/ulong_extras.pyx +21 -0
  217. sage/libs/flint/ulong_extras_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  218. sage/libs/flint/ulong_extras_sage.pyx +21 -0
  219. sage/matrix/all__sagemath_flint.py +1 -0
  220. sage/matrix/change_ring.cpython-310-x86_64-linux-gnu.so +0 -0
  221. sage/matrix/change_ring.pyx +43 -0
  222. sage/matrix/matrix_complex_ball_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  223. sage/matrix/matrix_complex_ball_dense.pxd +14 -0
  224. sage/matrix/matrix_complex_ball_dense.pyx +973 -0
  225. sage/matrix/matrix_cyclo_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  226. sage/matrix/matrix_cyclo_dense.pxd +16 -0
  227. sage/matrix/matrix_cyclo_dense.pyx +1761 -0
  228. sage/matrix/matrix_integer_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  229. sage/matrix/matrix_integer_dense.pxd +32 -0
  230. sage/matrix/matrix_integer_dense.pyx +5801 -0
  231. sage/matrix/matrix_integer_dense_hnf.py +1294 -0
  232. sage/matrix/matrix_integer_dense_saturation.py +346 -0
  233. sage/matrix/matrix_integer_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
  234. sage/matrix/matrix_integer_sparse.pxd +9 -0
  235. sage/matrix/matrix_integer_sparse.pyx +1090 -0
  236. sage/matrix/matrix_rational_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  237. sage/matrix/matrix_rational_dense.pxd +23 -0
  238. sage/matrix/matrix_rational_dense.pyx +2995 -0
  239. sage/matrix/matrix_rational_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
  240. sage/matrix/matrix_rational_sparse.pxd +11 -0
  241. sage/matrix/matrix_rational_sparse.pyx +789 -0
  242. sage/matrix/misc_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  243. sage/matrix/misc_flint.pyx +109 -0
  244. sage/modular/all__sagemath_flint.py +1 -0
  245. sage/modular/modform/all__sagemath_flint.py +1 -0
  246. sage/modular/modform/eis_series_cython.cpython-310-x86_64-linux-gnu.so +0 -0
  247. sage/modular/modform/eis_series_cython.pyx +226 -0
  248. sage/modular/modsym/all__sagemath_flint.py +1 -0
  249. sage/modular/modsym/apply.cpython-310-x86_64-linux-gnu.so +0 -0
  250. sage/modular/modsym/apply.pxd +6 -0
  251. sage/modular/modsym/apply.pyx +113 -0
  252. sage/modular/modsym/heilbronn.cpython-310-x86_64-linux-gnu.so +0 -0
  253. sage/modular/modsym/heilbronn.pyx +966 -0
  254. sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
  255. sage/modular/pollack_stevens/dist.cpython-310-x86_64-linux-gnu.so +0 -0
  256. sage/modular/pollack_stevens/dist.pxd +38 -0
  257. sage/modular/pollack_stevens/dist.pyx +1439 -0
  258. sage/quivers/algebra.py +691 -0
  259. sage/quivers/algebra_elements.cpython-310-x86_64-linux-gnu.so +0 -0
  260. sage/quivers/algebra_elements.pxd +97 -0
  261. sage/quivers/algebra_elements.pxi +1324 -0
  262. sage/quivers/algebra_elements.pyx +1424 -0
  263. sage/quivers/all.py +1 -0
  264. sage/quivers/ar_quiver.py +917 -0
  265. sage/quivers/homspace.py +640 -0
  266. sage/quivers/morphism.py +1282 -0
  267. sage/quivers/path_semigroup.py +1155 -0
  268. sage/quivers/paths.cpython-310-x86_64-linux-gnu.so +0 -0
  269. sage/quivers/paths.pxd +13 -0
  270. sage/quivers/paths.pyx +809 -0
  271. sage/quivers/representation.py +2975 -0
  272. sage/rings/all__sagemath_flint.py +37 -0
  273. sage/rings/cif.py +4 -0
  274. sage/rings/complex_arb.cpython-310-x86_64-linux-gnu.so +0 -0
  275. sage/rings/complex_arb.pxd +29 -0
  276. sage/rings/complex_arb.pyx +5176 -0
  277. sage/rings/complex_interval.cpython-310-x86_64-linux-gnu.so +0 -0
  278. sage/rings/complex_interval.pxd +30 -0
  279. sage/rings/complex_interval.pyx +2475 -0
  280. sage/rings/complex_interval_field.py +711 -0
  281. sage/rings/convert/all.py +1 -0
  282. sage/rings/convert/mpfi.cpython-310-x86_64-linux-gnu.so +0 -0
  283. sage/rings/convert/mpfi.pxd +6 -0
  284. sage/rings/convert/mpfi.pyx +576 -0
  285. sage/rings/factorint_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  286. sage/rings/factorint_flint.pyx +99 -0
  287. sage/rings/fraction_field_FpT.cpython-310-x86_64-linux-gnu.so +0 -0
  288. sage/rings/fraction_field_FpT.pxd +28 -0
  289. sage/rings/fraction_field_FpT.pyx +2043 -0
  290. sage/rings/imaginary_unit.py +5 -0
  291. sage/rings/monomials.py +73 -0
  292. sage/rings/number_field/S_unit_solver.py +2870 -0
  293. sage/rings/number_field/all__sagemath_flint.py +7 -0
  294. sage/rings/number_field/bdd_height.py +664 -0
  295. sage/rings/number_field/class_group.py +762 -0
  296. sage/rings/number_field/galois_group.py +1307 -0
  297. sage/rings/number_field/homset.py +612 -0
  298. sage/rings/number_field/maps.py +687 -0
  299. sage/rings/number_field/morphism.py +272 -0
  300. sage/rings/number_field/number_field.py +12820 -0
  301. sage/rings/number_field/number_field_element.cpython-310-x86_64-linux-gnu.so +0 -0
  302. sage/rings/number_field/number_field_element.pxd +59 -0
  303. sage/rings/number_field/number_field_element.pyx +5735 -0
  304. sage/rings/number_field/number_field_element_quadratic.cpython-310-x86_64-linux-gnu.so +0 -0
  305. sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
  306. sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
  307. sage/rings/number_field/number_field_ideal_rel.py +925 -0
  308. sage/rings/number_field/number_field_morphisms.cpython-310-x86_64-linux-gnu.so +0 -0
  309. sage/rings/number_field/number_field_morphisms.pyx +781 -0
  310. sage/rings/number_field/number_field_rel.py +2734 -0
  311. sage/rings/number_field/order.py +2981 -0
  312. sage/rings/number_field/order_ideal.py +804 -0
  313. sage/rings/number_field/selmer_group.py +715 -0
  314. sage/rings/number_field/small_primes_of_degree_one.py +242 -0
  315. sage/rings/number_field/splitting_field.py +606 -0
  316. sage/rings/number_field/structure.py +380 -0
  317. sage/rings/number_field/unit_group.py +721 -0
  318. sage/rings/padics/all__sagemath_flint.py +3 -0
  319. sage/rings/polynomial/all__sagemath_flint.py +1 -0
  320. sage/rings/polynomial/complex_roots.py +312 -0
  321. sage/rings/polynomial/evaluation_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  322. sage/rings/polynomial/evaluation_flint.pxd +7 -0
  323. sage/rings/polynomial/evaluation_flint.pyx +68 -0
  324. sage/rings/polynomial/hilbert.cpython-310-x86_64-linux-gnu.so +0 -0
  325. sage/rings/polynomial/hilbert.pyx +602 -0
  326. sage/rings/polynomial/polynomial_complex_arb.cpython-310-x86_64-linux-gnu.so +0 -0
  327. sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
  328. sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
  329. sage/rings/polynomial/polynomial_integer_dense_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  330. sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
  331. sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
  332. sage/rings/polynomial/polynomial_number_field.cpython-310-x86_64-linux-gnu.so +0 -0
  333. sage/rings/polynomial/polynomial_number_field.pyx +345 -0
  334. sage/rings/polynomial/polynomial_rational_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  335. sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
  336. sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
  337. sage/rings/polynomial/polynomial_zmod_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  338. sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
  339. sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
  340. sage/rings/polynomial/real_roots.cpython-310-x86_64-linux-gnu.so +0 -0
  341. sage/rings/polynomial/real_roots.pxd +81 -0
  342. sage/rings/polynomial/real_roots.pyx +4704 -0
  343. sage/rings/polynomial/refine_root.cpython-310-x86_64-linux-gnu.so +0 -0
  344. sage/rings/polynomial/refine_root.pyx +142 -0
  345. sage/rings/polynomial/weil/all.py +4 -0
  346. sage/rings/polynomial/weil/power_sums.h +46 -0
  347. sage/rings/polynomial/weil/weil_polynomials.cpython-310-x86_64-linux-gnu.so +0 -0
  348. sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
  349. sage/rings/qqbar.py +9025 -0
  350. sage/rings/real_arb.cpython-310-x86_64-linux-gnu.so +0 -0
  351. sage/rings/real_arb.pxd +21 -0
  352. sage/rings/real_arb.pyx +4065 -0
  353. sage/rings/real_interval_absolute.cpython-310-x86_64-linux-gnu.so +0 -0
  354. sage/rings/real_interval_absolute.pyx +1073 -0
  355. sage/rings/real_mpfi.cpython-310-x86_64-linux-gnu.so +0 -0
  356. sage/rings/real_mpfi.pyx +5428 -0
  357. sage/schemes/all__sagemath_flint.py +1 -0
  358. sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
  359. sage/schemes/elliptic_curves/descent_two_isogeny.cpython-310-x86_64-linux-gnu.so +0 -0
  360. sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
  361. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,2734 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.rings.number_field
3
+ r"""
4
+ Relative number fields
5
+
6
+ This example constructs a quadratic extension of a quartic number field::
7
+
8
+ sage: x = polygen(ZZ, 'x')
9
+ sage: K.<y> = NumberField(x^4 - 420*x^2 + 40000)
10
+ sage: z = y^5/11; z
11
+ 420/11*y^3 - 40000/11*y
12
+ sage: R.<y> = PolynomialRing(K)
13
+ sage: f = y^2 + y + 1
14
+ sage: L.<a> = K.extension(f); L
15
+ Number Field in a with defining polynomial y^2 + y + 1 over its base field
16
+ sage: KL.<b> = NumberField([x^4 - 420*x^2 + 40000, x^2 + x + 1]); KL
17
+ Number Field in b0 with defining polynomial x^4 - 420*x^2 + 40000 over its base field
18
+
19
+ We do some arithmetic in a tower of relative number fields::
20
+
21
+ sage: K.<cuberoot2> = NumberField(x^3 - 2)
22
+ sage: L.<cuberoot3> = K.extension(x^3 - 3)
23
+ sage: S.<sqrt2> = L.extension(x^2 - 2)
24
+ sage: S
25
+ Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
26
+ sage: sqrt2 * cuberoot3
27
+ cuberoot3*sqrt2
28
+ sage: (sqrt2 + cuberoot3)^5
29
+ (20*cuberoot3^2 + 15*cuberoot3 + 4)*sqrt2 + 3*cuberoot3^2 + 20*cuberoot3 + 60
30
+ sage: cuberoot2 + cuberoot3
31
+ cuberoot3 + cuberoot2
32
+ sage: cuberoot2 + cuberoot3 + sqrt2
33
+ sqrt2 + cuberoot3 + cuberoot2
34
+ sage: (cuberoot2 + cuberoot3 + sqrt2)^2
35
+ (2*cuberoot3 + 2*cuberoot2)*sqrt2 + cuberoot3^2 + 2*cuberoot2*cuberoot3 + cuberoot2^2 + 2
36
+ sage: cuberoot2 + sqrt2
37
+ sqrt2 + cuberoot2
38
+ sage: a = S(cuberoot2); a
39
+ cuberoot2
40
+ sage: a.parent()
41
+ Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
42
+
43
+ .. WARNING::
44
+
45
+ Doing arithmetic in towers of relative fields that depends on canonical
46
+ coercions is currently VERY SLOW. It is much better to explicitly coerce
47
+ all elements into a common field, then do arithmetic with them there (which
48
+ is quite fast).
49
+
50
+ TESTS::
51
+
52
+ sage: y = polygen(QQ,'y'); K.<beta> = NumberField([y^3 - 3, y^2 - 2])
53
+ sage: K(y^10)
54
+ 27*beta0
55
+ sage: beta^10
56
+ 27*beta0
57
+
58
+ AUTHORS:
59
+
60
+ - William Stein (2004, 2005): initial version
61
+ - Steven Sivek (2006-05-12): added support for relative extensions
62
+ - William Stein (2007-09-04): major rewrite and documentation
63
+ - Robert Bradshaw (2008-10): specified embeddings into ambient fields
64
+ - Nick Alexander (2009-01): modernized coercion implementation
65
+ - Robert Harron (2012-08): added is_CM_extension
66
+ - Julian Rüth (2014-04): absolute number fields are unique parents
67
+ """
68
+ # ****************************************************************************
69
+ # Copyright (C) 2004-2009 William Stein <wstein@gmail.com>
70
+ # 2014-2022 Julian Rüth <julian.rueth@fsfe.org>
71
+ #
72
+ # This program is free software: you can redistribute it and/or modify
73
+ # it under the terms of the GNU General Public License as published by
74
+ # the Free Software Foundation, either version 2 of the License, or
75
+ # (at your option) any later version.
76
+ # https://www.gnu.org/licenses/
77
+ # ****************************************************************************
78
+
79
+ from sage.categories.map import Map
80
+ from sage.structure.sequence import Sequence
81
+
82
+ import sage.rings.abc
83
+ import sage.structure.parent_gens
84
+
85
+ from . import maps
86
+ from . import structure
87
+
88
+ from sage.misc.latex import latex
89
+ from sage.misc.cachefunc import cached_method
90
+ from sage.structure.factorization import Factorization
91
+ import sage.rings.polynomial.polynomial_element as polynomial_element
92
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
93
+
94
+ from . import number_field_element
95
+ import sage.rings.number_field.number_field_ideal_rel
96
+ from .number_field_ideal import NumberFieldIdeal
97
+ from .number_field import (NumberField, NumberField_generic,
98
+ put_natural_embedding_first, proof_flag,
99
+ is_NumberFieldHomsetCodomain)
100
+ from sage.rings.number_field.number_field_base import NumberField as NumberField_base
101
+ from sage.rings.number_field.order import (RelativeOrder,
102
+ relative_order_from_ring_generators)
103
+ from sage.rings.number_field.morphism import RelativeNumberFieldHomomorphism_from_abs
104
+ from cypari2.gen import Gen as pari_gen
105
+
106
+ from sage.categories.homset import Hom
107
+ from sage.categories.sets_cat import Sets
108
+ from sage.modules.free_module import VectorSpace
109
+ from sage.modules.free_module_element import vector
110
+
111
+ from sage.rings.real_mpfr import RR
112
+ from sage.rings.rational_field import QQ
113
+ from sage.rings.integer_ring import ZZ
114
+
115
+
116
+ def is_RelativeNumberField(x):
117
+ r"""
118
+ Return ``True`` if `x` is a relative number field.
119
+
120
+ EXAMPLES::
121
+
122
+ sage: from sage.rings.number_field.number_field_rel import is_RelativeNumberField
123
+ sage: x = polygen(ZZ, 'x')
124
+ sage: is_RelativeNumberField(NumberField(x^2+1,'a'))
125
+ doctest:warning...
126
+ DeprecationWarning: The function is_RelativeNumberField is deprecated;
127
+ use 'isinstance(..., NumberField_relative)' instead.
128
+ See https://github.com/sagemath/sage/issues/38124 for details.
129
+ False
130
+ sage: k.<a> = NumberField(x^3 - 2)
131
+ sage: l.<b> = k.extension(x^3 - 3); l
132
+ Number Field in b with defining polynomial x^3 - 3 over its base field
133
+ sage: is_RelativeNumberField(l)
134
+ True
135
+ sage: is_RelativeNumberField(QQ)
136
+ False
137
+ """
138
+ from sage.misc.superseded import deprecation
139
+ deprecation(38124,
140
+ "The function is_RelativeNumberField is deprecated; "
141
+ "use 'isinstance(..., NumberField_relative)' instead.")
142
+ return isinstance(x, NumberField_relative)
143
+
144
+
145
+ class NumberField_relative(NumberField_generic):
146
+ """
147
+ INPUT:
148
+
149
+ - ``base`` -- the base field
150
+
151
+ - ``polynomial`` -- a polynomial which must be defined in the ring `K[x]`,
152
+ where `K` is the base field
153
+
154
+ - ``name`` -- string; the variable name
155
+
156
+ - ``latex_name`` -- string or ``None`` (default: ``None``); variable name
157
+ for latex printing
158
+
159
+ - ``check`` -- boolean (default: ``True``); whether to check
160
+ irreducibility of ``polynomial``
161
+
162
+ - ``embedding`` -- currently not supported, must be ``None``
163
+
164
+ - ``structure`` -- an instance of :class:`structure.NumberFieldStructure`
165
+ or ``None`` (default: ``None``), provides additional information about
166
+ this number field, e.g., the absolute number field from which it was
167
+ created
168
+
169
+ EXAMPLES::
170
+
171
+ sage: x = polygen(ZZ, 'x')
172
+ sage: K.<a> = NumberField(x^3 - 2)
173
+ sage: t = polygen(K)
174
+ sage: L.<b> = K.extension(t^2 + t + a); L
175
+ Number Field in b with defining polynomial x^2 + x + a over its base field
176
+
177
+ TESTS::
178
+
179
+ sage: Z = polygen(ZZ, 'Z')
180
+ sage: K.<w> = NumberField(Z^3 + Z + 1)
181
+ sage: L.<z> = K.extension(Z^3 + 2)
182
+ sage: K = loads(dumps(L))
183
+ sage: K
184
+ Number Field in z with defining polynomial Z^3 + 2 over its base field
185
+ sage: L is K
186
+ True
187
+
188
+ sage: M.<u,v> = L.change_names()
189
+ sage: M.structure()
190
+ (Isomorphism given by variable name change map:
191
+ From: Number Field in u with defining polynomial x^3 + 2 over its base field
192
+ To: Number Field in z with defining polynomial Z^3 + 2 over its base field,
193
+ Isomorphism given by variable name change map:
194
+ From: Number Field in z with defining polynomial Z^3 + 2 over its base field
195
+ To: Number Field in u with defining polynomial x^3 + 2 over its base field)
196
+ sage: loads(dumps(M)) is M
197
+ True
198
+ """
199
+ def __init__(self, base, polynomial, name,
200
+ latex_name=None, names=None, check=True, embedding=None, structure=None):
201
+ r"""
202
+ Initialization.
203
+
204
+ EXAMPLES::
205
+
206
+ sage: K.<x> = CyclotomicField(5)[]
207
+ sage: W.<a> = NumberField(x^2 + 1)
208
+ sage: W
209
+ Number Field in a with defining polynomial x^2 + 1 over its base field
210
+ sage: type(W)
211
+ <class 'sage.rings.number_field.number_field_rel.NumberField_relative_with_category'>
212
+
213
+ Test that check=False really skips the test::
214
+
215
+ sage: W.<a> = NumberField(K.cyclotomic_polynomial(5), check=False)
216
+ sage: W
217
+ Number Field in a with defining polynomial x^4 + x^3 + x^2 + x + 1 over its base field
218
+
219
+ A relative extension of a relative extension::
220
+
221
+ sage: x = polygen(ZZ)
222
+ sage: k.<a0,a1> = NumberField([x^2 + 2, x^2 + 1])
223
+ sage: l.<b> = k.extension(x^2 + 3)
224
+ sage: l
225
+ Number Field in b with defining polynomial x^2 + 3 over its base field
226
+ sage: l.base_field()
227
+ Number Field in a0 with defining polynomial x^2 + 2 over its base field
228
+ sage: l.base_field().base_field()
229
+ Number Field in a1 with defining polynomial x^2 + 1
230
+
231
+ Non-monic and non-integral polynomials are supported (:issue:`252`)::
232
+
233
+ sage: l.<b> = k.extension(5*x^2 + 3); l
234
+ Number Field in b with defining polynomial 5*x^2 + 3 over its base field
235
+ sage: l.pari_rnf()
236
+ [x^2 + (5/4*y^3 - 1/4*y^2 + 27/4*y - 3/4)*x + (-9/4*y^3 - 1/4*y^2 - 47/4*y - 7/4), ..., y^4 + 6*y^2 + 1, x^2 + (5/4*y^3 - 1/4*y^2 + 27/4*y - 3/4)*x + (-9/4*y^3 - 1/4*y^2 - 47/4*y - 7/4)], [0, 0]]
237
+ sage: b
238
+ b
239
+
240
+ sage: l.<b> = k.extension(x^2 + 3/5); l
241
+ Number Field in b with defining polynomial x^2 + 3/5 over its base field
242
+ sage: l.pari_rnf()
243
+ [x^2 + (5/4*y^3 - 1/4*y^2 + 27/4*y - 3/4)*x + (-9/4*y^3 - 1/4*y^2 - 47/4*y - 7/4), ..., y^4 + 6*y^2 + 1, x^2 + (5/4*y^3 - 1/4*y^2 + 27/4*y - 3/4)*x + (-9/4*y^3 - 1/4*y^2 - 47/4*y - 7/4)], [0, 0]]
244
+ sage: b
245
+ b
246
+
247
+ sage: l.<b> = k.extension(x - 1/a0); l
248
+ Number Field in b with defining polynomial x + 1/2*a0 over its base field
249
+ sage: l.pari_rnf()
250
+ [x, [4, -x^3 + x^2 - 7*x + 3, -2*x^3 - 10*x, x^3 + x^2 + 7*x + 3], ..., [x^4 + 6*x^2 + 1, -x, -1, y^4 + 6*y^2 + 1, x], [0, 0]]
251
+ sage: b
252
+ -1/2*a0
253
+
254
+ TESTS:
255
+
256
+ Test that irreducibility testing is working::
257
+
258
+ sage: x = polygen(ZZ)
259
+ sage: K.<a, b> = NumberField([x^2 + 2, x^2 + 3])
260
+ sage: K.<a> = NumberField(x^2 + 2)
261
+ sage: x = polygen(K)
262
+ sage: L.<b> = K.extension(x^3 + 3*a)
263
+
264
+ sage: (x^3 + 2*a).factor()
265
+ (x - a) * (x^2 + a*x - 2)
266
+ sage: L.<b> = K.extension(x^3 + 2*a)
267
+ Traceback (most recent call last):
268
+ ...
269
+ ValueError: defining polynomial (x^3 + 2*a) must be irreducible
270
+ sage: (x^2 + 2).factor()
271
+ (x - a) * (x + a)
272
+ sage: L.<b> = K.extension(x^2 + 2)
273
+ Traceback (most recent call last):
274
+ ...
275
+ ValueError: defining polynomial (x^2 + 2) must be irreducible
276
+ sage: L.<b> = K.extension(x^2 + 2)
277
+ Traceback (most recent call last):
278
+ ...
279
+ ValueError: defining polynomial (x^2 + 2) must be irreducible
280
+
281
+ Error checks::
282
+
283
+ sage: x = polygen(ZZ)
284
+ sage: K.<a> = NumberField(x^2 + 1)
285
+ sage: K.extension(x^2 + 2, 'a')
286
+ Traceback (most recent call last):
287
+ ...
288
+ ValueError: base field and extension cannot have the same name 'a'
289
+ """
290
+ if embedding is not None:
291
+ raise NotImplementedError("Embeddings not implemented for relative number fields")
292
+ if names is not None:
293
+ name = names
294
+ if not isinstance(base, NumberField_base):
295
+ raise TypeError("base (=%s) must be a number field" % base)
296
+ if not isinstance(polynomial, polynomial_element.Polynomial):
297
+ try:
298
+ polynomial = polynomial.polynomial(base)
299
+ except (AttributeError, TypeError):
300
+ raise TypeError("polynomial (=%r) must be a polynomial" % polynomial)
301
+ if name == base.variable_name():
302
+ raise ValueError("base field and extension cannot have the same name %r" % name)
303
+ if polynomial.parent().base_ring() != base:
304
+ polynomial = polynomial.change_ring(base)
305
+ # raise ValueError("The polynomial must be defined over the base field")
306
+
307
+ # Generate the nf and bnf corresponding to the base field
308
+ # defined as polynomials in y, e.g. for rnfisfree
309
+
310
+ # Convert the polynomial defining the base field into a
311
+ # polynomial in y to satisfy PARI's ordering requirements.
312
+
313
+ if base.is_relative():
314
+ abs_base = base.absolute_field(name + '0')
315
+ from_abs_base, to_abs_base = abs_base.structure()
316
+ else:
317
+ abs_base = base
318
+ from_abs_base = maps.IdentityMap(base)
319
+ to_abs_base = maps.IdentityMap(base)
320
+
321
+ self.__absolute_base_field = abs_base, from_abs_base, to_abs_base
322
+ self.__base_field = base
323
+ self.__relative_polynomial = polynomial
324
+ self._element_class = number_field_element.NumberFieldElement_relative
325
+
326
+ if check and not self.pari_relative_polynomial().polisirreducible():
327
+ raise ValueError("defining polynomial (%s) must be irreducible" % polynomial)
328
+
329
+ names = (name,) + base.variable_names()
330
+ self._assign_names(tuple(names), normalize=False)
331
+
332
+ NumberField_generic.__init__(self, self.absolute_polynomial(), name=None,
333
+ latex_name=latex_name, check=False,
334
+ embedding=embedding, structure=structure)
335
+
336
+ self._zero_element = self(0)
337
+ self._one_element = self(1)
338
+
339
+ def change_names(self, names):
340
+ r"""
341
+ Return relative number field isomorphic to ``self`` but with the
342
+ given generator names.
343
+
344
+ INPUT:
345
+
346
+ - ``names`` -- number of names should be at most the number of
347
+ generators of ``self``, i.e., the number of steps in the tower
348
+ of relative fields.
349
+
350
+ Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where
351
+ ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an
352
+ isomorphism from ``self`` to `K`.
353
+
354
+ EXAMPLES::
355
+
356
+ sage: x = polygen(ZZ, 'x')
357
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
358
+ Number Field in a with defining polynomial x^4 + 3 over its base field
359
+ sage: L.<c,d> = K.change_names()
360
+ sage: L
361
+ Number Field in c with defining polynomial x^4 + 3 over its base field
362
+ sage: L.base_field()
363
+ Number Field in d with defining polynomial x^2 + 2
364
+
365
+ An example with a 3-level tower::
366
+
367
+ sage: K.<a,b,c> = NumberField([x^2 + 17, x^2 + x + 1, x^3 - 2]); K
368
+ Number Field in a with defining polynomial x^2 + 17 over its base field
369
+ sage: L.<m,n,r> = K.change_names()
370
+ sage: L
371
+ Number Field in m with defining polynomial x^2 + 17 over its base field
372
+ sage: L.base_field()
373
+ Number Field in n with defining polynomial x^2 + x + 1 over its base field
374
+ sage: L.base_field().base_field()
375
+ Number Field in r with defining polynomial x^3 - 2
376
+
377
+ And a more complicated example::
378
+
379
+ sage: PQ.<X> = QQ[]
380
+ sage: F.<a, b> = NumberField([X^2 - 2, X^2 - 3])
381
+ sage: PF.<Y> = F[]
382
+ sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
383
+ sage: L.<m, n, r> = K.change_names(); L
384
+ Number Field in m with defining polynomial
385
+ x^2 + (-2*r - 3)*n - 2*r - 6 over its base field
386
+ sage: L.structure()
387
+ (Isomorphism given by variable name change map:
388
+ From: Number Field in m with defining polynomial
389
+ x^2 + (-2*r - 3)*n - 2*r - 6 over its base field
390
+ To: Number Field in c with defining polynomial
391
+ Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field,
392
+ Isomorphism given by variable name change map:
393
+ From: Number Field in c with defining polynomial
394
+ Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
395
+ To: Number Field in m with defining polynomial
396
+ x^2 + (-2*r - 3)*n - 2*r - 6 over its base field)
397
+ """
398
+ if len(names) == 0:
399
+ names = self.variable_names()
400
+ elif isinstance(names, str):
401
+ names = names.split(',')
402
+ K = self.base_field().change_names(tuple(names[1:]))
403
+ to_K = K.structure()[1]
404
+ old_poly = self.relative_polynomial()
405
+ new_poly = PolynomialRing(K, 'x')([to_K(c) for c in old_poly])
406
+ return K.extension(new_poly, names=names[0], structure=structure.NameChange(self))
407
+
408
+ def subfields(self, degree=0, name=None):
409
+ """
410
+ Return all subfields of this relative number field ``self`` of the given degree,
411
+ or of all possible degrees if degree is 0. The subfields are returned as
412
+ absolute fields together with an embedding into ``self``. For the case of the
413
+ field itself, the reverse isomorphism is also provided.
414
+
415
+ EXAMPLES::
416
+
417
+ sage: PQ.<X> = QQ[]
418
+ sage: F.<a, b> = NumberField([X^2 - 2, X^2 - 3])
419
+ sage: PF.<Y> = F[]
420
+ sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
421
+ sage: K.subfields(2)
422
+ [(Number Field in c0 with defining polynomial x^2 - 24*x + 96,
423
+ Ring morphism:
424
+ From: Number Field in c0 with defining polynomial x^2 - 24*x + 96
425
+ To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
426
+ Defn: c0 |--> -4*b + 12,
427
+ None),
428
+ (Number Field in c1 with defining polynomial x^2 - 24*x + 120,
429
+ Ring morphism:
430
+ From: Number Field in c1 with defining polynomial x^2 - 24*x + 120
431
+ To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
432
+ Defn: c1 |--> 2*b*a + 12,
433
+ None),
434
+ (Number Field in c2 with defining polynomial x^2 - 24*x + 72,
435
+ Ring morphism:
436
+ From: Number Field in c2 with defining polynomial x^2 - 24*x + 72
437
+ To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
438
+ Defn: c2 |--> -6*a + 12,
439
+ None)]
440
+ sage: K.subfields(8, 'w')
441
+ [(Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9,
442
+ Ring morphism:
443
+ From: Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9
444
+ To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
445
+ Defn: w0 |--> (-1/2*b*a + 1/2*b + 1/2)*c,
446
+ Relative number field morphism:
447
+ From: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
448
+ To: Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9
449
+ Defn: c |--> -1/3*w0^7 + 4*w0^5 - 12*w0^3 + 11*w0
450
+ a |--> 1/3*w0^6 - 10/3*w0^4 + 5*w0^2
451
+ b |--> -2/3*w0^6 + 7*w0^4 - 14*w0^2 + 6)]
452
+ sage: K.subfields(3)
453
+ []
454
+ """
455
+ if name is None:
456
+ name = self.variable_name()
457
+ abs = self.absolute_field(name)
458
+ from_abs, to_abs = abs.structure()
459
+ abs_subfields = abs.subfields(degree=degree)
460
+ ans = []
461
+ for K, from_K, to_K in abs_subfields:
462
+ from_K = K.hom([from_abs(from_K(K.gen()))])
463
+ if to_K is not None:
464
+ to_K = RelativeNumberFieldHomomorphism_from_abs(self.Hom(K), to_K*to_abs)
465
+ ans.append((K, from_K, to_K))
466
+ ans = Sequence(ans, immutable=True, cr=bool(ans))
467
+ return ans
468
+
469
+ def is_absolute(self):
470
+ r"""
471
+ Return ``False``, since this is not an absolute field.
472
+
473
+ EXAMPLES::
474
+
475
+ sage: x = polygen(ZZ, 'x')
476
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
477
+ Number Field in a with defining polynomial x^4 + 3 over its base field
478
+ sage: K.is_absolute()
479
+ False
480
+ sage: K.is_relative()
481
+ True
482
+ """
483
+ return False
484
+
485
+ def gens(self) -> tuple:
486
+ """
487
+ Return the generators of this relative number field.
488
+
489
+ EXAMPLES::
490
+
491
+ sage: x = polygen(ZZ, 'x')
492
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
493
+ Number Field in a with defining polynomial x^4 + 3 over its base field
494
+ sage: K.gens()
495
+ (a, b)
496
+
497
+ TESTS:
498
+
499
+ Trivial extensions work like non-trivial ones (:issue:`2220`)::
500
+
501
+ sage: NumberField([x^2 - 3, x], 'a').gens()
502
+ (a0, 0)
503
+ sage: NumberField([x, x^2 - 3], 'a').gens()
504
+ (0, a1)
505
+ """
506
+ return ((self._gen_relative(),) +
507
+ tuple(map(self, self.base_field().gens())))
508
+
509
+ def _first_ngens(self, n):
510
+ """
511
+ Return the first `n` generators of this relative number field.
512
+
513
+ If `n` is greater than the number of generators, the output is
514
+ the same as that of :meth:`gens`.
515
+
516
+ EXAMPLES::
517
+
518
+ sage: x = polygen(ZZ, 'x')
519
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
520
+ Number Field in a with defining polynomial x^4 + 3 over its base field
521
+ sage: K._first_ngens(0)
522
+ ()
523
+ sage: K._first_ngens(1)
524
+ (a,)
525
+ sage: K._first_ngens(2)
526
+ (a, b)
527
+ sage: K._first_ngens(3)
528
+ (a, b)
529
+ """
530
+ if n <= 0:
531
+ return ()
532
+ v = (self._gen_relative(),)
533
+ if n > 1:
534
+ v += tuple(map(self, self.base_field()._first_ngens(n - 1)))
535
+ return v
536
+
537
+ def ngens(self):
538
+ """
539
+ Return the number of generators of this relative number field.
540
+
541
+ EXAMPLES::
542
+
543
+ sage: x = polygen(ZZ, 'x')
544
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
545
+ Number Field in a with defining polynomial x^4 + 3 over its base field
546
+ sage: K.gens()
547
+ (a, b)
548
+ sage: K.ngens()
549
+ 2
550
+ """
551
+ return self.base_field().ngens() + 1
552
+
553
+ def gen(self, n=0):
554
+ """
555
+ Return the `n`-th generator of this relative number field.
556
+
557
+ EXAMPLES::
558
+
559
+ sage: x = polygen(ZZ, 'x')
560
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
561
+ Number Field in a with defining polynomial x^4 + 3 over its base field
562
+ sage: K.gens()
563
+ (a, b)
564
+ sage: K.gen(0)
565
+ a
566
+ """
567
+ if n == 0:
568
+ return self._gen_relative()
569
+ return self(self.base_field().gen(n - 1))
570
+
571
+ def galois_closure(self, names=None):
572
+ r"""
573
+ Return the absolute number field `K` that is the Galois closure of this
574
+ relative number field.
575
+
576
+ EXAMPLES::
577
+
578
+ sage: x = polygen(ZZ, 'x')
579
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
580
+ Number Field in a with defining polynomial x^4 + 3 over its base field
581
+ sage: K.galois_closure('c') # needs sage.groups
582
+ Number Field in c with defining polynomial x^16 + 16*x^14 + 28*x^12
583
+ + 784*x^10 + 19846*x^8 - 595280*x^6 + 2744476*x^4 + 3212848*x^2 + 29953729
584
+ """
585
+ return self.absolute_field('a').galois_closure(names=names)
586
+
587
+ def composite_fields(self, other, names=None, both_maps=False, preserve_embedding=True):
588
+ """
589
+ List of all possible composite number fields formed from ``self`` and
590
+ ``other``, together with (optionally) embeddings into the compositum;
591
+ see the documentation for ``both_maps`` below.
592
+
593
+ Since relative fields do not have ambient embeddings,
594
+ ``preserve_embedding`` has no effect. In every case all possible
595
+ composite number fields are returned.
596
+
597
+ INPUT:
598
+
599
+ - ``other`` -- a number field
600
+
601
+ - ``names`` -- generator name for composite fields
602
+
603
+ - ``both_maps`` -- boolean (default: ``False``); if ``True``, return
604
+ quadruples (`F`, ``self_into_F, ``other_into_F``, `k`) such that
605
+ ``self_into_F`` maps ``self`` into `F`, ``other_into_F`` maps
606
+ ``other`` into `F`. For relative number fields, `k` is always
607
+ ``None``.
608
+
609
+ - ``preserve_embedding`` -- boolean (default: ``True``); has no effect,
610
+ but is kept for compatibility with the absolute version of this,
611
+ method. In every case the list of all possible compositums is returned.
612
+
613
+ OUTPUT: list of the composite fields, possibly with maps
614
+
615
+ EXAMPLES::
616
+
617
+ sage: x = polygen(ZZ, 'x')
618
+ sage: K.<a, b> = NumberField([x^2 + 5, x^2 - 2])
619
+ sage: L.<c, d> = NumberField([x^2 + 5, x^2 - 3])
620
+ sage: K.composite_fields(L, 'e')
621
+ [Number Field in e with defining polynomial
622
+ x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600]
623
+ sage: K.composite_fields(L, 'e', both_maps=True)
624
+ [[Number Field in e with defining polynomial
625
+ x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600,
626
+ Relative number field morphism:
627
+ From: Number Field in a with defining polynomial x^2 + 5 over its base field
628
+ To: Number Field in e with defining polynomial
629
+ x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600
630
+ Defn: a |--> -9/66560*e^7 + 11/4160*e^5 - 241/4160*e^3 - 101/104*e
631
+ b |--> -21/166400*e^7 + 73/20800*e^5 - 779/10400*e^3 + 7/260*e,
632
+ Relative number field morphism:
633
+ From: Number Field in c with defining polynomial x^2 + 5 over its base field
634
+ To: Number Field in e with defining polynomial
635
+ x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600
636
+ Defn: c |--> -9/66560*e^7 + 11/4160*e^5 - 241/4160*e^3 - 101/104*e
637
+ d |--> -3/25600*e^7 + 7/1600*e^5 - 147/1600*e^3 + 1/40*e,
638
+ None]]
639
+ """
640
+ if not isinstance(other, NumberField_generic):
641
+ raise TypeError("other must be a number field.")
642
+ if names is None:
643
+ sv = self.variable_name()
644
+ ov = other.variable_name()
645
+ names = sv + (ov if ov != sv else "")
646
+
647
+ self_abs = self.absolute_field('w')
648
+ abs_composites = self_abs.composite_fields(other, names=names, both_maps=both_maps)
649
+
650
+ m = self.absolute_degree()
651
+
652
+ if not both_maps:
653
+ rets = []
654
+ for F in abs_composites:
655
+ if F.absolute_degree() == m:
656
+ F = self
657
+ rets.append(F)
658
+ return rets
659
+
660
+ from_self_abs, to_self_abs = self_abs.structure()
661
+
662
+ rets = []
663
+ for F, self_abs_to_F, other_to_F, k in abs_composites:
664
+ self_to_F = RelativeNumberFieldHomomorphism_from_abs(self.Hom(F), self_abs_to_F*to_self_abs)
665
+ if F.absolute_degree() == m:
666
+ if other.is_absolute():
667
+ other_to_F = other.hom([(from_self_abs*(~self_abs_to_F)*other_to_F)(other.gen())])
668
+ else:
669
+ other_to_F = RelativeNumberFieldHomomorphism_from_abs(self.Hom(self), from_self_abs*(~self_abs_to_F)*other_to_F)
670
+ self_to_F = RelativeNumberFieldHomomorphism_from_abs(self.Hom(self), from_self_abs)
671
+ F = self
672
+ rets.append([F, self_to_F, other_to_F, None])
673
+ return rets
674
+
675
+ def absolute_degree(self):
676
+ """
677
+ The degree of this relative number field over the rational field.
678
+
679
+ EXAMPLES::
680
+
681
+ sage: x = polygen(ZZ, 'x')
682
+ sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
683
+ sage: K.absolute_degree()
684
+ 6
685
+ """
686
+ return self.absolute_polynomial().degree()
687
+
688
+ def relative_degree(self):
689
+ r"""
690
+ Return the relative degree of this relative number field.
691
+
692
+ EXAMPLES::
693
+
694
+ sage: x = polygen(ZZ, 'x')
695
+ sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
696
+ sage: K.relative_degree()
697
+ 2
698
+ """
699
+ return self.relative_polynomial().degree()
700
+
701
+ def degree(self):
702
+ """
703
+ The degree, unqualified, of a relative number field is deliberately
704
+ not implemented, so that a user cannot mistake the absolute degree
705
+ for the relative degree, or vice versa.
706
+
707
+ EXAMPLES::
708
+
709
+ sage: x = polygen(ZZ, 'x')
710
+ sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
711
+ sage: K.degree()
712
+ Traceback (most recent call last):
713
+ ...
714
+ NotImplementedError: For a relative number field
715
+ you must use relative_degree or absolute_degree as appropriate
716
+ """
717
+ raise NotImplementedError("For a relative number field you must use relative_degree or absolute_degree as appropriate")
718
+
719
+ @cached_method
720
+ def _maximal_order(self, v=(), assume_maximal='non-maximal-non-unique'):
721
+ """
722
+ Implement :meth:`NumberField_generic.maximal_order` for relative
723
+ number fields.
724
+
725
+ EXAMPLES::
726
+
727
+ sage: x = polygen(ZZ, 'x')
728
+ sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
729
+ sage: K.maximal_order() is K.maximal_order() # indirect doctest
730
+ True
731
+ """
732
+ absolute_order = self.absolute_field('z').maximal_order(v=v, assume_maximal=assume_maximal)
733
+
734
+ return RelativeOrder(self, absolute_order, is_maximal=assume_maximal, is_maximal_at=v)
735
+
736
+ def _repr_(self):
737
+ """
738
+ Return string representation of this relative number field.
739
+
740
+ The base field is not part of the string representation. To
741
+ find out what the base field is use :meth:`~base_field`.
742
+
743
+ EXAMPLES::
744
+
745
+ sage: x = polygen(ZZ, 'x')
746
+ sage: k.<a, b> = NumberField([x^5 + 2, x^7 + 3])
747
+ sage: repr(k) # indirect doctest
748
+ 'Number Field in a with defining polynomial x^5 + 2 over its base field'
749
+ sage: k.base_field()
750
+ Number Field in b with defining polynomial x^7 + 3
751
+ """
752
+
753
+ return "Number Field in %s with defining polynomial %s over its base field" % (self.variable_name(), self.relative_polynomial())
754
+
755
+ def _Hom_(self, codomain, category=None):
756
+ """
757
+ Return homset of homomorphisms from this relative number field
758
+ to the codomain.
759
+
760
+ EXAMPLES:
761
+
762
+ This function is implicitly called by the ``Hom`` method or
763
+ function::
764
+
765
+ sage: x = polygen(ZZ, 'x')
766
+ sage: K.<a,b> = NumberField([x^3 - 2, x^2+1])
767
+ sage: K.Hom(K) # indirect doctest
768
+ Automorphism group of Number Field in a with defining polynomial x^3 - 2 over its base field
769
+ sage: type(K.Hom(K))
770
+ <class 'sage.rings.number_field.homset.RelativeNumberFieldHomset_with_category'>
771
+
772
+ TESTS::
773
+
774
+ sage: H = End(K)
775
+ sage: loads(dumps(H)) is H
776
+ True
777
+ """
778
+ if not is_NumberFieldHomsetCodomain(codomain):
779
+ raise TypeError("{} is not suitable as codomain for homomorphisms from {}".format(codomain, self))
780
+
781
+ from sage.rings.number_field.homset import RelativeNumberFieldHomset
782
+ return RelativeNumberFieldHomset(self, codomain, category)
783
+
784
+ def _latex_(self):
785
+ r"""
786
+ Return a `\LaTeX` representation of the extension.
787
+
788
+ EXAMPLES::
789
+
790
+ sage: x = polygen(QQ)
791
+ sage: x = polygen(ZZ, 'x')
792
+ sage: K.<a> = NumberField(x^3 - 2)
793
+ sage: t = polygen(K)
794
+ sage: K.extension(t^2+t+a, 'b')._latex_()
795
+ '( \\Bold{Q}[a]/(a^{3} - 2) )[b]/(b^{2} + b + a)'
796
+ """
797
+ latex_name = self.latex_variable_names()[0]
798
+ return "( %s )[%s]/(%s)" % (latex(self.base_field()), latex_name,
799
+ self.relative_polynomial()._latex_(latex_name))
800
+
801
+ def _coerce_from_other_number_field(self, x):
802
+ """
803
+ Coerce a number field element x into this number field.
804
+
805
+ In most cases this currently doesn't work (since it is
806
+ barely implemented) -- it only works for constants.
807
+
808
+ INPUT:
809
+
810
+ - ``x`` -- an element of some number field
811
+
812
+ EXAMPLES::
813
+
814
+ sage: x = polygen(ZZ, 'x')
815
+ sage: K.<a> = NumberField(x^3 + 2)
816
+ sage: L.<b> = NumberField(x^2 + 1)
817
+ sage: K._coerce_from_other_number_field(L(2/3))
818
+ 2/3
819
+ """
820
+ if x.parent() is self.base_ring():
821
+ return self.__base_inclusion(x)
822
+
823
+ f = x.polynomial()
824
+ if f.degree() <= 0:
825
+ return self._element_class(self, f[0])
826
+ # todo: more general coercion if embedding have been asserted
827
+ raise TypeError("Cannot coerce element into this number field")
828
+
829
+ def _convert_non_number_field_element(self, x):
830
+ r"""
831
+ Convert the non-number field element `x` into this number field.
832
+
833
+ INPUT:
834
+
835
+ - ``x`` -- a non number field element, e.g., a list,
836
+ integer, rational, or polynomial
837
+
838
+ EXAMPLES::
839
+
840
+ sage: x = polygen(ZZ)
841
+ sage: K.<a> = NumberField(x^5 + 2)
842
+ sage: L.<b> = K.extension(x^2 + 3*a)
843
+ sage: R.<u> = QQ[]
844
+ sage: S.<t> = R[]
845
+
846
+ sage: L(a + b)
847
+ b + a
848
+
849
+ sage: L(5*t*(1 + u) + 2/3*u)
850
+ (5*a + 5)*b + 2/3*a
851
+ sage: L(0*t + 2/3)
852
+ 2/3
853
+ sage: L(1/2*t + 5)
854
+ 1/2*b + 5
855
+
856
+ This seems reasonable::
857
+
858
+ sage: L(t*5)
859
+ 5*b
860
+
861
+ This is misleading, but correct! It is more often desired
862
+ to make a number field element given by rational
863
+ coefficients of the relative power basis (so 2*b^2 + 3)
864
+ than it is to create the constant term of such an element,
865
+ which is what would happen if L(u*5) gave 5*a.::
866
+
867
+ sage: L(u*5)
868
+ 5*b
869
+
870
+ sage: L([1, 1/2])
871
+ 1/2*b + 1
872
+ sage: L([ a, 1/2 + a/3 ])
873
+ (1/3*a + 1/2)*b + a
874
+
875
+ sage: L([ 1 ])
876
+ Traceback (most recent call last):
877
+ ...
878
+ ValueError: Length must be equal to the degree of this number field
879
+
880
+ TESTS:
881
+
882
+ Examples from :issue:`4727`::
883
+
884
+ sage: # needs fpylll sage.symbolic
885
+ sage: K.<j,b> = QQ[sqrt(-1), sqrt(2)]
886
+ sage: j
887
+ I
888
+ sage: j.list()
889
+ [0, 1]
890
+ sage: K(j.list())
891
+ I
892
+ sage: (b*j + 1/2).list()
893
+ [1/2, sqrt2]
894
+ sage: K((b*j + 1/2).list())
895
+ sqrt2*I + 1/2
896
+
897
+ Examples from :issue:`4869`::
898
+
899
+ sage: K.<z> = CyclotomicField(7)
900
+ sage: Ky.<y> = PolynomialRing(K)
901
+ sage: L.<a> = K.extension(y^2 + 1)
902
+ sage: K(K.polynomial_ring().random_element()) # random
903
+ -12*z^2 + 1/2*z - 1/95
904
+ sage: L(L.polynomial_ring().random_element()) # random
905
+ (z^5 + 1/3*z^4 - z^3 + z^2 - z + 2/3)*a + 1/4*z^5 - 7/2*z^4 + 5/3*z^3 - 1/4*z^2 + 3/2*z - 1
906
+
907
+ Examples from :issue:`11307`::
908
+
909
+ sage: L = NumberField([x^2 + 1, x^2 - 3], 'a')
910
+ sage: L(L)
911
+ Traceback (most recent call last):
912
+ ...
913
+ TypeError: unable to convert Number Field in a0 with defining polynomial x^2 + 1 over its base field
914
+ to Number Field in a0 with defining polynomial x^2 + 1 over its base field
915
+ sage: L in L
916
+ False
917
+
918
+ We construct the composite of three quadratic fields, then
919
+ coerce from the quartic subfield of the relative extension::
920
+
921
+ sage: k.<a,b,c> = NumberField([x^2 + 5, x^2 + 3, x^2 + 1])
922
+ sage: m = k.base_field(); m
923
+ Number Field in b with defining polynomial x^2 + 3 over its base field
924
+ sage: k(m.0)
925
+ b
926
+ sage: k(2/3)
927
+ 2/3
928
+ sage: k(m.0^4)
929
+ 9
930
+
931
+ sage: x = polygen(ZZ)
932
+ sage: K.<a> = NumberField(x^2 + 2, 'a')
933
+ sage: L.<b> = K.extension(x - a, 'b')
934
+ sage: L(a)
935
+ a
936
+ sage: L(b+a)
937
+ 2*a
938
+ sage: K.<a> = NumberField(x^5 + 2, 'a')
939
+ sage: L.<b> = K.extension(x - a, 'b')
940
+ sage: L(a)
941
+ a
942
+ sage: L(a**3)
943
+ a^3
944
+ sage: L(a**2+b)
945
+ a^2 + a
946
+ sage: L.<b> = K.extension(x + a/2, 'b')
947
+ sage: L(a)
948
+ a
949
+ sage: L(a).polynomial()
950
+ -x
951
+ sage: L(a).minpoly()
952
+ x - a
953
+ sage: L(a).absolute_minpoly()
954
+ x^5 + 2
955
+ sage: L(b)
956
+ -1/2*a
957
+ sage: L(b).polynomial()
958
+ 1/2*x
959
+ sage: L(b).absolute_minpoly()
960
+ x^5 - 1/16
961
+ sage: L(b).minpoly()
962
+ x + 1/2*a
963
+
964
+ ::
965
+
966
+ sage: K.<a> = NumberField(x^5+2)
967
+ sage: R.<y> = K[]
968
+ sage: L.<x0> = K.extension(y + a**2)
969
+ sage: L(a)
970
+ a
971
+ """
972
+ if isinstance(x, polynomial_element.Polynomial):
973
+ # we have been given a polynomial, change it to an absolute polynomial
974
+ K = self.base_ring()
975
+ R = self.polynomial_ring()
976
+ if QQ.has_coerce_map_from(x.parent().base_ring()):
977
+ # special case absolute polynomials -- they should be
978
+ # in terms of the relative generator
979
+ x = R(x.list())
980
+ # this should work for base_ring()['x'] and QQ['base']['ext']
981
+ x = self.polynomial_ring()(x)
982
+ f = R( [ K(coeff) for coeff in x.list() ] )
983
+ return self._element_class(self, f(self.gen()).polynomial() )
984
+
985
+ # Anything else: use the code for generic number fields
986
+ return super()._convert_non_number_field_element(x)
987
+
988
+ def _coerce_map_from_(self, R):
989
+ """
990
+ Canonical coercion of x into this relative number field.
991
+
992
+ Currently integers, rationals, the base field, and this field
993
+ itself coerce canonically into this field (and hence so does
994
+ anything that coerces into one of these).
995
+
996
+ EXAMPLES::
997
+
998
+ sage: x = polygen(ZZ, 'x')
999
+ sage: k.<a> = NumberField([x^5 + 2, x^7 + 3])
1000
+ sage: b = k(k.base_field().gen())
1001
+ sage: b = k.coerce(k.base_field().gen()) # indirect doctest
1002
+ sage: b^7
1003
+ -3
1004
+ sage: k.coerce(2/3)
1005
+ 2/3
1006
+ sage: c = a + b # no output
1007
+ """
1008
+ if R is int:
1009
+ return self._generic_coerce_map(R)
1010
+ if R in (ZZ, QQ, self.base_field()):
1011
+ return self._generic_coerce_map(R)
1012
+ if isinstance(R, sage.rings.abc.Order) and R.number_field() is self:
1013
+ return self._generic_coerce_map(R)
1014
+ mor = self.base_field()._internal_coerce_map_from(R)
1015
+ if mor is not None:
1016
+ return self._internal_coerce_map_from(self.base_field()) * mor
1017
+
1018
+ def _element_constructor_(self, x, check=True):
1019
+ """
1020
+ Construct a relative number field element from ``x``.
1021
+
1022
+ EXAMPLES:
1023
+
1024
+ We can create relative number field elements from PARI::
1025
+
1026
+ sage: y = polygen(QQ)
1027
+ sage: K.<a> = NumberField(y^2 + y + 1)
1028
+ sage: x = polygen(K)
1029
+ sage: L.<b> = NumberField(x^4 + a*x + 2)
1030
+ sage: e = a.__pari__(); e
1031
+ Mod(y, y^2 + y + 1)
1032
+ sage: L(e) # Conversion from PARI base field element
1033
+ a
1034
+ sage: e = (a*b).__pari__('x'); e
1035
+ Mod(-x^4 - 2, x^8 - x^5 + 4*x^4 + x^2 - 2*x + 4)
1036
+ sage: L(e) # Conversion from PARI absolute number field element
1037
+ a*b
1038
+ sage: e = L.pari_rnf().rnfeltabstorel(e); e
1039
+ Mod(Mod(y, y^2 + y + 1)*x, x^4 + Mod(y, y^2 + y + 1)*x + 2)
1040
+ sage: L(e) # Conversion from PARI relative number field element
1041
+ a*b
1042
+ sage: e = pari('Mod(0, x^8 + 1)'); L(e) # Wrong modulus
1043
+ Traceback (most recent call last):
1044
+ ...
1045
+ TypeError: cannot convert PARI element Mod(0, x^8 + 1) into Number Field in b with defining polynomial x^4 + a*x + 2 over its base field
1046
+
1047
+ We test a relative number field element created "by hand"::
1048
+
1049
+ sage: e = pari("Mod(Mod(y, y^2 + y + 1)*x^2 + Mod(1, y^2 + y + 1), x^4 + y*x + 2)")
1050
+ sage: L(e)
1051
+ a*b^2 + 1
1052
+
1053
+ A wrong modulus yields an error::
1054
+
1055
+ sage: e = pari('Mod(y*x, x^4 + y^2*x + 2)'); L(e)
1056
+ Traceback (most recent call last):
1057
+ ...
1058
+ TypeError: cannot convert PARI element Mod(y*x, x^4 + y^2*x + 2) into Number Field in b with defining polynomial x^4 + a*x + 2 over its base field
1059
+ """
1060
+ # If x is a *relative* PARI number field element, convert it
1061
+ # to an absolute element.
1062
+ if isinstance(x, pari_gen) and x.type() == "t_POLMOD":
1063
+ modulus = x.mod()
1064
+ if (modulus == self.pari_relative_polynomial()
1065
+ or modulus == self.pari_absolute_base_polynomial()):
1066
+ x = self._pari_rnfeq()._eltreltoabs(x.liftpol())
1067
+ check = False
1068
+ return NumberField_generic._element_constructor_(self, x, check=check)
1069
+
1070
+ def __base_inclusion(self, element):
1071
+ """
1072
+ Given an element of the base field, give its inclusion into
1073
+ this extension in terms of the generator of this field.
1074
+
1075
+ This is called by the canonical coercion map on elements from
1076
+ the base field.
1077
+
1078
+ EXAMPLES::
1079
+
1080
+ sage: x = polygen(ZZ, 'x')
1081
+ sage: k.<a> = NumberField([x^2 + 3, x^2 + 1])
1082
+ sage: m = k.base_field(); m
1083
+ Number Field in a1 with defining polynomial x^2 + 1
1084
+ sage: k.coerce(m.0 + 2/3) # indirect doctest
1085
+ a1 + 2/3
1086
+ sage: s = k.coerce(m.0); s
1087
+ a1
1088
+ sage: s^2
1089
+ -1
1090
+
1091
+ This implicitly tests this coercion map::
1092
+
1093
+ sage: K.<a> = NumberField([x^2 + p for p in [5,3,2]])
1094
+ sage: K.coerce(K.base_field().0)
1095
+ a1
1096
+ sage: K.coerce(K.base_field().0)^2
1097
+ -3
1098
+
1099
+ TESTS:
1100
+
1101
+ Check that :issue:`5828` is solved::
1102
+
1103
+ sage: K.<w> = QuadraticField(-1)
1104
+ sage: KX.<X> = K[]
1105
+ sage: H.<h> = K.extension(X-1)
1106
+ sage: H(w)
1107
+ w
1108
+ """
1109
+ abs_base, from_abs_base, to_abs_base = self.absolute_base_field()
1110
+ # Write element in terms of the absolute base field
1111
+ element = self.base_field().coerce(element)
1112
+ element = to_abs_base(element)
1113
+ # Express element as a polynomial in the absolute generator of self
1114
+ nfzk = self._pari_nfzk()
1115
+ expr_x = self._pari_base_nf()._nfeltup(element._pari_polynomial(), nfzk)
1116
+ # We do NOT call self(...) because this code is called by
1117
+ # __init__ before we initialize self.gens(), and self(...)
1118
+ # uses self.gens()
1119
+ return self._element_constructor_(expr_x, check=False)
1120
+
1121
+ def _fractional_ideal_class_(self):
1122
+ """
1123
+ Return the Python class used to represent ideals of a relative
1124
+ number field.
1125
+
1126
+ EXAMPLES::
1127
+
1128
+ sage: x = polygen(ZZ, 'x')
1129
+ sage: k.<a> = NumberField([x^5 + 2, x^7 + 3])
1130
+ sage: k._fractional_ideal_class_ ()
1131
+ <class 'sage.rings.number_field.number_field_ideal_rel.NumberFieldFractionalIdeal_rel'>
1132
+ """
1133
+ return sage.rings.number_field.number_field_ideal_rel.NumberFieldFractionalIdeal_rel
1134
+
1135
+ def _pari_base_bnf(self, proof=False, units=True):
1136
+ r"""
1137
+ Return the PARI bnf (big number field) representation of the
1138
+ absolute base field in terms of the pari variable ``y``, suitable
1139
+ for extension by the pari variable ``x``.
1140
+
1141
+ All caching is done by the absolute base field.
1142
+
1143
+ INPUT:
1144
+
1145
+ - ``proof`` -- boolean (default: ``True``); if ``True``, certify
1146
+ correctness of calculations (not assuming GRH)
1147
+
1148
+ EXAMPLES::
1149
+
1150
+ sage: x = polygen(ZZ, 'x')
1151
+ sage: k.<a> = NumberField([x^3 + 2, x^2 + 2])
1152
+ sage: k._pari_base_bnf()
1153
+ [[;], matrix(0,3), [;], ...]
1154
+ """
1155
+ abs_base, from_abs_base, to_abs_base = self.absolute_base_field()
1156
+ return abs_base.pari_bnf(proof, units)
1157
+
1158
+ def _pari_base_nf(self):
1159
+ r"""
1160
+ Return the PARI number field representation of the absolute
1161
+ base field, in terms of the pari variable ``y``, suitable for
1162
+ extension by the pari variable ``x``.
1163
+
1164
+ All caching is done by the absolute base field.
1165
+
1166
+ EXAMPLES::
1167
+
1168
+ sage: y = polygen(QQ,'y')
1169
+ sage: k.<a> = NumberField([y^3 + 2, y^2 + 2])
1170
+ sage: k._pari_base_nf()
1171
+ [y^2 + 2, [0, 1], -8, 1, ..., [1, 0, 0, -2; 0, 1, 1, 0]]
1172
+ """
1173
+ abs_base, from_abs_base, to_abs_base = self.absolute_base_field()
1174
+ return abs_base.pari_nf()
1175
+
1176
+ def is_galois(self):
1177
+ r"""
1178
+ For a relative number field, :meth:`is_galois` is deliberately not
1179
+ implemented, since it is not clear whether this would mean "Galois over
1180
+ `\QQ`" or "Galois over the given base field".
1181
+ Use either :meth:`is_galois_absolute` or :meth:`is_galois_relative`, respectively.
1182
+
1183
+ EXAMPLES::
1184
+
1185
+ sage: x = polygen(ZZ, 'x')
1186
+ sage: k.<a> = NumberField([x^3 - 2, x^2 + x + 1])
1187
+ sage: k.is_galois()
1188
+ Traceback (most recent call last):
1189
+ ...
1190
+ NotImplementedError: For a relative number field L you must use
1191
+ either L.is_galois_relative() or L.is_galois_absolute() as appropriate
1192
+ """
1193
+ raise NotImplementedError("For a relative number field L you must use either L.is_galois_relative() or L.is_galois_absolute() as appropriate")
1194
+
1195
+ def is_galois_relative(self):
1196
+ r"""
1197
+ Return ``True`` if for this relative extension `L/K`, `L` is a
1198
+ Galois extension of `K`.
1199
+
1200
+ EXAMPLES::
1201
+
1202
+ sage: x = polygen(ZZ, 'x')
1203
+ sage: K.<a> = NumberField(x^3 - 2)
1204
+ sage: y = polygen(K)
1205
+ sage: L.<b> = K.extension(y^2 - a)
1206
+ sage: L.is_galois_relative()
1207
+ True
1208
+ sage: M.<c> = K.extension(y^3 - a)
1209
+ sage: M.is_galois_relative()
1210
+ False
1211
+
1212
+ The next example previously gave a wrong result; see :issue:`9390`::
1213
+
1214
+ sage: F.<a, b> = NumberField([x^2 - 2, x^2 - 3])
1215
+ sage: F.is_galois_relative()
1216
+ True
1217
+ """
1218
+ d = self.relative_degree()
1219
+ if d <= 2:
1220
+ return True
1221
+ else:
1222
+ rel_poly = self.relative_polynomial()
1223
+ return d == len(rel_poly.base_extend(self).factor())
1224
+
1225
+ def is_galois_absolute(self):
1226
+ r"""
1227
+ Return ``True`` if for this relative extension `L/K`, `L` is a Galois extension of `\QQ`.
1228
+
1229
+ EXAMPLES::
1230
+
1231
+ sage: x = polygen(ZZ, 'x')
1232
+ sage: K.<a> = NumberField(x^3 - 2)
1233
+ sage: y = polygen(K); L.<b> = K.extension(y^2 - a)
1234
+ sage: L.is_galois_absolute() # needs sage.groups
1235
+ False
1236
+ """
1237
+ f = self.absolute_polynomial()
1238
+ return f.galois_group(pari_group=True).order() == self.absolute_degree()
1239
+
1240
+ def is_isomorphic_relative(self, other, base_isom=None):
1241
+ r"""
1242
+ For this relative extension `L/K` and another relative extension `M/K`, return ``True``
1243
+ if there is a `K`-linear isomorphism from `L` to `M`. More generally, ``other`` can be a
1244
+ relative extension `M/K^\prime` with ``base_isom`` an isomorphism from `K` to
1245
+ `K^\prime`.
1246
+
1247
+ EXAMPLES::
1248
+
1249
+ sage: x = polygen(ZZ, 'x')
1250
+ sage: K.<z9> = NumberField(x^6 + x^3 + 1)
1251
+ sage: R.<z> = PolynomialRing(K)
1252
+ sage: m1 = 3*z9^4 - 4*z9^3 - 4*z9^2 + 3*z9 - 8
1253
+ sage: L1 = K.extension(z^2 - m1, 'b1')
1254
+
1255
+ sage: # needs sage.groups
1256
+ sage: G = K.galois_group(); gamma = G.gen()
1257
+ sage: m2 = (gamma^2)(m1)
1258
+ sage: L2 = K.extension(z^2 - m2, 'b2')
1259
+ sage: L1.is_isomorphic_relative(L2)
1260
+ False
1261
+ sage: L1.is_isomorphic(L2)
1262
+ True
1263
+
1264
+ sage: L3 = K.extension(z^4 - m1, 'b3')
1265
+ sage: L1.is_isomorphic_relative(L3)
1266
+ False
1267
+
1268
+ If we have two extensions over different, but isomorphic, bases, we can compare them by
1269
+ letting ``base_isom`` be an isomorphism from ``self``'s base field to ``other``'s base field::
1270
+
1271
+ sage: Kcyc.<zeta9> = CyclotomicField(9)
1272
+ sage: Rcyc.<zcyc> = PolynomialRing(Kcyc)
1273
+ sage: phi1 = K.hom([zeta9])
1274
+ sage: m1cyc = phi1(m1)
1275
+ sage: L1cyc = Kcyc.extension(zcyc^2 - m1cyc, 'b1cyc')
1276
+ sage: L1.is_isomorphic_relative(L1cyc, base_isom=phi1)
1277
+ True
1278
+
1279
+ sage: # needs sage.groups
1280
+ sage: L2.is_isomorphic_relative(L1cyc, base_isom=phi1)
1281
+ False
1282
+ sage: phi2 = K.hom([phi1((gamma^(-2))(z9))])
1283
+ sage: L1.is_isomorphic_relative(L1cyc, base_isom=phi2)
1284
+ False
1285
+ sage: L2.is_isomorphic_relative(L1cyc, base_isom=phi2)
1286
+ True
1287
+
1288
+ Omitting ``base_isom`` raises a :exc:`ValueError` when the base fields
1289
+ are not identical::
1290
+
1291
+ sage: L1.is_isomorphic_relative(L1cyc)
1292
+ Traceback (most recent call last):
1293
+ ...
1294
+ ValueError: other does not have the same base field as self,
1295
+ so an isomorphism from self's base_field to other's base_field
1296
+ must be provided using the base_isom parameter.
1297
+
1298
+ The parameter ``base_isom`` can also be used to check if the relative extensions are
1299
+ Galois conjugate::
1300
+
1301
+ sage: for g in G: # needs sage.groups
1302
+ ....: if L1.is_isomorphic_relative(L2, g.as_hom()):
1303
+ ....: print(g.as_hom())
1304
+ Ring endomorphism of Number Field in z9 with defining polynomial x^6 + x^3 + 1
1305
+ Defn: z9 |--> z9^4
1306
+ """
1307
+ if isinstance(other, NumberField_relative):
1308
+ s_base_field = self.base_field()
1309
+ o_base_field = other.base_field()
1310
+ if base_isom is None:
1311
+ if s_base_field is o_base_field:
1312
+ return self.relative_degree() == other.relative_degree() and len(self.relative_polynomial().roots(other)) > 0
1313
+ raise ValueError("other does not have the same base field as self, so an isomorphism from self's base_field to other's base_field must be provided using the base_isom parameter.")
1314
+ if s_base_field.absolute_degree() != o_base_field.absolute_degree():
1315
+ raise ValueError("The base fields are not isomorphic.")
1316
+ if base_isom.domain() is s_base_field and base_isom.codomain() is o_base_field:
1317
+ if s_base_field.absolute_degree() != o_base_field.absolute_degree():
1318
+ raise ValueError("The base fields are not isomorphic.")
1319
+ if not self.relative_degree() == other.relative_degree():
1320
+ return False
1321
+ R = PolynomialRing(o_base_field, 'x')
1322
+ F = R([base_isom(_) for _ in self.relative_polynomial()])
1323
+ return len(F.roots(other)) > 0
1324
+ raise ValueError("base_isom is not a homomorphism from self's base_field to other's base_field")
1325
+ raise ValueError("other must be a relative number field.")
1326
+
1327
+ def is_CM_extension(self):
1328
+ """
1329
+ Return ``True`` is this is a CM extension, i.e. a totally imaginary
1330
+ quadratic extension of a totally real field.
1331
+
1332
+ EXAMPLES::
1333
+
1334
+ sage: x = polygen(ZZ, 'x')
1335
+ sage: F.<a> = NumberField(x^2 - 5)
1336
+ sage: K.<z> = F.extension(x^2 + 7)
1337
+ sage: K.is_CM_extension()
1338
+ True
1339
+ sage: K = CyclotomicField(7)
1340
+ sage: K_rel = K.relativize(K.gen() + K.gen()^(-1), 'z')
1341
+ sage: K_rel.is_CM_extension()
1342
+ True
1343
+ sage: F = CyclotomicField(3)
1344
+ sage: K.<z> = F.extension(x^3 - 2)
1345
+ sage: K.is_CM_extension()
1346
+ False
1347
+
1348
+ A CM field `K` such that `K/F` is not a CM extension
1349
+
1350
+ ::
1351
+
1352
+ sage: F.<a> = NumberField(x^2 + 1)
1353
+ sage: K.<z> = F.extension(x^2 - 3)
1354
+ sage: K.is_CM_extension()
1355
+ False
1356
+ sage: K.is_CM()
1357
+ True
1358
+ """
1359
+
1360
+ try:
1361
+ return self.__is_CM_extension
1362
+ except (AttributeError):
1363
+ pass
1364
+
1365
+ if self.relative_degree() == 2:
1366
+ if self.base_field().is_totally_real():
1367
+ if self.is_totally_imaginary():
1368
+ self.__is_CM_extension = True
1369
+ self.__is_CM = True
1370
+ self.__max_tot_real_sub = [self.base_field(), self._internal_coerce_map_from(self.base_field())]
1371
+ return True
1372
+ self.__is_CM_extension = False
1373
+ return False
1374
+
1375
+ @cached_method(key=lambda self, base, basis, map: (base or self.base_ring(), basis, map))
1376
+ def free_module(self, base=None, basis=None, map=True):
1377
+ """
1378
+ Return a vector space over a specified subfield that is isomorphic to this number field,
1379
+ together with the isomorphisms in each direction.
1380
+
1381
+ INPUT:
1382
+
1383
+ - ``base`` -- a subfield
1384
+
1385
+ - ``basis`` -- (optional) a list of elements giving a basis over the subfield
1386
+
1387
+ - ``map`` -- (default: ``True``) whether to return isomorphisms to and
1388
+ from the vector space
1389
+
1390
+ EXAMPLES::
1391
+
1392
+ sage: x = polygen(ZZ, 'x')
1393
+ sage: K.<a,b,c> = NumberField([x^2 + 2, x^3 + 2, x^3 + 3]); K
1394
+ Number Field in a with defining polynomial x^2 + 2 over its base field
1395
+ sage: V, from_V, to_V = K.free_module()
1396
+ sage: to_V(K.0)
1397
+ (0, 1)
1398
+ sage: W, from_W, to_W = K.free_module(base=QQ)
1399
+ sage: w = to_W(K.0); len(w)
1400
+ 18
1401
+ sage: w[0]
1402
+ -127917622658689792301282/48787705559800061938765
1403
+ """
1404
+ if basis is not None:
1405
+ raise NotImplementedError
1406
+ if base is None:
1407
+ base = self.base_field()
1408
+ if base is self.base_field():
1409
+ V = self.base_field()**self.relative_degree()
1410
+ if not map:
1411
+ return V
1412
+ fr = maps.MapRelativeVectorSpaceToRelativeNumberField(V, self)
1413
+ to = maps.MapRelativeNumberFieldToRelativeVectorSpace(self, V)
1414
+ elif base is QQ:
1415
+ if not map:
1416
+ return QQ**self.absolute_degree()
1417
+ K = self.absolute_field('a')
1418
+ from_K, to_K = K.structure()
1419
+ V, from_V, to_V = K.free_module()
1420
+ fr = maps.MapVectorSpaceToRelativeNumberField(V, self, from_V, from_K)
1421
+ to = maps.MapRelativeNumberFieldToVectorSpace(self, V, to_K, to_V)
1422
+ else:
1423
+ raise NotImplementedError
1424
+ return V, fr, to
1425
+
1426
+ def relative_vector_space(self, base=None, *args, **kwds):
1427
+ """
1428
+ Return vector space over the base field of ``self`` and isomorphisms
1429
+ from the vector space to ``self`` and in the other direction.
1430
+
1431
+ EXAMPLES::
1432
+
1433
+ sage: x = polygen(ZZ, 'x')
1434
+ sage: K.<a,b,c> = NumberField([x^2 + 2, x^3 + 2, x^3 + 3]); K
1435
+ Number Field in a with defining polynomial x^2 + 2 over its base field
1436
+ sage: V, from_V, to_V = K.relative_vector_space()
1437
+ sage: from_V(V.0)
1438
+ 1
1439
+ sage: to_V(K.0)
1440
+ (0, 1)
1441
+ sage: from_V(to_V(K.0))
1442
+ a
1443
+ sage: to_V(from_V(V.0))
1444
+ (1, 0)
1445
+ sage: to_V(from_V(V.1))
1446
+ (0, 1)
1447
+
1448
+ The underlying vector space and maps is cached::
1449
+
1450
+ sage: W, from_V, to_V = K.relative_vector_space()
1451
+ sage: V is W
1452
+ True
1453
+ """
1454
+ if base is not None and base is not self.base_field():
1455
+ raise ValueError("Relative vector space base must be the base field")
1456
+ return self.free_module(self.base_field(), *args, **kwds)
1457
+
1458
+ def absolute_vector_space(self, base=None, *args, **kwds):
1459
+ r"""
1460
+ Return vector space over `\QQ` of ``self`` and isomorphisms from
1461
+ the vector space to ``self`` and in the other direction.
1462
+
1463
+ EXAMPLES::
1464
+
1465
+ sage: x = polygen(ZZ, 'x')
1466
+ sage: K.<a,b> = NumberField([x^3 + 3, x^3 + 2]); K
1467
+ Number Field in a with defining polynomial x^3 + 3 over its base field
1468
+ sage: V,from_V,to_V = K.absolute_vector_space(); V
1469
+ Vector space of dimension 9 over Rational Field
1470
+ sage: from_V
1471
+ Isomorphism map:
1472
+ From: Vector space of dimension 9 over Rational Field
1473
+ To: Number Field in a with defining polynomial x^3 + 3 over its base field
1474
+ sage: to_V
1475
+ Isomorphism map:
1476
+ From: Number Field in a with defining polynomial x^3 + 3 over its base field
1477
+ To: Vector space of dimension 9 over Rational Field
1478
+ sage: c = (a+1)^5; c
1479
+ 7*a^2 - 10*a - 29
1480
+ sage: to_V(c)
1481
+ (-29, -712/9, 19712/45, 0, -14/9, 364/45, 0, -4/9, 119/45)
1482
+ sage: from_V(to_V(c))
1483
+ 7*a^2 - 10*a - 29
1484
+ sage: from_V(3*to_V(b))
1485
+ 3*b
1486
+ """
1487
+ if base is not None and base is not QQ:
1488
+ raise ValueError("Absolute vector space base must be QQ")
1489
+ return self.free_module(QQ, *args, **kwds)
1490
+
1491
+ def vector_space(self, *args, **kwds):
1492
+ r"""
1493
+ For a relative number field, :meth:`vector_space` is
1494
+ deliberately not implemented, so that a user cannot confuse
1495
+ :meth:`~relative_vector_space` with :meth:`~absolute_vector_space`.
1496
+
1497
+ EXAMPLES::
1498
+
1499
+ sage: x = polygen(ZZ, 'x')
1500
+ sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
1501
+ sage: K.vector_space()
1502
+ Traceback (most recent call last):
1503
+ ...
1504
+ NotImplementedError: For a relative number field L you must use either
1505
+ L.relative_vector_space() or L.absolute_vector_space() as appropriate
1506
+ """
1507
+ raise NotImplementedError("For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate")
1508
+
1509
+ def absolute_base_field(self):
1510
+ r"""
1511
+ Return the base field of this relative extension, but viewed
1512
+ as an absolute field over `\QQ`.
1513
+
1514
+ EXAMPLES::
1515
+
1516
+ sage: x = polygen(ZZ, 'x')
1517
+ sage: K.<a,b,c> = NumberField([x^2 + 2, x^3 + 3, x^3 + 2])
1518
+ sage: K
1519
+ Number Field in a with defining polynomial x^2 + 2 over its base field
1520
+ sage: K.base_field()
1521
+ Number Field in b with defining polynomial x^3 + 3 over its base field
1522
+ sage: K.absolute_base_field()[0]
1523
+ Number Field in a0 with defining polynomial x^9 + 3*x^6 + 165*x^3 + 1
1524
+ sage: K.base_field().absolute_field('z')
1525
+ Number Field in z with defining polynomial x^9 + 3*x^6 + 165*x^3 + 1
1526
+ """
1527
+ return self.__absolute_base_field
1528
+
1529
+ @cached_method
1530
+ def _pari_rnfeq(self):
1531
+ """
1532
+ Return PARI data attached to this relative number field.
1533
+
1534
+ OUTPUT:
1535
+
1536
+ A 5-element PARI vector containing an absolute polynomial and
1537
+ further data needed for ``eltabstorel`` and ``eltreltoabs``,
1538
+ obtained from PARI's ``nf_rnfeq`` function. This means that
1539
+ we do not have to initialize a full PARI ``rnf`` structure.
1540
+
1541
+ TESTS::
1542
+
1543
+ sage: x = polygen(ZZ, 'x')
1544
+ sage: K.<a> = NumberField(x^2 + 2)
1545
+ sage: x = polygen(K)
1546
+ sage: L.<b> = K.extension(x^5 + 2*a)
1547
+ sage: L._pari_rnfeq()
1548
+ [x^10 + 8, -1/2*x^5, 0, y^2 + 2, x^5 + 2*y]
1549
+ sage: x = polygen(ZZ)
1550
+ sage: NumberField(x^10 + 8, 'a').is_isomorphic(L)
1551
+ True
1552
+
1553
+ Initialization is lazy enough to allow arithmetic in massive fields::
1554
+
1555
+ sage: x = polygen(ZZ, 'x')
1556
+ sage: K.<a> = NumberField(x^10 + 2000*x + 100001)
1557
+ sage: x = polygen(K)
1558
+ sage: L.<b> = K.extension(x^10 + 2*a)
1559
+ sage: L._pari_rnfeq()
1560
+ [x^100 - 1024000*x^10 + 102401024, -1/2*x^10, 0, y^10 + 2000*y + 100001, x^10 + 2*y]
1561
+ sage: a + b
1562
+ b + a
1563
+ sage: b^100
1564
+ -2048000*a - 102401024
1565
+ sage: (-2*a)^10
1566
+ -2048000*a - 102401024
1567
+ """
1568
+ f = self.pari_absolute_base_polynomial()
1569
+ g = self.pari_relative_polynomial()
1570
+ return f._nf_rnfeq(g)
1571
+
1572
+ @cached_method
1573
+ def _pari_nfzk(self):
1574
+ """
1575
+ Return PARI data needed for constructing relative number field
1576
+ elements from elements of the base field.
1577
+
1578
+ TESTS::
1579
+
1580
+ sage: x = polygen(ZZ, 'x')
1581
+ sage: K.<a> = NumberField(x^2 - 2)
1582
+ sage: L.<b> = K.extension(x^2 - 3)
1583
+ sage: L._pari_nfzk()
1584
+ [2, -x^3 + 9*x]
1585
+ """
1586
+ return self._pari_base_nf()._nf_nfzk(self._pari_rnfeq())
1587
+
1588
+ @cached_method
1589
+ def _pari_relative_structure(self):
1590
+ r"""
1591
+ Return data relating the Sage and PARI relative polynomials.
1592
+
1593
+ OUTPUT:
1594
+
1595
+ Let `L` be this relative number field, let `K` be its base
1596
+ field, and let `f` be the defining polynomial of `L` over `K`.
1597
+ This method returns a triple ``(g, alpha, beta)``, where
1598
+
1599
+ - ``g`` -- the defining relative polynomial of the PARI
1600
+ ``rnf`` structure (see :meth:`pari_rnf`);
1601
+
1602
+ - ``alpha`` is the image of `x \bmod f` under some isomorphism
1603
+ `\phi\colon K[x]/(f) \to K[x]/(g)`;
1604
+
1605
+ - ``beta`` is the image of `x \bmod g` under the inverse
1606
+ isomorphism `\phi^{-1}\colon K[x]/(g) \to K[x]/(f)`.
1607
+
1608
+ EXAMPLES:
1609
+
1610
+ If the defining polynomials are monic and integral, the result
1611
+ satisfies ``g = f`` and ``alpha = beta = x``::
1612
+
1613
+ sage: R.<x> = QQ[]
1614
+ sage: K.<a> = NumberField(x^2 + 1)
1615
+ sage: L.<b> = K.extension(x^2 - a)
1616
+ sage: L._pari_relative_structure()
1617
+ (Mod(1, y^2 + 1)*x^2 + Mod(-y, y^2 + 1),
1618
+ Mod(x, Mod(1, y^2 + 1)*x^2 + Mod(-y, y^2 + 1)),
1619
+ Mod(x, Mod(1, y^2 + 1)*x^2 + Mod(-y, y^2 + 1)))
1620
+
1621
+ An example where the base field is defined by a monic integral
1622
+ polynomial, but the extension is not::
1623
+
1624
+ sage: K.<a> = NumberField(x^2 + 1)
1625
+ sage: L.<b> = K.extension(x^2 - 1/2)
1626
+ sage: L._pari_relative_structure()
1627
+ (x^2 + Mod(y, y^2 + 1),
1628
+ Mod(Mod(-1/2*y - 1/2, y^2 + 1)*x, x^2 + Mod(y, y^2 + 1)),
1629
+ Mod(Mod(y - 1, y^2 + 1)*x, x^2 + Mod(-1/2, y^2 + 1)))
1630
+
1631
+ An example where both fields are defined by non-integral or
1632
+ non-monic polynomials::
1633
+
1634
+ sage: K.<a> = NumberField(2*x^2 + 1)
1635
+ sage: L.<b> = K.extension(x^2 - 1/3)
1636
+ sage: L._pari_relative_structure()
1637
+ (x^2 + Mod(y, y^2 + 2)*x + 1,
1638
+ Mod(Mod(-1/3*y, y^2 + 2)*x + Mod(1/3, y^2 + 2), x^2 + Mod(y, y^2 + 2)*x + 1),
1639
+ Mod(Mod(3/2*y, y^2 + 2)*x + Mod(-1/2*y, y^2 + 2), Mod(1, y^2 + 2)*x^2 + Mod(-1/3, y^2 + 2)))
1640
+
1641
+ Note that in the last example, the *absolute* defining
1642
+ polynomials is the same for Sage and PARI, even though this is
1643
+ not the case for the base field::
1644
+
1645
+ sage: K._pari_absolute_structure()
1646
+ (y^2 + 2, Mod(1/2*y, y^2 + 2), Mod(2*y, y^2 + 1/2))
1647
+ sage: L._pari_absolute_structure()
1648
+ (y^4 + 4*y^2 + 1, Mod(y, y^4 + 4*y^2 + 1), Mod(y, y^4 + 4*y^2 + 1))
1649
+ """
1650
+ f = self.relative_polynomial()._pari_with_name('x')
1651
+ if f.pollead() == f.content().lift().content().denominator() == 1:
1652
+ g = f
1653
+ alpha = beta = f.variable().Mod(f)
1654
+ elif f.poldegree() == 1:
1655
+ # PARI's rnfpolredbest() does not always return a
1656
+ # polynomial with integral coefficients in this case.
1657
+ from sage.libs.pari import pari
1658
+ g = f.variable()
1659
+ alpha = -f[0]/f[1]
1660
+ beta = pari(0).Mod(f)
1661
+ else:
1662
+ g, alpha = self._pari_base_nf().rnfpolredbest(f, flag=1)
1663
+ beta = alpha.modreverse()
1664
+ return g, alpha, beta
1665
+
1666
+ @cached_method
1667
+ def _gen_relative(self):
1668
+ r"""
1669
+ Return root of defining polynomial, which is a generator of
1670
+ the relative number field over the base.
1671
+
1672
+ EXAMPLES::
1673
+
1674
+ sage: x = polygen(ZZ, 'x')
1675
+ sage: k.<a> = NumberField(x^2 + 1); k
1676
+ Number Field in a with defining polynomial x^2 + 1
1677
+ sage: y = polygen(k)
1678
+ sage: m.<b> = k.extension(y^2 + 3); m
1679
+ Number Field in b with defining polynomial x^2 + 3 over its base field
1680
+ sage: c = m.gen(); c # indirect doctest
1681
+ b
1682
+ sage: c^2 + 3
1683
+ 0
1684
+
1685
+ An example where the defining polynomials are not monic or
1686
+ integral::
1687
+
1688
+ sage: K.<a> = NumberField(3*x^2 + 1)
1689
+ sage: L.<b> = K.extension(x^2 - 1/2)
1690
+ sage: L._gen_relative()
1691
+ b
1692
+ """
1693
+ alpha = self._pari_relative_structure()[1].liftpol()
1694
+ return self._element_constructor_(self._pari_rnfeq()._eltreltoabs(alpha), check=False)
1695
+
1696
+ @cached_method
1697
+ def pari_rnf(self):
1698
+ r"""
1699
+ Return the PARI relative number field object associated
1700
+ to this relative extension.
1701
+
1702
+ EXAMPLES::
1703
+
1704
+ sage: x = polygen(ZZ, 'x')
1705
+ sage: k.<a> = NumberField([x^4 + 3, x^2 + 2])
1706
+ sage: k.pari_rnf()
1707
+ [x^4 + 3, [364, -10*x^7 - 87*x^5 - 370*x^3 - 41*x], [108, 3], ...]
1708
+ """
1709
+ return self._pari_base_nf().rnfinit(self.pari_relative_polynomial())
1710
+
1711
+ def pari_absolute_base_polynomial(self):
1712
+ r"""
1713
+ Return the PARI polynomial defining the absolute base field, in ``y``.
1714
+
1715
+ EXAMPLES::
1716
+
1717
+ sage: x = polygen(ZZ)
1718
+ sage: x = polygen(ZZ, 'x')
1719
+ sage: K.<a, b> = NumberField([x^2 + 2, x^2 + 3]); K
1720
+ Number Field in a with defining polynomial x^2 + 2 over its base field
1721
+ sage: K.pari_absolute_base_polynomial()
1722
+ y^2 + 3
1723
+ sage: type(K.pari_absolute_base_polynomial())
1724
+ <class 'cypari2.gen.Gen'>
1725
+ sage: z = ZZ['z'].0
1726
+ sage: K.<a, b, c> = NumberField([z^2 + 2, z^2 + 3, z^2 + 5]); K
1727
+ Number Field in a with defining polynomial z^2 + 2 over its base field
1728
+ sage: K.pari_absolute_base_polynomial()
1729
+ y^4 + 16*y^2 + 4
1730
+ sage: K.base_field()
1731
+ Number Field in b with defining polynomial z^2 + 3 over its base field
1732
+ sage: len(QQ['y'](K.pari_absolute_base_polynomial()).roots(K.base_field()))
1733
+ 4
1734
+ sage: type(K.pari_absolute_base_polynomial())
1735
+ <class 'cypari2.gen.Gen'>
1736
+ """
1737
+ abs_base, from_abs_base, to_abs_base = self.absolute_base_field()
1738
+ return abs_base.pari_polynomial('y')
1739
+
1740
+ def pari_relative_polynomial(self):
1741
+ r"""
1742
+ Return the PARI relative polynomial associated to this number
1743
+ field.
1744
+
1745
+ This is always a polynomial in `x` and `y`, suitable for PARI's
1746
+ :pari:`rnfinit` function. Notice that if this is a relative extension
1747
+ of a relative extension, the base field is the absolute base
1748
+ field.
1749
+
1750
+ EXAMPLES::
1751
+
1752
+ sage: x = polygen(ZZ, 'x')
1753
+ sage: k.<i> = NumberField(x^2 + 1)
1754
+ sage: m.<z> = k.extension(k['w']([i,0,1]))
1755
+ sage: m
1756
+ Number Field in z with defining polynomial w^2 + i over its base field
1757
+ sage: m.pari_relative_polynomial()
1758
+ Mod(1, y^2 + 1)*x^2 + Mod(y, y^2 + 1)
1759
+
1760
+ sage: l.<t> = m.extension(m['t'].0^2 + z)
1761
+ sage: l.pari_relative_polynomial()
1762
+ Mod(1, y^4 + 1)*x^2 + Mod(y, y^4 + 1)
1763
+ """
1764
+ return self._pari_relative_structure()[0]
1765
+
1766
+ def number_of_roots_of_unity(self):
1767
+ r"""
1768
+ Return the number of roots of unity in this relative field.
1769
+
1770
+ EXAMPLES::
1771
+
1772
+ sage: x = polygen(ZZ, 'x')
1773
+ sage: K.<a, b> = NumberField([x^2 + x + 1, x^4 + 1])
1774
+ sage: K.number_of_roots_of_unity()
1775
+ 24
1776
+ """
1777
+ return self.absolute_field('a').number_of_roots_of_unity()
1778
+
1779
+ def roots_of_unity(self):
1780
+ r"""
1781
+ Return all the roots of unity in this relative field, primitive or not.
1782
+
1783
+ EXAMPLES::
1784
+
1785
+ sage: x = polygen(ZZ, 'x')
1786
+ sage: K.<a, b> = NumberField([x^2 + x + 1, x^4 + 1])
1787
+ sage: rts = K.roots_of_unity()
1788
+ sage: len(rts)
1789
+ 24
1790
+ sage: all(u in rts for u in [b*a, -b^2*a - b^2, b^3, -a, b*a + b])
1791
+ True
1792
+ """
1793
+ abs = self.absolute_field('a')
1794
+ from_abs, _ = abs.structure()
1795
+ return [from_abs(x) for x in abs.roots_of_unity()]
1796
+
1797
+ def absolute_generator(self):
1798
+ r"""
1799
+ Return the chosen generator over `\QQ` for this relative number field.
1800
+
1801
+ EXAMPLES::
1802
+
1803
+ sage: y = polygen(QQ,'y')
1804
+ sage: k.<a> = NumberField([y^2 + 2, y^4 + 3])
1805
+ sage: g = k.absolute_generator(); g
1806
+ a0 - a1
1807
+ sage: g.minpoly()
1808
+ x^2 + 2*a1*x + a1^2 + 2
1809
+ sage: g.absolute_minpoly()
1810
+ x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49
1811
+ """
1812
+ try:
1813
+ return self.__abs_gen
1814
+ except AttributeError:
1815
+ self.__abs_gen = self._element_class(self, QQ['x'].gen())
1816
+ return self.__abs_gen
1817
+
1818
+ def absolute_field(self, names):
1819
+ """
1820
+ Return ``self`` as an absolute number field.
1821
+
1822
+ INPUT:
1823
+
1824
+ - ``names`` -- string; name of generator of the absolute field
1825
+
1826
+ OUTPUT: an absolute number field `K` that is isomorphic to this field
1827
+
1828
+ Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where
1829
+ ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K``
1830
+ is an isomorphism from ``self`` to `K`.
1831
+
1832
+ EXAMPLES::
1833
+
1834
+ sage: x = polygen(ZZ, 'x')
1835
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
1836
+ Number Field in a with defining polynomial x^4 + 3 over its base field
1837
+ sage: L.<xyz> = K.absolute_field(); L
1838
+ Number Field in xyz with defining polynomial x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49
1839
+ sage: L.<c> = K.absolute_field(); L
1840
+ Number Field in c with defining polynomial x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49
1841
+
1842
+ sage: from_L, to_L = L.structure()
1843
+ sage: from_L
1844
+ Isomorphism map:
1845
+ From: Number Field in c with defining polynomial
1846
+ x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49
1847
+ To: Number Field in a with defining polynomial x^4 + 3 over its base field
1848
+ sage: from_L(c)
1849
+ a - b
1850
+ sage: to_L
1851
+ Isomorphism map:
1852
+ From: Number Field in a with defining polynomial x^4 + 3 over its base field
1853
+ To: Number Field in c with defining polynomial
1854
+ x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49
1855
+ sage: to_L(a)
1856
+ -5/182*c^7 - 87/364*c^5 - 185/182*c^3 + 323/364*c
1857
+ sage: to_L(b)
1858
+ -5/182*c^7 - 87/364*c^5 - 185/182*c^3 - 41/364*c
1859
+ sage: to_L(a)^4
1860
+ -3
1861
+ sage: to_L(b)^2
1862
+ -2
1863
+ """
1864
+ return NumberField(self.absolute_polynomial(), names, structure=structure.AbsoluteFromRelative(self))
1865
+
1866
+ def absolute_polynomial_ntl(self):
1867
+ """
1868
+ Return defining polynomial of this number field
1869
+ as a pair, an ntl polynomial and a denominator.
1870
+
1871
+ This is used mainly to implement some internal arithmetic.
1872
+
1873
+ EXAMPLES::
1874
+
1875
+ sage: x = polygen(ZZ, 'x')
1876
+ sage: NumberField(x^2 + (2/3)*x - 9/17,'a').absolute_polynomial_ntl()
1877
+ ([-27 34 51], 51)
1878
+ """
1879
+ try:
1880
+ return (self.__abs_polynomial_ntl, self.__abs_denominator_ntl)
1881
+ except AttributeError:
1882
+ import sage.libs.ntl.all as ntl
1883
+ self.__abs_denominator_ntl = ntl.ZZ()
1884
+ den = self.absolute_polynomial().denominator()
1885
+ self.__abs_denominator_ntl.set_from_sage_int(ZZ(den))
1886
+ self.__abs_polynomial_ntl = ntl.ZZX((self.absolute_polynomial()*den).list())
1887
+ return (self.__abs_polynomial_ntl, self.__abs_denominator_ntl)
1888
+
1889
+ @cached_method
1890
+ def absolute_polynomial(self):
1891
+ r"""
1892
+ Return the polynomial over `\QQ` that defines this field as an
1893
+ extension of the rational numbers.
1894
+
1895
+ .. NOTE::
1896
+
1897
+ The absolute polynomial of a relative number field is
1898
+ chosen to be equal to the defining polynomial of the
1899
+ underlying PARI absolute number field (it cannot be
1900
+ specified by the user). In particular, it is always a
1901
+ monic polynomial with integral coefficients. On the other
1902
+ hand, the defining polynomial of an absolute number field
1903
+ and the relative polynomial of a relative number field are
1904
+ in general different from their PARI counterparts.
1905
+
1906
+ EXAMPLES::
1907
+
1908
+ sage: x = polygen(ZZ, 'x')
1909
+ sage: k.<a, b> = NumberField([x^2 + 1, x^3 + x + 1]); k
1910
+ Number Field in a with defining polynomial x^2 + 1 over its base field
1911
+ sage: k.absolute_polynomial()
1912
+ x^6 + 5*x^4 - 2*x^3 + 4*x^2 + 4*x + 1
1913
+
1914
+ An example comparing the various defining polynomials to their
1915
+ PARI counterparts::
1916
+
1917
+ sage: x = polygen(ZZ, 'x')
1918
+ sage: k.<a, c> = NumberField([x^2 + 1/3, x^2 + 1/4])
1919
+ sage: k.absolute_polynomial()
1920
+ x^4 - x^2 + 1
1921
+ sage: k.pari_polynomial()
1922
+ x^4 - x^2 + 1
1923
+ sage: k.base_field().absolute_polynomial()
1924
+ x^2 + 1/4
1925
+ sage: k.pari_absolute_base_polynomial()
1926
+ y^2 + 1
1927
+ sage: k.relative_polynomial()
1928
+ x^2 + 1/3
1929
+ sage: k.pari_relative_polynomial()
1930
+ x^2 + Mod(-y, y^2 + 1)*x - 1
1931
+ """
1932
+ return QQ['x'](self._pari_rnfeq()[0])
1933
+
1934
+ def relative_polynomial(self):
1935
+ """
1936
+ Return the defining polynomial of this relative number field over its base field.
1937
+
1938
+ EXAMPLES::
1939
+
1940
+ sage: x = polygen(ZZ, 'x')
1941
+ sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
1942
+ sage: K.relative_polynomial()
1943
+ x^2 + x + 1
1944
+
1945
+ Use :meth:`absolute_polynomial` for a polynomial that defines the absolute
1946
+ extension.::
1947
+
1948
+ sage: K.absolute_polynomial()
1949
+ x^6 + 3*x^5 + 8*x^4 + 9*x^3 + 7*x^2 + 6*x + 3
1950
+ """
1951
+ return self.__relative_polynomial
1952
+
1953
+ def defining_polynomial(self):
1954
+ """
1955
+ Return the defining polynomial of this relative number field.
1956
+
1957
+ This is exactly the same as :meth:`relative_polynomial`.
1958
+
1959
+ EXAMPLES::
1960
+
1961
+ sage: C.<z> = CyclotomicField(5)
1962
+ sage: PC.<X> = C[]
1963
+ sage: K.<a> = C.extension(X^2 + X + z); K
1964
+ Number Field in a with defining polynomial X^2 + X + z over its base field
1965
+ sage: K.defining_polynomial()
1966
+ X^2 + X + z
1967
+ """
1968
+ return self.relative_polynomial()
1969
+
1970
+ def polynomial(self):
1971
+ """
1972
+ For a relative number field, :meth:`polynomial` is deliberately
1973
+ not implemented. Either :meth:`~relative_polynomial` or
1974
+ :meth:`~absolute_polynomial` must be used.
1975
+
1976
+ EXAMPLES::
1977
+
1978
+ sage: x = polygen(ZZ, 'x')
1979
+ sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
1980
+ sage: K.polynomial()
1981
+ Traceback (most recent call last):
1982
+ ...
1983
+ NotImplementedError: For a relative number field L you must use either
1984
+ L.relative_polynomial() or L.absolute_polynomial() as appropriate
1985
+ """
1986
+ raise NotImplementedError("For a relative number field L you must use either L.relative_polynomial() or L.absolute_polynomial() as appropriate")
1987
+
1988
+ def base_field(self):
1989
+ """
1990
+ Return the base field of this relative number field.
1991
+
1992
+ EXAMPLES::
1993
+
1994
+ sage: x = polygen(ZZ, 'x')
1995
+ sage: k.<a> = NumberField([x^3 + x + 1])
1996
+ sage: R.<z> = k[]
1997
+ sage: L.<b> = NumberField(z^3 + a)
1998
+ sage: L.base_field()
1999
+ Number Field in a with defining polynomial x^3 + x + 1
2000
+ sage: L.base_field() is k
2001
+ True
2002
+
2003
+ This is very useful because the print representation of
2004
+ a relative field doesn't describe the base field.::
2005
+
2006
+ sage: L
2007
+ Number Field in b with defining polynomial z^3 + a over its base field
2008
+ """
2009
+ return self.__base_field
2010
+
2011
+ def base_ring(self):
2012
+ """
2013
+ This is exactly the same as base_field.
2014
+
2015
+ EXAMPLES::
2016
+
2017
+ sage: x = polygen(ZZ, 'x')
2018
+ sage: k.<a> = NumberField([x^2 + 1, x^3 + x + 1])
2019
+ sage: k.base_ring()
2020
+ Number Field in a1 with defining polynomial x^3 + x + 1
2021
+ sage: k.base_field()
2022
+ Number Field in a1 with defining polynomial x^3 + x + 1
2023
+ """
2024
+ return self.base_field()
2025
+
2026
+ def embeddings(self, K):
2027
+ r"""
2028
+ Compute all field embeddings of the relative number field self
2029
+ into the field `K` (which need not even be a number field,
2030
+ e.g., it could be the complex numbers). This will return an
2031
+ identical result when given `K` as input again.
2032
+
2033
+ If possible, the most natural embedding of ``self`` into `K`
2034
+ is put first in the list.
2035
+
2036
+ INPUT:
2037
+
2038
+ - ``K`` -- a field
2039
+
2040
+ EXAMPLES::
2041
+
2042
+ sage: x = polygen(ZZ, 'x')
2043
+ sage: K.<a,b> = NumberField([x^3 - 2, x^2 + 1])
2044
+ sage: f = K.embeddings(ComplexField(58)); f
2045
+ [Relative number field morphism:
2046
+ From: Number Field in a with defining polynomial x^3 - 2 over its base field
2047
+ To: Complex Field with 58 bits of precision
2048
+ Defn: a |--> -0.62996052494743676 - 1.0911236359717214*I
2049
+ b |--> -1.9428902930940239e-16 + 1.0000000000000000*I,
2050
+ ...
2051
+ Relative number field morphism:
2052
+ From: Number Field in a with defining polynomial x^3 - 2 over its base field
2053
+ To: Complex Field with 58 bits of precision
2054
+ Defn: a |--> 1.2599210498948731
2055
+ b |--> -0.99999999999999999*I]
2056
+ sage: f[0](a)^3
2057
+ 2.0000000000000002 - 8.6389229103644993e-16*I
2058
+ sage: f[0](b)^2
2059
+ -1.0000000000000001 - 3.8857805861880480e-16*I
2060
+ sage: f[0](a+b)
2061
+ -0.62996052494743693 - 0.091123635971721295*I
2062
+ """
2063
+ if K.characteristic():
2064
+ return Sequence([], immutable=True, check=False, universe=self.Hom(K))
2065
+
2066
+ try:
2067
+ # this should be concordant with automorphisms
2068
+ return self.__embeddings[K]
2069
+ except AttributeError:
2070
+ self.__embeddings = {}
2071
+ except KeyError:
2072
+ pass
2073
+ L = self.absolute_field('a')
2074
+ E = L.embeddings(K)
2075
+ v = [self.hom(f, K) for f in E]
2076
+
2077
+ # If there is an embedding that preserves variable names
2078
+ # then it is most natural, so we put it first.
2079
+ put_natural_embedding_first(v)
2080
+
2081
+ self.__embeddings[K] = Sequence(v, cr=bool(v), immutable=True, check=False, universe=self.Hom(K))
2082
+ return self.__embeddings[K]
2083
+
2084
+ def automorphisms(self):
2085
+ r"""
2086
+ Compute all Galois automorphisms of ``self`` over the base field. This is
2087
+ different from computing the embeddings of ``self`` into ``self``; there,
2088
+ automorphisms that do not fix the base field are considered.
2089
+
2090
+ EXAMPLES::
2091
+
2092
+ sage: x = polygen(ZZ, 'x')
2093
+ sage: K.<a, b> = NumberField([x^2 + 10000, x^2 + x + 50]); K
2094
+ Number Field in a with defining polynomial x^2 + 10000 over its base field
2095
+ sage: K.automorphisms()
2096
+ [Relative number field endomorphism of Number Field in a with defining polynomial x^2 + 10000 over its base field
2097
+ Defn: a |--> a
2098
+ b |--> b,
2099
+ Relative number field endomorphism of Number Field in a with defining polynomial x^2 + 10000 over its base field
2100
+ Defn: a |--> -a
2101
+ b |--> b]
2102
+ sage: rho, tau = K.automorphisms()
2103
+ sage: tau(a)
2104
+ -a
2105
+ sage: tau(b) == b
2106
+ True
2107
+
2108
+ sage: L.<b, a> = NumberField([x^2 + x + 50, x^2 + 10000, ]); L
2109
+ Number Field in b with defining polynomial x^2 + x + 50 over its base field
2110
+ sage: L.automorphisms()
2111
+ [Relative number field endomorphism of Number Field in b with defining polynomial x^2 + x + 50 over its base field
2112
+ Defn: b |--> b
2113
+ a |--> a,
2114
+ Relative number field endomorphism of Number Field in b with defining polynomial x^2 + x + 50 over its base field
2115
+ Defn: b |--> -b - 1
2116
+ a |--> a]
2117
+ sage: rho, tau = L.automorphisms()
2118
+ sage: tau(a) == a
2119
+ True
2120
+ sage: tau(b)
2121
+ -b - 1
2122
+
2123
+ sage: PQ.<X> = QQ[]
2124
+ sage: F.<a, b> = NumberField([X^2 - 2, X^2 - 3])
2125
+ sage: PF.<Y> = F[]
2126
+ sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
2127
+ sage: K.automorphisms()
2128
+ [Relative number field endomorphism of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
2129
+ Defn: c |--> c
2130
+ a |--> a
2131
+ b |--> b,
2132
+ Relative number field endomorphism of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field
2133
+ Defn: c |--> -c
2134
+ a |--> a
2135
+ b |--> b]
2136
+ """
2137
+ try:
2138
+ return self.__automorphisms
2139
+ except AttributeError:
2140
+ pass
2141
+
2142
+ L = self.absolute_field('a')
2143
+ L_into_self, self_into_L = L.structure()
2144
+ aas = L.automorphisms() # absolute automorphisms
2145
+
2146
+ a = self_into_L(self.gen())
2147
+ abs_base_gens = [self_into_L(_) for _ in self.base_field().gens()]
2148
+ v = sorted([self.hom([L_into_self(aa(a))]) for aa in aas
2149
+ if all(aa(g) == g for g in abs_base_gens)])
2150
+ put_natural_embedding_first(v)
2151
+ self.__automorphisms = Sequence(v, cr=bool(v), immutable=True,
2152
+ check=False, universe=self.Hom(self))
2153
+ return self.__automorphisms
2154
+
2155
+ def logarithmic_embedding(self, prec=53):
2156
+ r"""
2157
+ Return the morphism of ``self`` under the logarithmic embedding
2158
+ in the category Set.
2159
+
2160
+ The logarithmic embedding is defined as a map from the relative number field ``self`` to `\RR^n`.
2161
+
2162
+ It is defined under Definition 4.9.6 in [Coh1993]_.
2163
+
2164
+ INPUT:
2165
+
2166
+ - ``prec`` -- desired floating point precision
2167
+
2168
+ OUTPUT: the morphism of ``self`` under the logarithmic embedding in the category Set
2169
+
2170
+ EXAMPLES::
2171
+
2172
+ sage: K.<k> = CyclotomicField(3)
2173
+ sage: R.<x> = K[]
2174
+ sage: L.<l> = K.extension(x^5 + 5)
2175
+ sage: f = L.logarithmic_embedding()
2176
+ sage: f(0)
2177
+ (-1, -1, -1, -1, -1)
2178
+ sage: f(5)
2179
+ (3.21887582486820, 3.21887582486820, 3.21887582486820,
2180
+ 3.21887582486820, 3.21887582486820)
2181
+
2182
+ ::
2183
+
2184
+ sage: K.<i> = NumberField(x^2 + 1)
2185
+ sage: t = K['t'].gen()
2186
+ sage: L.<a> = K.extension(t^4 - i)
2187
+ sage: f = L.logarithmic_embedding()
2188
+ sage: f(0)
2189
+ (-1, -1, -1, -1, -1, -1, -1, -1)
2190
+ sage: f(3)
2191
+ (2.19722457733622, 2.19722457733622, 2.19722457733622, 2.19722457733622,
2192
+ 2.19722457733622, 2.19722457733622, 2.19722457733622, 2.19722457733622)
2193
+ """
2194
+ def closure_map(x, prec=53):
2195
+ """
2196
+ The function closure of the logarithmic embedding.
2197
+ """
2198
+ K = self
2199
+ K_embeddings = K.places(prec)
2200
+ r1, r2 = K.signature()
2201
+ r = r1 + r2 - 1
2202
+
2203
+ from sage.rings.real_mpfr import RealField
2204
+ Reals = RealField(prec)
2205
+
2206
+ if x == 0:
2207
+ return vector([-1 for _ in range(r + 1)])
2208
+
2209
+ x_logs = []
2210
+ for i in range(r1):
2211
+ sigma = K_embeddings[i]
2212
+ x_logs.append(Reals(abs(sigma(x))).log())
2213
+ for i in range(r1, r + 1):
2214
+ tau = K_embeddings[i]
2215
+ x_logs.append(2 * Reals(abs(tau(x))).log())
2216
+
2217
+ return vector(x_logs)
2218
+
2219
+ hom = Hom(self, VectorSpace(RR, len(closure_map(self(0), prec))), Sets())
2220
+ return hom(closure_map)
2221
+
2222
+ def places(self, all_complex=False, prec=None):
2223
+ """
2224
+ Return the collection of all infinite places of ``self``.
2225
+
2226
+ By default, this returns the set of real places as
2227
+ homomorphisms into ``RIF`` first, followed by a choice of one of
2228
+ each pair of complex conjugate homomorphisms into ``CIF``.
2229
+
2230
+ On the other hand, if ``prec`` is not ``None``, we simply return places
2231
+ into ``RealField(prec)`` and ``ComplexField(prec)`` (or ``RDF``, ``CDF`` if
2232
+ ``prec=53``).
2233
+
2234
+ There is an optional flag ``all_complex``, which defaults to ``False``. If
2235
+ ``all_complex`` is ``True``, then the real embeddings are returned as
2236
+ embeddings into ``CIF`` instead of ``RIF``.
2237
+
2238
+ EXAMPLES::
2239
+
2240
+ sage: x = polygen(ZZ, 'x')
2241
+ sage: L.<b, c> = NumberFieldTower([x^2 - 5, x^3 + x + 3])
2242
+ sage: L.places() # needs sage.libs.linbox
2243
+ [Relative number field morphism:
2244
+ From: Number Field in b with defining polynomial x^2 - 5 over its base field
2245
+ To: Real Field with 106 bits of precision
2246
+ Defn: b |--> -2.236067977499789696409173668937
2247
+ c |--> -1.213411662762229634132131377426,
2248
+ Relative number field morphism:
2249
+ From: Number Field in b with defining polynomial x^2 - 5 over its base field
2250
+ To: Real Field with 106 bits of precision
2251
+ Defn: b |--> 2.236067977499789696411548005367
2252
+ c |--> -1.213411662762229634130492421800,
2253
+ Relative number field morphism:
2254
+ From: Number Field in b with defining polynomial x^2 - 5 over its base field
2255
+ To: Complex Field with 53 bits of precision
2256
+ Defn: b |--> -2.23606797749979 ...e-1...*I
2257
+ c |--> 0.606705831381... - 1.45061224918844*I,
2258
+ Relative number field morphism:
2259
+ From: Number Field in b with defining polynomial x^2 - 5 over its base field
2260
+ To: Complex Field with 53 bits of precision
2261
+ Defn: b |--> 2.23606797749979 - 4.44089209850063e-16*I
2262
+ c |--> 0.606705831381115 - 1.45061224918844*I]
2263
+ """
2264
+ L = self.absolute_field('a')
2265
+ pl = L.places(all_complex, prec)
2266
+ return [self.hom(p, p.codomain()) for p in pl]
2267
+
2268
+ def absolute_different(self):
2269
+ r"""
2270
+ Return the absolute different of this relative number field `L`, as an
2271
+ ideal of `L`. To get the relative different of `L/K`, use
2272
+ :meth:`relative_different`.
2273
+
2274
+ EXAMPLES::
2275
+
2276
+ sage: x = polygen(ZZ, 'x')
2277
+ sage: K.<i> = NumberField(x^2 + 1)
2278
+ sage: t = K['t'].gen()
2279
+ sage: L.<b> = K.extension(t^4 - i)
2280
+ sage: L.absolute_different()
2281
+ Fractional ideal (8)
2282
+ """
2283
+ abs = self.absolute_field('a')
2284
+ from_abs = abs.structure()[0]
2285
+ return self.ideal([from_abs(g) for g in abs.different().gens()])
2286
+
2287
+ def relative_different(self):
2288
+ r"""
2289
+ Return the relative different of this extension `L/K` as
2290
+ an ideal of `L`. If you want the absolute different of
2291
+ `L/\QQ`, use :meth:`absolute_different`.
2292
+
2293
+ EXAMPLES::
2294
+
2295
+ sage: x = polygen(ZZ, 'x')
2296
+ sage: K.<i> = NumberField(x^2 + 1)
2297
+ sage: PK.<t> = K[]
2298
+ sage: L.<a> = K.extension(t^4 - i)
2299
+ sage: L.relative_different()
2300
+ Fractional ideal (4)
2301
+ """
2302
+ I = self.absolute_different()
2303
+ J = self.ideal(self.base_field().absolute_different().gens())
2304
+ return I/J
2305
+
2306
+ def different(self):
2307
+ """
2308
+ The different, unqualified, of a relative number field is deliberately
2309
+ not implemented, so that a user cannot mistake the absolute different
2310
+ for the relative different, or vice versa.
2311
+
2312
+ EXAMPLES::
2313
+
2314
+ sage: x = polygen(ZZ, 'x')
2315
+ sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
2316
+ sage: K.different()
2317
+ Traceback (most recent call last):
2318
+ ...
2319
+ NotImplementedError: For a relative number field you must use
2320
+ relative_different or absolute_different as appropriate
2321
+ """
2322
+ raise NotImplementedError("For a relative number field you must use relative_different or absolute_different as appropriate")
2323
+
2324
+ def absolute_discriminant(self, v=None):
2325
+ r"""
2326
+ Return the absolute discriminant of this relative number field
2327
+ or if ``v`` is specified, the determinant of the trace pairing
2328
+ on the elements of the list ``v``.
2329
+
2330
+ INPUT:
2331
+
2332
+ - ``v`` -- (optional) list of element of this relative number field
2333
+
2334
+ OUTPUT: integer if ``v`` is omitted, and Rational otherwise
2335
+
2336
+ EXAMPLES::
2337
+
2338
+ sage: x = polygen(ZZ, 'x')
2339
+ sage: K.<i> = NumberField(x^2 + 1)
2340
+ sage: t = K['t'].gen()
2341
+ sage: L.<b> = K.extension(t^4 - i)
2342
+ sage: L.absolute_discriminant()
2343
+ 16777216
2344
+ sage: L.absolute_discriminant([(b + i)^j for j in range(8)])
2345
+ 61911970349056
2346
+ """
2347
+ abs = self.absolute_field('a')
2348
+ if v is not None:
2349
+ to_abs = abs.structure()[1]
2350
+ v = [to_abs(x) for x in v]
2351
+ return abs.discriminant(v=v)
2352
+
2353
+ def relative_discriminant(self):
2354
+ r"""
2355
+ Return the relative discriminant of this extension `L/K` as an ideal of
2356
+ `K`. If you want the (rational) discriminant of `L/\QQ`, use e.g.
2357
+ ``L.absolute_discriminant()``.
2358
+
2359
+ EXAMPLES::
2360
+
2361
+ sage: x = polygen(ZZ, 'x')
2362
+ sage: K.<i> = NumberField(x^2 + 1)
2363
+ sage: t = K['t'].gen()
2364
+ sage: L.<b> = K.extension(t^4 - i)
2365
+ sage: L.relative_discriminant()
2366
+ Fractional ideal (256)
2367
+ sage: PQ.<X> = QQ[]
2368
+ sage: F.<a, b> = NumberField([X^2 - 2, X^2 - 3])
2369
+ sage: PF.<Y> = F[]
2370
+ sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
2371
+ sage: K.relative_discriminant() == F.ideal(4*b)
2372
+ True
2373
+
2374
+ TESTS:
2375
+
2376
+ Number fields defined by non-monic and non-integral
2377
+ polynomials are supported (:issue:`252`)::
2378
+
2379
+ sage: K.<a> = NumberField(x^2 + 1/2)
2380
+ sage: L.<b> = K.extension(x^2 - 1/2)
2381
+ sage: L.relative_discriminant()
2382
+ Fractional ideal (2)
2383
+ """
2384
+ base = self.base_field()
2385
+ nf = base.pari_nf()
2386
+ D, d = nf.rnfdisc(self.pari_relative_polynomial())
2387
+ return base.ideal(nf.idealhnf(D))
2388
+
2389
+ def discriminant(self):
2390
+ """
2391
+ The discriminant, unqualified, of a relative number field is deliberately
2392
+ not implemented, so that a user cannot mistake the absolute discriminant
2393
+ for the relative discriminant, or vice versa.
2394
+
2395
+ EXAMPLES::
2396
+
2397
+ sage: x = polygen(ZZ, 'x')
2398
+ sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
2399
+ sage: K.discriminant()
2400
+ Traceback (most recent call last):
2401
+ ...
2402
+ NotImplementedError: For a relative number field you must use
2403
+ relative_discriminant or absolute_discriminant as appropriate
2404
+ """
2405
+ raise NotImplementedError("For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate")
2406
+
2407
+ def disc(self):
2408
+ """
2409
+ The discriminant, unqualified, of a relative number field is deliberately
2410
+ not implemented, so that a user cannot mistake the absolute discriminant
2411
+ for the relative discriminant, or vice versa.
2412
+
2413
+ EXAMPLES::
2414
+
2415
+ sage: x = polygen(ZZ, 'x')
2416
+ sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
2417
+ sage: K.disc()
2418
+ Traceback (most recent call last):
2419
+ ...
2420
+ NotImplementedError: For a relative number field you must use
2421
+ relative_discriminant or absolute_discriminant as appropriate
2422
+ """
2423
+ raise NotImplementedError("For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate")
2424
+
2425
+ def order(self, *gens, **kwds):
2426
+ r"""
2427
+ Return the order with given ring generators in the maximal
2428
+ order of this number field.
2429
+
2430
+ INPUT:
2431
+
2432
+ - ``gens`` -- list of elements of ``self``; if no generators are given, just
2433
+ returns the cardinality of this number field (`\infty`) for consistency.
2434
+ - ``check_is_integral`` -- boolean (default: ``True``); whether to
2435
+ check that each generator is integral
2436
+ - ``check_rank`` -- boolean (default: ``True``); whether to check that
2437
+ the ring generated by ``gens`` is of full rank
2438
+ - ``allow_subfield`` -- boolean (default: ``False``); if ``True`` and
2439
+ the generators do not generate an order, i.e., they generate a
2440
+ subring of smaller rank, instead of raising an error, return an order
2441
+ in a smaller number field.
2442
+
2443
+ The ``check_is_integral`` and ``check_rank`` inputs must be given as
2444
+ explicit keyword arguments.
2445
+
2446
+ EXAMPLES::
2447
+
2448
+ sage: # needs fpylll sage.symbolic
2449
+ sage: P3.<a,b,c> = QQ[2^(1/2), 2^(1/3), 3^(1/2)]
2450
+ sage: R = P3.order([a,b,c]); R # not tested (83s, 2GB memory)
2451
+ Relative Order generated by
2452
+ [((-36372*sqrt3 + 371270)*a^2 + (-89082*sqrt3 + 384161)*a - 422504*sqrt3 - 46595)*sqrt2 + (303148*sqrt3 - 89080)*a^2 + (313664*sqrt3 - 218211)*a - 38053*sqrt3 - 1034933,
2453
+ ((-65954*sqrt3 + 323491)*a^2 + (-110591*sqrt3 + 350011)*a - 351557*sqrt3 + 77507)*sqrt2 + (264138*sqrt3 - 161552)*a^2 + (285784*sqrt3 - 270906)*a + 63287*sqrt3 - 861151,
2454
+ ((-89292*sqrt3 + 406648)*a^2 + (-137274*sqrt3 + 457033)*a - 449503*sqrt3 + 102712)*sqrt2 + (332036*sqrt3 - 218718)*a^2 + (373172*sqrt3 - 336261)*a + 83862*sqrt3 - 1101079,
2455
+ ((-164204*sqrt3 + 553344)*a^2 + (-225111*sqrt3 + 646064)*a - 594724*sqrt3 + 280879)*sqrt2 + (451819*sqrt3 - 402227)*a^2 + (527524*sqrt3 - 551431)*a + 229346*sqrt3 - 1456815,
2456
+ ((-73815*sqrt3 + 257278)*a^2 + (-102896*sqrt3 + 298046)*a - 277080*sqrt3 + 123726)*sqrt2 + (210072*sqrt3 - 180812)*a^2 + (243357*sqrt3 - 252052)*a + 101026*sqrt3 - 678718]
2457
+ in Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
2458
+
2459
+ sage: P2.<u,v> = QQ[2^(1/2), 2^(1/3)] # needs fpylll sage.symbolic
2460
+ sage: R = P2.order([u,v]); R # needs fpylll sage.symbolic
2461
+ Relative Order generated by [(6*a^2 - a - 1)*sqrt2 + 4*a^2 - 6*a - 9, sqrt2 - a]
2462
+ in Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
2463
+
2464
+ The base ring of an order in a relative extension is still `\ZZ`::
2465
+
2466
+ sage: R.base_ring() # needs fpylll sage.symbolic
2467
+ Integer Ring
2468
+
2469
+ One must give enough generators to generate a ring of finite index
2470
+ in the maximal order::
2471
+
2472
+ sage: P3.order([a, b]) # needs fpylll sage.symbolic
2473
+ Traceback (most recent call last):
2474
+ ...
2475
+ ValueError: the rank of the span of gens is wrong
2476
+ """
2477
+ if len(gens) == 0:
2478
+ return NumberField_generic.order(self)
2479
+ if len(gens) == 1 and isinstance(gens[0], (list, tuple)):
2480
+ gens = gens[0]
2481
+ gens = [self(x) for x in gens]
2482
+ return relative_order_from_ring_generators(gens, **kwds)
2483
+
2484
+ def is_free(self, proof=None):
2485
+ r"""
2486
+ Determine whether or not `L/K` is free.
2487
+
2488
+ (i.e. if `\mathcal{O}_L` is a free `\mathcal{O}_K`-module).
2489
+
2490
+ INPUT:
2491
+
2492
+ - ``proof`` -- (default: ``True``)
2493
+
2494
+ EXAMPLES::
2495
+
2496
+ sage: x = polygen(QQ)
2497
+ sage: K.<a> = NumberField(x^2 + 6)
2498
+ sage: x = polygen(K)
2499
+ sage: L.<b> = K.extension(x^2 + 3) # extend by x^2+3
2500
+ sage: L.is_free()
2501
+ False
2502
+ """
2503
+ proof = proof_flag(proof)
2504
+ base_bnf = self._pari_base_bnf(proof)
2505
+ return base_bnf.rnfisfree(self.pari_relative_polynomial()) == 1
2506
+
2507
+ def _factor_univariate_polynomial(self, poly, **kwargs):
2508
+ """
2509
+ Factorisation of univariate polynomials over relative number fields.
2510
+
2511
+ This is called by the ``factor`` method of univariate polynomials.
2512
+
2513
+ EXAMPLES::
2514
+
2515
+ sage: x = polygen(ZZ, 'x')
2516
+ sage: K.<i> = NumberField(x**2 + 1)
2517
+ sage: L.<sqrt2> = K.extension(x*x - 2)
2518
+ sage: x = polygen(L,'x')
2519
+ sage: factor(x**2+8) # indirect doctest
2520
+ (x + 2*i*sqrt2) * (x - 2*i*sqrt2)
2521
+ """
2522
+ M = self.absolute_field('a')
2523
+ from_M, to_M = M.structure()
2524
+ g = M['x']([to_M(x) for x in poly.list()])
2525
+ F = g.factor()
2526
+ S = poly.parent()
2527
+ v = [(S([from_M(x) for x in f.list()]), e) for f, e in F]
2528
+ return Factorization(v, from_M(F.unit()))
2529
+
2530
+ def lift_to_base(self, element):
2531
+ """
2532
+ Lift an element of this extension into the base field if possible,
2533
+ or raise a :exc:`ValueError` if it is not possible.
2534
+
2535
+ EXAMPLES::
2536
+
2537
+ sage: x = polygen(ZZ)
2538
+ sage: K.<a> = NumberField(x^3 - 2)
2539
+ sage: R.<y> = K[]
2540
+ sage: L.<b> = K.extension(y^2 - a)
2541
+ sage: L.lift_to_base(b^4)
2542
+ a^2
2543
+ sage: L.lift_to_base(b^6)
2544
+ 2
2545
+ sage: L.lift_to_base(355/113)
2546
+ 355/113
2547
+ sage: L.lift_to_base(b)
2548
+ Traceback (most recent call last):
2549
+ ...
2550
+ ValueError: The element b is not in the base field
2551
+
2552
+ TESTS:
2553
+
2554
+ Number fields defined by non-monic and non-integral
2555
+ polynomials are supported (:issue:`252`)::
2556
+
2557
+ sage: R.<x> = QQ[]
2558
+ sage: K.<a> = NumberField(x^2 + 1/2)
2559
+ sage: L.<b> = K.extension(x^2 - a/2)
2560
+ sage: L.lift_to_base(b^2)
2561
+ 1/2*a
2562
+ """
2563
+ # Convert the element to a PARI polynomial with t_POLMOD
2564
+ # coefficients representing elements of the base field.
2565
+ r = self._pari_rnfeq()._eltabstorel_lift(self(element)._pari_polynomial('x'))
2566
+ # Lift the coefficients and call simplify() to make PARI check
2567
+ # which variables really appear in the resulting polynomial
2568
+ # (otherwise we always have a polynomial in two variables even
2569
+ # though not all variables actually occur).
2570
+ r = r.lift().simplify()
2571
+
2572
+ # Special case: check whether the result is simply an integer or rational
2573
+ if r.type() in ["t_INT", "t_FRAC"]:
2574
+ return self.base_field()(r)
2575
+ # Now we should have a polynomial in the variable y.
2576
+ # Otherwise we're not in the base field.
2577
+ if r.type() != "t_POL" or str(r.variable()) != 'y':
2578
+ raise ValueError("The element %s is not in the base field" % element)
2579
+ return self.base_field()(r, check=False)
2580
+
2581
+ def relativize(self, alpha, names):
2582
+ r"""
2583
+ Given an element in ``self`` or an embedding of a subfield into ``self``,
2584
+ return a relative number field `K` isomorphic to ``self`` that is relative
2585
+ over the absolute field `\QQ(\alpha)` or the domain of `\alpha`, along
2586
+ with isomorphisms from `K` to ``self`` and from ``self`` to `K`.
2587
+
2588
+ INPUT:
2589
+
2590
+ - ``alpha`` -- an element of ``self``, or an embedding of a subfield into ``self``
2591
+ - ``names`` -- name of generator for output field `K`
2592
+
2593
+ OUTPUT: `K` -- a relative number field
2594
+
2595
+ Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where
2596
+ ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is
2597
+ an isomorphism from ``self`` to `K`.
2598
+
2599
+ EXAMPLES::
2600
+
2601
+ sage: x = polygen(ZZ, 'x')
2602
+ sage: K.<a,b> = NumberField([x^4 + 3, x^2 + 2]); K
2603
+ Number Field in a with defining polynomial x^4 + 3 over its base field
2604
+ sage: L.<z,w> = K.relativize(a^2)
2605
+ sage: z^2
2606
+ z^2
2607
+ sage: w^2
2608
+ -3
2609
+ sage: L
2610
+ Number Field in z with defining polynomial
2611
+ x^4 + (-2*w + 4)*x^2 + 4*w + 1 over its base field
2612
+ sage: L.base_field()
2613
+ Number Field in w with defining polynomial x^2 + 3
2614
+
2615
+ Now suppose we have `K` below `L` below `M`::
2616
+
2617
+ sage: M = NumberField(x^8 + 2, 'a'); M
2618
+ Number Field in a with defining polynomial x^8 + 2
2619
+ sage: L, L_into_M, _ = M.subfields(4)[0]; L
2620
+ Number Field in a0 with defining polynomial x^4 + 2
2621
+ sage: K, K_into_L, _ = L.subfields(2)[0]; K
2622
+ Number Field in a0_0 with defining polynomial x^2 + 2
2623
+ sage: K_into_M = L_into_M * K_into_L
2624
+
2625
+ sage: L_over_K = L.relativize(K_into_L, 'c'); L_over_K
2626
+ Number Field in c with defining polynomial x^2 + a0_0 over its base field
2627
+ sage: L_over_K_to_L, L_to_L_over_K = L_over_K.structure()
2628
+ sage: M_over_L_over_K = M.relativize(L_into_M * L_over_K_to_L, 'd')
2629
+ sage: M_over_L_over_K
2630
+ Number Field in d with defining polynomial x^2 + c over its base field
2631
+ sage: M_over_L_over_K.base_field() is L_over_K
2632
+ True
2633
+
2634
+ Test relativizing a degree 6 field over its degree 2 and degree 3
2635
+ subfields, using both an explicit element::
2636
+
2637
+ sage: K.<a> = NumberField(x^6 + 2); K
2638
+ Number Field in a with defining polynomial x^6 + 2
2639
+ sage: K2, K2_into_K, _ = K.subfields(2)[0]; K2
2640
+ Number Field in a0 with defining polynomial x^2 + 2
2641
+ sage: K3, K3_into_K, _ = K.subfields(3)[0]; K3
2642
+ Number Field in a0 with defining polynomial x^3 - 2
2643
+
2644
+ Here we explicitly relativize over an element of K2 (not the
2645
+ generator)::
2646
+
2647
+ sage: L = K.relativize(K3_into_K, 'b'); L
2648
+ Number Field in b with defining polynomial x^2 + a0 over its base field
2649
+ sage: L_to_K, K_to_L = L.structure()
2650
+ sage: L_over_K2 = L.relativize(K_to_L(K2_into_K(K2.gen() + 1)), 'c'); L_over_K2
2651
+ Number Field in c0 with defining polynomial x^3 - c1 + 1 over its base field
2652
+ sage: L_over_K2.base_field()
2653
+ Number Field in c1 with defining polynomial x^2 - 2*x + 3
2654
+
2655
+ Here we use a morphism to preserve the base field information::
2656
+
2657
+ sage: K2_into_L = K_to_L * K2_into_K
2658
+ sage: L_over_K2 = L.relativize(K2_into_L, 'c'); L_over_K2
2659
+ Number Field in c with defining polynomial x^3 - a0 over its base field
2660
+ sage: L_over_K2.base_field() is K2
2661
+ True
2662
+ """
2663
+ K = self.absolute_field('a')
2664
+ from_K, to_K = K.structure()
2665
+
2666
+ if isinstance(alpha, Map):
2667
+ # alpha is an embedding of a subfield into self; compose to get an
2668
+ # embedding of a subfield into the absolute field
2669
+ beta = to_K * alpha
2670
+ else:
2671
+ # alpha is an element coercible into self
2672
+ beta = to_K(alpha)
2673
+
2674
+ L = K.relativize(beta, names)
2675
+ return K.relativize(beta, names, structure=structure.RelativeFromRelative(L))
2676
+
2677
+ def uniformizer(self, P, others='positive'):
2678
+ """
2679
+ Return an element of ``self`` with valuation 1 at the prime ideal `P`.
2680
+
2681
+ INPUT:
2682
+
2683
+ - ``self`` -- a number field
2684
+
2685
+ - ``P`` -- a prime ideal of ``self``
2686
+
2687
+ - ``others`` -- either ``'positive'`` (default), in which case the
2688
+ element will have nonnegative valuation at all other primes of
2689
+ ``self``, or ``'negative'``, in which case the element will have
2690
+ nonpositive valuation at all other primes of ``self``
2691
+
2692
+
2693
+ .. NOTE::
2694
+
2695
+ When `P` is principal (e.g., always when ``self`` has class number
2696
+ one), the result may or may not be a generator of `P`!
2697
+
2698
+ EXAMPLES::
2699
+
2700
+ sage: x = polygen(ZZ, 'x')
2701
+ sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 3])
2702
+ sage: P = K.prime_factors(5)[0]; P
2703
+ Fractional ideal (5, -1/2*a + b + 5/2)
2704
+ sage: u = K.uniformizer(P)
2705
+ sage: u.valuation(P)
2706
+ 1
2707
+ sage: (P, 1) in K.factor(u)
2708
+ True
2709
+ """
2710
+ if not isinstance(P, NumberFieldIdeal):
2711
+ P = self.ideal(P)
2712
+ if not P.is_maximal():
2713
+ raise ValueError("P (=%s) must be a nonzero prime." % P)
2714
+ abs = self.absolute_field('a')
2715
+ from_abs = abs.structure()[0]
2716
+ return from_abs(abs.uniformizer(P.absolute_ideal(), others=others))
2717
+
2718
+
2719
+ def NumberField_relative_v1(base_field, poly, name, latex_name, canonical_embedding=None):
2720
+ """
2721
+ Used for unpickling old pickles.
2722
+
2723
+ EXAMPLES::
2724
+
2725
+ sage: from sage.rings.number_field.number_field_rel import NumberField_relative_v1
2726
+ sage: R.<x> = CyclotomicField(3)[]
2727
+ sage: NumberField_relative_v1(CyclotomicField(3), x^2 + 7, 'a', 'a')
2728
+ Number Field in a with defining polynomial x^2 + 7 over its base field
2729
+ """
2730
+ return NumberField(poly.change_ring(base_field), name, check=False,
2731
+ embedding=canonical_embedding, latex_name=latex_name)
2732
+
2733
+
2734
+ NumberField_extension_v1 = NumberField_relative_v1 # historical reasons only