passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (314) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,2582 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.rings.padics
3
+ r"""
4
+ Elements of Berkovich space.
5
+
6
+ :class:`Berkovich_Element` is an abstract parent class for elements of any Berkovich space.
7
+
8
+ :class:`Berkovich_Element_Cp_Affine` and :class:`Berkovich_Element_Cp_Projective`
9
+ implement elements of Berkovich space over `\CC_p` and `P^1(\CC_p)`. Elements are
10
+ determined by specific data and fall into one of the four following types:
11
+
12
+ - Type I points are represented by a center.
13
+
14
+ - Type II points are represented by a center and a rational power of `p`.
15
+
16
+ - Type III points are represented by a center and a nonnegative real radius.
17
+
18
+ - Type IV points are represented by a finite list of centers and a finite list of
19
+ nonnegative radii.
20
+
21
+ For an exposition of Berkovich space over `\CC_p`, see Chapter 6 of [Ben2019]_. For a more
22
+ involved exposition, see Chapter 1 and 2 of [BR2010]_.
23
+
24
+ AUTHORS:
25
+
26
+ - Alexander Galarraga (2020-06-22): initial implementation
27
+ """
28
+
29
+ # *****************************************************************************
30
+ # This program is free software: you can redistribute it and/or modify
31
+ # it under the terms of the GNU General Public License as published by
32
+ # the Free Software Foundation, either version 2 of the License, or
33
+ # (at your option) any later version.
34
+ # https://www.gnu.org/licenses/
35
+ # *****************************************************************************
36
+
37
+ import sage.rings.abc
38
+
39
+ from sage.categories.function_fields import FunctionFields
40
+ from sage.misc.lazy_import import lazy_import
41
+ from sage.rings.infinity import Infinity
42
+ from sage.rings.integer_ring import ZZ
43
+ from sage.rings.rational_field import QQ
44
+ from sage.rings.real_mpfr import RealNumber, RR
45
+ from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field
46
+ from sage.schemes.projective.projective_space import ProjectiveSpace
47
+ from sage.structure.element import Element, Expression
48
+
49
+ lazy_import('sage.rings.padics.padic_generic_element', 'pAdicGenericElement')
50
+ lazy_import('sage.rings.padics.padic_base_generic', 'pAdicBaseGeneric')
51
+
52
+
53
+ class Berkovich_Element(Element):
54
+ """
55
+ The parent class for any element of a Berkovich space.
56
+ """
57
+ pass
58
+
59
+
60
+ class Berkovich_Element_Cp(Berkovich_Element):
61
+ r"""
62
+ The abstract parent class for any element of Berkovich space over `\CC_p`.
63
+
64
+ This class should never be instantiated, instead use :class:`Berkovich_Element_Cp_Affine`
65
+ or :class:`Berkovich_Element_Cp_Projective`.
66
+
67
+ EXAMPLES::
68
+
69
+ sage: B = Berkovich_Cp_Affine(3)
70
+ sage: B(2)
71
+ Type I point centered at 2 + O(3^20)
72
+
73
+ ::
74
+
75
+ sage: B(0, 1)
76
+ Type II point centered at 0 of radius 3^0
77
+ """
78
+
79
+ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type=None, error_check=True):
80
+ """
81
+ Initialization function.
82
+
83
+ EXAMPLES::
84
+
85
+ sage: B = Berkovich_Cp_Affine(5)
86
+ sage: B(4)
87
+ Type I point centered at 4 + O(5^20)
88
+ """
89
+ from sage.rings.polynomial.polynomial_element import Polynomial
90
+ from sage.rings.fraction_field_element import FractionFieldElement_1poly_field
91
+ self._type = None
92
+
93
+ # if radius is a list or a tuple, this is a type 4 point
94
+ if isinstance(radius, (list, tuple)):
95
+ if error_check:
96
+ if not isinstance(center, (list, tuple)):
97
+ raise TypeError("center was passed a list but radius was not a list")
98
+ if len(radius) != len(center):
99
+ raise ValueError("the same number of centers and radii "
100
+ "must be specified to create "
101
+ "a type IV point")
102
+ self._center_lst = list(center)
103
+ self._radius_lst = list(radius)
104
+ self._prec = len(self._radius_lst)
105
+ self._center_func = None
106
+ self._radius_func = None
107
+ self._type = 4
108
+ self._radius = None
109
+ self._center = None
110
+ if not error_check:
111
+ return
112
+
113
+ elif isinstance(center, Element) and isinstance(radius, Element):
114
+ from sage.rings.polynomial.multi_polynomial import MPolynomial
115
+ if isinstance(center, MPolynomial):
116
+ try:
117
+ center = center.univariate_polynomial()
118
+ except AttributeError:
119
+ raise TypeError('center was %s, a multivariable polynomial' % center)
120
+
121
+ # check if the radius and the center are functions
122
+ center_func_check = center.parent() in FunctionFields() or \
123
+ isinstance(center, (Polynomial, FractionFieldElement_1poly_field, Expression))
124
+ radius_func_check = radius.parent() in FunctionFields() or \
125
+ isinstance(radius, (Polynomial, FractionFieldElement_1poly_field, Expression))
126
+
127
+ if center_func_check:
128
+ # check that both center and radii are supported univariate function
129
+ center_expr_check = False
130
+ radius_expr_check = False
131
+ if error_check:
132
+ if isinstance(center, Expression):
133
+ if len(center.variables()) != 1:
134
+ raise ValueError("an expression with %s " % (len(center.variables())) +
135
+ "variables cannot define the centers approximating a type IV point")
136
+ else:
137
+ # we do this since .subs is currently buggy for polynomials but not expressions
138
+ center_expr_check = True
139
+ if not radius_func_check:
140
+ raise TypeError("center was passed a function but radius was not a function")
141
+ if isinstance(radius, Expression):
142
+ if len(radius.variables()) != 1:
143
+ raise ValueError("an expression with %s " % (len(radius.variables())) +
144
+ "variables cannot define the radii approximating a type IV point")
145
+ else:
146
+ radius_expr_check = True
147
+ else:
148
+ if isinstance(center, Expression):
149
+ center_expr_check = True
150
+ if isinstance(radius, Expression):
151
+ radius_expr_check = True
152
+ self._type = 4
153
+ self._prec = prec
154
+ center_lst = []
155
+ radius_lst = []
156
+ self._center_func = center
157
+ self._radius_func = radius
158
+ if center_expr_check:
159
+ x = self._center_func.variables()[0]
160
+ if radius_expr_check:
161
+ y = self._radius_func.variables()[0]
162
+ for i in range(1, self._prec + 1):
163
+ if center_expr_check:
164
+ # we use .subs for expressions to avoid deprecation
165
+ center_lst.append(self._center_func.subs({x: i}))
166
+ else:
167
+ # .subs for polynomials is currently buggy
168
+ center_lst.append(self._center_func(i))
169
+ if radius_expr_check:
170
+ radius_lst.append(self._radius_func.subs({y: i}))
171
+ else:
172
+ radius_lst.append(self._radius_func(i))
173
+ self._center_lst = center_lst
174
+ self._radius_lst = radius_lst
175
+ self._radius = None
176
+ self._center = None
177
+ if not error_check:
178
+ return
179
+
180
+ if self._type == 4 and error_check:
181
+ if space_type == "projective":
182
+ for i in range(len(self._center_lst)):
183
+ center = self._center_lst[i]
184
+ radius = self._radius_lst[i]
185
+ # make sure the center is a point of projective space and not the point at infinity
186
+ if not isinstance(center, SchemeMorphism_point_projective_field):
187
+ try:
188
+ center = (self._base_space)(center)
189
+ except (TypeError, ValueError):
190
+ raise TypeError('could not convert %s to %s' % (center, self._base_space))
191
+ if self._base_type == 'padic field':
192
+ if not isinstance(center.scheme().base_ring(), sage.rings.abc.pAdicField):
193
+ if not isinstance(center.scheme().base_ring(), pAdicBaseGeneric):
194
+ try:
195
+ center = (self._base_space)(center)
196
+ except (TypeError, ValueError):
197
+ raise ValueError("could not convert %s to %s" % (center, self._base_space))
198
+ else:
199
+ # center is padic, not but an element of a scheme over a padic field.
200
+ # we convert to scheme over a padic field
201
+ center = ProjectiveSpace(center.scheme().base_ring().fraction_field(), 1)(center)
202
+ if center.scheme().base_ring().prime() != self._p:
203
+ raise ValueError("center must be an element of " +
204
+ "%s not %s" % self._base_space, center.scheme())
205
+ else:
206
+ if center not in self._base_space:
207
+ try:
208
+ center = (self._base_space)(center)
209
+ except (TypeError, ValueError):
210
+ raise ValueError('could not convert %s to %s' % (center, self._base_space))
211
+ if center.scheme().ambient_space() != center.scheme():
212
+ raise ValueError("the center of a point of Berkovich space over " +
213
+ "P^1(Cp(%s)) must be a point of Cp not %s" % (self._p, center.scheme()))
214
+ if center == (center.scheme())((1, 0)):
215
+ raise ValueError("the center of a disk approximating a type IV point of Berkovich " +
216
+ "space cannot be centered at %s" % ((center.scheme())((1, 0))))
217
+ # since we are over a field, we can normalize coordinates. all code assumes normalized coordinates
218
+ center.normalize_coordinates()
219
+ # make sure the radius coerces into the reals
220
+ if not isinstance(radius, RealNumber):
221
+ if isinstance(radius, Expression):
222
+ radius = RR(radius)
223
+ elif RR.has_coerce_map_from(radius.parent()):
224
+ radius = RR(radius)
225
+ else:
226
+ raise TypeError("the radius of a disk approximating a type IV point" +
227
+ "must coerce into the real numbers, %s does not coerce" % (radius))
228
+ if i != 0:
229
+ # check containment for the sequence of disks
230
+ previous_center = self._center_lst[i - 1]
231
+ previous_radius = self._radius_lst[i - 1]
232
+ dist = self._custom_abs(center[0] - previous_center[0])
233
+ if previous_radius < radius or dist > previous_radius:
234
+ raise ValueError("sequence of disks does not define a type IV point as " +
235
+ "containment is not proper")
236
+ self._center_lst[i] = center
237
+ self._radius_lst[i] = radius
238
+ return
239
+ elif space_type == "affine":
240
+ for i in range(len(self._center_lst)):
241
+ center = self._center_lst[i]
242
+ radius = self._radius_lst[i]
243
+ if self._base_type == 'padic field':
244
+ # make sure the center is in Cp
245
+ if not isinstance(center, pAdicGenericElement):
246
+ try:
247
+ center = (self._base_space)(center)
248
+ except (TypeError, ValueError):
249
+ raise TypeError("could not convert %s to %s" % (center, self._base_space))
250
+ elif not isinstance(center.parent(), sage.rings.abc.pAdicField):
251
+ # center is padic, not but an element of a padic field. we convert to padic field
252
+ center = (center.parent().fraction_field())(center)
253
+ if (center.parent()).prime() != self._p:
254
+ raise ValueError("center in %s, should be in %s") % (center.parent(), self._base_space)
255
+ else:
256
+ # make sure the center is in the appropriate number field
257
+ if center.parent() == self._base_space:
258
+ try:
259
+ center = (self._base_space)(center)
260
+ except (TypeError, ValueError):
261
+ raise ValueError('could not convert %s to %s' % (center, self._base_space))
262
+ # make sure the radius coerces into the reals
263
+ if not isinstance(radius, RealNumber):
264
+ if isinstance(radius, Expression):
265
+ radius = RR(radius)
266
+ elif RR.has_coerce_map_from(radius.parent()):
267
+ radius = RR(radius)
268
+ self._radius_lst[i] = radius
269
+ else:
270
+ raise ValueError("the radius of a disk approximating a type IV point must " +
271
+ "coerce into the real numbers, %s does not coerce" % (radius))
272
+ if i != 0:
273
+ # check containment for the sequence of disks
274
+ previous_center = self._center_lst[i - 1]
275
+ previous_radius = self._radius_lst[i - 1]
276
+ dist = self._custom_abs(center - previous_center)
277
+ if previous_radius < radius or dist > previous_radius:
278
+ raise ValueError("sequence of disks does not define a type IV point as " +
279
+ "containment is not proper")
280
+ self._center_lst[i] = center
281
+ self._radius_lst[i] = radius
282
+ return
283
+ else:
284
+ raise ValueError("bad value %s passed to space_type. Do not initialize " % (space_type) +
285
+ "Berkovich_Element_Cp directly")
286
+
287
+ # the point must now be type 1, 2, or 3, so we check that the center is of the appropriate type
288
+ if error_check:
289
+ if space_type == "projective":
290
+ if not isinstance(center, SchemeMorphism_point_projective_field):
291
+ try:
292
+ center = (self._base_space)(center)
293
+ except (ValueError, TypeError):
294
+ raise TypeError("could not convert %s to %s" % (center, self._base_space))
295
+ if self._base_type == 'padic field':
296
+ if not isinstance(center.scheme().base_ring(), sage.rings.abc.pAdicField):
297
+ if not isinstance(center.scheme().base_ring(), pAdicBaseGeneric):
298
+ try:
299
+ center = (self._base_space)(center)
300
+ except (TypeError, ValueError):
301
+ raise ValueError("could not convert %s to %s" % (center, self._base_space))
302
+ else:
303
+ # center is padic, not but an element of a scheme over a padic field.
304
+ # we convert to scheme over a padic field
305
+ field_scheme = ProjectiveSpace(center.scheme().base_ring().fraction_field(), 1)
306
+ try:
307
+ center = field_scheme(center)
308
+ except (TypeError, ValueError):
309
+ raise ValueError('could not convert %s to %s' % center, field_scheme)
310
+ if center.scheme().base_ring().prime() != self._p:
311
+ raise ValueError("center must be an element of " +
312
+ "%s not %s" % self._base_space, center.scheme())
313
+ else:
314
+ if center not in self._base_space:
315
+ try:
316
+ center = (self._base_space)(center)
317
+ except (TypeError, ValueError):
318
+ raise ValueError('could not convert %s to %s' % (center, self._base_space))
319
+ if center.scheme().ambient_space() is not center.scheme():
320
+ raise ValueError("the center of a point of projective Berkovich space cannot be " +
321
+ "a point of %s" % (center.scheme()))
322
+ # since we are over a field, we normalize coordinates
323
+ center.normalize_coordinates()
324
+ elif space_type == 'affine':
325
+ if self._base_type == 'padic field':
326
+ # make sure the center is in Cp
327
+ if not isinstance(center, pAdicGenericElement):
328
+ try:
329
+ center = (self._base_space)(center)
330
+ except (TypeError, ValueError):
331
+ raise TypeError("could not convert %s to %s" % (center, self._base_space))
332
+ elif not isinstance(center.parent(), sage.rings.abc.pAdicField):
333
+ # center is padic, not but an element of a padic field. we convert to padic field
334
+ center = (center.parent().fraction_field())(center)
335
+ if (center.parent()).prime() != self._p:
336
+ raise ValueError("center in %s, should be in %s") % (center.parent(), self._base_space)
337
+ else:
338
+ # make sure the center is in the appropriate number field
339
+ if not (center.parent() == self._base_space):
340
+ try:
341
+ center = (self._base_space)(center)
342
+ except (TypeError, ValueError):
343
+ raise ValueError('could not convert %s to %s' % (center, self._base_space))
344
+ else:
345
+ raise ValueError("bad value %s passed to space_type. Do not initialize " % (space_type) +
346
+ "Berkovich_Element_Cp directly")
347
+
348
+ self._center = center
349
+
350
+ # since this point is not type IV, these are None
351
+ self._center_func = None
352
+ self._center_lst = None
353
+ self._radius_lst = None
354
+ self._radius_func = None
355
+
356
+ if (radius is None and power is None) or radius == 0:
357
+ self._type = 1
358
+ self._radius = 0
359
+ self._power = None
360
+ return
361
+ # In order to simplify our representation, type II and III points cannot be centered at infinity
362
+ if space_type == "projective":
363
+ # TODO use involution map to allow for infinity to be passed in as center
364
+ if center[1] == 0:
365
+ raise ValueError('type II and III points can not be centered at infinity')
366
+ if power is not None:
367
+ if error_check:
368
+ try:
369
+ power = QQ(power)
370
+ except TypeError:
371
+ raise TypeError("power must convert to rationals")
372
+ if radius is not None:
373
+ if radius != RR(self._p**power):
374
+ raise ValueError("conflicting inputs for power and radius")
375
+ self._power = power
376
+ self._radius = RR(self._p**power)
377
+ self._type = 2
378
+ return
379
+ if radius is not None:
380
+ if isinstance(radius, Expression):
381
+ try:
382
+ power = QQ(radius.log(self._p).expand_log())
383
+ except TypeError:
384
+ pass
385
+ try:
386
+ radius = RR(radius)
387
+ self._radius = radius
388
+ except TypeError:
389
+ if len(radius.variables()) == 1:
390
+ raise ValueError('radius univariate function but center is constant. ' +
391
+ 'this does not define a type IV point')
392
+ raise TypeError("symbolic radius must be a real number")
393
+ if (not isinstance(radius, RealNumber)) and power is None:
394
+ if RR.has_coerce_map_from(radius.parent()):
395
+ self._radius = RR(radius)
396
+ else:
397
+ raise TypeError("radius must coerce into real numbers")
398
+ else:
399
+ self._radius = radius
400
+ if power is not None:
401
+ self._power = power
402
+ self._type = 2
403
+ return
404
+ power = RR(radius.log(self._p))
405
+ if power.is_integer():
406
+ self._power = QQ(power)
407
+ self._type = 2
408
+ else:
409
+ self._type = 3
410
+ self._power = power
411
+ return
412
+
413
+ raise ValueError('unknown error constructing point of Berkovich space over Cp')
414
+
415
+ def _custom_abs(self, x):
416
+ """
417
+ Return the absolute value of ``x`` with respect to the norm on ``Cp``.
418
+
419
+ Used to simplify code, as ``x`` may be a point of a number field
420
+ or a `p`-adic field.
421
+
422
+ EXAMPLES::
423
+
424
+ sage: B = Berkovich_Cp_Affine(QQ, 3)
425
+ sage: Q1 = B(9)
426
+ sage: Q1._custom_abs(Q1.center())
427
+ 1/9
428
+
429
+ ::
430
+
431
+ sage: B = Berkovich_Cp_Affine(Qp(3))
432
+ sage: Q1 = B(9)
433
+ sage: Q1._custom_abs(Q1.center())
434
+ 1/9
435
+ """
436
+ if self._base_type == 'padic field':
437
+ return x.abs()
438
+ if x.valuation(self._ideal) == Infinity:
439
+ return 0
440
+ if self._ideal in QQ:
441
+ return self.prime()**(-x.valuation(self._ideal))
442
+ return self.prime()**(-x.valuation(self._ideal) / self._ideal.absolute_ramification_index())
443
+
444
+ def center_function(self):
445
+ """
446
+ Return the function defining the centers of disks in the approximation.
447
+
448
+ Not defined unless this point is a type IV point created by using
449
+ a univariate function to compute centers.
450
+
451
+ OUTPUT: a univariate function
452
+
453
+ EXAMPLES::
454
+
455
+ sage: B = Berkovich_Cp_Projective(5)
456
+ sage: L.<t> = PolynomialRing(Qp(5))
457
+ sage: T = FractionField(L)
458
+ sage: f = T(1/t)
459
+ sage: R.<x> = RR[]
460
+ sage: Y = FractionField(R)
461
+ sage: g = (40*pi)/x # needs sage.symbolic
462
+ sage: Q1 = B(f, g) # needs sage.symbolic
463
+ sage: Q1.center_function() # needs sage.symbolic
464
+ (1 + O(5^20))/((1 + O(5^20))*t)
465
+ """
466
+ if self.type_of_point() != 4:
467
+ raise ValueError('center_function not defined for points which are not type IV')
468
+ if self._center_func is None:
469
+ raise ValueError('this type IV point does not have a center function')
470
+ return self._center_func
471
+
472
+ def radius_function(self):
473
+ """
474
+ Return the function defining the radii of disks in the approximation.
475
+
476
+ Not defined unless this point is a type IV point created by using
477
+ a univariate function to compute radii.
478
+
479
+ OUTPUT: a univariate function
480
+
481
+ EXAMPLES::
482
+
483
+ sage: B = Berkovich_Cp_Projective(5)
484
+ sage: L.<t> = PolynomialRing(Qp(5))
485
+ sage: T = FractionField(L)
486
+ sage: f = T(1/t)
487
+ sage: R.<x> = RR[]
488
+ sage: Y = FractionField(R)
489
+ sage: g = (40*pi)/x # needs sage.symbolic
490
+ sage: Q1 = B(f, g) # needs sage.symbolic
491
+ sage: Q1.radius_function() # needs sage.symbolic
492
+ 40.0000000000000*pi/x
493
+ """
494
+ if self.type_of_point() != 4:
495
+ raise ValueError('center_function not defined for points which are not type IV')
496
+ if self._radius_func is None:
497
+ raise ValueError('this type IV point does not have a radius function')
498
+ return self._radius_func
499
+
500
+ def precision(self):
501
+ """
502
+ Return the precision of a type IV point.
503
+
504
+ This integer is the number of disks used in the approximation of the type IV point.
505
+ Not defined for type I, II, or III points.
506
+
507
+ OUTPUT: integer
508
+
509
+ EXAMPLES::
510
+
511
+ sage: B = Berkovich_Cp_Affine(Qp(3))
512
+ sage: d = B([2, 2, 2], [1.761, 1.123, 1.112])
513
+ sage: d.precision()
514
+ 3
515
+
516
+ TESTS::
517
+
518
+ sage: d.precision == d.prec
519
+ True
520
+ """
521
+ if self._type in [1, 2, 3]:
522
+ raise AttributeError("type I, II, and III points do not have a precision")
523
+ return self._prec
524
+
525
+ prec = precision
526
+
527
+ def ideal(self):
528
+ r"""
529
+ The ideal which defines an embedding of the ``base_ring`` into `\CC_p`.
530
+
531
+ If this Berkovich space is backed by a `p`-adic field, then an embedding is
532
+ already specified, and this returns ``None``.
533
+
534
+ EXAMPLES::
535
+
536
+ sage: B = Berkovich_Cp_Projective(QQ, 3)
537
+ sage: B(0).ideal()
538
+ 3
539
+
540
+ ::
541
+
542
+ sage: B = Berkovich_Cp_Projective(3)
543
+ sage: B(0).ideal()
544
+ """
545
+ return self.parent().ideal()
546
+
547
+ def power(self):
548
+ r"""
549
+ The power of ``p`` such that `p^\text{power} = \text{radius}`.
550
+
551
+ For type II points, always in `\QQ`. For type III points,
552
+ a real number. Not defined for type I or IV points.
553
+
554
+ OUTPUT:
555
+
556
+ - A rational for type II points.
557
+ - A real number for type III points.
558
+
559
+ EXAMPLES::
560
+
561
+ sage: B = Berkovich_Cp_Affine(3)
562
+ sage: Q1 = B(1, 9)
563
+ sage: Q1.power()
564
+ 2
565
+
566
+ ::
567
+
568
+ sage: Q2 = B(1, 4)
569
+ sage: Q2.power()
570
+ 1.26185950714291
571
+ """
572
+ if self._type in [1, 4]:
573
+ raise AttributeError("type I and IV points do not have a power")
574
+ return self._power
575
+
576
+ def radius(self):
577
+ r"""
578
+ Radius of the corresponding disk (or sequence of disks) in `\CC_p`.
579
+
580
+ OUTPUT:
581
+
582
+ - A nonnegative real number for type I, II, or III points.
583
+ - A list of nonnegative real numbers for type IV points.
584
+
585
+ EXAMPLES::
586
+
587
+ sage: B = Berkovich_Cp_Affine(3)
588
+ sage: Q1 = B(1, 2/5)
589
+ sage: Q1.radius()
590
+ 0.400000000000000
591
+
592
+ ::
593
+
594
+ sage: d = B([2, 2, 2], [1.761, 1.123, 1.112])
595
+ sage: d.radius()
596
+ [1.76100000000000, 1.12300000000000, 1.11200000000000]
597
+ """
598
+ if self._type == 4:
599
+ return self._radius_lst
600
+ return self._radius
601
+
602
+ def diameter(self, basepoint=Infinity):
603
+ r"""
604
+ Generalized diameter function on Berkovich space.
605
+
606
+ If the basepoint is infinity, the diameter is equal to
607
+ the limit of the radii of the corresponding disks in `\CC_p`.
608
+
609
+ If the basepoint is not infinity, the diameter
610
+ is the Hsia kernel of this point with itself at
611
+ basepoint ``basepoint``.
612
+
613
+ INPUT:
614
+
615
+ - ``basepoint`` -- (default: ``Infinity``) a point of the
616
+ same Berkovich space as this point
617
+
618
+ OUTPUT: a real number
619
+
620
+ EXAMPLES::
621
+
622
+ sage: B = Berkovich_Cp_Affine(3)
623
+ sage: Q1 = B(3)
624
+ sage: Q1.diameter()
625
+ 0
626
+
627
+ ::
628
+
629
+ sage: Q2 = B(1/2, 9)
630
+ sage: Q2.diameter()
631
+ 9.00000000000000
632
+
633
+ The diameter of a type IV point is the limit of the radii::
634
+
635
+ sage: R.<x> = PolynomialRing(Qp(3))
636
+ sage: f = R(2)
637
+ sage: S.<y> = PolynomialRing(RR)
638
+ sage: S = FractionField(S)
639
+ sage: g = (y+1)/y
640
+ sage: B(f,g).diameter()
641
+ 1.0
642
+
643
+ ::
644
+
645
+ sage: B = Berkovich_Cp_Affine(3)
646
+ sage: Q1 = B(1/81, 1)
647
+ sage: Q2 = B(1/3)
648
+ sage: Q1.diameter(Q2)
649
+ 0.00137174211248285
650
+
651
+ ::
652
+
653
+ sage: Q2.diameter(Q2)
654
+ +infinity
655
+ """
656
+ if basepoint == Infinity:
657
+ if self._type == 4:
658
+ if self._radius_func is None:
659
+ return self._radius_lst[-1]
660
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
661
+ R = PolynomialRing(QQ, names='x')
662
+ x = R.gens()[0]
663
+ if isinstance(self._radius_func, Expression):
664
+ radius_func_variable = self._radius_func.variables()[0]
665
+ radius_expr = self._radius_func.subs({radius_func_variable: x})
666
+ else:
667
+ radius_expr = self._radius_func(x)
668
+ from sage.symbolic.ring import SymbolicRing as SR
669
+ radius_expr = SR(RR)(radius_expr)
670
+ return radius_expr.limit(x='oo')
671
+ return self._radius
672
+ if not isinstance(basepoint, Berkovich_Element_Cp):
673
+ raise TypeError('basepoint must be a point of Berkovich space, not %s' % basepoint)
674
+ if basepoint.parent() != self.parent():
675
+ raise ValueError('basepoint must be a point of the same Berkovich space')
676
+ return self.Hsia_kernel(self, basepoint)
677
+
678
+ def path_distance_metric(self, other):
679
+ r"""
680
+ Return the path distance metric distance between this point and ``other``.
681
+
682
+ Also referred to as the hyperbolic metric, or the big metric.
683
+
684
+ On the set of type II, III and IV points, the path distance metric
685
+ is a metric. Following Baker and Rumely, we extend
686
+ the path distance metric to type I points `x`, `y` by `\rho(x,x) = 0` and `\rho(x,y) =
687
+ \infty`. See [BR2010]_.
688
+
689
+ INPUT:
690
+
691
+ - ``other`` -- a point of the same Berkovich space as this point
692
+
693
+ OUTPUT: a finite or infinite real number
694
+
695
+ EXAMPLES::
696
+
697
+ sage: B = Berkovich_Cp_Affine(3)
698
+ sage: Q1 = B(1/4, 4)
699
+ sage: Q2 = B(1/4, 6)
700
+ sage: Q1.path_distance_metric(Q2)
701
+ 0.369070246428542
702
+
703
+ ::
704
+
705
+ sage: Q3 = B(1)
706
+ sage: Q3.path_distance_metric(Q1)
707
+ +infinity
708
+
709
+ ::
710
+
711
+ sage: Q3.path_distance_metric(Q3)
712
+ 0
713
+ """
714
+ if not isinstance(other, type(self)):
715
+ raise TypeError('other must be a point of Berkovich space. other was %s' % other)
716
+ if self.parent() != other.parent():
717
+ raise ValueError("other must be a point of the same Berkovich space")
718
+ if self.type_of_point() == 1 or other.type_of_point() == 1:
719
+ if self == other:
720
+ return 0
721
+ else:
722
+ return RR(Infinity)
723
+ return 2 * self.join(other).diameter().log(self.prime()) \
724
+ - self.diameter().log(self.prime()) \
725
+ - other.diameter().log(other.prime())
726
+
727
+ big_metric = path_distance_metric
728
+
729
+ hyperbolic_metric = path_distance_metric
730
+
731
+ def Hsia_kernel(self, other, basepoint):
732
+ """
733
+ The Hsia kernel of this point and ``other``,
734
+ with basepoint ``basepoint``.
735
+
736
+ The Hsia kernel with arbitrary basepoint
737
+ is a generalization of the Hsia kernel at infinity.
738
+
739
+ INPUT:
740
+
741
+ - ``other`` -- a point of the same Berkovich space as this point
742
+ - ``basepoint`` -- a point of the same Berkovich space as this point
743
+
744
+ OUTPUT: a finite or infinite real number
745
+
746
+ EXAMPLES::
747
+
748
+ sage: B = Berkovich_Cp_Projective(3)
749
+ sage: Q1 = B(2, 9)
750
+ sage: Q2 = B(1/27, 1/27)
751
+ sage: Q3 = B(1, 1/3)
752
+ sage: Q1.Hsia_kernel(Q2, Q3)
753
+ 0.111111111111111
754
+
755
+ ::
756
+
757
+ sage: B = Berkovich_Cp_Projective(3)
758
+ sage: Q1 = B(2, 9)
759
+ sage: Q2 = B(1/2)
760
+ sage: Q3 = B(1/2)
761
+ sage: Q1.Hsia_kernel(Q2, Q3)
762
+ +infinity
763
+ """
764
+ if not isinstance(other, type(self)):
765
+ raise TypeError('other must be a point of Berkovich space. other was %s' % other)
766
+ if self.parent() != other.parent():
767
+ raise ValueError("other must be a point of the same Berkovich space")
768
+ if not isinstance(basepoint, type(self)):
769
+ raise TypeError('basepoint must be a point of Berkovich space. basepoint was %s' % basepoint)
770
+ if basepoint.parent() != self.parent():
771
+ raise ValueError("basepoint must be a point of the same Berkovich space")
772
+ if basepoint.type_of_point() == 1:
773
+ if self == basepoint or other == basepoint:
774
+ return RR(Infinity)
775
+ return self.spherical_kernel(other) / \
776
+ (self.spherical_kernel(basepoint) * other.spherical_kernel(basepoint))
777
+
778
+ def small_metric(self, other):
779
+ r"""
780
+ Return the small metric distance between this point and ``other``.
781
+
782
+ The small metric is an extension of twice
783
+ the spherical distance on `P^1(\CC_p)`.
784
+
785
+ INPUT:
786
+
787
+ - ``other`` -- a point of the same Berkovich space as this point
788
+
789
+ OUTPUT: a real number
790
+
791
+ EXAMPLES::
792
+
793
+ sage: B = Berkovich_Cp_Affine(3)
794
+ sage: Q1 = B(1/4, 4)
795
+ sage: Q2 = B(1/4, 6)
796
+ sage: Q1.small_metric(Q2)
797
+ 0.0833333333333333
798
+
799
+ ::
800
+
801
+ sage: B = Berkovich_Cp_Projective(QQ, 5)
802
+ sage: Q1 = B(0, 1)
803
+ sage: Q2 = B(99)
804
+ sage: Q1.small_metric(Q2)
805
+ 1.00000000000000
806
+
807
+ ::
808
+
809
+ sage: Q3 = B(1/4, 4)
810
+ sage: Q3.small_metric(Q2)
811
+ 1.75000000000000
812
+
813
+ ::
814
+
815
+ sage: Q2.small_metric(Q3)
816
+ 1.75000000000000
817
+ """
818
+ if not isinstance(other, Berkovich_Element_Cp):
819
+ raise TypeError('other must be a point of affine Berkovich space. other was %s' % other)
820
+ if self.parent() != other.parent():
821
+ raise ValueError('other must be a point of the same Berkovich space')
822
+ gauss = self.parent()(RR(0), RR(1))
823
+ g_greater_than_s = gauss.gt(self)
824
+ g_greater_than_o = gauss.gt(other)
825
+ if g_greater_than_s and g_greater_than_o:
826
+ return 2 * self.join(other, gauss).diameter() - self.diameter() - other.diameter()
827
+ if not g_greater_than_s:
828
+ new_self = self.involution_map()
829
+ else:
830
+ new_self = self
831
+ if not g_greater_than_o:
832
+ new_other = other.involution_map()
833
+ else:
834
+ new_other = other
835
+ return 2 * new_self.join(new_other, gauss).diameter() \
836
+ - new_self.diameter() - new_other.diameter()
837
+
838
+ def potential_kernel(self, other, basepoint):
839
+ """
840
+ The potential kernel of this point with ``other``,
841
+ with basepoint ``basepoint``.
842
+
843
+ The potential kernel is the hyperbolic distance
844
+ between ``basepoint`` and the join of this point
845
+ with ``other`` relative to ``basepoint``.
846
+
847
+ INPUT:
848
+
849
+ - ``other`` -- a point of the same Berkovich space as this point
850
+ - ``basepoint`` -- a point of the same Berkovich space as this point
851
+
852
+ OUTPUT: a finite or infinite real number
853
+
854
+ EXAMPLES::
855
+
856
+ sage: B = Berkovich_Cp_Projective(3)
857
+ sage: Q1 = B(27, 1)
858
+ sage: Q2 = B(1/3, 2)
859
+ sage: Q3 = B(1/9, 1/2)
860
+ sage: Q3.potential_kernel(Q1, Q2)
861
+ 0.369070246428543
862
+
863
+ ::
864
+
865
+ sage: B = Berkovich_Cp_Affine(3)
866
+ sage: Q1 = B(27, 1)
867
+ sage: Q2 = B(1/3, 2)
868
+ sage: Q3 = B(1/9, 1/2)
869
+ sage: Q3.potential_kernel(Q1, Q2)
870
+ 0.369070246428543
871
+ """
872
+ if not isinstance(other, type(self)):
873
+ raise TypeError('other must be a point of a Berkovich space, not %s' % other)
874
+ if other.parent() != self.parent():
875
+ raise ValueError('other must be a point of the same Berkovich space')
876
+ if not isinstance(basepoint, type(self)):
877
+ raise TypeError('basepoint must be a point of Berkovich line, not %s' % basepoint)
878
+ if basepoint.parent() != self.parent():
879
+ raise ValueError('basepoint must be a point of the same Berkovich space')
880
+ return basepoint.path_distance_metric(self.join(other, basepoint))
881
+
882
+ def spherical_kernel(self, other):
883
+ r"""
884
+ The spherical kernel of this point with ``other``.
885
+
886
+ The spherical kernel is one possible extension of the spherical
887
+ distance on `P^1(\CC_p)` to the projective Berkovich line.
888
+ See [BR2010]_ for details.
889
+
890
+ INPUT:
891
+
892
+ - ``other`` -- a point of the same Berkovich space as this point
893
+
894
+ OUTPUT: a real number
895
+
896
+ EXAMPLES::
897
+
898
+ sage: B = Berkovich_Cp_Projective(3)
899
+ sage: Q1 = B(2, 2)
900
+ sage: Q2 = B(1/9, 1)
901
+ sage: Q1.spherical_kernel(Q2)
902
+ 0.500000000000000
903
+
904
+ ::
905
+
906
+ sage: Q3 = B(2)
907
+ sage: Q3.spherical_kernel(Q3)
908
+ 0
909
+ """
910
+ if not isinstance(other, type(self)):
911
+ raise TypeError('other must be a point of Berkovich space, not %s' % other)
912
+ if other.parent() != self.parent():
913
+ raise ValueError('other must be a point of the same Berkovich space')
914
+ gauss_point = self.parent()(ZZ(0), ZZ(1))
915
+ w = self.join(other, gauss_point)
916
+ dist = gauss_point.path_distance_metric(w)
917
+ if dist == Infinity:
918
+ return 0
919
+ return self.prime()**(-dist)
920
+
921
+ def Hsia_kernel_infinity(self, other):
922
+ r"""
923
+ Return the Hsia kernel at infinity of this point with ``other``.
924
+
925
+ The Hsia kernel at infinity is the natural extension of the
926
+ absolute value on `\CC_p` to Berkovich space.
927
+
928
+ INPUT:
929
+
930
+ - ``other`` -- a point of the same Berkovich space as this point
931
+
932
+ OUTPUT: a real number
933
+
934
+ EXAMPLES::
935
+
936
+ sage: B = Berkovich_Cp_Affine(Qp(3))
937
+ sage: Q1 = B(1/4, 4)
938
+ sage: Q2 = B(1/4, 6)
939
+ sage: Q1.Hsia_kernel_infinity(Q2)
940
+ 6.00000000000000
941
+
942
+ ::
943
+
944
+ sage: # needs sage.rings.number_field
945
+ sage: R.<x> = QQ[]
946
+ sage: A.<a> = NumberField(x^3 + 20)
947
+ sage: ideal = A.ideal(-1/2*a^2 + a - 3)
948
+ sage: B = Berkovich_Cp_Projective(A, ideal)
949
+ sage: Q1 = B(4)
950
+ sage: Q2 = B(0, 1.5)
951
+ sage: Q1.Hsia_kernel_infinity(Q2)
952
+ 1.50000000000000
953
+ """
954
+ return self.join(other).diameter()
955
+
956
+ def center(self):
957
+ r"""
958
+ Return the center of the corresponding disk (or sequence of disks)
959
+ in `\CC_p`.
960
+
961
+ OUTPUT: an element of the ``base`` of the parent Berkovich space
962
+
963
+ EXAMPLES::
964
+
965
+ sage: B = Berkovich_Cp_Affine(3)
966
+ sage: B(3, 1).center()
967
+ 3 + O(3^21)
968
+
969
+ ::
970
+
971
+ sage: C = Berkovich_Cp_Projective(3)
972
+ sage: C(3, 1).center()
973
+ (3 + O(3^21) : 1 + O(3^20))
974
+
975
+ ::
976
+
977
+ sage: # needs sage.rings.number_field
978
+ sage: R.<x> = QQ[]
979
+ sage: A.<a> = NumberField(x^3 + 20)
980
+ sage: ideal = A.ideal(-1/2*a^2 + a - 3)
981
+ sage: B = Berkovich_Cp_Projective(A, ideal)
982
+ sage: B(a^2 + 4).center()
983
+ (a^2 + 4 : 1)
984
+ """
985
+ if self._type == 4:
986
+ return self._center_lst
987
+ return self._center
988
+
989
+ def type_of_point(self):
990
+ r"""
991
+ Return the type of this point of Berkovich space over `\CC_p`.
992
+
993
+ OUTPUT: integer between 1 and 4 inclusive
994
+
995
+ EXAMPLES::
996
+
997
+ sage: B = Berkovich_Cp_Affine(3)
998
+ sage: B(1).type_of_point()
999
+ 1
1000
+
1001
+ ::
1002
+
1003
+ sage: B(0, 1).type_of_point()
1004
+ 2
1005
+ """
1006
+ return ZZ(self._type)
1007
+
1008
+ def prime(self):
1009
+ """
1010
+ The residue characteristic of the parent.
1011
+
1012
+ OUTPUT: a prime integer
1013
+
1014
+ EXAMPLES::
1015
+
1016
+ sage: B = Berkovich_Cp_Affine(3)
1017
+ sage: B(1).prime()
1018
+ 3
1019
+ """
1020
+ return ZZ(self._p)
1021
+
1022
+ def __ne__(self, other):
1023
+ """
1024
+ Non-equality operator.
1025
+
1026
+ EXAMPLES::
1027
+
1028
+ sage: # needs sage.symbolic
1029
+ sage: B = Berkovich_Cp_Affine(3)
1030
+ sage: Q1 = B(3, 3**(1/2))
1031
+ sage: Q2 = B(3, RR(3**(1/2)))
1032
+ sage: Q1 != Q2
1033
+ False
1034
+ """
1035
+ return not (self == other)
1036
+
1037
+ def _repr_(self):
1038
+ """
1039
+ String representation of this point.
1040
+
1041
+ EXAMPLES::
1042
+
1043
+ sage: B = Berkovich_Cp_Projective(3)
1044
+ sage: B(2, 1)
1045
+ Type II point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 3^0
1046
+ """
1047
+ if self._type == 1:
1048
+ return "Type I point centered at " + format(self._center)
1049
+ elif self._type == 2:
1050
+ return "Type II point centered at " \
1051
+ + format(self._center) \
1052
+ + " of radius %s^%s" % (self._p, self._power)
1053
+ elif self._type == 3:
1054
+ return "Type III point centered at " \
1055
+ + format(self._center) + " of radius " \
1056
+ + format(self._radius)
1057
+ else:
1058
+ if self._center_func is not None and self._radius_func is not None:
1059
+ return "Type IV point of precision %s " % self._prec + \
1060
+ "with centers given by %s and radii given by %s"\
1061
+ % (self._center_func, self._radius_func)
1062
+ else:
1063
+ return "Type IV point of precision %s, approximated " % self._prec + \
1064
+ "by disks centered at %s ... with radii %s ..." \
1065
+ % (self._center_lst[:min(self._prec, 2)], self._radius_lst[:min(self._prec, 2)])
1066
+
1067
+ def _latex_(self):
1068
+ r"""
1069
+ LaTeX representation of this point.
1070
+
1071
+ EXAMPLES::
1072
+
1073
+ sage: B = Berkovich_Cp_Projective(3)
1074
+ sage: latex(B(2, 1))
1075
+ \text{type 2 Point of } \text{Projective Berkovich line over }
1076
+ \Bold{C}_{3} \text{equivalent to the disk centered at
1077
+ (2 + O(3^20) : 1 + O(3^20)) of radius 1.00000000000000 in } \Bold{C}_3
1078
+ """
1079
+ from sage.misc.latex import latex
1080
+ if self._type == 1:
1081
+ text = r"the point %s of } \Bold{C}_%s" % (self._center, self._p)
1082
+ elif self._type in [2, 3]:
1083
+ text = r"the disk centered at %s of radius %s in } \Bold{C}_%s" \
1084
+ % (self._center, self._radius, self._p)
1085
+ else:
1086
+ text = "the sequence of disks with centers %s } " % self._center_lst[:2] + \
1087
+ r"\ldots \text{ and radii %s } \ldots" % self._radius_lst[:2]
1088
+ return r"\text{type %s Point of }" % (self._type) \
1089
+ + latex(self.parent()) + r"\text{equivalent to " + text
1090
+
1091
+
1092
+ class Berkovich_Element_Cp_Affine(Berkovich_Element_Cp):
1093
+ r"""
1094
+ Element class of the Berkovich affine line over `\CC_p`.
1095
+
1096
+ Elements are categorized into four types, represented by specific data:
1097
+
1098
+ - Type I points are represented by a center in the ``base`` of the parent Berkovich space,
1099
+ which is `\QQ_p`, a finite extension of `\QQ_p`, or a number field.
1100
+
1101
+ - Type II points are represented by a center in the ``base`` of the parent Berkovich space,
1102
+ and a rational power of `p`.
1103
+
1104
+ - Type III points are represented by a center in the ``base`` of the parent Berkovich space,
1105
+ and a radius, a real number in `[0,\infty)`.
1106
+
1107
+ - Type IV points are represented by a finite list of centers in the ``base`` of the parent
1108
+ Berkovich space and a finite list of radii in `[0,\infty)`. Type IV points can be created
1109
+ from univariate functions, allowing for arbitrary precision.
1110
+
1111
+ INPUT:
1112
+
1113
+ - ``center`` -- for type I, II, and III points, the center of the
1114
+ corresponding disk in `\CC_p`. If the parent Berkovich space was created using a number field
1115
+ `K`, then ``center`` must be an element of `K`. Otherwise, ``center`` must be an element of a
1116
+ `p`-adic field. For type IV points, can be a list of centers used to approximate the point or a
1117
+ univariate function that computes the centers (computation starts at 1).
1118
+
1119
+ - ``radius`` -- (optional) For type I, II, and III points, the radius of the
1120
+ corresponding disk in ``Cp``. Must coerce into the real numbers. For type IV points,
1121
+ can be a list of radii used to approximate the point or a univariate function that
1122
+ computes the radii (computation starts at 1).
1123
+
1124
+ - ``power`` -- (optional) Rational number. Used for constructing type II points; specifies
1125
+ the power of ``p`` such that `p^\text{power}` = radius
1126
+
1127
+ - ``prec`` -- (default: 20) the number of disks to be used to approximate a type IV point
1128
+
1129
+ - ``error_check`` -- boolean (default: ``True``); if error checking should be run on input. If
1130
+ input is correctly formatted, can be set to ``False`` for better performance.
1131
+ WARNING: with error check set to ``False``, any error in the input will lead to
1132
+ incorrect results.
1133
+
1134
+ EXAMPLES:
1135
+
1136
+ Type I points can be created by specifying the corresponding point of ``Cp``::
1137
+
1138
+ sage: B = Berkovich_Cp_Affine(Qp(3))
1139
+ sage: B(4)
1140
+ Type I point centered at 1 + 3 + O(3^20)
1141
+
1142
+ The center of a point can be an element of a finite extension of ``Qp``::
1143
+
1144
+ sage: A.<t> = Qq(27)
1145
+ sage: B(1 + t)
1146
+ Type I point centered at (t + 1) + O(3^20)
1147
+
1148
+ Type II and III points can be created by specifying a center and a radius::
1149
+
1150
+ sage: B(2, 3**(1/2)) # needs sage.symbolic
1151
+ Type II point centered at 2 + O(3^20) of radius 3^1/2
1152
+
1153
+ ::
1154
+
1155
+ sage: B(2, 1.6)
1156
+ Type III point centered at 2 + O(3^20) of radius 1.60000000000000
1157
+
1158
+ Some type II points may be mistaken for type III points::
1159
+
1160
+ sage: B(3, 3**0.5) # not tested
1161
+ Type III point centered at 3 + O(3^21) of radius 1.73205080756888
1162
+
1163
+ To avoid these errors, specify the power instead of the radius::
1164
+
1165
+ sage: B(3, power=RR(1/100000))
1166
+ Type II point centered at 3 + O(3^21) of radius 3^1/100000
1167
+
1168
+ Type IV points can be constructed in a number of ways, the first being
1169
+ from a list of centers and radii used to approximate the point::
1170
+
1171
+ sage: B([Qp(3)(2), Qp(3)(2), Qp(3)(2)], [1.761, 1.123, 1.112])
1172
+ Type IV point of precision 3, approximated by disks centered at
1173
+ [2 + O(3^20), 2 + O(3^20)] ... with radii [1.76100000000000, 1.12300000000000] ...
1174
+
1175
+ Type IV points can be constructed from univariate functions, with arbitrary precision::
1176
+
1177
+ sage: A.<t> = Qq(27)
1178
+ sage: R.<x> = PolynomialRing(A)
1179
+ sage: f = (1 + t)^2*x
1180
+ sage: S.<y> = PolynomialRing(RR)
1181
+ sage: S = FractionField(S)
1182
+ sage: g = (y + 1)/y
1183
+ sage: d = B(f, g, prec=100); d
1184
+ Type IV point of precision 100 with centers given by
1185
+ ((t^2 + 2*t + 1) + O(3^20))*x and radii given by (y + 1.00000000000000)/y
1186
+
1187
+ For increased performance, ``error_check`` can be set to ``False``. WARNING: with error check set
1188
+ to ``False``, any error in the input will lead to incorrect results::
1189
+
1190
+ sage: B(f, g, prec=100, error_check=False)
1191
+ Type IV point of precision 100 with centers given by
1192
+ ((t^2 + 2*t + 1) + O(3^20))*x and radii given by (y + 1.00000000000000)/y
1193
+
1194
+ When creating a Berkovich space backed by a number field, points can be created similarly::
1195
+
1196
+ sage: # needs sage.rings.number_field
1197
+ sage: R.<x> = QQ[]
1198
+ sage: A.<a> = NumberField(x^3 + 20)
1199
+ sage: ideal = A.prime_above(3)
1200
+ sage: B = Berkovich_Cp_Projective(A, ideal)
1201
+ sage: Q1 = B(a); Q1
1202
+ Type I point centered at (a : 1)
1203
+
1204
+ ::
1205
+
1206
+ sage: B(a + 1, 3) # needs sage.rings.number_field
1207
+ Type II point centered at (a + 1 : 1) of radius 3^1
1208
+
1209
+ TESTS::
1210
+
1211
+ sage: A = Berkovich_Cp_Affine(3)
1212
+ sage: Q1 = A(3, 1); Q1
1213
+ Type II point centered at 3 + O(3^21) of radius 3^0
1214
+ sage: Q2 = A(2.5, 1); Q2
1215
+ Type II point centered at 1 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + 3^7 +
1216
+ 3^8 + 3^9 + 3^10 + 3^11 + 3^12 + 3^13 + 3^14 + 3^15 + 3^16 + 3^17 +
1217
+ 3^18 + 3^19 + O(3^20) of radius 3^0
1218
+ sage: Q5 = A(3, 0); Q5
1219
+ Type I point centered at 3 + O(3^21)
1220
+ sage: A(Zp(3)(2), 2).center().parent() == A(Qp(3)(2), 2).center().parent()
1221
+ True
1222
+ sage: Q1 == Q2
1223
+ True
1224
+ sage: Q1 == Q5
1225
+ False
1226
+ sage: Q3 = A(Qp(3)(3), power=0, error_check=False); Q3
1227
+ Type II point centered at 3 + O(3^21) of radius 3^0
1228
+ sage: Q4 = A(3, 3**0); Q4
1229
+ Type II point centered at 3 + O(3^21) of radius 3^0
1230
+ sage: Q5 = A(3, power=1/2); Q5
1231
+ Type II point centered at 3 + O(3^21) of radius 3^1/2
1232
+ sage: Q6 = A(3, RR(3**(1/2))); Q6 # needs sage.symbolic
1233
+ Type III point centered at 3 + O(3^21) of radius 1.73205080756888
1234
+ sage: Q5 == Q6 # needs sage.symbolic
1235
+ True
1236
+
1237
+ sage: k = Qp(5)
1238
+ sage: R.<x> = k[]
1239
+ sage: l.<w> = k.extension(x^2 - 5)
1240
+ sage: B = Berkovich_Cp_Affine(5)
1241
+ sage: B(w, power=1)
1242
+ Type II point centered at w + O(w^41) of radius 5^1
1243
+
1244
+ sage: TestSuite(Q5).run()
1245
+ """
1246
+
1247
+ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check=True):
1248
+ """
1249
+ Initialization function.
1250
+
1251
+ EXAMPLES::
1252
+
1253
+ sage: A = Berkovich_Cp_Affine(17)
1254
+ sage: A(5, 1)
1255
+ Type II point centered at 5 + O(17^20) of radius 17^0
1256
+ """
1257
+ # we call Berkovich_Element_Cp constructor which is shared with projective Berkovich space
1258
+ # unless we are passed a point of projective Berkovich space
1259
+ Element.__init__(self, parent)
1260
+ self._p = parent.prime()
1261
+ self._base_space = parent.base()
1262
+ self._base_type = parent._base_type
1263
+ self._ideal = parent._ideal
1264
+
1265
+ # if this is a point of projective Berkovich space, we raise an error
1266
+ if isinstance(center, Berkovich_Element_Cp_Projective):
1267
+ raise TypeError('use as_affine_point to convert to affine Berkovich space')
1268
+
1269
+ Berkovich_Element_Cp.__init__(self, parent=parent, center=center, radius=radius, power=power,
1270
+ prec=prec, space_type='affine', error_check=error_check)
1271
+
1272
+ def as_projective_point(self):
1273
+ r"""
1274
+ Return the corresponding point of projective Berkovich space.
1275
+
1276
+ We identify affine Berkovich space with the subset `P^1_{\text{Berk}}(C_p) - \{(1 : 0)\}`.
1277
+
1278
+ EXAMPLES::
1279
+
1280
+ sage: B = Berkovich_Cp_Affine(5)
1281
+ sage: B(5).as_projective_point()
1282
+ Type I point centered at (5 + O(5^21) : 1 + O(5^20))
1283
+
1284
+ ::
1285
+
1286
+ sage: B(0, 1).as_projective_point()
1287
+ Type II point centered at (0 : 1 + O(5^20)) of radius 5^0
1288
+
1289
+ ::
1290
+
1291
+ sage: L.<t> = PolynomialRing(Qp(5))
1292
+ sage: T = FractionField(L)
1293
+ sage: f = T(1/t)
1294
+ sage: R.<x> = RR[]
1295
+ sage: Y = FractionField(R)
1296
+ sage: g = (40*pi)/x # needs sage.symbolic
1297
+ sage: Q2 = B(f, g) # needs sage.symbolic
1298
+ sage: Q2.as_projective_point() # needs sage.symbolic
1299
+ Type IV point of precision 20 with centers given by (1 + O(5^20))/((1 + O(5^20))*t)
1300
+ and radii given by 40.0000000000000*pi/x
1301
+ """
1302
+ from sage.schemes.berkovich.berkovich_space import Berkovich_Cp_Projective
1303
+ new_space = Berkovich_Cp_Projective(self.parent().base_ring(), self.parent().ideal())
1304
+ if self.type_of_point() == 1:
1305
+ return new_space(self.center())
1306
+ elif self.type_of_point() == 2:
1307
+ return new_space(self.center(), power=self.power())
1308
+ elif self.type_of_point() == 3:
1309
+ return new_space(self.center(), self.radius())
1310
+ if self._center_func is None:
1311
+ center = self.center()
1312
+ else:
1313
+ center = self.center_function()
1314
+ if self._radius_func is None:
1315
+ radius = self.radius()
1316
+ else:
1317
+ radius = self.radius_function()
1318
+ return new_space(center, radius, prec=self.prec())
1319
+
1320
+ def __eq__(self, other):
1321
+ """
1322
+ Equality operator.
1323
+
1324
+ EXAMPLES::
1325
+
1326
+ sage: B = Berkovich_Cp_Projective(3)
1327
+ sage: Q1 = B(1, RR(3**(1/2))) # needs sage.symbolic
1328
+ sage: Q2 = B(1, 3**(1/2)) # needs sage.symbolic
1329
+ sage: Q1 == Q2 # needs sage.symbolic
1330
+ True
1331
+
1332
+ ::
1333
+
1334
+ sage: Q3 = B(1)
1335
+ sage: Q4 = B(4)
1336
+ sage: Q3 == Q4
1337
+ False
1338
+
1339
+ ::
1340
+
1341
+ sage: Q5 = B(1, 4)
1342
+ sage: Q1 == Q5 # needs sage.symbolic
1343
+ False
1344
+
1345
+ ::
1346
+
1347
+ sage: Q1 == Q3 # needs sage.symbolic
1348
+ False
1349
+ """
1350
+ if other is self:
1351
+ return True
1352
+ if not isinstance(other, Berkovich_Element_Cp_Affine):
1353
+ return False
1354
+ if other.parent() != self.parent():
1355
+ return False
1356
+ stype = self.type_of_point()
1357
+ otype = other.type_of_point()
1358
+ if stype == otype and stype == 1:
1359
+ return self.center() == other.center()
1360
+ elif stype == otype and stype == 4:
1361
+ raise NotImplementedError("Equality for type IV points not yet implemented")
1362
+ elif stype in [2, 3] and otype in [2, 3]:
1363
+ if self.radius() != other.radius():
1364
+ return False
1365
+ center_dist = self._custom_abs(self.center() - other.center())
1366
+ return center_dist <= self.radius()
1367
+ else:
1368
+ return False
1369
+
1370
+ def __hash__(self):
1371
+ """
1372
+ Return the hash of this point.
1373
+
1374
+ EXAMPLES::
1375
+
1376
+ sage: B = Berkovich_Cp_Affine(3)
1377
+ sage: Q1 = B(1, RR(3**(1/2))) # needs sage.symbolic
1378
+ sage: Q2 = B(1, 3**(1/2)) # needs sage.symbolic
1379
+ sage: hash(Q1) == hash(Q2) # needs sage.symbolic
1380
+ True
1381
+
1382
+ ::
1383
+
1384
+ sage: # needs sage.rings.number_field
1385
+ sage: R.<x> = QQ[]
1386
+ sage: A.<a> = NumberField(x^3 + 20)
1387
+ sage: ideal = A.ideal(-1/2*a^2 + a - 3)
1388
+ sage: B = Berkovich_Cp_Projective(A, ideal)
1389
+ sage: Q1 = B(a^2 + 1, 2)
1390
+ sage: Q2 = B(0, 2)
1391
+ sage: hash(Q1) == hash(Q2)
1392
+ True
1393
+ """
1394
+ if self.type_of_point() == 1:
1395
+ return hash(self.center())
1396
+ elif self.type_of_point() == 4:
1397
+ raise NotImplementedError('hash not defined for type IV points')
1398
+ return hash(self.radius())
1399
+
1400
+ def lt(self, other):
1401
+ r"""
1402
+ Return ``True`` if this point is strictly less than ``other`` in the standard partial order.
1403
+
1404
+ Roughly, the partial order corresponds to containment of
1405
+ the corresponding disks in ``Cp``.
1406
+
1407
+ For example, let x and y be points of type II or III.
1408
+ If x has center `c_1` and radius `r_1` and y has center
1409
+ `c_2` and radius `r_2`, `x < y` if and only if `D(c_1,r_1)`
1410
+ is a subset of `D(c_2,r_2)` in `\CC_p`.
1411
+
1412
+ INPUT:
1413
+
1414
+ - ``other`` -- a point of the same Berkovich space as this point
1415
+
1416
+ OUTPUT:
1417
+
1418
+ - ``True`` -- if this point is less than ``other`` in the standard partial order
1419
+ - ``False`` -- otherwise
1420
+
1421
+ EXAMPLES::
1422
+
1423
+ sage: B = Berkovich_Cp_Projective(3)
1424
+ sage: Q1 = B(5, 0.5)
1425
+ sage: Q2 = B(5, 1)
1426
+ sage: Q1.lt(Q2)
1427
+ True
1428
+
1429
+ ::
1430
+
1431
+ sage: Q3 = B(1)
1432
+ sage: Q1.lt(Q3)
1433
+ False
1434
+
1435
+ TESTS::
1436
+
1437
+ sage: B = Berkovich_Cp_Projective(3)
1438
+ sage: Q1 = B(5)
1439
+ sage: Q1.lt(Q1)
1440
+ False
1441
+
1442
+ ::
1443
+
1444
+ sage: Q2 = B([4, 1/3], [5, 1])
1445
+ sage: Q1.lt(Q2)
1446
+ False
1447
+
1448
+ ::
1449
+
1450
+ sage: Q4 = B(0, 1)
1451
+ sage: Q1.lt(Q4)
1452
+ True
1453
+
1454
+ ::
1455
+
1456
+ sage: Q2.lt(Q4)
1457
+ False
1458
+ """
1459
+ if not isinstance(other, Berkovich_Element_Cp_Affine):
1460
+ raise TypeError('other must be a point of a projective Berkovich space, but was %s' % other)
1461
+ if self.parent() != other.parent():
1462
+ raise ValueError('other must be a point of the same projective Berkovich space')
1463
+
1464
+ if self == other:
1465
+ return False
1466
+ if other.type_of_point() in [1, 4]:
1467
+ return False
1468
+
1469
+ if self.type_of_point() == 4:
1470
+ center = self.center()[-1]
1471
+ dist = self._custom_abs(other.center() - center)
1472
+ return dist <= other.radius() and self.radius()[-1] <= other.radius()
1473
+ else:
1474
+ dist = self._custom_abs(self.center() - other.center())
1475
+ return dist <= other.radius() and self.radius() <= other.radius()
1476
+
1477
+ def gt(self, other):
1478
+ r"""
1479
+ Return ``True`` if this point is strictly greater than ``other`` in the standard partial order.
1480
+
1481
+ Roughly, the partial order corresponds to containment of
1482
+ the corresponding disks in `\CC_p`.
1483
+
1484
+ For example, let x and y be points of type II or III.
1485
+ If x has center `c_1` and radius `r_1` and y has center
1486
+ `c_2` and radius `r_2`, `x < y` if and only if `D(c_1,r_1)`
1487
+ is a subset of `D(c_2,r_2)` in `\CC_p`.
1488
+
1489
+ INPUT:
1490
+
1491
+ - ``other`` -- a point of the same Berkovich space as this point
1492
+
1493
+ OUTPUT:
1494
+
1495
+ - ``True`` -- if this point is greater than ``other`` in the standard partial order
1496
+ - ``False`` -- otherwise
1497
+
1498
+ EXAMPLES::
1499
+
1500
+ sage: B = Berkovich_Cp_Affine(QQ, 3)
1501
+ sage: Q1 = B(5, 3)
1502
+ sage: Q2 = B(5, 1)
1503
+ sage: Q1.gt(Q2)
1504
+ True
1505
+
1506
+ ::
1507
+
1508
+ sage: Q3 = B(1/27)
1509
+ sage: Q1.gt(Q3)
1510
+ False
1511
+
1512
+ TESTS::
1513
+
1514
+ sage: B = Berkovich_Cp_Affine(QQ, 3)
1515
+ sage: Q1 = B(5)
1516
+ sage: Q1.gt(Q1)
1517
+ False
1518
+
1519
+ ::
1520
+
1521
+ sage: Q2 = B(0, 1)
1522
+ sage: Q1.gt(Q2)
1523
+ False
1524
+
1525
+ ::
1526
+
1527
+ sage: Q3 = B([0, 3], [5, 1])
1528
+ sage: Q2.gt(Q3)
1529
+ True
1530
+ """
1531
+ if not isinstance(other, Berkovich_Element_Cp_Affine):
1532
+ raise TypeError('other must be a point of a projective Berkovich space, but was %s' % other)
1533
+ if self.parent() != other.parent():
1534
+ raise ValueError('other must be a point of the same projective Berkovich space')
1535
+
1536
+ if self == other:
1537
+ return False
1538
+ if self.type_of_point() in [1, 4]:
1539
+ return False
1540
+
1541
+ if other.type_of_point() == 4:
1542
+ center = other.center()[-1]
1543
+ dist = self._custom_abs(self.center() - center)
1544
+ return dist <= self.radius() and other.radius()[-1] <= self.radius()
1545
+ else:
1546
+ dist = self._custom_abs(self.center() - other.center())
1547
+ return dist <= self.radius() and other.radius() <= self.radius()
1548
+
1549
+ def join(self, other, basepoint=Infinity):
1550
+ """
1551
+ Compute the join of this point and ``other`` with respect to ``basepoint``.
1552
+
1553
+ The join is first point that lies on the intersection
1554
+ of the path from this point to ``basepoint`` and the path from ``other`` to
1555
+ ``basepoint``.
1556
+
1557
+ INPUT:
1558
+
1559
+ - ``other`` -- a point of the same Berkovich space as this point
1560
+ - ``basepoint`` -- (default: ``Infinity``) a point of the same
1561
+ Berkovich space as this point or ``Infinity``
1562
+
1563
+ OUTPUT: a point of the same Berkovich space
1564
+
1565
+ EXAMPLES::
1566
+
1567
+ sage: B = Berkovich_Cp_Affine(3)
1568
+ sage: Q1 = B(2, 1)
1569
+ sage: Q2 = B(2, 2)
1570
+ sage: Q1.join(Q2)
1571
+ Type III point centered at 2 + O(3^20) of radius 2.00000000000000
1572
+
1573
+ ::
1574
+
1575
+ sage: Q3 = B(5)
1576
+ sage: Q3.join(Q1)
1577
+ Type II point centered at 2 + 3 + O(3^20) of radius 3^0
1578
+
1579
+ ::
1580
+
1581
+ sage: Q3.join(Q1, basepoint=Q2)
1582
+ Type II point centered at 2 + O(3^20) of radius 3^0
1583
+
1584
+ TESTS::
1585
+
1586
+ sage: Q4 = B(1/3**8 + 2, 1)
1587
+ sage: Q2.join(Q4, basepoint=Q1)
1588
+ Type III point centered at 2 + O(3^20) of radius 2.00000000000000
1589
+
1590
+ ::
1591
+
1592
+ sage: Q5 = B(2, 1/9)
1593
+ sage: Q6 = B(1, 1/27)
1594
+ sage: Q4.join(Q5, basepoint=Q6)
1595
+ Type II point centered at 1 + O(3^20) of radius 3^0
1596
+
1597
+ ::
1598
+
1599
+ sage: Q7 = B(1/27, 1/27)
1600
+ sage: Q1.join(Q7, Q2)
1601
+ Type III point centered at 2 + O(3^20) of radius 2.00000000000000
1602
+ """
1603
+ # we error check and then pass to projective space to do the join
1604
+ if not isinstance(other, Berkovich_Element_Cp_Affine):
1605
+ raise TypeError('other must be a point of affine Berkovich space. other was %s' % other)
1606
+ if self.parent() != other.parent():
1607
+ raise ValueError('other must be a point of the same affine Berkovich space')
1608
+ if self.type_of_point() == 4 or other.type_of_point() == 4:
1609
+ raise NotImplementedError("join with type IV points not implemented")
1610
+
1611
+ proj_self = self.as_projective_point()
1612
+ proj_other = other.as_projective_point()
1613
+
1614
+ if basepoint == Infinity:
1615
+ return proj_self.join(proj_other).as_affine_point()
1616
+
1617
+ if not isinstance(basepoint, Berkovich_Element_Cp_Affine):
1618
+ raise TypeError('basepoint must a point of affine Berkovich space. basepoint was %s' % basepoint)
1619
+ if basepoint.parent() != self.parent():
1620
+ raise ValueError("basepoint must be a point of the same affine Berkovich space")
1621
+ if basepoint.type_of_point() == 4:
1622
+ raise NotImplementedError("join not implemented for type IV basepoint")
1623
+ proj_basepoint = basepoint.as_projective_point()
1624
+ return proj_self.join(proj_other, proj_basepoint).as_affine_point()
1625
+
1626
+ def involution_map(self):
1627
+ r"""
1628
+ Return the image of this point under the involution map.
1629
+
1630
+ The involution map is the extension of the map ``z |-> 1/z``
1631
+ on `\CC_p` to Berkovich space.
1632
+
1633
+ For affine Berkovich space, not defined for the type I
1634
+ point centered at 0.
1635
+
1636
+ If zero is contained in every disk approximating a type IV point,
1637
+ then the image under the involution map is not defined. To avoid
1638
+ this error, increase precision.
1639
+
1640
+ OUTPUT: a point of the same Berkovich space
1641
+
1642
+ EXAMPLES:
1643
+
1644
+ The involution map is 1/z on type I points::
1645
+
1646
+ sage: B = Berkovich_Cp_Affine(3)
1647
+ sage: Q1 = B(1/2)
1648
+ sage: Q1.involution_map()
1649
+ Type I point centered at 2 + O(3^20)
1650
+
1651
+ ::
1652
+
1653
+ sage: Q2 = B(0, 1/3)
1654
+ sage: Q2.involution_map()
1655
+ Type II point centered at 0 of radius 3^1
1656
+
1657
+ ::
1658
+
1659
+ sage: Q3 = B(1/3, 1/3)
1660
+ sage: Q3.involution_map()
1661
+ Type II point centered at 3 + O(3^21) of radius 3^-3
1662
+
1663
+ TESTS::
1664
+
1665
+ sage: B = Berkovich_Cp_Affine(3)
1666
+ sage: B(0).involution_map()
1667
+ Traceback (most recent call last):
1668
+ ...
1669
+ ValueError: involution map not defined on affine type I point centered at 0
1670
+
1671
+ ::
1672
+
1673
+ sage: B(1/81, 1.5).involution_map()
1674
+ Type III point centered at 3^4 + O(3^24) of radius 0.000228623685413809
1675
+
1676
+ ::
1677
+
1678
+ sage: B([1, 2], [3, 1]).involution_map()
1679
+ Traceback (most recent call last):
1680
+ ...
1681
+ ValueError: precision of type IV is not high enough to define image
1682
+
1683
+ ::
1684
+
1685
+ sage: B([1/81, 10/81], [10, 9]).involution_map()
1686
+ Type IV point of precision 2, approximated by disks centered at [3^4 + O(3^24),
1687
+ 3^4 + 2*3^6 + 2*3^7 + 2*3^10 + 2*3^11 + 2*3^14 + 2*3^15 + 2*3^18 + 2*3^19 + 2*3^22
1688
+ + 2*3^23 + O(3^24)] ... with radii [0.00152415790275873, 0.00137174211248285] ...
1689
+ """
1690
+ if self.type_of_point() == 1:
1691
+ if self.center() == 0:
1692
+ raise ValueError("involution map not defined on affine type I point centered at 0")
1693
+ return self.parent()(1 / self.center())
1694
+
1695
+ zero = self.parent()(ZZ(0))
1696
+ radius = self.radius()
1697
+
1698
+ if self.type_of_point() in [2, 3]:
1699
+ zero_contained_in_self = self.gt(zero)
1700
+ if zero_contained_in_self:
1701
+ if self.type_of_point() == 2:
1702
+ power = self.power()
1703
+ return self.parent()(ZZ(0), power=-power)
1704
+ return self.parent()(ZZ(0), RR(1 / radius))
1705
+ return self.parent()(1 / self.center(), RR(radius / (self._custom_abs(self.center())**2)))
1706
+
1707
+ new_center_lst = []
1708
+ new_radius_lst = []
1709
+ for i in range(len(self.center())):
1710
+ berk_point = self.parent()(self.center()[i], self.radius()[i])
1711
+ zero_check = berk_point.gt(zero)
1712
+ if zero_check:
1713
+ continue
1714
+ else:
1715
+ new_center = 1 / self.center()[i]
1716
+ new_radius = self.radius()[i] / (self._custom_abs(self.center()[i])**2)
1717
+ new_center_lst.append(new_center)
1718
+ new_radius_lst.append(new_radius)
1719
+ if not new_center_lst:
1720
+ raise ValueError('precision of type IV is not high enough to define image')
1721
+ return self.parent()(new_center_lst, new_radius_lst, error_check=False)
1722
+
1723
+ def contained_in_interval(self, start, end):
1724
+ """
1725
+ Check if this point is an element of the interval [``start``, ``end``].
1726
+
1727
+ INPUT:
1728
+
1729
+ - ``start`` -- a point of the same Berkovich space as this point
1730
+ - ``end`` -- a point of the same Berkovich space as this point
1731
+
1732
+ OUTPUT:
1733
+
1734
+ - ``True`` if this point is an element of [``start``, ``end``].
1735
+ - ``False`` otherwise.
1736
+
1737
+ EXAMPLES::
1738
+
1739
+ sage: B = Berkovich_Cp_Projective((3))
1740
+ sage: Q1 = B(2, 1)
1741
+ sage: Q2 = B(2, 4)
1742
+ sage: Q3 = B(1/3)
1743
+ sage: Q2.contained_in_interval(Q1, Q3.join(Q1))
1744
+ False
1745
+
1746
+ ::
1747
+
1748
+ sage: Q4 = B(1/81, 1)
1749
+ sage: Q2.contained_in_interval(Q1, Q4.join(Q1))
1750
+ True
1751
+ """
1752
+ if not isinstance(start, Berkovich_Element_Cp_Affine):
1753
+ raise TypeError("start must be a point of affine Berkovich space. start was %s" % start)
1754
+ if start.parent() != self.parent():
1755
+ raise ValueError("start must be a point of the same Berkovich space as this point")
1756
+ if not isinstance(end, Berkovich_Element_Cp_Affine):
1757
+ raise TypeError("end must be a point of affine Berkovich space. end was %s" % end)
1758
+ if end.parent() != self.parent():
1759
+ raise ValueError("end must be a point of the same Berkovich space as this point")
1760
+
1761
+ proj_self = self.as_projective_point()
1762
+ proj_start = start.as_projective_point()
1763
+ proj_end = end.as_projective_point()
1764
+ return proj_self.contained_in_interval(proj_start, proj_end)
1765
+
1766
+
1767
+ class Berkovich_Element_Cp_Projective(Berkovich_Element_Cp):
1768
+ r"""
1769
+ Element class of the Berkovich projective line over `\CC_p`.
1770
+
1771
+ Elements are categorized into four types, represented by specific data:
1772
+
1773
+ - Type I points are represented by a center in the ``base`` of the parent Berkovich space,
1774
+ which is projective space of dimension 1 over either `\QQ_p`, a finite extension of `\QQ_p`,
1775
+ or a number field.
1776
+
1777
+ - Type II points are represented by a center in the ``base`` of the parent Berkovich space,
1778
+ and a rational power of `p`.
1779
+
1780
+ - Type III points are represented by a center in the ``base`` of the parent Berkovich space,
1781
+ and by a radius, a real number, in `[0,\infty)`.
1782
+
1783
+ - Type IV points are represented by a finite list of centers in the ``base`` of the parent
1784
+ Berkovich space and a finite list of radii in `[0,\infty)`.
1785
+
1786
+ The projective Berkovich line is viewed as the one-point compactification of
1787
+ the affine Berkovich line. The projective Berkovich line therefore contains
1788
+ every point of the affine Berkovich line, along with a type I point centered
1789
+ at infinity.
1790
+
1791
+ INPUT:
1792
+
1793
+ - ``center`` -- for type I, II, and III points, the center of the
1794
+ corresponding disk in `P^1(\CC_p)`. If the parent Berkovich space was created using a number field
1795
+ `K`, then ``center`` can be an element of `P^1(K)`. Otherwise, ``center``
1796
+ must be an element of a projective space of dimension 1 over a `p`-adic field.
1797
+ For type IV points, can be a list of centers used to approximate the point or a
1798
+ univariate function that computes the centers (computation starts at 1).
1799
+
1800
+ - ``radius`` -- (optional) For type I, II, and III points, the radius of the
1801
+ corresponding disk in `\CC_p`. Must coerce into the real numbers. For type IV points,
1802
+ can be a list of radii used to approximate the point or a univariate function that
1803
+ computes the radii (computation starts at 1).
1804
+
1805
+ - ``power`` -- (optional) Rational number. Used for constructing type II points; specifies
1806
+ the power of ``p`` such that `p^\text{power}` = radius
1807
+
1808
+ - ``prec`` -- (default: 20) the number of disks to be used to approximate a type IV point
1809
+
1810
+ - ``error_check`` -- boolean (default: ``True``); if error checking should be run on input. If
1811
+ input is correctly formatted, can be set to ``False`` for better performance.
1812
+ WARNING: with error check set to ``False``, any error in the input will lead to
1813
+ incorrect results.
1814
+
1815
+ EXAMPLES:
1816
+
1817
+ Type I points can be created by specifying the corresponding point of `P^1(\CC_p)`::
1818
+
1819
+ sage: S = ProjectiveSpace(Qp(5), 1)
1820
+ sage: P = Berkovich_Cp_Projective(S); P
1821
+ Projective Berkovich line over Cp(5) of precision 20
1822
+
1823
+ ::
1824
+
1825
+ sage: a = S(0, 1)
1826
+ sage: Q1 = P(a); Q1
1827
+ Type I point centered at (0 : 1 + O(5^20))
1828
+
1829
+ ::
1830
+
1831
+ sage: Q2 = P((1,0)); Q2
1832
+ Type I point centered at (1 + O(5^20) : 0)
1833
+
1834
+ Type II and III points can be created by specifying a center and a radius::
1835
+
1836
+ sage: Q3 = P((0,5), 5**(3/2)); Q3 # needs sage.symbolic
1837
+ Type II point centered at (0 : 1 + O(5^20)) of radius 5^3/2
1838
+
1839
+ ::
1840
+
1841
+ sage: Q4 = P(0, 3**(3/2)); Q4 # needs sage.symbolic
1842
+ Type III point centered at (0 : 1 + O(5^20)) of radius 5.19615242270663
1843
+
1844
+ Type IV points can be created from lists of centers and radii::
1845
+
1846
+ sage: b = S((3,2)) # create centers
1847
+ sage: c = S((4,3))
1848
+ sage: d = S((2,3))
1849
+ sage: L = [b, c, d]
1850
+ sage: R = [1.761, 1.123, 1.112]
1851
+ sage: Q5 = P(L, R); Q5
1852
+ Type IV point of precision 3, approximated by disks centered at
1853
+ [(4 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 2*5^8 + 2*5^9 + 2*5^10 +
1854
+ 2*5^11 + 2*5^12 + 2*5^13 + 2*5^14 + 2*5^15 + 2*5^16 + 2*5^17 + 2*5^18 + 2*5^19 + O(5^20) :
1855
+ 1 + O(5^20)), (3 + 3*5 + 5^2 + 3*5^3 + 5^4 + 3*5^5 + 5^6 + 3*5^7 + 5^8 + 3*5^9 +
1856
+ 5^10 + 3*5^11 + 5^12 + 3*5^13 + 5^14 + 3*5^15 + 5^16 + 3*5^17 + 5^18 + 3*5^19 + O(5^20) :
1857
+ 1 + O(5^20))] ... with radii [1.76100000000000, 1.12300000000000] ...
1858
+
1859
+ Type IV points can also be created from univariate functions. Since the centers of
1860
+ the sequence of disks can not be the point at infinity in `P^1(\CC_p)`, only functions
1861
+ into `\CC_p` are supported::
1862
+
1863
+ sage: L.<t> = PolynomialRing(Qp(5))
1864
+ sage: T = FractionField(L)
1865
+ sage: f = T(1/t)
1866
+ sage: R.<x> = RR[]
1867
+ sage: Y = FractionField(R)
1868
+ sage: g = (40*pi)/x # needs sage.symbolic
1869
+ sage: Q6 = P(f, g); Q6 # needs sage.symbolic
1870
+ Type IV point of precision 20 with centers given by (1 + O(5^20))/((1 + O(5^20))*t)
1871
+ and radii given by 40.0000000000000*pi/x
1872
+
1873
+ TESTS::
1874
+
1875
+ sage: P((1,0), 3)
1876
+ Traceback (most recent call last):
1877
+ ...
1878
+ ValueError: type II and III points can not be centered at infinity
1879
+
1880
+ sage: B = Berkovich_Cp_Projective(3)
1881
+ sage: Q1 = B(3)
1882
+ sage: TestSuite(Q1).run()
1883
+ """
1884
+
1885
+ def __init__(self, parent, center, radius=None, power=None, prec=20, error_check=True):
1886
+ """
1887
+ Initialization function.
1888
+
1889
+ EXAMPLES::
1890
+
1891
+ sage: S = ProjectiveSpace(Qp(7), 1)
1892
+ sage: P = Berkovich_Cp_Projective(S)
1893
+ sage: P(0,1)
1894
+ Type II point centered at (0 : 1 + O(7^20)) of radius 7^0
1895
+ """
1896
+ # if we are given a point of Affine Berkovich Space, we do the conversion
1897
+ # otherwise we call the Berkovich_Element_Cp constructor with space_type="projective"
1898
+ Element.__init__(self, parent)
1899
+ self._p = parent.prime()
1900
+ self._base_space = parent.base()
1901
+ self._base_type = parent._base_type
1902
+ self._ideal = parent._ideal
1903
+
1904
+ # conversion from Affine points is handled in this constructor
1905
+ if isinstance(center, Berkovich_Element_Cp_Affine):
1906
+ raise TypeError('use as_projective_point to convert to projective Berkovich space')
1907
+
1908
+ Berkovich_Element_Cp.__init__(self, parent=parent, center=center, radius=radius, power=power,
1909
+ prec=prec, space_type='projective', error_check=error_check)
1910
+
1911
+ def as_affine_point(self):
1912
+ """
1913
+ Return the corresponding affine point after dehomogenizing at infinity.
1914
+
1915
+ OUTPUT: a point of affine Berkovich space
1916
+
1917
+ EXAMPLES::
1918
+
1919
+ sage: B = Berkovich_Cp_Projective(5)
1920
+ sage: B(5).as_affine_point()
1921
+ Type I point centered at 5 + O(5^21)
1922
+
1923
+ ::
1924
+
1925
+ sage: Q = B(0, 1).as_affine_point(); Q
1926
+ Type II point centered at 0 of radius 5^0
1927
+ sage: Q.parent()
1928
+ Affine Berkovich line over Cp(5) of precision 20
1929
+
1930
+ ::
1931
+
1932
+ sage: L.<t> = PolynomialRing(Qp(5))
1933
+ sage: T = FractionField(L)
1934
+ sage: f = T(1/t)
1935
+ sage: R.<x> = RR[]
1936
+ sage: Y = FractionField(R)
1937
+ sage: g = (40*pi)/x # needs sage.symbolic
1938
+ sage: Q2 = B(f, g) # needs sage.symbolic
1939
+ sage: Q2.as_affine_point() # needs sage.symbolic
1940
+ Type IV point of precision 20 with centers given by (1 + O(5^20))/((1 + O(5^20))*t)
1941
+ and radii given by 40.0000000000000*pi/x
1942
+ """
1943
+ if self.center()[1] == 0:
1944
+ raise ValueError('cannot convert infinity to affine Berkovich space')
1945
+ from sage.schemes.berkovich.berkovich_space import Berkovich_Cp_Affine
1946
+ new_space = Berkovich_Cp_Affine(self.parent().base_ring(), self.parent().ideal())
1947
+ if self.type_of_point() in [1, 2, 3]:
1948
+ center = self.center()[0]
1949
+ if self.type_of_point() == 1:
1950
+ return new_space(center)
1951
+ elif self.type_of_point() == 2:
1952
+ return new_space(center, power=self.power())
1953
+ elif self.type_of_point() == 3:
1954
+ return new_space(center, self.radius())
1955
+ if self._center_func is None:
1956
+ center = [i[0] for i in self.center()]
1957
+ else:
1958
+ center = self.center_function()
1959
+ if self._radius_func is None:
1960
+ radius = self.radius()
1961
+ else:
1962
+ radius = self.radius_function()
1963
+ return new_space(center, radius, prec=self.prec())
1964
+
1965
+ def __eq__(self, other):
1966
+ """
1967
+ Equality operator.
1968
+
1969
+ EXAMPLES::
1970
+
1971
+ sage: B = Berkovich_Cp_Projective(3)
1972
+ sage: Q1 = B([2, 2], RR(3**(1/2))) # needs sage.symbolic
1973
+ sage: Q2 = B([1, 1], 3**(1/2)) # needs sage.symbolic
1974
+ sage: Q1 == Q2 # needs sage.symbolic
1975
+ True
1976
+
1977
+ ::
1978
+
1979
+ sage: Q3 = B(1)
1980
+ sage: Q4 = B(4)
1981
+ sage: Q3 == Q4
1982
+ False
1983
+
1984
+ ::
1985
+
1986
+ sage: Q5 = B(1, 4)
1987
+ sage: Q1 == Q5 # needs sage.symbolic
1988
+ False
1989
+
1990
+ ::
1991
+
1992
+ sage: Q1 == Q3 # needs sage.symbolic
1993
+ False
1994
+ """
1995
+ if other is self:
1996
+ return True
1997
+ if not isinstance(other, Berkovich_Element_Cp_Projective):
1998
+ return False
1999
+ if other.parent() != self.parent():
2000
+ return False
2001
+ stype = self.type_of_point()
2002
+ otype = other.type_of_point()
2003
+ if stype == otype and stype == 1:
2004
+ return self.center() == other.center()
2005
+ elif stype == otype and stype == 4:
2006
+ raise NotImplementedError("equality for type IV points not implemented")
2007
+ elif stype in [2, 3] and otype in [2, 3]:
2008
+ if self.radius() != other.radius():
2009
+ return False
2010
+ scent = self.center()[0]
2011
+ ocent = other.center()[0]
2012
+ center_dist = self._custom_abs(scent - ocent)
2013
+ return center_dist <= self.radius()
2014
+ else:
2015
+ return False
2016
+
2017
+ def __hash__(self):
2018
+ """
2019
+ Return the hash of this point.
2020
+
2021
+ EXAMPLES::
2022
+
2023
+ sage: B = Berkovich_Cp_Projective(3)
2024
+ sage: P = ProjectiveSpace(B.base_ring(), 1)
2025
+ sage: Q1 = B(P.point([2, 2], False), RR(3**(1/2))) # needs sage.symbolic
2026
+ sage: Q2 = B([1, 1], 3**(1/2)) # needs sage.symbolic
2027
+ sage: hash(Q1) == hash(Q2) # needs sage.symbolic
2028
+ True
2029
+
2030
+ ::
2031
+
2032
+ sage: # needs sage.rings.number_field
2033
+ sage: R.<x> = QQ[]
2034
+ sage: A.<a> = NumberField(x^3 + 20)
2035
+ sage: ideal = A.ideal(-1/2*a^2 + a - 3)
2036
+ sage: B = Berkovich_Cp_Projective(A, ideal)
2037
+ sage: Q1 = B(a^2 + 1, 2)
2038
+ sage: Q2 = B(0, 2)
2039
+ sage: hash(Q1) == hash(Q2)
2040
+ True
2041
+ """
2042
+ if self.type_of_point() == 1:
2043
+ return hash(self.center())
2044
+ elif self.type_of_point() == 4:
2045
+ raise ValueError('hash not defined for type IV points')
2046
+ return hash(self.radius())
2047
+
2048
+ def lt(self, other):
2049
+ r"""
2050
+ Return ``True`` if this point is strictly less than ``other`` in the standard partial order.
2051
+
2052
+ Roughly, the partial order corresponds to containment of
2053
+ the corresponding disks in `\CC_p`.
2054
+
2055
+ For example, let x and y be points of type II or III.
2056
+ If x has center `c_1` and radius `r_1` and y has center
2057
+ `c_2` and radius `r_2`, `x < y` if and only if `D(c_1,r_1)`
2058
+ is a subset of `D(c_2,r_2)` in `\CC_p`.
2059
+
2060
+ INPUT:
2061
+
2062
+ - ``other`` -- a point of the same Berkovich space as this point
2063
+
2064
+ OUTPUT:
2065
+
2066
+ - ``True`` -- if this point is less than ``other`` in the standard partial order
2067
+ - ``False`` -- otherwise
2068
+
2069
+ EXAMPLES::
2070
+
2071
+ sage: B = Berkovich_Cp_Projective(3)
2072
+ sage: Q1 = B(5, 0.5)
2073
+ sage: Q2 = B(5, 1)
2074
+ sage: Q1.lt(Q2)
2075
+ True
2076
+
2077
+ ::
2078
+
2079
+ sage: Q3 = B(1)
2080
+ sage: Q1.lt(Q3)
2081
+ False
2082
+
2083
+ TESTS::
2084
+
2085
+ sage: B = Berkovich_Cp_Projective(3)
2086
+ sage: Q1 = B(5)
2087
+ sage: Q1.lt(Q1)
2088
+ False
2089
+
2090
+ ::
2091
+
2092
+ sage: Q2 = B([4, 1/3], [5, 1])
2093
+ sage: Q1.lt(Q2)
2094
+ False
2095
+
2096
+ ::
2097
+
2098
+ sage: Q3 = B((1,0))
2099
+ sage: Q4 = B(0, 1)
2100
+ sage: Q3.lt(Q4)
2101
+ False
2102
+
2103
+ ::
2104
+
2105
+ sage: Q4.lt(Q3)
2106
+ True
2107
+
2108
+ ::
2109
+
2110
+ sage: Q1.lt(Q4)
2111
+ True
2112
+
2113
+ ::
2114
+
2115
+ sage: Q2.lt(Q4)
2116
+ False
2117
+ """
2118
+ if not isinstance(other, Berkovich_Element_Cp_Projective):
2119
+ raise TypeError('other must be a point of a projective Berkovich space, but was %s' % other)
2120
+ if self.parent() != other.parent():
2121
+ raise ValueError('other must be a point of the same projective Berkovich space')
2122
+
2123
+ if self == other:
2124
+ return False
2125
+
2126
+ # infinity is maximal with respect to the standard partial order
2127
+ infinity = self.parent()((1, 0))
2128
+ if self == infinity:
2129
+ return False
2130
+ if other == infinity:
2131
+ return True
2132
+
2133
+ if other.type_of_point() in [1, 4]:
2134
+ return False
2135
+ if self.type_of_point() == 4:
2136
+ center = self.center()[-1]
2137
+ dist = self._custom_abs(other.center()[0] - center[0])
2138
+ return dist <= other.radius() and self.radius()[-1] <= other.radius()
2139
+ else:
2140
+ dist = self._custom_abs(self.center()[0] - other.center()[0])
2141
+ return dist <= other.radius() and self.radius() <= other.radius()
2142
+
2143
+ def gt(self, other):
2144
+ r"""
2145
+ Return ``True`` if this point is strictly greater than ``other`` in the standard partial order.
2146
+
2147
+ Roughly, the partial order corresponds to containment of
2148
+ the corresponding disks in `\CC_p`.
2149
+
2150
+ For example, let x and y be points of type II or III.
2151
+ If x has center `c_1` and radius `r_1` and y has center
2152
+ `c_2` and radius `r_2`, `x < y` if and only if `D(c_1, r_1)`
2153
+ is a subset of `D(c_2, r_2)` in `\CC_p`.
2154
+
2155
+ INPUT:
2156
+
2157
+ - ``other`` -- a point of the same Berkovich space as this point
2158
+
2159
+ OUTPUT:
2160
+
2161
+ - ``True`` -- if this point is greater than ``other`` in the standard partial order
2162
+ - ``False`` -- otherwise
2163
+
2164
+ EXAMPLES::
2165
+
2166
+ sage: B = Berkovich_Cp_Projective(QQ, 3)
2167
+ sage: Q1 = B(5, 3)
2168
+ sage: Q2 = B(5, 1)
2169
+ sage: Q1.gt(Q2)
2170
+ True
2171
+
2172
+ ::
2173
+
2174
+ sage: Q3 = B(1/27)
2175
+ sage: Q1.gt(Q3)
2176
+ False
2177
+
2178
+ TESTS::
2179
+
2180
+ sage: B = Berkovich_Cp_Projective(QQ, 3)
2181
+ sage: Q1 = B(5)
2182
+ sage: Q1.gt(Q1)
2183
+ False
2184
+
2185
+ ::
2186
+
2187
+ sage: Q2 = B(0, 1)
2188
+ sage: Q1.gt(Q2)
2189
+ False
2190
+
2191
+ ::
2192
+
2193
+ sage: Q3 = B([0, 3], [5, 1])
2194
+ sage: Q2.gt(Q3)
2195
+ True
2196
+
2197
+ ::
2198
+
2199
+ sage: Q4 = B((1,0))
2200
+ sage: Q4.gt(Q2)
2201
+ True
2202
+
2203
+ ::
2204
+
2205
+ sage: Q1.gt(Q4)
2206
+ False
2207
+ """
2208
+ if not isinstance(other, Berkovich_Element_Cp_Projective):
2209
+ raise TypeError('other must be a point of a projective Berkovich space, but was %s' % other)
2210
+ if self.parent() != other.parent():
2211
+ raise ValueError('other must be a point of the same projective Berkovich space')
2212
+
2213
+ if self == other:
2214
+ return False
2215
+ # infinity is maximal with respect to the standard partial order
2216
+ infinity = self.parent()((1, 0))
2217
+ if self == infinity:
2218
+ return True
2219
+ if other == infinity:
2220
+ return False
2221
+
2222
+ if self.type_of_point() in [1, 4]:
2223
+ return False
2224
+ if other.type_of_point() == 4:
2225
+ center = other.center()[-1]
2226
+ dist = self._custom_abs(self.center()[0] - center[0])
2227
+ return dist <= self.radius() and other.radius()[-1] <= self.radius()
2228
+ else:
2229
+ dist = self._custom_abs(self.center()[0] - other.center()[0])
2230
+ return dist <= self.radius() and other.radius() <= self.radius()
2231
+
2232
+ def join(self, other, basepoint=Infinity):
2233
+ """
2234
+ Compute the join of this point and ``other``, with respect to ``basepoint``.
2235
+
2236
+ The join is first point that lies on the intersection
2237
+ of the path from this point to ``basepoint`` and the path from ``other`` to
2238
+ ``basepoint``.
2239
+
2240
+ INPUT:
2241
+
2242
+ - ``other`` -- a point of the same Berkovich space as this point
2243
+ - ``basepoint`` -- (default: ``Infinity``) a point of the same
2244
+ Berkovich space as this point, or ``Infinity``
2245
+
2246
+ OUTPUT: a point of the same Berkovich space
2247
+
2248
+ EXAMPLES::
2249
+
2250
+ sage: B = Berkovich_Cp_Projective(3)
2251
+ sage: Q1 = B(2, 1)
2252
+ sage: Q2 = B(2, 2)
2253
+ sage: Q1.join(Q2)
2254
+ Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000
2255
+
2256
+ ::
2257
+
2258
+ sage: Q3 = B(5)
2259
+ sage: Q3.join(Q1)
2260
+ Type II point centered at (2 + 3 + O(3^20) : 1 + O(3^20)) of radius 3^0
2261
+
2262
+ ::
2263
+
2264
+ sage: Q3.join(Q1, basepoint=Q2)
2265
+ Type II point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 3^0
2266
+
2267
+ TESTS::
2268
+
2269
+ sage: Q4 = B(1/3**8 + 2, 1)
2270
+ sage: Q2.join(Q4, basepoint=Q1)
2271
+ Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000
2272
+ sage: Q5 = B(2, 1/9)
2273
+ sage: Q6 = B(1, 1/27)
2274
+ sage: Q4.join(Q5, basepoint=Q6)
2275
+ Type II point centered at (1 + O(3^20) : 1 + O(3^20)) of radius 3^0
2276
+ sage: Q7 = B(1/27, 1/27)
2277
+ sage: Q1.join(Q7, Q2)
2278
+ Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000
2279
+ sage: Q1.join(Q2, Q7)
2280
+ Type III point centered at (2 + O(3^20) : 1 + O(3^20)) of radius 2.00000000000000
2281
+ sage: Q8 = B(0, power=1/3)
2282
+ sage: Q9 = B(0, power=1/2)
2283
+ sage: Q8.join(Q9)
2284
+ Type II point centered at (0 : 1 + O(3^20)) of radius 3^1/2
2285
+
2286
+ sage: # needs sage.rings.number_field
2287
+ sage: R.<x> = QQ[]
2288
+ sage: A.<a> = NumberField(x^3 + 20)
2289
+ sage: ideal = A.prime_above(3)
2290
+ sage: C = Berkovich_Cp_Projective(A, ideal)
2291
+ sage: Q10 = C(a, 1/9)
2292
+ sage: Q10.join(Q9)
2293
+ Traceback (most recent call last):
2294
+ ...
2295
+ ValueError: other must be a point of the same projective Berkovich line
2296
+ sage: Q11 = C(0, 1/3)
2297
+ sage: Q11.join(Q10)
2298
+ Type II point centered at (0 : 1) of radius 3^0
2299
+ """
2300
+ if not isinstance(other, Berkovich_Element_Cp_Projective):
2301
+ raise TypeError('other must be a point of a projective Berkovich line, instead was %s' % other)
2302
+ if other.parent() != self.parent():
2303
+ raise ValueError('other must be a point of the same projective Berkovich line')
2304
+
2305
+ # if either self or other is type IV, we use the last disk in the approximation
2306
+ if self.type_of_point() == 4:
2307
+ new_center = self.center()[-1]
2308
+ new_radius = self.radius()[-1]
2309
+ return self.parent()(new_center, new_radius).join(other)
2310
+ if other.type_of_point() == 4:
2311
+ new_center = other.center()[-1]
2312
+ new_radius = other.radius()[-1]
2313
+ return self.join(self.parent()(new_center, new_radius))
2314
+
2315
+ # we deal with the point at infinity as a special case
2316
+ infty = self.parent()((1, 0))
2317
+
2318
+ if basepoint == Infinity or basepoint == infty:
2319
+ if self == infty or other == infty:
2320
+ return infty
2321
+ dist = self._custom_abs(self.center()[0] - other.center()[0])
2322
+ maximum = max(dist, self.radius(), other.radius())
2323
+ # optimize for when self or other are type II
2324
+ if maximum == self.radius() and self.type_of_point() == 2:
2325
+ return self.parent()(self.center(), power=self.power())
2326
+ if maximum == other.radius() and other.type_of_point() == 2:
2327
+ return self.parent()(self.center(), power=other.power())
2328
+ return self.parent()(self.center(), maximum)
2329
+
2330
+ if not isinstance(basepoint, Berkovich_Element_Cp_Projective):
2331
+ raise TypeError('basepoint must be a point of a projective Berkovich line, instead was %s' % basepoint)
2332
+ if basepoint.parent() != self.parent():
2333
+ raise ValueError("basepoint must be a point of the same Berkovich projective line")
2334
+
2335
+ # if the basepoint is type IV, we use the last disk in the approximation
2336
+ if basepoint.type_of_point() == 4:
2337
+ new_center = other.center()[-1]
2338
+ new_radius = other.radius()[-1]
2339
+ return self.join(other, self.parent()(new_center, new_radius))
2340
+
2341
+ if self == infty:
2342
+ return other.join(basepoint)
2343
+ if other == infty:
2344
+ return self.join(basepoint)
2345
+
2346
+ b_ge_s = basepoint.gt(self) or basepoint == self
2347
+ b_lt_s = basepoint.lt(self)
2348
+ b_ge_o = basepoint.gt(other) or basepoint == other
2349
+ b_lt_o = basepoint.lt(other)
2350
+ s_ge_o = self.gt(other) or self == other
2351
+ s_lt_o = self.lt(other)
2352
+
2353
+ # we deal with all the cases where self and other are not comparable first
2354
+ if not (s_lt_o or s_ge_o):
2355
+ if not (b_ge_o or b_lt_o):
2356
+ if not (b_ge_s or b_lt_s):
2357
+ # case where none of the points are comparable
2358
+ dist_b_s = self._custom_abs(self.center()[0] - basepoint.center()[0])
2359
+ dist_b_o = self._custom_abs(other.center()[0] - basepoint.center()[0])
2360
+ return self.parent()(basepoint.center(),
2361
+ min(max(dist_b_o, other.radius(), basepoint.radius()),
2362
+ max(dist_b_s, self.radius(), basepoint.radius())))
2363
+
2364
+ # case where self and basepoint are comparable
2365
+ else:
2366
+ if b_ge_s:
2367
+ return basepoint
2368
+ else:
2369
+ return self
2370
+
2371
+ # case where other and basepoint are comparable
2372
+ else:
2373
+ if b_ge_o:
2374
+ return basepoint
2375
+ else:
2376
+ return other
2377
+
2378
+ # now the cases where self > other
2379
+ elif s_ge_o:
2380
+ if not (b_ge_s or b_lt_s):
2381
+ return self
2382
+ if b_ge_s:
2383
+ return self
2384
+ if b_ge_o:
2385
+ return basepoint
2386
+ if b_lt_o:
2387
+ return other
2388
+
2389
+ # join is symmetric, so we flip self and other so that self > other
2390
+ else:
2391
+ return other.join(self, basepoint)
2392
+
2393
+ def involution_map(self):
2394
+ r"""
2395
+ Return the image of this point under the involution map.
2396
+
2397
+ The involution map is the extension of the map ``z |-> 1/z``
2398
+ on `P^1(\CC_p)` to Berkovich space.
2399
+
2400
+ If zero is contained in every disk approximating a type IV point,
2401
+ then the image under the involution map is not defined. To avoid
2402
+ this error, increase precision.
2403
+
2404
+ OUTPUT: a point of the same Berkovich space
2405
+
2406
+ EXAMPLES:
2407
+
2408
+ The involution map is 1/z on type I points::
2409
+
2410
+ sage: B = Berkovich_Cp_Projective(3)
2411
+ sage: Q1 = B(1/2)
2412
+ sage: Q1.involution_map()
2413
+ Type I point centered at (2 + O(3^20) : 1 + O(3^20))
2414
+
2415
+ ::
2416
+
2417
+ sage: Q2 = B(0, 1/3)
2418
+ sage: Q2.involution_map()
2419
+ Type II point centered at (0 : 1 + O(3^20)) of radius 3^1
2420
+
2421
+ ::
2422
+
2423
+ sage: Q3 = B(1/3, 1/3)
2424
+ sage: Q3.involution_map()
2425
+ Type II point centered at (3 + O(3^21) : 1 + O(3^20)) of radius 3^-3
2426
+
2427
+ TESTS::
2428
+
2429
+ sage: B = Berkovich_Cp_Projective(3)
2430
+ sage: B((1,0)).involution_map()
2431
+ Type I point centered at (0 : 1 + O(3^20))
2432
+
2433
+ ::
2434
+
2435
+ sage: B(0).involution_map()
2436
+ Type I point centered at (1 + O(3^20) : 0)
2437
+
2438
+ ::
2439
+
2440
+ sage: B(1/81, 1.5).involution_map()
2441
+ Type III point centered at (3^4 + O(3^24) : 1 + O(3^20)) of radius 0.000228623685413809
2442
+
2443
+ ::
2444
+
2445
+ sage: B([1, 2], [3, 1]).involution_map()
2446
+ Traceback (most recent call last):
2447
+ ...
2448
+ ValueError: precision of type IV is not high enough to define image
2449
+
2450
+ ::
2451
+
2452
+ sage: B([1/81, 10/81], [10, 9]).involution_map()
2453
+ Type IV point of precision 2, approximated by disks centered at
2454
+ [(3^4 + O(3^24) : 1 + O(3^20)), (3^4 + 2*3^6 + 2*3^7 + 2*3^10 + 2*3^11 +
2455
+ 2*3^14 + 2*3^15 + 2*3^18 + 2*3^19 + 2*3^22 + 2*3^23 + O(3^24) : 1 + O(3^20))]
2456
+ ... with radii [0.00152415790275873, 0.00137174211248285] ...
2457
+ """
2458
+ infty = self.parent()((1, 0))
2459
+ zero = self.parent()(0)
2460
+
2461
+ if self.type_of_point() == 1:
2462
+ if self == infty:
2463
+ return zero
2464
+ if self == zero:
2465
+ return infty
2466
+ return self.parent()(1 / self.center()[0])
2467
+
2468
+ if self.type_of_point() in [2, 3]:
2469
+ zero_contained_in_self = self.gt(zero)
2470
+ if zero_contained_in_self:
2471
+ if self.type_of_point() == 2:
2472
+ power = self.power()
2473
+ return self.parent()(ZZ(0), power=-power)
2474
+ return self.parent()(ZZ(0), 1 / self.radius())
2475
+ return self.parent()(1 / self.center()[0], self.radius() / (self._custom_abs(self.center()[0])**2))
2476
+
2477
+ new_center_lst = []
2478
+ new_radius_lst = []
2479
+ for i in range(len(self.center())):
2480
+ berk_point = self.parent()(self.center()[i], self.radius()[i])
2481
+ zero_check = berk_point.gt(zero)
2482
+ if zero_check:
2483
+ continue
2484
+ else:
2485
+ new_center = 1 / self.center()[i][0]
2486
+ new_radius = self.radius()[i] / (self._custom_abs(self.center()[i][0])**2)
2487
+ new_center_lst.append(new_center)
2488
+ new_radius_lst.append(new_radius)
2489
+ if not new_center_lst:
2490
+ raise ValueError('precision of type IV is not high enough to define image')
2491
+ return self.parent()(new_center_lst, new_radius_lst)
2492
+
2493
+ def contained_in_interval(self, start, end):
2494
+ """
2495
+ Check if this point is an element of the interval [``start``, ``end``].
2496
+
2497
+ INPUT:
2498
+
2499
+ - ``start`` -- a point of the same Berkovich space as this point
2500
+ - ``end`` -- a point of the same Berkovich space as this point
2501
+
2502
+ OUTPUT:
2503
+
2504
+ - ``True`` if this point is an element of [``start``, ``end``].
2505
+ - ``False`` otherwise.
2506
+
2507
+ EXAMPLES::
2508
+
2509
+ sage: B = Berkovich_Cp_Projective(3)
2510
+ sage: Q1 = B(2, 1)
2511
+ sage: Q2 = B(2, 4)
2512
+ sage: Q3 = B(1/3)
2513
+ sage: Q2.contained_in_interval(Q1, Q3.join(Q1))
2514
+ False
2515
+
2516
+ ::
2517
+
2518
+ sage: Q4 = B(1/81, 1)
2519
+ sage: Q2.contained_in_interval(Q1, Q4.join(Q1))
2520
+ True
2521
+
2522
+ TESTS::
2523
+
2524
+ sage: B = Berkovich_Cp_Projective(3)
2525
+ sage: infty = B((1, 0))
2526
+ sage: zero = B(0)
2527
+ sage: gauss = B(0, 1)
2528
+ sage: infty.contained_in_interval(zero, gauss)
2529
+ False
2530
+
2531
+ ::
2532
+
2533
+ sage: Q1 = B(1, 3)
2534
+ sage: infty.contained_in_interval(gauss, Q1)
2535
+ False
2536
+
2537
+ ::
2538
+
2539
+ sage: zero.contained_in_interval(infty, gauss)
2540
+ False
2541
+
2542
+ ::
2543
+
2544
+ sage: gauss.contained_in_interval(zero, infty)
2545
+ True
2546
+
2547
+ ::
2548
+
2549
+ sage: Q2 = B(81, 1/3)
2550
+ sage: gauss.contained_in_interval(infty, Q2)
2551
+ True
2552
+ """
2553
+ if not isinstance(start, Berkovich_Element_Cp_Projective):
2554
+ raise TypeError("start must be a point of Berkovich space")
2555
+ if start.parent() != self.parent():
2556
+ raise ValueError("start must be a point of the same Berkovich space as this point")
2557
+ if not isinstance(end, Berkovich_Element_Cp_Projective):
2558
+ raise TypeError("start must be a point of Berkovich space")
2559
+ if end.parent() != self.parent():
2560
+ raise ValueError("start must be a point of the same Berkovich space as this point")
2561
+
2562
+ # we treat infinity as a special case
2563
+ infty = self.parent()((1, 0))
2564
+ zero = self.parent()(ZZ(0))
2565
+ if self == infty:
2566
+ if start == zero or end == zero:
2567
+ return end == infty or start == infty
2568
+ return (self.involution_map()).contained_in_interval(start.involution_map(),
2569
+ end.involution_map())
2570
+ if start == infty or end == infty:
2571
+ if self == zero:
2572
+ return end == zero or start == zero
2573
+ if start == zero or end == zero:
2574
+ gauss = self.parent()(ZZ(0), ZZ(1))
2575
+ return self.contained_in_interval(start, gauss) or self.contained_in_interval(gauss, end)
2576
+ return self.involution_map().contained_in_interval(start.involution_map(),
2577
+ end.involution_map())
2578
+ join = start.join(end)
2579
+ j_ge_s = join.gt(self) or join == self
2580
+ s_ge_start = self.gt(start) or self == start
2581
+ s_ge_end = self.gt(end) or self == end
2582
+ return j_ge_s and (s_ge_end or s_ge_start)