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,804 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.libs.pari
3
+ r"""
4
+ Ideals of (Not Necessarily Maximal) Orders in Number Fields
5
+
6
+ This module implements (integral) ideals of orders in number fields.
7
+
8
+ .. NOTE::
9
+
10
+ Currently, Sage only offers very limited functionality for
11
+ ideals of non-maximal orders (compared to the maximal case).
12
+ This should hopefully change in the future.
13
+
14
+ EXAMPLES::
15
+
16
+ sage: O = QuadraticField(-1).order(5*i)
17
+ sage: I = O.ideal([13, 5*i-1]); I
18
+ Ideal (60*a + 1, 65*a) of Order of conductor 5 generated by 5*a
19
+ in Number Field in a with defining polynomial x^2 + 1 with a = 1*I
20
+
21
+ An ideal of an order in a relative number field::
22
+
23
+ sage: x = polygen(ZZ, 'x')
24
+ sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3])
25
+ sage: O = K.order([3*a,2*b])
26
+ sage: I = O.ideal((-6*b + 6)*a + 6*b + 18); I
27
+ Ideal ((-60*b + 180)*a + 72, (-54*b + 174)*a - 6*b + 54, (-72*b + 288)*a + 72, 1872*a)
28
+ of Relative Order generated by [3*a - 2*b, -6*b*a + 6, 3*a]
29
+ in Number Field in a with defining polynomial x^2 + 1 over its base field
30
+
31
+ Perhaps the most useful functionality at this time is mapping ideals
32
+ of *quadratic* orders to corresponding binary quadratic forms::
33
+
34
+ sage: K.<t> = QuadraticField(-21463)
35
+ sage: O = K.order(t)
36
+ sage: I = O.ideal([123457, t + 45259]); I
37
+ Ideal (23058*t + 1, 123457*t) of Order of conductor 26 generated by t
38
+ in Number Field in t with defining polynomial x^2 + 21463 with t = 146.5025597046004?*I
39
+ sage: I.quadratic_form()
40
+ 123457*x^2 - 90518*x*y + 16592*y^2
41
+
42
+ .. TODO::
43
+
44
+ Generalize more functionality (such as primality testing and
45
+ factoring) from
46
+ :class:`~sage.rings.number_field.number_field_ideal.NumberFieldFractionalIdeal`
47
+ to ideals of not necessarily maximal orders.
48
+
49
+ AUTHORS:
50
+
51
+ - Lorenz Panny (2022)
52
+ """
53
+
54
+ # ****************************************************************************
55
+ # Copyright (C) 2022 Lorenz Panny
56
+ #
57
+ # This program is free software: you can redistribute it and/or modify
58
+ # it under the terms of the GNU General Public License as published by
59
+ # the Free Software Foundation, either version 2 of the License, or
60
+ # (at your option) any later version.
61
+ # https://www.gnu.org/licenses/
62
+ # ****************************************************************************
63
+
64
+ from sage.structure.richcmp import richcmp
65
+ from sage.structure.sequence import Sequence
66
+ from sage.rings.integer_ring import ZZ
67
+ from sage.rings.rational_field import QQ
68
+ from sage.modules.free_module_element import vector
69
+ from sage.rings.polynomial.polynomial_ring import polygens
70
+ from sage.rings.ideal import Ideal_generic
71
+
72
+ import sage.rings.number_field.order
73
+
74
+ # TODO I*u works when u lies in I.ring().number_field(), but u*I doesn't
75
+
76
+
77
+ def NumberFieldOrderIdeal(O, *args, **kwds):
78
+ r"""
79
+ Construct either a :class:`NumberFieldOrderIdeal_generic`
80
+ or a :class:`NumberFieldOrderIdeal_quadratic` from the
81
+ given arguments.
82
+
83
+ EXAMPLES::
84
+
85
+ sage: from sage.rings.number_field.order_ideal import NumberFieldOrderIdeal
86
+ sage: R.<x> = QQ[]
87
+ sage: K.<t> = NumberField(x^3 - 40)
88
+ sage: O = K.order(t)
89
+ sage: I = NumberFieldOrderIdeal(O, [13, t-1]); I
90
+ Ideal (12*t^2 + 1, 12*t^2 + t, 13*t^2) of Order generated by t
91
+ in Number Field in t with defining polynomial x^3 - 40
92
+ sage: K.absolute_degree()
93
+ 3
94
+ sage: type(I)
95
+ <class 'sage.rings.number_field.order_ideal.NumberFieldOrderIdeal_generic'>
96
+
97
+ ::
98
+
99
+ sage: L.<u> = QuadraticField(-3)
100
+ sage: J = NumberFieldOrderIdeal(L.maximal_order(), [(u+5)/2])
101
+ sage: L.absolute_degree()
102
+ 2
103
+ sage: type(J)
104
+ <class 'sage.rings.number_field.order_ideal.NumberFieldOrderIdeal_quadratic'>
105
+ """
106
+ if O.absolute_degree() == 2:
107
+ cls = NumberFieldOrderIdeal_quadratic
108
+ else:
109
+ cls = NumberFieldOrderIdeal_generic
110
+ return cls(O, *args, **kwds)
111
+
112
+
113
+ class NumberFieldOrderIdeal_generic(Ideal_generic):
114
+ r"""
115
+ An ideal of a not necessarily maximal order in a number field.
116
+ """
117
+ def __init__(self, O, gens, *, coerce=True):
118
+ r"""
119
+ Ideals of not necessarily maximal orders.
120
+
121
+ The preferred way to construct objects of this class is via
122
+ the :meth:`~sage.rings.number_field.order.Order.ideal` method.
123
+
124
+ EXAMPLES::
125
+
126
+ sage: R.<x> = QQ[]
127
+ sage: K.<t> = NumberField(x^3 - 40)
128
+ sage: O = K.order(t)
129
+ sage: I = O.ideal([13, t-1]); I
130
+ Ideal (12*t^2 + 1, 12*t^2 + t, 13*t^2) of Order generated by t
131
+ in Number Field in t with defining polynomial x^3 - 40
132
+ sage: I.norm()
133
+ 13
134
+ """
135
+ if not isinstance(O, sage.rings.number_field.order.Order):
136
+ raise TypeError('not a number-field order')
137
+
138
+ if not isinstance(gens, (list, tuple)):
139
+ gens = [gens]
140
+
141
+ if coerce:
142
+ gens = Sequence(gens, O)
143
+
144
+ _, from_V, to_V = O.number_field().absolute_vector_space()
145
+ span = [to_V(a*g) for a in O.basis() for g in gens]
146
+ self._module = O.free_module().submodule(span)
147
+ basis = [O(from_V(v)) for v in self._module.basis()]
148
+
149
+ super().__init__(O, basis, coerce=False)
150
+
151
+ def __hash__(self):
152
+ r"""
153
+ Return a hash value for this ideal.
154
+
155
+ EXAMPLES::
156
+
157
+ sage: hash(QuadraticField(-1).order(5*i).ideal(7)) # random
158
+ 42
159
+ """
160
+ return hash((NumberFieldOrderIdeal_generic, self.ring(), self._module))
161
+
162
+ def _richcmp_(self, other, op):
163
+ r"""
164
+ Implement comparison of ideals of number-field orders.
165
+
166
+ EXAMPLES::
167
+
168
+ sage: K.<t> = QuadraticField(-123)
169
+ sage: g, = K.ring_of_integers().ring_generators()
170
+ sage: O = K.order(567*g)
171
+ sage: I = O.ideal([191, 567*t-27]); I
172
+ Ideal (56133/2*t + 1/2, 108297*t) of Order of conductor 567 generated by 567/2*t + 1/2
173
+ in Number Field in t with defining polynomial x^2 + 123 with t = 11.09053650640942?*I
174
+ sage: I == I
175
+ True
176
+ sage: I != I
177
+ False
178
+ sage: I == I^2
179
+ False
180
+ """
181
+ if not isinstance(other, NumberFieldOrderIdeal_generic):
182
+ return NotImplemented
183
+ if self.ring() != other.ring():
184
+ return NotImplemented
185
+ return richcmp(self._module, other._module, op)
186
+
187
+ def _contains_(self, x):
188
+ r"""
189
+ Test whether this ideal contains a given element.
190
+
191
+ EXAMPLES::
192
+
193
+ sage: K.<t> = QuadraticField(-123)
194
+ sage: g, = K.ring_of_integers().ring_generators()
195
+ sage: O = K.order(567*g)
196
+ sage: I = O.ideal([191, 567*t-27]); I
197
+ Ideal (56133/2*t + 1/2, 108297*t) of Order of conductor 567 generated by 567/2*t + 1/2
198
+ in Number Field in t with defining polynomial x^2 + 123 with t = 11.09053650640942?*I
199
+ sage: 0 in I
200
+ True
201
+ sage: -191 in I
202
+ True
203
+ sage: 1 in I
204
+ False
205
+ sage: 567*t in I
206
+ False
207
+ sage: t-91 in I
208
+ False
209
+ sage: t-91 in K.maximal_order().ideal(I.gens(), future=1)
210
+ True
211
+ """
212
+ x = self.ring()(x)
213
+ return vector(QQ, x.list()) in self._module
214
+
215
+ def free_module(self):
216
+ r"""
217
+ Return the free `\ZZ`-module corresponding to this ideal
218
+ as a submodule of the vector space associated to the ambient
219
+ number field.
220
+
221
+ EXAMPLES::
222
+
223
+ sage: K.<t> = QuadraticField(-123)
224
+ sage: g, = K.ring_of_integers().ring_generators()
225
+ sage: O = K.order(567*g)
226
+ sage: I = O.ideal([191, 567*t-27]); I
227
+ Ideal (56133/2*t + 1/2, 108297*t) of Order of conductor 567 generated by 567/2*t + 1/2
228
+ in Number Field in t with defining polynomial x^2 + 123 with t = 11.09053650640942?*I
229
+ sage: I.free_module()
230
+ Free module of degree 2 and rank 2 over Integer Ring
231
+ Echelon basis matrix:
232
+ [ 1/2 56133/2]
233
+ [ 0 108297]
234
+ sage: I.free_module().is_submodule(O.free_module())
235
+ True
236
+
237
+ .. SEEALSO::
238
+
239
+ - :meth:`sage.rings.number_field.number_field.NumberField_absolute.absolute_vector_space`
240
+ - :meth:`sage.rings.number_field.order.Order.free_module`
241
+ - :meth:`sage.rings.number_field.number_field_ideal.NumberFieldIdeal.free_module`
242
+ """
243
+ return self._module
244
+
245
+ def norm(self):
246
+ r"""
247
+ Return the norm of this ideal.
248
+
249
+ The norm is defined as the index (as an abelian group)
250
+ of the ideal in its order.
251
+
252
+ EXAMPLES::
253
+
254
+ sage: K.<t> = QuadraticField(-123)
255
+ sage: g, = K.ring_of_integers().ring_generators()
256
+ sage: O = K.order(567*g)
257
+ sage: I = O.ideal([191, 567*t-27])
258
+ sage: I.norm()
259
+ 191
260
+ sage: (O.free_module() / I.free_module()).cardinality()
261
+ 191
262
+ """
263
+ return self.free_module().index_in(self.ring().free_module())
264
+
265
+
266
+ def _positive_sqrt(R, D):
267
+ r"""
268
+ Return the "positive" square root of `D` in `R`, which must be
269
+ a quadratic field or an order in a quadratic field.
270
+
271
+ EXAMPLES::
272
+
273
+ sage: from sage.rings.number_field.order_ideal import _positive_sqrt
274
+ sage: K = QuadraticField(-77)
275
+ sage: _positive_sqrt(K, 0)
276
+ 0
277
+ sage: _positive_sqrt(K, -77)
278
+ a
279
+ sage: x = polygen(ZZ)
280
+ sage: O.<t> = EquationOrder(x^2 - x - 1)
281
+ sage: _positive_sqrt(O, O.number_field().discriminant())
282
+ 2*t - 1
283
+ """
284
+ if D.is_zero():
285
+ return R.zero()
286
+ sqrtD, = (s for s in R(D).sqrt(all=True) if s.real() > 0 or s.imag() > 0)
287
+ return sqrtD
288
+
289
+
290
+ def _gens_from_bqf(O, Q):
291
+ r"""
292
+ Helper function to compute generators of the ideal associated to
293
+ the given binary quadratic form.
294
+
295
+ The resulting map induces a left-inverse of
296
+ :meth:`NumberFieldOrderIdeal_quadratic.quadratic_form`
297
+ on equivalence classes.
298
+
299
+ REFERENCES:
300
+
301
+ The correspondence itself is classical.
302
+ Implemented after [Coh1993]_, §5.2.
303
+
304
+ EXAMPLES::
305
+
306
+ sage: K.<a> = QuadraticField(-18511)
307
+ sage: O = K.order([83/2*a+1/2,83*a])
308
+ sage: I = O.ideal([7868666196280491149/2*a + 107/2, 12934030292704639127*a])
309
+ sage: F = I.quadratic_form(); F
310
+ 16673990859269835983*x^2 - 19847240181321592929*x*y + 5906098697962163510*y^2
311
+ sage: J = O.ideal(F); J
312
+ Ideal (7868666196280491149/2*a + 107/2, 12934030292704639127*a)
313
+ of Order of conductor 83 generated by 83/2*a + 1/2
314
+ in Number Field in a with defining polynomial x^2 + 18511 with a = 136.0551358824797?*I
315
+ sage: G = J.quadratic_form(); G
316
+ 16673990859269835983*x^2 - 19847240181321592929*x*y + 5906098697962163510*y^2
317
+ sage: u = -479159/2*a + 665/2
318
+ sage: J *= u; J
319
+ Ideal (19274211614964208316630114412627/2*a + 43763/2, 33600036954602803764386186323012*a)
320
+ of Order of conductor 83 generated by 83/2*a + 1/2
321
+ in Number Field in a with defining polynomial x^2 + 18511 with a = 136.0551358824797?*I
322
+ sage: H = J.quadratic_form()
323
+ sage: H.is_equivalent(F)
324
+ True
325
+
326
+ TESTS:
327
+
328
+ Randomized testing::
329
+
330
+ sage: from sage.rings.number_field.order_ideal import _random_for_testing
331
+ sage: O, random_ideal = _random_for_testing()
332
+ sage: I = random_ideal()
333
+ sage: F = I.quadratic_form()
334
+ sage: M = matrix.random_unimodular(MatrixSpace(ZZ,2))
335
+ sage: assert M.det() == 1
336
+ sage: G = F.matrix_action_left(M)
337
+ sage: G.discriminant() == F.discriminant()
338
+ True
339
+ sage: J = O.ideal(G, future=1)
340
+ sage: J.quadratic_form().is_equivalent(G)
341
+ True
342
+ """
343
+ D = O.discriminant()
344
+ if Q.discriminant() != O.discriminant():
345
+ raise ValueError('order and form must have the same discriminant')
346
+ a, b, c = Q
347
+ sqrtD = _positive_sqrt(O.number_field(), D)
348
+ g = (- b + sqrtD) / 2
349
+ t = sqrtD if a < 0 else 1
350
+ return a*t, g*t
351
+
352
+
353
+ class NumberFieldOrderIdeal_quadratic(NumberFieldOrderIdeal_generic):
354
+ r"""
355
+ An ideal of a not necessarily maximal order in a *quadratic* number field.
356
+ """
357
+ def __init__(self, O, gens, *, coerce=True):
358
+ r"""
359
+ Ideals of *quadratic* orders are implemented by a specialized
360
+ class because they have some extra features not present in
361
+ general number fields.
362
+
363
+ The preferred way to construct objects of this class is via
364
+ the :meth:`~sage.rings.number_field.order.Order.ideal` method
365
+ (or the ``O*a`` convenience syntax).
366
+
367
+ EXAMPLES::
368
+
369
+ sage: K.<t> = QuadraticField(-100)
370
+ sage: O = K.order(t)
371
+ sage: type(O.ideal(7))
372
+ <class 'sage.rings.number_field.order_ideal.NumberFieldOrderIdeal_quadratic'>
373
+ sage: O*7 == O.ideal(7)
374
+ True
375
+ """
376
+ from sage.quadratic_forms.binary_qf import BinaryQF
377
+ if isinstance(gens, BinaryQF):
378
+ gens = _gens_from_bqf(O, gens)
379
+ coerce = False
380
+ super().__init__(O, gens, coerce=coerce)
381
+
382
+ def conjugate(self):
383
+ r"""
384
+ Return the conjugate of this ideal, defined by conjugating
385
+ the generators.
386
+
387
+ EXAMPLES::
388
+
389
+ sage: K.<t> = QuadraticField(-123)
390
+ sage: g, = K.ring_of_integers().ring_generators()
391
+ sage: O = K.order(567*g)
392
+ sage: I = O.ideal([191, 567*t-27])
393
+ sage: I.norm()
394
+ 191
395
+ sage: I.norm() in I.conjugate() * I
396
+ True
397
+ sage: I.conjugate() * I == I.norm() * O
398
+ True
399
+ """
400
+ conj_gens = [g.conjugate() for g in self.gens()]
401
+ return NumberFieldOrderIdeal(self.ring(), conj_gens)
402
+
403
+ def gens_two(self) -> tuple:
404
+ r"""
405
+ Express this ideal using exactly two generators, the first of
406
+ which is a generator for the intersection of the ideal with `\ZZ`.
407
+
408
+ EXAMPLES::
409
+
410
+ sage: K.<t> = QuadraticField(-100)
411
+ sage: O = K.order(t)
412
+ sage: I = O.ideal([123, 131-t, 21+23*t])
413
+ sage: I.gens_two()
414
+ (41, t - 8)
415
+ sage: I == O.ideal(I.gens_two())
416
+ True
417
+
418
+ The second generator is zero if and only if the ideal is
419
+ generated by an integer::
420
+
421
+ sage: J = O.ideal([-33*t, 11*t-6589])
422
+ sage: J.gens_two()
423
+ (11, 0)
424
+ sage: J == O.ideal(11)
425
+ True
426
+
427
+ .. WARNING::
428
+
429
+ The returned generators do *not* necessarily
430
+ form a `\ZZ`-basis of the ideal.
431
+
432
+ TESTS:
433
+
434
+ Random testing::
435
+
436
+ sage: from sage.rings.number_field.order_ideal import _random_for_testing
437
+ sage: O, random_ideal = _random_for_testing()
438
+ sage: I = random_ideal()
439
+ sage: gs2 = I.gens_two()
440
+ sage: len(gs2)
441
+ 2
442
+ sage: all(g in O for g in gs2)
443
+ True
444
+ sage: O.ideal(gs2, future=1) == I
445
+ True
446
+ """
447
+ O = self.ring()
448
+ if self.is_zero():
449
+ return (O.zero(),)*2
450
+ M = self._module & (ZZ**2).submodule([(1,0)])
451
+ (N,_), = M.gens()
452
+ NOgens = [N*g for g in O.free_module().basis()]
453
+ Q = self._module / self._module.submodule(NOgens)
454
+ if Q.invariants():
455
+ assert len(Q.invariants()) == 1
456
+ _, from_V, _ = O.number_field().absolute_vector_space()
457
+ alpha, = (from_V(g.lift()) for g in Q.gens())
458
+ else:
459
+ alpha = 0
460
+ return tuple(map(O, (N, alpha)))
461
+
462
+ def is_principal(self):
463
+ r"""
464
+ Determine whether or not this ideal is principal.
465
+
466
+ .. SEEALSO::
467
+
468
+ To find a generator, use :meth:`gens_reduced`.
469
+
470
+ EXAMPLES:
471
+
472
+ sage: K.<a> = QuadraticField(-163)
473
+ sage: O = K.order(7*a)
474
+ sage: O.class_number()
475
+ 24
476
+ sage: order = lambda v: next(e for e in range(1,99) if (v^e).is_principal())
477
+ sage: I = O.ideal([47, 7*a-35])
478
+ sage: order(I)
479
+ 24
480
+ sage: J = O.ideal([71, 7*a-65])
481
+ sage: order(J)
482
+ 12
483
+ sage: next(e for e in range(99) if (I^e * J.conjugate()).is_principal())
484
+ 10
485
+ sage: (I^10 * J.conjugate()).is_principal()
486
+ True
487
+
488
+ ::
489
+
490
+ sage: K.<a> = QuadraticField(229)
491
+ sage: O = K.order(7*a)
492
+ sage: I = O.ideal([3, 7*a-2])
493
+ sage: J = O.ideal([5, 7*a-4])
494
+ sage: (I * J.conjugate()).is_principal()
495
+ True
496
+ sage: el = 104 + 7*a
497
+ sage: el.norm()
498
+ -405
499
+ sage: (I * (J * el).conjugate()).is_principal()
500
+ True
501
+ """
502
+ if self.is_zero():
503
+ return True
504
+ f = self.quadratic_form()
505
+ sol = f.solve_integer(1)
506
+ if sol is None:
507
+ sol = f.solve_integer(-1)
508
+ return sol is not None
509
+
510
+ def gens_reduced(self) -> tuple:
511
+ r"""
512
+ Express this ideal in terms of at most two generators,
513
+ and one if possible (i.e., if the ideal is principal).
514
+
515
+ EXAMPLES::
516
+
517
+ sage: x = polygen(QQ)
518
+ sage: K.<a> = NumberField(x^2 + 11*x + 5)
519
+ sage: O = K.order(7*a)
520
+ sage: I = O.ideal([31915, -71145879*a - 32195694])
521
+ sage: I.gens_reduced()
522
+ (-63*a + 17,)
523
+
524
+ ALGORITHM:
525
+
526
+ Compute a reduction of the :meth:`quadratic_form` to see
527
+ if it represents `1`, then use the transformation matrix
528
+ to find an element in the ideal whose norm equals the
529
+ norm of the ideal.
530
+
531
+ TESTS::
532
+
533
+ sage: from sage.rings.number_field.order_ideal import _random_for_testing
534
+ sage: O, random_ideal = _random_for_testing()
535
+ sage: I = random_ideal()
536
+ sage: gs = I.gens_reduced()
537
+ sage: len(gs) in (1,2)
538
+ True
539
+ sage: all(g in O for g in gs)
540
+ True
541
+ sage: (len(gs) == 1) == I.is_principal()
542
+ True
543
+ sage: O.ideal(gs, future=1) == I
544
+ True
545
+ """
546
+ if self.is_zero():
547
+ return (self.ring().zero(),)
548
+ f, bas = self.quadratic_form(basis=True)
549
+ sol = f.solve_integer(1)
550
+ if sol is None:
551
+ sol = f.solve_integer(-1)
552
+ if sol is None:
553
+ return self.gens_two()
554
+ gen = sum(c * g for c, g in zip(sol, bas))
555
+ assert NumberFieldOrderIdeal(self.ring(), gen) == self
556
+ return (gen,)
557
+
558
+ def is_equivalent(self, other, narrow=False):
559
+ r"""
560
+ Determine whether this ideal is equivalent to another ideal
561
+ in the same order.
562
+
563
+ If ``narrow`` is ``True``, test narrow equivalence instead.
564
+
565
+ (Two ideals are equivalent if they differ by multiplication
566
+ by a nonzero element. They are narrowly equivalent if they
567
+ differ by multiplication by an element of positive norm.)
568
+
569
+ EXAMPLES::
570
+
571
+ sage: K.<a> = QuadraticField(-163)
572
+ sage: O = K.order(7*a)
573
+ sage: I = O.ideal([47, 7*a-35])
574
+ sage: J = O.ideal([71, 7*a-65])
575
+ sage: I.is_equivalent(J)
576
+ False
577
+ sage: (I^10).is_equivalent(J)
578
+ True
579
+
580
+ ::
581
+
582
+ sage: K.<a> = QuadraticField(229)
583
+ sage: O = K.order(7*a)
584
+ sage: O.class_number()
585
+ 3
586
+ sage: I = O.ideal([3, 7*a-2])
587
+ sage: J = O.ideal([5, 7*a-4])
588
+ sage: I.is_equivalent(J)
589
+ True
590
+
591
+ ::
592
+
593
+ sage: K.<a> = QuadraticField(273)
594
+ sage: O = K.order(11*a)
595
+ sage: O.class_number()
596
+ 20
597
+ sage: I = O.ideal([17, 11*a-11])
598
+ sage: J = O.ideal([19, 11*a-12])
599
+ sage: I.is_equivalent(J)
600
+ False
601
+ sage: (I^3).is_equivalent(J)
602
+ False
603
+ sage: (I^6).is_equivalent(J^2)
604
+ True
605
+ sage: el = 177 + 11*a
606
+ sage: el.norm()
607
+ -1704
608
+ sage: (I^6).is_equivalent(J^2, narrow=True)
609
+ True
610
+ sage: (I^6).is_equivalent(J^2*el, narrow=True)
611
+ False
612
+ """
613
+ if self.ring() != other.ring():
614
+ raise ValueError('ideals must lie in the same order')
615
+ if self.is_zero():
616
+ return other.is_zero()
617
+ if other.is_zero():
618
+ return False
619
+ gs = (self * other.conjugate()).gens_reduced()
620
+ assert len(gs) in (1,2)
621
+ if len(gs) > 1:
622
+ return False
623
+ elif narrow:
624
+ return gs[0].norm() > 0
625
+ return True
626
+
627
+ def quadratic_form(self, *, basis=False):
628
+ r"""
629
+ Return the binary quadratic form associated to this ideal.
630
+
631
+ This map induces an injective homomorphism from the narrow
632
+ class group on ideals to the class group on quadratic forms.
633
+
634
+ If ``basis`` is set to ``True`` (default: ``False``), the
635
+ method additionally returns a `\ZZ`-basis `(a,b)` of this
636
+ ideal `I` such that `f(x,y)` equals
637
+ `\mathrm{norm}(xa+yb) / \mathrm{norm}(I)`,
638
+ where `f` is the returned quadratic form.
639
+
640
+ .. NOTE::
641
+
642
+ The narrow class group is the group of invertible ideals
643
+ modulo the principal ideals generated by an element of
644
+ positive norm.
645
+
646
+ - For *imaginary* quadratic orders, the narrow class group
647
+ is identical to the class group.
648
+
649
+ - For *real* quadratic orders, identifying the classes of
650
+ `f(x,y)` and `-f(y,x)` recovers a correspondence with the
651
+ standard class group.
652
+
653
+ REFERENCES:
654
+
655
+ The correspondence itself is classical.
656
+ Implemented after [Coh1993]_, §5.2.
657
+
658
+ .. SEEALSO::
659
+
660
+ :meth:`sage.rings.number_field.number_field_ideal.NumberFieldFractionalIdeal.quadratic_form`
661
+
662
+ EXAMPLES::
663
+
664
+ sage: K.<t> = QuadraticField(-419)
665
+ sage: O = K.order(t)
666
+ sage: O.discriminant().factor()
667
+ -1 * 2^2 * 419
668
+ sage: I = O.ideal([t-1, 105]); I
669
+ Ideal (104*t + 1, 105*t) of Order of conductor 2 generated by t
670
+ in Number Field in t with defining polynomial x^2 + 419 with t = 20.46948949045873?*I
671
+ sage: f = I.quadratic_form(); f
672
+ 105*x^2 - 208*x*y + 107*y^2
673
+ sage: f.discriminant().factor()
674
+ -1 * 2^2 * 419
675
+ sage: power(f,3).reduced_form()
676
+ x^2 + 419*y^2
677
+
678
+ ::
679
+
680
+ sage: u = 23*t - 45
681
+ sage: J = I*u
682
+ sage: g = J.quadratic_form(); g
683
+ 23485980*x^2 - 22795498*x*y + 5531329*y^2
684
+ sage: f.is_equivalent(g)
685
+ True
686
+
687
+ The inverse operation (modulo equivalence) can be computed by
688
+ passing a :class:`~sage.quadratic_forms.binary_qf.BinaryQF`
689
+ to ``O.ideal()``::
690
+
691
+ sage: II = O.ideal(f); II
692
+ Ideal (104*t + 1, 105*t) of Order of conductor 2 generated by t
693
+ in Number Field in t with defining polynomial x^2 + 419 with t = 20.46948949045873?*I
694
+ sage: II.quadratic_form().is_equivalent(f)
695
+ True
696
+
697
+ TESTS:
698
+
699
+ Randomized testing (principal ideals generated by an element
700
+ of positive norm map to the principal form)::
701
+
702
+ sage: from sage.rings.number_field.order_ideal import _random_for_testing
703
+ sage: O, _ = _random_for_testing()
704
+ sage: D = O.discriminant()
705
+ sage: gen = (O.random_element() for _ in iter(int,1))
706
+ sage: g = next(el for el in gen if el.norm() > 0)
707
+ sage: I = O.ideal(g, future=1)
708
+ sage: F = I.quadratic_form()
709
+ sage: F.is_equivalent(BinaryQF.principal(D))
710
+ True
711
+
712
+ Randomized testing (mapping is a homomorphism)::
713
+
714
+ sage: from sage.rings.number_field.order_ideal import _random_for_testing
715
+ sage: O, random_ideal = _random_for_testing()
716
+ sage: I = random_ideal()
717
+ sage: J = random_ideal()
718
+ sage: F = I.quadratic_form()
719
+ sage: G = J.quadratic_form()
720
+ sage: # Once future=1 is the default, the following line can be K = I * J
721
+ sage: K = O.ideal([g*h for g in I.gens() for h in J.gens()], future=1)
722
+ sage: H = K.quadratic_form()
723
+ sage: F.discriminant() == G.discriminant() == H.discriminant() == O.discriminant()
724
+ True
725
+ sage: H.is_equivalent(F*G)
726
+ True
727
+
728
+ Constructing an ideal from a form is indeed a one-sided inverse::
729
+
730
+ sage: II = O.ideal(F, future=1)
731
+ sage: II.quadratic_form().is_equivalent(F)
732
+ True
733
+ """
734
+ if self.is_zero():
735
+ if basis:
736
+ return BinaryQF(0), (self.ring().zero(),)*2
737
+ return BinaryQF(0)
738
+
739
+ O = self.ring()
740
+ sqrtD = _positive_sqrt(O.number_field(), O.discriminant())
741
+
742
+ # find a "good" ZZ-basis of the ideal
743
+ M = self._module.basis_matrix()[:,::-1]
744
+ M = M.row_space(ZZ).basis_matrix()[:,::-1]
745
+ beta, alpha = map(O, M.rows())
746
+ assert alpha in QQ
747
+ if QQ(alpha * (beta - beta.galois_conjugate()) / sqrtD) < 0:
748
+ alpha = -alpha
749
+
750
+ # compute the (reduced) norm form of the ideal
751
+ A,B = (g.matrix() for g in (alpha, beta))
752
+ x,y = polygens(QQ, 'x,y')
753
+ Q = (x*A - y*B).determinant() / self.norm()
754
+ Q = Q.change_ring(ZZ)
755
+
756
+ from sage.quadratic_forms.binary_qf import BinaryQF
757
+ Q = BinaryQF(Q)
758
+ assert Q.discriminant() == O.discriminant()
759
+ return (Q, (alpha, -beta)) if basis else Q
760
+
761
+
762
+ def _random_for_testing():
763
+ r"""
764
+ A small helper function to produce somewhat random examples
765
+ of ideals of (not necessarily maximal) quadratic orders.
766
+
767
+ Used in doctests.
768
+
769
+ EXAMPLES::
770
+
771
+ sage: from sage.rings.number_field.order_ideal import _random_for_testing
772
+ sage: O, random_ideal = _random_for_testing()
773
+ sage: random_ideal().ring() is O
774
+ True
775
+ """
776
+ from sage.misc.prandom import choice, randrange
777
+ from sage.rings.number_field.number_field import QuadraticField
778
+ from sage.arith.misc import primes
779
+ from sage.rings.finite_rings.integer_mod_ring import Zmod
780
+ while True:
781
+ d = ZZ(choice((-1, +1)) * randrange(1, 10**5))
782
+ if not d.is_square():
783
+ break
784
+ K,t = QuadraticField(d).objgen()
785
+ g, = K.ring_of_integers().ring_generators()
786
+
787
+ f = randrange(1, 100)
788
+ O = K.order(f*g)
789
+ assert O.discriminant() == f**2 * K.discriminant()
790
+
791
+ poly = (f*g).minpoly()
792
+ base = []
793
+ for l in primes(1000):
794
+ vs = poly.roots(ring=Zmod(l), multiplicities=False)
795
+ base += [NumberFieldOrderIdeal(O, [l, f*g-ZZ(v)]) for v in vs]
796
+
797
+ def random_ideal():
798
+ I = NumberFieldOrderIdeal(O, [1])
799
+ for _ in range(randrange(20)):
800
+ J = choice(base)
801
+ I = NumberFieldOrderIdeal(O, [x*y for x in I.gens() for y in J.gens()])
802
+ return I
803
+
804
+ return O, random_ideal