passagemath-flint 10.6.1rc10__cp311-cp311-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-311-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-311-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-311-x86_64-linux-gnu.so +0 -0
  26. sage/graphs/chrompoly.pyx +555 -0
  27. sage/graphs/matchpoly.cpython-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-x86_64-linux-gnu.so +0 -0
  221. sage/matrix/change_ring.pyx +43 -0
  222. sage/matrix/matrix_complex_ball_dense.cpython-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-x86_64-linux-gnu.so +0 -0
  286. sage/rings/factorint_flint.pyx +99 -0
  287. sage/rings/fraction_field_FpT.cpython-311-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-311-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-311-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-311-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-311-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-311-x86_64-linux-gnu.so +0 -0
  325. sage/rings/polynomial/hilbert.pyx +602 -0
  326. sage/rings/polynomial/polynomial_complex_arb.cpython-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-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-311-x86_64-linux-gnu.so +0 -0
  354. sage/rings/real_interval_absolute.pyx +1073 -0
  355. sage/rings/real_mpfi.cpython-311-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-311-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,2981 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.libs.linbox
3
+ """
4
+ Orders in number fields
5
+
6
+ EXAMPLES:
7
+
8
+ We define an absolute order::
9
+
10
+ sage: x = polygen(ZZ, 'x')
11
+ sage: K.<a> = NumberField(x^2 + 1); O = K.order(2*a)
12
+ sage: O.basis()
13
+ [1, 2*a]
14
+
15
+ We compute a basis for an order in a relative extension
16
+ that is generated by 2 elements::
17
+
18
+ sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3])
19
+ sage: O = K.order([3*a, 2*b])
20
+ sage: O.basis()
21
+ [1, 3*a - 2*b, -6*b*a + 6, 3*a]
22
+
23
+ We compute a maximal order of a degree 10 field::
24
+
25
+ sage: K.<a> = NumberField((x+1)^10 + 17)
26
+ sage: K.maximal_order()
27
+ Maximal Order generated by a in Number Field in a with defining polynomial
28
+ x^10 + 10*x^9 + 45*x^8 + 120*x^7 + 210*x^6 + 252*x^5 + 210*x^4 + 120*x^3 + 45*x^2 + 10*x + 18
29
+
30
+ We compute a suborder, which has index a power of 17 in the maximal order::
31
+
32
+ sage: O = K.order(17*a); O
33
+ Order generated by 17*a in Number Field in a with defining polynomial
34
+ x^10 + 10*x^9 + 45*x^8 + 120*x^7 + 210*x^6 + 252*x^5 + 210*x^4 + 120*x^3 + 45*x^2 + 10*x + 18
35
+ sage: m = O.index_in(K.maximal_order()); m
36
+ 23453165165327788911665591944416226304630809183732482257
37
+ sage: factor(m)
38
+ 17^45
39
+
40
+ AUTHORS:
41
+
42
+ - William Stein and Robert Bradshaw (2007-09): initial version
43
+ """
44
+ # ****************************************************************************
45
+ # Copyright (C) 2007 Robert Bradshaw <robertwb@gmail.com>
46
+ # 2007-2009 William Stein <wstein@gmail.com>
47
+ # 2007-2017 David Roe <roed.math@gmail.com>
48
+ # 2008 Craig Citro <craigcitro@gmail.com>
49
+ # 2008 Alexandru Ghitza <aghitza@alum.mit.edu>
50
+ # 2008 Gary Furnish <bill@indirectproof.net>
51
+ # 2008-2009 Francis Clarke <F.Clarke@Swansea.ac.uk>
52
+ # 2008-2017 John Cremona <john.cremona@gmail.com>
53
+ # 2008 Mike Hansen <mhansen@gmail.com>
54
+ # 2008-2011 David Loeffler <D.Loeffler@dpmms.cam.ac.uk>
55
+ # 2009 Sebastian Pancratz <sage@pancratz.org>
56
+ # 2010-2016 Jeroen Demeyer <jdemeyer@cage.ugent.be>
57
+ # 2011 Martin Albrecht <martinralbrecht@googlemail.com>
58
+ # 2012 Vincent Delecroix <vincent.delecroix@u-bordeaux.fr>
59
+ # 2013-2020 Marc Mezzarobba <marc@mezzarobba.net>
60
+ # 2014 Wilfried Luebbe <wluebbe@gmail.com>
61
+ # 2014-2016 Peter Bruin <P.J.Bruin@math.leidenuniv.nl>
62
+ # 2014 Gonzalo Tornaría <tornaria@cmat.edu.uy>
63
+ # 2014-2018 Frédéric Chapoton <chapoton@unistra.fr>
64
+ # 2016 Marc Masdeu <marc.masdeu@gmail.com>
65
+ # 2017 Édouard Rousseau <edouard.rousseau@u-psud.fr>
66
+ # 2017-2022 Julian Rüth <julian.rueth@fsfe.org>
67
+ # 2018 Erik M. Bray <erik.bray@lri.fr>
68
+ # 2019-2021 Matthias Koeppe <mkoeppe@math.ucdavis.edu>
69
+ # 2019 Tuomas Tajakka <tuomas.tajakka@gmail.com>
70
+ # 2020 John H. Palmieri <jhpalmieri64@gmail.com>
71
+ # 2020 Thierry Monteil <sage@lma.metelu.net>
72
+ # 2021 Antonio Rojas <arojas@archlinux.org>
73
+ # 2021 Jonathan Kliem <jonathan.kliem@gmail.com>
74
+ #
75
+ # Distributed under the terms of the GNU General Public License (GPL)
76
+ # as published by the Free Software Foundation; either version 2 of
77
+ # the License, or (at your option) any later version.
78
+ # https://www.gnu.org/licenses/
79
+ # ****************************************************************************
80
+
81
+ from sage.categories.integral_domains import IntegralDomains
82
+ from sage.categories.noetherian_rings import NoetherianRings
83
+ from sage.misc.cachefunc import cached_method
84
+ from sage.structure.parent import Parent
85
+ from sage.structure.sequence import Sequence
86
+ from sage.rings.integer_ring import ZZ
87
+ import sage.rings.abc
88
+ from sage.structure.element import Element
89
+ from sage.structure.factory import UniqueFactory
90
+ from .number_field_element import OrderElement_absolute, OrderElement_relative
91
+
92
+ from .number_field_element_quadratic import OrderElement_quadratic
93
+
94
+ from sage.rings.monomials import monomials
95
+
96
+
97
+ def quadratic_order_class_number(disc):
98
+ r"""
99
+ Return the class number of the quadratic order of given discriminant.
100
+
101
+ EXAMPLES::
102
+
103
+ sage: from sage.rings.number_field.order import quadratic_order_class_number
104
+ sage: quadratic_order_class_number(-419)
105
+ 9
106
+ sage: quadratic_order_class_number(60)
107
+ 2
108
+
109
+ ALGORITHM: Either :pari:`qfbclassno` or :pari:`quadclassunit`,
110
+ depending on the size of the discriminant.
111
+ """
112
+ from sage.libs.pari import pari
113
+
114
+ # cutoffs from PARI documentation
115
+ if disc < -10**25 or disc > 10**10:
116
+ h = pari.quadclassunit(disc)[0]
117
+ else:
118
+ h = pari.qfbclassno(disc)
119
+ return ZZ(h)
120
+
121
+
122
+ class OrderFactory(UniqueFactory):
123
+ r"""
124
+ Abstract base class for factories creating orders, such as
125
+ :class:`AbsoluteOrderFactory` and :class:`RelativeOrderFactory`.
126
+
127
+ TESTS::
128
+
129
+ sage: from sage.rings.number_field.order import AbsoluteOrder, OrderFactory
130
+ sage: isinstance(AbsoluteOrder, OrderFactory)
131
+ True
132
+ """
133
+
134
+ def get_object(self, version, key, extra_args):
135
+ r"""
136
+ Create the order identified by ``key``.
137
+
138
+ This overrides the default implementation to update the maximality of
139
+ the order if it was explicitly specified.
140
+
141
+ EXAMPLES:
142
+
143
+ Even though orders are unique parents, this lets us update their
144
+ internal state when they are recreated with more additional
145
+ information available about them::
146
+
147
+ sage: x = polygen(ZZ, 'x')
148
+ sage: L.<a, b> = NumberField([x^2 - 1000003, x^2 - 5*1000099^2])
149
+ sage: O = L.maximal_order([2], assume_maximal=None)
150
+
151
+ sage: O._is_maximal_at(2)
152
+ True
153
+ sage: O._is_maximal_at(3) is None
154
+ True
155
+
156
+ sage: N = L.maximal_order([3], assume_maximal=None)
157
+ sage: N is O
158
+ True
159
+ sage: N._is_maximal_at(2)
160
+ True
161
+ sage: N._is_maximal_at(3)
162
+ True
163
+ """
164
+ is_maximal = extra_args.pop("is_maximal", None)
165
+ is_maximal_at = extra_args.pop("is_maximal_at", {})
166
+
167
+ order = super().get_object(version, key, extra_args)
168
+
169
+ # Add assumptions about maximality to the order (potentially creating
170
+ # an independent non-unique clone to support legacy use cases.)
171
+ order = order._assume_maximal(is_maximal)
172
+ for p, v in is_maximal_at.items():
173
+ order = order._assume_maximal(p=p, is_maximal=v)
174
+
175
+ return order
176
+
177
+
178
+ class AbsoluteOrderFactory(OrderFactory):
179
+ r"""
180
+ An order in an (absolute) number field.
181
+
182
+ EXAMPLES::
183
+
184
+ sage: x = polygen(ZZ, 'x')
185
+ sage: K.<i> = NumberField(x^2 + 1)
186
+ sage: K.order(i)
187
+ Gaussian Integers generated by i in Number Field in i with defining polynomial x^2 + 1
188
+ """
189
+
190
+ def create_key_and_extra_args(self, K, module_rep, is_maximal=None, check=True, is_maximal_at=()):
191
+ r"""
192
+ Return normalized arguments to create an absolute order.
193
+
194
+ TESTS:
195
+
196
+ In particular, this normalizes the data that is used when pickling orders::
197
+
198
+ sage: x = polygen(ZZ, 'x')
199
+ sage: K.<i> = NumberField(x^2 + 1)
200
+ sage: OK = K.order(i)
201
+ sage: OK._factory_data
202
+ (<sage.rings.number_field.order.AbsoluteOrderFactory object at 0x...>,
203
+ (...),
204
+ (Number Field in i with defining polynomial x^2 + 1,
205
+ Free module of degree 2 and rank 2 over Integer Ring
206
+ Echelon basis matrix:
207
+ [1 0]
208
+ [0 1]),
209
+ {})
210
+
211
+ Note how the above is lacking the ``is_maximal`` and ``is_maximal_at``
212
+ keywords. These are stripped by :meth:`OrderFactory.get_object` and
213
+ then put back in by :meth:`reduce_data`.
214
+ """
215
+ if check:
216
+ if not K.is_absolute():
217
+ raise ValueError("AbsoluteOrder must be called with an absolute number field")
218
+
219
+ _, _, to_v = K.vector_space()
220
+ if to_v(1) not in module_rep:
221
+ raise ValueError("1 is not in the span of the module, hence not an order")
222
+
223
+ if module_rep.rank() != K.degree():
224
+ raise ValueError("the module defining an absolute order must have full rank")
225
+
226
+ return (K, module_rep), {"is_maximal": is_maximal, "is_maximal_at": {p: True for p in is_maximal_at}}
227
+
228
+ def create_object(self, version, key, is_maximal=None, is_maximal_at=()):
229
+ r"""
230
+ Create an absolute order.
231
+
232
+ TESTS:
233
+
234
+ This method is also used during unpickling::
235
+
236
+ sage: x = polygen(ZZ, 'x')
237
+ sage: K.<i> = NumberField(x^2 + 1)
238
+ sage: OK = K.order(i)
239
+ sage: loads(dumps(OK)) is OK
240
+ True
241
+ """
242
+ K, module_rep = key
243
+
244
+ # We intentionally ignore is_maximal and is_maximal_at.
245
+ # OrderFactory.get_object() sets these for us.
246
+ return Order_absolute(K, module_rep)
247
+
248
+ def reduce_data(self, order):
249
+ r"""
250
+ Return the data that can be used to pickle an order created by this factory.
251
+
252
+ This overrides the default implementation to update the latest
253
+ knowledge about primes at which the order is maximal.
254
+
255
+ EXAMPLES:
256
+
257
+ This also works for relative orders since they are wrapping absolute
258
+ orders::
259
+
260
+ sage: x = polygen(ZZ, 'x')
261
+ sage: L.<a, b> = NumberField([x^2 - 1000003, x^2 - 5*1000099^2])
262
+ sage: O = L.maximal_order([5], assume_maximal=None)
263
+
264
+ sage: s = dumps(O)
265
+ sage: loads(s) is O
266
+ True
267
+
268
+ sage: N = L.maximal_order([7], assume_maximal=None)
269
+ sage: dumps(N) == s
270
+ False
271
+
272
+ sage: loads(dumps(N)) is O
273
+ True
274
+ """
275
+ reduction = super().reduce_data(order)
276
+ reduction[1][3]["is_maximal"] = order._is_maximal()
277
+ reduction[1][3]["is_maximal_at"] = order._is_maximal_at()
278
+ return reduction
279
+
280
+
281
+ AbsoluteOrder = AbsoluteOrderFactory("sage.rings.number_field.order.AbsoluteOrder")
282
+
283
+
284
+ class RelativeOrderFactory(OrderFactory):
285
+ r"""
286
+ An order in a relative number field extension.
287
+
288
+ EXAMPLES::
289
+
290
+ sage: x = polygen(ZZ, 'x')
291
+ sage: K.<i> = NumberField(x^2 + 1)
292
+ sage: R.<j> = K[]
293
+ sage: L.<j> = K.extension(j^2 - 2)
294
+ sage: L.order([i, j])
295
+ Relative Order generated by [-i*j + 1, -i] in
296
+ Number Field in j with defining polynomial j^2 - 2 over its base field
297
+ """
298
+
299
+ def create_key_and_extra_args(self, K, absolute_order, is_maximal=None, check=True, is_maximal_at=()):
300
+ r"""
301
+ Return normalized arguments to create a relative order.
302
+
303
+ TESTS:
304
+
305
+ In particular, this normalizes the data that is used when pickling orders::
306
+
307
+ sage: x = polygen(ZZ, 'x')
308
+ sage: K.<i> = NumberField(x^2 + 1)
309
+ sage: R.<j> = K[]
310
+ sage: L.<j> = K.extension(j^2 - 2)
311
+ sage: OK = L.order([i, j])
312
+ sage: OK._factory_data
313
+ (<sage.rings.number_field.order.RelativeOrderFactory object at 0x...>,
314
+ (...),
315
+ (Number Field in j with defining polynomial j^2 - 2 over its base field,
316
+ Order generated by [1/2*z^2 + 1/2, 1/6*z^3 + 1/6*z] in Number Field in z with defining polynomial x^4 - 2*x^2 + 9),
317
+ {})
318
+
319
+ Note how the above is lacking the ``is_maximal`` and ``is_maximal_at``
320
+ keywords. These are stripped by :meth:`OrderFactory.get_object`. Since
321
+ they are applied to the underlying absolute order, they then get
322
+ pickled when the underlying order is pickled.
323
+ """
324
+ return (K, absolute_order), {"is_maximal": is_maximal, "is_maximal_at": {p: True for p in is_maximal_at}}
325
+
326
+ def create_object(self, version, key, is_maximal=None, is_maximal_at=()):
327
+ r"""
328
+ Create a relative order.
329
+
330
+ TESTS:
331
+
332
+ This method is also used during unpickling::
333
+
334
+ sage: x = polygen(ZZ, 'x')
335
+ sage: K.<i> = NumberField(x^2 + 1)
336
+ sage: R.<j> = K[]
337
+ sage: L.<j> = K.extension(j^2 - 2)
338
+ sage: OK = L.order([i, j])
339
+ sage: loads(dumps(OK)) is OK
340
+ True
341
+ """
342
+ K, absolute_order = key
343
+
344
+ # We intentionally ignore is_maximal and is_maximal_at.
345
+ # OrderFactory.get_object() sets these for us.
346
+ return Order_relative(K, absolute_order)
347
+
348
+
349
+ RelativeOrder = RelativeOrderFactory("sage.rings.number_field.order.RelativeOrder")
350
+
351
+
352
+ def is_NumberFieldOrder(R):
353
+ r"""
354
+ Return ``True`` if `R` is either an order in a number field or is the ring `\ZZ` of integers.
355
+
356
+ EXAMPLES::
357
+
358
+ sage: from sage.rings.number_field.order import is_NumberFieldOrder
359
+ sage: x = polygen(ZZ, 'x')
360
+ sage: is_NumberFieldOrder(NumberField(x^2 + 1, 'a').maximal_order())
361
+ doctest:warning...
362
+ DeprecationWarning: The function is_NumberFieldOrder is deprecated;
363
+ use 'isinstance(..., sage.rings.abc.Order) or ... == ZZ' instead.
364
+ See https://github.com/sagemath/sage/issues/38124 for details.
365
+ True
366
+ sage: is_NumberFieldOrder(ZZ)
367
+ True
368
+ sage: is_NumberFieldOrder(QQ)
369
+ False
370
+ sage: is_NumberFieldOrder(45)
371
+ False
372
+ """
373
+ from sage.misc.superseded import deprecation
374
+ deprecation(38124,
375
+ "The function is_NumberFieldOrder is deprecated; "
376
+ "use 'isinstance(..., sage.rings.abc.Order) or ... == ZZ' instead.")
377
+ return isinstance(R, Order) or R == ZZ
378
+
379
+
380
+ def EquationOrder(f, names, **kwds):
381
+ r"""
382
+ Return the equation order generated by a root of the irreducible
383
+ polynomial `f` or list ``f`` of polynomials (to construct a relative
384
+ equation order).
385
+
386
+ IMPORTANT: Note that the generators of the returned order need
387
+ *not* be roots of `f`, since the generators of an order are -- in
388
+ Sage -- module generators.
389
+
390
+ EXAMPLES::
391
+
392
+ sage: x = polygen(ZZ, 'x')
393
+ sage: O.<a,b> = EquationOrder([x^2 + 1, x^2 + 2])
394
+ sage: O
395
+ Relative Order generated by [-b*a - 1, -3*a + 2*b] in
396
+ Number Field in a with defining polynomial x^2 + 1 over its base field
397
+ sage: O.0
398
+ -b*a - 1
399
+ sage: O.1
400
+ -3*a + 2*b
401
+
402
+ Of course the input polynomial must be integral::
403
+
404
+ sage: R = EquationOrder(x^3 + x + 1/3, 'alpha'); R
405
+ Traceback (most recent call last):
406
+ ...
407
+ ValueError: each generator must be integral
408
+
409
+ sage: R = EquationOrder([x^3 + x + 1, x^2 + 1/2], 'alpha'); R
410
+ Traceback (most recent call last):
411
+ ...
412
+ ValueError: each generator must be integral
413
+ """
414
+ from .number_field import NumberField
415
+ R = ZZ['x']
416
+ if isinstance(f, (list, tuple)):
417
+ for g in f:
418
+ try:
419
+ R(g)
420
+ except TypeError:
421
+ raise ValueError('each generator must be integral')
422
+ else:
423
+ try:
424
+ R(f)
425
+ except TypeError:
426
+ raise ValueError('each generator must be integral')
427
+
428
+ K = NumberField(f, names=names, **kwds)
429
+ return K.order(K.gens())
430
+
431
+
432
+ class Order(Parent, sage.rings.abc.Order):
433
+ r"""
434
+ An order in a number field.
435
+
436
+ An order is a subring of the number field that has `\ZZ`-rank equal
437
+ to the degree of the number field over `\QQ`.
438
+
439
+ EXAMPLES::
440
+
441
+ sage: x = polygen(ZZ, 'x')
442
+ sage: K.<theta> = NumberField(x^4 + x + 17)
443
+ sage: K.maximal_order()
444
+ Maximal Order generated by theta in Number Field in theta with defining polynomial x^4 + x + 17
445
+ sage: R = K.order(17*theta); R
446
+ Order generated by 17*theta in Number Field in theta with defining polynomial x^4 + x + 17
447
+ sage: R.basis()
448
+ [1, 17*theta, 289*theta^2, 4913*theta^3]
449
+ sage: R = K.order(17*theta, 13*theta); R
450
+ Maximal Order generated by theta in Number Field in theta with defining polynomial x^4 + x + 17
451
+ sage: R.basis()
452
+ [1, theta, theta^2, theta^3]
453
+ sage: R = K.order([34*theta, 17*theta + 17]); R
454
+ Order generated by 17*theta in Number Field in theta with defining polynomial x^4 + x + 17
455
+ sage: K.<b> = NumberField(x^4 + x^2 + 2)
456
+ sage: (b^2).charpoly().factor()
457
+ (x^2 + x + 2)^2
458
+ sage: K.order(b^2)
459
+ Traceback (most recent call last):
460
+ ...
461
+ ValueError: the rank of the span of gens is wrong
462
+
463
+ Orders are always Noetherian::
464
+
465
+ sage: x = polygen(ZZ, 'x')
466
+ sage: L.<alpha> = NumberField(x**4 - x**2 + 7)
467
+ sage: O = L.maximal_order() ; O.is_noetherian()
468
+ True
469
+ sage: E.<w> = NumberField(x^2 - x + 2)
470
+ sage: OE = E.ring_of_integers(); OE.is_noetherian()
471
+ True
472
+ """
473
+
474
+ def __init__(self, K):
475
+ """
476
+ This is called when creating an order to set the ambient field.
477
+
478
+ EXAMPLES::
479
+
480
+ sage: k = CyclotomicField(5)
481
+ sage: k.maximal_order()
482
+ Maximal Order generated by zeta5 in Cyclotomic Field of order 5 and degree 4
483
+
484
+ TESTS::
485
+
486
+ sage: x = polygen(ZZ, 'x')
487
+ sage: k.<alg> = NumberField(x^7 + 3*x + 1, embedding=CC(0,1))
488
+ sage: O = k.order(alg)
489
+ sage: ordelt = O(alg)
490
+ sage: CC(ordelt)
491
+ 0.0535229072603327 + 1.20934552493846*I
492
+ """
493
+ self._K = K
494
+ cat = IntegralDomains() & NoetherianRings()
495
+ Parent.__init__(self, base=ZZ, names=K.variable_names(),
496
+ normalize=False, category=cat)
497
+ self._populate_coercion_lists_(embedding=self.number_field())
498
+ if self.absolute_degree() == 2:
499
+ self.is_maximal() # cache
500
+
501
+ def fractional_ideal(self, *args, **kwds):
502
+ """
503
+ Return the fractional ideal of the maximal order with given
504
+ generators.
505
+
506
+ EXAMPLES::
507
+
508
+ sage: x = polygen(ZZ, 'x')
509
+ sage: K.<a> = NumberField(x^2 + 2)
510
+ sage: R = K.maximal_order()
511
+ sage: R.fractional_ideal(2/3 + 7*a, a)
512
+ Fractional ideal (1/3*a)
513
+ """
514
+ return self.number_field().fractional_ideal(*args, **kwds)
515
+
516
+ def ideal(self, *args, **kwds):
517
+ """
518
+ Return the integral ideal with given generators.
519
+
520
+ .. NOTE::
521
+
522
+ This method constructs an ideal of this (not necessarily maximal) order.
523
+ To construct a fractional ideal in the ambient number field, use
524
+ :meth:`~sage.rings.number_field.number_field.NumberField_generic.fractional_ideal`.
525
+
526
+ EXAMPLES::
527
+
528
+ sage: x = polygen(ZZ, 'x')
529
+ sage: K.<a> = NumberField(x^2 + 7)
530
+ sage: R = K.maximal_order()
531
+ sage: R.ideal([7*a, 77 + 28*a])
532
+ Ideal (7/2*a + 7/2, 7*a) of Maximal Order generated by 1/2*a + 1/2 in Number Field in a with defining polynomial x^2 + 7
533
+ sage: R = K.order(4*a)
534
+ sage: R.ideal(8)
535
+ Ideal (8, 32*a) of Order of conductor 8 generated by 4*a
536
+ in Number Field in a with defining polynomial x^2 + 7
537
+
538
+ This function is called implicitly below::
539
+
540
+ sage: R = EquationOrder(x^2 + 2, 'a'); R
541
+ Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 2
542
+ sage: (3,15)*R
543
+ Ideal (3, 3*a) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 2
544
+
545
+ The zero ideal is handled properly::
546
+
547
+ sage: R.ideal(0)
548
+ Ideal (0) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 2
549
+ """
550
+ # these keyword arguments are ignored since there used to be optional
551
+ # arguments with these names for controlling deprecated/future behavior;
552
+ # see #34806 and #35762
553
+ if 'warn' in kwds:
554
+ del kwds['warn']
555
+ if 'future' in kwds:
556
+ del kwds['future']
557
+ from sage.rings.number_field.order_ideal import NumberFieldOrderIdeal
558
+ return NumberFieldOrderIdeal(self, *args, **kwds)
559
+
560
+ def _coerce_map_from_(self, R):
561
+ """
562
+ Orders currently only have coerce maps from the integers.
563
+
564
+ EXAMPLES::
565
+
566
+ sage: x = polygen(ZZ, 'x')
567
+ sage: k.<a> = NumberField(x^2 + 5077)
568
+ sage: Ok = k.maximal_order()
569
+ sage: Ok.has_coerce_map_from(k) #indirect doctest
570
+ False
571
+ sage: Ok.has_coerce_map_from(ZZ)
572
+ True
573
+ """
574
+ return R is ZZ or R is int
575
+
576
+ def __mul__(self, right):
577
+ """
578
+ Create an ideal in this order using the syntax ``O * gens``.
579
+
580
+ EXAMPLES::
581
+
582
+ sage: x = polygen(ZZ, 'x')
583
+ sage: k.<a> = NumberField(x^2 + 5077); G = k.class_group(); G
584
+ Class group of order 22 with structure C22 of Number Field in a with defining polynomial x^2 + 5077
585
+ sage: G.0 ^ -9
586
+ Fractional ideal class (43, a + 13)
587
+ sage: Ok = k.maximal_order(); Ok
588
+ Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077
589
+ sage: Ok * (11, a + 7)
590
+ Ideal (8*a + 1, 11*a) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077
591
+ sage: (11, a + 7) * Ok
592
+ Ideal (8*a + 1, 11*a) of Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077
593
+ """
594
+ return self.ideal(right)
595
+
596
+ def __rmul__(self, left):
597
+ """
598
+ Create an ideal in this order using the syntax ``gens * O``.
599
+
600
+ EXAMPLES::
601
+
602
+ sage: x = polygen(ZZ, 'x')
603
+ sage: k.<a> = NumberField(x^2 + 431); G = k.class_group(); G
604
+ Class group of order 21 with structure C21 of Number Field in a with defining polynomial x^2 + 431
605
+ sage: G.0 # random output
606
+ Fractional ideal class (6, 1/2*a + 11/2)
607
+ sage: Ok = k.maximal_order(); Ok
608
+ Maximal Order generated by 1/2*a + 1/2 in Number Field in a with defining polynomial x^2 + 431
609
+ sage: (6, 1/2*a + 11/2)*Ok # random output
610
+ Fractional ideal (6, 1/2*a + 11/2)
611
+ sage: 17*Ok
612
+ Ideal (17/2*a + 17/2, 17*a) of Maximal Order generated by 1/2*a + 1/2 in Number Field in a with defining polynomial x^2 + 431
613
+ """
614
+ return self.ideal(left)
615
+
616
+ def is_field(self, proof=True):
617
+ r"""
618
+ Return ``False`` (because an order is never a field).
619
+
620
+ EXAMPLES::
621
+
622
+ sage: x = polygen(ZZ, 'x')
623
+ sage: L.<alpha> = NumberField(x**4 - x**2 + 7)
624
+ sage: O = L.maximal_order() ; O.is_field()
625
+ False
626
+ sage: CyclotomicField(12).ring_of_integers().is_field()
627
+ False
628
+ """
629
+ return False
630
+
631
+ def is_integrally_closed(self) -> bool:
632
+ r"""
633
+ Return whether this ring is integrally closed.
634
+
635
+ This is true if and only if it is equal
636
+ to the maximal order.
637
+
638
+ EXAMPLES::
639
+
640
+ sage: x = polygen(ZZ, 'x')
641
+ sage: K.<a> = NumberField(x^2 + 189*x + 394)
642
+ sage: R = K.order(2*a)
643
+ sage: R.is_integrally_closed()
644
+ False
645
+ sage: R
646
+ Order of conductor 2 generated by 2*a in Number Field in a with defining polynomial x^2 + 189*x + 394
647
+ sage: S = K.maximal_order(); S
648
+ Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 189*x + 394
649
+ sage: S.is_integrally_closed()
650
+ True
651
+ """
652
+ return self.is_maximal()
653
+
654
+ def krull_dimension(self):
655
+ r"""
656
+ Return the Krull dimension of this order, which is 1.
657
+
658
+ EXAMPLES::
659
+
660
+ sage: K.<a> = QuadraticField(5)
661
+ sage: OK = K.maximal_order()
662
+ sage: OK.krull_dimension()
663
+ 1
664
+ sage: O2 = K.order(2*a)
665
+ sage: O2.krull_dimension()
666
+ 1
667
+ """
668
+ return ZZ.one()
669
+
670
+ def integral_closure(self):
671
+ r"""
672
+ Return the integral closure of this order.
673
+
674
+ EXAMPLES::
675
+
676
+ sage: K.<a> = QuadraticField(5)
677
+ sage: O2 = K.order(2*a); O2
678
+ Order of conductor 4 generated by 2*a in Number Field in a
679
+ with defining polynomial x^2 - 5 with a = 2.236067977499790?
680
+ sage: O2.integral_closure()
681
+ Maximal Order generated by 1/2*a + 1/2 in Number Field in a
682
+ with defining polynomial x^2 - 5 with a = 2.236067977499790?
683
+ sage: OK = K.maximal_order()
684
+ sage: OK is OK.integral_closure()
685
+ True
686
+ """
687
+ if self.is_maximal():
688
+ return self
689
+ else:
690
+ return self.number_field().maximal_order()
691
+
692
+ def gen(self, i):
693
+ r"""
694
+ Return `i`-th module generator of this order.
695
+
696
+ EXAMPLES::
697
+
698
+ sage: x = polygen(ZZ, 'x')
699
+ sage: K.<c> = NumberField(x^3 + 2*x + 17)
700
+ sage: O = K.maximal_order(); O
701
+ Maximal Order generated by c in Number Field in c with defining polynomial x^3 + 2*x + 17
702
+ sage: O.basis()
703
+ [1, c, c^2]
704
+ sage: O.gen(1)
705
+ c
706
+ sage: O.gen(2)
707
+ c^2
708
+ sage: O.gen(5)
709
+ Traceback (most recent call last):
710
+ ...
711
+ IndexError: no 5th generator
712
+ sage: O.gen(-1)
713
+ Traceback (most recent call last):
714
+ ...
715
+ IndexError: no -1th generator
716
+ """
717
+ b = self.basis()
718
+ if i < 0 or i >= len(b):
719
+ raise IndexError("no %sth generator" % i)
720
+ return self.basis()[i]
721
+
722
+ def ngens(self):
723
+ r"""
724
+ Return the number of module generators of this order.
725
+
726
+ EXAMPLES::
727
+
728
+ sage: x = polygen(ZZ, 'x')
729
+ sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8)
730
+ sage: O = K.maximal_order()
731
+ sage: O.ngens()
732
+ 3
733
+ """
734
+ return self.absolute_degree()
735
+
736
+ def gens(self) -> tuple:
737
+ """
738
+ Return the generators as a tuple.
739
+
740
+ EXAMPLES::
741
+
742
+ sage: x = polygen(ZZ, 'x')
743
+ sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8)
744
+ sage: O = K.maximal_order()
745
+ sage: O.gens()
746
+ (1, 1/2*a^2 + 1/2*a, a^2)
747
+ """
748
+ return tuple(self.gen(i) for i in range(self.absolute_degree()))
749
+
750
+ def basis(self): # this must be defined in derived class
751
+ r"""
752
+ Return a basis over `\ZZ` of this order.
753
+
754
+ EXAMPLES::
755
+
756
+ sage: x = polygen(ZZ, 'x')
757
+ sage: K.<a> = NumberField(x^3 + x^2 - 16*x + 16)
758
+ sage: O = K.maximal_order(); O
759
+ Maximal Order generated by 1/4*a^2 + 1/4*a in Number Field in a with defining polynomial x^3 + x^2 - 16*x + 16
760
+ sage: O.basis()
761
+ [1, 1/4*a^2 + 1/4*a, a^2]
762
+ """
763
+ raise NotImplementedError('child classes must implement')
764
+
765
+ def coordinates(self, x):
766
+ r"""
767
+ Return the coordinate vector of `x` with respect to this order.
768
+
769
+ INPUT:
770
+
771
+ - ``x`` -- an element of the number field of this order
772
+
773
+ OUTPUT:
774
+
775
+ A vector of length `n` (the degree of the field) giving
776
+ the coordinates of `x` with respect to the integral basis
777
+ of the order. In general this will be a vector of
778
+ rationals; it will consist of integers if and only if `x`
779
+ is in the order.
780
+
781
+ AUTHOR: John Cremona 2008-11-15
782
+
783
+ ALGORITHM:
784
+
785
+ Uses linear algebra. The change-of-basis matrix is
786
+ cached. Provides simpler implementations for
787
+ :meth:`_contains_`, :meth:`is_integral` and :meth:`smallest_integer`.
788
+
789
+ EXAMPLES::
790
+
791
+ sage: K.<i> = QuadraticField(-1)
792
+ sage: OK = K.ring_of_integers()
793
+ sage: OK_basis = OK.basis(); OK_basis
794
+ [1, i]
795
+ sage: a = 23-14*i
796
+ sage: acoords = OK.coordinates(a); acoords
797
+ (23, -14)
798
+ sage: sum([OK_basis[j]*acoords[j] for j in range(2)]) == a
799
+ True
800
+ sage: OK.coordinates((120+340*i)/8)
801
+ (15, 85/2)
802
+
803
+ sage: O = K.order(3*i)
804
+ sage: O.is_maximal()
805
+ False
806
+ sage: O.index_in(OK)
807
+ 3
808
+ sage: acoords = O.coordinates(a); acoords
809
+ (23, -14/3)
810
+ sage: sum([O.basis()[j]*acoords[j] for j in range(2)]) == a
811
+ True
812
+ """
813
+ K = self.number_field()
814
+ V, from_V, to_V = K.absolute_vector_space()
815
+
816
+ try:
817
+ M = self.__basis_matrix_inverse
818
+ except AttributeError:
819
+ from sage.matrix.constructor import Matrix
820
+ self.__basis_matrix_inverse = Matrix([to_V(b) for b in self.basis()]).inverse()
821
+ M = self.__basis_matrix_inverse
822
+ return to_V(K(x)) * M
823
+
824
+ def free_module(self):
825
+ r"""
826
+ Return the free `\ZZ`-module contained in the vector space
827
+ associated to the ambient number field, that corresponds
828
+ to this order.
829
+
830
+ EXAMPLES::
831
+
832
+ sage: x = polygen(ZZ, 'x')
833
+ sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8)
834
+ sage: O = K.maximal_order(); O.basis()
835
+ [1, 1/2*a^2 + 1/2*a, a^2]
836
+ sage: O.free_module()
837
+ Free module of degree 3 and rank 3 over Integer Ring
838
+ User basis matrix:
839
+ [ 1 0 0]
840
+ [ 0 1/2 1/2]
841
+ [ 0 0 1]
842
+
843
+ An example in a relative extension. Notice that the module is
844
+ a `\ZZ`-module in the absolute field associated to the relative
845
+ field::
846
+
847
+ sage: x = polygen(ZZ, 'x')
848
+ sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2])
849
+ sage: O = K.maximal_order(); O.basis()
850
+ [(-3/2*b - 5)*a + 7/2*b - 2, -3*a + 2*b, -2*b*a - 3, -7*a + 5*b]
851
+ sage: O.free_module()
852
+ Free module of degree 4 and rank 4 over Integer Ring
853
+ User basis matrix:
854
+ [1/4 1/4 3/4 3/4]
855
+ [ 0 1/2 0 1/2]
856
+ [ 0 0 1 0]
857
+ [ 0 0 0 1]
858
+ """
859
+ try:
860
+ return self.__free_module
861
+ except AttributeError:
862
+ pass
863
+ from .number_field_ideal import basis_to_module
864
+ M = basis_to_module(self.basis(), self.number_field())
865
+ self.__free_module = M
866
+ return M
867
+
868
+ @cached_method
869
+ def ring_generators(self):
870
+ """
871
+ Return generators for ``self`` as a ring.
872
+
873
+ EXAMPLES::
874
+
875
+ sage: x = polygen(ZZ, 'x')
876
+ sage: K.<i> = NumberField(x^2 + 1)
877
+ sage: O = K.maximal_order(); O
878
+ Gaussian Integers generated by i in Number Field in i with defining polynomial x^2 + 1
879
+ sage: O.ring_generators()
880
+ [i]
881
+
882
+ This is an example where 2 generators are required (because 2 is an essential
883
+ discriminant divisor).::
884
+
885
+ sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8)
886
+ sage: O = K.maximal_order(); O.basis()
887
+ [1, 1/2*a^2 + 1/2*a, a^2]
888
+ sage: O.ring_generators()
889
+ [1/2*a^2 + 1/2*a, a^2]
890
+
891
+ An example in a relative number field::
892
+
893
+ sage: K.<a, b> = NumberField([x^2 + x + 1, x^3 - 3])
894
+ sage: O = K.maximal_order()
895
+ sage: O.ring_generators()
896
+ [(-5/3*b^2 + 3*b - 2)*a - 7/3*b^2 + b + 3,
897
+ (-5*b^2 - 9)*a - 5*b^2 - b,
898
+ (-6*b^2 - 11)*a - 6*b^2 - b]
899
+ """
900
+ K = self._K
901
+ n = []
902
+ V, from_V, to_V = self._K.absolute_vector_space()
903
+ A = ZZ**K.absolute_degree()
904
+ remaining = [x for x in self.basis() if x != 1]
905
+ gens = []
906
+ while remaining:
907
+ g = remaining.pop(0)
908
+ gens.append(g)
909
+ n.append(g.absolute_minpoly().degree())
910
+ W = A.span([to_V(x) for x in monomials(gens, n)])
911
+ remaining = [x for x in remaining if to_V(x) not in W]
912
+ return Sequence(gens, immutable=True)
913
+
914
+ @cached_method
915
+ def _defining_names(self):
916
+ """
917
+ Return the generators of the ambient number field, but with
918
+ this order as parent.
919
+
920
+ EXAMPLES::
921
+
922
+ sage: x = polygen(ZZ, 'x')
923
+ sage: B.<z> = EquationOrder(x^2 + 3)
924
+ sage: B._defining_names()
925
+ (z,)
926
+
927
+ For relative extensions::
928
+
929
+ sage: O.<a,b> = EquationOrder([x^2 + 1, x^2 + 2])
930
+ sage: O._defining_names()
931
+ (a, b)
932
+ """
933
+ gens = self.number_field().gens()
934
+ return tuple(self(g) for g in gens)
935
+
936
+ def zeta(self, n=2, all=False):
937
+ r"""
938
+ Return a primitive `n`-th root of unity in this order, if it
939
+ contains one. If ``all`` is ``True``, return all of them.
940
+
941
+ EXAMPLES::
942
+
943
+ sage: x = polygen(ZZ, 'x')
944
+ sage: F.<alpha> = NumberField(x**2 + 3)
945
+ sage: F.ring_of_integers().zeta(6)
946
+ -1/2*alpha + 1/2
947
+ sage: O = F.order([3*alpha])
948
+ sage: O.zeta(3)
949
+ Traceback (most recent call last):
950
+ ...
951
+ ArithmeticError: there are no 3rd roots of unity in self
952
+ """
953
+ roots_in_field = self.number_field().zeta(n, True)
954
+ roots_in_self = [self(x) for x in roots_in_field if x in self]
955
+ if not roots_in_self:
956
+ if all:
957
+ return []
958
+ else:
959
+ raise ArithmeticError("there are no %s roots of unity in self" % n.ordinal_str())
960
+ if all:
961
+ return roots_in_self
962
+ else:
963
+ return roots_in_self[0]
964
+
965
+ def number_field(self):
966
+ """
967
+ Return the number field of this order, which is the ambient
968
+ number field that this order is embedded in.
969
+
970
+ EXAMPLES::
971
+
972
+ sage: x = polygen(ZZ, 'x')
973
+ sage: K.<b> = NumberField(x^4 + x^2 + 2)
974
+ sage: O = K.order(2*b); O
975
+ Order generated by 2*b in Number Field in b with defining polynomial x^4 + x^2 + 2
976
+ sage: O.basis()
977
+ [1, 2*b, 4*b^2, 8*b^3]
978
+ sage: O.number_field()
979
+ Number Field in b with defining polynomial x^4 + x^2 + 2
980
+ sage: O.number_field() is K
981
+ True
982
+ """
983
+ return self._K
984
+
985
+ def ambient(self):
986
+ r"""
987
+ Return the ambient number field that contains ``self``.
988
+
989
+ This is the same as :meth:`number_field` and
990
+ :meth:`fraction_field`
991
+
992
+ EXAMPLES::
993
+
994
+ sage: x = polygen(ZZ, 'x')
995
+ sage: k.<z> = NumberField(x^2 - 389)
996
+ sage: o = k.order(389*z + 1)
997
+ sage: o
998
+ Order of conductor 778 generated by 389*z in Number Field in z with defining polynomial x^2 - 389
999
+ sage: o.basis()
1000
+ [1, 389*z]
1001
+ sage: o.ambient()
1002
+ Number Field in z with defining polynomial x^2 - 389
1003
+ """
1004
+ return self._K
1005
+
1006
+ def residue_field(self, prime, names=None, check=False):
1007
+ """
1008
+ Return the residue field of this order at a given prime, i.e., `O/pO`.
1009
+
1010
+ INPUT:
1011
+
1012
+ - ``prime`` -- a prime ideal of the maximal order in this number field
1013
+ - ``names`` -- the name of the variable in the residue field
1014
+ - ``check`` -- whether or not to check the primality of prime
1015
+
1016
+ OUTPUT: the residue field at this prime
1017
+
1018
+ EXAMPLES::
1019
+
1020
+ sage: R.<x> = QQ[]
1021
+ sage: x = polygen(ZZ, 'x')
1022
+ sage: K.<a> = NumberField(x^4 + 3*x^2 - 17)
1023
+ sage: P = K.ideal(61).factor()[0][0]
1024
+ sage: OK = K.maximal_order()
1025
+ sage: OK.residue_field(P)
1026
+ Residue field in abar of Fractional ideal (61, a^2 + 30)
1027
+ sage: Fp.<b> = OK.residue_field(P)
1028
+ sage: Fp
1029
+ Residue field in b of Fractional ideal (61, a^2 + 30)
1030
+ """
1031
+ if self.is_maximal():
1032
+ return self.number_field().residue_field(prime, names, check=check)
1033
+
1034
+ raise NotImplementedError("residue fields of non-maximal orders "
1035
+ "are not yet supported")
1036
+
1037
+ def fraction_field(self):
1038
+ """
1039
+ Return the fraction field of this order, which is the
1040
+ ambient number field.
1041
+
1042
+ EXAMPLES::
1043
+
1044
+ sage: x = polygen(ZZ, 'x')
1045
+ sage: K.<b> = NumberField(x^4 + 17*x^2 + 17)
1046
+ sage: O = K.order(17*b); O
1047
+ Order generated by 17*b in Number Field in b with defining polynomial x^4 + 17*x^2 + 17
1048
+ sage: O.fraction_field()
1049
+ Number Field in b with defining polynomial x^4 + 17*x^2 + 17
1050
+ """
1051
+ return self._K
1052
+
1053
+ def degree(self):
1054
+ r"""
1055
+ Return the degree of this order, which is the rank of this order as a
1056
+ `\ZZ`-module.
1057
+
1058
+ EXAMPLES::
1059
+
1060
+ sage: x = polygen(ZZ, 'x')
1061
+ sage: k.<c> = NumberField(x^3 + x^2 - 2*x+8)
1062
+ sage: o = k.maximal_order()
1063
+ sage: o.degree()
1064
+ 3
1065
+ sage: o.rank()
1066
+ 3
1067
+ """
1068
+ return self._K.degree()
1069
+
1070
+ def rank(self):
1071
+ r"""
1072
+ Return the rank of this order, which is the rank of the underlying
1073
+ `\ZZ`-module, or the degree of the ambient number field that contains
1074
+ this order.
1075
+
1076
+ This is a synonym for :meth:`degree`.
1077
+
1078
+ EXAMPLES::
1079
+
1080
+ sage: x = polygen(ZZ, 'x')
1081
+ sage: k.<c> = NumberField(x^5 + x^2 + 1)
1082
+ sage: o = k.maximal_order(); o
1083
+ Maximal Order generated by c in Number Field in c with defining polynomial x^5 + x^2 + 1
1084
+ sage: o.rank()
1085
+ 5
1086
+ """
1087
+ return self.degree()
1088
+
1089
+ def class_number(self, proof=None):
1090
+ r"""
1091
+ Return the class number of this order.
1092
+
1093
+ EXAMPLES::
1094
+
1095
+ sage: ZZ[2^(1/3)].class_number() # needs fpylll sage.symbolic
1096
+ 1
1097
+ sage: QQ[sqrt(-23)].maximal_order().class_number() # needs fpylll sage.symbolic
1098
+ 3
1099
+ sage: ZZ[120*sqrt(-23)].class_number() # needs fpylll sage.symbolic
1100
+ 288
1101
+
1102
+ Note that non-maximal orders are only supported in quadratic fields::
1103
+
1104
+ sage: ZZ[120*sqrt(-23)].class_number() # needs fpylll sage.symbolic
1105
+ 288
1106
+ sage: ZZ[100*sqrt(3)].class_number() # needs fpylll sage.symbolic
1107
+ 4
1108
+ sage: ZZ[11*2^(1/3)].class_number() # needs fpylll sage.symbolic
1109
+ Traceback (most recent call last):
1110
+ ...
1111
+ NotImplementedError: computation of class numbers of non-maximal orders
1112
+ not in quadratic fields is not implemented
1113
+
1114
+ TESTS:
1115
+
1116
+ Test for PARI bug #2466::
1117
+
1118
+ sage: x = polygen(ZZ)
1119
+ sage: R.<t> = EquationOrder(x^2 - 8461)
1120
+ sage: R.class_number()
1121
+ 3
1122
+ """
1123
+ if not self.is_maximal():
1124
+ K = self.number_field()
1125
+ if K.degree() != 2:
1126
+ raise NotImplementedError("computation of class numbers of non-maximal orders not in quadratic fields is not implemented")
1127
+ return quadratic_order_class_number(self.discriminant())
1128
+ return self.number_field().class_number(proof=proof)
1129
+
1130
+ def class_group(self, proof=None, names='c'):
1131
+ r"""
1132
+ Return the class group of this order.
1133
+
1134
+ (Currently only implemented for the maximal order.)
1135
+
1136
+ EXAMPLES::
1137
+
1138
+ sage: x = polygen(ZZ, 'x')
1139
+ sage: k.<a> = NumberField(x^2 + 5077)
1140
+ sage: O = k.maximal_order(); O
1141
+ Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 5077
1142
+ sage: O.class_group()
1143
+ Class group of order 22 with structure C22 of
1144
+ Number Field in a with defining polynomial x^2 + 5077
1145
+ """
1146
+ if self.is_maximal():
1147
+ return self.number_field().class_group(proof=proof, names=names)
1148
+ else:
1149
+ raise NotImplementedError('non-maximal orders are not yet supported')
1150
+
1151
+ def is_suborder(self, other):
1152
+ """
1153
+ Return ``True`` if ``self`` and ``other`` are both orders in the
1154
+ same ambient number field and ``self`` is a subset of ``other``.
1155
+
1156
+ EXAMPLES::
1157
+
1158
+ sage: x = polygen(ZZ, 'x')
1159
+ sage: W.<i> = NumberField(x^2 + 1)
1160
+ sage: O5 = W.order(5*i)
1161
+ sage: O10 = W.order(10*i)
1162
+ sage: O15 = W.order(15*i)
1163
+ sage: O15.is_suborder(O5)
1164
+ True
1165
+ sage: O5.is_suborder(O15)
1166
+ False
1167
+ sage: O10.is_suborder(O15)
1168
+ False
1169
+
1170
+ We create another isomorphic but different field::
1171
+
1172
+ sage: W2.<j> = NumberField(x^2 + 1)
1173
+ sage: P5 = W2.order(5*j)
1174
+
1175
+ This is ``False`` because the ambient number fields are not equal.::
1176
+
1177
+ sage: O5.is_suborder(P5)
1178
+ False
1179
+
1180
+ We create a field that contains (in no natural way!) `W`,
1181
+ and of course again :meth:`is_suborder` returns False::
1182
+
1183
+ sage: K.<z> = NumberField(x^4 + 1)
1184
+ sage: M = K.order(5*z)
1185
+ sage: O5.is_suborder(M)
1186
+ False
1187
+ """
1188
+ if not isinstance(other, Order):
1189
+ return False
1190
+ if other.number_field() != self.number_field():
1191
+ return False
1192
+ return self.module().is_submodule(other.module())
1193
+
1194
+ def __eq__(self, other):
1195
+ r"""
1196
+ Check whether the order ``self`` is equal to ``other``.
1197
+
1198
+ .. NOTE::
1199
+
1200
+ This method is just for equality. If you want to check if
1201
+ ``self`` is contained in ``other``, use instead
1202
+ ``self.is_suborder(other)`` to determine inclusion.
1203
+
1204
+ EXAMPLES::
1205
+
1206
+ sage: x = polygen(ZZ, 'x')
1207
+ sage: K.<a> = NumberField(x^3 + 2)
1208
+ sage: O1 = K.order(a); O1
1209
+ Order generated by a in Number Field in a with defining polynomial x^3 + 2
1210
+ sage: O2 = K.order(a^2); O2
1211
+ Order generated by [2*a, a^2] in Number Field in a with defining polynomial x^3 + 2
1212
+ sage: O1 == O2
1213
+ False
1214
+
1215
+ sage: O1 == K
1216
+ False
1217
+ sage: K == O1
1218
+ False
1219
+
1220
+ Here is how to check for inclusion::
1221
+
1222
+ sage: O2.is_suborder(O1)
1223
+ True
1224
+ """
1225
+ if not isinstance(other, Order):
1226
+ return False
1227
+ if self._K != other._K:
1228
+ return False
1229
+ if self is other:
1230
+ return True
1231
+ return self._module_rep == other._module_rep
1232
+
1233
+ def __ne__(self, other):
1234
+ """
1235
+ Check whether the order ``self`` is not equal to ``other``.
1236
+
1237
+ EXAMPLES::
1238
+
1239
+ sage: x = polygen(ZZ, 'x')
1240
+ sage: K.<a> = NumberField(x^3 + 2)
1241
+ sage: O1 = K.order(a); O1
1242
+ Order generated by a in Number Field in a with defining polynomial x^3 + 2
1243
+ sage: O2 = K.order(a^2); O2
1244
+ Order generated by [2*a, a^2] in Number Field in a with defining polynomial x^3 + 2
1245
+ sage: O1 != O2
1246
+ True
1247
+ """
1248
+ return not (self == other)
1249
+
1250
+ def __hash__(self):
1251
+ """
1252
+ Compute the hash of ``self``.
1253
+
1254
+ EXAMPLES::
1255
+
1256
+ sage: x = polygen(ZZ, 'x')
1257
+ sage: K.<a> = NumberField(x^3 + 2)
1258
+ sage: L.<b> = NumberField(x^3 + 3)
1259
+ sage: O1 = K.order(a)
1260
+ sage: hash(O1) == hash(K.order(a))
1261
+ True
1262
+ sage: hash(O1) == hash(K.order(a^2))
1263
+ False
1264
+ sage: hash(O1) == hash(L.order(b))
1265
+ False
1266
+ """
1267
+ return hash((self._K, self._module_rep))
1268
+
1269
+ def conductor(self):
1270
+ r"""
1271
+ For orders in *quadratic* number fields, return the conductor
1272
+ of this order.
1273
+
1274
+ The conductor is the unique positive integer `f` such that
1275
+ the discriminant of this order is `f^2` times the discriminant
1276
+ of the containing quadratic field.
1277
+
1278
+ Not implemented for orders in number fields of degree `\neq 2`.
1279
+
1280
+ .. SEEALSO ::
1281
+
1282
+ :meth:`sage.rings.number_field.number_field.NumberField_quadratic.order_of_conductor`
1283
+
1284
+ EXAMPLES::
1285
+
1286
+ sage: K.<t> = QuadraticField(-101)
1287
+ sage: K.maximal_order().conductor()
1288
+ 1
1289
+ sage: K.order(5*t).conductor()
1290
+ 5
1291
+ sage: K.discriminant().factor()
1292
+ -1 * 2^2 * 101
1293
+ sage: K.order(5*t).discriminant().factor()
1294
+ -1 * 2^2 * 5^2 * 101
1295
+
1296
+ TESTS::
1297
+
1298
+ sage: type(K.order(5*t).conductor())
1299
+ <class 'sage.rings.integer.Integer'>
1300
+ """
1301
+ if not isinstance(self._K, sage.rings.abc.NumberField_quadratic):
1302
+ raise NotImplementedError('not implemented for number fields of degree != 2')
1303
+ D = self.discriminant()
1304
+ D0 = self._K.discriminant()
1305
+ return (D // D0).sqrt()
1306
+
1307
+ def random_element(self, *args, **kwds):
1308
+ r"""
1309
+ Return a random element of this order.
1310
+
1311
+ INPUT:
1312
+
1313
+ - ``args``, ``kwds`` -- parameters passed to the random
1314
+ integer function. See the documentation for
1315
+ ``ZZ.random_element()`` for details.
1316
+
1317
+ OUTPUT:
1318
+
1319
+ A random element of this order, computed as a random
1320
+ `\ZZ`-linear combination of the basis.
1321
+
1322
+ EXAMPLES::
1323
+
1324
+ sage: x = polygen(ZZ, 'x')
1325
+ sage: K.<a> = NumberField(x^3 + 2)
1326
+ sage: OK = K.ring_of_integers()
1327
+ sage: OK.random_element() # random output
1328
+ -2*a^2 - a - 2
1329
+ sage: OK.random_element(distribution='uniform') # random output
1330
+ -a^2 - 1
1331
+ sage: OK.random_element(-10,10) # random output
1332
+ -10*a^2 - 9*a - 2
1333
+ sage: K.order(a).random_element() # random output
1334
+ a^2 - a - 3
1335
+
1336
+ ::
1337
+
1338
+ sage: K.<z> = CyclotomicField(17)
1339
+ sage: OK = K.ring_of_integers()
1340
+ sage: OK.random_element() # random output
1341
+ z^15 - z^11 - z^10 - 4*z^9 + z^8 + 2*z^7 + z^6
1342
+ - 2*z^5 - z^4 - 445*z^3 - 2*z^2 - 15*z - 2
1343
+ sage: OK.random_element().is_integral()
1344
+ True
1345
+ sage: OK.random_element().parent() is OK
1346
+ True
1347
+
1348
+ A relative example::
1349
+
1350
+ sage: K.<a, b> = NumberField([x^2 + 2, x^2 + 1000*x + 1])
1351
+ sage: OK = K.ring_of_integers()
1352
+ sage: OK.random_element() # random output
1353
+ (42221/2*b + 61/2)*a + 7037384*b + 7041
1354
+ sage: OK.random_element().is_integral() # random output
1355
+ True
1356
+ sage: OK.random_element().parent() is OK # random output
1357
+ True
1358
+
1359
+ An example in a non-maximal order::
1360
+
1361
+ sage: K.<a> = QuadraticField(-3)
1362
+ sage: R = K.ring_of_integers()
1363
+ sage: A = K.order(a)
1364
+ sage: A.index_in(R)
1365
+ 2
1366
+ sage: R.random_element() # random output
1367
+ -39/2*a - 1/2
1368
+ sage: A.random_element() # random output
1369
+ 2*a - 1
1370
+ sage: A.random_element().is_integral()
1371
+ True
1372
+ sage: A.random_element().parent() is A
1373
+ True
1374
+ """
1375
+ return sum([ZZ.random_element(*args, **kwds) * a
1376
+ for a in self.basis()])
1377
+
1378
+ def absolute_degree(self):
1379
+ r"""
1380
+ Return the absolute degree of this order, i.e., the degree of this order over `\ZZ`.
1381
+
1382
+ EXAMPLES::
1383
+
1384
+ sage: x = polygen(ZZ, 'x')
1385
+ sage: K.<a> = NumberField(x^3 + 2)
1386
+ sage: O = K.maximal_order()
1387
+ sage: O.absolute_degree()
1388
+ 3
1389
+ """
1390
+ return self.number_field().absolute_degree()
1391
+
1392
+ def valuation(self, p):
1393
+ r"""
1394
+ Return the `p`-adic valuation on this order.
1395
+
1396
+ EXAMPLES:
1397
+
1398
+ The valuation can be specified with an integer prime `p` that is
1399
+ completely ramified or unramified::
1400
+
1401
+ sage: x = polygen(ZZ, 'x')
1402
+ sage: K.<a> = NumberField(x^2 + 1)
1403
+ sage: O = K.order(2*a)
1404
+ sage: valuations.pAdicValuation(O, 2) # needs sage.geometry.polyhedron
1405
+ 2-adic valuation
1406
+
1407
+ sage: GaussianIntegers().valuation(2) # needs sage.geometry.polyhedron
1408
+ 2-adic valuation
1409
+
1410
+ ::
1411
+
1412
+ sage: GaussianIntegers().valuation(3) # needs sage.geometry.polyhedron
1413
+ 3-adic valuation
1414
+
1415
+ A prime `p` that factors into pairwise distinct factors, results in an error::
1416
+
1417
+ sage: GaussianIntegers().valuation(5) # needs sage.geometry.polyhedron
1418
+ Traceback (most recent call last):
1419
+ ...
1420
+ ValueError: The valuation Gauss valuation induced by 5-adic valuation does not
1421
+ approximate a unique extension of 5-adic valuation with respect to x^2 + 1
1422
+
1423
+ The valuation can also be selected by giving a valuation on the base
1424
+ ring that extends uniquely::
1425
+
1426
+ sage: CyclotomicField(5).ring_of_integers().valuation(ZZ.valuation(5)) # needs sage.geometry.polyhedron
1427
+ 5-adic valuation
1428
+
1429
+ When the extension is not unique, this does not work::
1430
+
1431
+ sage: GaussianIntegers().valuation(ZZ.valuation(5)) # needs sage.geometry.polyhedron
1432
+ Traceback (most recent call last):
1433
+ ...
1434
+ ValueError: The valuation Gauss valuation induced by 5-adic valuation does not
1435
+ approximate a unique extension of 5-adic valuation with respect to x^2 + 1
1436
+
1437
+ If the fraction field is of the form `K[x]/(G)`, you can specify a
1438
+ valuation by providing a discrete pseudo-valuation on `K[x]` which
1439
+ sends `G` to infinity::
1440
+
1441
+ sage: # needs sage.geometry.polyhedron
1442
+ sage: R.<x> = QQ[]
1443
+ sage: GV5 = GaussValuation(R, QQ.valuation(5))
1444
+ sage: v = GaussianIntegers().valuation(GV5.augmentation(x + 2, infinity))
1445
+ sage: w = GaussianIntegers().valuation(GV5.augmentation(x + 1/2, infinity))
1446
+ sage: v == w
1447
+ False
1448
+
1449
+ .. SEEALSO::
1450
+
1451
+ :meth:`NumberField_generic.valuation() <sage.rings.number_field.number_field.NumberField_generic.valuation>`,
1452
+ :meth:`pAdicGeneric.valuation() <sage.rings.padics.padic_generic.pAdicGeneric.valuation>`
1453
+ """
1454
+ from sage.rings.padics.padic_valuation import pAdicValuation
1455
+ return pAdicValuation(self, p)
1456
+
1457
+ def some_elements(self):
1458
+ """
1459
+ Return a list of elements of the given order.
1460
+
1461
+ EXAMPLES::
1462
+
1463
+ sage: G = GaussianIntegers(); G
1464
+ Gaussian Integers generated by I in Number Field in I with defining polynomial x^2 + 1 with I = 1*I
1465
+ sage: G.some_elements()
1466
+ [1, I, 2*I, -1, 0, -I, 2, 4*I, -2, -2*I, -4]
1467
+
1468
+ sage: R.<t> = QQ[]
1469
+ sage: K.<a> = QQ.extension(t^3 - 2); K
1470
+ Number Field in a with defining polynomial t^3 - 2
1471
+ sage: Z = K.ring_of_integers(); Z
1472
+ Maximal Order generated by a in Number Field in a with defining polynomial t^3 - 2
1473
+ sage: Z.some_elements()
1474
+ [1, a, a^2, 2*a, 0, 2, a^2 + 2*a + 1, ..., a^2 + 1, 2*a^2 + 2, a^2 + 2*a, 4*a^2 + 4]
1475
+
1476
+ TESTS:
1477
+
1478
+ This also works for trivial extensions::
1479
+
1480
+ sage: R.<t> = QQ[]
1481
+ sage: K.<a> = QQ.extension(t); K
1482
+ Number Field in a with defining polynomial t
1483
+ sage: Z = K.ring_of_integers(); Z
1484
+ Maximal Order generated by [] in Number Field in a with defining polynomial t
1485
+ sage: Z.some_elements()
1486
+ [1, 0, 2, -1, -2, 4]
1487
+ """
1488
+ elements = list(self.basis())
1489
+ for a in self.fraction_field().some_elements():
1490
+ if a in self and a not in elements:
1491
+ elements.append(self(a))
1492
+ return elements
1493
+
1494
+ # def absolute_polynomial(self):
1495
+ # """
1496
+ # Return the absolute polynomial of this order, which is just the absolute polynomial of the number field.
1497
+
1498
+ # EXAMPLES::
1499
+
1500
+ # sage: K.<a, b> = NumberField([x^2 + 1, x^3 + x + 1]); OK = K.maximal_order()
1501
+ # Traceback (most recent call last):
1502
+ # ...
1503
+ # NotImplementedError
1504
+
1505
+ # #sage: OK.absolute_polynomial()
1506
+ # #x^6 + 5*x^4 - 2*x^3 + 4*x^2 + 4*x + 1
1507
+ # """
1508
+ # return self.number_field().absolute_polynomial()
1509
+
1510
+ # def polynomial(self):
1511
+ # """
1512
+ # Return the polynomial defining the number field that contains self.
1513
+ # """
1514
+ # return self.number_field().polynomial()
1515
+
1516
+ # def polynomial_ntl(self):
1517
+ # """
1518
+ # Return defining polynomial of the parent number field as a
1519
+ # pair, an ntl polynomial and a denominator.
1520
+
1521
+ # This is used mainly to implement some internal arithmetic.
1522
+
1523
+ # EXAMPLES::
1524
+
1525
+ # sage: NumberField(x^2 + 1,'a').maximal_order().polynomial_ntl()
1526
+ # ([1 0 1], 1)
1527
+ # """
1528
+ # return self.number_field().polynomial_ntl()
1529
+
1530
+
1531
+ class Order_absolute(Order):
1532
+ def __init__(self, K, module_rep):
1533
+ """
1534
+ EXAMPLES::
1535
+
1536
+ sage: from sage.rings.number_field.order import *
1537
+ sage: x = polygen(QQ)
1538
+ sage: K.<a> = NumberField(x^3 + 2)
1539
+ sage: V, from_v, to_v = K.vector_space()
1540
+ sage: M = span([to_v(a^2), to_v(a), to_v(1)],ZZ)
1541
+ sage: O = AbsoluteOrder(K, M); O
1542
+ Maximal Order generated by a in Number Field in a with defining polynomial x^3 + 2
1543
+
1544
+ sage: M = span([to_v(a^2), to_v(a), to_v(2)],ZZ)
1545
+ sage: O = AbsoluteOrder(K, M); O
1546
+ Traceback (most recent call last):
1547
+ ...
1548
+ ValueError: 1 is not in the span of the module, hence not an order
1549
+
1550
+ TESTS::
1551
+
1552
+ sage: loads(dumps(O)) is O
1553
+ True
1554
+ sage: TestSuite(O).run()
1555
+ """
1556
+ if K.degree() == 2:
1557
+ self._element_type = OrderElement_quadratic
1558
+ # adding the following attribute makes the comparison of elements
1559
+ # faster.
1560
+ self._standard_embedding = K._standard_embedding
1561
+ else:
1562
+ self._element_type = OrderElement_absolute
1563
+
1564
+ # Whether this order is the maximal order, or None if we have not found out yet.
1565
+ self.__is_maximal = None
1566
+ # Maps each prime to whether this order is maximal at that prime.
1567
+ self.__is_maximal_at = {}
1568
+
1569
+ self._module_rep = module_rep
1570
+ Order.__init__(self, K)
1571
+
1572
+ if self.absolute_degree() == 2:
1573
+ self.discriminant() # cache
1574
+
1575
+ def _element_constructor_(self, x):
1576
+ r"""
1577
+ Coerce ``x`` into this order.
1578
+
1579
+ EXAMPLES::
1580
+
1581
+ sage: x = polygen(QQ)
1582
+ sage: k.<z> = NumberField(x^2 - 389)
1583
+ sage: m = k.order(3*z); m
1584
+ Order of conductor 6 generated by 3*z in Number Field in z with defining polynomial x^2 - 389
1585
+ sage: m(6*z)
1586
+ 6*z
1587
+ sage: k(m(6*z))
1588
+ 6*z
1589
+
1590
+ If ``x`` is a list or tuple the element constructed is the
1591
+ linear combination of the generators with these coefficients
1592
+ (see :issue:`10017`)::
1593
+
1594
+ sage: x = polygen(QQ)
1595
+ sage: K.<a> = NumberField(x^3 - 10)
1596
+ sage: ZK = K.ring_of_integers()
1597
+ sage: ZK.basis()
1598
+ [1/3*a^2 + 1/3*a + 1/3, a, a^2]
1599
+ sage: ZK([1,2,3])
1600
+ 10/3*a^2 + 7/3*a + 1/3
1601
+ sage: K([1,2,3])
1602
+ 3*a^2 + 2*a + 1
1603
+ """
1604
+ if isinstance(x, (tuple, list)):
1605
+ x = sum(xi * gi for xi, gi in zip(x, self.gens()))
1606
+ if not isinstance(x, Element) or x.parent() is not self._K:
1607
+ x = self._K(x)
1608
+ V, _, embedding = self._K.vector_space()
1609
+ if embedding(x) not in self._module_rep:
1610
+ raise TypeError("Not an element of the order.")
1611
+ return self._element_type(self, x)
1612
+
1613
+ def __add__(left, right):
1614
+ """
1615
+ Add two orders.
1616
+
1617
+ EXAMPLES::
1618
+
1619
+ sage: K.<a> = NumberField(polygen(QQ,'z')^3 - 2)
1620
+ sage: O6 = K.order(6*a); O6
1621
+ Order generated by 6*a in Number Field in a with defining polynomial z^3 - 2
1622
+ sage: O6.basis()
1623
+ [1, 6*a, 36*a^2]
1624
+ sage: O15 = K.order(15*a^2); O15.basis()
1625
+ [1, 450*a, 15*a^2]
1626
+ sage: R = O6 + O15; R
1627
+ Order generated by [6*a, 3*a^2] in Number Field in a with defining polynomial z^3 - 2
1628
+ sage: R.basis()
1629
+ [1, 6*a, 3*a^2]
1630
+ """
1631
+ if not isinstance(right, Order_absolute):
1632
+ raise NotImplementedError("cannot add these orders yet")
1633
+
1634
+ if left.number_field() != right.number_field():
1635
+ raise TypeError("number fields do not match")
1636
+
1637
+ if left._is_maximal():
1638
+ return left
1639
+
1640
+ elif right._is_maximal():
1641
+ return right
1642
+
1643
+ return AbsoluteOrder(left._K, left._module_rep + right._module_rep)
1644
+
1645
+ def __and__(left, right):
1646
+ """
1647
+ Intersect orders.
1648
+
1649
+ EXAMPLES::
1650
+
1651
+ sage: K.<i> = QuadraticField(-1)
1652
+ sage: O3 = K.order(3*i); O5 = K.order(5*i)
1653
+ sage: R = O3 & O5; R
1654
+ Order of conductor 15 generated by 15*i in Number Field in i with defining polynomial x^2 + 1 with i = 1*I
1655
+ sage: R.basis()
1656
+ [1, 15*i]
1657
+ sage: O3.intersection(O5).basis()
1658
+ [1, 15*i]
1659
+
1660
+ TESTS:
1661
+
1662
+ Verify that :issue:`33386` has been resolved::
1663
+
1664
+ sage: (K.maximal_order() & K.maximal_order()).is_maximal()
1665
+ True
1666
+
1667
+ Verify that an absolute order can be intersected with a relative order::
1668
+
1669
+ sage: x = polygen(ZZ, 'x')
1670
+ sage: L.<a> = K.extension(x^2 - 2)
1671
+ sage: L.absolute_field('z').maximal_order() & L.maximal_order()
1672
+ Maximal Order generated by [7/12*z^3 + 3/4*z^2 + 1/12*z + 1/4, 1/6*z^3 + 1/6*z, z^2] in Number Field in z with defining polynomial x^4 - 2*x^2 + 9
1673
+ sage: L.maximal_order() & L.absolute_field('z').maximal_order()
1674
+ Maximal Order generated by [7/12*z^3 + 3/4*z^2 + 1/12*z + 1/4, 1/6*z^3 + 1/6*z, z^2] in Number Field in z with defining polynomial x^4 - 2*x^2 + 9
1675
+ """
1676
+ if isinstance(right, Order_relative):
1677
+ return right & left
1678
+
1679
+ if left.number_field() != right.number_field():
1680
+ raise TypeError("number fields do not match")
1681
+
1682
+ is_maximal = None
1683
+
1684
+ # Note that this is not correct while orders created with
1685
+ # non-maximal-non-unique are still around. Once that deprecation has
1686
+ # been removed, these simple rules can be enabled.
1687
+ # if left._is_maximal() is True and right._is_maximal() is True:
1688
+ # is_maximal = True
1689
+ # if left._is_maximal() is False or right._is_maximal() is False:
1690
+ # is_maximal = False
1691
+
1692
+ return AbsoluteOrder(left._K, left._module_rep.intersection(right._module_rep), is_maximal=is_maximal)
1693
+
1694
+ def _magma_init_(self, magma):
1695
+ """
1696
+ Return Magma version of this absolute order.
1697
+
1698
+ INPUT:
1699
+
1700
+ - ``magma`` -- a magma interpreter
1701
+
1702
+ OUTPUT: a :class:`MagmaElement`, the magma version of this absolute order
1703
+
1704
+ EXAMPLES::
1705
+
1706
+ sage: x = polygen(ZZ, 'x')
1707
+ sage: K.<a> = NumberField(x^3 + 2) # optional - magma
1708
+ sage: magma(K.maximal_order()) # optional - magma
1709
+ Equation Order with defining polynomial x^3 + 2 over its ground order
1710
+
1711
+ _magma_init_ was called implicitly by the above call::
1712
+
1713
+ sage: K.maximal_order()._magma_init_(magma) # optional - magma
1714
+ 'Order([(_sage_[...]![1, 0, 0]),(_sage_[...]![0, 1, 0]),(_sage_[...]![0, 0, 1])])'
1715
+ """
1716
+ K = self.number_field()
1717
+ v = (K(a)._magma_init_(magma) for a in self.basis())
1718
+ return 'Order([{}])'.format(','.join(v))
1719
+
1720
+ def discriminant(self):
1721
+ """
1722
+ Return the discriminant of this order.
1723
+
1724
+ EXAMPLES::
1725
+
1726
+ sage: x = polygen(ZZ, 'x')
1727
+ sage: K.<a> = NumberField(x^8 + x^3 - 13*x + 26)
1728
+ sage: O = K.maximal_order()
1729
+ sage: factor(O.discriminant())
1730
+ 3 * 11 * 13^2 * 613 * 1575917857
1731
+ sage: L = K.order(13*a^2)
1732
+ sage: factor(L.discriminant())
1733
+ 3^3 * 5^2 * 11 * 13^60 * 613 * 733^2 * 1575917857
1734
+ sage: factor(L.index_in(O))
1735
+ 3 * 5 * 13^29 * 733
1736
+ sage: L.discriminant() / O.discriminant() == L.index_in(O)^2
1737
+ True
1738
+
1739
+ TESTS::
1740
+
1741
+ sage: type(K.order(5*a).discriminant())
1742
+ <class 'sage.rings.integer.Integer'>
1743
+ """
1744
+ try:
1745
+ return self.__discriminant
1746
+ except AttributeError:
1747
+ if self._is_maximal():
1748
+ D = self._K.discriminant()
1749
+ else:
1750
+ D = ZZ(self._K.discriminant(self.basis()))
1751
+ self.__discriminant = D
1752
+ return D
1753
+
1754
+ absolute_discriminant = discriminant
1755
+
1756
+ def is_maximal(self, p=None):
1757
+ """
1758
+ Return whether this is the maximal order.
1759
+
1760
+ INPUT:
1761
+
1762
+ - ``p`` -- integer prime or ``None`` (default: ``None``); if
1763
+ set, return whether this order is maximal at the prime `p`
1764
+
1765
+ EXAMPLES::
1766
+
1767
+ sage: x = polygen(ZZ, 'x')
1768
+ sage: K.<i> = NumberField(x^2 + 1)
1769
+
1770
+ sage: K.order(3*i).is_maximal()
1771
+ False
1772
+ sage: K.order(5*i).is_maximal()
1773
+ False
1774
+ sage: (K.order(3*i) + K.order(5*i)).is_maximal()
1775
+ True
1776
+ sage: K.maximal_order().is_maximal()
1777
+ True
1778
+
1779
+ Maximality can be checked at primes when the order is maximal at that
1780
+ prime by construction::
1781
+
1782
+ sage: K.maximal_order().is_maximal(p=3)
1783
+ True
1784
+
1785
+ And also at other primes::
1786
+
1787
+ sage: K.order(3*i).is_maximal(p=3)
1788
+ False
1789
+
1790
+ An example involving a relative order::
1791
+
1792
+ sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 3])
1793
+ sage: O = K.order([3*a, 2*b])
1794
+ sage: O.is_maximal()
1795
+ False
1796
+ """
1797
+ if self._is_maximal() is True:
1798
+ return True
1799
+
1800
+ if p is None:
1801
+ if self._is_maximal() is None:
1802
+ self._assume_maximal(self.absolute_discriminant() == self._K.absolute_discriminant())
1803
+ return self._is_maximal()
1804
+ else:
1805
+ p = ZZ(p).abs()
1806
+
1807
+ if self._is_maximal_at(p) is None:
1808
+ is_maximal = self._K.maximal_order(p, assume_maximal=None).absolute_discriminant().valuation(p) == self.absolute_discriminant().valuation(p)
1809
+ self._assume_maximal(is_maximal, p=p)
1810
+
1811
+ return self._is_maximal_at(p)
1812
+
1813
+ def _is_maximal(self):
1814
+ r"""
1815
+ Return whether this order is already known to be maximal.
1816
+
1817
+ Used by :meth:`is_maximal`.
1818
+
1819
+ EXAMPLES::
1820
+
1821
+ sage: x = polygen(ZZ, 'x')
1822
+ sage: K.<t> = NumberField(x^3 + x + 1)
1823
+ sage: K.order(1337*t)._is_maximal() is None
1824
+ True
1825
+ sage: K.order(1337*t).is_maximal()
1826
+ False
1827
+ sage: K.order(1337*t)._is_maximal()
1828
+ False
1829
+ """
1830
+ return self.__is_maximal
1831
+
1832
+ def _is_maximal_at(self, p=None):
1833
+ r"""
1834
+ Return whether this order is already known to be maximal at ``p``.
1835
+
1836
+ When no ``p`` is specified, returns a dictionary of primes for which
1837
+ maximality is known.
1838
+
1839
+ Used by :meth:`is_maximal`.
1840
+
1841
+ EXAMPLES::
1842
+
1843
+ sage: x = polygen(ZZ, 'x')
1844
+ sage: K.<a> = NumberField(x^13 - 2)
1845
+
1846
+ sage: O = K.order(a)
1847
+ sage: O._is_maximal_at(p=1361) is None
1848
+ True
1849
+ sage: O._assume_maximal(p=1361) is O
1850
+ True
1851
+ sage: K.order(a).is_maximal(p=1361)
1852
+ True
1853
+ sage: K.order(a)._is_maximal_at(p=1361)
1854
+ True
1855
+
1856
+ TESTS::
1857
+
1858
+ sage: L.<a, b> = NumberField([x^2 - 1000005, x^2 - 5*1000099^2])
1859
+ sage: K = L.absolute_field('c')
1860
+ sage: O = K.maximal_order([13], assume_maximal=None)
1861
+ sage: O._is_maximal_at()
1862
+ {13: True}
1863
+ """
1864
+ if p is None:
1865
+ return dict(self.__is_maximal_at)
1866
+
1867
+ p = ZZ(p).abs()
1868
+ return self.__is_maximal_at.get(p, None)
1869
+
1870
+ def _assume_maximal(self, is_maximal=True, p=None):
1871
+ r"""
1872
+ Record that this order ``is_maximal`` at the integer prime ``p``.
1873
+
1874
+ To support the deprecated behavior for
1875
+ ``is_maximal="non-maximal-non-unique"``, this returns an order.
1876
+ Typically, the order itself.
1877
+
1878
+ EXAMPLES::
1879
+
1880
+ sage: x = polygen(ZZ, 'x')
1881
+ sage: K.<a> = NumberField(x^4 - 10001822082820*x^2 + 25009091240356266913960000)
1882
+ sage: O = K.maximal_order([13], assume_maximal=None)
1883
+
1884
+ We can store information about more primes::
1885
+
1886
+ sage: O._is_maximal_at(p=7) is None
1887
+ True
1888
+ sage: 7.divides(K.absolute_discriminant())
1889
+ False
1890
+ sage: O._assume_maximal(p=7) is O
1891
+ True
1892
+ sage: O._is_maximal_at(p=7)
1893
+ True
1894
+
1895
+ We cannot store contradicting information at a prime::
1896
+
1897
+ sage: O._assume_maximal(p=7, is_maximal=False)
1898
+ Traceback (most recent call last):
1899
+ ...
1900
+ ValueError: cannot assume this order to be non-maximal at 7 because we already found it to be maximal at that prime
1901
+
1902
+ We can safely store information that we know to be wrong to support
1903
+ legacy behavior of orders that are assumed to be only maximal at some
1904
+ primes::
1905
+
1906
+ sage: K.<i> = NumberField(x^2 + 1)
1907
+ sage: O = K.order(1+i)
1908
+ sage: O.is_maximal()
1909
+ True
1910
+ sage: N = O._assume_maximal(is_maximal='non-maximal-non-unique')
1911
+ sage: N._assume_maximal(p=2) is N
1912
+ True
1913
+ sage: N is O
1914
+ False
1915
+ sage: N == O
1916
+ True
1917
+ sage: N.is_maximal()
1918
+ False
1919
+ sage: N.is_maximal(p=2)
1920
+ True
1921
+ """
1922
+ if is_maximal is None:
1923
+ # No assumption made, return the object unchanged.
1924
+ return self
1925
+
1926
+ if p is None:
1927
+ if is_maximal == "non-maximal-non-unique":
1928
+ # We force this order to be non-maximal to support legacy code that
1929
+ # could create such orders.
1930
+ self = type(self)(self._K, self._module_rep)
1931
+ self.__is_maximal = False
1932
+ elif is_maximal:
1933
+ if self._is_maximal() is False:
1934
+ raise ValueError("cannot assume this order to be maximal because we already found it to be a non-maximal order")
1935
+ self.__is_maximal = True
1936
+ # No need to keep information at specific primes anymore.
1937
+ self.__is_maximal_at = {}
1938
+ else:
1939
+ if self._is_maximal() is True:
1940
+ raise ValueError("cannot assume this order to be non-maximal because we already found it to be a maximal order")
1941
+ self.__is_maximal = False
1942
+ else:
1943
+ p = ZZ(p).abs()
1944
+
1945
+ if is_maximal == "non-maximal-non-unique":
1946
+ raise NotImplementedError("legacy support for explicitly non-maximal orders only possible at all primes")
1947
+ elif is_maximal:
1948
+ if self._is_maximal_at(p) is False:
1949
+ raise ValueError(f"cannot assume this order to be maximal at {p} because we already found it to be non-maximal at that prime")
1950
+ self.__is_maximal_at[p] = True
1951
+ else:
1952
+ if self._is_maximal_at(p) is True:
1953
+ raise ValueError(f"cannot assume this order to be non-maximal at {p} because we already found it to be maximal at that prime")
1954
+
1955
+ self._assume_maximal(False)
1956
+ self.__is_maximal_at[p] = False
1957
+
1958
+ return self
1959
+
1960
+ def change_names(self, names):
1961
+ """
1962
+ Return a new order isomorphic to this one in the number field with
1963
+ given variable names.
1964
+
1965
+ EXAMPLES::
1966
+
1967
+ sage: x = polygen(ZZ, 'x')
1968
+ sage: R = EquationOrder(x^3 + x + 1, 'alpha'); R
1969
+ Order generated by alpha in Number Field in alpha with defining polynomial x^3 + x + 1
1970
+ sage: R.basis()
1971
+ [1, alpha, alpha^2]
1972
+ sage: S = R.change_names('gamma'); S
1973
+ Order generated by gamma in Number Field in gamma with defining polynomial x^3 + x + 1
1974
+ sage: S.basis()
1975
+ [1, gamma, gamma^2]
1976
+ """
1977
+ K = self.number_field().change_names(names)
1978
+ _, to_K = K.structure()
1979
+ B = [to_K(a) for a in self.basis()]
1980
+ return K.order(B, check_is_integral=False, check_rank=False, allow_subfield=True)
1981
+
1982
+ def index_in(self, other):
1983
+ """
1984
+ Return the index of ``self`` in ``other``.
1985
+
1986
+ This is a lattice index,
1987
+ so it is a rational number if ``self`` is not contained in ``other``.
1988
+
1989
+ INPUT:
1990
+
1991
+ - ``other`` -- another absolute order with the same ambient number field
1992
+
1993
+ OUTPUT: a rational number
1994
+
1995
+ EXAMPLES::
1996
+
1997
+ sage: x = polygen(ZZ, 'x')
1998
+ sage: k.<i> = NumberField(x^2 + 1)
1999
+ sage: O1 = k.order(i)
2000
+ sage: O5 = k.order(5*i)
2001
+ sage: O5.index_in(O1)
2002
+ 5
2003
+
2004
+ sage: k.<a> = NumberField(x^3 + x^2 - 2*x+8)
2005
+ sage: o = k.maximal_order()
2006
+ sage: o
2007
+ Maximal Order generated by [1/2*a^2 + 1/2*a, a^2] in Number Field in a with defining polynomial x^3 + x^2 - 2*x + 8
2008
+ sage: O1 = k.order(a); O1
2009
+ Order generated by a in Number Field in a with defining polynomial x^3 + x^2 - 2*x + 8
2010
+ sage: O1.index_in(o)
2011
+ 2
2012
+ sage: O2 = k.order(1+2*a); O2
2013
+ Order generated by 2*a in Number Field in a with defining polynomial x^3 + x^2 - 2*x + 8
2014
+ sage: O1.basis()
2015
+ [1, a, a^2]
2016
+ sage: O2.basis()
2017
+ [1, 2*a, 4*a^2]
2018
+ sage: o.index_in(O2)
2019
+ 1/16
2020
+ """
2021
+ if not isinstance(other, Order_absolute):
2022
+ raise TypeError("other must be an absolute order.")
2023
+ if other.ambient() != self.ambient():
2024
+ raise ValueError("other must have the same ambient number field as self.")
2025
+ return self._module_rep.index_in(other._module_rep)
2026
+
2027
+ def module(self):
2028
+ """
2029
+ Return the underlying free module corresponding to this
2030
+ order, embedded in the vector space corresponding to the
2031
+ ambient number field.
2032
+
2033
+ EXAMPLES::
2034
+
2035
+ sage: x = polygen(ZZ, 'x')
2036
+ sage: k.<a> = NumberField(x^3 + x + 3)
2037
+ sage: m = k.order(3*a); m
2038
+ Order generated by 3*a in Number Field in a with defining polynomial x^3 + x + 3
2039
+ sage: m.module()
2040
+ Free module of degree 3 and rank 3 over Integer Ring
2041
+ Echelon basis matrix:
2042
+ [1 0 0]
2043
+ [0 3 0]
2044
+ [0 0 9]
2045
+ """
2046
+ return self._module_rep
2047
+
2048
+ def intersection(self, other):
2049
+ """
2050
+ Return the intersection of this order with another order.
2051
+
2052
+ EXAMPLES::
2053
+
2054
+ sage: x = polygen(ZZ, 'x')
2055
+ sage: k.<i> = NumberField(x^2 + 1)
2056
+ sage: O6 = k.order(6*i)
2057
+ sage: O9 = k.order(9*i)
2058
+ sage: O6.basis()
2059
+ [1, 6*i]
2060
+ sage: O9.basis()
2061
+ [1, 9*i]
2062
+ sage: O6.intersection(O9).basis()
2063
+ [1, 18*i]
2064
+ sage: (O6 & O9).basis()
2065
+ [1, 18*i]
2066
+ sage: (O6 + O9).basis()
2067
+ [1, 3*i]
2068
+ """
2069
+ return self & other
2070
+
2071
+ def _repr_(self):
2072
+ """
2073
+ Return print representation of this absolute order.
2074
+
2075
+ EXAMPLES::
2076
+
2077
+ sage: x = polygen(ZZ, 'x')
2078
+ sage: K.<a> = NumberField(x^4 - 5)
2079
+ sage: K.maximal_order()._repr_()
2080
+ 'Maximal Order generated by [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a] in Number Field in a with defining polynomial x^4 - 5'
2081
+ sage: K.order(a)._repr_()
2082
+ 'Order generated by a in Number Field in a with defining polynomial x^4 - 5'
2083
+
2084
+ We have special cases for Gaussian and Eisenstein integers::
2085
+
2086
+ sage: K = CyclotomicField(4)
2087
+ sage: K.ring_of_integers()
2088
+ Gaussian Integers generated by zeta4 in Cyclotomic Field of order 4 and degree 2
2089
+ sage: K = QuadraticField(-3)
2090
+ sage: K.ring_of_integers()
2091
+ Eisenstein Integers generated by 1/2*a + 1/2 in Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
2092
+ """
2093
+ if self._is_maximal():
2094
+ s = "Maximal Order"
2095
+ if self.degree() == 2:
2096
+ D = self.discriminant()
2097
+ if D == -3:
2098
+ s = "Eisenstein Integers"
2099
+ if D == -4:
2100
+ s = "Gaussian Integers"
2101
+ else:
2102
+ s = "Order"
2103
+ if self.number_field().absolute_degree() == 2:
2104
+ f = self.conductor()
2105
+ s += f' of conductor {f}'
2106
+ try:
2107
+ gens = self.ring_generators()
2108
+ except TypeError:
2109
+ gens = self.gens()
2110
+ s += f' generated by {gens[0] if len(gens) == 1 else "[" + ", ".join(map(str, gens)) + "]"}'
2111
+ s += f' in {self._K}'
2112
+ return s
2113
+
2114
+ def basis(self):
2115
+ r"""
2116
+ Return the basis over `\ZZ` for this order.
2117
+
2118
+ EXAMPLES::
2119
+
2120
+ sage: x = polygen(ZZ, 'x')
2121
+ sage: k.<c> = NumberField(x^3 + x^2 + 1)
2122
+ sage: O = k.maximal_order(); O
2123
+ Maximal Order generated by c in Number Field in c with defining polynomial x^3 + x^2 + 1
2124
+ sage: O.basis()
2125
+ [1, c, c^2]
2126
+
2127
+ The basis is an immutable sequence::
2128
+
2129
+ sage: type(O.basis())
2130
+ <class 'sage.structure.sequence.Sequence_generic'>
2131
+
2132
+ The generator functionality uses the basis method::
2133
+
2134
+ sage: O.0
2135
+ 1
2136
+ sage: O.1
2137
+ c
2138
+ sage: O.basis()
2139
+ [1, c, c^2]
2140
+ sage: O.ngens()
2141
+ 3
2142
+ """
2143
+ try:
2144
+ return self.__basis
2145
+ except AttributeError:
2146
+ V, from_V, to_V = self._K.vector_space()
2147
+ B = Sequence([self(from_V(b)) for b in self._module_rep.basis()], immutable=True)
2148
+ self.__basis = B
2149
+ return B
2150
+
2151
+ def absolute_order(self):
2152
+ """
2153
+ Return the absolute order associated to this order, which is
2154
+ just this order again since this is an absolute order.
2155
+
2156
+ EXAMPLES::
2157
+
2158
+ sage: x = polygen(ZZ, 'x')
2159
+ sage: K.<a> = NumberField(x^3 + 2)
2160
+ sage: O1 = K.order(a); O1
2161
+ Maximal Order generated by a in Number Field in a with defining polynomial x^3 + 2
2162
+ sage: O1.absolute_order() is O1
2163
+ True
2164
+ """
2165
+ return self
2166
+
2167
+
2168
+ class Order_relative(Order):
2169
+ """
2170
+ A relative order in a number field.
2171
+
2172
+ A relative order is an order in some relative number field.
2173
+
2174
+ Invariants of this order may be computed with respect to the
2175
+ contained order.
2176
+ """
2177
+
2178
+ def __init__(self, K, absolute_order):
2179
+ """
2180
+ Create the relative order.
2181
+
2182
+ EXAMPLES::
2183
+
2184
+ sage: x = polygen(ZZ, 'x')
2185
+ sage: k.<a,b> = NumberFieldTower([x^2 - 3, x^2 + 1])
2186
+ sage: O = k.maximal_order(); O # indirect doctest
2187
+ Maximal Relative Order generated by 1/2*a - 1/2*b in Number Field in a with defining polynomial x^2 - 3 over its base field
2188
+
2189
+ sage: _ = O.basis()
2190
+
2191
+ TESTS::
2192
+
2193
+ sage: loads(dumps(O)) is O
2194
+ True
2195
+ sage: TestSuite(O).run()
2196
+ """
2197
+ self._absolute_order = absolute_order
2198
+ self._module_rep = absolute_order._module_rep
2199
+
2200
+ Order.__init__(self, K)
2201
+
2202
+ def _element_constructor_(self, x):
2203
+ """
2204
+ Coerce an element into this relative order.
2205
+
2206
+ EXAMPLES::
2207
+
2208
+ sage: x = polygen(ZZ, 'x')
2209
+ sage: K.<a, b> = NumberField([x^2 + 2, x^2 + 1000*x + 1])
2210
+ sage: OK = K.ring_of_integers()
2211
+ sage: OK(a)
2212
+ a
2213
+ sage: OK([3, 4])
2214
+ 4*a + 3
2215
+
2216
+ The following used to fail; see :issue:`5276`::
2217
+
2218
+ sage: S.<y> = OK[]; S
2219
+ Univariate Polynomial Ring in y over Maximal Relative Order generated by [(-5787/2*b - 9/2)*a - 964565*b - 965, (-1500*b - 2)*a - 499997*b - 500] in Number Field in a with defining polynomial x^2 + 2 over its base field
2220
+
2221
+ We test that :issue:`4193` is also fixed::
2222
+
2223
+ sage: K1.<a> = NumberField(x^3 - 2)
2224
+ sage: R.<y> = PolynomialRing(K1)
2225
+ sage: K2.<b> = K1.extension(y^2 - a)
2226
+ sage: R = K2.order(b)
2227
+ sage: b in R
2228
+ True
2229
+ sage: bb = R.basis()[1] # b by any other name
2230
+ sage: bb == b
2231
+ True
2232
+ sage: bb.parent() is R
2233
+ True
2234
+ sage: bb in R # this used to return False
2235
+ True
2236
+ sage: R(bb) == bb # this used to raise an error
2237
+ True
2238
+ """
2239
+
2240
+ x = self._K(x)
2241
+ abs_order = self._absolute_order
2242
+ to_abs = abs_order._K.structure()[1]
2243
+ x = abs_order(to_abs(x)) # will test membership
2244
+ return OrderElement_relative(self, x)
2245
+
2246
+ def _repr_(self):
2247
+ """
2248
+ Return print representation of this relative order.
2249
+
2250
+ EXAMPLES::
2251
+
2252
+ sage: x = polygen(ZZ, 'x')
2253
+ sage: O = EquationOrder([x^2 + x + 1, x^3 - 2],'a,b')
2254
+ sage: O._repr_()
2255
+ 'Relative Order generated by [(-b^2 + 6*b + 11)*a + 3*b^2 + b + 14, (-2*b^2 - 2)*a - 2*b^2 - b, (b + 6)*a + 3*b^2 + 6] in Number Field in a with defining polynomial x^2 + x + 1 over its base field'
2256
+ """
2257
+ s = 'Maximal ' if self._is_maximal() else ''
2258
+ s += 'Relative Order'
2259
+ try:
2260
+ gens = self.ring_generators()
2261
+ except TypeError:
2262
+ gens = self.gens()
2263
+ s += f' generated by {gens[0] if len(gens) == 1 else "[" + ", ".join(map(str, gens)) + "]"}'
2264
+ s += f' in {self._K}'
2265
+ return s
2266
+
2267
+ def absolute_order(self, names='z'):
2268
+ """
2269
+ Return underlying absolute order associated to this relative
2270
+ order.
2271
+
2272
+ INPUT:
2273
+
2274
+ - ``names`` -- string (default: ``'z'``); name of generator of absolute
2275
+ extension
2276
+
2277
+ .. NOTE::
2278
+
2279
+ There *is* a default variable name, since this absolute
2280
+ order is frequently used for internal algorithms.
2281
+
2282
+ EXAMPLES::
2283
+
2284
+ sage: x = polygen(ZZ, 'x')
2285
+ sage: R = EquationOrder([x^2 + 1, x^2 - 5], 'i,g'); R
2286
+ Relative Order generated by [6*i - g, -g*i + 2, 7*i - g] in
2287
+ Number Field in i with defining polynomial x^2 + 1 over its base field
2288
+ sage: R.basis()
2289
+ [1, 6*i - g, -g*i + 2, 7*i - g]
2290
+
2291
+ sage: S = R.absolute_order(); S
2292
+ Order generated by [5/12*z^3 + 1/6*z, 1/2*z^2, 1/2*z^3] in Number Field in z with defining polynomial x^4 - 8*x^2 + 36
2293
+ sage: S.basis()
2294
+ [1, 5/12*z^3 + 1/6*z, 1/2*z^2, 1/2*z^3]
2295
+
2296
+ We compute a relative order in alpha0, alpha1, then make the
2297
+ generator of the number field that contains the absolute order be called
2298
+ gamma.::
2299
+
2300
+ sage: R = EquationOrder( [x^2 + 2, x^2 - 3], 'alpha'); R
2301
+ Relative Order generated by [-alpha1*alpha0 + 1, 5*alpha0 + 2*alpha1, 7*alpha0 + 3*alpha1] in
2302
+ Number Field in alpha0 with defining polynomial x^2 + 2 over its base field
2303
+ sage: R.absolute_order('gamma')
2304
+ Order generated by [1/2*gamma^2 + 1/2, 7/10*gamma^3 + 1/10*gamma, gamma^3] in Number Field in gamma with defining polynomial x^4 - 2*x^2 + 25
2305
+ sage: R.absolute_order('gamma').basis()
2306
+ [1/2*gamma^2 + 1/2, 7/10*gamma^3 + 1/10*gamma, gamma^2, gamma^3]
2307
+ """
2308
+ if names == 'z' or names == ('z',):
2309
+ return self._absolute_order
2310
+ else:
2311
+ return self._absolute_order.change_names(names)
2312
+
2313
+ def basis(self):
2314
+ r"""
2315
+ Return a basis for this order as `\ZZ`-module.
2316
+
2317
+ EXAMPLES::
2318
+
2319
+ sage: x = polygen(ZZ, 'x')
2320
+ sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 3])
2321
+ sage: O = K.order([a,b])
2322
+ sage: O.basis()
2323
+ [1, -2*a + b, -b*a - 2, -5*a + 3*b]
2324
+ sage: z = O.1; z
2325
+ -2*a + b
2326
+ sage: z.absolute_minpoly()
2327
+ x^4 + 14*x^2 + 1
2328
+ """
2329
+ try:
2330
+ return self.__basis
2331
+ except AttributeError:
2332
+ pass
2333
+ O = self._absolute_order
2334
+ K = O.number_field()
2335
+ from_K, _ = K.structure()
2336
+ self.__basis = [OrderElement_relative(self, from_K(a)) for a in O.basis()]
2337
+ return self.__basis
2338
+
2339
+ def __add__(left, right):
2340
+ """
2341
+ Add two relative orders or a relative order to an absolute
2342
+ order (which always results in an absolute order).
2343
+
2344
+ EXAMPLES::
2345
+
2346
+ sage: x = polygen(ZZ, 'x')
2347
+ sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 3])
2348
+ sage: O2 = K.order([2*a, b]); O2.absolute_discriminant()
2349
+ 36864
2350
+ sage: O3 = K.order([3*a, 2*b]); O3.absolute_discriminant()
2351
+ 2985984
2352
+ sage: R = O2 + O3; R
2353
+ Relative Order generated by [-2*a + b, -2*b*a - 4, -5*a + 3*b] in Number Field in a with defining polynomial x^2 + 1 over its base field
2354
+ sage: R.absolute_discriminant()
2355
+ 9216
2356
+ sage: R.is_suborder(O2)
2357
+ False
2358
+ sage: O2.is_suborder(R)
2359
+ True
2360
+ sage: O3.is_suborder(R)
2361
+ True
2362
+ """
2363
+ if isinstance(right, Order_absolute):
2364
+ return left._absolute_order + right
2365
+
2366
+ if not isinstance(right, Order_relative):
2367
+ raise NotImplementedError("cannot add these orders yet")
2368
+
2369
+ if left._K != right._K:
2370
+ raise TypeError("number fields do not match")
2371
+
2372
+ if left._is_maximal():
2373
+ return left
2374
+
2375
+ if right._is_maximal():
2376
+ return right
2377
+
2378
+ return RelativeOrder(left._K, left._absolute_order + right._absolute_order, check=False)
2379
+
2380
+ def __and__(left, right):
2381
+ """
2382
+ Intersect two relative orders or a relative and absolute order
2383
+ (which always results in an absolute order).
2384
+
2385
+ EXAMPLES::
2386
+
2387
+ sage: x = polygen(ZZ, 'x')
2388
+ sage: L.<a, b> = NumberField([x^2 + 1, x^2 - 5])
2389
+ sage: O1 = L.order([a, 2*b])
2390
+ sage: O2 = L.order([2*a, b])
2391
+ sage: O3 = O1 & O2; O3
2392
+ Relative Order generated by [12*a - 2*b, -2*b*a + 4, 14*a - 2*b] in Number Field in a with defining polynomial x^2 + 1 over its base field
2393
+ sage: O3.index_in(L.maximal_order())
2394
+ 32
2395
+
2396
+ TESTS:
2397
+
2398
+ Verify that :issue:`33386` has been resolved::
2399
+
2400
+ sage: (L.maximal_order() & L.maximal_order()).is_maximal()
2401
+ True
2402
+ """
2403
+ if isinstance(right, Order_absolute):
2404
+ return left._absolute_order & right
2405
+
2406
+ if not isinstance(right, Order_relative):
2407
+ raise NotImplementedError("cannot intersect these orders yet")
2408
+
2409
+ if left._K != right._K:
2410
+ raise TypeError("number fields do not match")
2411
+
2412
+ return RelativeOrder(left._K, left._absolute_order & right._absolute_order, check=False)
2413
+
2414
+ def is_maximal(self, p=None):
2415
+ """
2416
+ Return whether this is the maximal order.
2417
+
2418
+ INPUT:
2419
+
2420
+ - ``p`` -- integer prime or ``None`` (default: ``None``); if
2421
+ set, return whether this order is maximal at the prime `p`
2422
+
2423
+ EXAMPLES::
2424
+
2425
+ sage: x = polygen(ZZ, 'x')
2426
+ sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 5])
2427
+
2428
+ sage: K.order(3*a, b).is_maximal()
2429
+ False
2430
+ sage: K.order(5*a, b/2 + 1/2).is_maximal()
2431
+ False
2432
+ sage: (K.order(3*a, b) + K.order(5*a, b/2 + 1/2)).is_maximal()
2433
+ True
2434
+ sage: K.maximal_order().is_maximal()
2435
+ True
2436
+
2437
+ Maximality can be checked at primes when the order is maximal at that
2438
+ prime by construction::
2439
+
2440
+ sage: K.maximal_order().is_maximal(p=3)
2441
+ True
2442
+
2443
+ And at other primes::
2444
+
2445
+ sage: K.order(3*a, b).is_maximal(p=3)
2446
+ False
2447
+ """
2448
+ return self._absolute_order.is_maximal(p=p)
2449
+
2450
+ def _is_maximal(self):
2451
+ r"""
2452
+ Return whether this order is already known to be maximal.
2453
+
2454
+ EXAMPLES::
2455
+
2456
+ sage: x = polygen(ZZ, 'x')
2457
+ sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 5])
2458
+ sage: O = K.order(a, b)
2459
+ sage: O._is_maximal() is None
2460
+ True
2461
+ sage: O.is_maximal()
2462
+ False
2463
+ sage: O._is_maximal()
2464
+ False
2465
+ """
2466
+ return self._absolute_order._is_maximal()
2467
+
2468
+ def _is_maximal_at(self, p=None):
2469
+ r"""
2470
+ Return whether this order is already known to be maximal at ``p``.
2471
+
2472
+ When no ``p`` is specified, returns a dictionary of primes for which
2473
+ maximality is known.
2474
+
2475
+ EXAMPLES::
2476
+
2477
+ sage: x = polygen(ZZ, 'x')
2478
+ sage: K.<a, b> = NumberField([x^2 - 2, x^13 - 2])
2479
+ sage: O = K.maximal_order([2, 3, 5], assume_maximal=None)
2480
+ sage: O._is_maximal_at(p=7) is None
2481
+ True
2482
+ sage: O = K.maximal_order([2, 3, 7], assume_maximal=None)
2483
+ sage: O._is_maximal_at(p=5)
2484
+ True
2485
+ sage: O._is_maximal_at(p=7)
2486
+ True
2487
+ sage: O._is_maximal_at()
2488
+ {2: True, 3: True, 5: True, 7: True}
2489
+ """
2490
+ return self._absolute_order._is_maximal_at(p=p)
2491
+
2492
+ def _assume_maximal(self, is_maximal=True, p=None):
2493
+ r"""
2494
+ Record that this order ``is_maximal`` at the integer prime ``p``.
2495
+
2496
+ To support the deprecated behavior for
2497
+ ``is_maximal="non-maximal-non-unique"``, this returns an order.
2498
+ Typically, the order itself.
2499
+
2500
+ EXAMPLES::
2501
+
2502
+ sage: x = polygen(ZZ, 'x')
2503
+ sage: L.<a, b> = NumberField([x^2 - 1000005, x^2 - 5*1000099^2])
2504
+ sage: O = L.maximal_order([13], assume_maximal=None)
2505
+
2506
+ We can store information about more primes::
2507
+
2508
+ sage: O._is_maximal_at(p=7) is None
2509
+ True
2510
+ sage: 7.divides(L.absolute_discriminant())
2511
+ False
2512
+ sage: O._assume_maximal(p=7) is O
2513
+ True
2514
+ sage: O._is_maximal_at(p=7)
2515
+ True
2516
+
2517
+ We cannot store contradicting information at a prime::
2518
+
2519
+ sage: O._assume_maximal(p=7, is_maximal=False)
2520
+ Traceback (most recent call last):
2521
+ ...
2522
+ ValueError: cannot assume this order to be non-maximal at 7 because we already found it to be maximal at that prime
2523
+
2524
+ We can safely store information that we know to be wrong to support
2525
+ legacy behavior of orders that are assumed to be only maximal at some
2526
+ primes::
2527
+
2528
+ sage: L.<a, b> = NumberField([x^2 - 2, x^3 - 2])
2529
+ sage: O = L.maximal_order([2, 3], assume_maximal=None)
2530
+ sage: O.is_maximal()
2531
+ True
2532
+ sage: N = O._assume_maximal(is_maximal='non-maximal-non-unique')
2533
+ sage: N._assume_maximal(p=2) is N
2534
+ True
2535
+ sage: N is O
2536
+ False
2537
+ sage: N == O
2538
+ True
2539
+ sage: N.is_maximal()
2540
+ False
2541
+ sage: N.is_maximal(p=2)
2542
+ True
2543
+ """
2544
+ absolute_order = self._absolute_order._assume_maximal(is_maximal=is_maximal, p=p)
2545
+ if absolute_order is not self._absolute_order:
2546
+ assert is_maximal == "non-maximal-non-unique"
2547
+ self = type(self)(self._K, absolute_order)
2548
+ return self
2549
+
2550
+ def absolute_discriminant(self):
2551
+ """
2552
+ Return the absolute discriminant of ``self``, which is the discriminant
2553
+ of the absolute order associated to ``self``.
2554
+
2555
+ OUTPUT: integer
2556
+
2557
+ EXAMPLES::
2558
+
2559
+ sage: x = polygen(ZZ, 'x')
2560
+ sage: R = EquationOrder([x^2 + 1, x^3 + 2], 'a,b')
2561
+ sage: d = R.absolute_discriminant(); d
2562
+ -746496
2563
+ sage: d is R.absolute_discriminant()
2564
+ True
2565
+ sage: factor(d)
2566
+ -1 * 2^10 * 3^6
2567
+ """
2568
+ return self.absolute_order().discriminant()
2569
+
2570
+ def is_suborder(self, other):
2571
+ """
2572
+ Return ``True`` if ``self`` is a subset of the order ``other``.
2573
+
2574
+ EXAMPLES::
2575
+
2576
+ sage: x = polygen(ZZ, 'x')
2577
+ sage: K.<a,b> = NumberField([x^2 + 1, x^3 + 2])
2578
+ sage: R1 = K.order([a, b])
2579
+ sage: R2 = K.order([2*a, b])
2580
+ sage: R3 = K.order([a + b, b + 2*a])
2581
+ sage: R1.is_suborder(R2)
2582
+ False
2583
+ sage: R2.is_suborder(R1)
2584
+ True
2585
+ sage: R3.is_suborder(R1)
2586
+ True
2587
+ sage: R1.is_suborder(R3)
2588
+ True
2589
+ sage: R1 == R3
2590
+ True
2591
+ """
2592
+ return self.absolute_order().is_suborder(other.absolute_order())
2593
+
2594
+ def index_in(self, other):
2595
+ """
2596
+ Return the index of ``self`` in ``other``.
2597
+
2598
+ This is a lattice index,
2599
+ so it is a rational number if ``self`` is not contained in ``other``.
2600
+
2601
+ INPUT:
2602
+
2603
+ - ``other`` -- another order with the same ambient absolute number field
2604
+
2605
+ OUTPUT: a rational number
2606
+
2607
+ EXAMPLES::
2608
+
2609
+ sage: x = polygen(ZZ, 'x')
2610
+ sage: K.<a,b> = NumberField([x^3 + x + 3, x^2 + 1])
2611
+ sage: R1 = K.order([3*a, 2*b])
2612
+ sage: R2 = K.order([a, 4*b])
2613
+ sage: R1.index_in(R2)
2614
+ 729/8
2615
+ sage: R2.index_in(R1)
2616
+ 8/729
2617
+ """
2618
+ if not isinstance(other, Order):
2619
+ raise TypeError("other must be an absolute order.")
2620
+ return self.absolute_order().index_in(other.absolute_order())
2621
+
2622
+
2623
+ def each_is_integral(v):
2624
+ """
2625
+ Return whether every element of the list ``v`` of elements of a number
2626
+ field is integral.
2627
+
2628
+ EXAMPLES::
2629
+
2630
+ sage: x = polygen(ZZ, 'x')
2631
+ sage: W.<sqrt5> = NumberField(x^2 - 5)
2632
+ sage: from sage.rings.number_field.order import each_is_integral
2633
+ sage: each_is_integral([sqrt5, 2, (1+sqrt5)/2])
2634
+ True
2635
+ sage: each_is_integral([sqrt5, (1+sqrt5)/3])
2636
+ False
2637
+ """
2638
+ return all(x.is_integral() for x in v)
2639
+
2640
+
2641
+ def absolute_order_from_ring_generators(gens, check_is_integral=True,
2642
+ check_rank=True, is_maximal=None,
2643
+ allow_subfield=False):
2644
+ """
2645
+ INPUT:
2646
+
2647
+ - ``gens`` -- list of integral elements of an absolute order
2648
+ - ``check_is_integral`` -- boolean (default: ``True``); whether to check
2649
+ that each generator is integral
2650
+ - ``check_rank`` -- boolean (default: ``True``); whether to check that the
2651
+ ring generated by ``gens`` is of full rank
2652
+ - ``is_maximal`` -- boolean (or ``None``); set if maximality of the
2653
+ generated order is known
2654
+ - ``allow_subfield`` -- boolean (default: ``False``); if ``True`` and the
2655
+ generators do not generate an order, i.e., they generate a subring of
2656
+ smaller rank, instead of raising an error, return an order in a smaller
2657
+ number field
2658
+
2659
+ EXAMPLES::
2660
+
2661
+ sage: x = polygen(ZZ, 'x')
2662
+ sage: K.<a> = NumberField(x^4 - 5)
2663
+ sage: K.order(a)
2664
+ Order generated by a in Number Field in a with defining polynomial x^4 - 5
2665
+
2666
+ We have to explicitly import this function, since typically it is called
2667
+ with ``K.order`` as above.::
2668
+
2669
+ sage: from sage.rings.number_field.order import absolute_order_from_ring_generators
2670
+ sage: absolute_order_from_ring_generators([a])
2671
+ Order generated by a in Number Field in a with defining polynomial x^4 - 5
2672
+ sage: absolute_order_from_ring_generators([3*a, 2, 6*a + 1])
2673
+ Order generated by 3*a in Number Field in a with defining polynomial x^4 - 5
2674
+
2675
+ If one of the inputs is non-integral, it is an error.::
2676
+
2677
+ sage: absolute_order_from_ring_generators([a/2])
2678
+ Traceback (most recent call last):
2679
+ ...
2680
+ ValueError: each generator must be integral
2681
+
2682
+ If the ``gens`` do not generate an order, i.e., generate a ring of full
2683
+ rank, then it is an error.::
2684
+
2685
+ sage: absolute_order_from_ring_generators([a^2])
2686
+ Traceback (most recent call last):
2687
+ ...
2688
+ ValueError: the rank of the span of gens is wrong
2689
+
2690
+ Both checking for integrality and checking for full rank can be
2691
+ turned off in order to save time, though one can get nonsense as
2692
+ illustrated below.::
2693
+
2694
+ sage: absolute_order_from_ring_generators([a/2], check_is_integral=False)
2695
+ Order generated by [1, 1/2*a, 1/4*a^2, 1/8*a^3] in Number Field in a with defining polynomial x^4 - 5
2696
+ sage: absolute_order_from_ring_generators([a^2], check_rank=False)
2697
+ Order generated by a^2 in Number Field in a with defining polynomial x^4 - 5
2698
+ """
2699
+ if check_is_integral and not each_is_integral(gens):
2700
+ raise ValueError("each generator must be integral")
2701
+ gens = Sequence(gens)
2702
+ n = [x.absolute_minpoly().degree() for x in gens]
2703
+ module_gens = monomials(gens, n)
2704
+ return absolute_order_from_module_generators(module_gens,
2705
+ check_integral=False,
2706
+ check_is_ring=False,
2707
+ check_rank=check_rank,
2708
+ is_maximal=is_maximal,
2709
+ allow_subfield=allow_subfield)
2710
+
2711
+
2712
+ def absolute_order_from_module_generators(gens,
2713
+ check_integral=True, check_rank=True,
2714
+ check_is_ring=True, is_maximal=None,
2715
+ allow_subfield=False, is_maximal_at=()):
2716
+ r"""
2717
+ INPUT:
2718
+
2719
+ - ``gens`` -- list of elements of an absolute number field that generates an
2720
+ order in that number field as a `\ZZ`-*module*
2721
+ - ``check_integral`` -- check that each generator is integral
2722
+ - ``check_rank`` -- check that the ``gens`` span a module of the correct
2723
+ rank
2724
+ - ``check_is_ring`` -- check that the module is closed under multiplication
2725
+ (this is very expensive)
2726
+ - ``is_maximal`` -- boolean (or ``None``); set if maximality of the
2727
+ generated order is known
2728
+ - ``is_maximal_at`` -- tuple of primes where this order is known to be
2729
+ maximal
2730
+
2731
+ OUTPUT: an absolute order
2732
+
2733
+ EXAMPLES:
2734
+
2735
+ We have to explicitly import the function, since it is not meant
2736
+ for regular usage::
2737
+
2738
+ sage: from sage.rings.number_field.order import absolute_order_from_module_generators
2739
+
2740
+ sage: x = polygen(ZZ, 'x')
2741
+ sage: K.<a> = NumberField(x^4 - 5)
2742
+ sage: O = K.maximal_order(); O
2743
+ Maximal Order generated by [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a] in Number Field in a with defining polynomial x^4 - 5
2744
+ sage: O.basis()
2745
+ [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a, a^2, a^3]
2746
+ sage: O.module()
2747
+ Free module of degree 4 and rank 4 over Integer Ring
2748
+ Echelon basis matrix:
2749
+ [1/2 0 1/2 0]
2750
+ [ 0 1/2 0 1/2]
2751
+ [ 0 0 1 0]
2752
+ [ 0 0 0 1]
2753
+ sage: g = O.basis(); g
2754
+ [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a, a^2, a^3]
2755
+ sage: absolute_order_from_module_generators(g)
2756
+ Maximal Order generated by [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a] in Number Field in a with defining polynomial x^4 - 5
2757
+
2758
+ We illustrate each check flag -- the output is the same but in case
2759
+ the function would run ever so slightly faster::
2760
+
2761
+ sage: absolute_order_from_module_generators(g, check_is_ring=False)
2762
+ Maximal Order generated by [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a] in Number Field in a with defining polynomial x^4 - 5
2763
+ sage: absolute_order_from_module_generators(g, check_rank=False)
2764
+ Maximal Order generated by [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a] in Number Field in a with defining polynomial x^4 - 5
2765
+ sage: absolute_order_from_module_generators(g, check_integral=False)
2766
+ Maximal Order generated by [1/2*a^2 + 1/2, 1/2*a^3 + 1/2*a] in Number Field in a with defining polynomial x^4 - 5
2767
+
2768
+ Next we illustrate constructing "fake" orders to illustrate turning
2769
+ off various check flags::
2770
+
2771
+ sage: k.<i> = NumberField(x^2 + 1)
2772
+ sage: R = absolute_order_from_module_generators([2, 2*i],
2773
+ ....: check_is_ring=False); R
2774
+ Order of conductor 4 generated by [2, 2*i]
2775
+ in Number Field in i with defining polynomial x^2 + 1
2776
+ sage: R.basis()
2777
+ [2, 2*i]
2778
+ sage: R = absolute_order_from_module_generators([k(1)], # needs sage.symbolic
2779
+ ....: check_rank=False); R
2780
+ Order of conductor I generated by []
2781
+ in Number Field in i with defining polynomial x^2 + 1
2782
+ sage: R.basis() # needs sage.symbolic
2783
+ [1]
2784
+
2785
+ If the order contains a non-integral element, even if we do not check
2786
+ that, we will find that the rank is wrong or that the order is not closed
2787
+ under multiplication::
2788
+
2789
+ sage: absolute_order_from_module_generators([1/2, i],
2790
+ ....: check_integral=False)
2791
+ Traceback (most recent call last):
2792
+ ...
2793
+ ValueError: the module span of the gens is not closed under multiplication.
2794
+ sage: R = absolute_order_from_module_generators([1/2, i],
2795
+ ....: check_is_ring=False,
2796
+ ....: check_integral=False); R
2797
+ Order of conductor 0 generated by [1/2, i] in Number Field in i with defining polynomial x^2 + 1
2798
+ sage: R.basis()
2799
+ [1/2, i]
2800
+
2801
+ We turn off all check flags and make a really messed up order::
2802
+
2803
+ sage: R = absolute_order_from_module_generators([1/2, i],
2804
+ ....: check_is_ring=False,
2805
+ ....: check_integral=False,
2806
+ ....: check_rank=False); R
2807
+ Order of conductor 0 generated by [1/2, i] in Number Field in i with defining polynomial x^2 + 1
2808
+ sage: R.basis()
2809
+ [1/2, i]
2810
+
2811
+ An order that lives in a subfield::
2812
+
2813
+ sage: F.<alpha> = NumberField(x**4 + 3)
2814
+ sage: F.order([alpha**2], allow_subfield=True)
2815
+ Order of conductor 2 generated by ... in Number Field in beta with defining polynomial ... with beta = ...
2816
+ """
2817
+ if not gens:
2818
+ raise ValueError("gens must span an order over ZZ")
2819
+ gens = Sequence(gens)
2820
+ if check_integral and not each_is_integral(gens):
2821
+ raise ValueError("each generator must be integral")
2822
+
2823
+ K = gens.universe()
2824
+ if isinstance(K, Order) or K == ZZ:
2825
+ K = K.number_field()
2826
+ V, from_V, to_V = K.vector_space()
2827
+ mod_gens = [to_V(x) for x in gens]
2828
+ ambient = ZZ**V.dimension()
2829
+ W = ambient.span(mod_gens)
2830
+
2831
+ if allow_subfield:
2832
+ if W.rank() < K.degree():
2833
+ # We have to make the order in a smaller field.
2834
+ # We do this by choosing a random element of W,
2835
+ # moving it back to K, and checking that it defines
2836
+ # a field of degree equal to the degree of W.
2837
+ # Then we move everything into that field, where
2838
+ # W does define an order.
2839
+ while True:
2840
+ alpha = from_V(W.random_element())
2841
+ if alpha.minpoly().degree() == W.rank():
2842
+ break
2843
+ # Now alpha generates a subfield where W is an order
2844
+ # (with the right rank).
2845
+ # We move each generator of W to this subfield.
2846
+ K, _ = K.subfield(alpha, 'beta')
2847
+ gens = [K(x) for x in gens]
2848
+ V, from_V, to_V = K.vector_space()
2849
+ mod_gens = [to_V(x) for x in gens]
2850
+ ambient = ZZ**V.dimension()
2851
+ W = ambient.span(mod_gens)
2852
+
2853
+ elif check_rank:
2854
+ if W.rank() != K.degree():
2855
+ raise ValueError("the rank of the span of gens is wrong")
2856
+
2857
+ if check_is_ring:
2858
+ if any(to_V(x * y) not in W for x in gens for y in gens):
2859
+ raise ValueError("the module span of the gens is not closed under multiplication.")
2860
+
2861
+ return AbsoluteOrder(K, W, check=False, is_maximal=is_maximal, is_maximal_at=is_maximal_at)
2862
+
2863
+
2864
+ def relative_order_from_ring_generators(gens,
2865
+ check_is_integral=True,
2866
+ check_rank=True,
2867
+ is_maximal=None,
2868
+ allow_subfield=False,
2869
+ is_maximal_at=()):
2870
+ """
2871
+ INPUT:
2872
+
2873
+ - ``gens`` -- list of integral elements of an absolute order
2874
+ - ``check_is_integral`` -- boolean (default: ``True``); whether to check
2875
+ that each generator is integral
2876
+ - ``check_rank`` -- boolean (default: ``True``); whether to check that the
2877
+ ring generated by ``gens`` is of full rank
2878
+ - ``is_maximal`` -- boolean (or ``None``); set if maximality of the
2879
+ generated order is known
2880
+
2881
+ EXAMPLES:
2882
+
2883
+ We have to explicitly import this function, since it is not meant
2884
+ for regular usage::
2885
+
2886
+ sage: from sage.rings.number_field.order import relative_order_from_ring_generators
2887
+ sage: x = polygen(ZZ, 'x')
2888
+ sage: K.<i, a> = NumberField([x^2 + 1, x^2 - 17])
2889
+ sage: R = K.base_field().maximal_order()
2890
+ sage: S = relative_order_from_ring_generators([i,a]); S
2891
+ Relative Order generated by [7*i - 2*a, -a*i + 8, 25*i - 7*a] in
2892
+ Number Field in i with defining polynomial x^2 + 1 over its base field
2893
+
2894
+ Basis for the relative order, which is obtained by computing the algebra generated
2895
+ by i and a::
2896
+
2897
+ sage: S.basis()
2898
+ [1, 7*i - 2*a, -a*i + 8, 25*i - 7*a]
2899
+ """
2900
+ if check_is_integral and not each_is_integral(gens):
2901
+ raise ValueError("each generator must be integral")
2902
+ gens = Sequence(gens)
2903
+
2904
+ # The top number field that contains the order.
2905
+ K = gens.universe()
2906
+
2907
+ # The absolute version of that field.
2908
+ Kabs = K.absolute_field('z')
2909
+ from_Kabs, to_Kabs = Kabs.structure()
2910
+
2911
+ module_gens = [to_Kabs(a) for a in gens]
2912
+ n = [a.absolute_minpoly().degree() for a in gens]
2913
+ absolute_order_module_gens = monomials(module_gens, n)
2914
+
2915
+ abs_order = absolute_order_from_module_generators(absolute_order_module_gens,
2916
+ check_integral=False,
2917
+ check_is_ring=False,
2918
+ check_rank=check_rank,
2919
+ is_maximal=is_maximal,
2920
+ is_maximal_at=is_maximal_at)
2921
+
2922
+ return RelativeOrder(K, abs_order, check=False)
2923
+
2924
+
2925
+ def GaussianIntegers(names='I', latex_name='i'):
2926
+ r"""
2927
+ Return the ring of Gaussian integers.
2928
+
2929
+ This is the ring of all complex numbers
2930
+ of the form `a + b I` with `a` and `b` integers and `I = \sqrt{-1}`.
2931
+
2932
+ EXAMPLES::
2933
+
2934
+ sage: ZZI.<I> = GaussianIntegers()
2935
+ sage: ZZI
2936
+ Gaussian Integers generated by I in Number Field in I with defining polynomial x^2 + 1 with I = 1*I
2937
+ sage: factor(3 + I)
2938
+ (-2*I - 1) * (I - 1)
2939
+ sage: CC(I)
2940
+ 1.00000000000000*I
2941
+ sage: I.minpoly()
2942
+ x^2 + 1
2943
+ sage: GaussianIntegers().basis()
2944
+ [1, I]
2945
+ """
2946
+ from sage.rings.complex_double import CDF
2947
+ from sage.rings.number_field.number_field import NumberField
2948
+ f = ZZ['x']([1, 0, 1])
2949
+ nf = NumberField(f, names, embedding=CDF(0, 1), latex_name=latex_name)
2950
+ return nf.ring_of_integers()
2951
+
2952
+
2953
+ def EisensteinIntegers(names='omega'):
2954
+ r"""
2955
+ Return the ring of Eisenstein integers.
2956
+
2957
+ This is the ring of all complex numbers
2958
+ of the form `a + b \omega` with `a` and `b` integers and
2959
+ `\omega = (-1 + \sqrt{-3})/2`.
2960
+
2961
+ EXAMPLES::
2962
+
2963
+ sage: R.<omega> = EisensteinIntegers()
2964
+ sage: R
2965
+ Eisenstein Integers generated by omega in Number Field in omega
2966
+ with defining polynomial x^2 + x + 1
2967
+ with omega = -0.50000000000000000? + 0.866025403784439?*I
2968
+ sage: factor(3 + omega)
2969
+ (omega) * (-3*omega - 2)
2970
+ sage: CC(omega)
2971
+ -0.500000000000000 + 0.866025403784439*I
2972
+ sage: omega.minpoly()
2973
+ x^2 + x + 1
2974
+ sage: EisensteinIntegers().basis()
2975
+ [1, omega]
2976
+ """
2977
+ from sage.rings.complex_double import CDF
2978
+ from sage.rings.number_field.number_field import NumberField
2979
+ f = ZZ['x']([1, 1, 1])
2980
+ nf = NumberField(f, names, embedding=CDF(-0.5, 0.8660254037844386))
2981
+ return nf.ring_of_integers()