passagemath-schemes 10.6.47__cp312-cp312-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.
- passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
- passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- 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)
|