passagemath-pari 10.6.32__cp314-cp314-musllinux_1_2_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.

Potentially problematic release.


This version of passagemath-pari might be problematic. Click here for more details.

Files changed (331) hide show
  1. PARIKernel/__init__.py +2 -0
  2. PARIKernel/__main__.py +5 -0
  3. PARIKernel/io.cpython-314-x86_64-linux-musl.so +0 -0
  4. PARIKernel/io.pxd +7 -0
  5. PARIKernel/io.pyx +84 -0
  6. PARIKernel/kernel.cpython-314-x86_64-linux-musl.so +0 -0
  7. PARIKernel/kernel.pyx +260 -0
  8. PARIKernel/paridecl.pxd +95 -0
  9. PARIKernel/svg.cpython-314-x86_64-linux-musl.so +0 -0
  10. PARIKernel/svg.pyx +52 -0
  11. cypari2/__init__.py +8 -0
  12. cypari2/auto_paridecl.pxd +1070 -0
  13. cypari2/closure.cpython-314-x86_64-linux-musl.so +0 -0
  14. cypari2/closure.pxd +5 -0
  15. cypari2/closure.pyx +246 -0
  16. cypari2/convert.cpython-314-x86_64-linux-musl.so +0 -0
  17. cypari2/convert.pxd +80 -0
  18. cypari2/convert.pyx +613 -0
  19. cypari2/custom_block.cpython-314-x86_64-linux-musl.so +0 -0
  20. cypari2/custom_block.pyx +30 -0
  21. cypari2/cypari.h +13 -0
  22. cypari2/gen.cpython-314-x86_64-linux-musl.so +0 -0
  23. cypari2/gen.pxd +69 -0
  24. cypari2/gen.pyx +4819 -0
  25. cypari2/handle_error.cpython-314-x86_64-linux-musl.so +0 -0
  26. cypari2/handle_error.pxd +7 -0
  27. cypari2/handle_error.pyx +232 -0
  28. cypari2/pari_instance.cpython-314-x86_64-linux-musl.so +0 -0
  29. cypari2/pari_instance.pxd +27 -0
  30. cypari2/pari_instance.pyx +1438 -0
  31. cypari2/paridecl.pxd +5353 -0
  32. cypari2/paripriv.pxd +34 -0
  33. cypari2/pycore_long.h +98 -0
  34. cypari2/pycore_long.pxd +9 -0
  35. cypari2/stack.cpython-314-x86_64-linux-musl.so +0 -0
  36. cypari2/stack.pxd +27 -0
  37. cypari2/stack.pyx +278 -0
  38. cypari2/string_utils.cpython-314-x86_64-linux-musl.so +0 -0
  39. cypari2/string_utils.pxd +29 -0
  40. cypari2/string_utils.pyx +65 -0
  41. cypari2/types.pxd +147 -0
  42. passagemath_pari-10.6.32.data/data/etc/jupyter/nbconfig/notebook.d/gp-mode.json +5 -0
  43. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.js +28 -0
  44. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.json +6 -0
  45. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/logo-64x64.png +0 -0
  46. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/kernel.json +13 -0
  47. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-32x32.png +0 -0
  48. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-64x64.png +0 -0
  49. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-svg.svg +75 -0
  50. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/gp.js +284 -0
  51. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/main.js +15 -0
  52. passagemath_pari-10.6.32.dist-info/METADATA +209 -0
  53. passagemath_pari-10.6.32.dist-info/RECORD +331 -0
  54. passagemath_pari-10.6.32.dist-info/WHEEL +5 -0
  55. passagemath_pari-10.6.32.dist-info/top_level.txt +4 -0
  56. passagemath_pari.libs/libcrypto-f04afe95.so.3 +0 -0
  57. passagemath_pari.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
  58. passagemath_pari.libs/libgcc_s-0cd532bd.so.1 +0 -0
  59. passagemath_pari.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  60. passagemath_pari.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
  61. passagemath_pari.libs/libgivaro-9a94c711.so.9.2.1 +0 -0
  62. passagemath_pari.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  63. passagemath_pari.libs/libgmpxx-9e08595c.so.4.7.0 +0 -0
  64. passagemath_pari.libs/libgsl-42cda06f.so.28.0.0 +0 -0
  65. passagemath_pari.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  66. passagemath_pari.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
  67. passagemath_pari.libs/libntl-26885ca2.so.44.0.1 +0 -0
  68. passagemath_pari.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
  69. passagemath_pari.libs/libpari-gmp-tls-f31f908f.so.2.17.2 +0 -0
  70. passagemath_pari.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
  71. passagemath_pari.libs/libreadline-06542304.so.8.2 +0 -0
  72. passagemath_pari.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  73. passagemath_pari.libs/libuuid-f3770415.so.1.3.0 +0 -0
  74. passagemath_pari.libs/libxeus-735780ff.so.13.1.0 +0 -0
  75. passagemath_pari.libs/libxeus-zmq-c68577b4.so.6.0.1 +0 -0
  76. passagemath_pari.libs/libzmq-1ba9a3da.so.5.2.5 +0 -0
  77. sage/all__sagemath_pari.py +26 -0
  78. sage/databases/all__sagemath_pari.py +7 -0
  79. sage/databases/conway.py +274 -0
  80. sage/ext/all__sagemath_pari.py +1 -0
  81. sage/ext/memory.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/ext/memory.pyx +98 -0
  83. sage/ext_data/pari/buzzard/DimensionSk.g +286 -0
  84. sage/ext_data/pari/buzzard/Tpprog.g +179 -0
  85. sage/ext_data/pari/buzzard/genusn.g +129 -0
  86. sage/ext_data/pari/dokchitser/computel.gp +740 -0
  87. sage/ext_data/pari/dokchitser/computel.gp.template +740 -0
  88. sage/ext_data/pari/dokchitser/ex-bsw +43 -0
  89. sage/ext_data/pari/dokchitser/ex-chgen +48 -0
  90. sage/ext_data/pari/dokchitser/ex-chqua +37 -0
  91. sage/ext_data/pari/dokchitser/ex-delta +35 -0
  92. sage/ext_data/pari/dokchitser/ex-eisen +30 -0
  93. sage/ext_data/pari/dokchitser/ex-gen2 +38 -0
  94. sage/ext_data/pari/dokchitser/ex-gen3 +49 -0
  95. sage/ext_data/pari/dokchitser/ex-gen4 +54 -0
  96. sage/ext_data/pari/dokchitser/ex-nf +48 -0
  97. sage/ext_data/pari/dokchitser/ex-shin +50 -0
  98. sage/ext_data/pari/dokchitser/ex-tau2 +30 -0
  99. sage/ext_data/pari/dokchitser/ex-zeta +27 -0
  100. sage/ext_data/pari/dokchitser/ex-zeta2 +47 -0
  101. sage/ext_data/pari/dokchitser/testall +13 -0
  102. sage/ext_data/pari/simon/ell.gp +2129 -0
  103. sage/ext_data/pari/simon/ellQ.gp +2151 -0
  104. sage/ext_data/pari/simon/ellcommon.gp +126 -0
  105. sage/ext_data/pari/simon/qfsolve.gp +722 -0
  106. sage/ext_data/pari/simon/resultant3.gp +306 -0
  107. sage/groups/all__sagemath_pari.py +3 -0
  108. sage/groups/pari_group.py +175 -0
  109. sage/interfaces/all__sagemath_pari.py +1 -0
  110. sage/interfaces/genus2reduction.py +464 -0
  111. sage/interfaces/gp.py +1114 -0
  112. sage/libs/all__sagemath_pari.py +2 -0
  113. sage/libs/linkages/__init__.py +1 -0
  114. sage/libs/linkages/padics/API.pxi +617 -0
  115. sage/libs/linkages/padics/Polynomial_ram.pxi +388 -0
  116. sage/libs/linkages/padics/Polynomial_shared.pxi +554 -0
  117. sage/libs/linkages/padics/__init__.py +1 -0
  118. sage/libs/linkages/padics/fmpz_poly_unram.pxi +869 -0
  119. sage/libs/linkages/padics/mpz.pxi +691 -0
  120. sage/libs/linkages/padics/relaxed/API.pxi +518 -0
  121. sage/libs/linkages/padics/relaxed/__init__.py +1 -0
  122. sage/libs/linkages/padics/relaxed/flint.pxi +543 -0
  123. sage/libs/linkages/padics/unram_shared.pxi +247 -0
  124. sage/libs/pari/__init__.py +210 -0
  125. sage/libs/pari/all.py +5 -0
  126. sage/libs/pari/convert_flint.cpython-314-x86_64-linux-musl.so +0 -0
  127. sage/libs/pari/convert_flint.pxd +14 -0
  128. sage/libs/pari/convert_flint.pyx +159 -0
  129. sage/libs/pari/convert_gmp.cpython-314-x86_64-linux-musl.so +0 -0
  130. sage/libs/pari/convert_gmp.pxd +14 -0
  131. sage/libs/pari/convert_gmp.pyx +210 -0
  132. sage/libs/pari/convert_sage.cpython-314-x86_64-linux-musl.so +0 -0
  133. sage/libs/pari/convert_sage.pxd +16 -0
  134. sage/libs/pari/convert_sage.pyx +588 -0
  135. sage/libs/pari/convert_sage_complex_double.cpython-314-x86_64-linux-musl.so +0 -0
  136. sage/libs/pari/convert_sage_complex_double.pxd +14 -0
  137. sage/libs/pari/convert_sage_complex_double.pyx +132 -0
  138. sage/libs/pari/convert_sage_matrix.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/libs/pari/convert_sage_matrix.pyx +106 -0
  140. sage/libs/pari/convert_sage_real_double.cpython-314-x86_64-linux-musl.so +0 -0
  141. sage/libs/pari/convert_sage_real_double.pxd +5 -0
  142. sage/libs/pari/convert_sage_real_double.pyx +14 -0
  143. sage/libs/pari/convert_sage_real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
  144. sage/libs/pari/convert_sage_real_mpfr.pxd +7 -0
  145. sage/libs/pari/convert_sage_real_mpfr.pyx +108 -0
  146. sage/libs/pari/misc.cpython-314-x86_64-linux-musl.so +0 -0
  147. sage/libs/pari/misc.pxd +4 -0
  148. sage/libs/pari/misc.pyx +26 -0
  149. sage/libs/pari/tests.py +1848 -0
  150. sage/matrix/all__sagemath_pari.py +1 -0
  151. sage/matrix/matrix_integer_pari.cpython-314-x86_64-linux-musl.so +0 -0
  152. sage/matrix/matrix_integer_pari.pyx +187 -0
  153. sage/matrix/matrix_rational_pari.cpython-314-x86_64-linux-musl.so +0 -0
  154. sage/matrix/matrix_rational_pari.pyx +160 -0
  155. sage/quadratic_forms/all__sagemath_pari.py +10 -0
  156. sage/quadratic_forms/genera/all.py +9 -0
  157. sage/quadratic_forms/genera/genus.py +3506 -0
  158. sage/quadratic_forms/genera/normal_form.py +1519 -0
  159. sage/quadratic_forms/genera/spinor_genus.py +243 -0
  160. sage/quadratic_forms/qfsolve.py +255 -0
  161. sage/quadratic_forms/quadratic_form__automorphisms.py +427 -0
  162. sage/quadratic_forms/quadratic_form__genus.py +141 -0
  163. sage/quadratic_forms/quadratic_form__local_density_interfaces.py +140 -0
  164. sage/quadratic_forms/quadratic_form__local_normal_form.py +421 -0
  165. sage/quadratic_forms/quadratic_form__local_representation_conditions.py +889 -0
  166. sage/quadratic_forms/quadratic_form__mass.py +69 -0
  167. sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +663 -0
  168. sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +373 -0
  169. sage/quadratic_forms/quadratic_form__siegel_product.py +198 -0
  170. sage/quadratic_forms/special_values.py +323 -0
  171. sage/rings/all__sagemath_pari.py +15 -0
  172. sage/rings/factorint_pari.cpython-314-x86_64-linux-musl.so +0 -0
  173. sage/rings/factorint_pari.pyx +80 -0
  174. sage/rings/finite_rings/all__sagemath_pari.py +1 -0
  175. sage/rings/finite_rings/element_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  176. sage/rings/finite_rings/element_givaro.pxd +91 -0
  177. sage/rings/finite_rings/element_givaro.pyx +1769 -0
  178. sage/rings/finite_rings/element_ntl_gf2e.cpython-314-x86_64-linux-musl.so +0 -0
  179. sage/rings/finite_rings/element_ntl_gf2e.pxd +22 -0
  180. sage/rings/finite_rings/element_ntl_gf2e.pyx +1333 -0
  181. sage/rings/finite_rings/element_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  182. sage/rings/finite_rings/element_pari_ffelt.pxd +13 -0
  183. sage/rings/finite_rings/element_pari_ffelt.pyx +1441 -0
  184. sage/rings/finite_rings/finite_field_givaro.py +612 -0
  185. sage/rings/finite_rings/finite_field_pari_ffelt.py +238 -0
  186. sage/rings/finite_rings/hom_finite_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  187. sage/rings/finite_rings/hom_finite_field_givaro.pxd +28 -0
  188. sage/rings/finite_rings/hom_finite_field_givaro.pyx +280 -0
  189. sage/rings/finite_rings/residue_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  190. sage/rings/finite_rings/residue_field_givaro.pyx +133 -0
  191. sage/rings/finite_rings/residue_field_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  192. sage/rings/finite_rings/residue_field_pari_ffelt.pyx +128 -0
  193. sage/rings/function_field/all__sagemath_pari.py +1 -0
  194. sage/rings/function_field/valuation.py +1450 -0
  195. sage/rings/function_field/valuation_ring.py +212 -0
  196. sage/rings/number_field/all__sagemath_pari.py +14 -0
  197. sage/rings/number_field/totallyreal.cpython-314-x86_64-linux-musl.so +0 -0
  198. sage/rings/number_field/totallyreal.pyx +509 -0
  199. sage/rings/number_field/totallyreal_data.cpython-314-x86_64-linux-musl.so +0 -0
  200. sage/rings/number_field/totallyreal_data.pxd +26 -0
  201. sage/rings/number_field/totallyreal_data.pyx +928 -0
  202. sage/rings/number_field/totallyreal_phc.py +144 -0
  203. sage/rings/number_field/totallyreal_rel.py +1018 -0
  204. sage/rings/padics/CA_template.pxi +1847 -0
  205. sage/rings/padics/CA_template_header.pxi +50 -0
  206. sage/rings/padics/CR_template.pxi +2563 -0
  207. sage/rings/padics/CR_template_header.pxi +57 -0
  208. sage/rings/padics/FM_template.pxi +1575 -0
  209. sage/rings/padics/FM_template_header.pxi +50 -0
  210. sage/rings/padics/FP_template.pxi +2176 -0
  211. sage/rings/padics/FP_template_header.pxi +57 -0
  212. sage/rings/padics/all.py +3 -0
  213. sage/rings/padics/all__sagemath_pari.py +11 -0
  214. sage/rings/padics/common_conversion.cpython-314-x86_64-linux-musl.so +0 -0
  215. sage/rings/padics/common_conversion.pxd +15 -0
  216. sage/rings/padics/common_conversion.pyx +508 -0
  217. sage/rings/padics/eisenstein_extension_generic.py +232 -0
  218. sage/rings/padics/factory.py +3623 -0
  219. sage/rings/padics/generic_nodes.py +1615 -0
  220. sage/rings/padics/lattice_precision.py +2889 -0
  221. sage/rings/padics/morphism.cpython-314-x86_64-linux-musl.so +0 -0
  222. sage/rings/padics/morphism.pxd +11 -0
  223. sage/rings/padics/morphism.pyx +366 -0
  224. sage/rings/padics/padic_base_generic.py +467 -0
  225. sage/rings/padics/padic_base_leaves.py +1235 -0
  226. sage/rings/padics/padic_capped_absolute_element.cpython-314-x86_64-linux-musl.so +0 -0
  227. sage/rings/padics/padic_capped_absolute_element.pxd +15 -0
  228. sage/rings/padics/padic_capped_absolute_element.pyx +520 -0
  229. sage/rings/padics/padic_capped_relative_element.cpython-314-x86_64-linux-musl.so +0 -0
  230. sage/rings/padics/padic_capped_relative_element.pxd +14 -0
  231. sage/rings/padics/padic_capped_relative_element.pyx +614 -0
  232. sage/rings/padics/padic_extension_generic.py +990 -0
  233. sage/rings/padics/padic_extension_leaves.py +738 -0
  234. sage/rings/padics/padic_fixed_mod_element.cpython-314-x86_64-linux-musl.so +0 -0
  235. sage/rings/padics/padic_fixed_mod_element.pxd +15 -0
  236. sage/rings/padics/padic_fixed_mod_element.pyx +584 -0
  237. sage/rings/padics/padic_floating_point_element.cpython-314-x86_64-linux-musl.so +0 -0
  238. sage/rings/padics/padic_floating_point_element.pxd +14 -0
  239. sage/rings/padics/padic_floating_point_element.pyx +447 -0
  240. sage/rings/padics/padic_generic_element.cpython-314-x86_64-linux-musl.so +0 -0
  241. sage/rings/padics/padic_generic_element.pxd +48 -0
  242. sage/rings/padics/padic_generic_element.pyx +4642 -0
  243. sage/rings/padics/padic_lattice_element.py +1342 -0
  244. sage/rings/padics/padic_printing.cpython-314-x86_64-linux-musl.so +0 -0
  245. sage/rings/padics/padic_printing.pxd +38 -0
  246. sage/rings/padics/padic_printing.pyx +1505 -0
  247. sage/rings/padics/padic_relaxed_element.cpython-314-x86_64-linux-musl.so +0 -0
  248. sage/rings/padics/padic_relaxed_element.pxd +56 -0
  249. sage/rings/padics/padic_relaxed_element.pyx +18 -0
  250. sage/rings/padics/padic_relaxed_errors.cpython-314-x86_64-linux-musl.so +0 -0
  251. sage/rings/padics/padic_relaxed_errors.pxd +11 -0
  252. sage/rings/padics/padic_relaxed_errors.pyx +71 -0
  253. sage/rings/padics/padic_template_element.pxi +1212 -0
  254. sage/rings/padics/padic_template_element_header.pxi +50 -0
  255. sage/rings/padics/padic_valuation.py +1423 -0
  256. sage/rings/padics/pow_computer_flint.cpython-314-x86_64-linux-musl.so +0 -0
  257. sage/rings/padics/pow_computer_flint.pxd +38 -0
  258. sage/rings/padics/pow_computer_flint.pyx +641 -0
  259. sage/rings/padics/pow_computer_relative.cpython-314-x86_64-linux-musl.so +0 -0
  260. sage/rings/padics/pow_computer_relative.pxd +29 -0
  261. sage/rings/padics/pow_computer_relative.pyx +415 -0
  262. sage/rings/padics/qadic_flint_CA.cpython-314-x86_64-linux-musl.so +0 -0
  263. sage/rings/padics/qadic_flint_CA.pxd +21 -0
  264. sage/rings/padics/qadic_flint_CA.pyx +130 -0
  265. sage/rings/padics/qadic_flint_CR.cpython-314-x86_64-linux-musl.so +0 -0
  266. sage/rings/padics/qadic_flint_CR.pxd +13 -0
  267. sage/rings/padics/qadic_flint_CR.pyx +172 -0
  268. sage/rings/padics/qadic_flint_FM.cpython-314-x86_64-linux-musl.so +0 -0
  269. sage/rings/padics/qadic_flint_FM.pxd +14 -0
  270. sage/rings/padics/qadic_flint_FM.pyx +111 -0
  271. sage/rings/padics/qadic_flint_FP.cpython-314-x86_64-linux-musl.so +0 -0
  272. sage/rings/padics/qadic_flint_FP.pxd +12 -0
  273. sage/rings/padics/qadic_flint_FP.pyx +165 -0
  274. sage/rings/padics/relative_extension_leaves.py +429 -0
  275. sage/rings/padics/relative_ramified_CA.cpython-314-x86_64-linux-musl.so +0 -0
  276. sage/rings/padics/relative_ramified_CA.pxd +9 -0
  277. sage/rings/padics/relative_ramified_CA.pyx +33 -0
  278. sage/rings/padics/relative_ramified_CR.cpython-314-x86_64-linux-musl.so +0 -0
  279. sage/rings/padics/relative_ramified_CR.pxd +8 -0
  280. sage/rings/padics/relative_ramified_CR.pyx +33 -0
  281. sage/rings/padics/relative_ramified_FM.cpython-314-x86_64-linux-musl.so +0 -0
  282. sage/rings/padics/relative_ramified_FM.pxd +9 -0
  283. sage/rings/padics/relative_ramified_FM.pyx +33 -0
  284. sage/rings/padics/relative_ramified_FP.cpython-314-x86_64-linux-musl.so +0 -0
  285. sage/rings/padics/relative_ramified_FP.pxd +8 -0
  286. sage/rings/padics/relative_ramified_FP.pyx +33 -0
  287. sage/rings/padics/relaxed_template.pxi +4229 -0
  288. sage/rings/padics/relaxed_template_header.pxi +160 -0
  289. sage/rings/padics/tests.py +35 -0
  290. sage/rings/padics/tutorial.py +341 -0
  291. sage/rings/padics/unramified_extension_generic.py +335 -0
  292. sage/rings/padics/witt_vector.py +917 -0
  293. sage/rings/padics/witt_vector_ring.py +934 -0
  294. sage/rings/pari_ring.py +235 -0
  295. sage/rings/polynomial/all__sagemath_pari.py +1 -0
  296. sage/rings/polynomial/padics/all.py +1 -0
  297. sage/rings/polynomial/padics/polynomial_padic.py +360 -0
  298. sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +1324 -0
  299. sage/rings/polynomial/padics/polynomial_padic_flat.py +72 -0
  300. sage/rings/power_series_pari.cpython-314-x86_64-linux-musl.so +0 -0
  301. sage/rings/power_series_pari.pxd +6 -0
  302. sage/rings/power_series_pari.pyx +934 -0
  303. sage/rings/tate_algebra.py +1282 -0
  304. sage/rings/tate_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
  305. sage/rings/tate_algebra_element.pxd +49 -0
  306. sage/rings/tate_algebra_element.pyx +3464 -0
  307. sage/rings/tate_algebra_ideal.cpython-314-x86_64-linux-musl.so +0 -0
  308. sage/rings/tate_algebra_ideal.pxd +7 -0
  309. sage/rings/tate_algebra_ideal.pyx +1307 -0
  310. sage/rings/valuation/all.py +7 -0
  311. sage/rings/valuation/augmented_valuation.py +2118 -0
  312. sage/rings/valuation/developing_valuation.py +362 -0
  313. sage/rings/valuation/gauss_valuation.py +812 -0
  314. sage/rings/valuation/inductive_valuation.py +1686 -0
  315. sage/rings/valuation/limit_valuation.py +946 -0
  316. sage/rings/valuation/mapped_valuation.py +656 -0
  317. sage/rings/valuation/scaled_valuation.py +322 -0
  318. sage/rings/valuation/trivial_valuation.py +382 -0
  319. sage/rings/valuation/valuation.py +1119 -0
  320. sage/rings/valuation/valuation_space.py +1615 -0
  321. sage/rings/valuation/valuations_catalog.py +10 -0
  322. sage/rings/valuation/value_group.py +697 -0
  323. sage/schemes/all__sagemath_pari.py +1 -0
  324. sage/schemes/elliptic_curves/all__sagemath_pari.py +1 -0
  325. sage/schemes/elliptic_curves/descent_two_isogeny_pari.cpython-314-x86_64-linux-musl.so +0 -0
  326. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pyx +46 -0
  327. sage_wheels/bin/gp +0 -0
  328. sage_wheels/bin/gp2c +0 -0
  329. sage_wheels/bin/gp2c-run +57 -0
  330. sage_wheels/bin/xeus-gp +0 -0
  331. sage_wheels/share/gp2c/func.dsc +18414 -0
