passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-schemes might be problematic. Click here for more details.
- 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.40.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.40.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-314-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-314-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-314-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-314-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-314-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-314-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-314-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-314-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.cpython-314-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314-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-314-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-314-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,2576 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Wehler K3 Surfaces
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- Ben Hutz (11-2012)
|
|
8
|
+
- Joao Alberto de Faria (10-2013)
|
|
9
|
+
|
|
10
|
+
.. TODO::
|
|
11
|
+
|
|
12
|
+
Hasse-Weil Zeta Function
|
|
13
|
+
|
|
14
|
+
Picard Number
|
|
15
|
+
|
|
16
|
+
Number Fields
|
|
17
|
+
|
|
18
|
+
REFERENCES: [FH2015]_, [CS1996]_, [Weh1998]_, [Hutz2007]
|
|
19
|
+
"""
|
|
20
|
+
# ****************************************************************************
|
|
21
|
+
# This program is free software: you can redistribute it and/or modify
|
|
22
|
+
# it under the terms of the GNU General Public License as published by
|
|
23
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
24
|
+
# (at your option) any later version.
|
|
25
|
+
# https://www.gnu.org/licenses/
|
|
26
|
+
# ****************************************************************************
|
|
27
|
+
|
|
28
|
+
from copy import copy
|
|
29
|
+
|
|
30
|
+
import sage.rings.abc
|
|
31
|
+
|
|
32
|
+
from sage.categories.commutative_rings import CommutativeRings
|
|
33
|
+
from sage.categories.fields import Fields
|
|
34
|
+
from sage.categories.number_fields import NumberFields
|
|
35
|
+
from sage.misc.cachefunc import cached_method
|
|
36
|
+
from sage.misc.functional import sqrt
|
|
37
|
+
from sage.misc.lazy_import import lazy_import
|
|
38
|
+
from sage.misc.mrange import xmrange
|
|
39
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
40
|
+
from sage.rings.fraction_field import FractionField
|
|
41
|
+
from sage.rings.integer_ring import ZZ
|
|
42
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
43
|
+
from sage.rings.rational_field import QQ
|
|
44
|
+
from sage.rings.real_mpfr import RealField
|
|
45
|
+
from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme
|
|
46
|
+
from sage.schemes.product_projective.space import ProductProjectiveSpaces
|
|
47
|
+
from sage.schemes.product_projective.subscheme import AlgebraicScheme_subscheme_product_projective
|
|
48
|
+
|
|
49
|
+
lazy_import("sage.calculus.functions", "jacobian")
|
|
50
|
+
lazy_import('sage.rings.padics.factory', 'Qp')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
_NumberFields = NumberFields()
|
|
54
|
+
_Fields = Fields()
|
|
55
|
+
_CommutativeRings = CommutativeRings()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def WehlerK3Surface(polys):
|
|
59
|
+
r"""
|
|
60
|
+
Define a K3 Surface over `\mathbb{P}^2 \times \mathbb{P}^2` defined as
|
|
61
|
+
the intersection of a bilinear and biquadratic form. [Weh1998]_
|
|
62
|
+
|
|
63
|
+
INPUT:
|
|
64
|
+
|
|
65
|
+
- ``polys`` -- bilinear and biquadratic polynomials as a tuple or list
|
|
66
|
+
|
|
67
|
+
OUTPUT: :class:`WehlerK3Surface_ring`
|
|
68
|
+
|
|
69
|
+
EXAMPLES::
|
|
70
|
+
|
|
71
|
+
sage: PP.<x0,x1, x2, y0, y1, y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
72
|
+
sage: L = x0*y0 + x1*y1 - x2*y2
|
|
73
|
+
sage: Q = x0*x1*y1^2 + x2^2*y0*y2
|
|
74
|
+
sage: WehlerK3Surface([L, Q])
|
|
75
|
+
Closed subscheme of Product of projective spaces P^2 x P^2 over Rational
|
|
76
|
+
Field defined by:
|
|
77
|
+
x0*y0 + x1*y1 - x2*y2,
|
|
78
|
+
x0*x1*y1^2 + x2^2*y0*y2
|
|
79
|
+
"""
|
|
80
|
+
if not isinstance(polys, (list, tuple)):
|
|
81
|
+
raise TypeError("polys must be a list or tuple of polynomials")
|
|
82
|
+
|
|
83
|
+
R = polys[0].parent().base_ring()
|
|
84
|
+
if R in _Fields:
|
|
85
|
+
if R in _Fields.Finite():
|
|
86
|
+
return WehlerK3Surface_finite_field(polys)
|
|
87
|
+
return WehlerK3Surface_field(polys)
|
|
88
|
+
if R in _CommutativeRings:
|
|
89
|
+
return WehlerK3Surface_ring(polys)
|
|
90
|
+
raise TypeError("R (= %s) must be a commutative ring" % R)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def random_WehlerK3Surface(PP):
|
|
94
|
+
r"""
|
|
95
|
+
Produces a random K3 surface in `\mathbb{P}^2 \times \mathbb{P}^2` defined as the
|
|
96
|
+
intersection of a bilinear and biquadratic form. [Weh1998]_
|
|
97
|
+
|
|
98
|
+
INPUT:
|
|
99
|
+
|
|
100
|
+
- ``PP`` -- projective space cartesian product
|
|
101
|
+
|
|
102
|
+
OUTPUT: :class:`WehlerK3Surface_ring`
|
|
103
|
+
|
|
104
|
+
EXAMPLES::
|
|
105
|
+
|
|
106
|
+
sage: PP.<x0, x1, x2, y0, y1, y2> = ProductProjectiveSpaces([2, 2], GF(3))
|
|
107
|
+
sage: w = random_WehlerK3Surface(PP)
|
|
108
|
+
sage: type(w)
|
|
109
|
+
<class 'sage.dynamics.arithmetic_dynamics.wehlerK3.WehlerK3Surface_finite_field_with_category'>
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
CR = PP.coordinate_ring()
|
|
113
|
+
BR = PP.base_ring()
|
|
114
|
+
Q = 0
|
|
115
|
+
for a in xmrange([3,3]):
|
|
116
|
+
for b in xmrange([3,3]):
|
|
117
|
+
Q += BR.random_element() * CR.gen(a[0]) * CR.gen(a[1]) * CR.gen(3+b[0]) * CR.gen(3+b[1])
|
|
118
|
+
#We can always change coordinates to make L diagonal
|
|
119
|
+
L = CR.gen(0) * CR.gen(3) + CR.gen(1) * CR.gen(4) + CR.gen(2) * CR.gen(5)
|
|
120
|
+
return WehlerK3Surface([L, Q])
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class WehlerK3Surface_ring(AlgebraicScheme_subscheme_product_projective):
|
|
124
|
+
r"""
|
|
125
|
+
A K3 surface in `\mathbb{P}^2 \times \mathbb{P}^2` defined as the
|
|
126
|
+
intersection of a bilinear and biquadratic form. [Weh1998]_
|
|
127
|
+
|
|
128
|
+
EXAMPLES::
|
|
129
|
+
|
|
130
|
+
sage: R.<x,y,z,u,v,w> = PolynomialRing(QQ, 6)
|
|
131
|
+
sage: L = x*u - y*v
|
|
132
|
+
sage: Q = x*y*v^2 + z^2*u*w
|
|
133
|
+
sage: WehlerK3Surface([L, Q])
|
|
134
|
+
Closed subscheme of Product of projective spaces P^2 x P^2 over Rational
|
|
135
|
+
Field defined by:
|
|
136
|
+
x*u - y*v,
|
|
137
|
+
x*y*v^2 + z^2*u*w
|
|
138
|
+
"""
|
|
139
|
+
def __init__(self, polys):
|
|
140
|
+
if not isinstance(polys, (list, tuple)):
|
|
141
|
+
raise TypeError("polys must be a list or tuple of polynomials")
|
|
142
|
+
R = polys[0].parent()
|
|
143
|
+
vars = R.variable_names()
|
|
144
|
+
A = ProductProjectiveSpaces([2, 2],R.base_ring(),vars)
|
|
145
|
+
CR = A.coordinate_ring()
|
|
146
|
+
#Check for following:
|
|
147
|
+
# Is the user calling in 2 polynomials from a list or tuple?
|
|
148
|
+
# Is there one biquadratic and one bilinear polynomial?
|
|
149
|
+
if len(polys) != 2:
|
|
150
|
+
raise AttributeError("there must be 2 polynomials")
|
|
151
|
+
|
|
152
|
+
if (all(((e[0] + e[1] + e[2]) == 1 and (e[3] + e[4] + e[5]) == 1) for e in polys[0].exponents())):
|
|
153
|
+
self.L = CR(polys[0])
|
|
154
|
+
elif (all(((e[0] + e[1] + e[2]) == 1 and (e[3] + e[4] + e[5]) == 1) for e in polys[1].exponents())):
|
|
155
|
+
self.L = CR(polys[1])
|
|
156
|
+
else:
|
|
157
|
+
raise AttributeError("there must be one bilinear polynomial")
|
|
158
|
+
|
|
159
|
+
if (all(((e[0] + e[1] + e[2]) == 2 and (e[3] + e[4] + e[5]) == 2) for e in polys[0].exponents())):
|
|
160
|
+
self.Q = CR(polys[0])
|
|
161
|
+
elif (all(((e[0] + e[1] + e[2]) == 2 and (e[3] + e[4] + e[5]) == 2) for e in polys[1].exponents())):
|
|
162
|
+
self.Q = CR(polys[1])
|
|
163
|
+
else:
|
|
164
|
+
raise AttributeError("there must be one biquadratic polynomial")
|
|
165
|
+
AlgebraicScheme_subscheme.__init__(self, A, polys)
|
|
166
|
+
|
|
167
|
+
def change_ring(self, R):
|
|
168
|
+
r"""
|
|
169
|
+
Changes the base ring on which the Wehler K3 Surface is defined.
|
|
170
|
+
|
|
171
|
+
INPUT:
|
|
172
|
+
|
|
173
|
+
- ``R`` -- ring
|
|
174
|
+
|
|
175
|
+
OUTPUT: K3 Surface defined over input ring
|
|
176
|
+
|
|
177
|
+
EXAMPLES::
|
|
178
|
+
|
|
179
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], GF(3))
|
|
180
|
+
sage: L = x0*y0 + x1*y1 - x2*y2
|
|
181
|
+
sage: Q = x0*x1*y1^2 + x2^2*y0*y2
|
|
182
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
183
|
+
sage: W.base_ring()
|
|
184
|
+
Finite Field of size 3
|
|
185
|
+
sage: T = W.change_ring(GF(7))
|
|
186
|
+
sage: T.base_ring()
|
|
187
|
+
Finite Field of size 7
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
LR = self.L.change_ring(R)
|
|
191
|
+
LQ = self.Q.change_ring(R)
|
|
192
|
+
return (WehlerK3Surface( [LR,LQ]))
|
|
193
|
+
|
|
194
|
+
def _check_satisfies_equations(self, P):
|
|
195
|
+
r"""
|
|
196
|
+
Function checks to see if point ``P`` lies on the K3 Surface.
|
|
197
|
+
|
|
198
|
+
INPUT:
|
|
199
|
+
|
|
200
|
+
- ``P`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
201
|
+
|
|
202
|
+
OUTPUT: ``True`` if the point is not on the surface; :exc:`AttributeError`
|
|
203
|
+
otherwise
|
|
204
|
+
|
|
205
|
+
EXAMPLES::
|
|
206
|
+
|
|
207
|
+
sage: P.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
208
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 \
|
|
209
|
+
....: + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 - \
|
|
210
|
+
....: 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
211
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - \
|
|
212
|
+
....: 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
213
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
214
|
+
sage: Y = x0 * y0 + x1 * y1 + x2 * y2
|
|
215
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
216
|
+
sage: X._check_satisfies_equations([0, 0, 1, 1, 0, 0])
|
|
217
|
+
True
|
|
218
|
+
|
|
219
|
+
::
|
|
220
|
+
|
|
221
|
+
sage: P.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
222
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 \
|
|
223
|
+
....: + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 - \
|
|
224
|
+
....: 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
225
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - \
|
|
226
|
+
....: 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
227
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
228
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
229
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
230
|
+
sage: X._check_satisfies_equations([0, 1, 1, 1, 0, 0])
|
|
231
|
+
Traceback (most recent call last):
|
|
232
|
+
...
|
|
233
|
+
AttributeError: point not on surface
|
|
234
|
+
"""
|
|
235
|
+
Point = list(P)
|
|
236
|
+
if self.L(*Point) == 0 and self.Q(*Point) == 0:
|
|
237
|
+
return True
|
|
238
|
+
else:
|
|
239
|
+
raise AttributeError("point not on surface")
|
|
240
|
+
|
|
241
|
+
def _Lcoeff(self, component, i):
|
|
242
|
+
r"""
|
|
243
|
+
Return the polynomials `L^x_i` or `L^y_i`.
|
|
244
|
+
|
|
245
|
+
These polynomials are defined as:
|
|
246
|
+
|
|
247
|
+
`L^x_i` = the coefficients of `y_i` in `L(x, y)` (Component = 0)
|
|
248
|
+
|
|
249
|
+
`L^y_i` = the coefficients of `x_i` in `L(x, y)` (Component = 1)
|
|
250
|
+
|
|
251
|
+
Definition and Notation from: [CS1996]_
|
|
252
|
+
|
|
253
|
+
INPUT:
|
|
254
|
+
|
|
255
|
+
- ``component`` -- integer; 0 or 1
|
|
256
|
+
|
|
257
|
+
- ``i`` -- integer; 0, 1 or 2
|
|
258
|
+
|
|
259
|
+
OUTPUT: polynomial in terms of either y (Component = 0) or x (Component = 1)
|
|
260
|
+
|
|
261
|
+
EXAMPLES::
|
|
262
|
+
|
|
263
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
264
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
265
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 \
|
|
266
|
+
....: + x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
267
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
268
|
+
sage: X._Lcoeff(0, 0)
|
|
269
|
+
y0
|
|
270
|
+
|
|
271
|
+
::
|
|
272
|
+
|
|
273
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
274
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
275
|
+
sage: Z =x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 \
|
|
276
|
+
....: + x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
277
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
278
|
+
sage: X._Lcoeff(1, 0)
|
|
279
|
+
x0
|
|
280
|
+
"""
|
|
281
|
+
# Error Checks for Passed in Values
|
|
282
|
+
if component not in [0, 1]:
|
|
283
|
+
raise ValueError("component can only be 1 or 0")
|
|
284
|
+
if i not in [0, 1, 2]:
|
|
285
|
+
raise ValueError("index must be 0, 1, or 2")
|
|
286
|
+
R = self.ambient_space().coordinate_ring()
|
|
287
|
+
return self.L.coefficient(R.gen(component*3 + i))
|
|
288
|
+
|
|
289
|
+
def _Qcoeff(self, component, i, j):
|
|
290
|
+
r"""
|
|
291
|
+
Return the polynomials `Q^x_{ij}` or `Q^y_{ij}`.
|
|
292
|
+
|
|
293
|
+
These polynomials are defined as:
|
|
294
|
+
|
|
295
|
+
`Q^x_{ij}` = the coefficients of `y_{i}y_{j}` in `Q(x, y)` (Component = 0).
|
|
296
|
+
|
|
297
|
+
`Q^y_{ij}` = the coefficients of `x_{i}x_{j}` in `Q(x, y)` (Component = 1).
|
|
298
|
+
|
|
299
|
+
Definition and Notation from: [CS1996]_.
|
|
300
|
+
|
|
301
|
+
INPUT:
|
|
302
|
+
|
|
303
|
+
- ``component`` -- integer; 0 or 1
|
|
304
|
+
|
|
305
|
+
- ``i`` -- integer; 0, 1 or 2
|
|
306
|
+
|
|
307
|
+
- ``j`` -- integer; 0, 1 or 2
|
|
308
|
+
|
|
309
|
+
OUTPUT: polynomial in terms of either y (Component = 0) or x (Component = 1)
|
|
310
|
+
|
|
311
|
+
EXAMPLES::
|
|
312
|
+
|
|
313
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
314
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
315
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 \
|
|
316
|
+
....: + x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
317
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
318
|
+
sage: X._Qcoeff(0, 0, 0)
|
|
319
|
+
y0*y1 + y2^2
|
|
320
|
+
|
|
321
|
+
::
|
|
322
|
+
|
|
323
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
324
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
325
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 \
|
|
326
|
+
....: + x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
327
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
328
|
+
sage: X._Qcoeff(1, 1, 0)
|
|
329
|
+
x0^2
|
|
330
|
+
"""
|
|
331
|
+
# Check Errors in Passed in Values
|
|
332
|
+
if component not in [0, 1]:
|
|
333
|
+
raise ValueError("component can only be 1 or 0")
|
|
334
|
+
|
|
335
|
+
if i not in [0, 1, 2] or j not in [0, 1, 2]:
|
|
336
|
+
raise ValueError("the two indexes must be either 0, 1, or 2")
|
|
337
|
+
|
|
338
|
+
R = self.ambient_space().coordinate_ring()
|
|
339
|
+
return self.Q.coefficient(R.gen(component * 3 + i) * R.gen(component * 3 + j))
|
|
340
|
+
|
|
341
|
+
@cached_method
|
|
342
|
+
def Gpoly(self, component, k):
|
|
343
|
+
r"""
|
|
344
|
+
Return the G polynomials `G^*_k`.
|
|
345
|
+
|
|
346
|
+
They are defined as:
|
|
347
|
+
`G^*_k = \left(L^*_j\right)^2Q^*_{ii}-L^*_iL^*_jQ^*_{ij}+\left(L^*_i\right)^2Q^*_{jj}`
|
|
348
|
+
where `(i, j, k)` is some permutation of `(0, 1, 2)` and `*` is either
|
|
349
|
+
`x` (``component=1``) or `y` (``component=0``).
|
|
350
|
+
|
|
351
|
+
INPUT:
|
|
352
|
+
|
|
353
|
+
- ``component`` -- integer; 0 or 1
|
|
354
|
+
|
|
355
|
+
- ``k`` -- integer; 0, 1 or 2
|
|
356
|
+
|
|
357
|
+
OUTPUT: polynomial in terms of either `y` (``component=0``) or `x` (``component=1``)
|
|
358
|
+
|
|
359
|
+
EXAMPLES::
|
|
360
|
+
|
|
361
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
362
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
363
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 \
|
|
364
|
+
....: + x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
365
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
366
|
+
sage: X.Gpoly(1, 0)
|
|
367
|
+
x0^2*x1^2 + x1^4 - x0*x1^2*x2 + x1^3*x2 + x1^2*x2^2 + x2^4
|
|
368
|
+
"""
|
|
369
|
+
# Check Errors in passed in values
|
|
370
|
+
if component not in [0, 1]:
|
|
371
|
+
raise ValueError("component can only be 1 or 0")
|
|
372
|
+
|
|
373
|
+
if k not in [0, 1, 2]:
|
|
374
|
+
raise ValueError("index must be either 0, 1, or 2")
|
|
375
|
+
|
|
376
|
+
Indices = [0, 1, 2]
|
|
377
|
+
Indices.remove( k)
|
|
378
|
+
i = Indices[0]
|
|
379
|
+
j = Indices[1]
|
|
380
|
+
|
|
381
|
+
return (self._Lcoeff(component, j)**2) * (self._Qcoeff(component, i, i)) - (self._Lcoeff(component, i)) * \
|
|
382
|
+
(self._Lcoeff(component, j)) * (self._Qcoeff(component, i, j)) + (self._Lcoeff( component, i)**2) * \
|
|
383
|
+
(self._Qcoeff( component, j, j))
|
|
384
|
+
|
|
385
|
+
@cached_method
|
|
386
|
+
def Hpoly(self, component, i, j):
|
|
387
|
+
r"""
|
|
388
|
+
Return the H polynomials defined as `H^*_{ij}`.
|
|
389
|
+
|
|
390
|
+
This polynomial is defined by:
|
|
391
|
+
|
|
392
|
+
`H^*_{ij} = 2L^*_iL^*_jQ^*_{kk}-L^*_iL^*_kQ^*_{jk} - L^*_jL^*_kQ^*_{ik}+\left(L^*_k\right)^2Q^*_{ij}`
|
|
393
|
+
where {i, j, k} is some permutation of (0, 1, 2) and * is either y (``component=0``) or x (``component=1``).
|
|
394
|
+
|
|
395
|
+
INPUT:
|
|
396
|
+
|
|
397
|
+
- ``component`` -- integer; 0 or 1
|
|
398
|
+
|
|
399
|
+
- ``i`` -- integer; 0, 1 or 2
|
|
400
|
+
|
|
401
|
+
- ``j`` -- integer; 0, 1 or 2
|
|
402
|
+
|
|
403
|
+
OUTPUT: polynomial in terms of either y (``component=0``) or x (``component=1``)
|
|
404
|
+
|
|
405
|
+
EXAMPLES::
|
|
406
|
+
|
|
407
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
408
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
409
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 \
|
|
410
|
+
....: + x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
411
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
412
|
+
sage: X.Hpoly(0, 1, 0)
|
|
413
|
+
2*y0*y1^3 + 2*y0*y1*y2^2 - y1*y2^3
|
|
414
|
+
"""
|
|
415
|
+
#Check Errors in Passed in Values
|
|
416
|
+
if component not in [0, 1]:
|
|
417
|
+
raise ValueError("component can only be 1 or 0")
|
|
418
|
+
|
|
419
|
+
if (i not in [0, 1, 2]) or (j not in [0, 1, 2]):
|
|
420
|
+
raise ValueError("the two indexes must be either 0, 1, or 2")
|
|
421
|
+
|
|
422
|
+
Indices = [0, 1, 2]
|
|
423
|
+
Indices.remove(i)
|
|
424
|
+
Indices.remove(j)
|
|
425
|
+
|
|
426
|
+
k = Indices[0]
|
|
427
|
+
|
|
428
|
+
return 2*(self._Lcoeff(component, i)) * (self._Lcoeff(component, j)) * (self._Qcoeff(component, k, k)) -\
|
|
429
|
+
(self._Lcoeff(component, i)) * (self._Lcoeff( component, k)) * (self._Qcoeff(component, j, k)) -\
|
|
430
|
+
(self._Lcoeff(component, j)) * (self._Lcoeff(component, k)) * (self._Qcoeff( component, i, k)) +\
|
|
431
|
+
(self._Lcoeff(component, k)**2) * (self._Qcoeff(component, i, j))
|
|
432
|
+
|
|
433
|
+
def Lxa(self, a):
|
|
434
|
+
r"""
|
|
435
|
+
Function will return the L polynomial defining the fiber, given by `L^{x}_{a}`.
|
|
436
|
+
|
|
437
|
+
This polynomial is defined as:
|
|
438
|
+
|
|
439
|
+
`L^{x}_{a} = \{(a, y) \in \mathbb{P}^{2} \times \mathbb{P}^{2} \colon L(a, y) = 0\}`.
|
|
440
|
+
|
|
441
|
+
Notation and definition from: [CS1996]_
|
|
442
|
+
|
|
443
|
+
INPUT:
|
|
444
|
+
|
|
445
|
+
- ``a`` -- point in `\mathbb{P}^2`
|
|
446
|
+
|
|
447
|
+
OUTPUT: a polynomial representing the fiber
|
|
448
|
+
|
|
449
|
+
EXAMPLES::
|
|
450
|
+
|
|
451
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
452
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 \
|
|
453
|
+
....: + 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - \
|
|
454
|
+
....: x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2 \
|
|
455
|
+
....: + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 \
|
|
456
|
+
....: + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
457
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
458
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
459
|
+
sage: T = PP(1, 1, 0, 1, 0, 0)
|
|
460
|
+
sage: X.Lxa(T[0])
|
|
461
|
+
y0 + y1
|
|
462
|
+
"""
|
|
463
|
+
if a not in self.ambient_space()[0]:
|
|
464
|
+
raise TypeError("point must be in projective space of dimension 2")
|
|
465
|
+
AS = self.ambient_space()
|
|
466
|
+
ASC = AS.coordinate_ring()
|
|
467
|
+
PSY = AS[1]
|
|
468
|
+
PSYC = PSY.coordinate_ring()
|
|
469
|
+
#Define projection homomorphism
|
|
470
|
+
p = ASC.hom([a[0],a[1],a[2]] + list(PSY.gens()), PSYC)
|
|
471
|
+
return p(self.L)
|
|
472
|
+
|
|
473
|
+
def Qxa(self, a):
|
|
474
|
+
r"""
|
|
475
|
+
Function will return the Q polynomial defining a fiber given by `Q^{x}_{a}`.
|
|
476
|
+
|
|
477
|
+
This polynomial is defined as:
|
|
478
|
+
|
|
479
|
+
`Q^{x}_{a} = \{(a,y) \in \mathbb{P}^{2} \times \mathbb{P}^{2} \colon Q(a,y) = 0\}`.
|
|
480
|
+
|
|
481
|
+
Notation and definition from: [CS1996]_
|
|
482
|
+
|
|
483
|
+
INPUT:
|
|
484
|
+
|
|
485
|
+
- ``a`` -- point in `\mathbb{P}^2`
|
|
486
|
+
|
|
487
|
+
OUTPUT: a polynomial representing the fiber
|
|
488
|
+
|
|
489
|
+
EXAMPLES::
|
|
490
|
+
|
|
491
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
492
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 \
|
|
493
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2 \
|
|
494
|
+
....: + 5*x0*x2*y0*y2 \
|
|
495
|
+
....: - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
496
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
497
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
498
|
+
sage: T = PP(1, 1, 0, 1, 0, 0)
|
|
499
|
+
sage: X.Qxa(T[0])
|
|
500
|
+
5*y0^2 + 7*y0*y1 + y1^2 + 11*y1*y2 + y2^2
|
|
501
|
+
"""
|
|
502
|
+
if a not in self.ambient_space()[0]:
|
|
503
|
+
raise TypeError("point must be in Projective Space of dimension 2")
|
|
504
|
+
AS = self.ambient_space()
|
|
505
|
+
ASC = AS.coordinate_ring()
|
|
506
|
+
PSY = AS[1]
|
|
507
|
+
PSYC = PSY.coordinate_ring()
|
|
508
|
+
#Define projection homomorphism
|
|
509
|
+
p = ASC.hom([a[0], a[1], a[2]] + list(PSY.gens()), PSYC)
|
|
510
|
+
return p(self.Q)
|
|
511
|
+
|
|
512
|
+
def Sxa(self, a):
|
|
513
|
+
r"""
|
|
514
|
+
Function will return fiber by `S^{x}_{a}`.
|
|
515
|
+
|
|
516
|
+
This function is defined as:
|
|
517
|
+
|
|
518
|
+
`S^{x}_{a} = L^{x}_{a} \cap Q^{x}_{a}`.
|
|
519
|
+
|
|
520
|
+
Notation and definition from: [CS1996]_
|
|
521
|
+
|
|
522
|
+
INPUT:
|
|
523
|
+
|
|
524
|
+
- ``a`` -- point in `\mathbb{P}^2`
|
|
525
|
+
|
|
526
|
+
OUTPUT: a subscheme representing the fiber
|
|
527
|
+
|
|
528
|
+
EXAMPLES::
|
|
529
|
+
|
|
530
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
531
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 \
|
|
532
|
+
....: + 3*x0*x1*y0*y1 \
|
|
533
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2 \
|
|
534
|
+
....: + 5*x0*x2*y0*y2 \
|
|
535
|
+
....: - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
536
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
537
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
538
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
539
|
+
sage: T = PP(1, 1, 0, 1, 0, 0)
|
|
540
|
+
sage: X.Sxa(T[0])
|
|
541
|
+
Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
|
|
542
|
+
y0 + y1,
|
|
543
|
+
5*y0^2 + 7*y0*y1 + y1^2 + 11*y1*y2 + y2^2
|
|
544
|
+
"""
|
|
545
|
+
if a not in self.ambient_space()[0]:
|
|
546
|
+
raise TypeError("point must be in projective space of dimension 2")
|
|
547
|
+
PSY = self.ambient_space()[1]
|
|
548
|
+
return PSY.subscheme([self.Lxa(a),self.Qxa(a)])
|
|
549
|
+
|
|
550
|
+
def Lyb(self, b):
|
|
551
|
+
r"""
|
|
552
|
+
Function will return a fiber by `L^{y}_{b}`.
|
|
553
|
+
|
|
554
|
+
This polynomial is defined as:
|
|
555
|
+
|
|
556
|
+
`L^{y}_{b} = \{(x,b) \in \mathbb{P}^{2} \times \mathbb{P}^{2} \colon L(x,b) = 0\}`.
|
|
557
|
+
|
|
558
|
+
Notation and definition from: [CS1996]_
|
|
559
|
+
|
|
560
|
+
INPUT:
|
|
561
|
+
|
|
562
|
+
- ``b`` -- point in projective space
|
|
563
|
+
|
|
564
|
+
OUTPUT: a polynomial representing the fiber
|
|
565
|
+
|
|
566
|
+
EXAMPLES::
|
|
567
|
+
|
|
568
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
569
|
+
sage: Z =x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 \
|
|
570
|
+
....: + 3*x0*x1*y0*y1 \
|
|
571
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2 \
|
|
572
|
+
....: + 5*x0*x2*y0*y2 \
|
|
573
|
+
....: - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
574
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
575
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
576
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
577
|
+
sage: T = PP(1, 1, 0, 1, 0, 0)
|
|
578
|
+
sage: X.Lyb(T[1])
|
|
579
|
+
x0
|
|
580
|
+
"""
|
|
581
|
+
if b not in self.ambient_space()[1]:
|
|
582
|
+
raise TypeError("point must be in projective space of dimension 2")
|
|
583
|
+
AS = self.ambient_space()
|
|
584
|
+
ASC = AS.coordinate_ring()
|
|
585
|
+
PSY = AS[0]
|
|
586
|
+
PSYC = PSY.coordinate_ring()
|
|
587
|
+
p = ASC.hom(list(PSY.gens()) + [b[0], b[1], b[2]], PSYC)
|
|
588
|
+
return (p(self.L))
|
|
589
|
+
|
|
590
|
+
def Qyb(self, b):
|
|
591
|
+
r"""
|
|
592
|
+
|
|
593
|
+
Function will return a fiber by `Q^{y}_{b}`.
|
|
594
|
+
|
|
595
|
+
This polynomial is defined as:
|
|
596
|
+
|
|
597
|
+
`Q^{y}_{b} = \{(x,b) \in \mathbb{P}^{2} \times \mathbb{P}^{2} \colon Q(x,b) = 0\}`.
|
|
598
|
+
|
|
599
|
+
Notation and definition from: [CS1996]_
|
|
600
|
+
|
|
601
|
+
INPUT:
|
|
602
|
+
|
|
603
|
+
- ``b`` -- point in projective space
|
|
604
|
+
|
|
605
|
+
OUTPUT: a polynomial representing the fiber
|
|
606
|
+
|
|
607
|
+
EXAMPLES::
|
|
608
|
+
|
|
609
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
610
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 \
|
|
611
|
+
....: + 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
612
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 \
|
|
613
|
+
....: + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
614
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
615
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
616
|
+
sage: T = PP(1, 1, 0, 1, 0, 0)
|
|
617
|
+
sage: X.Qyb(T[1])
|
|
618
|
+
x0^2 + 3*x0*x1 + x1^2
|
|
619
|
+
"""
|
|
620
|
+
if b not in self.ambient_space()[1]:
|
|
621
|
+
raise TypeError("point must be in projective space of dimension 2")
|
|
622
|
+
AS = self.ambient_space()
|
|
623
|
+
ASC = AS.coordinate_ring()
|
|
624
|
+
PSY = AS[0]
|
|
625
|
+
PSYC = PSY.coordinate_ring()
|
|
626
|
+
p = ASC.hom(list(PSY.gens()) + [b[0], b[1], b[2]], PSYC)
|
|
627
|
+
return (p(self.Q))
|
|
628
|
+
|
|
629
|
+
def Syb(self, b):
|
|
630
|
+
r"""
|
|
631
|
+
Function will return fiber by `S^{y}_{b}`.
|
|
632
|
+
|
|
633
|
+
This function is defined by:
|
|
634
|
+
|
|
635
|
+
`S^{y}_{b} = L^{y}_{b} \cap Q^{y}_{b}`.
|
|
636
|
+
|
|
637
|
+
Notation and definition from: [CS1996]_
|
|
638
|
+
|
|
639
|
+
INPUT:
|
|
640
|
+
|
|
641
|
+
- ``b`` -- point in `\mathbb{P}^2`
|
|
642
|
+
|
|
643
|
+
OUTPUT: a subscheme representing the fiber
|
|
644
|
+
|
|
645
|
+
EXAMPLES::
|
|
646
|
+
|
|
647
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
648
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
649
|
+
....: 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
650
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 \
|
|
651
|
+
....: + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
652
|
+
sage: Y = x0 * y0 + x1 * y1 + x2 * y2
|
|
653
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
654
|
+
sage: T = PP(1, 1, 0, 1, 0, 0)
|
|
655
|
+
sage: X.Syb(T[1])
|
|
656
|
+
Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
|
|
657
|
+
x0,
|
|
658
|
+
x0^2 + 3*x0*x1 + x1^2
|
|
659
|
+
"""
|
|
660
|
+
if b not in self.ambient_space()[1]:
|
|
661
|
+
raise TypeError("point must be in projective space of dimension 2")
|
|
662
|
+
AS = self.ambient_space()
|
|
663
|
+
PSY = AS[0]
|
|
664
|
+
return PSY.subscheme([self.Lyb(b), self.Qyb(b)])
|
|
665
|
+
|
|
666
|
+
def Ramification_poly(self, i):
|
|
667
|
+
r"""
|
|
668
|
+
Function will return the Ramification polynomial `g^*`.
|
|
669
|
+
|
|
670
|
+
This polynomial is defined by:
|
|
671
|
+
|
|
672
|
+
`g^* = \frac{\left(H^*_{ij}\right)^2 - 4G^*_iG^*_j}{\left(L^*_k\right)^2}`.
|
|
673
|
+
|
|
674
|
+
The roots of this polynomial will either be degenerate fibers or fixed points
|
|
675
|
+
of the involutions `\sigma_x` or `\sigma_y` for more information, see [CS1996]_.
|
|
676
|
+
|
|
677
|
+
INPUT:
|
|
678
|
+
|
|
679
|
+
- ``i`` -- integer; either 0 (polynomial in y) or 1 (polynomial in x)
|
|
680
|
+
|
|
681
|
+
OUTPUT: polynomial in the coordinate ring of the ambient space
|
|
682
|
+
|
|
683
|
+
EXAMPLES::
|
|
684
|
+
|
|
685
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
686
|
+
sage: Z = (x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1
|
|
687
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2
|
|
688
|
+
....: + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2
|
|
689
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2)
|
|
690
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
691
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
692
|
+
sage: X.Ramification_poly(0)
|
|
693
|
+
8*y0^5*y1 - 24*y0^4*y1^2 + 48*y0^2*y1^4 - 16*y0*y1^5 + y1^6 + 84*y0^3*y1^2*y2
|
|
694
|
+
+ 46*y0^2*y1^3*y2 - 20*y0*y1^4*y2 + 16*y1^5*y2 + 53*y0^4*y2^2 + 56*y0^3*y1*y2^2
|
|
695
|
+
- 32*y0^2*y1^2*y2^2 - 80*y0*y1^3*y2^2 - 92*y1^4*y2^2 - 12*y0^2*y1*y2^3
|
|
696
|
+
- 168*y0*y1^2*y2^3 - 122*y1^3*y2^3 + 14*y0^2*y2^4 + 8*y0*y1*y2^4 - 112*y1^2*y2^4
|
|
697
|
+
+ y2^6
|
|
698
|
+
"""
|
|
699
|
+
return ((self._Lcoeff(i, 0))**2)*(self._Qcoeff(i, 1, 2))**2 + \
|
|
700
|
+
((self._Lcoeff(i, 1))**2)*(self._Qcoeff(i, 0, 2)**2) + \
|
|
701
|
+
((self._Lcoeff(i, 2))**2)*(self._Qcoeff(i, 0, 1)**2) - \
|
|
702
|
+
2*(self._Lcoeff(i, 0))*(self._Lcoeff(i, 1))*(self._Qcoeff(i, 0, 2))*(self._Qcoeff(i, 1, 2))\
|
|
703
|
+
- 2*(self._Lcoeff(i, 0))*(self._Lcoeff(i, 2))*(self._Qcoeff(i, 0, 1))*(self._Qcoeff(i, 1, 2))\
|
|
704
|
+
- 2*(self._Lcoeff(i, 1))*(self._Lcoeff(i, 2))*(self._Qcoeff(i, 0, 1))*(self._Qcoeff(i, 0, 2)) + \
|
|
705
|
+
4*(self._Lcoeff(i, 0))*(self._Lcoeff(i, 1))*(self._Qcoeff(i, 0, 1))*(self._Qcoeff(i, 2, 2)) + \
|
|
706
|
+
4*(self._Lcoeff(i, 0))*(self._Lcoeff(i, 2))*(self._Qcoeff(i, 0, 2))*(self._Qcoeff(i, 1, 1)) + \
|
|
707
|
+
4*(self._Lcoeff(i, 1))*(self._Lcoeff(i, 2))*(self._Qcoeff(i, 1, 2))*(self._Qcoeff(i, 0, 0)) - \
|
|
708
|
+
4*((self._Lcoeff(i, 0))**2)*(self._Qcoeff(i, 1, 1))*(self._Qcoeff(i, 2, 2)) - \
|
|
709
|
+
4*((self._Lcoeff(i, 1))**2)*(self._Qcoeff(i, 0, 0))*(self._Qcoeff(i, 2, 2)) - \
|
|
710
|
+
4*((self._Lcoeff(i, 2))**2)*(self._Qcoeff(i, 1, 1))*(self._Qcoeff(i, 0, 0))
|
|
711
|
+
|
|
712
|
+
@cached_method
|
|
713
|
+
def is_degenerate(self):
|
|
714
|
+
r"""
|
|
715
|
+
Function will return ``True`` if there is a fiber (over the algebraic closure of the
|
|
716
|
+
base ring) of dimension greater than 0 and ``False`` otherwise.
|
|
717
|
+
|
|
718
|
+
OUTPUT: boolean
|
|
719
|
+
|
|
720
|
+
EXAMPLES::
|
|
721
|
+
|
|
722
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
723
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
724
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 + x2^2*y2^2 + \
|
|
725
|
+
....: x2^2*y1^2 + x1^2*y2^2
|
|
726
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
727
|
+
sage: X.is_degenerate()
|
|
728
|
+
True
|
|
729
|
+
|
|
730
|
+
::
|
|
731
|
+
|
|
732
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
733
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 - \
|
|
734
|
+
....: 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - \
|
|
735
|
+
....: 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
736
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
737
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
738
|
+
sage: X.is_degenerate()
|
|
739
|
+
False
|
|
740
|
+
|
|
741
|
+
::
|
|
742
|
+
|
|
743
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], GF(3))
|
|
744
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 - \
|
|
745
|
+
....: 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - \
|
|
746
|
+
....: 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
747
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
748
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
749
|
+
sage: X.is_degenerate()
|
|
750
|
+
True
|
|
751
|
+
"""
|
|
752
|
+
PP = self.ambient_space()
|
|
753
|
+
K = FractionField(PP[0].base_ring())
|
|
754
|
+
R = PP.coordinate_ring()
|
|
755
|
+
PS = PP[0] #check for x fibers
|
|
756
|
+
vars = list(PS.gens())
|
|
757
|
+
R0 = PolynomialRing(K, 3, vars) #for dimension calculation to work,
|
|
758
|
+
#must be done with Polynomial ring over a field
|
|
759
|
+
#Degenerate is equivalent to a common zero, see Prop 1.4 in [CS1996]_
|
|
760
|
+
I = R.ideal(self.Gpoly(1, 0), self.Gpoly(1, 1), self.Gpoly(1, 2), self.Hpoly(1, 0, 1),
|
|
761
|
+
self.Hpoly(1, 0, 2), self.Hpoly(1, 1, 2))
|
|
762
|
+
phi = R.hom(vars + [0, 0, 0], R0)
|
|
763
|
+
I = phi(I)
|
|
764
|
+
if I.dimension() != 0:
|
|
765
|
+
return True
|
|
766
|
+
|
|
767
|
+
PS = PP[1] #check for y fibers
|
|
768
|
+
vars = list(PS.gens())
|
|
769
|
+
R0 = PolynomialRing(K,3,vars) #for dimension calculation to work,
|
|
770
|
+
#must be done with Polynomial ring over a field
|
|
771
|
+
#Degenerate is equivalent to a common zero, see Prop 1.4 in [CS1996]_
|
|
772
|
+
I = R.ideal(self.Gpoly(0, 0), self.Gpoly(0, 1), self.Gpoly(0, 2), self.Hpoly(0, 0, 1),
|
|
773
|
+
self.Hpoly(0, 0, 2), self.Hpoly(0, 1, 2))
|
|
774
|
+
phi = R.hom([0, 0, 0] + vars, R0)
|
|
775
|
+
I = phi(I)
|
|
776
|
+
return I.dimension() != 0
|
|
777
|
+
|
|
778
|
+
def degenerate_fibers(self):
|
|
779
|
+
r"""
|
|
780
|
+
Return the (rational) degenerate fibers of the surface defined over
|
|
781
|
+
the base ring, or the fraction field of the base ring if it is not a field.
|
|
782
|
+
|
|
783
|
+
ALGORITHM:
|
|
784
|
+
|
|
785
|
+
The criteria for degeneracy by the common vanishing of the polynomials
|
|
786
|
+
``self.Gpoly(1, 0)``, ``self.Gpoly(1, 1)``, ``self.Gpoly(1, 2)``,
|
|
787
|
+
``self.Hpoly(1, 0, 1)``, ``self.Hpoly(1, 0, 2)``,
|
|
788
|
+
``self.Hpoly(1, 1, 2)`` (for the first component), is from Proposition 1.4
|
|
789
|
+
in the following article: [CS1996]_.
|
|
790
|
+
|
|
791
|
+
This function finds the common solution through elimination via Groebner bases
|
|
792
|
+
by using the .variety() function on the three affine charts in each component.
|
|
793
|
+
|
|
794
|
+
OUTPUT: the output is a list of lists where the elements of lists are
|
|
795
|
+
points in the appropriate projective space.
|
|
796
|
+
The first list is the points whose pullback by the projection to the
|
|
797
|
+
first component (projective space) is dimension greater than 0.
|
|
798
|
+
The second list is points in the second component
|
|
799
|
+
|
|
800
|
+
EXAMPLES::
|
|
801
|
+
|
|
802
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
803
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
804
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 + x2^2*y2^2\
|
|
805
|
+
....: + x2^2*y1^2 + x1^2*y2^2
|
|
806
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
807
|
+
sage: X.degenerate_fibers()
|
|
808
|
+
[[], [(1 : 0 : 0)]]
|
|
809
|
+
|
|
810
|
+
::
|
|
811
|
+
|
|
812
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
813
|
+
sage: Z = (x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1
|
|
814
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2
|
|
815
|
+
....: + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2
|
|
816
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2)
|
|
817
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
818
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
819
|
+
sage: X.degenerate_fibers()
|
|
820
|
+
[[], []]
|
|
821
|
+
|
|
822
|
+
::
|
|
823
|
+
|
|
824
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
825
|
+
sage: R = PP.coordinate_ring()
|
|
826
|
+
sage: l = y0*x0 + y1*x1 + (y0 - y1)*x2
|
|
827
|
+
sage: q = (y1*y0 + y2^2)*x0^2 + ((y0^2 - y2*y1)*x1 + (y0^2 + (y1^2 - y2^2))*x2)*x0 \
|
|
828
|
+
....: + (y2*y0 + y1^2)*x1^2 + (y0^2 + (-y1^2 + y2^2))*x2*x1
|
|
829
|
+
sage: X = WehlerK3Surface([l,q])
|
|
830
|
+
sage: X.degenerate_fibers()
|
|
831
|
+
[[(-1 : 1 : 1), (0 : 0 : 1)], [(-1 : -1 : 1), (0 : 0 : 1)]]
|
|
832
|
+
"""
|
|
833
|
+
PP = self.ambient_space()
|
|
834
|
+
R = PP.coordinate_ring()
|
|
835
|
+
PSX = PP[0]
|
|
836
|
+
vars = list(PSX.gens())
|
|
837
|
+
K = FractionField(PSX.base_ring())
|
|
838
|
+
R0 = PolynomialRing(K, 3, vars)
|
|
839
|
+
I = R.ideal(self.Gpoly(1, 0), self.Gpoly(1, 1), self.Gpoly(1, 2), self.Hpoly(1, 0,1 ),
|
|
840
|
+
self.Hpoly(1, 0, 2), self.Hpoly(1, 1, 2))
|
|
841
|
+
phi = R.hom(vars + [0, 0, 0], R0)
|
|
842
|
+
I = phi(I)
|
|
843
|
+
xFibers = []
|
|
844
|
+
#check affine charts
|
|
845
|
+
for n in range(3):
|
|
846
|
+
affvars = list(R0.gens())
|
|
847
|
+
del affvars[n]
|
|
848
|
+
R1 = PolynomialRing(K, 2, affvars, order='lex')
|
|
849
|
+
mapvars = list(R1.gens())
|
|
850
|
+
mapvars.insert(n,1)
|
|
851
|
+
phi1 = R0.hom(mapvars, R1)
|
|
852
|
+
J = phi1(I)
|
|
853
|
+
if (J.dimension() == 0):
|
|
854
|
+
Var = J.variety()
|
|
855
|
+
if Var != [{}]:
|
|
856
|
+
for d in Var: #iterate through dictionaries
|
|
857
|
+
P = [] #new point
|
|
858
|
+
for z in mapvars: #assign coordinate values
|
|
859
|
+
if (z == 1):
|
|
860
|
+
P.append(1)
|
|
861
|
+
else:
|
|
862
|
+
P.append(d[z])
|
|
863
|
+
MP = PSX(P) #make projective point
|
|
864
|
+
if MP not in xFibers:
|
|
865
|
+
xFibers.append(MP)
|
|
866
|
+
PSY = PP[1]
|
|
867
|
+
vars = list(PSY.gens())
|
|
868
|
+
K = FractionField(PSY.base_ring())
|
|
869
|
+
R0 = PolynomialRing(K, 3, vars)
|
|
870
|
+
I = R.ideal(self.Gpoly(0, 0), self.Gpoly(0, 1), self.Gpoly(0, 2), self.Hpoly(0, 0, 1),
|
|
871
|
+
self.Hpoly(0, 0, 2), self.Hpoly(0, 1, 2))
|
|
872
|
+
phi = PP.coordinate_ring().hom([0, 0, 0] + vars, R0)
|
|
873
|
+
I = phi(I)
|
|
874
|
+
yFibers = []
|
|
875
|
+
#check affine charts
|
|
876
|
+
for n in range(3):
|
|
877
|
+
affvars = list(R0.gens())
|
|
878
|
+
del affvars[n]
|
|
879
|
+
R1 = PolynomialRing(K, 2, affvars, order='lex')
|
|
880
|
+
mapvars = list(R1.gens())
|
|
881
|
+
mapvars.insert(n, 1)
|
|
882
|
+
phi1 = R0.hom(mapvars,R1)
|
|
883
|
+
J = phi1(I)
|
|
884
|
+
if (J.dimension() == 0):
|
|
885
|
+
Var = J.variety()
|
|
886
|
+
if Var != [{}]:
|
|
887
|
+
for d in Var: #iterate through dictionaries
|
|
888
|
+
P = [] #new point
|
|
889
|
+
for z in mapvars: #assign coordinate values
|
|
890
|
+
if (z == 1):
|
|
891
|
+
P.append(1)
|
|
892
|
+
else:
|
|
893
|
+
P.append(d[z])
|
|
894
|
+
MP = PSY(P) #make projective point
|
|
895
|
+
if MP not in yFibers:
|
|
896
|
+
yFibers.append(MP)
|
|
897
|
+
return [xFibers,yFibers]
|
|
898
|
+
|
|
899
|
+
@cached_method
|
|
900
|
+
def degenerate_primes(self, check=True):
|
|
901
|
+
r"""
|
|
902
|
+
Determine which primes `p` ``self`` has degenerate fibers over `\GF{p}`.
|
|
903
|
+
|
|
904
|
+
If ``check`` is ``False``, then may return primes that do not have degenerate fibers.
|
|
905
|
+
Raises an error if the surface is degenerate.
|
|
906
|
+
Works only for ``ZZ`` or ``QQ``.
|
|
907
|
+
|
|
908
|
+
INPUT:
|
|
909
|
+
|
|
910
|
+
- ``check`` -- boolean (default: ``True``); whether the primes are verified
|
|
911
|
+
|
|
912
|
+
ALGORITHM:
|
|
913
|
+
|
|
914
|
+
`p` is a prime of bad reduction if and only if the defining
|
|
915
|
+
polynomials of ``self`` plus the G and H polynomials have a common
|
|
916
|
+
zero. Or stated another way, `p` is a prime of bad reduction if
|
|
917
|
+
and only if the radical of the ideal defined by the defining
|
|
918
|
+
polynomials of ``self`` plus the G and H polynomials is not
|
|
919
|
+
`(x_0,x_1,\ldots,x_N)`. This happens if and only if some
|
|
920
|
+
power of each `x_i` is not in the ideal defined by the
|
|
921
|
+
defining polynomials of ``self`` (with G and H). This last condition
|
|
922
|
+
is what is checked. The lcm of the coefficients of the monomials `x_i` in
|
|
923
|
+
a Groebner basis is computed. This may return extra primes.
|
|
924
|
+
|
|
925
|
+
OUTPUT: list of primes
|
|
926
|
+
|
|
927
|
+
EXAMPLES::
|
|
928
|
+
|
|
929
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(QQ, 6)
|
|
930
|
+
sage: L = y0*x0 + (y1*x1 + y2*x2)
|
|
931
|
+
sage: Q = (2*y0^2 + y2*y0 + (2*y1^2 + y2^2))*x0^2 + ((y0^2 + y1*y0 + \
|
|
932
|
+
....: (y1^2 + 2*y2*y1 + y2^2))*x1 + (2*y1^2 + y2*y1 + y2^2)*x2)*x0 + ((2*y0^2\
|
|
933
|
+
....: + (y1 + 2*y2)*y0 + (2*y1^2 + y2*y1))*x1^2 + ((2*y1 + 2*y2)*y0 + (y1^2 + \
|
|
934
|
+
....: y2*y1 + 2*y2^2))*x2*x1 + (2*y0^2 + y1*y0 + (2*y1^2 + y2^2))*x2^2)
|
|
935
|
+
sage: X = WehlerK3Surface([L, Q])
|
|
936
|
+
sage: X.degenerate_primes()
|
|
937
|
+
[2, 3, 5, 11, 23, 47, 48747691, 111301831]
|
|
938
|
+
"""
|
|
939
|
+
PP = self.ambient_space()
|
|
940
|
+
if PP.base_ring() != ZZ and PP.base_ring() != QQ:
|
|
941
|
+
if PP.base_ring() in _NumberFields or isinstance(PP.base_ring(), sage.rings.abc.Order):
|
|
942
|
+
raise NotImplementedError("only implemented for ZZ and QQ")
|
|
943
|
+
else:
|
|
944
|
+
raise TypeError("must be over a number field or number field order")
|
|
945
|
+
if self.is_degenerate():
|
|
946
|
+
raise TypeError("surface is degenerate at all primes")
|
|
947
|
+
RR = PP.coordinate_ring()
|
|
948
|
+
|
|
949
|
+
#x-fibers
|
|
950
|
+
PSX = PP[0]
|
|
951
|
+
vars = list(PSX.gens())
|
|
952
|
+
K = PSX.base_ring()
|
|
953
|
+
R = PolynomialRing(K, 3, vars)
|
|
954
|
+
I = RR.ideal(self.Gpoly(1, 0), self.Gpoly(1, 1), self.Gpoly(1, 2), self.Hpoly(1, 0, 1),
|
|
955
|
+
self.Hpoly(1, 0, 2), self.Hpoly(1, 1, 2))
|
|
956
|
+
phi = PP.coordinate_ring().hom(vars + [0, 0, 0], R)
|
|
957
|
+
I = phi(I)
|
|
958
|
+
bad_primes = []
|
|
959
|
+
|
|
960
|
+
#move the ideal to the ring of integers
|
|
961
|
+
if R.base_ring().is_field():
|
|
962
|
+
S = PolynomialRing(R.base_ring().ring_of_integers(),R.gens(),R.ngens())
|
|
963
|
+
I = S.ideal(I.gens())
|
|
964
|
+
GB = I.groebner_basis()
|
|
965
|
+
#get the primes dividing the coefficients of the monomials x_i^k_i
|
|
966
|
+
for i in range(len(GB)):
|
|
967
|
+
LT = GB[i].lt().degrees()
|
|
968
|
+
power = 0
|
|
969
|
+
for j in range(R.ngens()):
|
|
970
|
+
if LT[j] != 0:
|
|
971
|
+
power += 1
|
|
972
|
+
if power == 1:
|
|
973
|
+
bad_primes = bad_primes+GB[i].lt().coefficients()[0].support()
|
|
974
|
+
|
|
975
|
+
#y-fibers
|
|
976
|
+
PSY = PP[1]
|
|
977
|
+
vars = list(PSY.gens())
|
|
978
|
+
K = PSY.base_ring()
|
|
979
|
+
R = PolynomialRing(K, 3, vars)
|
|
980
|
+
I = RR.ideal(self.Gpoly(0, 0), self.Gpoly(0, 1), self.Gpoly(0, 2), self.Hpoly(0, 0, 1),
|
|
981
|
+
self.Hpoly(0, 0, 2), self.Hpoly(0, 1, 2))
|
|
982
|
+
phi = PP.coordinate_ring().hom([0, 0, 0] + vars, R)
|
|
983
|
+
I = phi(I)
|
|
984
|
+
#move the ideal to the ring of integers
|
|
985
|
+
if R.base_ring().is_field():
|
|
986
|
+
S = PolynomialRing(R.base_ring().ring_of_integers(),R.gens(),R.ngens())
|
|
987
|
+
I = S.ideal(I.gens())
|
|
988
|
+
GB = I.groebner_basis()
|
|
989
|
+
#get the primes dividing the coefficients of the monomials x_i^k_i
|
|
990
|
+
for i in range(len(GB)):
|
|
991
|
+
LT = GB[i].lt().degrees()
|
|
992
|
+
power = 0
|
|
993
|
+
for j in range(R.ngens()):
|
|
994
|
+
if LT[j] != 0:
|
|
995
|
+
power += 1
|
|
996
|
+
if power == 1:
|
|
997
|
+
bad_primes = bad_primes+GB[i].lt().coefficients()[0].support()
|
|
998
|
+
bad_primes = sorted(set(bad_primes))
|
|
999
|
+
#check to return only the truly bad primes
|
|
1000
|
+
if check:
|
|
1001
|
+
for p in bad_primes:
|
|
1002
|
+
X = self.change_ring(GF(p))
|
|
1003
|
+
if not X.is_degenerate():
|
|
1004
|
+
bad_primes.remove(p)
|
|
1005
|
+
return bad_primes
|
|
1006
|
+
|
|
1007
|
+
def is_smooth(self):
|
|
1008
|
+
r"""
|
|
1009
|
+
Function will return the status of the smoothness of the surface.
|
|
1010
|
+
|
|
1011
|
+
ALGORITHM:
|
|
1012
|
+
|
|
1013
|
+
Checks to confirm that all of the 2x2 minors of the Jacobian generated from
|
|
1014
|
+
the biquadratic and bilinear forms have no common vanishing points.
|
|
1015
|
+
|
|
1016
|
+
OUTPUT: boolean
|
|
1017
|
+
|
|
1018
|
+
EXAMPLES::
|
|
1019
|
+
|
|
1020
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
1021
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
1022
|
+
sage: Z = x0^2*y0*y1 + x0^2*y2^2 - x0*x1*y1*y2 + x1^2*y2*y1 +\
|
|
1023
|
+
....: x2^2*y2^2 + x2^2*y1^2 + x1^2*y2^2
|
|
1024
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1025
|
+
sage: X.is_smooth()
|
|
1026
|
+
False
|
|
1027
|
+
|
|
1028
|
+
::
|
|
1029
|
+
|
|
1030
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1031
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
1032
|
+
....: 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
1033
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
1034
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1035
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1036
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1037
|
+
sage: X.is_smooth()
|
|
1038
|
+
True
|
|
1039
|
+
"""
|
|
1040
|
+
vars = list(self.ambient_space().gens())
|
|
1041
|
+
M = jacobian([self.L, self.Q], vars)
|
|
1042
|
+
R = self.ambient_space().coordinate_ring()
|
|
1043
|
+
I = R.ideal(M.minors(2) + [self.L,self.Q])
|
|
1044
|
+
T = PolynomialRing(self.ambient_space().base_ring().fraction_field(), 4, 'h')
|
|
1045
|
+
#check the 9 affine charts for a singular point
|
|
1046
|
+
for l in xmrange([3, 3]):
|
|
1047
|
+
vars = list(T.gens())
|
|
1048
|
+
vars.insert(l[0], 1)
|
|
1049
|
+
vars.insert(3 + l[1], 1)
|
|
1050
|
+
phi = R.hom(vars, T)
|
|
1051
|
+
J = phi(I)
|
|
1052
|
+
if J.dimension() != -1:
|
|
1053
|
+
return False
|
|
1054
|
+
return True
|
|
1055
|
+
|
|
1056
|
+
def sigmaX(self, P, **kwds):
|
|
1057
|
+
r"""
|
|
1058
|
+
Function returns the involution on the Wehler K3 surface induced by the double covers.
|
|
1059
|
+
|
|
1060
|
+
In particular, it fixes the projection to the first coordinate and swaps the
|
|
1061
|
+
two points in the fiber, i.e. `(x, y) \to (x, y')`.
|
|
1062
|
+
Note that in the degenerate case, while we can split fiber into pairs of points,
|
|
1063
|
+
it is not always possibleto distinguish them, using this algorithm.
|
|
1064
|
+
|
|
1065
|
+
ALGORITHM:
|
|
1066
|
+
|
|
1067
|
+
Refer to Section 6: "An algorithm to compute `\sigma_x`, `\sigma_y`, `\phi`,
|
|
1068
|
+
and `\psi`" in [CS1996FH2015.
|
|
1069
|
+
For the degenerate case refer to [FH2015]_.
|
|
1070
|
+
|
|
1071
|
+
INPUT:
|
|
1072
|
+
|
|
1073
|
+
- ``P`` -- a point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
1074
|
+
|
|
1075
|
+
kwds:
|
|
1076
|
+
|
|
1077
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
1078
|
+
|
|
1079
|
+
- ``normalize`` -- boolean (default: ``True``); normalizes the point
|
|
1080
|
+
|
|
1081
|
+
OUTPUT: a point on the K3 surface
|
|
1082
|
+
|
|
1083
|
+
EXAMPLES::
|
|
1084
|
+
|
|
1085
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1086
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 +\
|
|
1087
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -\
|
|
1088
|
+
....: 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 +\
|
|
1089
|
+
....: 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1090
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1091
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1092
|
+
sage: T = PP(0, 0, 1, 1, 0, 0)
|
|
1093
|
+
sage: X.sigmaX(T)
|
|
1094
|
+
(0 : 0 : 1 , 0 : 1 : 0)
|
|
1095
|
+
|
|
1096
|
+
degenerate examples::
|
|
1097
|
+
|
|
1098
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1099
|
+
sage: l = y0*x0 + y1*x1 + (y0 - y1)*x2
|
|
1100
|
+
sage: q = (y1*y0)*x0^2 + ((y0^2)*x1 + (y0^2 + (y1^2 - y2^2))*x2)*x0\
|
|
1101
|
+
....: + (y2*y0 + y1^2)*x1^2 + (y0^2 + (-y1^2 + y2^2))*x2*x1
|
|
1102
|
+
sage: X = WehlerK3Surface([l, q])
|
|
1103
|
+
sage: X.sigmaX(X([1, 0, 0, 0, 1, -2]))
|
|
1104
|
+
(1 : 0 : 0 , 0 : 1/2 : 1)
|
|
1105
|
+
sage: X.sigmaX(X([1, 0, 0, 0, 0, 1]))
|
|
1106
|
+
(1 : 0 : 0 , 0 : 0 : 1)
|
|
1107
|
+
sage: X.sigmaX(X([-1, 1, 1, -1, -1, 1]))
|
|
1108
|
+
(-1 : 1 : 1 , 2 : 2 : 1)
|
|
1109
|
+
sage: X.sigmaX(X([0, 0, 1, 1, 1, 0]))
|
|
1110
|
+
(0 : 0 : 1 , 1 : 1 : 0)
|
|
1111
|
+
sage: X.sigmaX(X([0, 0, 1, 1, 1, 1]))
|
|
1112
|
+
(0 : 0 : 1 , -1 : -1 : 1)
|
|
1113
|
+
|
|
1114
|
+
Case where we cannot distinguish the two points::
|
|
1115
|
+
|
|
1116
|
+
sage: PP.<y0,y1,y2,x0,x1,x2>=ProductProjectiveSpaces([2, 2], GF(3))
|
|
1117
|
+
sage: l = x0*y0 + x1*y1 + x2*y2
|
|
1118
|
+
sage: q = (-3*x0^2*y0^2 + 4*x0*x1*y0^2 - 3*x0*x2*y0^2 - 5*x0^2*y0*y1
|
|
1119
|
+
....: - 190*x0*x1*y0*y1 - 5*x1^2*y0*y1 + 5*x0*x2*y0*y1 + 14*x1*x2*y0*y1
|
|
1120
|
+
....: + 5*x2^2*y0*y1 - x0^2*y1^2 - 6*x0*x1*y1^2 - 2*x1^2*y1^2
|
|
1121
|
+
....: + 2*x0*x2*y1^2 - 4*x2^2*y1^2 + 4*x0^2*y0*y2 - x1^2*y0*y2
|
|
1122
|
+
....: + 3*x0*x2*y0*y2 + 6*x1*x2*y0*y2 - 6*x0^2*y1*y2 - 4*x0*x1*y1*y2
|
|
1123
|
+
....: - x1^2*y1*y2 + 51*x0*x2*y1*y2 - 7*x1*x2*y1*y2 - 9*x2^2*y1*y2
|
|
1124
|
+
....: - x0^2*y2^2 - 4*x0*x1*y2^2 + 4*x1^2*y2^2 - x0*x2*y2^2
|
|
1125
|
+
....: + 13*x1*x2*y2^2 - x2^2*y2^2)
|
|
1126
|
+
sage: X = WehlerK3Surface([l, q])
|
|
1127
|
+
sage: P = X([1, 0, 0, 0, 1, 1])
|
|
1128
|
+
sage: X.sigmaX(X.sigmaX(P))
|
|
1129
|
+
Traceback (most recent call last):
|
|
1130
|
+
...
|
|
1131
|
+
ValueError: cannot distinguish points in the degenerate fiber
|
|
1132
|
+
"""
|
|
1133
|
+
check = kwds.get("check", True)
|
|
1134
|
+
normalize = kwds.get("normalize", True)
|
|
1135
|
+
|
|
1136
|
+
if check:
|
|
1137
|
+
if self != P.codomain():
|
|
1138
|
+
try:
|
|
1139
|
+
P = self(list(P))
|
|
1140
|
+
except (TypeError, NotImplementedError, AttributeError):
|
|
1141
|
+
raise TypeError("%s fails to convert into the map's domain %s, but a `pushforward` method is not properly implemented" % (P, self))
|
|
1142
|
+
pt = list(P[0]) + [0, 0, 0]
|
|
1143
|
+
if P[1][0] != 0:
|
|
1144
|
+
a, b, c = [P[1][0]*self.Gpoly(1, 0)(*pt),
|
|
1145
|
+
-1*P[1][0]*self.Hpoly(1, 0, 1)(*pt) - P[1][1]*self.Gpoly(1, 0)(*pt),
|
|
1146
|
+
-P[1][0]*self.Hpoly(1, 0, 2)(*pt) - P[1][2]*self.Gpoly(1, 0)(*pt)]
|
|
1147
|
+
elif P[1][1] != 0:
|
|
1148
|
+
a, b, c = [-1*P[1][1]*self.Hpoly(1, 0, 1)(*pt)-P[1][0]*self.Gpoly(1, 1)(*pt),
|
|
1149
|
+
P[1][1]*self.Gpoly(1, 1)(*pt),
|
|
1150
|
+
-P[1][1]*self.Hpoly(1, 1, 2)(*pt)-P[1][2]*self.Gpoly(1, 1)(*pt)]
|
|
1151
|
+
else:
|
|
1152
|
+
a, b, c = [-1*P[1][2]*self.Hpoly(1, 0, 2)(*pt) - P[1][0]*self.Gpoly(1, 2)(*pt),
|
|
1153
|
+
-P[1][2]*self.Hpoly(1, 1, 2)(*pt) - P[1][1]*self.Gpoly(1, 2)(*pt),
|
|
1154
|
+
P[1][2]*self.Gpoly(1, 2)(*pt)]
|
|
1155
|
+
Point = [P[0][0], P[0][1], P[0][2], a, b, c]
|
|
1156
|
+
|
|
1157
|
+
if any([a, b, c]):
|
|
1158
|
+
if normalize:
|
|
1159
|
+
Point = self.point(Point,False)
|
|
1160
|
+
Point.normalize_coordinates()
|
|
1161
|
+
return Point
|
|
1162
|
+
return self.point(Point,False)
|
|
1163
|
+
#Start of the degenerate case
|
|
1164
|
+
R = self.ambient_space().coordinate_ring()
|
|
1165
|
+
BR = self.ambient_space().base_ring()
|
|
1166
|
+
S = PolynomialRing(BR, 6, 's0, s1, w1, z0, z1, z2')
|
|
1167
|
+
s0,s1,w1,z0,z1,z2 = S.gens()
|
|
1168
|
+
#Define the blow-up map with (s0,s1) the new `\mathbb{P}^1` coordinates
|
|
1169
|
+
#so that the points on the fiber come in pairs on the lines defined by `(s0,s1)`
|
|
1170
|
+
#this allows us to extend the involution to degenerate fibers
|
|
1171
|
+
if P[0][0] != 0:
|
|
1172
|
+
t1 = BR(P[0][1]/P[0][0])
|
|
1173
|
+
t = w1 - t1
|
|
1174
|
+
phi = R.hom([s0, s0*w1, s1*t + s0*P[0][2]/P[0][0], z0, z1, z2], S)
|
|
1175
|
+
elif P[0][1] != 0:
|
|
1176
|
+
t1 = BR(P[0][0]/P[0][1])
|
|
1177
|
+
t = w1 - t1
|
|
1178
|
+
phi = R.hom([s0*w1, s0, s1*t + s0*P[0][2]/P[0][1], z0, z1, z2], S)
|
|
1179
|
+
else:
|
|
1180
|
+
t1 = BR(P[0][1]/P[0][2])
|
|
1181
|
+
t = w1 - t1
|
|
1182
|
+
phi = R.hom([s1*(t) + s0*P[0][0]/P[0][2], s0*w1, s0, z0, z1, z2], S)
|
|
1183
|
+
|
|
1184
|
+
# Blow-up the fiber
|
|
1185
|
+
T = [phi(self.L),phi(self.Q),
|
|
1186
|
+
phi(self.Gpoly(1, 0)),
|
|
1187
|
+
phi(self.Gpoly(1, 1)),
|
|
1188
|
+
phi(self.Gpoly(1, 2)),
|
|
1189
|
+
-phi(self.Hpoly(1, 0, 1)),
|
|
1190
|
+
-phi(self.Hpoly(1, 0, 2)),
|
|
1191
|
+
-phi(self.Hpoly(1, 1, 2))]
|
|
1192
|
+
maxexp = []
|
|
1193
|
+
|
|
1194
|
+
#Find highest exponent that we can divide out by to get a nonzero answer
|
|
1195
|
+
for i in range(2,len(T)):
|
|
1196
|
+
e = 0
|
|
1197
|
+
while (T[i]/t**e).subs({w1:t1}) == 0:
|
|
1198
|
+
e += 1
|
|
1199
|
+
maxexp.append(e)
|
|
1200
|
+
|
|
1201
|
+
e = min(maxexp)
|
|
1202
|
+
|
|
1203
|
+
#Fix L and Q
|
|
1204
|
+
for i in range(2):
|
|
1205
|
+
while T[i].subs({w1:t1}) == 0:
|
|
1206
|
+
T[i] = T[i]/t
|
|
1207
|
+
T[i] = T[i].subs({w1:t1})
|
|
1208
|
+
|
|
1209
|
+
#Fix G and H polys
|
|
1210
|
+
for i in range(2,len(T)):
|
|
1211
|
+
T[i] = T[i]/t**e
|
|
1212
|
+
T[i] = T[i].subs({w1:t1})
|
|
1213
|
+
|
|
1214
|
+
#Defines the ideal whose solution gives `(s0, s1)` and the two points
|
|
1215
|
+
#on the fiber
|
|
1216
|
+
RR = PolynomialRing(BR, 5,'s0, s1, z0, z1, z2',order='lex')
|
|
1217
|
+
s0, s1, z0, z1, z2 = RR.gens()
|
|
1218
|
+
I = RR.ideal([RR(T[0]),
|
|
1219
|
+
RR(T[1]),
|
|
1220
|
+
RR(T[2]) - P[1][0]*z0, RR(T[3]) - P[1][1]*z1, RR(T[4])-P[1][2]*z2,
|
|
1221
|
+
RR(T[5]) - (P[1][0]*z1 + P[1][1]*z0),
|
|
1222
|
+
RR(T[6]) - (P[1][0]*z2 + P[1][2]*z0),
|
|
1223
|
+
RR(T[7]) - (P[1][1]*z2 + P[1][2]*z1)])
|
|
1224
|
+
|
|
1225
|
+
#Find the points
|
|
1226
|
+
SS = PolynomialRing(BR, 4,'s, z0, z1, z2', order='lex')
|
|
1227
|
+
s, z0, z1, z2 = SS.gens()
|
|
1228
|
+
phi = RR.hom([s, 1, z0, z1, z2], SS)
|
|
1229
|
+
J = phi(I)
|
|
1230
|
+
if J.dimension() > 0:
|
|
1231
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1232
|
+
V = J.variety()
|
|
1233
|
+
#Our blow-up point has more than one line passing through it, thus we cannot find
|
|
1234
|
+
#the corresponding point on the surface
|
|
1235
|
+
if len(V) > 2:
|
|
1236
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1237
|
+
#We always expect to have the trivial solution (0, 0, 0)
|
|
1238
|
+
if len(V) == 2:
|
|
1239
|
+
for D in V:
|
|
1240
|
+
if D[s] != 0:
|
|
1241
|
+
a, b, c = [D[z0], D[z1], D[z2]]
|
|
1242
|
+
else:
|
|
1243
|
+
newT = [phi(tee) for tee in T]
|
|
1244
|
+
for i in range(2):
|
|
1245
|
+
while newT[i] != 0 and s.divides(newT[i]):
|
|
1246
|
+
newT[i] = SS(newT[i]/s)
|
|
1247
|
+
maxexp = []
|
|
1248
|
+
|
|
1249
|
+
for i in range(2, len(T)):
|
|
1250
|
+
e = 0
|
|
1251
|
+
if newT[i] != 0:
|
|
1252
|
+
while (newT[i]/s**e).subs({s:0}) == 0:
|
|
1253
|
+
e += 1
|
|
1254
|
+
maxexp.append(e)
|
|
1255
|
+
e = min(maxexp)
|
|
1256
|
+
|
|
1257
|
+
#Cancel the powers of s
|
|
1258
|
+
for i in range(2,len(T)):
|
|
1259
|
+
newT[i] = newT[i]/s**e
|
|
1260
|
+
#Create the new ideal
|
|
1261
|
+
II = SS.ideal([SS(newT[0]),
|
|
1262
|
+
SS(newT[1]),
|
|
1263
|
+
SS(newT[2]) - P[1][0]*z0,
|
|
1264
|
+
SS(newT[3]) - P[1][1]*z1,
|
|
1265
|
+
SS(newT[4]) - P[1][2]*z2,
|
|
1266
|
+
SS(newT[5]) - (P[1][0]*z1 + P[1][1]*z0),
|
|
1267
|
+
SS(newT[6]) - (P[1][0]*z2 + P[1][2]*z0),
|
|
1268
|
+
SS(newT[7]) - (P[1][1]*z2 + P[1][2]*z1)])
|
|
1269
|
+
|
|
1270
|
+
#Find the points
|
|
1271
|
+
SSS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex')
|
|
1272
|
+
z0,z1,z2 = SSS.gens()
|
|
1273
|
+
phi = SS.hom([0, z0, z1, z2], SSS)
|
|
1274
|
+
J2 = phi(II)
|
|
1275
|
+
if J2.dimension() > 0:
|
|
1276
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1277
|
+
V = J2.variety()
|
|
1278
|
+
if len(V) > 1:
|
|
1279
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1280
|
+
|
|
1281
|
+
if len(V) == 1:
|
|
1282
|
+
a, b, c = [V[0][z0], V[0][z1], V[0][z2]]
|
|
1283
|
+
|
|
1284
|
+
if len(V) == 0 or not any([a, b, c]):
|
|
1285
|
+
SS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex')
|
|
1286
|
+
z0,z1,z2 = SS.gens()
|
|
1287
|
+
phi = RR.hom([1, 0, z0, z1, z2], SS)
|
|
1288
|
+
J = phi(I)
|
|
1289
|
+
if J.dimension() > 0:
|
|
1290
|
+
raise ValueError( "cannot distinguish points in the degenerate fiber")
|
|
1291
|
+
V = phi(I).variety()
|
|
1292
|
+
if len(V) > 1:
|
|
1293
|
+
raise ValueError( "cannot distinguish points in the degenerate fiber")
|
|
1294
|
+
a, b, c = [V[0][z0], V[0][z1], V[0][z2]]
|
|
1295
|
+
|
|
1296
|
+
Point = [P[0][0], P[0][1], P[0][2], a, b, c]
|
|
1297
|
+
if normalize:
|
|
1298
|
+
Point = self.point(Point, False)
|
|
1299
|
+
Point.normalize_coordinates()
|
|
1300
|
+
return Point
|
|
1301
|
+
return self.point(Point, False)
|
|
1302
|
+
|
|
1303
|
+
def sigmaY(self, P, **kwds):
|
|
1304
|
+
r"""
|
|
1305
|
+
Return the involution on the Wehler K3 surfaces induced by the double covers.
|
|
1306
|
+
|
|
1307
|
+
In particular, it fixes the projection to the second coordinate and swaps
|
|
1308
|
+
the two points in the fiber, i.e. `(x,y) \to (x',y)`.
|
|
1309
|
+
Note that in the degenerate case, while we can split the fiber into two points,
|
|
1310
|
+
it is not always possible to distinguish them, using this algorithm.
|
|
1311
|
+
|
|
1312
|
+
ALGORITHM:
|
|
1313
|
+
|
|
1314
|
+
Refer to Section 6: "An algorithm to compute `\sigma_x`, `\sigma_y`, `\phi`,
|
|
1315
|
+
and `\psi`" in [CS1996]_.
|
|
1316
|
+
For the degenerate case refer to [FH2015]_.
|
|
1317
|
+
|
|
1318
|
+
INPUT:
|
|
1319
|
+
|
|
1320
|
+
- ``P`` -- a point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
1321
|
+
|
|
1322
|
+
kwds:
|
|
1323
|
+
|
|
1324
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
1325
|
+
|
|
1326
|
+
- ``normalize`` -- boolean (default: ``True``); normalizes the point
|
|
1327
|
+
|
|
1328
|
+
OUTPUT: a point on the K3 surface
|
|
1329
|
+
|
|
1330
|
+
EXAMPLES::
|
|
1331
|
+
|
|
1332
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1333
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
1334
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
1335
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
1336
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1337
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1338
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1339
|
+
sage: T = PP(0, 0, 1, 1, 0, 0)
|
|
1340
|
+
sage: X.sigmaY(T)
|
|
1341
|
+
(0 : 0 : 1 , 1 : 0 : 0)
|
|
1342
|
+
|
|
1343
|
+
degenerate examples::
|
|
1344
|
+
|
|
1345
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1346
|
+
sage: l = y0*x0 + y1*x1 + (y0 - y1)*x2
|
|
1347
|
+
sage: q = (y1*y0)*x0^2 + ((y0^2)*x1 + (y0^2 + (y1^2 - y2^2))*x2)*x0 +\
|
|
1348
|
+
....: (y2*y0 + y1^2)*x1^2 + (y0^2 + (-y1^2 + y2^2))*x2*x1
|
|
1349
|
+
sage: X = WehlerK3Surface([l, q])
|
|
1350
|
+
sage: X.sigmaY(X([1, -1, 0 ,-1, -1, 1]))
|
|
1351
|
+
(1/10 : -1/10 : 1 , -1 : -1 : 1)
|
|
1352
|
+
sage: X.sigmaY(X([0, 0, 1, -1, -1, 1]))
|
|
1353
|
+
(-4 : 4 : 1 , -1 : -1 : 1)
|
|
1354
|
+
sage: X.sigmaY(X([1, 2, 0, 0, 0, 1]))
|
|
1355
|
+
(-3 : -3 : 1 , 0 : 0 : 1)
|
|
1356
|
+
sage: X.sigmaY(X([1, 1, 1, 0, 0, 1]))
|
|
1357
|
+
(1 : 0 : 0 , 0 : 0 : 1)
|
|
1358
|
+
|
|
1359
|
+
Case where we cannot distinguish the two points::
|
|
1360
|
+
|
|
1361
|
+
sage: PP.<x0,x1,x2,y0,y1,y2>=ProductProjectiveSpaces([2, 2], GF(3))
|
|
1362
|
+
sage: l = x0*y0 + x1*y1 + x2*y2
|
|
1363
|
+
sage: q = (-3*x0^2*y0^2 + 4*x0*x1*y0^2 - 3*x0*x2*y0^2 - 5*x0^2*y0*y1
|
|
1364
|
+
....: - 190*x0*x1*y0*y1 - 5*x1^2*y0*y1 + 5*x0*x2*y0*y1 + 14*x1*x2*y0*y1
|
|
1365
|
+
....: + 5*x2^2*y0*y1 - x0^2*y1^2 - 6*x0*x1*y1^2 - 2*x1^2*y1^2 + 2*x0*x2*y1^2
|
|
1366
|
+
....: - 4*x2^2*y1^2 + 4*x0^2*y0*y2 - x1^2*y0*y2 + 3*x0*x2*y0*y2
|
|
1367
|
+
....: + 6*x1*x2*y0*y2 - 6*x0^2*y1*y2 - 4*x0*x1*y1*y2 - x1^2*y1*y2
|
|
1368
|
+
....: + 51*x0*x2*y1*y2 - 7*x1*x2*y1*y2 - 9*x2^2*y1*y2 - x0^2*y2^2
|
|
1369
|
+
....: - 4*x0*x1*y2^2 + 4*x1^2*y2^2 - x0*x2*y2^2 + 13*x1*x2*y2^2 - x2^2*y2^2)
|
|
1370
|
+
sage: X = WehlerK3Surface([l ,q])
|
|
1371
|
+
sage: P = X([0, 1, 1, 1, 0, 0])
|
|
1372
|
+
sage: X.sigmaY(X.sigmaY(P))
|
|
1373
|
+
Traceback (most recent call last):
|
|
1374
|
+
...
|
|
1375
|
+
ValueError: cannot distinguish points in the degenerate fiber
|
|
1376
|
+
"""
|
|
1377
|
+
check = kwds.get("check", True)
|
|
1378
|
+
normalize = kwds.get("normalize", True)
|
|
1379
|
+
|
|
1380
|
+
if check:
|
|
1381
|
+
if self != P.codomain():
|
|
1382
|
+
try:
|
|
1383
|
+
P = self(list(P))
|
|
1384
|
+
except (TypeError, NotImplementedError, AttributeError):
|
|
1385
|
+
raise TypeError("%s fails to convert into the map's domain %s, but a `pushforward` method is not properly implemented" % (P, self))
|
|
1386
|
+
pt = [0, 0, 0] + list(P[1])
|
|
1387
|
+
if P[0][0] != 0:
|
|
1388
|
+
a, b, c = [P[0][0]*self.Gpoly(0, 0)(*pt),
|
|
1389
|
+
-1*P[0][0]*self.Hpoly(0, 0, 1)(*pt) - P[0][1]*self.Gpoly(0, 0)(*pt),
|
|
1390
|
+
-P[0][0]*self.Hpoly(0, 0, 2)(*pt) - P[0][2]*self.Gpoly(0, 0)(*pt)]
|
|
1391
|
+
elif P[0][1] != 0:
|
|
1392
|
+
a, b, c = [-1*P[0][1]*self.Hpoly(0, 0, 1)(*pt) - P[0][0]*self.Gpoly(0, 1)(*pt),
|
|
1393
|
+
P[0][1]*self.Gpoly(0, 1)(*pt),
|
|
1394
|
+
-P[0][1]*self.Hpoly(0, 1, 2)(*pt) - P[0][2]*self.Gpoly(0, 1)(*pt)]
|
|
1395
|
+
else:
|
|
1396
|
+
a, b, c = [-1*P[0][2]*self.Hpoly(0, 0, 2)(*pt) - P[0][0]*self.Gpoly(0, 2)(*pt),
|
|
1397
|
+
- P[0][2]*self.Hpoly(0, 1, 2)(*pt) - P[0][1]*self.Gpoly(0, 2)(*pt),
|
|
1398
|
+
P[0][2]*self.Gpoly(0, 2)(*pt)]
|
|
1399
|
+
Point = [a, b, c, P[1][0], P[1][1], P[1][2]]
|
|
1400
|
+
if any([a, b, c]):
|
|
1401
|
+
if normalize:
|
|
1402
|
+
Point = self.point(Point, False)
|
|
1403
|
+
Point.normalize_coordinates()
|
|
1404
|
+
return Point
|
|
1405
|
+
return self.point(Point, False)
|
|
1406
|
+
|
|
1407
|
+
#Start of the degenerate case
|
|
1408
|
+
R = self.ambient_space().coordinate_ring()
|
|
1409
|
+
BR = self.ambient_space().base_ring()
|
|
1410
|
+
S = PolynomialRing(BR, 6, 'z0, z1, z2, s0, s1, w1')
|
|
1411
|
+
z0, z1, z2, s0, s1, w1 = S.gens()
|
|
1412
|
+
#Define the blow-up map with (s0,s1) the new `\mathbb{P}^1` coordinates
|
|
1413
|
+
#so that the points on the fiber come in pairs on the lines defined by `(s0,s1)`
|
|
1414
|
+
#this allows us to extend the involution to degenerate fibers
|
|
1415
|
+
if P[1][0] != 0:
|
|
1416
|
+
t1 = BR(P[1][1]/P[1][0])
|
|
1417
|
+
t = w1 - t1
|
|
1418
|
+
phi = R.hom([z0, z1, z2, s0, s0*w1, s1*t + s0*P[1][2]/P[1][0]], S)
|
|
1419
|
+
elif P[1][1] != 0:
|
|
1420
|
+
t1 = BR(P[1][0]/P[1][1])
|
|
1421
|
+
t = w1 - t1
|
|
1422
|
+
phi = R.hom([z0, z1, z2, s0*w1, s0, s1*t + s0*P[1][2]/P[1][1]], S)
|
|
1423
|
+
else:
|
|
1424
|
+
t1 = BR(P[1][1]/P[1][2])
|
|
1425
|
+
t = w1 - t1
|
|
1426
|
+
phi = R.hom([z0, z1, z2, s1*(t) + s0*P[1][0]/P[1][2], s0*w1, s0], S)
|
|
1427
|
+
|
|
1428
|
+
#Blow-up the fiber
|
|
1429
|
+
T = [phi(self.L),
|
|
1430
|
+
phi(self.Q),
|
|
1431
|
+
phi(self.Gpoly(0, 0)),
|
|
1432
|
+
phi(self.Gpoly(0, 1)),
|
|
1433
|
+
phi(self.Gpoly(0, 2)),
|
|
1434
|
+
-phi(self.Hpoly(0, 0, 1)),
|
|
1435
|
+
-phi(self.Hpoly(0, 0, 2)),
|
|
1436
|
+
-phi(self.Hpoly(0, 1, 2))]
|
|
1437
|
+
maxexp = []
|
|
1438
|
+
|
|
1439
|
+
# Find highest exponent that we can divide out by to get a
|
|
1440
|
+
# nonzero answer
|
|
1441
|
+
for i in range(2, len(T)):
|
|
1442
|
+
e = 0
|
|
1443
|
+
while (T[i]/t**e).subs({w1:t1}) == 0:
|
|
1444
|
+
e += 1
|
|
1445
|
+
maxexp.append(e)
|
|
1446
|
+
|
|
1447
|
+
e = min(maxexp)
|
|
1448
|
+
|
|
1449
|
+
for i in range(2):
|
|
1450
|
+
while T[i].subs({w1:t1}) == 0:
|
|
1451
|
+
T[i] = T[i]/t
|
|
1452
|
+
T[i] = T[i].subs({w1:t1})
|
|
1453
|
+
for i in range(2, len(T)):
|
|
1454
|
+
T[i] = T[i]/t**e
|
|
1455
|
+
T[i] = T[i].subs({w1:t1})
|
|
1456
|
+
|
|
1457
|
+
# Defines the ideal whose solution gives `(s0,s1)` and the two points
|
|
1458
|
+
# on the fiber
|
|
1459
|
+
RR = PolynomialRing(BR, 5, 's0, s1, z0, z1, z2', order='lex')
|
|
1460
|
+
s0, s1, z0, z1, z2 = RR.gens()
|
|
1461
|
+
I = RR.ideal([RR(T[0]),
|
|
1462
|
+
RR(T[1]),
|
|
1463
|
+
RR(T[2]) - P[0][0]*z0,
|
|
1464
|
+
RR(T[3]) - P[0][1]*z1,
|
|
1465
|
+
RR(T[4]) - P[0][2]*z2,
|
|
1466
|
+
RR(T[5]) - (P[0][0]*z1 + P[0][1]*z0),
|
|
1467
|
+
RR(T[6]) - (P[0][0]*z2 + P[0][2]*z0),
|
|
1468
|
+
RR(T[7]) - (P[0][1]*z2 + P[0][2]*z1)])
|
|
1469
|
+
#Find the points
|
|
1470
|
+
SS = PolynomialRing(BR, 4, 's, z0, z1, z2', order='lex')
|
|
1471
|
+
s, z0, z1, z2 = SS.gens()
|
|
1472
|
+
phi = RR.hom([s, 1, z0, z1, z2], SS)
|
|
1473
|
+
J = phi(I)
|
|
1474
|
+
if J.dimension() > 0:
|
|
1475
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1476
|
+
V = J.variety()
|
|
1477
|
+
|
|
1478
|
+
#Our blow-up point has more than one line passing through it, thus we cannot find
|
|
1479
|
+
#the corresponding point on the surface
|
|
1480
|
+
if len(V) > 2:
|
|
1481
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1482
|
+
# We always expect to have the trivial solution (0, 0, 0)
|
|
1483
|
+
if len(V) == 2:
|
|
1484
|
+
for D in V:
|
|
1485
|
+
if D[s] != 0:
|
|
1486
|
+
a, b, c = [D[z0], D[z1], D[z2]]
|
|
1487
|
+
else:
|
|
1488
|
+
newT = [phi(tee) for tee in T]
|
|
1489
|
+
for i in range(2):
|
|
1490
|
+
while newT[i] != 0 and s.divides(newT[i]):
|
|
1491
|
+
newT[i] = SS(newT[i]/s)
|
|
1492
|
+
maxexp = []
|
|
1493
|
+
for i in range(2, len(T)):
|
|
1494
|
+
e = 0
|
|
1495
|
+
if newT[i] != 0:
|
|
1496
|
+
while (newT[i]/s**e).subs({s:0}) == 0:
|
|
1497
|
+
e += 1
|
|
1498
|
+
maxexp.append(e)
|
|
1499
|
+
e = min(maxexp)
|
|
1500
|
+
#Cancel out the powers of s
|
|
1501
|
+
for i in range(2,len(T)):
|
|
1502
|
+
newT[i] = newT[i]/s**e
|
|
1503
|
+
#Create the new ideal
|
|
1504
|
+
II = SS.ideal([SS(newT[0]),
|
|
1505
|
+
SS(newT[1]),
|
|
1506
|
+
SS(newT[2]) - P[0][0]*z0,
|
|
1507
|
+
SS(newT[3]) - P[0][1]*z1,
|
|
1508
|
+
SS(newT[4]) - P[0][2]*z2,
|
|
1509
|
+
SS(newT[5]) - (P[0][0]*z1 + P[0][1]*z0),
|
|
1510
|
+
SS(newT[6]) - (P[0][0]*z2 + P[0][2]*z0),
|
|
1511
|
+
SS(newT[7]) - (P[0][1]*z2 + P[0][2]*z1)])
|
|
1512
|
+
# Find the points
|
|
1513
|
+
SSS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex')
|
|
1514
|
+
z0, z1, z2 = SSS.gens()
|
|
1515
|
+
phi = SS.hom([0, z0, z1, z2], SSS)
|
|
1516
|
+
J2 = phi(II)
|
|
1517
|
+
if J2.dimension() > 0:
|
|
1518
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1519
|
+
V = J2.variety()
|
|
1520
|
+
|
|
1521
|
+
if len(V) > 1:
|
|
1522
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1523
|
+
if len(V) == 1:
|
|
1524
|
+
a, b, c = [V[0][z0], V[0][z1], V[0][z2]]
|
|
1525
|
+
if len(V) == 0 or not any([a, b, c]):
|
|
1526
|
+
SS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex')
|
|
1527
|
+
z0, z1, z2 = SS.gens()
|
|
1528
|
+
phi = RR.hom([1, 0, z0, z1, z2], SS)
|
|
1529
|
+
J = phi(I)
|
|
1530
|
+
if J.dimension() > 0:
|
|
1531
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1532
|
+
V = phi(I).variety()
|
|
1533
|
+
if len(V) > 1:
|
|
1534
|
+
raise ValueError("cannot distinguish points in the degenerate fiber")
|
|
1535
|
+
a, b, c = [V[0][z0], V[0][z1], V[0][z2]]
|
|
1536
|
+
|
|
1537
|
+
Point = [a, b, c, P[1][0], P[1][1], P[1][2]]
|
|
1538
|
+
if normalize:
|
|
1539
|
+
Point = self.point(Point, False)
|
|
1540
|
+
Point.normalize_coordinates()
|
|
1541
|
+
return Point
|
|
1542
|
+
return self.point(Point, False)
|
|
1543
|
+
|
|
1544
|
+
def phi(self, a, **kwds):
|
|
1545
|
+
r"""
|
|
1546
|
+
Evaluates the function `\phi = \sigma_y \circ \sigma_x`.
|
|
1547
|
+
|
|
1548
|
+
ALGORITHM:
|
|
1549
|
+
|
|
1550
|
+
Refer to Section 6: "An algorithm to compute `\sigma_x`, `\sigma_y`,
|
|
1551
|
+
`\phi`, and `\psi`" in [CS1996]_.
|
|
1552
|
+
|
|
1553
|
+
For the degenerate case refer to [FH2015]_.
|
|
1554
|
+
|
|
1555
|
+
INPUT:
|
|
1556
|
+
|
|
1557
|
+
- ``a`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
1558
|
+
|
|
1559
|
+
kwds:
|
|
1560
|
+
|
|
1561
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
1562
|
+
|
|
1563
|
+
- ``normalize`` -- boolean (default: ``True``); normalizes the point
|
|
1564
|
+
|
|
1565
|
+
OUTPUT: a point on this surface
|
|
1566
|
+
|
|
1567
|
+
EXAMPLES::
|
|
1568
|
+
|
|
1569
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1570
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
1571
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
1572
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
1573
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1574
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1575
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1576
|
+
sage: T = PP([0, 0, 1, 1 ,0, 0])
|
|
1577
|
+
sage: X.phi(T)
|
|
1578
|
+
(-1 : 0 : 1 , 0 : 1 : 0)
|
|
1579
|
+
"""
|
|
1580
|
+
A = self.sigmaX(a, **kwds)
|
|
1581
|
+
kwds.update({"check":False})
|
|
1582
|
+
return self.sigmaY(A, **kwds)
|
|
1583
|
+
|
|
1584
|
+
def psi(self, a, **kwds):
|
|
1585
|
+
r"""
|
|
1586
|
+
Evaluates the function `\psi = \sigma_x \circ \sigma_y`.
|
|
1587
|
+
|
|
1588
|
+
ALGORITHM:
|
|
1589
|
+
|
|
1590
|
+
Refer to Section 6: "An algorithm to compute `\sigma_x`, `\sigma_y`,
|
|
1591
|
+
`\phi`, and `\psi`" in [CS1996]_.
|
|
1592
|
+
|
|
1593
|
+
For the degenerate case refer to [FH2015]_.
|
|
1594
|
+
|
|
1595
|
+
INPUT:
|
|
1596
|
+
|
|
1597
|
+
- ``a`` -- point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
1598
|
+
|
|
1599
|
+
kwds:
|
|
1600
|
+
|
|
1601
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
1602
|
+
|
|
1603
|
+
- ``normalize`` -- boolean (default: ``True``); normalizes the point
|
|
1604
|
+
|
|
1605
|
+
OUTPUT: a point on this surface
|
|
1606
|
+
|
|
1607
|
+
EXAMPLES::
|
|
1608
|
+
|
|
1609
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1610
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
1611
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
1612
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
1613
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1614
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1615
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1616
|
+
sage: T = PP([0, 0, 1, 1, 0, 0])
|
|
1617
|
+
sage: X.psi(T)
|
|
1618
|
+
(0 : 0 : 1 , 0 : 1 : 0)
|
|
1619
|
+
"""
|
|
1620
|
+
A = self.sigmaY(a, **kwds)
|
|
1621
|
+
kwds.update({"check":False})
|
|
1622
|
+
return self.sigmaX(A, **kwds)
|
|
1623
|
+
|
|
1624
|
+
def lambda_plus(self, P, v, N, m, n, prec=100):
|
|
1625
|
+
r"""
|
|
1626
|
+
Evaluates the local canonical height plus function of Call-Silverman at
|
|
1627
|
+
the place ``v`` for ``P`` with ``N`` terms of the series.
|
|
1628
|
+
|
|
1629
|
+
Use ``v = 0`` for the archimedean place. Must be over `\ZZ` or `\QQ`.
|
|
1630
|
+
|
|
1631
|
+
ALGORITHM:
|
|
1632
|
+
|
|
1633
|
+
Sum over local heights using convergent series, for more details,
|
|
1634
|
+
see section 4 of [CS1996]_.
|
|
1635
|
+
|
|
1636
|
+
INPUT:
|
|
1637
|
+
|
|
1638
|
+
- ``P`` -- a surface point
|
|
1639
|
+
|
|
1640
|
+
- ``N`` -- positive integer; number of terms of the series to use
|
|
1641
|
+
|
|
1642
|
+
- ``v`` -- nonnegative integer; a place, use v = 0 for the Archimedean place
|
|
1643
|
+
|
|
1644
|
+
- ``m``, ``n`` -- positive integers; we compute the local height for
|
|
1645
|
+
the divisor `E_{mn}^{+}`. These must be indices of nonzero
|
|
1646
|
+
coordinates of the point ``P``
|
|
1647
|
+
|
|
1648
|
+
- ``prec`` -- (default: 100) float point or `p`-adic precision
|
|
1649
|
+
|
|
1650
|
+
OUTPUT: a real number
|
|
1651
|
+
|
|
1652
|
+
EXAMPLES::
|
|
1653
|
+
|
|
1654
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1655
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1\
|
|
1656
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -4*x1*x2*y1^2 + 5*x0*x2*y0*y2\
|
|
1657
|
+
....: - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1658
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1659
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1660
|
+
sage: P = X([0, 0, 1, 1, 0, 0])
|
|
1661
|
+
sage: X.lambda_plus(P, 0, 10, 2, 0) # needs sage.symbolic
|
|
1662
|
+
0.89230705169161608922595928129
|
|
1663
|
+
"""
|
|
1664
|
+
if not (v == 0 or v.is_prime()):
|
|
1665
|
+
raise ValueError("invalid valuation (= %s) entered" % v)
|
|
1666
|
+
R = RealField(prec)
|
|
1667
|
+
if v == 0:
|
|
1668
|
+
K = R
|
|
1669
|
+
else:
|
|
1670
|
+
K = Qp(v, prec)
|
|
1671
|
+
PK = P.change_ring(K)
|
|
1672
|
+
W = self.change_ring(K)
|
|
1673
|
+
Rx = W.ambient_space().coordinate_ring().hom(
|
|
1674
|
+
list(W.ambient_space()[0].coordinate_ring().gens()) + [0, 0, 0],
|
|
1675
|
+
W.ambient_space()[0].coordinate_ring())
|
|
1676
|
+
Ry = W.ambient_space().coordinate_ring().hom(
|
|
1677
|
+
[0, 0, 0] + list(W.ambient_space()[1].coordinate_ring().gens()),
|
|
1678
|
+
W.ambient_space()[1].coordinate_ring())
|
|
1679
|
+
beta = R(2 + sqrt(3))
|
|
1680
|
+
L = [x.abs() for x in list(PK[0])]
|
|
1681
|
+
i = L.index(max(L))
|
|
1682
|
+
L = [y.abs() for y in list(PK[1])]
|
|
1683
|
+
j = L.index(max(L))
|
|
1684
|
+
|
|
1685
|
+
#Compute the local height wrt the divisor E_{mn}^{+}
|
|
1686
|
+
local_height = beta*R((PK[0][i]/PK[0][m]).abs()).log() - R((PK[1][j]/PK[1][n]).abs()).log()
|
|
1687
|
+
|
|
1688
|
+
for e in range(N):
|
|
1689
|
+
#Take next iterate
|
|
1690
|
+
Q = W.phi(PK, check=False)
|
|
1691
|
+
L = [x.abs() for x in list(Q[0])]
|
|
1692
|
+
k = L.index(max(L))
|
|
1693
|
+
L = [y.abs() for y in list(Q[1])]
|
|
1694
|
+
l = L.index(max(L))
|
|
1695
|
+
newP = copy(PK)
|
|
1696
|
+
#normalize PK
|
|
1697
|
+
newP.scale_by([~PK[0][i], ZZ.one()])
|
|
1698
|
+
|
|
1699
|
+
#Find B and A, helper values for the local height
|
|
1700
|
+
if PK[1][j].abs() <= PK[1][l].abs():
|
|
1701
|
+
B = Rx(W.Gpoly(1, l))(tuple(newP[0]))*PK[1][j]/PK[1][l]
|
|
1702
|
+
else:
|
|
1703
|
+
B = -Rx(W.Gpoly(1, j))(tuple(newP[0]))*PK[1][l]/PK[1][j]
|
|
1704
|
+
B = B - Rx(W.Hpoly(1, j, l))(tuple(newP[0]))
|
|
1705
|
+
|
|
1706
|
+
#Normalize Q
|
|
1707
|
+
newQ = copy(Q)
|
|
1708
|
+
newQ.scale_by([ZZ.one(), ~Q[1][l]])
|
|
1709
|
+
|
|
1710
|
+
if PK[0][i].abs() <= PK[0][k].abs():
|
|
1711
|
+
A = Ry(W.Gpoly(0, k))(tuple(newQ[1]))*PK[0][i]/PK[0][k]
|
|
1712
|
+
else:
|
|
1713
|
+
A = -Ry(W.Gpoly(0, i))(tuple(newQ[1]))*PK[0][k]/PK[0][i]
|
|
1714
|
+
A = A - Ry(W.Hpoly(0, i, k))(tuple(newQ[1]))
|
|
1715
|
+
#Compute the new local height
|
|
1716
|
+
local_height += beta**(-2*R(e)-1)*R(A.abs()).log() + beta**(-2*R(e))*R(B.abs()).log()
|
|
1717
|
+
|
|
1718
|
+
i = k
|
|
1719
|
+
j = l
|
|
1720
|
+
newQ.scale_by([~Q[0][k], ZZ.one()])
|
|
1721
|
+
PK = newQ
|
|
1722
|
+
return local_height
|
|
1723
|
+
|
|
1724
|
+
def lambda_minus(self, P, v, N, m, n, prec=100):
|
|
1725
|
+
r"""
|
|
1726
|
+
Evaluates the local canonical height minus function of Call-Silverman
|
|
1727
|
+
at the place ``v`` for ``P`` with ``N`` terms of the series.
|
|
1728
|
+
|
|
1729
|
+
Use ``v = 0`` for the Archimedean place. Must be over `\ZZ` or `\QQ`.
|
|
1730
|
+
|
|
1731
|
+
ALGORITHM:
|
|
1732
|
+
|
|
1733
|
+
Sum over local heights using convergent series, for more details,
|
|
1734
|
+
see section 4 of [CS1996]_.
|
|
1735
|
+
|
|
1736
|
+
INPUT:
|
|
1737
|
+
|
|
1738
|
+
- ``P`` -- a projective point
|
|
1739
|
+
|
|
1740
|
+
- ``N`` -- positive integer. number of terms of the series to use
|
|
1741
|
+
|
|
1742
|
+
- ``v`` -- nonnegative integer. a place, use v = 0 for the Archimedean place
|
|
1743
|
+
|
|
1744
|
+
- ``m``, ``n`` -- positive integers; we compute the local height for
|
|
1745
|
+
the divisor `E_{mn}^{+}`. These must be indices of nonzero
|
|
1746
|
+
coordinates of the point ``P``.
|
|
1747
|
+
|
|
1748
|
+
- ``prec`` -- (default: 100) float point or `p`-adic precision
|
|
1749
|
+
|
|
1750
|
+
OUTPUT: a real number
|
|
1751
|
+
|
|
1752
|
+
EXAMPLES::
|
|
1753
|
+
|
|
1754
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1755
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 \
|
|
1756
|
+
....: - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -4*x1*x2*y1^2 + 5*x0*x2*y0*y2\
|
|
1757
|
+
....: - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1758
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1759
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1760
|
+
sage: P = X([0, 0, 1, 1, 0, 0])
|
|
1761
|
+
sage: X.lambda_minus(P, 2, 20, 2, 0, 200) # needs sage.symbolic
|
|
1762
|
+
-0.18573351672047135037172805779671791488351056677474271893705
|
|
1763
|
+
"""
|
|
1764
|
+
R = RealField(prec)
|
|
1765
|
+
if v == 0:
|
|
1766
|
+
K = R
|
|
1767
|
+
else:
|
|
1768
|
+
K = Qp(v, prec)
|
|
1769
|
+
PK = P.change_ring(K)
|
|
1770
|
+
W = self.change_ring(K)
|
|
1771
|
+
Rx = W.ambient_space().coordinate_ring().hom(list(W.ambient_space()[0].coordinate_ring().gens())
|
|
1772
|
+
+ [0, 0, 0], W.ambient_space()[0].coordinate_ring())
|
|
1773
|
+
Ry = W.ambient_space().coordinate_ring().hom([0, 0, 0] +
|
|
1774
|
+
list(W.ambient_space()[1].coordinate_ring().gens()),
|
|
1775
|
+
W.ambient_space()[1].coordinate_ring())
|
|
1776
|
+
beta = R(2 + sqrt(3))
|
|
1777
|
+
L = [x.abs() for x in list(PK[0])]
|
|
1778
|
+
j = L.index(max(L))
|
|
1779
|
+
L = [y.abs() for y in list(PK[1])]
|
|
1780
|
+
i = L.index(max(L))
|
|
1781
|
+
|
|
1782
|
+
##Compute the local height wrt the divisor E_{mn}^{-}
|
|
1783
|
+
local_height = beta*R((PK[1][i]/PK[1][n]).abs()).log() - R((PK[0][j]/PK[0][m]).abs()).log()
|
|
1784
|
+
for e in range(N):
|
|
1785
|
+
#Take the next iterate
|
|
1786
|
+
Q = W.psi(PK, check=False)
|
|
1787
|
+
L = [x.abs() for x in list(Q[0])]
|
|
1788
|
+
l = L.index(max(L))
|
|
1789
|
+
L = [y.abs() for y in list(Q[1])]
|
|
1790
|
+
k = L.index(max(L))
|
|
1791
|
+
#Normalize the point
|
|
1792
|
+
newP = copy(PK)
|
|
1793
|
+
newP.scale_by([ZZ.one(), ~PK[1][i]])
|
|
1794
|
+
#Find A and B, helper functions for computing local height
|
|
1795
|
+
if PK[0][j].abs() <= PK[0][l].abs():
|
|
1796
|
+
B = Ry(W.Gpoly(0, l))(tuple(newP[1]))*PK[0][j]/PK[0][l]
|
|
1797
|
+
else:
|
|
1798
|
+
B = -Ry(W.Gpoly(0, j))(tuple(newP[1]))*PK[0][l]/PK[0][j]
|
|
1799
|
+
B = B - Ry(W.Hpoly(0, j, l))(tuple(newP[1]))
|
|
1800
|
+
|
|
1801
|
+
#Normalize Q
|
|
1802
|
+
newQ = copy(Q)
|
|
1803
|
+
newQ.scale_by([~Q[0][l], ZZ.one()])
|
|
1804
|
+
|
|
1805
|
+
if PK[1][i].abs() <= PK[1][k].abs():
|
|
1806
|
+
A = Rx(W.Gpoly(1, k))(tuple(newQ[0]))*PK[1][i]/PK[1][k]
|
|
1807
|
+
else:
|
|
1808
|
+
A = -Rx(W.Gpoly(1, i))(tuple(newQ[0]))*PK[1][k]/PK[1][i]
|
|
1809
|
+
A = A-Rx(W.Hpoly(1, i, k))(tuple(newQ[0]))
|
|
1810
|
+
|
|
1811
|
+
#Compute the local height
|
|
1812
|
+
local_height += beta**(-2*R(e)-1)*R(A.abs()).log() + beta**(-2*R(e))*R(B.abs()).log()
|
|
1813
|
+
i = k
|
|
1814
|
+
j = l
|
|
1815
|
+
newQ.scale_by([ZZ.one(), ~Q[1][k]])
|
|
1816
|
+
PK = newQ
|
|
1817
|
+
return local_height
|
|
1818
|
+
|
|
1819
|
+
def canonical_height_plus(self, P, N, badprimes=None, prec=100):
|
|
1820
|
+
r"""
|
|
1821
|
+
Evaluates the canonical height plus function of Call-Silverman
|
|
1822
|
+
for ``P`` with ``N`` terms of the series of the local heights.
|
|
1823
|
+
|
|
1824
|
+
Must be over `\ZZ` or `\QQ`.
|
|
1825
|
+
|
|
1826
|
+
ALGORITHM:
|
|
1827
|
+
|
|
1828
|
+
Sum over the lambda plus heights (local heights) in a convergent series,
|
|
1829
|
+
for more detail see section 7 of [CS1996]_.
|
|
1830
|
+
|
|
1831
|
+
INPUT:
|
|
1832
|
+
|
|
1833
|
+
- ``P`` -- a surface point
|
|
1834
|
+
|
|
1835
|
+
- ``N`` -- positive integer. Number of terms of the series to use
|
|
1836
|
+
|
|
1837
|
+
- ``badprimes`` -- (optional) list of integer primes (where the surface is degenerate)
|
|
1838
|
+
|
|
1839
|
+
- ``prec`` -- (default: 100) float point or `p`-adic precision
|
|
1840
|
+
|
|
1841
|
+
OUTPUT: a real number
|
|
1842
|
+
|
|
1843
|
+
EXAMPLES::
|
|
1844
|
+
|
|
1845
|
+
sage: set_verbose(None)
|
|
1846
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(QQ, 6)
|
|
1847
|
+
sage: L = (-y0 - y1)*x0 + (-y0*x1 - y2*x2)
|
|
1848
|
+
sage: Q = (-y2*y0 - y1^2)*x0^2 + ((-y0^2 - y2*y0 + (-y2*y1 - y2^2))*x1 + \
|
|
1849
|
+
....: (-y0^2 - y2*y1)*x2)*x0 + ((-y0^2 - y2*y0 - y2^2)*x1^2 + (-y2*y0 - y1^2)*x2*x1 \
|
|
1850
|
+
....: + (-y0^2 + (-y1 - y2)*y0)*x2^2)
|
|
1851
|
+
sage: X = WehlerK3Surface([L, Q])
|
|
1852
|
+
sage: P = X([1, 0, -1, 1, -1, 0]) #order 16
|
|
1853
|
+
sage: X.canonical_height_plus(P, 5) # long time
|
|
1854
|
+
0.00000000000000000000000000000
|
|
1855
|
+
|
|
1856
|
+
Call-Silverman Example::
|
|
1857
|
+
|
|
1858
|
+
sage: set_verbose(None)
|
|
1859
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1860
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
1861
|
+
....: 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
1862
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
1863
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1864
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1865
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1866
|
+
sage: P = X([0, 1, 0, 0, 0, 1])
|
|
1867
|
+
sage: X.canonical_height_plus(P, 4) # long time
|
|
1868
|
+
0.14752753298983071394400412161
|
|
1869
|
+
"""
|
|
1870
|
+
if badprimes is None:
|
|
1871
|
+
badprimes = self.degenerate_primes()
|
|
1872
|
+
m = 2
|
|
1873
|
+
while P[0][m] == 0:
|
|
1874
|
+
m = m - 1
|
|
1875
|
+
n = 2
|
|
1876
|
+
while P[1][n] == 0:
|
|
1877
|
+
n = n-1
|
|
1878
|
+
h = self.lambda_plus(P, 0, N, m, n, prec)
|
|
1879
|
+
for p in badprimes:
|
|
1880
|
+
h += self.lambda_plus(P, p, N, m, n, prec)
|
|
1881
|
+
return h
|
|
1882
|
+
|
|
1883
|
+
def canonical_height_minus(self, P, N, badprimes=None, prec=100):
|
|
1884
|
+
r"""
|
|
1885
|
+
Evaluates the canonical height minus function of Call-Silverman
|
|
1886
|
+
for ``P`` with ``N`` terms of the series of the local heights.
|
|
1887
|
+
|
|
1888
|
+
Must be over `\ZZ` or `\QQ`.
|
|
1889
|
+
|
|
1890
|
+
ALGORITHM:
|
|
1891
|
+
|
|
1892
|
+
Sum over the lambda minus heights (local heights) in a convergent series,
|
|
1893
|
+
for more detail see section 7 of [CS1996]_.
|
|
1894
|
+
|
|
1895
|
+
INPUT:
|
|
1896
|
+
|
|
1897
|
+
- ``P`` -- a surface point
|
|
1898
|
+
|
|
1899
|
+
- ``N`` -- positive integer (number of terms of the series to use)
|
|
1900
|
+
|
|
1901
|
+
- ``badprimes`` -- (optional) list of integer primes (where the surface is degenerate)
|
|
1902
|
+
|
|
1903
|
+
- ``prec`` -- (default: 100) float point or `p`-adic precision
|
|
1904
|
+
|
|
1905
|
+
OUTPUT: a real number
|
|
1906
|
+
|
|
1907
|
+
EXAMPLES::
|
|
1908
|
+
|
|
1909
|
+
sage: set_verbose(None)
|
|
1910
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(QQ, 6)
|
|
1911
|
+
sage: L = (-y0 - y1)*x0 + (-y0*x1 - y2*x2)
|
|
1912
|
+
sage: Q = (-y2*y0 - y1^2)*x0^2 + ((-y0^2 - y2*y0 + (-y2*y1 - y2^2))*x1\
|
|
1913
|
+
....: + (-y0^2 - y2*y1)*x2)*x0 + ((-y0^2 - y2*y0 - y2^2)*x1^2 + (-y2*y0 - y1^2)*x2*x1\
|
|
1914
|
+
....: + (-y0^2 + (-y1 - y2)*y0)*x2^2)
|
|
1915
|
+
sage: X = WehlerK3Surface([L, Q])
|
|
1916
|
+
sage: P = X([1, 0, -1, 1, -1, 0]) #order 16
|
|
1917
|
+
sage: X.canonical_height_minus(P, 5) # long time
|
|
1918
|
+
0.00000000000000000000000000000
|
|
1919
|
+
|
|
1920
|
+
Call-Silverman example::
|
|
1921
|
+
|
|
1922
|
+
sage: set_verbose(None)
|
|
1923
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1924
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 +\
|
|
1925
|
+
....: 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - \
|
|
1926
|
+
....: 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + \
|
|
1927
|
+
....: x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1928
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1929
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1930
|
+
sage: P = X([0, 1, 0, 0, 0, 1])
|
|
1931
|
+
sage: X.canonical_height_minus(P, 4) # long time
|
|
1932
|
+
0.55073705369676788175590206734
|
|
1933
|
+
"""
|
|
1934
|
+
if badprimes is None:
|
|
1935
|
+
badprimes = self.degenerate_primes()
|
|
1936
|
+
m = 2
|
|
1937
|
+
while P[0][m] == 0:
|
|
1938
|
+
m = m - 1
|
|
1939
|
+
n = 2
|
|
1940
|
+
while P[1][n] == 0:
|
|
1941
|
+
n = n-1
|
|
1942
|
+
h = self.lambda_minus(P, 0, N, m, n, prec)
|
|
1943
|
+
for p in badprimes:
|
|
1944
|
+
h += self.lambda_minus(P, p, N, m, n, prec)
|
|
1945
|
+
return h
|
|
1946
|
+
|
|
1947
|
+
def canonical_height(self, P, N, badprimes=None, prec=100):
|
|
1948
|
+
r"""
|
|
1949
|
+
Evaluates the canonical height for ``P`` with ``N`` terms of the series of the local
|
|
1950
|
+
heights.
|
|
1951
|
+
|
|
1952
|
+
ALGORITHM:
|
|
1953
|
+
|
|
1954
|
+
The sum of the canonical height minus and canonical height plus,
|
|
1955
|
+
for more info see section 4 of [CS1996]_.
|
|
1956
|
+
|
|
1957
|
+
INPUT:
|
|
1958
|
+
|
|
1959
|
+
- ``P`` -- a surface point
|
|
1960
|
+
|
|
1961
|
+
- ``N`` -- positive integer (number of terms of the series to use)
|
|
1962
|
+
|
|
1963
|
+
- ``badprimes`` -- (optional) list of integer primes (where the surface is degenerate)
|
|
1964
|
+
|
|
1965
|
+
- ``prec`` -- (default: 100) float point or `p`-adic precision
|
|
1966
|
+
|
|
1967
|
+
OUTPUT: a real number
|
|
1968
|
+
|
|
1969
|
+
EXAMPLES::
|
|
1970
|
+
|
|
1971
|
+
sage: set_verbose(None)
|
|
1972
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(QQ, 6)
|
|
1973
|
+
sage: L = (-y0 - y1)*x0 + (-y0*x1 - y2*x2)
|
|
1974
|
+
sage: Q = (-y2*y0 - y1^2)*x0^2 + ((-y0^2 - y2*y0 + (-y2*y1 - y2^2))*x1 + \
|
|
1975
|
+
....: (-y0^2 - y2*y1)*x2)*x0 + ((-y0^2 - y2*y0 - y2^2)*x1^2 + (-y2*y0 - y1^2)*x2*x1 \
|
|
1976
|
+
....: + (-y0^2 + (-y1 - y2)*y0)*x2^2)
|
|
1977
|
+
sage: X = WehlerK3Surface([L, Q])
|
|
1978
|
+
sage: P = X([1, 0, -1, 1,- 1, 0]) #order 16
|
|
1979
|
+
sage: X.canonical_height(P, 5) # long time
|
|
1980
|
+
0.00000000000000000000000000000
|
|
1981
|
+
|
|
1982
|
+
Call-Silverman example::
|
|
1983
|
+
|
|
1984
|
+
sage: set_verbose(None)
|
|
1985
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
1986
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 - \
|
|
1987
|
+
....: 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 \
|
|
1988
|
+
....: -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
1989
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
1990
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
1991
|
+
sage: P = X(0, 1, 0, 0, 0, 1)
|
|
1992
|
+
sage: X.canonical_height(P, 4) # needs sage.symbolic
|
|
1993
|
+
0.69826458668659859569990618895
|
|
1994
|
+
"""
|
|
1995
|
+
if badprimes is None:
|
|
1996
|
+
badprimes = self.degenerate_primes()
|
|
1997
|
+
return (self.canonical_height_plus(P, N, badprimes, prec) +
|
|
1998
|
+
self.canonical_height_minus(P, N, badprimes, prec))
|
|
1999
|
+
|
|
2000
|
+
def fiber(self, p, component):
|
|
2001
|
+
r"""
|
|
2002
|
+
Return the fibers [y (component = 1) or x (Component = 0)] of
|
|
2003
|
+
a point on a K3 Surface.
|
|
2004
|
+
|
|
2005
|
+
This will work for nondegenerate fibers only.
|
|
2006
|
+
|
|
2007
|
+
For algorithm, see [Hutz2007]_.
|
|
2008
|
+
|
|
2009
|
+
INPUT:
|
|
2010
|
+
|
|
2011
|
+
- ``p`` -- a point in `\mathbb{P}^2`
|
|
2012
|
+
|
|
2013
|
+
OUTPUT: the corresponding fiber (as a list)
|
|
2014
|
+
|
|
2015
|
+
EXAMPLES::
|
|
2016
|
+
|
|
2017
|
+
sage: R.<x0,x1,x2,y0,y1,y2> = PolynomialRing(ZZ, 6)
|
|
2018
|
+
sage: Y = x0*y0 + x1*y1 - x2*y2
|
|
2019
|
+
sage: Z = y0^2*x0*x1 + y0^2*x2^2 - y0*y1*x1*x2 + y1^2*x2*x1 + y2^2*x2^2 +\
|
|
2020
|
+
....: y2^2*x1^2 + y1^2*x2^2
|
|
2021
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2022
|
+
sage: Proj = ProjectiveSpace(QQ, 2)
|
|
2023
|
+
sage: P = Proj([1, 0, 0])
|
|
2024
|
+
sage: X.fiber(P, 1)
|
|
2025
|
+
Traceback (most recent call last):
|
|
2026
|
+
...
|
|
2027
|
+
TypeError: fiber is degenerate
|
|
2028
|
+
|
|
2029
|
+
::
|
|
2030
|
+
|
|
2031
|
+
sage: P.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2032
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 - \
|
|
2033
|
+
....: 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - \
|
|
2034
|
+
....: 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
2035
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
2036
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2037
|
+
sage: Proj = P[0]
|
|
2038
|
+
sage: T = Proj([0, 0, 1])
|
|
2039
|
+
sage: X.fiber(T, 1)
|
|
2040
|
+
[(0 : 0 : 1 , 0 : 1 : 0), (0 : 0 : 1 , 2 : 0 : 0)]
|
|
2041
|
+
|
|
2042
|
+
::
|
|
2043
|
+
|
|
2044
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], GF(7))
|
|
2045
|
+
sage: L = x0*y0 + x1*y1 - 1*x2*y2
|
|
2046
|
+
sage: Q = ((2*x0^2 + x2*x0 + (2*x1^2 + x2^2))*y0^2
|
|
2047
|
+
....: + ((x0^2 + x1*x0 +(x1^2 + 2*x2*x1 + x2^2))*y1
|
|
2048
|
+
....: + (2*x1^2 + x2*x1 + x2^2)*y2)*y0
|
|
2049
|
+
....: + ((2*x0^2 + (x1 + 2*x2)*x0 + (2*x1^2 + x2*x1))*y1^2
|
|
2050
|
+
....: + ((2*x1 + 2*x2)*x0 + (x1^2 + x2*x1 + 2*x2^2))*y2*y1
|
|
2051
|
+
....: + (2*x0^2 + x1*x0 + (2*x1^2 + x2^2))*y2^2))
|
|
2052
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
2053
|
+
sage: W.fiber([4, 0, 1], 0)
|
|
2054
|
+
[(0 : 1 : 0 , 4 : 0 : 1), (4 : 0 : 2 , 4 : 0 : 1)]
|
|
2055
|
+
"""
|
|
2056
|
+
R = self.base_ring()
|
|
2057
|
+
Zero = R(0)
|
|
2058
|
+
One = R(1)
|
|
2059
|
+
P = []
|
|
2060
|
+
for i in list(p):
|
|
2061
|
+
j = R(i)
|
|
2062
|
+
P.append(j)
|
|
2063
|
+
if component == 1:
|
|
2064
|
+
P0 = P + [Zero, Zero, Zero]
|
|
2065
|
+
else:
|
|
2066
|
+
P0 = [Zero, Zero, Zero] + P
|
|
2067
|
+
Points = []
|
|
2068
|
+
|
|
2069
|
+
if (self.Gpoly(component,0)(P0) != 0):
|
|
2070
|
+
# We are using the quadratic formula, we need this check
|
|
2071
|
+
# to ensure that the points will be rational
|
|
2072
|
+
T0 = (self.Hpoly(component, 0, 1)(P0)**2 - 4*self.Gpoly(component, 0)(P0)*self.Gpoly(component, 1)(P0))
|
|
2073
|
+
T1 = (self.Hpoly(component, 0, 2)(P0)**2 - 4*self.Gpoly(component, 0)(P0)*self.Gpoly(component, 2)(P0))
|
|
2074
|
+
if (T0.is_square() and T1.is_square()):
|
|
2075
|
+
T0 = T0.sqrt()
|
|
2076
|
+
T1 = T1.sqrt()
|
|
2077
|
+
B1 = (-self.Hpoly(component, 0, 1)(P0)+T0)/(2*self.Gpoly(component, 0)(P0))
|
|
2078
|
+
B2 = (-self.Hpoly(component, 0, 1)(P0)-T0)/(2*self.Gpoly(component, 0)(P0))
|
|
2079
|
+
C1 = (-self.Hpoly(component, 0, 2)(P0)+T1)/(2*self.Gpoly(component, 0)(P0))
|
|
2080
|
+
C2 = (-self.Hpoly(component, 0, 2)(P0)-T1)/(2*self.Gpoly(component, 0)(P0))
|
|
2081
|
+
if component == 1:
|
|
2082
|
+
Points.append(P+[One, B1, C1])
|
|
2083
|
+
Points.append(P+[One, B2, C1])
|
|
2084
|
+
Points.append(P+[One, B1, C2])
|
|
2085
|
+
Points.append(P+[One, B2, C2])
|
|
2086
|
+
else:
|
|
2087
|
+
Points.append([One, B1, C1]+P)
|
|
2088
|
+
Points.append([One, B2, C1]+P)
|
|
2089
|
+
Points.append([One, B1, C2]+P)
|
|
2090
|
+
Points.append([One, B2, C2]+P)
|
|
2091
|
+
else:
|
|
2092
|
+
return []
|
|
2093
|
+
elif (self.Gpoly(component, 1)(P0) != 0):
|
|
2094
|
+
T0 = (self.Hpoly(component, 0, 1)(P0)**2 - 4*self.Gpoly(component, 0)(P0)*self.Gpoly(component, 1)(P0))
|
|
2095
|
+
T1 = (self.Hpoly(component, 1, 2)(P0)**2 - 4*self.Gpoly(component, 1)(P0)*self.Gpoly(component, 2)(P0))
|
|
2096
|
+
if (T0.is_square() and T1.is_square()):
|
|
2097
|
+
T0 = T0.sqrt()
|
|
2098
|
+
T1 = T1.sqrt()
|
|
2099
|
+
A1 = (-self.Hpoly(component, 0, 1)(P0)+T0)/(2*self.Gpoly(component, 1)(P0))
|
|
2100
|
+
A2 = (-self.Hpoly(component, 0, 1)(P0)-T0)/(2*self.Gpoly(component, 1)(P0))
|
|
2101
|
+
C1 = (-self.Hpoly(component, 1, 2)(P0)+T1)/(2*self.Gpoly(component, 1)(P0))
|
|
2102
|
+
C2 = (-self.Hpoly(component, 1, 2)(P0)-T1)/(2*self.Gpoly(component, 1)(P0))
|
|
2103
|
+
if component == 1:
|
|
2104
|
+
Points.append(P + [A1, One, C1])
|
|
2105
|
+
Points.append(P + [A1, One, C2])
|
|
2106
|
+
Points.append(P + [A2, One, C1])
|
|
2107
|
+
Points.append(P + [A2, One, C2])
|
|
2108
|
+
else:
|
|
2109
|
+
Points.append([A1, One, C1] + P)
|
|
2110
|
+
Points.append([A1, One, C2] + P)
|
|
2111
|
+
Points.append([A2, One, C1] + P)
|
|
2112
|
+
Points.append([A2, One, C2] + P)
|
|
2113
|
+
else:
|
|
2114
|
+
return []
|
|
2115
|
+
elif self.Gpoly(component, 2)(P0) != 0:
|
|
2116
|
+
T0 = (self.Hpoly(component, 0, 2)(P0)**2 - 4*self.Gpoly(component, 0)(P0)*self.Gpoly(component, 2)(P0))
|
|
2117
|
+
T1 = (self.Hpoly(component, 1, 2)(P0)**2 - 4*self.Gpoly(component, 1)(P0)*self.Gpoly(component, 2)(P0))
|
|
2118
|
+
if (T0.is_square() and T1.is_square()):
|
|
2119
|
+
T0 = T0.sqrt()
|
|
2120
|
+
T1 = T1.sqrt()
|
|
2121
|
+
A1 = (-self.Hpoly(component, 0, 2)(P0)+T0)/(2*self.Gpoly(component, 2)(P0))
|
|
2122
|
+
A2 = (-self.Hpoly(component, 0, 2)(P0)-T0)/(2*self.Gpoly(component, 2)(P0))
|
|
2123
|
+
B1 = (-self.Hpoly(component, 1, 2)(P0)+T1)/(2*self.Gpoly(component, 2)(P0))
|
|
2124
|
+
B2 = (-self.Hpoly(component, 1, 2)(P0)-T1)/(2*self.Gpoly(component, 2)(P0))
|
|
2125
|
+
if component == 1:
|
|
2126
|
+
Points.append(P + [A1, B1, One])
|
|
2127
|
+
Points.append(P + [A1, B2, One])
|
|
2128
|
+
Points.append(P + [A2, B1, One])
|
|
2129
|
+
Points.append(P + [A2, B2, One])
|
|
2130
|
+
else:
|
|
2131
|
+
Points.append([A1, B1, One] + P)
|
|
2132
|
+
Points.append([A1, B2, One] + P)
|
|
2133
|
+
Points.append([A2, B1, One] + P)
|
|
2134
|
+
Points.append([A2, B2, One] + P)
|
|
2135
|
+
else:
|
|
2136
|
+
return []
|
|
2137
|
+
elif self.Hpoly(component, 0, 1)(P0) != 0:
|
|
2138
|
+
if component == 1:
|
|
2139
|
+
Points.append(P+[Zero, One, Zero])
|
|
2140
|
+
Points.append(P+[-self.Hpoly(component, 0, 1)(P0),Zero,
|
|
2141
|
+
-self.Hpoly(component, 1, 2)(P0)])
|
|
2142
|
+
Points.append(P+[One,Zero,Zero])
|
|
2143
|
+
Points.append(P+[Zero,-self.Hpoly(component, 0, 1)(P0),
|
|
2144
|
+
-self.Hpoly(component, 0, 2)(P0)])
|
|
2145
|
+
else:
|
|
2146
|
+
Points.append([Zero,One,Zero]+P)
|
|
2147
|
+
Points.append([-self.Hpoly(component, 0, 1)(P0),Zero,
|
|
2148
|
+
-self.Hpoly(component, 1, 2)(P0)] + P)
|
|
2149
|
+
Points.append([One,Zero,Zero]+P)
|
|
2150
|
+
Points.append([Zero,-self.Hpoly(component, 0, 1)(P0),
|
|
2151
|
+
-self.Hpoly(component, 0, 2)(P0)] + P)
|
|
2152
|
+
elif self.Hpoly(component, 0, 2)(P0) != 0:
|
|
2153
|
+
if component == 1:
|
|
2154
|
+
Points.append(P+[Zero, Zero, One])
|
|
2155
|
+
Points.append(P+[-self.Hpoly(component, 0, 2)(P0),
|
|
2156
|
+
-self.Hpoly(component, 1, 2)(P0), Zero])
|
|
2157
|
+
else:
|
|
2158
|
+
Points.append([Zero, Zero, One]+P)
|
|
2159
|
+
Points.append([-self.Hpoly(component, 0, 2)(P0),
|
|
2160
|
+
-self.Hpoly(component, 1, 2)(P0), Zero] + P)
|
|
2161
|
+
elif self.Hpoly(component, 1, 2)(P0) != 0:
|
|
2162
|
+
if component == 1:
|
|
2163
|
+
Points.append(P + [Zero, Zero, One])
|
|
2164
|
+
Points.append(P + [Zero, One, Zero])
|
|
2165
|
+
else:
|
|
2166
|
+
Points.append([Zero, Zero, One] + P)
|
|
2167
|
+
Points.append([Zero, One, Zero] + P)
|
|
2168
|
+
else:
|
|
2169
|
+
raise TypeError("fiber is degenerate")
|
|
2170
|
+
|
|
2171
|
+
fiber = []
|
|
2172
|
+
for x in Points:
|
|
2173
|
+
if (self.L(x) == 0) and (self.Q(x) == 0):
|
|
2174
|
+
Y = self.point(x, False)
|
|
2175
|
+
if Y not in fiber:
|
|
2176
|
+
fiber.append(Y)
|
|
2177
|
+
return fiber
|
|
2178
|
+
|
|
2179
|
+
def nth_iterate_phi(self, P, n, **kwds):
|
|
2180
|
+
r"""
|
|
2181
|
+
Compute the `n`-th iterate for the phi function.
|
|
2182
|
+
|
|
2183
|
+
INPUT:
|
|
2184
|
+
|
|
2185
|
+
- ``P`` -- a point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
2186
|
+
|
|
2187
|
+
- ``n`` -- integer
|
|
2188
|
+
|
|
2189
|
+
kwds:
|
|
2190
|
+
|
|
2191
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is
|
|
2192
|
+
on the surface
|
|
2193
|
+
|
|
2194
|
+
- ``normalize`` -- boolean (default: ``False``); normalizes the point
|
|
2195
|
+
|
|
2196
|
+
OUTPUT: the `n`-th iterate of the point given the phi function (if `n`
|
|
2197
|
+
is positive), or the psi function (if `n` is negative)
|
|
2198
|
+
|
|
2199
|
+
EXAMPLES::
|
|
2200
|
+
|
|
2201
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2202
|
+
sage: L = x0*y0 + x1*y1 + x2*y2
|
|
2203
|
+
sage: Q = x1^2*y0^2 + 2*x2^2*y0*y1 + x0^2*y1^2 - x0*x1*y2^2
|
|
2204
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
2205
|
+
sage: T = W([-1, -1, 1, 1, 0, 1])
|
|
2206
|
+
sage: W.nth_iterate_phi(T, 7)
|
|
2207
|
+
(-1 : 0 : 1 , 1 : -2 : 1)
|
|
2208
|
+
|
|
2209
|
+
::
|
|
2210
|
+
|
|
2211
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2212
|
+
sage: L = x0*y0 + x1*y1 + x2*y2
|
|
2213
|
+
sage: Q = x1^2*y0^2 + 2*x2^2*y0*y1 + x0^2*y1^2 - x0*x1*y2^2
|
|
2214
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
2215
|
+
sage: T = W([-1, -1, 1, 1, 0, 1])
|
|
2216
|
+
sage: W.nth_iterate_phi(T, -7)
|
|
2217
|
+
(1 : 0 : 1 , -1 : 2 : 1)
|
|
2218
|
+
|
|
2219
|
+
::
|
|
2220
|
+
|
|
2221
|
+
sage: R.<x0,x1,x2,y0,y1,y2>=PolynomialRing(QQ, 6)
|
|
2222
|
+
sage: L = (-y0 - y1)*x0 + (-y0*x1 - y2*x2)
|
|
2223
|
+
sage: Q = (-y2*y0 - y1^2)*x0^2 + ((-y0^2 - y2*y0 + (-y2*y1 - y2^2))*x1 + (-y0^2 - y2*y1)*x2)*x0 \
|
|
2224
|
+
....: + ((-y0^2 - y2*y0 - y2^2)*x1^2 + (-y2*y0 - y1^2)*x2*x1 + (-y0^2 + (-y1 - y2)*y0)*x2^2)
|
|
2225
|
+
sage: X = WehlerK3Surface([L, Q])
|
|
2226
|
+
sage: P = X([1, 0, -1, 1, -1, 0])
|
|
2227
|
+
sage: X.nth_iterate_phi(P, 8) == X.nth_iterate_psi(P, 8)
|
|
2228
|
+
True
|
|
2229
|
+
"""
|
|
2230
|
+
try:
|
|
2231
|
+
n = ZZ(n)
|
|
2232
|
+
except TypeError:
|
|
2233
|
+
raise TypeError("iterate number must be an integer")
|
|
2234
|
+
#Since phi and psi are inverses and automorphisms
|
|
2235
|
+
if n < 0:
|
|
2236
|
+
return self.nth_iterate_psi(P, abs(n), **kwds)
|
|
2237
|
+
if n == 0:
|
|
2238
|
+
return self
|
|
2239
|
+
else:
|
|
2240
|
+
Q = self.phi(P, **kwds)
|
|
2241
|
+
for i in range(2, n+1):
|
|
2242
|
+
Q = self.phi(Q, **kwds)
|
|
2243
|
+
return Q
|
|
2244
|
+
|
|
2245
|
+
def nth_iterate_psi(self, P, n, **kwds):
|
|
2246
|
+
r"""
|
|
2247
|
+
Compute the `n`-th iterate for the psi function.
|
|
2248
|
+
|
|
2249
|
+
INPUT:
|
|
2250
|
+
|
|
2251
|
+
- ``P`` -- a point in `\mathbb{P}^2 \times \mathbb{P}^2`
|
|
2252
|
+
|
|
2253
|
+
- ``n`` -- integer
|
|
2254
|
+
|
|
2255
|
+
kwds:
|
|
2256
|
+
|
|
2257
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
2258
|
+
|
|
2259
|
+
- ``normalize`` -- boolean (default: ``False``); normalizes the point
|
|
2260
|
+
|
|
2261
|
+
OUTPUT: the `n`-th iterate of the point given the psi function (if `n` is positive),
|
|
2262
|
+
or the phi function (if `n` is negative)
|
|
2263
|
+
|
|
2264
|
+
EXAMPLES::
|
|
2265
|
+
|
|
2266
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2267
|
+
sage: L = x0*y0 + x1*y1 + x2*y2
|
|
2268
|
+
sage: Q = x1^2*y0^2 + 2*x2^2*y0*y1 + x0^2*y1^2 - x0*x1*y2^2
|
|
2269
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
2270
|
+
sage: T = W([-1, -1, 1, 1, 0, 1])
|
|
2271
|
+
sage: W.nth_iterate_psi(T, -7)
|
|
2272
|
+
(-1 : 0 : 1 , 1 : -2 : 1)
|
|
2273
|
+
|
|
2274
|
+
::
|
|
2275
|
+
|
|
2276
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2277
|
+
sage: L = x0*y0 + x1*y1 + x2*y2
|
|
2278
|
+
sage: Q = x1^2*y0^2 + 2*x2^2*y0*y1 + x0^2*y1^2 - x0*x1*y2^2
|
|
2279
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
2280
|
+
sage: T = W([-1, -1, 1, 1, 0, 1])
|
|
2281
|
+
sage: W.nth_iterate_psi(T, 7)
|
|
2282
|
+
(1 : 0 : 1 , -1 : 2 : 1)
|
|
2283
|
+
"""
|
|
2284
|
+
try:
|
|
2285
|
+
n = ZZ(n)
|
|
2286
|
+
except TypeError:
|
|
2287
|
+
raise TypeError("iterate number must be an integer")
|
|
2288
|
+
#Since phi and psi and inverses
|
|
2289
|
+
if n < 0:
|
|
2290
|
+
return self.nth_iterate_phi(P, abs(n), **kwds)
|
|
2291
|
+
if n == 0:
|
|
2292
|
+
return self
|
|
2293
|
+
else:
|
|
2294
|
+
Q = self.psi(P, **kwds)
|
|
2295
|
+
for i in range(2, n+1):
|
|
2296
|
+
Q = self.psi(Q, **kwds)
|
|
2297
|
+
return Q
|
|
2298
|
+
|
|
2299
|
+
def orbit_phi(self, P, N, **kwds):
|
|
2300
|
+
r"""
|
|
2301
|
+
Return the orbit of the `\phi` function defined by
|
|
2302
|
+
`\phi = \sigma_y \circ \sigma_x`.
|
|
2303
|
+
|
|
2304
|
+
This function is defined in [CS1996]_.
|
|
2305
|
+
|
|
2306
|
+
INPUT:
|
|
2307
|
+
|
|
2308
|
+
- ``P`` -- point on the K3 surface
|
|
2309
|
+
|
|
2310
|
+
- ``N`` -- nonnegative integer or list or tuple of two nonnegative integers
|
|
2311
|
+
|
|
2312
|
+
kwds:
|
|
2313
|
+
|
|
2314
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
2315
|
+
|
|
2316
|
+
- ``normalize`` -- boolean (default: ``False``); normalizes the point
|
|
2317
|
+
|
|
2318
|
+
OUTPUT: list of points in the orbit
|
|
2319
|
+
|
|
2320
|
+
EXAMPLES::
|
|
2321
|
+
|
|
2322
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2323
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
2324
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - \
|
|
2325
|
+
....: 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + \
|
|
2326
|
+
....: x0*x1*y2^2 + 3*x2^2*y2^2
|
|
2327
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
2328
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2329
|
+
sage: T = PP(0, 0, 1, 1, 0, 0)
|
|
2330
|
+
sage: X.orbit_phi(T,2, normalize = True)
|
|
2331
|
+
[(0 : 0 : 1 , 1 : 0 : 0), (-1 : 0 : 1 , 0 : 1 : 0), (-12816/6659 : 55413/6659 : 1 , 1 : 1/9 : 1)]
|
|
2332
|
+
sage: X.orbit_phi(T,[2,3], normalize = True)
|
|
2333
|
+
[(-12816/6659 : 55413/6659 : 1 , 1 : 1/9 : 1),
|
|
2334
|
+
(7481279673854775690938629732119966552954626693713001783595660989241/18550615454277582153932951051931712107449915856862264913424670784695
|
|
2335
|
+
: 3992260691327218828582255586014718568398539828275296031491644987908/18550615454277582153932951051931712107449915856862264913424670784695 :
|
|
2336
|
+
1 , -117756062505511/54767410965117 : -23134047983794359/37466994368025041 : 1)]
|
|
2337
|
+
"""
|
|
2338
|
+
if not isinstance(N, (list, tuple)):
|
|
2339
|
+
N = [0, N]
|
|
2340
|
+
try:
|
|
2341
|
+
N[0] = ZZ(N[0])
|
|
2342
|
+
N[1] = ZZ(N[1])
|
|
2343
|
+
except TypeError:
|
|
2344
|
+
raise TypeError("orbit bounds must be integers")
|
|
2345
|
+
if N[0] < 0 or N[1] < 0:
|
|
2346
|
+
raise TypeError("orbit bounds must be nonnegative")
|
|
2347
|
+
if N[0] > N[1]:
|
|
2348
|
+
return []
|
|
2349
|
+
Q = self(copy(P))
|
|
2350
|
+
for i in range(1, N[0] + 1):
|
|
2351
|
+
Q = self.phi(Q, **kwds)
|
|
2352
|
+
Orb = [Q]
|
|
2353
|
+
for i in range(N[0] + 1, N[1] + 1):
|
|
2354
|
+
Q = self.phi(Q, **kwds)
|
|
2355
|
+
Orb.append(Q)
|
|
2356
|
+
return Orb
|
|
2357
|
+
|
|
2358
|
+
def orbit_psi(self, P, N, **kwds):
|
|
2359
|
+
r"""
|
|
2360
|
+
Return the orbit of the `\psi` function defined by
|
|
2361
|
+
`\psi = \sigma_x \circ \sigma_y`.
|
|
2362
|
+
|
|
2363
|
+
This function is defined in [CS1996]_.
|
|
2364
|
+
|
|
2365
|
+
INPUT:
|
|
2366
|
+
|
|
2367
|
+
- ``P`` -- a point on the K3 surface
|
|
2368
|
+
|
|
2369
|
+
- ``N`` -- nonnegative integer or list or tuple of two nonnegative integers
|
|
2370
|
+
|
|
2371
|
+
kwds:
|
|
2372
|
+
|
|
2373
|
+
- ``check`` -- boolean (default: ``True``); checks to see if point is on the surface
|
|
2374
|
+
|
|
2375
|
+
- ``normalize`` -- boolean (default: ``False``); normalizes the point
|
|
2376
|
+
|
|
2377
|
+
OUTPUT: list of points in the orbit
|
|
2378
|
+
|
|
2379
|
+
EXAMPLES::
|
|
2380
|
+
|
|
2381
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2382
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
2383
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 - \
|
|
2384
|
+
....: 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + \
|
|
2385
|
+
....: x0*x1*y2^2 + 3*x2^2*y2^2
|
|
2386
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
2387
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2388
|
+
sage: T = X(0, 0, 1, 1, 0, 0)
|
|
2389
|
+
sage: X.orbit_psi(T, 2, normalize=True)
|
|
2390
|
+
[(0 : 0 : 1 , 1 : 0 : 0), (0 : 0 : 1 , 0 : 1 : 0), (-1 : 0 : 1 , 1 : 1/9 : 1)]
|
|
2391
|
+
sage: X.orbit_psi(T,[2,3], normalize=True)
|
|
2392
|
+
[(-1 : 0 : 1 , 1 : 1/9 : 1),
|
|
2393
|
+
(-12816/6659 : 55413/6659 : 1 , -117756062505511/54767410965117 : -23134047983794359/37466994368025041 : 1)]
|
|
2394
|
+
"""
|
|
2395
|
+
if not isinstance(N, (list, tuple)):
|
|
2396
|
+
N = [0, N]
|
|
2397
|
+
try:
|
|
2398
|
+
N[0] = ZZ(N[0])
|
|
2399
|
+
N[1] = ZZ(N[1])
|
|
2400
|
+
except TypeError:
|
|
2401
|
+
raise TypeError("orbit bounds must be integers")
|
|
2402
|
+
if N[0] < 0 or N[1] < 0:
|
|
2403
|
+
raise TypeError("orbit bounds must be nonnegative")
|
|
2404
|
+
if N[0] > N[1]:
|
|
2405
|
+
return []
|
|
2406
|
+
Q = self(copy(P))
|
|
2407
|
+
for i in range(1, N[0] + 1):
|
|
2408
|
+
Q = self.psi(Q, **kwds)
|
|
2409
|
+
Orb = [Q]
|
|
2410
|
+
for i in range(N[0] + 1, N[1] + 1):
|
|
2411
|
+
Q = self.psi(Q, **kwds)
|
|
2412
|
+
Orb.append(Q)
|
|
2413
|
+
return Orb
|
|
2414
|
+
|
|
2415
|
+
def is_isomorphic(self, right):
|
|
2416
|
+
r"""
|
|
2417
|
+
Check to see if two K3 surfaces have the same defining ideal.
|
|
2418
|
+
|
|
2419
|
+
INPUT:
|
|
2420
|
+
|
|
2421
|
+
- ``right`` -- the K3 surface to compare to the original
|
|
2422
|
+
|
|
2423
|
+
OUTPUT: boolean
|
|
2424
|
+
|
|
2425
|
+
EXAMPLES::
|
|
2426
|
+
|
|
2427
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2428
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
2429
|
+
....: 3*x0*x1*y0*y1 -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
2430
|
+
....: -4*x1*x2*y1^2 + 5*x0*x2*y0*y2 - 4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
2431
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
2432
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
2433
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2434
|
+
sage: W = WehlerK3Surface([Z + Y^2, Y])
|
|
2435
|
+
sage: X.is_isomorphic(W)
|
|
2436
|
+
True
|
|
2437
|
+
|
|
2438
|
+
::
|
|
2439
|
+
|
|
2440
|
+
sage: R.<x,y,z,u,v,w> = PolynomialRing(QQ, 6)
|
|
2441
|
+
sage: L = x*u - y*v
|
|
2442
|
+
sage: Q = x*y*v^2 + z^2*u*w
|
|
2443
|
+
sage: W1 = WehlerK3Surface([L, Q])
|
|
2444
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2445
|
+
sage: L = x0*y0 + x1*y1 + x2*y2
|
|
2446
|
+
sage: Q = x1^2*y0^2 + 2*x2^2*y0*y1 + x0^2*y1^2 - x0*x1*y2^2
|
|
2447
|
+
sage: W2 = WehlerK3Surface([L, Q])
|
|
2448
|
+
sage: W1.is_isomorphic(W2)
|
|
2449
|
+
False
|
|
2450
|
+
"""
|
|
2451
|
+
return self.defining_ideal() == right.defining_ideal()
|
|
2452
|
+
|
|
2453
|
+
def is_symmetric_orbit(self, orbit):
|
|
2454
|
+
r"""
|
|
2455
|
+
Check to see if the orbit is symmetric (i.e. if one of the points on the
|
|
2456
|
+
orbit is fixed by '\sigma_x' or '\sigma_y').
|
|
2457
|
+
|
|
2458
|
+
INPUT:
|
|
2459
|
+
|
|
2460
|
+
- ``orbit`` -- a periodic cycle of either psi or phi
|
|
2461
|
+
|
|
2462
|
+
OUTPUT: boolean
|
|
2463
|
+
|
|
2464
|
+
EXAMPLES::
|
|
2465
|
+
|
|
2466
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], GF(7))
|
|
2467
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + 3*x0*x1*y0*y1 \
|
|
2468
|
+
....: -2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 -4*x1*x2*y1^2 + 5*x0*x2*y0*y2 \
|
|
2469
|
+
....: -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
2470
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
2471
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2472
|
+
sage: T = PP([0, 0, 1, 1, 0, 0])
|
|
2473
|
+
sage: orbit = X.orbit_psi(T, 4)
|
|
2474
|
+
sage: X.is_symmetric_orbit(orbit)
|
|
2475
|
+
True
|
|
2476
|
+
|
|
2477
|
+
::
|
|
2478
|
+
|
|
2479
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], QQ)
|
|
2480
|
+
sage: L = x0*y0 + x1*y1 + x2*y2
|
|
2481
|
+
sage: Q = x1^2*y0^2 + 2*x2^2*y0*y1 + x0^2*y1^2 - x0*x1*y2^2
|
|
2482
|
+
sage: W = WehlerK3Surface([L, Q])
|
|
2483
|
+
sage: T = W([-1, -1, 1, 1, 0, 1])
|
|
2484
|
+
sage: Orb = W.orbit_phi(T, 7)
|
|
2485
|
+
sage: W.is_symmetric_orbit(Orb)
|
|
2486
|
+
False
|
|
2487
|
+
"""
|
|
2488
|
+
N = len(orbit)
|
|
2489
|
+
if self.nth_iterate_phi(orbit[0], N) != orbit[0] and self.nth_iterate_psi(orbit[0], N) != orbit[0]:
|
|
2490
|
+
raise ValueError("must be an orbit of phi or psi functions")
|
|
2491
|
+
sym = False
|
|
2492
|
+
i = 0
|
|
2493
|
+
while i < len(orbit) - 1 and not sym:
|
|
2494
|
+
P = orbit[i]
|
|
2495
|
+
Q = orbit[i + 1]
|
|
2496
|
+
if P[0] == Q[0] or P[1] == Q[1]:
|
|
2497
|
+
sym = True
|
|
2498
|
+
i += 1
|
|
2499
|
+
return sym
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
class WehlerK3Surface_field( WehlerK3Surface_ring):
|
|
2503
|
+
pass
|
|
2504
|
+
|
|
2505
|
+
|
|
2506
|
+
class WehlerK3Surface_finite_field( WehlerK3Surface_field):
|
|
2507
|
+
def cardinality( self):
|
|
2508
|
+
r"""
|
|
2509
|
+
Count the total number of points on the K3 surface.
|
|
2510
|
+
|
|
2511
|
+
ALGORITHM:
|
|
2512
|
+
|
|
2513
|
+
Enumerate points over `\mathbb{P}^2`, and then count the points on the fiber of
|
|
2514
|
+
each of those points.
|
|
2515
|
+
|
|
2516
|
+
OUTPUT: integer; total number of points on the surface
|
|
2517
|
+
|
|
2518
|
+
EXAMPLES::
|
|
2519
|
+
|
|
2520
|
+
sage: PP.<x0,x1,x2,y0,y1,y2> = ProductProjectiveSpaces([2, 2], GF(7))
|
|
2521
|
+
sage: Z = x0^2*y0^2 + 3*x0*x1*y0^2 + x1^2*y0^2 + 4*x0^2*y0*y1 + \
|
|
2522
|
+
....: 3*x0*x1*y0*y1 - 2*x2^2*y0*y1 - x0^2*y1^2 + 2*x1^2*y1^2 - x0*x2*y1^2 \
|
|
2523
|
+
....: - 4*x1*x2*y1^2 + 5*x0*x2*y0*y2 -4*x1*x2*y0*y2 + 7*x0^2*y1*y2 + 4*x1^2*y1*y2 \
|
|
2524
|
+
....: + x0*x1*y2^2 + 3*x2^2*y2^2
|
|
2525
|
+
sage: Y = x0*y0 + x1*y1 + x2*y2
|
|
2526
|
+
sage: X = WehlerK3Surface([Z, Y])
|
|
2527
|
+
sage: X.cardinality()
|
|
2528
|
+
55
|
|
2529
|
+
"""
|
|
2530
|
+
def getPx1():
|
|
2531
|
+
return ([x, y, 1] for x in self.base_ring() for y in self.base_ring())
|
|
2532
|
+
|
|
2533
|
+
def getPx2():
|
|
2534
|
+
return ([x, 1, 0] for x in self.base_ring())
|
|
2535
|
+
Count = 0
|
|
2536
|
+
Xpoint = [1, 0, 0]
|
|
2537
|
+
Ypoint = [1, 0, 0]
|
|
2538
|
+
# Create all possible Px1 Values
|
|
2539
|
+
for i in getPx1():
|
|
2540
|
+
for j in getPx1():
|
|
2541
|
+
A = i + j
|
|
2542
|
+
if self.L(A) == 0 and self.Q(A) == 0:
|
|
2543
|
+
Count += 1
|
|
2544
|
+
for k in getPx2():
|
|
2545
|
+
A = i + k
|
|
2546
|
+
if self.L(A) == 0 and self.Q(A) == 0:
|
|
2547
|
+
Count += 1
|
|
2548
|
+
B = i + Ypoint
|
|
2549
|
+
if self.L(B) == 0 and self.Q(B) == 0:
|
|
2550
|
+
Count += 1
|
|
2551
|
+
#Create all possible Px2 Values
|
|
2552
|
+
for i in getPx2():
|
|
2553
|
+
for j in getPx1():
|
|
2554
|
+
A = i + j
|
|
2555
|
+
if self.L(A) == 0 and self.Q(A) == 0:
|
|
2556
|
+
Count += 1
|
|
2557
|
+
for k in getPx2():
|
|
2558
|
+
A = i + k
|
|
2559
|
+
if (self.L(A) == 0 and self.Q(A) == 0):
|
|
2560
|
+
Count += 1
|
|
2561
|
+
B = i + Ypoint
|
|
2562
|
+
if (self.L(B) == 0 and self.Q(B) == 0):
|
|
2563
|
+
Count += 1
|
|
2564
|
+
#Create all Xpoint values
|
|
2565
|
+
for j in getPx1():
|
|
2566
|
+
A = Xpoint+j
|
|
2567
|
+
if (self.L(A) == 0 and self.Q(A) == 0):
|
|
2568
|
+
Count += 1
|
|
2569
|
+
for k in getPx2():
|
|
2570
|
+
B = Xpoint + k
|
|
2571
|
+
if (self.L(B) == 0 and self.Q(B) == 0):
|
|
2572
|
+
Count += 1
|
|
2573
|
+
C = Xpoint + Ypoint
|
|
2574
|
+
if (self.L(C) == 0 and self.Q(C) == 0):
|
|
2575
|
+
Count += 1
|
|
2576
|
+
return Count
|