passagemath-flint 10.6.1rc10__cp313-cp313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
  26. sage/graphs/chrompoly.pyx +555 -0
  27. sage/graphs/matchpoly.cpython-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
  221. sage/matrix/change_ring.pyx +43 -0
  222. sage/matrix/matrix_complex_ball_dense.cpython-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
  286. sage/rings/factorint_flint.pyx +99 -0
  287. sage/rings/fraction_field_FpT.cpython-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
  325. sage/rings/polynomial/hilbert.pyx +602 -0
  326. sage/rings/polynomial/polynomial_complex_arb.cpython-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
  354. sage/rings/real_interval_absolute.pyx +1073 -0
  355. sage/rings/real_mpfi.cpython-313-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-313-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,2475 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ """
3
+ Arbitrary precision complex intervals
4
+
5
+ This is a simple complex interval package, using intervals which are
6
+ axis-aligned rectangles in the complex plane. It has very few special
7
+ functions, and it does not use any special tricks to keep the size of
8
+ the intervals down.
9
+
10
+ AUTHORS:
11
+
12
+ These authors wrote ``complex_mpfr.pyx`` (renamed from ``complex_number.pyx``)::
13
+
14
+ - William Stein (2006-01-26): complete rewrite
15
+ - Joel B. Mohler (2006-12-16): naive rewrite into pyrex
16
+ - William Stein(2007-01): rewrite of Mohler's rewrite
17
+
18
+ Then ``complex_number.pyx`` was copied to ``complex_interval.pyx`` and
19
+ heavily modified:
20
+
21
+ - Carl Witty (2007-10-24): rewrite to become a complex interval package
22
+
23
+ - Travis Scrimshaw (2012-10-18): Added documentation to get full coverage.
24
+
25
+
26
+ .. WARNING::
27
+
28
+ Mixing symbolic expressions with intervals (in particular, converting
29
+ constant symbolic expressions to intervals), can lead to incorrect
30
+ results::
31
+
32
+ sage: ref = ComplexIntervalField(100)(ComplexBallField(100).one().airy_ai())
33
+ sage: ref
34
+ 0.135292416312881415524147423515?
35
+ sage: val = CIF(airy_ai(1)); val # known bug
36
+ 0.13529241631288142?
37
+ sage: val.overlaps(ref) # known bug
38
+ False
39
+
40
+ .. TODO::
41
+
42
+ Implement :class:`ComplexIntervalFieldElement` multiplicative
43
+ order similar to :class:`ComplexNumber` multiplicative
44
+ order with ``_set_multiplicative_order(n)`` and
45
+ :meth:`ComplexNumber.multiplicative_order()` methods.
46
+ """
47
+
48
+ # ****************************************************************************
49
+ # Copyright (C) 2006 William Stein <wstein@gmail.com>
50
+ #
51
+ # This program is free software: you can redistribute it and/or modify
52
+ # it under the terms of the GNU General Public License as published by
53
+ # the Free Software Foundation, either version 2 of the License, or
54
+ # (at your option) any later version.
55
+ # https://www.gnu.org/licenses/
56
+ # ****************************************************************************
57
+
58
+ from cpython.object cimport Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE
59
+ from cysignals.signals cimport sig_on, sig_off
60
+
61
+ from sage.libs.gmp.mpz cimport mpz_sgn, mpz_cmpabs_ui
62
+ from sage.libs.mpfr cimport *
63
+ from sage.libs.mpfi cimport *
64
+ from sage.libs.flint.fmpz cimport *
65
+ from sage.libs.mpfr cimport MPFR_RNDU
66
+ from sage.arith.constants cimport LOG_TEN_TWO_PLUS_EPSILON
67
+
68
+ from sage.structure.element cimport FieldElement
69
+ from sage.structure.parent cimport Parent
70
+ from sage.rings.complex_mpfr cimport ComplexNumber
71
+ from sage.rings.integer cimport Integer
72
+ cimport sage.rings.real_mpfi as real_mpfi
73
+ from sage.rings.real_mpfr cimport RealNumber
74
+ from sage.rings.convert.mpfi cimport mpfi_set_sage
75
+ from sage.rings.infinity import infinity
76
+
77
+
78
+ def is_ComplexIntervalFieldElement(x):
79
+ """
80
+ Check if ``x`` is a :class:`ComplexIntervalFieldElement`.
81
+
82
+ EXAMPLES::
83
+
84
+ sage: from sage.rings.complex_interval import is_ComplexIntervalFieldElement as is_CIFE
85
+ sage: is_CIFE(CIF(2))
86
+ doctest:warning...
87
+ DeprecationWarning: The function is_ComplexIntervalFieldElement is deprecated;
88
+ use 'isinstance(..., ComplexIntervalFieldElement)' instead.
89
+ See https://github.com/sagemath/sage/issues/38128 for details.
90
+ True
91
+ sage: is_CIFE(CC(2))
92
+ False
93
+ """
94
+ from sage.misc.superseded import deprecation_cython
95
+ deprecation_cython(38128,
96
+ "The function is_ComplexIntervalFieldElement is deprecated; "
97
+ "use 'isinstance(..., ComplexIntervalFieldElement)' instead.")
98
+ return isinstance(x, ComplexIntervalFieldElement)
99
+
100
+
101
+ cdef class ComplexIntervalFieldElement(FieldElement):
102
+ """
103
+ A complex interval.
104
+
105
+ EXAMPLES::
106
+
107
+ sage: I = CIF.gen()
108
+ sage: b = 3/2 + 5/2*I
109
+ sage: TestSuite(b).run()
110
+ """
111
+ def __cinit__(self, parent, *args):
112
+ """
113
+ TESTS::
114
+
115
+ sage: from sage.rings.complex_interval import ComplexIntervalFieldElement
116
+ sage: ComplexIntervalFieldElement.__new__(ComplexIntervalFieldElement)
117
+ Traceback (most recent call last):
118
+ ...
119
+ TypeError: ...__cinit__() takes at least 1 positional argument (0 given)
120
+ sage: ComplexIntervalFieldElement.__new__(ComplexIntervalFieldElement, CIF)
121
+ [.. NaN ..] + [.. NaN ..]*I
122
+ """
123
+ self._parent = <Parent?>parent
124
+ self._prec = parent._prec
125
+ self._multiplicative_order = None
126
+ mpfi_init2(self.__re, self._prec)
127
+ mpfi_init2(self.__im, self._prec)
128
+
129
+ def __init__(self, parent, real, imag=None, int base=10):
130
+ """
131
+ Initialize a complex number (interval).
132
+
133
+ EXAMPLES::
134
+
135
+ sage: CIF(1.5, 2.5)
136
+ 1.5000000000000000? + 2.5000000000000000?*I
137
+ sage: CIF((1.5, 2.5))
138
+ 1.5000000000000000? + 2.5000000000000000?*I
139
+ sage: CIF(1.5 + 2.5*I)
140
+ 1.5000000000000000? + 2.5000000000000000?*I
141
+ """
142
+ self._multiplicative_order = None
143
+ if real is None:
144
+ mpfi_set_ui(self.__re, 0)
145
+ mpfi_set_ui(self.__im, 0)
146
+ elif imag is None:
147
+ # "real" may be real or complex
148
+ mpfi_set_sage(self.__re, self.__im, real, parent, base)
149
+ else:
150
+ # Set real and imaginary parts separately
151
+ mpfi_set_sage(self.__re, NULL, real, parent, base)
152
+ mpfi_set_sage(self.__im, NULL, imag, parent, base)
153
+
154
+ def __dealloc__(self):
155
+ if self._parent is not None:
156
+ mpfi_clear(self.__re)
157
+ mpfi_clear(self.__im)
158
+
159
+ def _repr_(self):
160
+ """
161
+ Return a string representation of ``self``.
162
+
163
+ EXAMPLES::
164
+
165
+ sage: CIF(1.5) # indirect doctest
166
+ 1.5000000000000000?
167
+ sage: CIF(1.5, 2.5) # indirect doctest
168
+ 1.5000000000000000? + 2.5000000000000000?*I
169
+ """
170
+ return self.str(10)
171
+
172
+ def __hash__(self):
173
+ """
174
+ Return the hash value of ``self``.
175
+
176
+ EXAMPLES::
177
+
178
+ sage: C = ComplexIntervalField()
179
+ sage: hash(CIF(1.5)) == hash(C(1.5))
180
+ True
181
+ sage: hash(CIF(1.5, 2.5)) != hash(CIF(2,3))
182
+ True
183
+ """
184
+ return hash(self.str())
185
+
186
+ def __getitem__(self, i):
187
+ """
188
+ Return either the real or imaginary component of ``self`` depending
189
+ on the choice of ``i``: real (``i=0``), imaginary (``i=1``)
190
+
191
+ INPUT:
192
+
193
+ - ``i`` -- 0 or 1
194
+
195
+ - ``0`` -- will return the real component of ``self``
196
+ - ``1`` -- will return the imaginary component of ``self``
197
+
198
+ EXAMPLES::
199
+
200
+ sage: z = CIF(1.5, 2.5)
201
+ sage: z[0]
202
+ 1.5000000000000000?
203
+ sage: z[1]
204
+ 2.5000000000000000?
205
+ """
206
+ if i == 0:
207
+ return self.real()
208
+ elif i == 1:
209
+ return self.imag()
210
+ raise IndexError("i must be between 0 and 1.")
211
+
212
+ def __reduce__(self):
213
+ """
214
+ Pickling support.
215
+
216
+ TESTS::
217
+
218
+ sage: a = CIF(1 + I)
219
+ sage: loads(dumps(a)) == a
220
+ True
221
+ """
222
+ # TODO: This is potentially slow -- make a 1 version that
223
+ # is native and much faster -- doesn't use .real()/.imag()
224
+ return (make_ComplexIntervalFieldElement0, (self._parent, self.real(), self.imag()))
225
+
226
+ def str(self, base=10, style=None):
227
+ """
228
+ Return a string representation of ``self``.
229
+
230
+ EXAMPLES::
231
+
232
+ sage: CIF(1.5).str()
233
+ '1.5000000000000000?'
234
+ sage: CIF(1.5, 2.5).str()
235
+ '1.5000000000000000? + 2.5000000000000000?*I'
236
+ sage: CIF(1.5, -2.5).str()
237
+ '1.5000000000000000? - 2.5000000000000000?*I'
238
+ sage: CIF(0, -2.5).str()
239
+ '-2.5000000000000000?*I'
240
+ sage: CIF(1.5).str(base=3)
241
+ '1.1111111111111111111111111111111112?'
242
+ sage: CIF(1, pi).str(style='brackets') # needs sage.symbolic
243
+ '[1.0000000000000000 .. 1.0000000000000000] + [3.1415926535897931 .. 3.1415926535897936]*I'
244
+
245
+ .. SEEALSO::
246
+
247
+ - :meth:`RealIntervalFieldElement.str`
248
+ """
249
+ s = ""
250
+ if not self.real().is_zero():
251
+ s = self.real().str(base=base, style=style)
252
+ if not self.imag().is_zero():
253
+ y = self.imag()
254
+ if s:
255
+ if y < 0:
256
+ s += " - "
257
+ y = -y
258
+ else:
259
+ s += " + "
260
+ s += "%s*I" % y.str(base=base, style=style)
261
+ if not s:
262
+ s = "0"
263
+ return s
264
+
265
+ def _mpfr_(self, parent):
266
+ r"""
267
+ If the imaginary part is zero, convert this interval field element
268
+ to a real number.
269
+
270
+ Fail if the imaginary part is not exactly zero.
271
+
272
+ INPUT:
273
+
274
+ - ``parent`` -- :class:`~sage.rings.real_mpfr.RealField_class`,
275
+ target parent
276
+
277
+ EXAMPLES::
278
+
279
+ sage: RR(CIF(1/3))
280
+ 0.333333333333333
281
+ sage: RR(CIF(1, 1/3) - CIF(0, 1/3))
282
+ Traceback (most recent call last):
283
+ ...
284
+ TypeError: unable to convert complex interval 1 + 0.?e-16*I to real number
285
+ """
286
+ if self.imag() == 0:
287
+ return parent(self.real())
288
+ else:
289
+ raise TypeError(f"unable to convert complex interval {self} to real number")
290
+
291
+ def plot(self, pointsize=10, **kwds):
292
+ r"""
293
+ Plot a complex interval as a rectangle.
294
+
295
+ EXAMPLES::
296
+
297
+ sage: sum(plot(CIF(RIF(1/k, 1/k), RIF(-k, k))) for k in [1..10]) # needs sage.plot
298
+ Graphics object consisting of 20 graphics primitives
299
+
300
+ Exact and nearly exact points are still visible::
301
+
302
+ sage: # needs sage.plot sage.symbolic
303
+ sage: plot(CIF(pi, 1), color='red') + plot(CIF(1, e), color='purple') + plot(CIF(-1, -1))
304
+ Graphics object consisting of 6 graphics primitives
305
+
306
+ A demonstration that `z \mapsto z^2` acts chaotically on `|z|=1`::
307
+
308
+ sage: # needs sage.plot sage.symbolic
309
+ sage: z = CIF(0, 2*pi/1000).exp()
310
+ sage: g = Graphics()
311
+ sage: for i in range(40):
312
+ ....: z = z^2
313
+ ....: g += z.plot(color=(1./(40-i), 0, 1))
314
+ ...
315
+ sage: g
316
+ Graphics object consisting of 80 graphics primitives
317
+ """
318
+ from sage.plot.polygon import polygon2d
319
+ x, y = self.real(), self.imag()
320
+ x0, y0 = x.lower(), y.lower()
321
+ x1, y1 = x.upper(), y.upper()
322
+ g = polygon2d([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)],
323
+ thickness=pointsize/4, **kwds)
324
+ # Nearly empty polygons don't show up.
325
+ g += self.center().plot(pointsize=pointsize, **kwds)
326
+ return g
327
+
328
+ def _latex_(self):
329
+ """
330
+ Return a latex representation of ``self``.
331
+
332
+ EXAMPLES::
333
+
334
+ sage: latex(CIF(1.5, -2.5)) # indirect doctest
335
+ 1.5000000000000000? - 2.5000000000000000?i
336
+ sage: latex(CIF(0, 3e200)) # indirect doctest
337
+ 3.0000000000000000? \times 10^{200}i
338
+ """
339
+ import re
340
+ s = self.str().replace('*I', 'i')
341
+ return re.sub(r"e(-?\d+)", r" \\times 10^{\1}", s)
342
+
343
+ def bisection(self):
344
+ """
345
+ Return the bisection of ``self`` into four intervals whose union is
346
+ ``self`` and intersection is :meth:`center()`.
347
+
348
+ EXAMPLES::
349
+
350
+ sage: z = CIF(RIF(2, 3), RIF(-5, -4))
351
+ sage: z.bisection()
352
+ (3.? - 5.?*I, 3.? - 5.?*I, 3.? - 5.?*I, 3.? - 5.?*I)
353
+ sage: for z in z.bisection():
354
+ ....: print(z.real().endpoints())
355
+ ....: print(z.imag().endpoints())
356
+ (2.00000000000000, 2.50000000000000)
357
+ (-5.00000000000000, -4.50000000000000)
358
+ (2.50000000000000, 3.00000000000000)
359
+ (-5.00000000000000, -4.50000000000000)
360
+ (2.00000000000000, 2.50000000000000)
361
+ (-4.50000000000000, -4.00000000000000)
362
+ (2.50000000000000, 3.00000000000000)
363
+ (-4.50000000000000, -4.00000000000000)
364
+
365
+ sage: # needs sage.symbolic
366
+ sage: z = CIF(RIF(sqrt(2), sqrt(3)), RIF(e, pi))
367
+ sage: a, b, c, d = z.bisection()
368
+ sage: a.intersection(b).intersection(c).intersection(d) == CIF(z.center())
369
+ True
370
+ sage: zz = a.union(b).union(c).union(c)
371
+ sage: zz.real().endpoints() == z.real().endpoints()
372
+ True
373
+ sage: zz.imag().endpoints() == z.imag().endpoints()
374
+ True
375
+ """
376
+ a00 = self._new()
377
+ mpfr_set(&a00.__re.left, &self.__re.left, MPFR_RNDN)
378
+ mpfi_mid(&a00.__re.right, self.__re)
379
+ mpfr_set(&a00.__im.left, &self.__im.left, MPFR_RNDN)
380
+ mpfi_mid(&a00.__im.right, self.__im)
381
+
382
+ a01 = self._new()
383
+ mpfr_set(&a01.__re.left, &a00.__re.right, MPFR_RNDN)
384
+ mpfr_set(&a01.__re.right, &self.__re.right, MPFR_RNDN)
385
+ mpfi_set(a01.__im, a00.__im)
386
+
387
+ a10 = self._new()
388
+ mpfi_set(a10.__re, a00.__re)
389
+ mpfi_mid(&a10.__im.left, self.__im)
390
+ mpfr_set(&a10.__im.right, &self.__im.right, MPFR_RNDN)
391
+
392
+ a11 = self._new()
393
+ mpfi_set(a11.__re, a01.__re)
394
+ mpfi_set(a11.__im, a10.__im)
395
+
396
+ return a00, a01, a10, a11
397
+
398
+ def is_exact(self):
399
+ """
400
+ Return whether this complex interval is exact (i.e. contains exactly
401
+ one complex value).
402
+
403
+ EXAMPLES::
404
+
405
+ sage: CIF(3).is_exact()
406
+ True
407
+ sage: CIF(0, 2).is_exact()
408
+ True
409
+ sage: CIF(-4, 0).sqrt().is_exact()
410
+ True
411
+ sage: CIF(-5, 0).sqrt().is_exact()
412
+ False
413
+ sage: CIF(0, 2*pi).is_exact() # needs sage.symbolic
414
+ False
415
+ sage: CIF(e).is_exact() # needs sage.symbolic
416
+ False
417
+ sage: CIF(1e100).is_exact()
418
+ True
419
+ sage: (CIF(1e100) + 1).is_exact()
420
+ False
421
+ """
422
+ return mpfr_equal_p(&self.__re.left, &self.__re.right) and \
423
+ mpfr_equal_p(&self.__im.left, &self.__im.right)
424
+
425
+ def endpoints(self):
426
+ """
427
+ Return the 4 corners of the rectangle in the complex plane
428
+ defined by this interval.
429
+
430
+ OUTPUT: a 4-tuple of complex numbers
431
+ (lower left, upper right, upper left, lower right)
432
+
433
+ .. SEEALSO::
434
+
435
+ :meth:`edges` which returns the 4 edges of the rectangle.
436
+
437
+ EXAMPLES::
438
+
439
+ sage: CIF(RIF(1,2), RIF(3,4)).endpoints()
440
+ (1.00000000000000 + 3.00000000000000*I,
441
+ 2.00000000000000 + 4.00000000000000*I,
442
+ 1.00000000000000 + 4.00000000000000*I,
443
+ 2.00000000000000 + 3.00000000000000*I)
444
+ sage: ComplexIntervalField(20)(-2).log().endpoints()
445
+ (0.69315 + 3.1416*I,
446
+ 0.69315 + 3.1416*I,
447
+ 0.69315 + 3.1416*I,
448
+ 0.69315 + 3.1416*I)
449
+ """
450
+ left, right = self.real().endpoints()
451
+ lower, upper = self.imag().endpoints()
452
+ CC = self._parent.middle_field()
453
+ return (CC(left, lower), CC(right, upper),
454
+ CC(left, upper), CC(right, lower))
455
+
456
+ def edges(self):
457
+ """
458
+ Return the 4 edges of the rectangle in the complex plane
459
+ defined by this interval as intervals.
460
+
461
+ OUTPUT: a 4-tuple of complex intervals
462
+ (left edge, right edge, lower edge, upper edge)
463
+
464
+ .. SEEALSO::
465
+
466
+ :meth:`endpoints` which returns the 4 corners of the
467
+ rectangle.
468
+
469
+ EXAMPLES::
470
+
471
+ sage: CIF(RIF(1,2), RIF(3,4)).edges()
472
+ (1 + 4.?*I, 2 + 4.?*I, 2.? + 3*I, 2.? + 4*I)
473
+ sage: ComplexIntervalField(20)(-2).log().edges()
474
+ (0.69314671? + 3.14160?*I,
475
+ 0.69314766? + 3.14160?*I,
476
+ 0.693147? + 3.1415902?*I,
477
+ 0.693147? + 3.1415940?*I)
478
+ """
479
+ left = self._new()
480
+ right = self._new()
481
+ lower = self._new()
482
+ upper = self._new()
483
+ cdef mpfr_t x
484
+ mpfr_init2(x, self.prec())
485
+
486
+ # Set real parts
487
+ mpfi_get_left(x, self.__re)
488
+ mpfi_set_fr(left.__re, x)
489
+ mpfi_get_right(x, self.__re)
490
+ mpfi_set_fr(right.__re, x)
491
+ mpfi_set(lower.__re, self.__re)
492
+ mpfi_set(upper.__re, self.__re)
493
+
494
+ # Set imaginary parts
495
+ mpfi_get_left(x, self.__im)
496
+ mpfi_set_fr(lower.__im, x)
497
+ mpfi_get_right(x, self.__im)
498
+ mpfi_set_fr(upper.__im, x)
499
+ mpfi_set(left.__im, self.__im)
500
+ mpfi_set(right.__im, self.__im)
501
+
502
+ mpfr_clear(x)
503
+
504
+ return (left, right, lower, upper)
505
+
506
+ def diameter(self):
507
+ """
508
+ Return a somewhat-arbitrarily defined "diameter" for this interval.
509
+
510
+ The diameter of an interval is the maximum of the diameter of the real
511
+ and imaginary components, where diameter on a real interval is defined
512
+ as absolute diameter if the interval contains zero, and relative
513
+ diameter otherwise.
514
+
515
+ EXAMPLES::
516
+
517
+ sage: CIF(RIF(-1, 1), RIF(13, 17)).diameter()
518
+ 2.00000000000000
519
+ sage: CIF(RIF(-0.1, 0.1), RIF(13, 17)).diameter()
520
+ 0.266666666666667
521
+ sage: CIF(RIF(-1, 1), 15).diameter()
522
+ 2.00000000000000
523
+ """
524
+ cdef RealNumber diam
525
+ diam = RealNumber(self._parent.real_field().middle_field(), None)
526
+ cdef mpfr_t tmp
527
+ mpfr_init2(tmp, self.prec())
528
+ mpfi_diam(diam.value, self.__re)
529
+ mpfi_diam(tmp, self.__im)
530
+ mpfr_max(diam.value, diam.value, tmp, MPFR_RNDU)
531
+ mpfr_clear(tmp)
532
+ return diam
533
+
534
+ def overlaps(self, ComplexIntervalFieldElement other):
535
+ """
536
+ Return ``True`` if ``self`` and ``other`` are intervals with at least
537
+ one value in common.
538
+
539
+ EXAMPLES::
540
+
541
+ sage: CIF(0).overlaps(CIF(RIF(0, 1), RIF(-1, 0)))
542
+ True
543
+ sage: CIF(1).overlaps(CIF(1, 1))
544
+ False
545
+ """
546
+ return mpfr_greaterequal_p(&self.__re.right, &other.__re.left) \
547
+ and mpfr_greaterequal_p(&other.__re.right, &self.__re.left) \
548
+ and mpfr_greaterequal_p(&self.__im.right, &other.__im.left) \
549
+ and mpfr_greaterequal_p(&other.__im.right, &self.__im.left)
550
+
551
+ def intersection(self, other):
552
+ """
553
+ Return the intersection of the two complex intervals ``self`` and
554
+ ``other``.
555
+
556
+ EXAMPLES::
557
+
558
+ sage: CIF(RIF(1, 3), RIF(1, 3)).intersection(CIF(RIF(2, 4), RIF(2, 4))).str(style='brackets')
559
+ '[2.0000000000000000 .. 3.0000000000000000] + [2.0000000000000000 .. 3.0000000000000000]*I'
560
+ sage: CIF(RIF(1, 2), RIF(1, 3)).intersection(CIF(RIF(3, 4), RIF(2, 4)))
561
+ Traceback (most recent call last):
562
+ ...
563
+ ValueError: intersection of non-overlapping intervals
564
+ """
565
+ x = self._new()
566
+ cdef ComplexIntervalFieldElement other_intv
567
+ if isinstance(other, ComplexIntervalFieldElement):
568
+ other_intv = other
569
+ else:
570
+ # Let type errors from _coerce_ propagate...
571
+ other_intv = self._parent(other)
572
+
573
+ mpfi_intersect(x.__re, self.__re, other_intv.__re)
574
+ mpfi_intersect(x.__im, self.__im, other_intv.__im)
575
+ if mpfr_less_p(&x.__re.right, &x.__re.left) \
576
+ or mpfr_less_p(&x.__im.right, &x.__im.left):
577
+ raise ValueError("intersection of non-overlapping intervals")
578
+
579
+ return x
580
+
581
+ def union(self, other):
582
+ """
583
+ Return the smallest complex interval including the
584
+ two complex intervals ``self`` and ``other``.
585
+
586
+ EXAMPLES::
587
+
588
+ sage: CIF(0).union(CIF(5, 5)).str(style='brackets')
589
+ '[0.0000000000000000 .. 5.0000000000000000] + [0.0000000000000000 .. 5.0000000000000000]*I'
590
+ """
591
+ x = self._new()
592
+ cdef ComplexIntervalFieldElement other_intv
593
+ if isinstance(other, ComplexIntervalFieldElement):
594
+ other_intv = other
595
+ else:
596
+ # Let type errors from _coerce_ propagate...
597
+ other_intv = self._parent(other)
598
+
599
+ mpfi_union(x.__re, self.__re, other_intv.__re)
600
+ mpfi_union(x.__im, self.__im, other_intv.__im)
601
+ return x
602
+
603
+ def magnitude(self):
604
+ """
605
+ The largest absolute value of the elements of the interval, rounded
606
+ away from zero.
607
+
608
+ OUTPUT: a real number with rounding mode ``RNDU``
609
+
610
+ EXAMPLES::
611
+
612
+ sage: CIF(RIF(-1,1), RIF(-1,1)).magnitude()
613
+ 1.41421356237310
614
+ sage: CIF(RIF(1,2), RIF(3,4)).magnitude()
615
+ 4.47213595499958
616
+ sage: parent(CIF(1).magnitude())
617
+ Real Field with 53 bits of precision and rounding RNDU
618
+ """
619
+ cdef real_mpfi.RealIntervalField_class RIF = self._parent.real_field()
620
+ cdef RealNumber x = RIF.__upper_field._new()
621
+ cdef RealNumber y = RIF.__upper_field._new()
622
+ mpfi_mag(x.value, self.__re)
623
+ mpfi_mag(y.value, self.__im)
624
+ mpfr_hypot(x.value, x.value, y.value, MPFR_RNDA)
625
+ return x
626
+
627
+ def mignitude(self):
628
+ """
629
+ The smallest absolute value of the elements of the interval, rounded
630
+ towards zero.
631
+
632
+ OUTPUT: a real number with rounding mode ``RNDD``
633
+
634
+ EXAMPLES::
635
+
636
+ sage: CIF(RIF(-1,1), RIF(-1,1)).mignitude()
637
+ 0.000000000000000
638
+ sage: CIF(RIF(1,2), RIF(3,4)).mignitude()
639
+ 3.16227766016837
640
+ sage: parent(CIF(1).mignitude())
641
+ Real Field with 53 bits of precision and rounding RNDD
642
+ """
643
+ cdef real_mpfi.RealIntervalField_class RIF = self._parent.real_field()
644
+ cdef RealNumber x = RIF.__lower_field._new()
645
+ cdef RealNumber y = RIF.__lower_field._new()
646
+ mpfi_mig(x.value, self.__re)
647
+ mpfi_mig(y.value, self.__im)
648
+ mpfr_hypot(x.value, x.value, y.value, MPFR_RNDZ)
649
+ return x
650
+
651
+ def center(self):
652
+ """
653
+ Return the closest floating-point approximation to the center
654
+ of the interval.
655
+
656
+ EXAMPLES::
657
+
658
+ sage: CIF(RIF(1, 2), RIF(3, 4)).center()
659
+ 1.50000000000000 + 3.50000000000000*I
660
+ """
661
+ cdef ComplexNumber center
662
+ center = ComplexNumber(self._parent.middle_field(), None)
663
+ mpfi_mid(center.__re, self.__re)
664
+ mpfi_mid(center.__im, self.__im)
665
+
666
+ return center
667
+
668
+ def __contains__(self, other):
669
+ """
670
+ Test whether ``other`` is totally contained in ``self``.
671
+
672
+ EXAMPLES::
673
+
674
+ sage: CIF(1, 1) in CIF(RIF(1, 2), RIF(1, 2))
675
+ True
676
+ """
677
+ # This could be more efficient (and support more types for "other").
678
+ return (other.real() in self.real()) and (other.imag() in self.imag())
679
+
680
+ def contains_zero(self):
681
+ """
682
+ Return ``True`` if ``self`` is an interval containing zero.
683
+
684
+ EXAMPLES::
685
+
686
+ sage: CIF(0).contains_zero()
687
+ True
688
+ sage: CIF(RIF(-1, 1), 1).contains_zero()
689
+ False
690
+ """
691
+ return mpfi_has_zero(self.__re) and mpfi_has_zero(self.__im)
692
+
693
+ cpdef _add_(self, right):
694
+ """
695
+ Add ``self`` and ``right``.
696
+
697
+ EXAMPLES::
698
+
699
+ sage: CIF(2,-3)._add_(CIF(1,-2))
700
+ 3 - 5*I
701
+ """
702
+ x = self._new()
703
+ mpfi_add(x.__re, self.__re, (<ComplexIntervalFieldElement>right).__re)
704
+ mpfi_add(x.__im, self.__im, (<ComplexIntervalFieldElement>right).__im)
705
+ return x
706
+
707
+ cpdef _sub_(self, right):
708
+ """
709
+ Subtract ``self`` by ``right``.
710
+
711
+ EXAMPLES::
712
+
713
+ sage: CIF(2,-3)._sub_(CIF(1,-2))
714
+ 1 - 1*I
715
+ """
716
+ x = self._new()
717
+ mpfi_sub(x.__re, self.__re, (<ComplexIntervalFieldElement>right).__re)
718
+ mpfi_sub(x.__im, self.__im, (<ComplexIntervalFieldElement>right).__im)
719
+ return x
720
+
721
+ cpdef _mul_(self, right):
722
+ """
723
+ Multiply ``self`` and ``right``.
724
+
725
+ EXAMPLES::
726
+
727
+ sage: CIF(2,-3)._mul_(CIF(1,-2))
728
+ -4 - 7*I
729
+ """
730
+ x = self._new()
731
+ cdef mpfi_t t0, t1
732
+ mpfi_init2(t0, self._prec)
733
+ mpfi_init2(t1, self._prec)
734
+ mpfi_mul(t0, self.__re, (<ComplexIntervalFieldElement>right).__re)
735
+ mpfi_mul(t1, self.__im, (<ComplexIntervalFieldElement>right).__im)
736
+ mpfi_sub(x.__re, t0, t1)
737
+ mpfi_mul(t0, self.__re, (<ComplexIntervalFieldElement>right).__im)
738
+ mpfi_mul(t1, self.__im, (<ComplexIntervalFieldElement>right).__re)
739
+ mpfi_add(x.__im, t0, t1)
740
+ mpfi_clear(t0)
741
+ mpfi_clear(t1)
742
+ return x
743
+
744
+ def norm(self):
745
+ r"""
746
+ Return the norm of this complex number.
747
+
748
+ If `c = a + bi` is a complex number, then the norm of `c` is defined as
749
+ the product of `c` and its complex conjugate:
750
+
751
+ .. MATH::
752
+
753
+ \text{norm}(c)
754
+ =
755
+ \text{norm}(a + bi)
756
+ =
757
+ c \cdot \overline{c}
758
+ =
759
+ a^2 + b^2.
760
+
761
+ The norm of a complex number is different from its absolute value.
762
+ The absolute value of a complex number is defined to be the square
763
+ root of its norm. A typical use of the complex norm is in the
764
+ integral domain `\ZZ[i]` of Gaussian integers, where the norm of
765
+ each Gaussian integer `c = a + bi` is defined as its complex norm.
766
+
767
+ .. SEEALSO::
768
+
769
+ - :meth:`sage.rings.complex_double.ComplexDoubleElement.norm`
770
+
771
+ EXAMPLES::
772
+
773
+ sage: CIF(2, 1).norm()
774
+ 5
775
+ sage: CIF(1, -2).norm()
776
+ 5
777
+ """
778
+ x = self._new_real()
779
+
780
+ cdef mpfi_t t
781
+ mpfi_init2(t, self._prec)
782
+
783
+ mpfi_sqr(x.value, self.__re)
784
+ mpfi_sqr(t, self.__im)
785
+
786
+ mpfi_add(x.value, x.value, t)
787
+
788
+ mpfi_clear(t)
789
+ return x
790
+
791
+ cpdef _div_(self, right):
792
+ """
793
+ Divide ``self`` by ``right``.
794
+
795
+ EXAMPLES::
796
+
797
+ sage: CIF(2,-3)._div_(CIF(1,-2))
798
+ 1.600000000000000? + 0.200000000000000?*I
799
+ sage: a = CIF((1, 2), (3, 4))
800
+ sage: b = CIF(-1, (2, 3))
801
+ sage: c = a/b
802
+ sage: c.endpoints()
803
+ (0.500000000000000 - 1.60000000000000*I,
804
+ 1.50000000000000 - 0.600000000000000*I,
805
+ 0.500000000000000 - 0.600000000000000*I,
806
+ 1.50000000000000 - 1.60000000000000*I)
807
+ sage: c = b/a
808
+ sage: c.endpoints()
809
+ (0.246153846153846 + 0.317647058823529*I,
810
+ 0.841176470588236 + 0.761538461538462*I,
811
+ 0.246153846153846 + 0.761538461538462*I,
812
+ 0.841176470588236 + 0.317647058823529*I)
813
+ """
814
+ return self * right.__invert__()
815
+
816
+ def __pow__(self, right, modulus):
817
+ r"""
818
+ Compute `x^y`.
819
+
820
+ If `y` is an integer, uses multiplication;
821
+ otherwise, uses the standard definition `\exp(\log(x) \cdot y)`.
822
+
823
+ .. WARNING::
824
+
825
+ If the interval `x` crosses the negative real axis, then we use a
826
+ non-standard definition of `\log()` (see the docstring for
827
+ :meth:`argument()` for more details). This means that we will not
828
+ select the principal value of the power, for part of the input
829
+ interval (and that we violate the interval guarantees).
830
+
831
+ EXAMPLES::
832
+
833
+ sage: C.<i> = ComplexIntervalField(20)
834
+ sage: a = i^2; a
835
+ -1
836
+ sage: a.parent()
837
+ Complex Interval Field with 20 bits of precision
838
+ sage: a = (1+i)^7; a
839
+ 8 - 8*I
840
+ sage: (1+i)^(1+i)
841
+ 0.27396? + 0.58370?*I
842
+ sage: a.parent()
843
+ Complex Interval Field with 20 bits of precision
844
+ sage: (2+i)^(-39)
845
+ 1.688?e-14 + 1.628?e-14*I
846
+
847
+ If the interval crosses the negative real axis, then we don't use the
848
+ standard branch cut (and we violate the interval guarantees)::
849
+
850
+ sage: (CIF(-7, RIF(-1, 1)) ^ CIF(0.3)).str(style='brackets')
851
+ '[0.99109735947126309 .. 1.1179269966896264] + [1.4042388462787560 .. 1.4984624123369835]*I'
852
+ sage: CIF(-7, -1) ^ CIF(0.3)
853
+ 1.117926996689626? - 1.408500714575360?*I
854
+
855
+ Note that ``x^2`` is not the same as ``x*x``::
856
+
857
+ sage: a = CIF(RIF(-1,1))
858
+ sage: print((a^2).str(style='brackets'))
859
+ [0.0000000000000000 .. 1.0000000000000000]
860
+ sage: print((a*a).str(style='brackets'))
861
+ [-1.0000000000000000 .. 1.0000000000000000]
862
+ sage: a = CIF(0, RIF(-1,1))
863
+ sage: print((a^2).str(style='brackets'))
864
+ [-1.0000000000000000 .. -0.0000000000000000]
865
+ sage: print((a*a).str(style='brackets'))
866
+ [-1.0000000000000000 .. 1.0000000000000000]
867
+ sage: a = CIF(RIF(-1,1), RIF(-1,1))
868
+ sage: print((a^2).str(style='brackets'))
869
+ [-1.0000000000000000 .. 1.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I
870
+ sage: print((a*a).str(style='brackets'))
871
+ [-2.0000000000000000 .. 2.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I
872
+
873
+ We can take very high powers::
874
+
875
+ sage: RIF = RealIntervalField(27)
876
+ sage: CIF = ComplexIntervalField(27)
877
+ sage: s = RealField(27, rnd="RNDZ")(1/2)^(1/3)
878
+ sage: a = CIF(RIF(-s/2,s/2), RIF(-s, s))
879
+ sage: r = a^(10^10000)
880
+ sage: print(r.str(style='brackets'))
881
+ [-2.107553304e1028 .. 2.107553304e1028] + [-2.107553304e1028 .. 2.107553304e1028]*I
882
+
883
+ TESTS::
884
+
885
+ sage: CIF = ComplexIntervalField(7)
886
+ sage: [CIF(2) ^ RDF(i) for i in range(-5,6)]
887
+ [0.03125?, 0.06250?, 0.1250?, 0.2500?, 0.5000?, 1, 2, 4, 8, 16, 32]
888
+ sage: pow(CIF(1), CIF(1), CIF(1))
889
+ Traceback (most recent call last):
890
+ ...
891
+ TypeError: pow() 3rd argument not allowed unless all arguments are integers
892
+ """
893
+ if modulus is not None:
894
+ raise TypeError("pow() 3rd argument not allowed unless all arguments are integers")
895
+
896
+ cdef ComplexIntervalFieldElement z, z2, t = None
897
+ z = <ComplexIntervalFieldElement?>self
898
+
899
+ # Convert right to an integer
900
+ if not isinstance(right, Integer):
901
+ try:
902
+ right = Integer(right)
903
+ except (TypeError, ValueError):
904
+ # Exponent is really not an integer
905
+ return (z.log() * z._parent(right)).exp()
906
+
907
+ cdef int s = mpz_sgn((<Integer>right).value)
908
+ if s == 0:
909
+ return z._parent.one()
910
+ elif s < 0:
911
+ z = ~z
912
+ if not mpz_cmpabs_ui((<Integer>right).value, 1):
913
+ return z
914
+
915
+ # Convert exponent to fmpz_t
916
+ cdef fmpz_t e
917
+ fmpz_init(e)
918
+ fmpz_set_mpz(e, (<Integer>right).value)
919
+ fmpz_abs(e, e)
920
+
921
+ # Now we know that e >= 2.
922
+ # Use binary powering with special formula for squares.
923
+
924
+ # Handle first bit more efficiently:
925
+ if fmpz_tstbit(e, 0):
926
+ res = z
927
+ else:
928
+ res = z._parent.one()
929
+ fmpz_tdiv_q_2exp(e, e, 1) # e >>= 1
930
+
931
+ # Allocate a temporary ComplexIntervalFieldElement
932
+ z2 = z._new()
933
+
934
+ while True:
935
+ # Compute z2 = z^2 using the formula
936
+ # (a + bi)^2 = (a^2 - b^2) + 2abi
937
+ mpfi_sqr(z2.__re, z.__re) # a^2
938
+ mpfi_sqr(z2.__im, z.__im) # b^2
939
+ mpfi_sub(z2.__re, z2.__re, z2.__im) # a^2 - b^2
940
+ mpfi_mul(z2.__im, z.__re, z.__im) # ab
941
+ mpfi_mul_2ui(z2.__im, z2.__im, 1) # 2ab
942
+ z = z2
943
+ if fmpz_tstbit(e, 0):
944
+ res *= z
945
+ fmpz_tdiv_q_2exp(e, e, 1) # e >>= 1
946
+ if fmpz_is_zero(e):
947
+ break
948
+
949
+ # Swap temporary elements z2 and t (allocate t first if needed)
950
+ if t is not None:
951
+ z2 = t
952
+ else:
953
+ z2 = z2._new()
954
+ t = z
955
+ fmpz_clear(e)
956
+ return res
957
+
958
+ def _magma_init_(self, magma):
959
+ r"""
960
+ Return a string representation of ``self`` in the Magma language.
961
+
962
+ EXAMPLES::
963
+
964
+ sage: t = CIF((1, 1.1), 2.5); t
965
+ 1.1? + 2.5000000000000000?*I
966
+ sage: magma(t) # optional - magma # indirect doctest
967
+ 1.05000000000000 + 2.50000000000000*$.1
968
+ sage: t = ComplexIntervalField(100)((1, 4/3), 2.5); t
969
+ 2.? + 2.5000000000000000000000000000000?*I
970
+ sage: magma(t) # optional - magma
971
+ 1.16666666666666666666666666670 + 2.50000000000000000000000000000*$.1
972
+ """
973
+ return "%s![%s, %s]" % (self.parent()._magma_init_(magma), self.center().real(), self.center().imag())
974
+
975
+ def _interface_init_(self, I=None):
976
+ """
977
+ Raise a :exc:`TypeError`.
978
+
979
+ This function would return the string representation of ``self``
980
+ that makes sense as a default representation of a complex
981
+ interval in other computer algebra systems. But, most other
982
+ computer algebra systems do not support interval arithmetic,
983
+ so instead we just raise a :exc:`TypeError`.
984
+
985
+ Define the appropriate ``_cas_init_`` function if there is a
986
+ computer algebra system you would like to support.
987
+
988
+ EXAMPLES::
989
+
990
+ sage: n = CIF(1.3939494594)
991
+ sage: n._interface_init_()
992
+ Traceback (most recent call last):
993
+ ...
994
+ TypeError
995
+
996
+ Here a conversion to Maxima happens, which results in a :exc:`TypeError`::
997
+
998
+ sage: a = CIF(2.3)
999
+ sage: maxima(a) # needs sage.symbolic
1000
+ Traceback (most recent call last):
1001
+ ...
1002
+ TypeError
1003
+ """
1004
+ raise TypeError
1005
+
1006
+ def _sage_input_(self, sib, coerce):
1007
+ r"""
1008
+ Produce an expression which will reproduce this value when evaluated.
1009
+
1010
+ EXAMPLES::
1011
+
1012
+ sage: sage_input(CIF(RIF(e, pi), RIF(sqrt(2), sqrt(3))), verify=True) # needs sage.symbolic
1013
+ # Verified
1014
+ CIF(RIF(RR(2.7182818284590451), RR(3.1415926535897936)), RIF(RR(1.4142135623730949), RR(1.7320508075688774)))
1015
+ sage: sage_input(ComplexIntervalField(64)(2)^I, preparse=False, verify=True)
1016
+ # Verified
1017
+ RIF64 = RealIntervalField(64)
1018
+ RR64 = RealField(64)
1019
+ ComplexIntervalField(64)(RIF64(RR64('0.769238901363972126565'), RR64('0.769238901363972126619')), RIF64(RR64('0.638961276313634801076'), RR64('0.638961276313634801184')))
1020
+ sage: from sage.misc.sage_input import SageInputBuilder
1021
+ sage: sib = SageInputBuilder()
1022
+ sage: ComplexIntervalField(15)(3+I).log()._sage_input_(sib, False)
1023
+ {call: {call: {atomic:ComplexIntervalField}({atomic:15})}({call: {call: {atomic:RealIntervalField}({atomic:15})}({call: {call: {atomic:RealField}({atomic:15})}({atomic:1.15125})}, {call: {call: {atomic:RealField}({atomic:15})}({atomic:1.15137})})}, {call: {call: {atomic:RealIntervalField}({atomic:15})}({call: {call: {atomic:RealField}({atomic:15})}({atomic:0.321655})}, {call: {call: {atomic:RealField}({atomic:15})}({atomic:0.321777})})})}
1024
+ """
1025
+ # Interval printing could often be much prettier,
1026
+ # but I'm feeling lazy :)
1027
+ return sib(self.parent())(sib(self.real()), sib(self.imag()))
1028
+
1029
+ def prec(self):
1030
+ """
1031
+ Return precision of this complex number.
1032
+
1033
+ EXAMPLES::
1034
+
1035
+ sage: i = ComplexIntervalField(2000).0
1036
+ sage: i.prec()
1037
+ 2000
1038
+ """
1039
+ return self._parent.prec()
1040
+
1041
+ def real(self):
1042
+ """
1043
+ Return real part of ``self``.
1044
+
1045
+ EXAMPLES::
1046
+
1047
+ sage: i = ComplexIntervalField(100).0
1048
+ sage: z = 2 + 3*i
1049
+ sage: x = z.real(); x
1050
+ 2
1051
+ sage: x.parent()
1052
+ Real Interval Field with 100 bits of precision
1053
+ """
1054
+ x = self._new_real()
1055
+ mpfi_set(x.value, self.__re)
1056
+ return x
1057
+
1058
+ def imag(self):
1059
+ """
1060
+ Return imaginary part of ``self``.
1061
+
1062
+ EXAMPLES::
1063
+
1064
+ sage: i = ComplexIntervalField(100).0
1065
+ sage: z = 2 + 3*i
1066
+ sage: x = z.imag(); x
1067
+ 3
1068
+ sage: x.parent()
1069
+ Real Interval Field with 100 bits of precision
1070
+ """
1071
+ x = self._new_real()
1072
+ mpfi_set(x.value, self.__im)
1073
+ return x
1074
+
1075
+ def __neg__(self):
1076
+ """
1077
+ Return the negation of ``self``.
1078
+
1079
+ EXAMPLES::
1080
+
1081
+ sage: CIF(1.5, 2.5).__neg__()
1082
+ -1.5000000000000000? - 2.5000000000000000?*I
1083
+ """
1084
+ x = self._new()
1085
+ mpfi_neg(x.__re, self.__re)
1086
+ mpfi_neg(x.__im, self.__im)
1087
+ return x
1088
+
1089
+ def __pos__(self):
1090
+ """
1091
+ Return the "positive" of ``self``, which is just ``self``.
1092
+
1093
+ EXAMPLES::
1094
+
1095
+ sage: CIF(1.5, 2.5).__pos__()
1096
+ 1.5000000000000000? + 2.5000000000000000?*I
1097
+ """
1098
+ return self
1099
+
1100
+ def __abs__(self):
1101
+ """
1102
+ Return the absolute value of ``self``.
1103
+
1104
+ EXAMPLES::
1105
+
1106
+ sage: abs(CIF(1.5, 2.5))
1107
+ 2.915475947422650?
1108
+ sage: CIF(1.5, 2.5).__abs__()
1109
+ 2.915475947422650?
1110
+ """
1111
+ x = self._new_real()
1112
+
1113
+ cdef mpfi_t t
1114
+ mpfi_init2(t, self._prec)
1115
+
1116
+ mpfi_sqr(x.value, self.__re)
1117
+ mpfi_sqr(t, self.__im)
1118
+
1119
+ mpfi_add(x.value, x.value, t)
1120
+ mpfi_sqrt(x.value, x.value)
1121
+
1122
+ mpfi_clear(t)
1123
+ return x
1124
+
1125
+ def __invert__(self):
1126
+ """
1127
+ Return the multiplicative inverse of ``self``.
1128
+
1129
+ EXAMPLES::
1130
+
1131
+ sage: I = CIF.0
1132
+ sage: a = ~(5+I) # indirect doctest
1133
+ sage: a * (5+I)
1134
+ 1.000000000000000? + 0.?e-16*I
1135
+ sage: a = CIF((1, 2), (3, 4))
1136
+ sage: c = a.__invert__()
1137
+ sage: c.endpoints()
1138
+ (0.0588235294117647 - 0.300000000000000*I,
1139
+ 0.153846153846154 - 0.200000000000000*I,
1140
+ 0.0588235294117647 - 0.200000000000000*I,
1141
+ 0.153846153846154 - 0.300000000000000*I)
1142
+
1143
+ TESTS:
1144
+
1145
+ Check that the code is valid in all kind of complex intervals::
1146
+
1147
+ sage: rpts = [0, -194323/42, -110/439423, -411923/122212, \
1148
+ ....: 15423/906, 337/59976, 145151/145112]
1149
+ sage: rpts = [RIF(a, b) if a <= b else RIF(b,a) \
1150
+ ....: for a in rpts for b in rpts]
1151
+ sage: cpts = [CIF(a, b) for a in rpts for b in rpts if not CIF(a, b).contains_zero()]
1152
+ sage: for x in cpts:
1153
+ ....: assert (x * (~x) - 1).contains_zero()
1154
+
1155
+ Test that the bug reported in :issue:`25414` has been fixed::
1156
+
1157
+ sage: 1 / CIF(RIF(-1 ,1), 0)
1158
+ [.. NaN ..] + [.. NaN ..]*I
1159
+
1160
+ Test that the bug reported in :issue:`37927` is fixed::
1161
+
1162
+ sage: (961 * (1 / CIF(0, 31))**2 + 1).contains_zero()
1163
+ True
1164
+
1165
+ REFERENCES:
1166
+
1167
+ - [RL1971]_
1168
+ """
1169
+ cdef ComplexIntervalFieldElement result
1170
+ x = self._new()
1171
+
1172
+ if mpfi_nan_p(self.__re) or mpfi_nan_p(self.__im):
1173
+ # Return NaN if any input is NaN
1174
+ return x
1175
+
1176
+ if mpfi_has_zero(self.__re) and mpfi_has_zero(self.__im):
1177
+ # Return NaN when dividing by (a complex interval containing) zero.
1178
+ return x
1179
+
1180
+ # The algorithm roughly follows [RL1971].
1181
+ #
1182
+ # However, we deviate from [RL1971] significantly and the
1183
+ # documentation here is self-contained and hopefully easier
1184
+ # to follow than [RL1971]. There is a visualization at:
1185
+ # https://www.shadertoy.com/view/M3VXWG
1186
+ #
1187
+ # Note that [RL1971] has several mistakes. For example, when analyzing
1188
+ # the second case where y1 < 0 and y2 > 0 (and x1 >= 0 from earlier
1189
+ # assumptions), they have a subcase "y_1 >= x_1". That inequality can
1190
+ # never be true given the earlier assumptions and should be
1191
+ # "-y_1 >= x_1".
1192
+
1193
+ # To maximize symmetry considerations, we actually compute the
1194
+ # circle inversion (z |-> conjugate(1/z)) and conjugate at the end.
1195
+
1196
+ # Let the input be the complex interval [xmin, xmax] + [ymin, ymax] * I.
1197
+ #
1198
+ # We say that the complex interval is in standard form if either:
1199
+ # (I) It is contained within the first quadrant. Furthermore its
1200
+ # left bottom corner is on or below the north east diagonal.
1201
+ # That is 0 <= ymin <= xmin. Or:
1202
+ # (II) It is contained within the first and fourth quadrant crossing
1203
+ # the (positive) x-Axis. Furthermore, its midpoint is above the
1204
+ # x-Axis.
1205
+ # That is 0 < xmin; ymin < 0 < ymax and |ymin| <= |ymax|.
1206
+ #
1207
+ # Since we already guarded against the input containing zero, we always
1208
+ # can and will bring it into standard form by negating or swapping the
1209
+ # real and imaginary part.
1210
+
1211
+ cdef mpfr_t xmin, xmax, ymin, ymax
1212
+ mpfr_init2(xmin, self._prec)
1213
+ mpfr_init2(xmax, self._prec)
1214
+ mpfr_init2(ymin, self._prec)
1215
+ mpfr_init2(ymax, self._prec)
1216
+
1217
+ mpfi_get_left(xmin, self.__re)
1218
+ mpfi_get_right(xmax, self.__re)
1219
+ mpfi_get_left(ymin, self.__im)
1220
+ mpfi_get_right(ymax, self.__im)
1221
+
1222
+ # Record what mirror symmetries we applied to undo them later.
1223
+ #
1224
+ # We assume that we flip about the coordinate axes before flipping
1225
+ # about the north east diagonal.
1226
+ cdef bint negated_x = False
1227
+ cdef bint negated_y = False
1228
+ cdef bint swapped_xy = False
1229
+
1230
+ # Record whether we are in case (II).
1231
+ cdef bint crosses_x_axis = False
1232
+
1233
+ ########################################################################
1234
+ # Now bring the input into standard form.
1235
+
1236
+ if mpfr_sgn(ymax) <= 0:
1237
+ # Interval below (and possibly touching) x-Axis, flip about it.
1238
+ _negate_interval(ymin, ymax)
1239
+ negated_y = True
1240
+ elif mpfr_sgn(ymin) < 0:
1241
+ # Interval crosses x-Axis
1242
+ crosses_x_axis = True
1243
+ # else: Interval is above x-Axis
1244
+
1245
+ # Negating interval for y and swapping do not commute, so
1246
+ # order of the above and below if-block is important.
1247
+
1248
+ if mpfr_sgn(xmax) <= 0:
1249
+ # Interval left of (and possibly touching) y-Axis, flip about it.
1250
+ _negate_interval(xmin, xmax)
1251
+ negated_x = True
1252
+ elif mpfr_sgn(xmin) < 0:
1253
+ # Interval crosses y-Axis, swap to make it cross x-Axis instead.
1254
+ mpfr_swap(xmin, ymin)
1255
+ mpfr_swap(xmax, ymax)
1256
+ swapped_xy = True
1257
+ crosses_x_axis = True
1258
+ # else: Interval is right of y-Axis
1259
+
1260
+ if crosses_x_axis:
1261
+ # Case (II). Ensure standard condition |ymax| >= |ymin|
1262
+ if mpfr_cmpabs(ymin, ymax) > 0:
1263
+ _negate_interval(ymin, ymax)
1264
+ # Note that we negate after potentially swapping.
1265
+ # Determine what we should have negated before swapping instead.
1266
+ if swapped_xy:
1267
+ # negated_x cannot be True already.
1268
+ negated_x = True
1269
+ else:
1270
+ # negated_y cannot be True already.
1271
+ negated_y = True
1272
+ else:
1273
+ # Case (I). Ensure standard condition |ymin| <= |xmin|.
1274
+ if mpfr_cmp(xmin, ymin) < 0:
1275
+ mpfr_swap(xmin, ymin)
1276
+ mpfr_swap(xmax, ymax)
1277
+ swapped_xy = True
1278
+
1279
+ ########################################################################
1280
+ # Apply circle inversion
1281
+
1282
+ # Result will be [amin, amax] + [bmin, bmax] * I.
1283
+ cdef mpfr_t amin, amax, bmin, bmax
1284
+
1285
+ mpfr_init2(amin, self._prec)
1286
+ mpfr_init2(amax, self._prec)
1287
+ mpfr_init2(bmin, self._prec)
1288
+ mpfr_init2(bmax, self._prec)
1289
+
1290
+ _circle_invert_standard(
1291
+ amin, amax, bmin, bmax,
1292
+ xmin, xmax, ymin, ymax,
1293
+ crosses_x_axis, self._prec)
1294
+
1295
+ ########################################################################
1296
+ # Undo symmetries applied above.
1297
+
1298
+ if swapped_xy:
1299
+ mpfr_swap(amin, bmin)
1300
+ mpfr_swap(amax, bmax)
1301
+
1302
+ if negated_x:
1303
+ _negate_interval(amin, amax)
1304
+
1305
+ # We sneak in the promised conjugation by
1306
+ # inverting negated_y.
1307
+ if not negated_y:
1308
+ _negate_interval(bmin, bmax)
1309
+
1310
+ ########################################################################
1311
+ # Write out result and free memory
1312
+
1313
+ mpfi_interv_fr(x.__re, amin, amax)
1314
+ mpfi_interv_fr(x.__im, bmin, bmax)
1315
+
1316
+ mpfr_clear(xmin)
1317
+ mpfr_clear(xmax)
1318
+ mpfr_clear(ymin)
1319
+ mpfr_clear(ymax)
1320
+ mpfr_clear(amin)
1321
+ mpfr_clear(amax)
1322
+ mpfr_clear(bmin)
1323
+ mpfr_clear(bmax)
1324
+
1325
+ return x
1326
+
1327
+ def _complex_mpfr_field_(self, field):
1328
+ """
1329
+ Convert to a complex field.
1330
+
1331
+ EXAMPLES::
1332
+
1333
+ sage: re = RIF("1.2")
1334
+ sage: im = RIF(2, 3)
1335
+ sage: a = ComplexIntervalField(30)(re, im)
1336
+ sage: CC(a)
1337
+ 1.20000000018626 + 2.50000000000000*I
1338
+ """
1339
+ cdef ComplexNumber x = field(0)
1340
+ mpfi_mid(x.__re, self.__re)
1341
+ mpfi_mid(x.__im, self.__im)
1342
+ return x
1343
+
1344
+ def __int__(self):
1345
+ """
1346
+ Convert ``self`` to an ``int``.
1347
+
1348
+ EXAMPLES::
1349
+
1350
+ sage: int(CIF(1,1))
1351
+ Traceback (most recent call last):
1352
+ ...
1353
+ TypeError: can...t convert complex interval to int
1354
+ """
1355
+ raise TypeError("can't convert complex interval to int")
1356
+
1357
+ def _integer_(self, _):
1358
+ r"""
1359
+ Convert this interval to an integer.
1360
+
1361
+ EXAMPLES::
1362
+
1363
+ sage: ZZ(CIF(-3))
1364
+ -3
1365
+ sage: ZZ(CIF(1+I))
1366
+ Traceback (most recent call last):
1367
+ ...
1368
+ ValueError: unable to convert interval 1 + 1*I to an integer
1369
+ sage: ZZ(CIF(RIF(1/2,3/2)))
1370
+ Traceback (most recent call last):
1371
+ ...
1372
+ ValueError: unable to convert interval 1.? to an integer
1373
+ """
1374
+ try:
1375
+ if self.imag()._integer_(None).is_zero():
1376
+ return self.real()._integer_(None)
1377
+ except ValueError:
1378
+ pass
1379
+ raise ValueError("unable to convert interval {!r} to an integer".format(self))
1380
+
1381
+ def __float__(self):
1382
+ """
1383
+ Convert ``self`` to a ``float``.
1384
+
1385
+ EXAMPLES::
1386
+
1387
+ sage: float(CIF(1))
1388
+ 1.0
1389
+ sage: float(CIF(1,1))
1390
+ Traceback (most recent call last):
1391
+ ...
1392
+ TypeError: can...t convert complex interval to float
1393
+ """
1394
+ if self.imag() == 0:
1395
+ return float(self.real().n(self._prec))
1396
+ else:
1397
+ raise TypeError("can't convert complex interval to float")
1398
+
1399
+ def __complex__(self):
1400
+ """
1401
+ Convert ``self`` to a ``complex``.
1402
+
1403
+ EXAMPLES::
1404
+
1405
+ sage: complex(CIF(1,1))
1406
+ (1+1j)
1407
+ """
1408
+ return complex(self.real().n(self._prec),
1409
+ self.imag().n(self._prec))
1410
+
1411
+ def __bool__(self):
1412
+ """
1413
+ Return ``True`` if ``self`` is not known to be exactly zero.
1414
+
1415
+ EXAMPLES::
1416
+
1417
+ sage: bool(CIF(RIF(0, 0), RIF(0, 0)))
1418
+ False
1419
+ sage: bool(CIF(RIF(1), RIF(0)))
1420
+ True
1421
+ sage: bool(CIF(RIF(0), RIF(1)))
1422
+ True
1423
+ sage: bool(CIF(RIF(1, 2), RIF(0)))
1424
+ True
1425
+ sage: bool(CIF(RIF(-1, 1), RIF(-1, 1)))
1426
+ True
1427
+ """
1428
+ return bool(self.real()) or bool(self.imag())
1429
+
1430
+ cpdef _richcmp_(left, right, int op):
1431
+ r"""
1432
+ As with the real interval fields this never returns false positives.
1433
+
1434
+ Thus, `a == b` is ``True`` iff both `a` and `b` represent the same
1435
+ one-point interval. Likewise `a != b` is ``True`` iff `x != y` for all
1436
+ `x \in a, y \in b`.
1437
+
1438
+ EXAMPLES::
1439
+
1440
+ sage: CIF(0) == CIF(0)
1441
+ True
1442
+ sage: CIF(0) == CIF(1)
1443
+ False
1444
+ sage: CIF.gen() == CIF.gen()
1445
+ True
1446
+ sage: CIF(0) == CIF.gen()
1447
+ False
1448
+ sage: CIF(0) != CIF(1)
1449
+ True
1450
+ sage: -CIF(-3).sqrt() != CIF(-3).sqrt()
1451
+ True
1452
+
1453
+ These intervals overlap, but contain unequal points::
1454
+
1455
+ sage: CIF(3).sqrt() == CIF(3).sqrt()
1456
+ False
1457
+ sage: CIF(3).sqrt() != CIF(3).sqrt()
1458
+ False
1459
+
1460
+ In the future, complex interval elements may be unordered,
1461
+ but or backwards compatibility we order them lexicographically::
1462
+
1463
+ sage: CDF(-1) < -CDF.gen() < CDF.gen() < CDF(1)
1464
+ True
1465
+ sage: CDF(1) >= CDF(1) >= CDF.gen() >= CDF.gen() >= 0 >= -CDF.gen() >= CDF(-1)
1466
+ True
1467
+ """
1468
+ cdef ComplexIntervalFieldElement lt, rt
1469
+ lt = left
1470
+ rt = right
1471
+ if op == Py_EQ:
1472
+ # intervals a == b iff a<=b and b <= a
1473
+ # (this gives a result with two comparisons, where the
1474
+ # obvious approach would use three)
1475
+ return mpfr_lessequal_p(&lt.__re.right, &rt.__re.left) \
1476
+ and mpfr_lessequal_p(&rt.__re.right, &lt.__re.left) \
1477
+ and mpfr_lessequal_p(&lt.__im.right, &rt.__im.left) \
1478
+ and mpfr_lessequal_p(&rt.__im.right, &lt.__im.left)
1479
+ elif op == Py_NE:
1480
+ return mpfr_less_p(&lt.__re.right, &rt.__re.left) \
1481
+ or mpfr_less_p(&rt.__re.right, &lt.__re.left) \
1482
+ or mpfr_less_p(&lt.__im.right, &rt.__im.left) \
1483
+ or mpfr_less_p(&rt.__im.right, &lt.__im.left)
1484
+ else:
1485
+ # Eventually we probably want to disable comparison of complex
1486
+ # intervals, just like python complexes will be unordered.
1487
+ ## raise TypeError("no ordering relation is defined for complex numbers")
1488
+ diff = left - right
1489
+ real_diff = diff.real()
1490
+ imag_diff = diff.imag()
1491
+ if op == Py_LT:
1492
+ return real_diff < 0 or (real_diff == 0 and imag_diff < 0)
1493
+ elif op == Py_LE:
1494
+ return real_diff < 0 or (real_diff == 0 and imag_diff <= 0)
1495
+ elif op == Py_GT:
1496
+ return real_diff > 0 or (real_diff == 0 and imag_diff > 0)
1497
+ elif op == Py_GE:
1498
+ return real_diff > 0 or (real_diff == 0 and imag_diff >= 0)
1499
+
1500
+ def lexico_cmp(left, right):
1501
+ """
1502
+ Intervals are compared lexicographically on the 4-tuple:
1503
+ ``(x.real().lower(), x.real().upper(),
1504
+ x.imag().lower(), x.imag().upper())``
1505
+
1506
+ EXAMPLES::
1507
+
1508
+ sage: a = CIF(RIF(0,1), RIF(0,1))
1509
+ sage: b = CIF(RIF(0,1), RIF(0,2))
1510
+ sage: c = CIF(RIF(0,2), RIF(0,2))
1511
+ sage: a.lexico_cmp(b)
1512
+ -1
1513
+ sage: b.lexico_cmp(c)
1514
+ -1
1515
+ sage: a.lexico_cmp(c)
1516
+ -1
1517
+ sage: a.lexico_cmp(a)
1518
+ 0
1519
+ sage: b.lexico_cmp(a)
1520
+ 1
1521
+
1522
+ TESTS::
1523
+
1524
+ sage: tests = []
1525
+ sage: for rl in (0, 1):
1526
+ ....: for ru in (rl, rl + 1):
1527
+ ....: for il in (0, 1):
1528
+ ....: for iu in (il, il + 1):
1529
+ ....: tests.append((CIF(RIF(rl, ru), RIF(il, iu)), (rl, ru, il, iu)))
1530
+ sage: for (i1, t1) in tests:
1531
+ ....: for (i2, t2) in tests:
1532
+ ....: if t1 == t2:
1533
+ ....: assert(i1.lexico_cmp(i2) == 0)
1534
+ ....: elif t1 < t2:
1535
+ ....: assert(i1.lexico_cmp(i2) == -1)
1536
+ ....: elif t1 > t2:
1537
+ ....: assert(i1.lexico_cmp(i2) == 1)
1538
+ """
1539
+ cdef int a, b
1540
+ a = mpfi_nan_p(left.__re)
1541
+ b = mpfi_nan_p((<ComplexIntervalFieldElement>right).__re)
1542
+ if a != b:
1543
+ return -1
1544
+
1545
+ cdef int i
1546
+ i = mpfr_cmp(&left.__re.left, &(<ComplexIntervalFieldElement>right).__re.left)
1547
+ if i < 0:
1548
+ return -1
1549
+ elif i > 0:
1550
+ return 1
1551
+ i = mpfr_cmp(&left.__re.right, &(<ComplexIntervalFieldElement>right).__re.right)
1552
+ if i < 0:
1553
+ return -1
1554
+ elif i > 0:
1555
+ return 1
1556
+ i = mpfr_cmp(&left.__im.left, &(<ComplexIntervalFieldElement>right).__im.left)
1557
+ if i < 0:
1558
+ return -1
1559
+ elif i > 0:
1560
+ return 1
1561
+ i = mpfr_cmp(&left.__im.right, &(<ComplexIntervalFieldElement>right).__im.right)
1562
+ if i < 0:
1563
+ return -1
1564
+ elif i > 0:
1565
+ return 1
1566
+ return 0
1567
+
1568
+ ########################################################################
1569
+ # Transcendental (and other) functions
1570
+ ########################################################################
1571
+
1572
+ def multiplicative_order(self):
1573
+ """
1574
+ Return the multiplicative order of this complex number, if known,
1575
+ or raise a :exc:`NotImplementedError`.
1576
+
1577
+ EXAMPLES::
1578
+
1579
+ sage: C = CIF
1580
+ sage: i = C.0
1581
+ sage: i.multiplicative_order()
1582
+ 4
1583
+ sage: C(1).multiplicative_order()
1584
+ 1
1585
+ sage: C(-1).multiplicative_order()
1586
+ 2
1587
+ sage: (i^2).multiplicative_order()
1588
+ 2
1589
+ sage: (-i).multiplicative_order()
1590
+ 4
1591
+ sage: C(2).multiplicative_order()
1592
+ +Infinity
1593
+ sage: w = (1 + C(-3).sqrt())/2 ; w
1594
+ 0.50000000000000000? + 0.866025403784439?*I
1595
+ sage: w.multiplicative_order()
1596
+ Traceback (most recent call last):
1597
+ ...
1598
+ NotImplementedError: order of element not known
1599
+ """
1600
+ if self._multiplicative_order is not None:
1601
+ return Integer(self._multiplicative_order)
1602
+ ring = self._parent
1603
+ if self == ring.one():
1604
+ return Integer(1)
1605
+ if self == -ring.one():
1606
+ return Integer(2)
1607
+ if self == ring.gen() or self == -ring.gen():
1608
+ return Integer(4)
1609
+ if 1 not in abs(self): # clearly not a root of unity
1610
+ return infinity
1611
+ raise NotImplementedError("order of element not known")
1612
+
1613
+ def argument(self):
1614
+ r"""
1615
+ The argument (angle) of the complex number, normalized
1616
+ so that `-\pi < \theta.lower() \leq \pi`.
1617
+
1618
+ We raise a :exc:`ValueError` if the interval strictly contains 0,
1619
+ or if the interval contains only 0.
1620
+
1621
+ .. WARNING::
1622
+
1623
+ We do not always use the standard branch cut for
1624
+ argument! If the interval crosses the negative real axis,
1625
+ then the argument will be an interval whose lower bound is
1626
+ less than `\pi` and whose upper bound is more than `\pi`; in
1627
+ effect, we move the branch cut away from the interval.
1628
+
1629
+ EXAMPLES::
1630
+
1631
+ sage: i = CIF.0
1632
+ sage: (i^2).argument()
1633
+ 3.141592653589794?
1634
+ sage: (1+i).argument()
1635
+ 0.785398163397449?
1636
+ sage: i.argument()
1637
+ 1.570796326794897?
1638
+ sage: (-i).argument()
1639
+ -1.570796326794897?
1640
+ sage: (-1/1000 - i).argument()
1641
+ -1.571796326461564?
1642
+ sage: CIF(2).argument()
1643
+ 0
1644
+ sage: CIF(-2).argument()
1645
+ 3.141592653589794?
1646
+
1647
+ Here we see that if the interval crosses the negative real
1648
+ axis, then the argument can exceed `\pi`, and we
1649
+ we violate the standard interval guarantees in the process::
1650
+
1651
+ sage: CIF(-2, RIF(-0.1, 0.1)).argument().str(style='brackets')
1652
+ '[3.0916342578678501 .. 3.1915510493117365]'
1653
+ sage: CIF(-2, -0.1).argument()
1654
+ -3.091634257867851?
1655
+ """
1656
+ if mpfi_has_zero(self.__re) and mpfi_has_zero(self.__im):
1657
+
1658
+ if mpfi_is_zero(self.__re) and mpfi_is_zero(self.__im):
1659
+ raise ValueError("Can't take the argument of complex zero")
1660
+ if not mpfi_is_nonpos(self.__re) and not mpfi_is_nonneg(self.__re) \
1661
+ and not mpfi_is_nonpos(self.__im) and not mpfi_is_nonneg(self.__im):
1662
+ raise ValueError("Can't take the argument of interval strictly containing zero")
1663
+
1664
+ # Now if we exclude zero from the interval, we know that the
1665
+ # argument of the remaining points is bounded. Check which
1666
+ # axes the interval extends along (we can deduce information
1667
+ # about the quadrants from information about the axes).
1668
+
1669
+ which_axes = [False, False, False, False]
1670
+ if not mpfi_is_nonpos(self.__re):
1671
+ which_axes[0] = True
1672
+ if not mpfi_is_nonpos(self.__im):
1673
+ which_axes[1] = True
1674
+ if not mpfi_is_nonneg(self.__re):
1675
+ which_axes[2] = True
1676
+ if not mpfi_is_nonneg(self.__im):
1677
+ which_axes[3] = True
1678
+
1679
+ lower = None
1680
+ for i in range(-1, 3):
1681
+ if which_axes[i % 4] and not which_axes[(i - 1) % 4]:
1682
+ if lower is not None:
1683
+ raise ValueError("Can't take the argument of line-segment interval strictly containing zero")
1684
+ lower = i
1685
+
1686
+ for i in range(lower, lower+4):
1687
+ if which_axes[i % 4] and not which_axes[(i + 1) % 4]:
1688
+ upper = i
1689
+ break
1690
+
1691
+ fld = self._parent.real_field()
1692
+ return fld.pi() * fld(lower, upper) * fld(0.5)
1693
+
1694
+ else:
1695
+
1696
+ # OK, we know that the interval is bounded away from zero
1697
+ # in either the real or the imaginary direction (or both).
1698
+ # We'll handle the "bounded away in the imaginary direction"
1699
+ # case first.
1700
+
1701
+ fld = self._parent.real_field()
1702
+
1703
+ if mpfi_is_strictly_pos(self.__im):
1704
+ return (-self.real() / self.imag()).arctan() + fld.pi()/2
1705
+ if mpfi_is_strictly_neg(self.__im):
1706
+ return (-self.real() / self.imag()).arctan() - fld.pi()/2
1707
+
1708
+ if mpfi_is_strictly_pos(self.__re):
1709
+ return (self.imag() / self.real()).arctan()
1710
+
1711
+ # The only remaining case is that self.__re is strictly
1712
+ # negative and self.__im contains 0. In that case, we
1713
+ # return an interval containing pi.
1714
+
1715
+ return (self.imag() / self.real()).arctan() + fld.pi()
1716
+
1717
+ def arg(self):
1718
+ """
1719
+ Same as :meth:`argument()`.
1720
+
1721
+ EXAMPLES::
1722
+
1723
+ sage: i = CIF.0
1724
+ sage: (i^2).arg()
1725
+ 3.141592653589794?
1726
+ """
1727
+ return self.argument()
1728
+
1729
+ def crosses_log_branch_cut(self):
1730
+ """
1731
+ Return ``True`` if this interval crosses the standard branch cut
1732
+ for :meth:`log()` (and hence for exponentiation) and for argument.
1733
+ (Recall that this branch cut is infinitesimally below the
1734
+ negative portion of the real axis.)
1735
+
1736
+ EXAMPLES::
1737
+
1738
+ sage: z = CIF(1.5, 2.5) - CIF(0, 2.50000000000000001); z
1739
+ 1.5000000000000000? + -1.?e-15*I
1740
+ sage: z.crosses_log_branch_cut()
1741
+ False
1742
+ sage: CIF(-2, RIF(-0.1, 0.1)).crosses_log_branch_cut()
1743
+ True
1744
+ """
1745
+
1746
+ if mpfi_is_nonneg(self.__re):
1747
+ return False
1748
+ if mpfi_is_nonneg(self.__im):
1749
+ return False
1750
+ if mpfi_is_neg(self.__im):
1751
+ return False
1752
+ return True
1753
+
1754
+ def conjugate(self):
1755
+ """
1756
+ Return the complex conjugate of this complex number.
1757
+
1758
+ EXAMPLES::
1759
+
1760
+ sage: i = CIF.0
1761
+ sage: (1+i).conjugate()
1762
+ 1 - 1*I
1763
+ """
1764
+ x = self._new()
1765
+
1766
+ mpfi_set(x.__re, self.__re)
1767
+ mpfi_neg(x.__im, self.__im)
1768
+ return x
1769
+
1770
+ def exp(self):
1771
+ r"""
1772
+ Compute `e^z` or `\exp(z)` where `z` is the complex number ``self``.
1773
+
1774
+ EXAMPLES::
1775
+
1776
+ sage: i = ComplexIntervalField(300).0
1777
+ sage: z = 1 + i
1778
+ sage: z.exp()
1779
+ 1.46869393991588515713896759732660426132695673662900872279767567631093696585951213872272450? + 2.28735528717884239120817190670050180895558625666835568093865811410364716018934540926734485?*I
1780
+ """
1781
+ mag = self.real().exp()
1782
+ theta = self.imag()
1783
+ re = theta.cos() * mag
1784
+ im = theta.sin() * mag
1785
+ return ComplexIntervalFieldElement(self._parent, re, im)
1786
+
1787
+ def log(self, base=None):
1788
+ """
1789
+ Complex logarithm of `z`.
1790
+
1791
+ .. WARNING::
1792
+
1793
+ This does always not use the standard branch cut for complex log!
1794
+ See the docstring for :meth:`argument()` to see what we do instead.
1795
+
1796
+ EXAMPLES::
1797
+
1798
+ sage: a = CIF(RIF(3, 4), RIF(13, 14))
1799
+ sage: a.log().str(style='brackets')
1800
+ '[2.5908917751460420 .. 2.6782931373360067] + [1.2722973952087170 .. 1.3597029935721503]*I'
1801
+ sage: a.log().exp().str(style='brackets')
1802
+ '[2.7954667135098274 .. 4.2819545928390213] + [12.751682453911920 .. 14.237018048974635]*I'
1803
+ sage: a in a.log().exp()
1804
+ True
1805
+
1806
+ If the interval crosses the negative real axis, then we don't
1807
+ use the standard branch cut (and we violate the interval guarantees)::
1808
+
1809
+ sage: CIF(-3, RIF(-1/4, 1/4)).log().str(style='brackets')
1810
+ '[1.0986122886681095 .. 1.1020725100903968] + [3.0584514217013518 .. 3.2247338854782349]*I'
1811
+ sage: CIF(-3, -1/4).log()
1812
+ 1.102072510090397? - 3.058451421701352?*I
1813
+
1814
+ Usually if an interval contains zero, we raise an exception::
1815
+
1816
+ sage: CIF(RIF(-1,1),RIF(-1,1)).log()
1817
+ Traceback (most recent call last):
1818
+ ...
1819
+ ValueError: Can...t take the argument of interval strictly containing zero
1820
+
1821
+ But we allow the exact input zero::
1822
+
1823
+ sage: CIF(0).log()
1824
+ [-infinity .. -infinity]
1825
+
1826
+ If a base is passed from another function, we can accommodate this::
1827
+
1828
+ sage: CIF(-1,1).log(2)
1829
+ 0.500000000000000? + 3.39927010637040?*I
1830
+ """
1831
+ if not self:
1832
+ from sage.rings.real_mpfi import RIF
1833
+ return RIF(0).log()
1834
+ re = abs(self).log()
1835
+ im = self.argument()
1836
+ if base == 'e':
1837
+ base = None
1838
+ if base is not None:
1839
+ base = self._parent._real_field()(base)
1840
+ f = base.log()
1841
+ re /= f
1842
+ im /= f
1843
+ return ComplexIntervalFieldElement(self._parent, re, im)
1844
+
1845
+ def sqrt(self, bint all=False, **kwds):
1846
+ """
1847
+ The square root function.
1848
+
1849
+ .. WARNING::
1850
+
1851
+ We approximate the standard branch cut along the negative real
1852
+ axis, with ``sqrt(-r^2) = i*r`` for positive real ``r``; but if
1853
+ the interval crosses the negative real axis, we pick the root with
1854
+ positive imaginary component for the entire interval.
1855
+
1856
+ INPUT:
1857
+
1858
+ - ``all`` -- boolean (default: ``False``); if ``True``, return a list
1859
+ of all square roots
1860
+
1861
+ EXAMPLES::
1862
+
1863
+ sage: CIF(-1).sqrt()^2
1864
+ -1
1865
+ sage: sqrt(CIF(2))
1866
+ 1.414213562373095?
1867
+ sage: sqrt(CIF(-1))
1868
+ 1*I
1869
+ sage: sqrt(CIF(2-I))^2
1870
+ 2.00000000000000? - 1.00000000000000?*I
1871
+ sage: CC(-2-I).sqrt()^2
1872
+ -2.00000000000000 - 1.00000000000000*I
1873
+
1874
+ Here, we select a non-principal root for part of the interval, and
1875
+ violate the standard interval guarantees::
1876
+
1877
+ sage: CIF(-5, RIF(-1, 1)).sqrt().str(style='brackets')
1878
+ '[-0.22250788030178321 .. 0.22250788030178296] + [2.2251857651053086 .. 2.2581008643532262]*I'
1879
+ sage: CIF(-5, -1).sqrt()
1880
+ 0.222507880301783? - 2.247111425095870?*I
1881
+ """
1882
+ if self.is_zero():
1883
+ return [self] if all else self
1884
+ if mpfi_is_zero(self.__im) and not mpfi_has_zero(self.__re):
1885
+ if mpfr_sgn(&self.__re.left) > 0:
1886
+ x = ComplexIntervalFieldElement(self._parent, self.real().sqrt(), 0)
1887
+ else:
1888
+ x = ComplexIntervalFieldElement(self._parent, 0, (-self.real()).sqrt())
1889
+ else:
1890
+ theta = self.argument()/2
1891
+ rho = abs(self).sqrt()
1892
+ x = ComplexIntervalFieldElement(self._parent, rho*theta.cos(), rho*theta.sin())
1893
+ if all:
1894
+ return [x, -x]
1895
+ else:
1896
+ return x
1897
+
1898
+ def is_square(self):
1899
+ r"""
1900
+ Return ``True`` as `\CC` is algebraically closed.
1901
+
1902
+ EXAMPLES::
1903
+
1904
+ sage: CIF(2, 1).is_square()
1905
+ True
1906
+ """
1907
+ return True
1908
+
1909
+ def is_NaN(self):
1910
+ r"""
1911
+ Return ``True`` if this is not-a-number.
1912
+
1913
+ EXAMPLES::
1914
+
1915
+ sage: CIF(2, 1).is_NaN()
1916
+ False
1917
+ sage: CIF(NaN).is_NaN() # needs sage.symbolic
1918
+ True
1919
+ sage: (1 / CIF(0, 0)).is_NaN()
1920
+ True
1921
+ """
1922
+ return mpfi_nan_p(self.__re) or mpfi_nan_p(self.__im)
1923
+
1924
+ def cos(self):
1925
+ r"""
1926
+ Compute the cosine of this complex interval.
1927
+
1928
+ EXAMPLES::
1929
+
1930
+ sage: CIF(1,1).cos()
1931
+ 0.833730025131149? - 0.988897705762865?*I
1932
+ sage: CIF(3).cos()
1933
+ -0.9899924966004455?
1934
+ sage: CIF(0,2).cos()
1935
+ 3.762195691083632?
1936
+
1937
+ Check that :issue:`17285` is fixed::
1938
+
1939
+ sage: CIF(cos(2/3)) # needs sage.symbolic
1940
+ 0.7858872607769480?
1941
+
1942
+ ALGORITHM:
1943
+
1944
+ The implementation uses the following trigonometric identity
1945
+
1946
+ .. MATH::
1947
+
1948
+ \cos(x + iy) = \cos(x) \cosh(y) - i \sin(x) \sinh(y)
1949
+ """
1950
+ res = self._new()
1951
+ cdef mpfi_t tmp
1952
+ mpfi_init2(tmp, self._parent.prec())
1953
+ sig_on()
1954
+ mpfi_cos(res.__re, self.__re)
1955
+ mpfi_cosh(tmp, self.__im)
1956
+ mpfi_mul(res.__re, res.__re, tmp)
1957
+
1958
+ mpfi_sin(res.__im, self.__re)
1959
+ mpfi_sinh(tmp, self.__im)
1960
+ mpfi_mul(res.__im, res.__im, tmp)
1961
+ mpfi_neg(res.__im, res.__im)
1962
+ sig_off()
1963
+ mpfi_clear(tmp)
1964
+ return res
1965
+
1966
+ def sin(self):
1967
+ r"""
1968
+ Compute the sine of this complex interval.
1969
+
1970
+ EXAMPLES::
1971
+
1972
+ sage: CIF(1,1).sin()
1973
+ 1.298457581415978? + 0.634963914784736?*I
1974
+ sage: CIF(2).sin()
1975
+ 0.909297426825682?
1976
+ sage: CIF(0,2).sin()
1977
+ 3.626860407847019?*I
1978
+
1979
+ Check that :issue:`17825` is fixed::
1980
+
1981
+ sage: CIF(sin(2/3)) # needs sage.symbolic
1982
+ 0.618369803069737?
1983
+
1984
+ ALGORITHM:
1985
+
1986
+ The implementation uses the following trigonometric identity
1987
+
1988
+ .. MATH::
1989
+
1990
+ \sin(x + iy) = \sin(x) \cosh(y) + i \cos (x) \sinh(y)
1991
+ """
1992
+ res = self._new()
1993
+ cdef mpfi_t tmp
1994
+ mpfi_init2(tmp, self._parent.prec())
1995
+ sig_on()
1996
+ mpfi_sin(res.__re, self.__re)
1997
+ mpfi_cosh(tmp, self.__im)
1998
+ mpfi_mul(res.__re, res.__re, tmp)
1999
+
2000
+ mpfi_cos(res.__im, self.__re)
2001
+ mpfi_sinh(tmp, self.__im)
2002
+ mpfi_mul(res.__im, res.__im, tmp)
2003
+ sig_off()
2004
+ mpfi_clear(tmp)
2005
+ return res
2006
+
2007
+ def tan(self):
2008
+ r"""
2009
+ Return the tangent of this complex interval.
2010
+
2011
+ EXAMPLES::
2012
+
2013
+ sage: CIF(1,1).tan()
2014
+ 0.27175258531952? + 1.08392332733870?*I
2015
+ sage: CIF(2).tan()
2016
+ -2.185039863261519?
2017
+ sage: CIF(0,2).tan()
2018
+ 0.964027580075817?*I
2019
+ """
2020
+ return self.sin() / self.cos()
2021
+
2022
+ def cosh(self):
2023
+ r"""
2024
+ Return the hyperbolic cosine of this complex interval.
2025
+
2026
+ EXAMPLES::
2027
+
2028
+ sage: CIF(1,1).cosh()
2029
+ 0.833730025131149? + 0.988897705762865?*I
2030
+ sage: CIF(2).cosh()
2031
+ 3.762195691083632?
2032
+ sage: CIF(0,2).cosh()
2033
+ -0.4161468365471424?
2034
+
2035
+ ALGORITHM:
2036
+
2037
+ The implementation uses the following trigonometric identity
2038
+
2039
+ .. MATH::
2040
+
2041
+ \cosh(x+iy) = \cos(y) \cosh(x) + i \sin(y) \sinh(x)
2042
+ """
2043
+ res = self._new()
2044
+ cdef mpfi_t tmp
2045
+ mpfi_init2(tmp, self._parent.prec())
2046
+ sig_on()
2047
+ mpfi_cos(res.__re, self.__im)
2048
+ mpfi_cosh(tmp, self.__re)
2049
+ mpfi_mul(res.__re, res.__re, tmp)
2050
+
2051
+ mpfi_sin(res.__im, self.__im)
2052
+ mpfi_sinh(tmp, self.__re)
2053
+ mpfi_mul(res.__im, res.__im, tmp)
2054
+ sig_off()
2055
+ mpfi_clear(tmp)
2056
+ return res
2057
+
2058
+ def sinh(self):
2059
+ r"""
2060
+ Return the hyperbolic sine of this complex interval.
2061
+
2062
+ EXAMPLES::
2063
+
2064
+ sage: CIF(1,1).sinh()
2065
+ 0.634963914784736? + 1.298457581415978?*I
2066
+ sage: CIF(2).sinh()
2067
+ 3.626860407847019?
2068
+ sage: CIF(0,2).sinh()
2069
+ 0.909297426825682?*I
2070
+
2071
+ ALGORITHM:
2072
+
2073
+ The implementation uses the following trigonometric identity
2074
+
2075
+ .. MATH::
2076
+
2077
+ \sinh(x+iy) = \cos(y) \sinh(x) + i \sin(y) \cosh(x)
2078
+ """
2079
+ res = self._new()
2080
+ cdef mpfi_t tmp
2081
+ mpfi_init2(tmp, self._parent.prec())
2082
+ sig_on()
2083
+ mpfi_cos(res.__re, self.__im)
2084
+ mpfi_sinh(tmp, self.__re)
2085
+ mpfi_mul(res.__re, res.__re, tmp)
2086
+
2087
+ mpfi_sin(res.__im, self.__im)
2088
+ mpfi_cosh(tmp, self.__re)
2089
+ mpfi_mul(res.__im, res.__im, tmp)
2090
+ sig_off()
2091
+ mpfi_clear(tmp)
2092
+ return res
2093
+
2094
+ def tanh(self):
2095
+ r"""
2096
+ Return the hyperbolic tangent of this complex interval.
2097
+
2098
+ EXAMPLES::
2099
+
2100
+ sage: CIF(1,1).tanh()
2101
+ 1.08392332733870? + 0.27175258531952?*I
2102
+ sage: CIF(2).tanh()
2103
+ 0.964027580075817?
2104
+ sage: CIF(0,2).tanh()
2105
+ -2.185039863261519?*I
2106
+ """
2107
+ return self.sinh() / self.cosh()
2108
+
2109
+ def zeta(self, a=None):
2110
+ """
2111
+ Return the image of this interval by the Hurwitz zeta function.
2112
+
2113
+ For ``a = 1`` (or ``a = None``), this computes the Riemann zeta function.
2114
+
2115
+ EXAMPLES::
2116
+
2117
+ sage: zeta(CIF(2, 3))
2118
+ 0.7980219851462757? - 0.1137443080529385?*I
2119
+ sage: _.parent()
2120
+ Complex Interval Field with 53 bits of precision
2121
+ sage: CIF(2, 3).zeta(1/2)
2122
+ -1.955171567161496? + 3.123301509220897?*I
2123
+ """
2124
+ from sage.rings.complex_arb import ComplexBallField
2125
+ return ComplexBallField(self.prec())(self).zeta(a).\
2126
+ _complex_mpfi_(self._parent)
2127
+
2128
+ cdef _negate_interval(mpfr_ptr xmin, mpfr_ptr xmax):
2129
+ """
2130
+ Negate interval with endpoints xmin and xmax in place.
2131
+ """
2132
+ mpfr_swap(xmin, xmax)
2133
+ mpfr_neg(xmin, xmin, MPFR_RNDD)
2134
+ mpfr_neg(xmax, xmax, MPFR_RNDU)
2135
+
2136
+ cdef _inversion_coordinate(
2137
+ mpfr_ptr result, mpfr_ptr tmp,
2138
+ mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_denom, mpfr_rnd_t rnd):
2139
+ """
2140
+ Compute the x-coordinate of the image of the point (x,y) under inversion.
2141
+ That is compute x / (x^2 + y^2).
2142
+
2143
+ rnd_denom determines how to round when computing the denominator.
2144
+ rnd determines how to round when doing the division.
2145
+
2146
+ This function expects the callee to allocate and pass an mpfr number tmp
2147
+ that will be used for intermediate computations. This way, an allocated
2148
+ mpfr number can be used in multiple calculations.
2149
+ """
2150
+
2151
+ mpfr_sqr(tmp, x, rnd_denom)
2152
+ mpfr_sqr(result, y, rnd_denom)
2153
+ mpfr_add(tmp, tmp, result, rnd_denom)
2154
+ mpfr_div(result, x, tmp, rnd)
2155
+
2156
+ cdef _inversion_coordinate_pos_down(
2157
+ mpfr_ptr result, mpfr_ptr tmp,
2158
+ mpfr_srcptr x, mpfr_srcptr y):
2159
+ """
2160
+ Computes a lower bound for x / (x^2 + y^2) assuming that x is non-negative.
2161
+
2162
+ Note that the result will not be NaN as long as x or y is positive.
2163
+ """
2164
+
2165
+ # Let us check that we do not get NaN.
2166
+ # We need to check mpfr_div since it could return NaN if we divide by zero
2167
+ # (it currently returns +/-inf, but the documentation says this might be
2168
+ # subject to change).
2169
+ # We round up when computing the denominator and thus should get something
2170
+ # positive if x or y is positive. Even if, say, x is so small that squaring
2171
+ # produces something smaller than the smallest positive mpfr floating point
2172
+ # number, we get something non-zero because we round up.
2173
+
2174
+ _inversion_coordinate(
2175
+ result, tmp, x, y,
2176
+ MPFR_RNDU, # denominator rounding
2177
+ MPFR_RNDD) # division rounding
2178
+
2179
+ cdef _inversion_coordinate_pos_up(
2180
+ mpfr_ptr result, mpfr_ptr tmp,
2181
+ mpfr_srcptr x, mpfr_srcptr y):
2182
+ """
2183
+ Computes an upper bound for x / (x^2 + y^2) assuming that x is non-negative.
2184
+ """
2185
+ _inversion_coordinate(
2186
+ result, tmp, x, y,
2187
+ MPFR_RNDD, # denominator rounding
2188
+ MPFR_RNDU) # division rounding
2189
+
2190
+ cdef _inversion_coordinate_neg_down(
2191
+ mpfr_ptr result, mpfr_ptr tmp,
2192
+ mpfr_srcptr x, mpfr_srcptr y):
2193
+ """
2194
+ Computes a lower bound for x / (x^2 + y^2) assuming that x is non-positive.
2195
+ """
2196
+ _inversion_coordinate(
2197
+ result, tmp, x, y,
2198
+ MPFR_RNDD, # denominator rounding
2199
+ MPFR_RNDD) # division rounding
2200
+
2201
+ cdef _circle_invert_standard(
2202
+ mpfr_ptr amin, mpfr_ptr amax, mpfr_ptr bmin, mpfr_ptr bmax,
2203
+ mpfr_srcptr xmin, mpfr_srcptr xmax, mpfr_srcptr ymin, mpfr_srcptr ymax,
2204
+ bint crosses_x_axis, mpfr_prec_t prec):
2205
+ """
2206
+ Assumes that the input [xmin, xmax] + [ymin, ymax] * I is in standard form
2207
+ as described above in ComplexIntervalFieldElement.__invert__ with
2208
+ crosses_x_axis saying whether case (II) applies.
2209
+
2210
+ Computes a complex interval [amin, amax] + [bmin, bmax] * I containing
2211
+ the image of the input under circle inversion f(z) = conjugate(1/z).
2212
+ """
2213
+
2214
+ # Note that, by the maximum principle, it is sufficient to consider the
2215
+ # image of the boundary of the input rect which will be formed by four
2216
+ # arcs or line segments.
2217
+
2218
+ # It is useful to do a case analysis by considering whether the input
2219
+ # crosses the x-Axis, the north east or south east diagonal, respectively.
2220
+ #
2221
+ # Given standard form, the input also has to cross the north east
2222
+ # diagonal and x-Axis if it crosses the south east diagonal.
2223
+ #
2224
+ # Thus, we are left with five cases:
2225
+ #
2226
+ # NE diagonal x-Axis SE diagonal.
2227
+ # 1.
2228
+ # 2. crosses
2229
+ # 3. crosses
2230
+ # 4. crosses crosses
2231
+ # 5. crosses crosses crosses
2232
+
2233
+ # The reader can go to https://www.shadertoy.com/view/M3VXWG to explore
2234
+ # the different cases visually.
2235
+
2236
+ # Case 1 is the easiest (and the generic case for small intervals).
2237
+ #
2238
+ # Consider the images
2239
+ # f(xmin + ymin * I), ..., f(xmax + ymax * I)
2240
+ # of the four corners of the input rect under inversion f.
2241
+ # Now consider the axis-parallel rectangle R that these images span.
2242
+ # In general, the image of the input rect might not be contained in R.
2243
+ # In case 1, however, (and only in case 1) it is and we furthermore know
2244
+ # which image is mapped to which edge of R. Thus, we have:
2245
+ #
2246
+ # amin = Re(f(xmax + ymax * I)) # Image of right top corner
2247
+ # amax = Re(f(xmin + ymin * I)) # left bottom corner
2248
+ # bmin = Im(f(xmax + ymin * I)) # right bottom corner
2249
+ # = Re(f(ymin + xmax * I))
2250
+ # bmax = Im(f(xmin + ymax * I)) # left top corner
2251
+ # = Re(f(ymax + xmin * I))
2252
+ #
2253
+ # Re(f(...)) can be computed with the correct rounding using one of the
2254
+ # helper functions such as _inversion_coordinate_pos_down.
2255
+
2256
+ # For the other cases, we might need to consider the images of two corners
2257
+ # and take the minimum to compute, say amin.
2258
+
2259
+ # Furthermore, we also need to consider the image of t + xmin * I which is
2260
+ # a circle touching the y-Axis at the origin. Depending on which of the
2261
+ # diagonals and x-Axis the input rect crosses, we need to expand R to
2262
+ # include the lowest, highest or rightmost point on this circle for the
2263
+ # correct result.
2264
+ #
2265
+ # For example, we have
2266
+ # amax = 1 / xmin for case 2 and bmax = 1 / (2 * ymin) for case 3.
2267
+ #
2268
+
2269
+ cdef bint crosses_NE_diagonal = mpfr_cmp(ymax, xmin) > 0
2270
+ cdef bint crosses_both_diagonals = False
2271
+ # Using that input can only cross south east diagonal if it crosses
2272
+ # x-Axis and north east diagonal.
2273
+ if crosses_x_axis and crosses_NE_diagonal:
2274
+ crosses_both_diagonals = mpfr_cmpabs(ymin, xmin) > 0
2275
+
2276
+ # Some temporary variables
2277
+ cdef mpfr_t tmp, min2
2278
+
2279
+ mpfr_init2(tmp, prec)
2280
+ if crosses_NE_diagonal:
2281
+ # Temporary variable needed only in some cases.
2282
+ mpfr_init2(min2, prec)
2283
+
2284
+ ########################################################################
2285
+ # Compute amin
2286
+
2287
+ # Use image of right top corner
2288
+ _inversion_coordinate_pos_down(amin, tmp, xmax, ymax)
2289
+
2290
+ if crosses_NE_diagonal:
2291
+ # Also use image of left top corner.
2292
+
2293
+ # This is because in this case, the image of the left top corner
2294
+ # can be left of the image of the right top corner.
2295
+
2296
+ _inversion_coordinate_pos_down(min2, tmp, xmin, ymax)
2297
+
2298
+ # Note that mpfr_min does not return NaN if one (but not the other)
2299
+ # input is NaN. This could be a problem. Luckily,
2300
+ # _inversion_coordinate_pos_down never produces NaN.
2301
+ mpfr_min(amin, amin, min2, MPFR_RNDD)
2302
+
2303
+ # Note that we do not need to consider the images of the left or right
2304
+ # bottom corner here. Not even in case 5.
2305
+ # This is because in standard form, the top edge is further aways from
2306
+ # the x-Axis than the bottom edge. Thus, the images of the left and
2307
+ # right corner of the top edge is left of those of the bottom edge,
2308
+ # respectively.
2309
+
2310
+ # Potential optimization: if bmax >= amax, we only need to use the
2311
+ # image of the left top corner and skip computing the image of the
2312
+ # right top corner.
2313
+
2314
+ ########################################################################
2315
+ # Compute amax
2316
+
2317
+ if crosses_x_axis:
2318
+ # Use rightmost point on the circle that is the image of
2319
+ # image of t + xmin * I
2320
+ mpfr_ui_div(amax, 1, xmin, MPFR_RNDU)
2321
+ else:
2322
+ # Use image of left bottom corner
2323
+ _inversion_coordinate_pos_up(amax, tmp, xmin, ymin)
2324
+
2325
+ ########################################################################
2326
+ # Compute bmax
2327
+
2328
+ # In case 5, bmin can reuse bmax (up to sign), so we compute bmax first.
2329
+
2330
+ if crosses_NE_diagonal:
2331
+ # Use highest point on the circle that is the image of
2332
+ # t + xmin * I. That is bmax = 1 / (2 * xmin).
2333
+ if crosses_x_axis:
2334
+ # Re-use amax = 1 / xmin.
2335
+ # We can just copy the mantissa and decrease the exponent by 1.
2336
+ mpfr_div_2ui(bmax, amax, 1, MPFR_RNDU)
2337
+ else:
2338
+ # Compute bmax from scratch.
2339
+ mpfr_ui_div(bmax, 1, xmin, MPFR_RNDU)
2340
+ mpfr_div_2ui(bmax, bmax, 1, MPFR_RNDU)
2341
+ else:
2342
+ # Use image of of left top corner
2343
+ _inversion_coordinate_pos_up(bmax, tmp, ymax, xmin)
2344
+
2345
+ ########################################################################
2346
+ # Compute bmin
2347
+
2348
+ # bmin is probably the hardest to compute.
2349
+
2350
+ cdef bint right_edge_crosses_NE_diagonal
2351
+
2352
+ if crosses_x_axis:
2353
+ # ymin and thus bmin will be negative.
2354
+ if crosses_both_diagonals:
2355
+ # We are in case 5.
2356
+ #
2357
+ # Use lowest point on the circle that is the image of
2358
+ # t + xmin * I. That is bmin = -1 / (2 * xmin).
2359
+ #
2360
+ # We can reuse bmax = 1 / (2 * xmin).
2361
+ mpfr_neg(bmin, bmax, MPFR_RNDD)
2362
+ else:
2363
+ # Use image of left bottom corner.
2364
+ _inversion_coordinate_neg_down(bmin, tmp, ymin, xmin)
2365
+ else:
2366
+ # ymin and thus bmin will be non-negative.
2367
+
2368
+ # Use image of right bottom corner.
2369
+ _inversion_coordinate_pos_down(bmin, tmp, ymin, xmax)
2370
+
2371
+ if crosses_NE_diagonal:
2372
+ right_edge_crosses_NE_diagonal = mpfr_cmp(ymax, xmax) > 0
2373
+ if right_edge_crosses_NE_diagonal:
2374
+ # Also use image of right top corner.
2375
+ #
2376
+ # This is similar to the computation of amin which also
2377
+ # considered a second corner when crosses_NE_diagonal.
2378
+ #
2379
+ # In particular, the same comment about NaN applies.
2380
+ #
2381
+ _inversion_coordinate_pos_down(min2, tmp, ymax, xmax)
2382
+
2383
+ # See comment about NaN above.
2384
+ mpfr_min(bmin, bmin, min2, MPFR_RNDD)
2385
+
2386
+ ########################################################################
2387
+ # Free memory
2388
+
2389
+ mpfr_clear(tmp)
2390
+ if crosses_NE_diagonal:
2391
+ mpfr_clear(min2)
2392
+
2393
+
2394
+ def make_ComplexIntervalFieldElement0( fld, re, im ):
2395
+ """
2396
+ Construct a :class:`ComplexIntervalFieldElement` for pickling.
2397
+
2398
+ TESTS::
2399
+
2400
+ sage: a = CIF(1 + I)
2401
+ sage: loads(dumps(a)) == a # indirect doctest
2402
+ True
2403
+ """
2404
+ return fld(re, im)
2405
+
2406
+
2407
+ def create_ComplexIntervalFieldElement(s_real, s_imag=None, int pad=0, min_prec=53):
2408
+ r"""
2409
+ Return the complex number defined by the strings ``s_real`` and ``s_imag``
2410
+ as an element of ``ComplexIntervalField(prec=n)``, where `n` potentially
2411
+ has slightly more (controlled by pad) bits than given by `s`.
2412
+
2413
+ INPUT:
2414
+
2415
+ - ``s_real`` -- string that defines a real number (or something whose
2416
+ string representation defines a number)
2417
+
2418
+ - ``s_imag`` -- string that defines a real number (or something whose
2419
+ string representation defines a number)
2420
+
2421
+ - ``pad`` -- integer at least 0
2422
+
2423
+ - ``min_prec`` -- number will have at least this many bits of precision,
2424
+ no matter what
2425
+
2426
+ EXAMPLES::
2427
+
2428
+ sage: ComplexIntervalFieldElement('2.3')
2429
+ 2.300000000000000?
2430
+ sage: ComplexIntervalFieldElement('2.3','1.1')
2431
+ 2.300000000000000? + 1.100000000000000?*I
2432
+ sage: ComplexIntervalFieldElement(10)
2433
+ 10
2434
+ sage: ComplexIntervalFieldElement(10,10)
2435
+ 10 + 10*I
2436
+ sage: ComplexIntervalFieldElement(1.000000000000000000000000000,2)
2437
+ 1 + 2*I
2438
+ sage: ComplexIntervalFieldElement(1,2.000000000000000000000)
2439
+ 1 + 2*I
2440
+ sage: ComplexIntervalFieldElement(1.234567890123456789012345, 5.4321098654321987654321)
2441
+ 1.234567890123456789012350? + 5.432109865432198765432000?*I
2442
+
2443
+ TESTS:
2444
+
2445
+ Make sure we've rounded up ``log(10,2)`` enough to guarantee
2446
+ sufficient precision (:issue:`10164`). This is a little tricky
2447
+ because at the time of writing, we don't support intervals long
2448
+ enough to trip the error. However, at least we can make sure that
2449
+ we either do it correctly or fail noisily::
2450
+
2451
+ sage: c_CIFE = sage.rings.complex_interval.create_ComplexIntervalFieldElement
2452
+ sage: for kp in range(2,6):
2453
+ ....: s = '1.' + '0'*10**kp + '1'
2454
+ ....: try:
2455
+ ....: assert c_CIFE(s,0).real()-1 != 0
2456
+ ....: assert c_CIFE(0,s).imag()-1 != 0
2457
+ ....: except TypeError:
2458
+ ....: pass
2459
+ """
2460
+ if s_imag is None:
2461
+ s_imag = 0
2462
+
2463
+ if not isinstance(s_real, str):
2464
+ s_real = str(s_real).strip()
2465
+ if not isinstance(s_imag, str):
2466
+ s_imag = str(s_imag).strip()
2467
+ #if base == 10:
2468
+ bits = max(int(LOG_TEN_TWO_PLUS_EPSILON*len(s_real)),
2469
+ int(LOG_TEN_TWO_PLUS_EPSILON*len(s_imag)))
2470
+ #else:
2471
+ # bits = max(int(math.log(base,2)*len(s_imag)),int(math.log(base,2)*len(s_imag)))
2472
+
2473
+ from sage.rings.complex_interval_field import ComplexIntervalField
2474
+ C = ComplexIntervalField(prec=max(bits+pad, min_prec))
2475
+ return ComplexIntervalFieldElement(C, s_real, s_imag)