@@ -0,0 +1,1018 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ # sage.doctest: needs sage.geometry.polyhedron sage.libs.linbox sage.modules sage.rings.number_field
3
+ r"""
4
+ Enumeration of totally real fields: relative extensions
5
+
6
+ This module contains functions to enumerate primitive extensions `L / K`, where
7
+ `K` is a given totally real number field, with given degree and small root
8
+ discriminant. This is a relative analogue of the problem described in
9
+ :mod:`sage.rings.number_field.totallyreal`, and we use a similar approach
10
+ based on a relative version of Hunter's theorem.
11
+
12
+ In this first simple example, we compute the totally real quadratic
13
+ fields of `F = \QQ(\sqrt{2})` of discriminant `\le 2000`.
14
+
15
+ ::
16
+
17
+ sage: ZZx.<x> = ZZ[]
18
+ sage: F.<t> = NumberField(x^2 - 2)
19
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
20
+ [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]
21
+
22
+ There is indeed only one such extension, given by `F(\sqrt{5})`.
23
+
24
+ Next, we list all totally real quadratic extensions of `\QQ(\sqrt 5)`
25
+ with root discriminant `\le 10`.
26
+
27
+ ::
28
+
29
+ sage: F.<t> = NumberField(x^2 - 5)
30
+ sage: ls = enumerate_totallyreal_fields_rel(F, 2, 10^4)
31
+ sage: ls # random (the second factor is platform-dependent)
32
+ [[725, x^4 - x^3 - 3*x^2 + x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1],
33
+ [1125, x^4 - x^3 - 4*x^2 + 4*x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1/2*t + 3/2],
34
+ [1600, x^4 - 6*x^2 + 4, xF^2 - 2],
35
+ [2000, x^4 - 5*x^2 + 5, xF^2 - 1/2*t - 5/2],
36
+ [2225, x^4 - x^3 - 5*x^2 + 2*x + 4, xF^2 + (-1/2*t + 1/2)*xF - 3/2*t - 7/2],
37
+ [2525, x^4 - 2*x^3 - 4*x^2 + 5*x + 5, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 5/2],
38
+ [3600, x^4 - 2*x^3 - 7*x^2 + 8*x + 1, xF^2 - 3],
39
+ [4225, x^4 - 9*x^2 + 4, xF^2 + (-1/2*t - 1/2)*xF - 3/2*t - 9/2],
40
+ [4400, x^4 - 7*x^2 + 11, xF^2 - 1/2*t - 7/2],
41
+ [4525, x^4 - x^3 - 7*x^2 + 3*x + 9, xF^2 + (-1/2*t - 1/2)*xF - 3],
42
+ [5125, x^4 - 2*x^3 - 6*x^2 + 7*x + 11, xF^2 + (-1/2*t - 1/2)*xF - t - 4],
43
+ [5225, x^4 - x^3 - 8*x^2 + x + 11, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 7/2],
44
+ [5725, x^4 - x^3 - 8*x^2 + 6*x + 11, xF^2 + (-1/2*t + 1/2)*xF - 1/2*t - 7/2],
45
+ [6125, x^4 - x^3 - 9*x^2 + 9*x + 11, xF^2 + (-1/2*t + 1/2)*xF - t - 4],
46
+ [7225, x^4 - 11*x^2 + 9, xF^2 + (-1)*xF - 4],
47
+ [7600, x^4 - 9*x^2 + 19, xF^2 - 1/2*t - 9/2],
48
+ [7625, x^4 - x^3 - 9*x^2 + 4*x + 16, xF^2 + (-1/2*t - 1/2)*xF - 4],
49
+ [8000, x^4 - 10*x^2 + 20, xF^2 - t - 5],
50
+ [8525, x^4 - 2*x^3 - 8*x^2 + 9*x + 19, xF^2 + (-1)*xF - 1/2*t - 9/2],
51
+ [8725, x^4 - x^3 - 10*x^2 + 2*x + 19, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 9/2],
52
+ [9225, x^4 - x^3 - 10*x^2 + 7*x + 19, xF^2 + (-1/2*t + 1/2)*xF - 1/2*t - 9/2]]
53
+ sage: [ f[0] for f in ls ]
54
+ [725, 1125, 1600, 2000, 2225, 2525, 3600, 4225, 4400, 4525, 5125, 5225, 5725, 6125, 7225, 7600, 7625, 8000, 8525, 8725, 9225]
55
+
56
+ sage: [NumberField(ZZx(x[1]), 't').is_galois() for x in ls] # needs sage.groups
57
+ [False, True, True, True, False, False, True, True, False, False, False, False, False, True, True, False, False, True, False, False, False]
58
+
59
+ Eight out of 21 such fields are Galois (with Galois group `C_4`
60
+ or `C_2 \times C_2`); the others have Galois closure of degree 8
61
+ (with Galois group `D_8`).
62
+
63
+ Finally, we compute the cubic extensions of `\QQ(\zeta_7)^+` with
64
+ discriminant `\le 17 \times 10^9`.
65
+
66
+ ::
67
+
68
+ sage: F.<t> = NumberField(ZZx([1,-4,3,1]))
69
+ sage: F.disc()
70
+ 49
71
+ sage: enumerate_totallyreal_fields_rel(F, 3, 17*10^9) # not tested, too long time (258s on sage.math, 2013)
72
+ [[16240385609L, x^9 - x^8 - 9*x^7 + 4*x^6 + 26*x^5 - 2*x^4 - 25*x^3 - x^2 + 7*x + 1, xF^3 + (-t^2 - 4*t + 1)*xF^2 + (t^2 + 3*t - 5)*xF + 3*t^2 + 11*t - 5]] # 32-bit
73
+ [[16240385609, x^9 - x^8 - 9*x^7 + 4*x^6 + 26*x^5 - 2*x^4 - 25*x^3 - x^2 + 7*x + 1, xF^3 + (-t^2 - 4*t + 1)*xF^2 + (t^2 + 3*t - 5)*xF + 3*t^2 + 11*t - 5]] # 64-bit
74
+
75
+ TESTS:
76
+
77
+ Check that :issue:`27646` is fixed::
78
+
79
+ sage: L = enumerate_totallyreal_fields_all(6,435000) # long time
80
+
81
+ AUTHORS:
82
+
83
+ - John Voight (2007-11-03): initial version
84
+ """
85
+
86
+ # ****************************************************************************
87
+ # Copyright (C) 2007 William Stein and John Voight
88
+ #
89
+ # Distributed under the terms of the GNU General Public License (GPL)
90
+ # as published by the Free Software Foundation; either version 2 of
91
+ # the License, or (at your option) any later version.
92
+ # https://www.gnu.org/licenses/
93
+ # ****************************************************************************
94
+
95
+ from sage.arith.misc import binomial
96
+ from sage.arith.misc import GCD as gcd
97
+ from sage.arith.misc import divisors
98
+ from sage.rings.integer import Integer
99
+ from sage.rings.integer_ring import IntegerRing
100
+ from sage.rings.number_field.totallyreal_data import ZZx, lagrange_degree_3, int_has_small_square_divisor, hermite_constant
101
+ from sage.rings.number_field.number_field import NumberField
102
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
103
+ from sage.rings.number_field.totallyreal import weed_fields, odlyzko_bound_totallyreal, enumerate_totallyreal_fields_prim
104
+ from sage.libs.pari import pari
105
+ from sage.rings.integer_ring import ZZ
106
+ from sage.rings.rational_field import QQ
107
+
108
+ import math
109
+ import sys
110
+
111
+
112
+ def integral_elements_in_box(K, C):
113
+ r"""
114
+ Return all integral elements of the totally real field `K` whose
115
+ embeddings lie *numerically* within the bounds specified by the
116
+ list ``C``. The output is architecture dependent, and one may want
117
+ to expand the bounds that define ``C`` by some epsilon.
118
+
119
+ INPUT:
120
+
121
+ - ``K`` -- a totally real number field
122
+ - ``C`` -- list ``[[lower, upper], ...]`` of lower and upper bounds,
123
+ for each embedding
124
+
125
+ EXAMPLES::
126
+
127
+ sage: x = polygen(QQ)
128
+ sage: K.<alpha> = NumberField(x^2 - 2)
129
+ sage: eps = 10e-6
130
+ sage: C = [[0-eps, 5+eps], [0-eps, 10+eps]]
131
+ sage: ls = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C) # needs palp
132
+ sage: sorted(a.trace() for a in ls) # needs palp
133
+ [0, 2, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 10, 12, 12, 14]
134
+ sage: len(ls) # needs palp
135
+ 19
136
+
137
+ sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C) # needs palp
138
+ sage: sorted(v) # needs palp
139
+ [0, -alpha + 2, 1, -alpha + 3, 2, 3, alpha + 2, 4, alpha + 3, 5, alpha + 4,
140
+ 2*alpha + 3, alpha + 5, 2*alpha + 4, alpha + 6, 2*alpha + 5, 2*alpha + 6,
141
+ 3*alpha + 5, 2*alpha + 7]
142
+
143
+ A cubic field::
144
+
145
+ sage: x = polygen(QQ)
146
+ sage: K.<a> = NumberField(x^3 - 16*x +16)
147
+ sage: eps = 10e-6
148
+ sage: C = [[0-eps,5+eps]]*3
149
+ sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C) # needs palp
150
+
151
+ Note that the output is platform dependent (sometimes a 5 is listed
152
+ below, and sometimes it isn't)::
153
+
154
+ sage: sorted(v) # needs palp
155
+ [-1/2*a + 2, 1/4*a^2 + 1/2*a, 0, 1, 2, 3, 4,...-1/4*a^2 - 1/2*a + 5,
156
+ 1/2*a + 3, -1/4*a^2 + 5]
157
+ """
158
+ d = K.degree()
159
+ Foo = K.real_embeddings()
160
+ B = K.reduced_basis()
161
+
162
+ import numpy
163
+ import numpy.linalg
164
+ L = numpy.array([[v(b) for b in B] for v in Foo])
165
+ Linv = numpy.linalg.inv(L)
166
+ Vi = [[C[0][0]], [C[0][1]]]
167
+ for i in range(1, d):
168
+ Vi = sum([[v + [C[i][0]], v + [C[i][1]]] for v in Vi], [])
169
+ V = numpy.matrix(Linv) * numpy.matrix(Vi).transpose()
170
+ j = 0
171
+ while j < 2**d:
172
+ for i in range(d):
173
+ if V[i, j] < V[i, j+1]:
174
+ V[i, j] = math.floor(V[i, j])
175
+ V[i, j+1] = math.ceil(V[i, j+1])
176
+ else:
177
+ V[i, j] = math.ceil(V[i, j])
178
+ V[i, j+1] = math.floor(V[i, j+1])
179
+ j += 2
180
+ W0 = (Linv*numpy.array([Vi[0]] * d)).transpose()
181
+ W = (Linv*numpy.array([Vi[2**i] for i in range(d)])).transpose()
182
+ for j in range(d):
183
+ for i in range(d):
184
+ if W[i,j] < W0[i,j]:
185
+ W[i,j] = math.floor(W[i,j])
186
+ W0[i,j] = math.ceil(W0[i,j])
187
+ else:
188
+ W[i,j] = math.ceil(W[i,j])
189
+ W0[i,j] = math.floor(W0[i,j])
190
+ M = [[int(V[i,j]) for i in range(V.shape[0])] for j in range(V.shape[1])]
191
+ M += [[int(W0[i,j]) for j in range(W0.shape[0])] for i in range(W0.shape[0])]
192
+ M += [[int(W[i,j]) for j in range(W.shape[1])] for i in range(W.shape[0])]
193
+
194
+ from sage.matrix.constructor import matrix
195
+ M = (matrix(IntegerRing(),len(M),len(M[0]), M).transpose()).columns()
196
+
197
+ i = 0
198
+ while i < len(M):
199
+ j = i+1
200
+ while j < len(M):
201
+ if M[i] == M[j]:
202
+ M.pop(j)
203
+ else:
204
+ j += 1
205
+ i += 1
206
+
207
+ from sage.geometry.lattice_polytope import LatticePolytope
208
+ P = LatticePolytope(M)
209
+
210
+ try:
211
+ pts = P.points()
212
+ except ValueError:
213
+ return []
214
+
215
+ S = []
216
+ for p in pts:
217
+ theta = sum(a * b for a, b in zip(p.list(), B))
218
+ if all((C[i][0] <= Foo[i](theta) <= C[i][1])
219
+ for i in range(d)):
220
+ S.append(theta)
221
+
222
+ return S
223
+
224
+
225
+ #********************************************************************************
226
+ # Main class
227
+ #********************************************************************************
228
+
229
+ eps_global = 10**(-6)
230
+
231
+
232
+ class tr_data_rel:
233
+ r"""
234
+ This class encodes the data used in the enumeration of totally real
235
+ fields for relative extensions.
236
+
237
+ We do not give a complete description here. For more information,
238
+ see the attached functions; all of these are used internally by the
239
+ functions in totallyreal_rel.py, so see that file for examples and
240
+ further documentation.
241
+ """
242
+
243
+ def __init__(self, F, m, B, a=None):
244
+ r"""
245
+ Initialization routine (constructor).
246
+
247
+ INPUT:
248
+
249
+ - ``F`` -- number field; the base field
250
+ - ``m`` -- integer; the relative degree
251
+ - ``B`` -- integer; the discriminant bound
252
+ - ``a`` -- list (default: ``[]``); the coefficient list to begin with,
253
+ corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))``
254
+
255
+ OUTPUT:
256
+
257
+ the data initialized to begin enumeration of totally real fields
258
+ with base field `F`, degree `n`, discriminant bounded by `B`, and starting
259
+ with coefficients `a`.
260
+
261
+ EXAMPLES::
262
+
263
+ sage: x = polygen(ZZ, 'x')
264
+ sage: F.<t> = NumberField(x^2 - 2)
265
+ sage: T = sage.rings.number_field.totallyreal_rel.tr_data_rel(F, 2, 2000)
266
+ """
267
+ if a is None: # don't make the stupid noob mistake of putting a=[]
268
+ a = [] # in the function signature above.
269
+
270
+ # Initialize constants.
271
+ self.m = m
272
+ d = F.degree()
273
+ self.d = d
274
+ self.n = n = m*d
275
+ self.B = B
276
+ self.gamma = hermite_constant(self.n-self.d)
277
+
278
+ self.F = F
279
+ self.Z_F = F.maximal_order()
280
+ self.Foo = F.real_embeddings()
281
+ self.dF = abs(F.disc())
282
+ self.Fx = PolynomialRing(F, 'xF')
283
+
284
+ self.beta = [[]]*m
285
+ self.gnk = [[]]*m
286
+
287
+ self.trace_elts = []
288
+
289
+ Z_Fbasis = self.Z_F.basis()
290
+
291
+ # Initialize variables.
292
+ if not a:
293
+ # No starting input, all polynomials will be found; initialize to zero.
294
+ self.a = [0]*m + [1]
295
+ self.amaxvals = [[]]*m
296
+ anm1s = [[i] for i in range(0,m//2+1)]
297
+ for i in range(1,self.d):
298
+ for j in range(len(anm1s)):
299
+ anm1s[j] = [anm1s[j] + [i] for i in range(m)]
300
+ anm1s = sum(anm1s, [])
301
+ anm1s = [sum([Z_Fbasis[i] * aa[i] for i in range(self.d)]) for aa in anm1s]
302
+ # Minimize trace in class.
303
+ import numpy
304
+ for i in range(len(anm1s)):
305
+ Q = [[v(m*x) for v in self.Foo] + [0] for x in Z_Fbasis] + [[v(anm1s[i]) for v in self.Foo] + [10**6]]
306
+ pari_string = '[' + ';'.join(','.join("%s" % ii for ii in row) for row in zip(*Q)) + ']'
307
+ adj = pari(pari_string).qflll()[self.d]
308
+ anm1s[i] += sum([m*Z_Fbasis[ii]*int(adj[ii])//int(adj[self.d]) for ii in range(self.d)])
309
+
310
+ self.amaxvals[m-1] = anm1s
311
+ self.a[m-1] = self.amaxvals[m-1].pop()
312
+ self.k = m-2
313
+
314
+ bl = math.ceil(1.7719*self.n)
315
+ br = max([1./m*(am1**2).trace() +
316
+ self.gamma*(1./(m**d)*self.B/self.dF)**(1./(self.n-d))
317
+ for am1 in anm1s])
318
+ br = math.floor(br)
319
+ T2s = self.F._positive_integral_elements_with_trace([bl, br])
320
+ self.trace_elts.append([bl, br, T2s])
321
+
322
+ elif len(a) <= m + 1:
323
+ # First few coefficients have been specified.
324
+ # The value of k is the largest index of the coefficients of a which is
325
+ # currently unknown; e.g., if k == -1, then we can iterate
326
+ # over polynomials, and if k == n-1, then we have finished iterating.
327
+ if a[len(a)-1] != 1:
328
+ raise ValueError("a[len(a)-1](=%s) must be 1 so polynomial is monic" % a[len(a)-1])
329
+
330
+ raise NotImplementedError("These have not been checked.")
331
+
332
+ k = m-len(a)
333
+ self.k = k
334
+ a = [0]*(k+1) + a
335
+ self.amaxvals = [[]]*m
336
+ for i in range(n+1):
337
+ self.a[i] = a[i]
338
+
339
+ # Bounds come from an application of Lagrange multipliers in degrees 2,3.
340
+ self.b_lower = [-1./m*(v(self.a[m-1]) +
341
+ (m-1.)*math.sqrt(v(self.a[m-1])**2 - 2.*(1+1./(m-1))*v(self.a[m-2]))) for v in self.Foo]
342
+ self.b_upper = [-1./m*(v(self.a[m-1]) -
343
+ (m-1.)*math.sqrt(v(self.a[m-1])**2 - 2.*(1+1./(m-1))*v(self.a[m-2]))) for v in self.Foo]
344
+ if k < m - 2:
345
+ bminmax = [lagrange_degree_3(n,v(self.a[m-1]),v(self.a[m-2]),v(self.a[m-3])) for v in self.Foo]
346
+ self.b_lower = bminmax[0]
347
+ self.b_upper = bminmax[1]
348
+
349
+ # Annoying, but must reverse coefficients for numpy.
350
+ gnk = [binomial(j,k+2)*a[j] for j in range(k+2,n+1)]
351
+ self.beta[k+1] = [[self.b_lower] + numpy.roots([v(gnk[i]) for i in range(len(gnk))].reverse()).tolist().sort() + [self.b_upper] for v in self.Foo]
352
+
353
+ # Now to really initialize gnk.
354
+ self.gnk[k+1] = [[0] + [binomial(j,k+1)*v(a[j])
355
+ for j in range(k+2,m+1)] for v in self.Foo]
356
+ else:
357
+ # Bad input!
358
+ raise ValueError("a has length %s > m+1" % len(a))
359
+
360
+ def incr(self, f_out, verbose=False, haltk=0):
361
+ r"""
362
+ 'Increment' the totally real data to the next
363
+ value which satisfies the bounds essentially given by Rolle's
364
+ theorem, and return the next polynomial in the sequence
365
+ ``f_out``.
366
+
367
+ The default or usual case just increments the constant
368
+ coefficient; then inductively, if this is outside of the
369
+ bounds we increment the next higher coefficient, and so on.
370
+
371
+ If there are no more coefficients to be had, returns the zero
372
+ polynomial.
373
+
374
+ INPUT:
375
+
376
+ - ``f_out`` -- integer sequence; to be written with the coefficients of
377
+ the next polynomial
378
+ - ``verbose`` -- boolean or nonnegative integer (default: ``False``);
379
+ print verbosely computational details. It prints extra information if
380
+ ``verbose`` is set to ``2`` or more.
381
+ - ``haltk`` -- integer; the level at which to halt the inductive
382
+ coefficient bounds
383
+
384
+ OUTPUT: the successor polynomial as a coefficient list
385
+ """
386
+ import numpy
387
+
388
+ m = self.m
389
+ k = self.k
390
+ d = self.d
391
+
392
+ # If k == -1, we have a full polynomial, so we add 1 to the constant coefficient.
393
+ if k == -1:
394
+ if len(self.amaxvals[0]) > 0 and self.amaxvals[0]:
395
+ self.a[0] = self.amaxvals[0].pop()
396
+ for i in range(0,m):
397
+ f_out[i] = self.a[i]
398
+ return
399
+ else:
400
+ if verbose:
401
+ print(" finished")
402
+
403
+ # Already reached maximum, so "carry the 1" to find the next value of k.
404
+ k += 1
405
+ while k < m and len(self.amaxvals[k]) == 0:
406
+ k += 1
407
+ if k < m:
408
+ self.a[k] = self.amaxvals[k].pop()
409
+ k -= 1
410
+
411
+ # If we are working through an initialization routine, treat that.
412
+ elif haltk and k == haltk-1:
413
+ if len(self.maxvals[k]) == 0:
414
+ k += 1
415
+ while k <= m-1 and len(self.amaxvals[k]) == 0:
416
+ k += 1
417
+ if k < m:
418
+ self.a[k] = self.amaxvals[k].pop()
419
+ k -= 1
420
+
421
+ # If in the previous step we finished all possible values of
422
+ # the lastmost coefficient, so we must compute bounds on the next coefficient.
423
+ # Recall k == n-1 implies iteration is complete.
424
+ while k < m-1:
425
+ # maxoutflag flags a required abort along the way
426
+ maxoutflag = False
427
+
428
+ # Recall k == -1 means all coefficients are good to go.
429
+ while k >= 0 and (not haltk or k >= haltk):
430
+ if verbose:
431
+ print(k, ":", end="")
432
+ for i in range(self.m + 1):
433
+ print(self.a[i], end="")
434
+ print("")
435
+
436
+ if k == m - 2:
437
+ # We only know the value of a[n-1], the trace.
438
+ bl = max(math.ceil(1.7719*self.n), ((self.a[m-1]**2).trace()*1./m))
439
+ br = 1./m*(self.a[m-1]**2).trace() + \
440
+ self.gamma*(1./(m**d)*self.B/self.dF)**(1./(self.n-d))
441
+ br = math.floor(br)
442
+
443
+ # Check for trivially empty.
444
+ if bl > br:
445
+ if verbose:
446
+ print(" ", br, ">", bl)
447
+ maxoutflag = 1
448
+ break
449
+
450
+ if verbose >= 2:
451
+ print(" bl, br:", bl, br)
452
+
453
+ # Enumerate all elements of Z_F with T_2 <= br
454
+ T2s = []
455
+ trace_elts_found = False
456
+ for tre in self.trace_elts:
457
+ if tre[0] <= bl and tre[1] >= br:
458
+ trace_elts_found = True
459
+ if verbose >= 2:
460
+ print(" found copy!")
461
+ T2s.extend(theta for theta in tre[2]
462
+ if bl <= theta.trace() <= br)
463
+ break
464
+ if not trace_elts_found:
465
+ T2s = self.F._positive_integral_elements_with_trace([bl,br])
466
+ self.trace_elts.append([bl,br,T2s])
467
+
468
+ # Now ensure that T2 satisfies the correct parity condition
469
+ am2s = []
470
+ for t2 in T2s:
471
+ am2 = (self.a[m-1]**2-t2)/2
472
+ if am2.is_integral():
473
+ ispositive = True
474
+ for v in self.Foo:
475
+ ispositive = ispositive and v((m-1)*self.a[m-1]**2-2*m*am2) > 0
476
+ if ispositive:
477
+ am2s.append(am2)
478
+
479
+ if verbose >= 2:
480
+ print(" am2s:", am2s)
481
+
482
+ # If none survive, break!
483
+ if len(am2s) == 0:
484
+ if verbose:
485
+ print(" finished")
486
+ maxoutflag = 1
487
+ break
488
+
489
+ self.amaxvals[m-2] = am2s
490
+ self.a[m-2] = self.amaxvals[m-2].pop()
491
+
492
+ # Initialize the second derivative.
493
+ self.b_lower = [-1./m*(v(self.a[m-1]) +
494
+ (m-1.)*math.sqrt(v(self.a[m-1])**2 - 2.*(1+1./(m-1))*v(self.a[m-2]))) for v in self.Foo]
495
+ self.b_upper = [-1./m*(v(self.a[m-1]) -
496
+ (m-1.)*math.sqrt(v(self.a[m-1])**2 - 2.*(1+1./(m-1))*v(self.a[m-2]))) for v in self.Foo]
497
+ self.beta[k] = [[self.b_lower[i], -self.Foo[i](self.a[m-1])/m, self.b_upper[i]] for i in range(d)]
498
+ self.gnk[k] = [0, (m-1)*self.a[m-1], m*(m-1)/2]
499
+
500
+ if verbose >= 2:
501
+ print(" betak:", self.beta[k])
502
+ else:
503
+ # Compute the roots of the derivative.
504
+ self.gnk[k+1][0] = self.a[k+1]
505
+ gnk = self.gnk[k+1]
506
+ self.beta[k] = [numpy.roots([v(gnk[len(gnk)-1-i]) for i in range(len(gnk))]).tolist() for v in self.Foo]
507
+
508
+ try:
509
+ for i in range(d):
510
+ self.beta[k][i].sort()
511
+ except TypeError:
512
+ if verbose:
513
+ print(" betak:", self.beta[k])
514
+ maxoutflag = True
515
+ break
516
+
517
+ # Check for double roots
518
+ for i in range(len(self.beta[k][0])-1):
519
+ if abs(self.beta[k][0][i] - self.beta[k][0][i+1]) < 2*eps_global:
520
+ # This happens reasonably infrequently, so calling
521
+ # the Python routine should be sufficiently fast...
522
+ f = self.Fx(self.gnk[k+1])
523
+ df = self.Fx(self.gnk[k+2])
524
+ if gcd(f,df) != 1:
525
+ if verbose:
526
+ print(" gnk has multiple factor!")
527
+ maxoutflag = True
528
+ break
529
+ if maxoutflag:
530
+ break
531
+
532
+ if k == m-3:
533
+ self.b_lower = [-1./m*(v(self.a[m-1]) +
534
+ (m-1.)*math.sqrt(v(self.a[m-1])**2 - 2.*(1+1./(m-1))*v(self.a[m-2]))) for v in self.Foo]
535
+ self.b_upper = [-1./m*(v(self.a[m-1]) -
536
+ (m-1.)*math.sqrt(v(self.a[m-1])**2 - 2.*(1+1./(m-1))*v(self.a[m-2]))) for v in self.Foo]
537
+ elif k == m-4:
538
+ # New bounds from Lagrange multiplier in degree 3.
539
+ bminmax = [lagrange_degree_3(m,v(self.a[m-1]),v(self.a[m-2]),v(self.a[m-3])) for v in self.Foo]
540
+ self.b_lower = [bminmax[i][0] for i in range(len(bminmax))]
541
+ self.b_upper = [bminmax[i][1] for i in range(len(bminmax))]
542
+
543
+ self.beta[k] = [[self.b_lower[i]] + self.beta[k][i] + [self.b_upper[i]] for i in range(len(self.beta[k]))]
544
+
545
+ if verbose >= 2:
546
+ print(" betak:", self.beta[k])
547
+
548
+ # Compute next g_(m-(k+1)), k times the formal integral of g_(m-k).
549
+ self.gnk[k] = [self.F.primitive_element()*0] + [self.gnk[k+1][i-1]*(k+1)/i for i in range(1,m-k+1)]
550
+ gnk = self.gnk[k]
551
+ gnks = [[v(gnk[len(gnk)-1-i])
552
+ for i in range(len(gnk))]
553
+ for v in self.Foo]
554
+ gnkm1 = self.gnk[k+1]
555
+ gnkm1s = [[v(gnkm1[len(gnkm1)-1-i])
556
+ for i in range(len(gnkm1))]
557
+ for v in self.Foo]
558
+ mk = m - (k + 1)
559
+
560
+ if verbose >= 2:
561
+ print(" gnk:", self.gnk[k])
562
+ print(" gnks:", gnks)
563
+
564
+ # Compute upper and lower bounds which guarantee one retains
565
+ # a polynomial with all real roots.
566
+ betak = self.beta[k]
567
+ akmin = [-numpy.polyval(gnks[j], betak[j][mk+1]) -
568
+ abs(numpy.polyval(gnkm1s[j], betak[j][mk+1]))*eps_global for j in range(self.d)]
569
+ for i in range(1,(mk+1)//2+1):
570
+ # Use the fact that f(z) <= f(x)+|f'(x)|eps if |x-z| < eps
571
+ # for sufficiently small eps, f(z) = 0, and f''(z) < 0.
572
+ akmin = [max(akmin[j],
573
+ -numpy.polyval(gnks[j], betak[j][mk+1-2*i]) -
574
+ abs(numpy.polyval(gnkm1s[j], betak[j][mk+1-2*i])*eps_global)) for j in range(self.d)]
575
+
576
+ akmax = [-numpy.polyval(gnks[j], betak[j][mk]) +
577
+ abs(numpy.polyval(gnkm1s[j], betak[j][mk]))*eps_global for j in range(self.d)]
578
+ for i in range(1, mk//2+1):
579
+ akmax = [min(akmax[j],
580
+ -numpy.polyval(gnks[j], betak[j][mk-2*i]) +
581
+ abs(numpy.polyval(gnkm1s[j], betak[j][mk-2*i])*eps_global)) for j in range(self.d)]
582
+
583
+ if verbose >= 2:
584
+ print(" akmin:", akmin)
585
+ print(" akmax:", akmax)
586
+
587
+ for i in range(self.d):
588
+ if akmin[i] > akmax[i]:
589
+ if verbose:
590
+ print(" ", akmin[i], ">", akmax[i])
591
+ maxoutflag = 1
592
+ break
593
+ if maxoutflag:
594
+ break
595
+
596
+ self.amaxvals[k] = integral_elements_in_box(self.F, [[akmin[i],akmax[i]] for i in range(d)])
597
+ if k == 0:
598
+ a0s = [0, -sum([self.a[i] for i in range(1,m+1)]),
599
+ -sum([self.a[i]*(-1)**i for i in range(1,m+1)]),
600
+ -sum([self.a[i]*2**i for i in range(1,m+1)]),
601
+ -sum([self.a[i]*(-2)**i for i in range(1,m+1)])]
602
+ for a0 in a0s:
603
+ try:
604
+ self.amaxvals[0].remove(a0)
605
+ except Exception:
606
+ pass
607
+
608
+ if verbose:
609
+ print(" amaxvals[k]:", self.amaxvals[k])
610
+ if len(self.amaxvals[k]) == 0:
611
+ if verbose:
612
+ print(" finished")
613
+ maxoutflag = True
614
+ break
615
+ self.a[k] = self.amaxvals[k].pop()
616
+
617
+ self.k -= 1
618
+ k -= 1
619
+
620
+ if not maxoutflag:
621
+ self.k = k
622
+ for i in range(m):
623
+ f_out[i] = self.a[i]
624
+ return
625
+ else:
626
+ k += 1
627
+ while k < m and len(self.amaxvals[k]) == 0:
628
+ k += 1
629
+ if k < m:
630
+ self.a[k] = self.amaxvals[k].pop()
631
+ k -= 1
632
+
633
+ # k == n-1, so iteration is complete; return the zero polynomial (of degree n+1).
634
+ self.k = k
635
+ f_out[m] = 0
636
+ return
637
+
638
+
639
+ # ****************************************************************************
640
+ # Main routine
641
+ # ****************************************************************************
642
+
643
+ def enumerate_totallyreal_fields_rel(F, m, B, a=[], verbose=0,
644
+ return_seqs=False,
645
+ return_pari_objects=True):
646
+ r"""
647
+ This function enumerates (primitive) totally real field extensions of
648
+ degree `m>1` of the totally real field F with discriminant `d \leq B`;
649
+ optionally one can specify the first few coefficients, where the sequence ``a``
650
+ corresponds to a polynomial by
651
+
652
+ ::
653
+
654
+ a[k]*x^m + ... + a[0]*x^(m-k)
655
+
656
+ if ``length(a) = k+1``, so in particular always ``a[k] = 1``.
657
+
658
+ .. NOTE::
659
+
660
+ This is guaranteed to give all primitive such fields, and
661
+ seems in practice to give many imprimitive ones.
662
+
663
+ INPUT:
664
+
665
+ - ``F`` -- number field; the base field
666
+ - ``m`` -- integer; the degree
667
+ - ``B`` -- integer; the discriminant bound
668
+ - ``a`` -- list (default: ``[]``); the coefficient list to begin with
669
+ - ``verbose`` -- boolean or nonnegative integer or string (default: 0);
670
+ give a verbose description of the computations being performed. If
671
+ ``verbose`` is set to ``2`` or more then it outputs some extra
672
+ information. If ``verbose`` is a string then it outputs to a file
673
+ specified by ``verbose``.
674
+ - ``return_seqs`` -- boolean (default: ``False``); if ``True``, then return
675
+ the polynomials as sequences (for easier exporting to a file). This
676
+ also returns a list of four numbers, as explained in the OUTPUT
677
+ section below.
678
+ - ``return_pari_objects`` -- boolean (default: ``True``); if both
679
+ ``return_seqs`` and ``return_pari_objects`` are ``False`` then it returns
680
+ the elements as Sage objects; otherwise it returns PARI objects.
681
+
682
+ OUTPUT:
683
+
684
+ - the list of fields with entries ``[d,fabs,f]``, where ``d`` is the
685
+ discriminant, ``fabs`` is an absolute defining polynomial, and ``f``
686
+ is a defining polynomial relative to `F`, sorted by discriminant.
687
+
688
+ - if ``return_seqs`` is ``True``, then the first field of the list is
689
+ a list containing the count of four items as explained below
690
+
691
+ - the first entry gives the number of polynomials tested
692
+ - the second entry gives the number of polynomials with its
693
+ discriminant having a large enough square divisor
694
+ - the third entry is the number of irreducible polynomials
695
+ - the fourth entry is the number of irreducible polynomials with
696
+ discriminant at most `B`
697
+
698
+ EXAMPLES::
699
+
700
+ sage: ZZx.<x> = ZZ[]
701
+ sage: F.<t> = NumberField(x^2 - 2)
702
+ sage: enumerate_totallyreal_fields_rel(F, 1, 2000)
703
+ [[1, [-2, 0, 1], xF - 1]]
704
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
705
+ [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]
706
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True)
707
+ [[9, 6, 5, 0], [[1600, [4, 0, -6, 0, 1], [-1, 1, 1]]]]
708
+
709
+ TESTS:
710
+
711
+ Each of the outputs must be elements of Sage if ``return_pari_objects``
712
+ is set to ``False``::
713
+
714
+ sage: type(enumerate_totallyreal_fields_rel(F, 2, 2000)[0][1])
715
+ <class 'cypari2.gen.Gen'>
716
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_pari_objects=False)[0][0].parent()
717
+ Integer Ring
718
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_pari_objects=False)[0][1].parent()
719
+ Univariate Polynomial Ring in x over Rational Field
720
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_pari_objects=False)[0][2].parent()
721
+ Univariate Polynomial Ring in xF over Number Field in t with defining polynomial x^2 - 2
722
+ sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True)[1][0][1][0].parent()
723
+ Rational Field
724
+
725
+ AUTHORS:
726
+
727
+ - John Voight (2007-11-01)
728
+ """
729
+
730
+ if not isinstance(m, Integer):
731
+ try:
732
+ m = Integer(m)
733
+ except TypeError:
734
+ raise TypeError("cannot coerce m (= %s) to an integer" % m)
735
+ if (m < 1):
736
+ raise ValueError("m must be at least 1.")
737
+
738
+ n = F.degree()*m
739
+
740
+ # Initialize
741
+ S = {} # dictionary of the form {(d, fabs): f, ...}
742
+ dB_odlyzko = odlyzko_bound_totallyreal(n)
743
+ dB = math.ceil(40000*dB_odlyzko**n)
744
+ counts = [0,0,0,0]
745
+
746
+ # Trivial case
747
+ if m == 1:
748
+ g = pari(F.defining_polynomial()).polrecip().Vec()
749
+ if return_seqs:
750
+ return [[0,0,0,0], [1, [-1, 1], g]]
751
+ elif return_pari_objects:
752
+ return [[1, g, pari('xF-1')]]
753
+ else:
754
+ Px = PolynomialRing(QQ, 'xF')
755
+ return [[ZZ(1), [QQ(_) for _ in g], Px.gen()-1]]
756
+
757
+ if verbose:
758
+ saveout = sys.stdout
759
+ if isinstance(verbose, str):
760
+ fsock = open(verbose, 'w')
761
+ sys.stdout = fsock
762
+ # Else, print to screen
763
+ f_out = [0]*m + [1]
764
+ T = tr_data_rel(F, m, B, a)
765
+ if verbose == 2:
766
+ T.incr(f_out,verbose)
767
+ else:
768
+ T.incr(f_out)
769
+
770
+ Fx = PolynomialRing(F, 'xF')
771
+
772
+ nfF = pari(str(F.defining_polynomial()).replace('x',
773
+ str(F.primitive_element())))
774
+ parit = pari(str(F.primitive_element()))
775
+
776
+ while f_out[m] != 0:
777
+ counts[0] += 1
778
+ if verbose:
779
+ print("==>", f_out, end="")
780
+
781
+ f_str = ''
782
+ for i in range(len(f_out)):
783
+ f_str += '(' + str(f_out[i]) + ')*x^' + str(i)
784
+ if i < len(f_out)-1:
785
+ f_str += '+'
786
+ nf = pari(f_str)
787
+ if nf.poldegree('t') == 0:
788
+ nf = nf.subst('x', 'x-t')
789
+ nf = nf.polresultant(nfF, parit) # either monic or -monic
790
+ if nf[n] == -1:
791
+ nf *= -1
792
+ d = nf.poldisc()
793
+ #counts[0] += 1
794
+ if d > 0 and nf.polsturm() == n:
795
+ da = int_has_small_square_divisor(Integer(d))
796
+ if d > dB or d <= B*da:
797
+ counts[1] += 1
798
+ if nf.polisirreducible():
799
+ counts[2] += 1
800
+ zk, d = nf.nfbasis_d()
801
+
802
+ if d <= B:
803
+ if verbose:
804
+ print("has discriminant", d, end="")
805
+
806
+ # Find a minimal lattice element
807
+ counts[3] += 1
808
+ ng = pari([nf,zk]).polredabs()
809
+
810
+ # Check if K is contained in the list.
811
+ if (d, ng) in S:
812
+ if verbose:
813
+ print("but is not new")
814
+ else:
815
+ if verbose:
816
+ print("and is new!")
817
+ S[(d, ng)] = Fx(f_out)
818
+ else:
819
+ if verbose:
820
+ print("has discriminant", abs(d), "> B")
821
+ else:
822
+ if verbose:
823
+ print("is not absolutely irreducible")
824
+ else:
825
+ if verbose:
826
+ print("has discriminant", abs(d), "with no large enough square divisor")
827
+ else:
828
+ if verbose:
829
+ if d == 0:
830
+ print("is not squarefree")
831
+ else:
832
+ print("is not totally real")
833
+ if verbose == 2:
834
+ T.incr(f_out,verbose=verbose)
835
+ else:
836
+ T.incr(f_out)
837
+
838
+ # In the application of Smyth's theorem above, we exclude finitely
839
+ # many possibilities which we must now throw back in.
840
+ if m == 2:
841
+ if Fx([-1,1,1]).is_irreducible():
842
+ K = F.extension(Fx([-1,1,1]), 'tK')
843
+ Kabs = K.absolute_field('tKabs')
844
+ Kabs_pari = pari(Kabs.defining_polynomial())
845
+ d = K.absolute_discriminant()
846
+ if abs(d) <= B:
847
+ ng = Kabs_pari.polredabs()
848
+ S[(d, ng)] = Fx([-1,1,1])
849
+ elif F.degree() == 2:
850
+ for ff in [[1,-7,13,-7,1],[1,-8,14,-7,1]]:
851
+ f = Fx(ff).factor()[0][0]
852
+ K = F.extension(f, 'tK')
853
+ Kabs = K.absolute_field('tKabs')
854
+ Kabs_pari = pari(Kabs.defining_polynomial())
855
+ d = K.absolute_discriminant()
856
+ if abs(d) <= B:
857
+ ng = Kabs_pari.polredabs()
858
+ S[(d, ng)] = f
859
+ elif m == 3:
860
+ if Fx([-1, 6, -5, 1]).is_irreducible():
861
+ K = F.extension(Fx([-1, 6, -5, 1]), 'tK')
862
+ Kabs = K.absolute_field('tKabs')
863
+ Kabs_pari = pari(Kabs.defining_polynomial())
864
+ d = K.absolute_discriminant()
865
+ if abs(d) <= B:
866
+ ng = Kabs_pari.polredabs()
867
+ S[(d, ng)] = Fx([-1, 6, -5, 1])
868
+
869
+ # Convert S to a sorted list of triples [d, fabs, f], taking care
870
+ # not to use the comparison operators on PARI polynomials.
871
+ S = [[s[0], s[1], t] for s, t in S.items()]
872
+ S.sort(key=lambda x: (x[0], [QQ(cf) for cf in x[1].polrecip().Vec()]))
873
+
874
+ # Now check for isomorphic fields
875
+ weed_fields(S)
876
+
877
+ # Output.
878
+ if verbose:
879
+ print("=" * 80)
880
+ print("Polynomials tested: {}".format(counts[0]))
881
+ print("Polynomials with discriminant with large enough square"
882
+ " divisor: {}".format(counts[1]))
883
+ print("Irreducible polynomials: {}".format(counts[2]))
884
+ print("Polynomials with nfdisc <= B: {}".format(counts[3]))
885
+ for i in range(len(S)):
886
+ print(S[i])
887
+ if isinstance(verbose, str):
888
+ fsock.close()
889
+ sys.stdout = saveout
890
+
891
+ # Make sure to return elements that belong to Sage
892
+ if return_seqs:
893
+ return [[ZZ(x) for x in counts],
894
+ [[s[0], [QQ(x) for x in s[1].polrecip().Vec()],
895
+ s[2].coefficients(sparse=False)]
896
+ for s in S]]
897
+ elif return_pari_objects:
898
+ return S
899
+ else:
900
+ Px = PolynomialRing(QQ, 'x')
901
+ return [[s[0], Px([QQ(_) for _ in s[1].list()]), s[2]] for s in S]
902
+
903
+
904
+ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False,
905
+ return_pari_objects=True):
906
+ r"""
907
+ Enumerate *all* totally real fields of degree ``n`` with discriminant
908
+ at most ``B``, primitive or otherwise.
909
+
910
+ INPUT:
911
+
912
+ - ``n`` -- integer; the degree
913
+ - ``B`` -- integer; the discriminant bound
914
+ - ``verbose`` -- boolean or nonnegative integer or string (default: 0);
915
+ give a verbose description of the computations being performed. If
916
+ ``verbose`` is set to ``2`` or more, it outputs some extra information.
917
+ If ``verbose`` is a string, it outputs to a file specified by ``verbose``.
918
+ - ``return_seqs`` -- boolean (default: ``False``); if ``True``, then return
919
+ the polynomials as sequences (for easier exporting to a file). This
920
+ also returns a list of four numbers, as explained in the OUTPUT
921
+ section below.
922
+ - ``return_pari_objects`` -- boolean (default: ``True``); if both
923
+ ``return_seqs`` and ``return_pari_objects`` are ``False`` then it
924
+ returns the elements as Sage objects; otherwise it returns PARI objects.
925
+
926
+ EXAMPLES::
927
+
928
+ sage: enumerate_totallyreal_fields_all(4, 2000)
929
+ [[725, x^4 - x^3 - 3*x^2 + x + 1],
930
+ [1125, x^4 - x^3 - 4*x^2 + 4*x + 1],
931
+ [1600, x^4 - 6*x^2 + 4],
932
+ [1957, x^4 - 4*x^2 - x + 1],
933
+ [2000, x^4 - 5*x^2 + 5]]
934
+ sage: enumerate_totallyreal_fields_all(1, 10)
935
+ [[1, x - 1]]
936
+
937
+ TESTS:
938
+
939
+ Each of the outputs must be elements of Sage if ``return_pari_objects``
940
+ is set to ``False``::
941
+
942
+ sage: enumerate_totallyreal_fields_all(2, 10)
943
+ [[5, x^2 - x - 1], [8, x^2 - 2]]
944
+ sage: type(enumerate_totallyreal_fields_all(2, 10)[0][1])
945
+ <class 'cypari2.gen.Gen'>
946
+ sage: enumerate_totallyreal_fields_all(2, 10, return_pari_objects=False)[0][1].parent()
947
+ Univariate Polynomial Ring in x over Rational Field
948
+
949
+ In practice most of these will be found by
950
+ :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`,
951
+ which is guaranteed to return all primitive fields but often returns
952
+ many non-primitive ones as well. For instance, only one of the five
953
+ fields in the example above is primitive, but
954
+ :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`
955
+ finds four out of the five (the exception being `x^4 - 6x^2 + 4`).
956
+
957
+ The following was fixed in :issue:`13101`::
958
+
959
+ sage: enumerate_totallyreal_fields_all(8, 10^6) # long time (about 2 s)
960
+ []
961
+ """
962
+ S = []
963
+ counts = [0, 0, 0, 0]
964
+ div_n = divisors(n)
965
+ if len(div_n) > 4:
966
+ raise ValueError("Only implemented for n = p*q with p,q prime")
967
+ for d in div_n:
968
+ if 1 < d < n:
969
+ Sds = enumerate_totallyreal_fields_prim(d, int(math.floor((1.*B)**(1.*d/n))), verbose=verbose)
970
+ for i in range(len(Sds)):
971
+ if verbose:
972
+ print("=" * 80)
973
+ print("Taking F =", Sds[i][1])
974
+ F = NumberField(ZZx(Sds[i][1]), 't')
975
+ T = enumerate_totallyreal_fields_rel(F, n/d, B, verbose=verbose, return_seqs=return_seqs)
976
+ if return_seqs:
977
+ for k in range(4):
978
+ counts[k] += T[0][k]
979
+ S += [[t[0],pari(t[1]).Polrev()] for t in T[1]]
980
+ else:
981
+ S += [[t[0],t[1]] for t in T]
982
+ for E in enumerate_totallyreal_fields_prim(n/d, int(math.floor((1.*B)**(1./d)/(1.*Sds[i][0])**(n*1./d**2)))):
983
+ for EF in F.composite_fields(NumberField(ZZx(E[1]), 'u')):
984
+ if EF.degree() == n and EF.disc() <= B:
985
+ S.append([EF.disc(), pari(EF.absolute_polynomial())])
986
+ S += enumerate_totallyreal_fields_prim(n, B, verbose=verbose)
987
+ S.sort(key=lambda x: (x[0], [QQ(cf) for cf in x[1].polrecip().Vec()]))
988
+ weed_fields(S)
989
+
990
+ # Output.
991
+ if verbose:
992
+ saveout = sys.stdout
993
+ if isinstance(verbose, str):
994
+ fsock = open(verbose, 'w')
995
+ sys.stdout = fsock
996
+ # Else, print to screen
997
+ print("=" * 80)
998
+ print("Polynomials tested: {}".format(counts[0]))
999
+ print("Polynomials with discriminant with large enough square"
1000
+ " divisor: {}".format(counts[1]))
1001
+ print("Irreducible polynomials: {}".format(counts[2]))
1002
+ print("Polynomials with nfdisc <= B: {}".format(counts[3]))
1003
+ for i in range(len(S)):
1004
+ print(S[i])
1005
+ if isinstance(verbose, str):
1006
+ fsock.close()
1007
+ sys.stdout = saveout
1008
+
1009
+ # Make sure to return elements that belong to Sage
1010
+ if return_seqs:
1011
+ return [[ZZ(_) for _ in counts],
1012
+ [[ZZ(s[0]), [QQ(_) for _ in s[1].polrecip().Vec()]] for s in S]]
1013
+ elif return_pari_objects:
1014
+ return S
1015
+ else:
1016
+ Px = PolynomialRing(QQ, 'x')
1017
+ return [[ZZ(s[0]), Px([QQ(_) for _ in s[1].list()])]
1018
+ for s in S]