passagemath-schemes 10.6.47__cp312-cp312-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
- passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,1014 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Global and semi-global minimal models for elliptic curves over number fields
|
|
4
|
+
|
|
5
|
+
When `E` is an elliptic curve defined over a number field `K` of class
|
|
6
|
+
number 1, then it has a global minimal model, and we have a method to
|
|
7
|
+
compute it, namely ``E.global_minimal_model()``. Until Sage-6.7 this was
|
|
8
|
+
done using Tate's algorithm to minimise one prime at a time without
|
|
9
|
+
affecting the other primes. When the class number is not 1, a
|
|
10
|
+
different approach is used.
|
|
11
|
+
|
|
12
|
+
In the general case global minimal models may or may not exist. This
|
|
13
|
+
module includes functions to determine this, and to find a global
|
|
14
|
+
minimal model when it does exist. The obstruction to the existence of
|
|
15
|
+
a global minimal model is encoded in an ideal class, which is trivial
|
|
16
|
+
if and only if a global minimal model exists: we provide a function
|
|
17
|
+
which returns this class. When the obstruction is not trivial, there
|
|
18
|
+
exist models which are minimal at all primes except at a single prime
|
|
19
|
+
in the obstruction class, where the discriminant valuation is 12 more
|
|
20
|
+
than the minimal valuation at that prime; we provide a function to
|
|
21
|
+
return such a model.
|
|
22
|
+
|
|
23
|
+
The implementation of this functionality is based on work of Kraus
|
|
24
|
+
[Kra1989]_ which gives a local condition for when a pair of number field
|
|
25
|
+
elements `c_4`, `c_6` belong to a Weierstrass model which is
|
|
26
|
+
integral at a prime `P`, together with a global version. Only primes
|
|
27
|
+
dividing 2 or 3 are hard to deal with. In order to compute the
|
|
28
|
+
corresponding integral model one then needs to combine together the
|
|
29
|
+
local transformations implicit in [Kra1989]_ into a single global one.
|
|
30
|
+
|
|
31
|
+
Various utility functions relating to the testing and use of Kraus's
|
|
32
|
+
conditions are included here.
|
|
33
|
+
|
|
34
|
+
AUTHORS:
|
|
35
|
+
|
|
36
|
+
- John Cremona (2015)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
##############################################################################
|
|
40
|
+
# Copyright (C) 2012-2014 John Cremona <john.cremona@gmail.com>
|
|
41
|
+
# William Stein <wstein@gmail.com>
|
|
42
|
+
#
|
|
43
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
44
|
+
#
|
|
45
|
+
# This code is distributed in the hope that it will be useful,
|
|
46
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
47
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
48
|
+
# General Public License for more details.
|
|
49
|
+
#
|
|
50
|
+
# The full text of the GPL is available at:
|
|
51
|
+
#
|
|
52
|
+
# https://www.gnu.org/licenses/
|
|
53
|
+
##############################################################################
|
|
54
|
+
|
|
55
|
+
from sage.schemes.elliptic_curves.constructor import EllipticCurve
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def c4c6_nonsingular(c4, c6):
|
|
59
|
+
r"""
|
|
60
|
+
Check if `c_4`, `c_6` are integral with valid associated discriminant.
|
|
61
|
+
|
|
62
|
+
INPUT:
|
|
63
|
+
|
|
64
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
65
|
+
|
|
66
|
+
OUTPUT:
|
|
67
|
+
|
|
68
|
+
Boolean, ``True`` if `c_4`, `c_6` are both integral and `c_4^3-c_6^2` is a
|
|
69
|
+
nonzero multiple of 1728.
|
|
70
|
+
|
|
71
|
+
EXAMPLES:
|
|
72
|
+
|
|
73
|
+
Over `\QQ`::
|
|
74
|
+
|
|
75
|
+
sage: from sage.schemes.elliptic_curves.kraus import c4c6_nonsingular
|
|
76
|
+
sage: c4c6_nonsingular(0,0)
|
|
77
|
+
False
|
|
78
|
+
sage: c4c6_nonsingular(0,1/2)
|
|
79
|
+
False
|
|
80
|
+
sage: c4c6_nonsingular(2,3)
|
|
81
|
+
False
|
|
82
|
+
sage: c4c6_nonsingular(4,8)
|
|
83
|
+
False
|
|
84
|
+
sage: all(c4c6_nonsingular(*E.c_invariants()) for E in cremona_curves([ 11..100]))
|
|
85
|
+
True
|
|
86
|
+
|
|
87
|
+
Over number fields::
|
|
88
|
+
|
|
89
|
+
sage: # needs sage.rings.number_field
|
|
90
|
+
sage: x = polygen(ZZ, 'x')
|
|
91
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
92
|
+
sage: c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
|
|
93
|
+
True
|
|
94
|
+
sage: K.<a> = NumberField(x^3 - 10)
|
|
95
|
+
sage: c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
|
|
96
|
+
True
|
|
97
|
+
"""
|
|
98
|
+
if not (c4.is_integral() and c6.is_integral()):
|
|
99
|
+
return False
|
|
100
|
+
D = (c4**3-c6**2)/1728
|
|
101
|
+
return not D.is_zero() and D.is_integral()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def c4c6_model(c4, c6, assume_nonsingular=False):
|
|
105
|
+
r"""
|
|
106
|
+
Return the elliptic curve [0,0,0,-c4/48,-c6/864] with given c-invariants.
|
|
107
|
+
|
|
108
|
+
INPUT:
|
|
109
|
+
|
|
110
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
111
|
+
|
|
112
|
+
- ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
|
|
113
|
+
check for integrality and nosingularity
|
|
114
|
+
|
|
115
|
+
OUTPUT:
|
|
116
|
+
|
|
117
|
+
The elliptic curve with a-invariants `[0,0,0,-c_4/48,-c_6/864]`, whose
|
|
118
|
+
c-invariants are the given `c_4`, `c_6`. If the supplied invariants are
|
|
119
|
+
singular, returns ``None`` when ``assume_nonsingular`` is ``False`` and
|
|
120
|
+
raises an :exc:`ArithmeticError` otherwise.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: from sage.schemes.elliptic_curves.kraus import c4c6_model
|
|
125
|
+
sage: x = polygen(ZZ, 'x')
|
|
126
|
+
sage: K.<a> = NumberField(x^3 - 10) # needs sage.rings.number_field
|
|
127
|
+
sage: c4c6_model(-217728*a - 679104, 141460992*a + 409826304) # needs sage.rings.number_field
|
|
128
|
+
Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
|
|
129
|
+
over Number Field in a with defining polynomial x^3 - 10
|
|
130
|
+
|
|
131
|
+
sage: c4, c6 = EllipticCurve('389a1').c_invariants()
|
|
132
|
+
sage: c4c6_model(c4,c6)
|
|
133
|
+
Elliptic Curve defined by y^2 = x^3 - 7/3*x + 107/108 over Rational Field
|
|
134
|
+
"""
|
|
135
|
+
if not assume_nonsingular:
|
|
136
|
+
if not c4c6_nonsingular(c4,c6):
|
|
137
|
+
return None
|
|
138
|
+
return EllipticCurve([0,0,0,-c4/48,-c6/864])
|
|
139
|
+
|
|
140
|
+
# Arithmetic utility functions
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def make_integral(a, P, e):
|
|
144
|
+
r"""
|
|
145
|
+
Return `b` in `O_K` with `P^e|(a-b)`, given `a` in `O_{K,P}`.
|
|
146
|
+
|
|
147
|
+
INPUT:
|
|
148
|
+
|
|
149
|
+
- ``a`` -- a number field element integral at `P`
|
|
150
|
+
|
|
151
|
+
- ``P`` -- a prime ideal of the number field
|
|
152
|
+
|
|
153
|
+
- ``e`` -- positive integer
|
|
154
|
+
|
|
155
|
+
OUTPUT:
|
|
156
|
+
|
|
157
|
+
A globally integral number field element `b` which is congruent to
|
|
158
|
+
`a` modulo `P^e`.
|
|
159
|
+
|
|
160
|
+
ALGORITHM:
|
|
161
|
+
|
|
162
|
+
Totally naive, we simply test residues modulo `P^e` until one
|
|
163
|
+
works. We will only use this when `P` is a prime dividing 2 and `e`
|
|
164
|
+
is the ramification degree, so the number of residues to check is
|
|
165
|
+
at worst `2^d` where `d` is the degree of the field.
|
|
166
|
+
|
|
167
|
+
EXAMPLES::
|
|
168
|
+
|
|
169
|
+
sage: from sage.schemes.elliptic_curves.kraus import make_integral
|
|
170
|
+
|
|
171
|
+
sage: # needs sage.rings.number_field
|
|
172
|
+
sage: x = polygen(ZZ, 'x')
|
|
173
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
174
|
+
sage: P = K.primes_above(2)[0]
|
|
175
|
+
sage: e = P.ramification_index(); e
|
|
176
|
+
2
|
|
177
|
+
sage: x = 1/5
|
|
178
|
+
sage: b = make_integral(x, P, e); b
|
|
179
|
+
1
|
|
180
|
+
sage: (b-x).valuation(P) >= e
|
|
181
|
+
True
|
|
182
|
+
sage: make_integral(1/a, P, e)
|
|
183
|
+
Traceback (most recent call last):
|
|
184
|
+
...
|
|
185
|
+
ArithmeticError: Cannot lift 1/10*a to O_K mod (Fractional ideal (2, a))^2
|
|
186
|
+
"""
|
|
187
|
+
for b in (P**e).residues():
|
|
188
|
+
if (a-b).valuation(P) >= e:
|
|
189
|
+
return b
|
|
190
|
+
raise ArithmeticError("Cannot lift %s to O_K mod (%s)^%s" % (a, P, e))
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def sqrt_mod_4(x, P):
|
|
194
|
+
r"""
|
|
195
|
+
Return a local square root mod 4, if it exists.
|
|
196
|
+
|
|
197
|
+
INPUT:
|
|
198
|
+
|
|
199
|
+
- ``x`` -- an integral number field element
|
|
200
|
+
|
|
201
|
+
- ``P`` -- a prime ideal of the number field dividing 2
|
|
202
|
+
|
|
203
|
+
OUTPUT:
|
|
204
|
+
|
|
205
|
+
A pair ``(True, r)`` where that `r^2-x` has valuation at least `2e`,
|
|
206
|
+
or ``(False, 0)`` if there is no such `r`. Note that
|
|
207
|
+
`r^2\mod{P^{2e}}` only depends on `r\mod{P^e}`.
|
|
208
|
+
|
|
209
|
+
EXAMPLES::
|
|
210
|
+
|
|
211
|
+
sage: # needs sage.rings.number_field
|
|
212
|
+
sage: from sage.schemes.elliptic_curves.kraus import sqrt_mod_4
|
|
213
|
+
sage: x = polygen(ZZ, 'x')
|
|
214
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
215
|
+
sage: P = K.primes_above(2)[0]
|
|
216
|
+
sage: sqrt_mod_4(1 + 2*a, P)
|
|
217
|
+
(False, 0)
|
|
218
|
+
sage: sqrt_mod_4(-1 + 2*a, P)
|
|
219
|
+
(True, a + 1)
|
|
220
|
+
sage: (1+a)^2 - (-1 + 2*a)
|
|
221
|
+
12
|
|
222
|
+
sage: e = P.ramification_index()
|
|
223
|
+
sage: ((1+a)^2 - (-1+2*a)).mod(P**e)
|
|
224
|
+
0
|
|
225
|
+
"""
|
|
226
|
+
e = P.ramification_index()
|
|
227
|
+
P2 = P**e
|
|
228
|
+
for r in P2.residues():
|
|
229
|
+
if (r*r-x).valuation(P) >= 2*e:
|
|
230
|
+
return True, r
|
|
231
|
+
return False, 0
|
|
232
|
+
|
|
233
|
+
# Kraus test and check for primes dividing 3:
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def test_b2_local(c4, c6, P, b2, debug=False):
|
|
237
|
+
r"""
|
|
238
|
+
Test if `b_2` gives a valid model at a prime dividing 3.
|
|
239
|
+
|
|
240
|
+
INPUT:
|
|
241
|
+
|
|
242
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
243
|
+
|
|
244
|
+
- ``P`` -- a prime ideal of the number field which divides 3
|
|
245
|
+
|
|
246
|
+
- ``b2`` -- an element of the number field
|
|
247
|
+
|
|
248
|
+
OUTPUT:
|
|
249
|
+
|
|
250
|
+
The elliptic curve which is the `(b_2/12,0,0)`-transform of
|
|
251
|
+
`[0,0,0,-c_4/48,-c_6/864]` if this is integral at `P`, else ``False``.
|
|
252
|
+
|
|
253
|
+
EXAMPLES::
|
|
254
|
+
|
|
255
|
+
sage: # needs sage.rings.number_field
|
|
256
|
+
sage: x = polygen(ZZ, 'x')
|
|
257
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
258
|
+
sage: c4 = -60544*a + 385796
|
|
259
|
+
sage: c6 = -55799680*a + 262126328
|
|
260
|
+
sage: P3a, P3b = K.primes_above(3)
|
|
261
|
+
sage: from sage.schemes.elliptic_curves.kraus import test_b2_local
|
|
262
|
+
|
|
263
|
+
`b_2=0` works at the first prime but not the second::
|
|
264
|
+
|
|
265
|
+
sage: b2 = 0
|
|
266
|
+
sage: test_b2_local(c4,c6,P3a,b2) # needs sage.rings.number_field
|
|
267
|
+
Elliptic Curve defined by
|
|
268
|
+
y^2 = x^3 + (3784/3*a-96449/12)*x + (1743740/27*a-32765791/108)
|
|
269
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
270
|
+
sage: test_b2_local(c4,c6,P3b,b2) # needs sage.rings.number_field
|
|
271
|
+
False
|
|
272
|
+
|
|
273
|
+
`b_2=-a` works at the second prime but not the first::
|
|
274
|
+
|
|
275
|
+
sage: b2 = -a # needs sage.rings.number_field
|
|
276
|
+
sage: test_b2_local(c4,c6,P3a,b2,debug=True) # needs sage.rings.number_field
|
|
277
|
+
test_b2_local: not integral at Fractional ideal (3, a + 1)
|
|
278
|
+
False
|
|
279
|
+
sage: test_b2_local(c4,c6,P3b,b2) # needs sage.rings.number_field
|
|
280
|
+
Elliptic Curve defined by
|
|
281
|
+
y^2 = x^3 + (-1/4*a)*x^2 + (3784/3*a-192893/24)*x + (56378369/864*a-32879311/108)
|
|
282
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
283
|
+
|
|
284
|
+
Using CRT we can do both with the same `b_2`::
|
|
285
|
+
|
|
286
|
+
sage: b2 = K.solve_CRT([0,-a],[P3a,P3b]); b2 # needs sage.rings.number_field
|
|
287
|
+
a + 1
|
|
288
|
+
sage: test_b2_local(c4,c6,P3a,b2) # needs sage.rings.number_field
|
|
289
|
+
Elliptic Curve defined by
|
|
290
|
+
y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
|
|
291
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
292
|
+
sage: test_b2_local(c4,c6,P3b,b2) # needs sage.rings.number_field
|
|
293
|
+
Elliptic Curve defined
|
|
294
|
+
by y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
|
|
295
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
296
|
+
"""
|
|
297
|
+
E = c4c6_model(c4,c6).rst_transform(b2/12,0,0)
|
|
298
|
+
if not (c4,c6) == E.c_invariants():
|
|
299
|
+
if debug:
|
|
300
|
+
print("test_b2_local: wrong c-invariants at P=%s" % P)
|
|
301
|
+
return False
|
|
302
|
+
if not E.is_local_integral_model(P):
|
|
303
|
+
if debug:
|
|
304
|
+
print("test_b2_local: not integral at %s" % P)
|
|
305
|
+
return False
|
|
306
|
+
return E
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def test_b2_global(c4, c6, b2, debug=False):
|
|
310
|
+
r"""
|
|
311
|
+
Test if `b_2` gives a valid model at all primes dividing 3.
|
|
312
|
+
|
|
313
|
+
INPUT:
|
|
314
|
+
|
|
315
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
316
|
+
|
|
317
|
+
- ``b2`` -- an element of the number field
|
|
318
|
+
|
|
319
|
+
OUTPUT:
|
|
320
|
+
|
|
321
|
+
The elliptic curve which is the `(b_2/12,0,0)`-transform of
|
|
322
|
+
`[0,0,0,-c_4/48,-c_6/864]` if this is integral at all primes `P`
|
|
323
|
+
dividing 3, else ``False``.
|
|
324
|
+
|
|
325
|
+
EXAMPLES::
|
|
326
|
+
|
|
327
|
+
sage: # needs sage.rings.number_field
|
|
328
|
+
sage: x = polygen(ZZ, 'x')
|
|
329
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
330
|
+
sage: c4 = -60544*a + 385796
|
|
331
|
+
sage: c6 = -55799680*a + 262126328
|
|
332
|
+
sage: b2 = a+1
|
|
333
|
+
sage: from sage.schemes.elliptic_curves.kraus import test_b2_global
|
|
334
|
+
sage: test_b2_global(c4,c6,b2)
|
|
335
|
+
Elliptic Curve defined by
|
|
336
|
+
y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
|
|
337
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
338
|
+
sage: test_b2_global(c4,c6,0,debug=True)
|
|
339
|
+
test_b2_global: not integral at all primes dividing 3
|
|
340
|
+
False
|
|
341
|
+
sage: test_b2_global(c4,c6,-a,debug=True)
|
|
342
|
+
test_b2_global: not integral at all primes dividing 3
|
|
343
|
+
False
|
|
344
|
+
"""
|
|
345
|
+
E = c4c6_model(c4,c6).rst_transform(b2/12,0,0)
|
|
346
|
+
if not (c4,c6) == E.c_invariants():
|
|
347
|
+
if debug:
|
|
348
|
+
print("test_b2_global: wrong c-invariants")
|
|
349
|
+
return False
|
|
350
|
+
if not all(E.is_local_integral_model(P)
|
|
351
|
+
for P in c4.parent().primes_above(3)):
|
|
352
|
+
if debug:
|
|
353
|
+
print("test_b2_global: not integral at all primes dividing 3")
|
|
354
|
+
return False
|
|
355
|
+
return E
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def check_Kraus_local_3(c4, c6, P, assume_nonsingular=False, debug=False):
|
|
359
|
+
r"""
|
|
360
|
+
Test if `c_4`, `c_6` satisfy Kraus's conditions at a prime `P` dividing 3.
|
|
361
|
+
|
|
362
|
+
INPUT:
|
|
363
|
+
|
|
364
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
365
|
+
|
|
366
|
+
- ``P`` -- a prime ideal of the number field which divides 3
|
|
367
|
+
|
|
368
|
+
- ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
|
|
369
|
+
check for integrality and nosingularity
|
|
370
|
+
|
|
371
|
+
OUTPUT:
|
|
372
|
+
|
|
373
|
+
Either ``(False, 0)`` if Kraus's conditions fail, or ``(True, b2)`` if
|
|
374
|
+
they pass, in which case the elliptic curve which is the
|
|
375
|
+
`(b_2/12,0,0)`-transform of `[0,0,0,-c_4/48,-c_6/864]` is integral at `P`.
|
|
376
|
+
|
|
377
|
+
EXAMPLES::
|
|
378
|
+
|
|
379
|
+
sage: # needs sage.rings.number_field
|
|
380
|
+
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local_3
|
|
381
|
+
sage: x = polygen(ZZ, 'x')
|
|
382
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
383
|
+
sage: c4 = -60544*a + 385796
|
|
384
|
+
sage: c6 = -55799680*a + 262126328
|
|
385
|
+
sage: P3a, P3b = K.primes_above(3)
|
|
386
|
+
sage: check_Kraus_local_3(c4,c6,P3a)
|
|
387
|
+
(True, 0)
|
|
388
|
+
sage: check_Kraus_local_3(c4,c6,P3b)
|
|
389
|
+
(True, -a)
|
|
390
|
+
|
|
391
|
+
An example in a field where 3 is ramified::
|
|
392
|
+
|
|
393
|
+
sage: # needs sage.rings.number_field
|
|
394
|
+
sage: K.<a> = NumberField(x^2 - 15)
|
|
395
|
+
sage: c4 = -60504*a + 386001
|
|
396
|
+
sage: c6 = -55346820*a + 261045153
|
|
397
|
+
sage: P3 = K.primes_above(3)[0]
|
|
398
|
+
sage: check_Kraus_local_3(c4,c6,P3)
|
|
399
|
+
(True, a)
|
|
400
|
+
"""
|
|
401
|
+
if not assume_nonsingular:
|
|
402
|
+
if not c4c6_nonsingular(c4,c6):
|
|
403
|
+
return False, 0
|
|
404
|
+
e = P.ramification_index()
|
|
405
|
+
P3 = P**e
|
|
406
|
+
if c4.valuation(P) == 0:
|
|
407
|
+
b2 = (-c6*c4.inverse_mod(P3)).mod(P3)
|
|
408
|
+
if debug:
|
|
409
|
+
assert test_b2_local(c4,c6,P,b2)
|
|
410
|
+
return True, b2
|
|
411
|
+
if c6.valuation(P) >= 3*e:
|
|
412
|
+
b2 = c6.parent().zero()
|
|
413
|
+
if debug:
|
|
414
|
+
assert test_b2_local(c4,c6,P,b2)
|
|
415
|
+
return True, b2
|
|
416
|
+
# check for a solution x to x^3-3*x*c4-26=0 (27), such an x must
|
|
417
|
+
# also satisfy x*c4+c6=0 (3) and x^2=c4 (3) and x^3=-c6 (9), and
|
|
418
|
+
# if x is a solution then so is any x'=x (3) so it is enough to
|
|
419
|
+
# check residues mod 3.
|
|
420
|
+
for x in P3.residues():
|
|
421
|
+
if (x*c4+c6).valuation(P) >= e:
|
|
422
|
+
if (x*(x*x-3*c4)-2*c6).valuation(P) >= 3*e:
|
|
423
|
+
if debug:
|
|
424
|
+
assert test_b2_local(c4,c6,P,x)
|
|
425
|
+
return True, x
|
|
426
|
+
return False, 0
|
|
427
|
+
|
|
428
|
+
# Kraus test and check for primes dividing 2:
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def test_a1a3_local(c4, c6, P, a1, a3, debug=False):
|
|
432
|
+
r"""
|
|
433
|
+
Test if `a_1`, `a_3` are valid at a prime `P` dividing `2`.
|
|
434
|
+
|
|
435
|
+
INPUT:
|
|
436
|
+
|
|
437
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
438
|
+
|
|
439
|
+
- ``P`` -- a prime ideal of the number field which divides 2
|
|
440
|
+
|
|
441
|
+
- ``a1``, ``a3`` -- elements of the number field
|
|
442
|
+
|
|
443
|
+
OUTPUT:
|
|
444
|
+
|
|
445
|
+
The elliptic curve which is the `(a_1^2/12,a_1/2,a_3/2)`-transform of
|
|
446
|
+
`[0,0,0,-c_4/48,-c_6/864]` if this is integral at `P`, else ``False``.
|
|
447
|
+
|
|
448
|
+
EXAMPLES::
|
|
449
|
+
|
|
450
|
+
sage: # needs sage.rings.number_field
|
|
451
|
+
sage: from sage.schemes.elliptic_curves.kraus import test_a1a3_local
|
|
452
|
+
sage: x = polygen(ZZ, 'x')
|
|
453
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
454
|
+
sage: c4 = -60544*a + 385796
|
|
455
|
+
sage: c6 = -55799680*a + 262126328
|
|
456
|
+
sage: P = K.primes_above(2)[0]
|
|
457
|
+
sage: test_a1a3_local(c4,c6,P,a,0)
|
|
458
|
+
Elliptic Curve defined by
|
|
459
|
+
y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
|
|
460
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
461
|
+
sage: test_a1a3_local(c4,c6,P,a,a,debug=True)
|
|
462
|
+
test_a1a3_local: not integral at Fractional ideal (2, a)
|
|
463
|
+
False
|
|
464
|
+
"""
|
|
465
|
+
E = c4c6_model(c4,c6).rst_transform(a1**2/12,a1/2,a3/2)
|
|
466
|
+
if not (c4,c6) == E.c_invariants():
|
|
467
|
+
if debug:
|
|
468
|
+
print("test_a1a3_local: wrong c-invariants at P=%s" % P)
|
|
469
|
+
return False
|
|
470
|
+
if not E.is_local_integral_model(P):
|
|
471
|
+
if debug:
|
|
472
|
+
print("test_a1a3_local: not integral at %s" % P)
|
|
473
|
+
return False
|
|
474
|
+
return E
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def test_a1a3_global(c4, c6, a1, a3, debug=False):
|
|
478
|
+
r"""
|
|
479
|
+
Test if `a_1`, `a_3` are valid at all primes `P` dividing 2.
|
|
480
|
+
|
|
481
|
+
INPUT:
|
|
482
|
+
|
|
483
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
484
|
+
|
|
485
|
+
- ``a1``, ``a3`` -- elements of the number field
|
|
486
|
+
|
|
487
|
+
OUTPUT:
|
|
488
|
+
|
|
489
|
+
The elliptic curve which is the `(a_1^2/12,a_1/2,a_3/2)`-transform of
|
|
490
|
+
`[0,0,0,-c_4/48,-c_6/864]` if this is integral at all primes `P`
|
|
491
|
+
dividing 2, else ``False``.
|
|
492
|
+
|
|
493
|
+
EXAMPLES::
|
|
494
|
+
|
|
495
|
+
sage: # needs sage.rings.number_field
|
|
496
|
+
sage: from sage.schemes.elliptic_curves.kraus import test_a1a3_global
|
|
497
|
+
sage: x = polygen(ZZ, 'x')
|
|
498
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
499
|
+
sage: c4 = -60544*a + 385796
|
|
500
|
+
sage: c6 = -55799680*a + 262126328
|
|
501
|
+
sage: test_a1a3_global(c4,c6,a,a,debug=False)
|
|
502
|
+
False
|
|
503
|
+
sage: test_a1a3_global(c4,c6,a,0)
|
|
504
|
+
Elliptic Curve defined by
|
|
505
|
+
y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
|
|
506
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
507
|
+
"""
|
|
508
|
+
E = c4c6_model(c4,c6).rst_transform(a1**2/12,a1/2,a3/2)
|
|
509
|
+
if not (c4, c6) == E.c_invariants():
|
|
510
|
+
if debug:
|
|
511
|
+
print("wrong c-invariants")
|
|
512
|
+
return False
|
|
513
|
+
if not all(E.is_local_integral_model(P)
|
|
514
|
+
for P in c4.parent().primes_above(2)):
|
|
515
|
+
if debug:
|
|
516
|
+
print("not integral at all primes above 2")
|
|
517
|
+
return False
|
|
518
|
+
return E
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def test_rst_global(c4, c6, r, s, t, debug=False):
|
|
522
|
+
r"""
|
|
523
|
+
Test if the `(r,s,t)`-transform of the standard `c_4,c_6`-model is integral.
|
|
524
|
+
|
|
525
|
+
INPUT:
|
|
526
|
+
|
|
527
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
528
|
+
|
|
529
|
+
- ``r``, ``s``, ``t`` -- elements of the number field
|
|
530
|
+
|
|
531
|
+
OUTPUT:
|
|
532
|
+
|
|
533
|
+
The elliptic curve which is the `(r,s,t)`-transform of
|
|
534
|
+
`[0,0,0,-c_4/48,-c_6/864]` if this is integral at all primes `P`, else
|
|
535
|
+
``False``.
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: # needs sage.rings.number_field
|
|
540
|
+
sage: from sage.schemes.elliptic_curves.kraus import test_rst_global
|
|
541
|
+
sage: x = polygen(ZZ, 'x')
|
|
542
|
+
sage: K.<a> = NumberField(x^2-10)
|
|
543
|
+
sage: c4 = -60544*a + 385796
|
|
544
|
+
sage: c6 = -55799680*a + 262126328
|
|
545
|
+
sage: test_rst_global(c4,c6,1/3*a - 133/6, 3/2*a, -89/2*a + 5)
|
|
546
|
+
Elliptic Curve defined by
|
|
547
|
+
y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
|
|
548
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
549
|
+
sage: test_rst_global(c4,c6,a, 3, -89*a, debug=False)
|
|
550
|
+
False
|
|
551
|
+
"""
|
|
552
|
+
E = c4c6_model(c4,c6).rst_transform(r,s,t)
|
|
553
|
+
if not (c4,c6) == E.c_invariants():
|
|
554
|
+
if debug:
|
|
555
|
+
print("test_rst_global: wrong c-invariants")
|
|
556
|
+
return False
|
|
557
|
+
if not E.is_global_integral_model():
|
|
558
|
+
if debug:
|
|
559
|
+
print("test_rst_global: not integral at some prime")
|
|
560
|
+
print(E.ainvs())
|
|
561
|
+
K = E.base_field()
|
|
562
|
+
for P in K.primes_above(2)+K.primes_above(3):
|
|
563
|
+
if not E.is_local_integral_model(P):
|
|
564
|
+
print(" -- not integral at P=%s" % P)
|
|
565
|
+
return False
|
|
566
|
+
return E
|
|
567
|
+
|
|
568
|
+
# When a1 is None this function finds a pair a1, a3 such that there is
|
|
569
|
+
# a model with these invariants and a2=0 with the given c4, c6,
|
|
570
|
+
# integral at P. The value of a1 is unique modulo 2 (i.e. mod P^e
|
|
571
|
+
# where e is the ramification degree of 2); the value of a3 is unique
|
|
572
|
+
# mod 2 once a1 is fixed, but not otherwise: when a1 is replaced by
|
|
573
|
+
# a1+2s we must replace a3 by a3 + a1*s*(a1+s).
|
|
574
|
+
|
|
575
|
+
# Because of the latter point, and to fix the bug at #19665, we allow
|
|
576
|
+
# the user to specify a1, in which case a3 is computed from it. This
|
|
577
|
+
# is important in the global application where we need to put together
|
|
578
|
+
# the transforms for all the primes above 2: we must first get the
|
|
579
|
+
# local a1's, then CRT these to get a global a1, then go back to get
|
|
580
|
+
# the local a3's and finally CRT these.
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
def check_Kraus_local_2(c4, c6, P, a1=None, assume_nonsingular=False):
|
|
584
|
+
r"""
|
|
585
|
+
Test if `c_4`, `c_6` satisfy Kraus's conditions at a prime `P` dividing 2.
|
|
586
|
+
|
|
587
|
+
INPUT:
|
|
588
|
+
|
|
589
|
+
- ``c4``, ``c6`` -- integral elements of a number field
|
|
590
|
+
|
|
591
|
+
- ``P`` -- a prime ideal of the number field which divides 2
|
|
592
|
+
|
|
593
|
+
- ``a1`` -- an integral elements of a number field, or ``None`` (default)
|
|
594
|
+
|
|
595
|
+
- ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
|
|
596
|
+
check for integrality and nonsingularity
|
|
597
|
+
|
|
598
|
+
OUTPUT:
|
|
599
|
+
|
|
600
|
+
Either ``(False, 0, 0)`` if Kraus's conditions fail, or ``(True, a1,
|
|
601
|
+
a3)`` if they pass, in which case the elliptic curve which is the
|
|
602
|
+
`(a_1^2/12,a_1/2,a_3/2)`-transform of `[0,0,0,-c_4/48,-c_6/864]` is
|
|
603
|
+
integral at `P`. If `a_1` is provided and valid then the output will
|
|
604
|
+
be ``(True, a1, a3)`` for suitable `a_3`.
|
|
605
|
+
|
|
606
|
+
EXAMPLES::
|
|
607
|
+
|
|
608
|
+
sage: # needs sage.rings.number_field
|
|
609
|
+
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local_2
|
|
610
|
+
sage: x = polygen(ZZ, 'x')
|
|
611
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
612
|
+
sage: c4 = -60544*a + 385796 # EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
|
|
613
|
+
sage: c6 = -55799680*a + 262126328
|
|
614
|
+
sage: P = K.primes_above(2)[0]
|
|
615
|
+
sage: check_Kraus_local_2(c4,c6,P)
|
|
616
|
+
(True, a, 0)
|
|
617
|
+
"""
|
|
618
|
+
if not assume_nonsingular:
|
|
619
|
+
if not c4c6_nonsingular(c4,c6):
|
|
620
|
+
return False,0,0
|
|
621
|
+
e = P.ramification_index()
|
|
622
|
+
P2 = P**e
|
|
623
|
+
c4val = c4.valuation(P)
|
|
624
|
+
|
|
625
|
+
if c4val == 0:
|
|
626
|
+
if a1 is None:
|
|
627
|
+
flag, t = sqrt_mod_4(-c6,P)
|
|
628
|
+
if not flag:
|
|
629
|
+
return False,0,0
|
|
630
|
+
# In the assignment to a1, a3 we divide by units at P,
|
|
631
|
+
# (note that c6+a1**6 = 0 mod P**e so dividing by 4 is OK)
|
|
632
|
+
# but the results, which are well-defined modulo P^e, may
|
|
633
|
+
# not be globally integral
|
|
634
|
+
a1 = make_integral(c4/t,P,e)
|
|
635
|
+
a13 = a1**3
|
|
636
|
+
a3 = make_integral((c6+a13**2)/(4*a13),P,2*e)
|
|
637
|
+
if test_a1a3_local(c4,c6,P,a1,a3):
|
|
638
|
+
return True, a1,a3
|
|
639
|
+
else:
|
|
640
|
+
raise RuntimeError("check_Kraus_local_2 fails")
|
|
641
|
+
|
|
642
|
+
if c4val >= 4*e:
|
|
643
|
+
if a1 is None:
|
|
644
|
+
a1 = c4.parent().zero() # 0
|
|
645
|
+
flag, a3 = sqrt_mod_4(c6/8,P)
|
|
646
|
+
if flag:
|
|
647
|
+
if test_a1a3_local(c4,c6,P,a1,a3):
|
|
648
|
+
return True, a1,a3
|
|
649
|
+
else:
|
|
650
|
+
raise RuntimeError("check_Kraus_local_2 fails")
|
|
651
|
+
else:
|
|
652
|
+
return False,0,0
|
|
653
|
+
|
|
654
|
+
# val(c4) strictly between 0 and 4e; a1 unique mod 2, with 3 conditions to be satisfied:
|
|
655
|
+
|
|
656
|
+
P2res = [a1] if a1 else P2.residues()
|
|
657
|
+
for a1 in P2res:
|
|
658
|
+
Px = -a1**6+3*a1**2*c4+2*c6
|
|
659
|
+
if Px.valuation(P) >= 4*e: # (i)
|
|
660
|
+
flag, a3 = sqrt_mod_4(Px/16,P) # (ii)
|
|
661
|
+
if flag:
|
|
662
|
+
a1sq = a1*a1
|
|
663
|
+
if (4*a1sq*Px-(a1sq**2-c4)**2).valuation(P) >= 8*e: # (iii)
|
|
664
|
+
if test_a1a3_local(c4,c6,P,a1,a3):
|
|
665
|
+
return True, a1, a3
|
|
666
|
+
else:
|
|
667
|
+
raise RuntimeError("check_Kraus_local_2 fails")
|
|
668
|
+
# end of loop, but no a1 found
|
|
669
|
+
return False, 0, 0
|
|
670
|
+
|
|
671
|
+
# Wrapper function for local Kraus check, outsources the real work to
|
|
672
|
+
# other functions for primes dividing 2 or 3:
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
def check_Kraus_local(c4, c6, P, assume_nonsingular=False):
|
|
676
|
+
r"""
|
|
677
|
+
Check Kraus's conditions locally at a prime `P`.
|
|
678
|
+
|
|
679
|
+
INPUT:
|
|
680
|
+
|
|
681
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
682
|
+
|
|
683
|
+
- ``P`` -- a prime ideal of the number field
|
|
684
|
+
|
|
685
|
+
- ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
|
|
686
|
+
check for integrality and nonsingularity
|
|
687
|
+
|
|
688
|
+
OUTPUT:
|
|
689
|
+
|
|
690
|
+
Tuple: either ``(True, E)`` if there is a Weierstrass model `E` integral
|
|
691
|
+
at `P` and with invariants `c_4`, `c_6`, or ``(False, None)`` if there is
|
|
692
|
+
none.
|
|
693
|
+
|
|
694
|
+
EXAMPLES::
|
|
695
|
+
|
|
696
|
+
sage: # needs sage.rings.number_field
|
|
697
|
+
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local
|
|
698
|
+
sage: x = polygen(ZZ, 'x')
|
|
699
|
+
sage: K.<a> = NumberField(x^2 - 15)
|
|
700
|
+
sage: P2 = K.primes_above(2)[0]
|
|
701
|
+
sage: P3 = K.primes_above(3)[0]
|
|
702
|
+
sage: P5 = K.primes_above(5)[0]
|
|
703
|
+
sage: E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
|
|
704
|
+
sage: c4, c6 = E.c_invariants()
|
|
705
|
+
sage: flag, E = check_Kraus_local(c4,c6,P2); flag
|
|
706
|
+
True
|
|
707
|
+
sage: E.is_local_integral_model(P2) and (c4,c6)==E.c_invariants()
|
|
708
|
+
True
|
|
709
|
+
sage: flag, E = check_Kraus_local(c4,c6,P3); flag
|
|
710
|
+
True
|
|
711
|
+
sage: E.is_local_integral_model(P3) and (c4,c6)==E.c_invariants()
|
|
712
|
+
True
|
|
713
|
+
sage: flag, E = check_Kraus_local(c4,c6,P5); flag
|
|
714
|
+
True
|
|
715
|
+
sage: E.is_local_integral_model(P5) and (c4,c6)==E.c_invariants()
|
|
716
|
+
True
|
|
717
|
+
|
|
718
|
+
sage: # needs sage.rings.number_field
|
|
719
|
+
sage: c4 = 123+456*a
|
|
720
|
+
sage: c6 = 789+101112*a
|
|
721
|
+
sage: check_Kraus_local(c4,c6,P2)
|
|
722
|
+
(False, None)
|
|
723
|
+
sage: check_Kraus_local(c4,c6,P3)
|
|
724
|
+
(False, None)
|
|
725
|
+
sage: check_Kraus_local(c4,c6,P5)
|
|
726
|
+
(False, None)
|
|
727
|
+
"""
|
|
728
|
+
if not assume_nonsingular:
|
|
729
|
+
if not c4c6_nonsingular(c4,c6):
|
|
730
|
+
return False, None
|
|
731
|
+
K = c4.parent()
|
|
732
|
+
if K(2).valuation(P) > 0:
|
|
733
|
+
flag, a1, a3 = check_Kraus_local_2(c4,c6,P,None,True)
|
|
734
|
+
if flag:
|
|
735
|
+
E = test_a1a3_local(c4,c6,P,a1,a3)
|
|
736
|
+
if E:
|
|
737
|
+
return (True, E)
|
|
738
|
+
return (False, None)
|
|
739
|
+
if K(3).valuation(P) > 0:
|
|
740
|
+
flag, b2 = check_Kraus_local_3(c4,c6,P,True)
|
|
741
|
+
if flag:
|
|
742
|
+
E = test_b2_local(c4,c6,P,b2)
|
|
743
|
+
if E:
|
|
744
|
+
return (True, E)
|
|
745
|
+
return (False, None)
|
|
746
|
+
return (True, c4c6_model(c4,c6))
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
def check_Kraus_global(c4, c6, assume_nonsingular=False, debug=False):
|
|
750
|
+
r"""
|
|
751
|
+
Test if `c_4`, `c_6` satisfy Kraus's conditions at all primes.
|
|
752
|
+
|
|
753
|
+
INPUT:
|
|
754
|
+
|
|
755
|
+
- ``c4``, ``c6`` -- elements of a number field
|
|
756
|
+
|
|
757
|
+
- ``assume_nonsingular`` -- boolean (default: ``False``); if ``True``,
|
|
758
|
+
check for integrality and nonsingularity
|
|
759
|
+
|
|
760
|
+
OUTPUT:
|
|
761
|
+
|
|
762
|
+
Either ``False`` if Kraus's conditions fail, or, if they pass, an
|
|
763
|
+
elliptic curve `E` which is integral and has c-invariants `c_4`, `c_6`.
|
|
764
|
+
|
|
765
|
+
EXAMPLES::
|
|
766
|
+
|
|
767
|
+
sage: # needs sage.rings.number_field
|
|
768
|
+
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_global
|
|
769
|
+
sage: x = polygen(ZZ, 'x')
|
|
770
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
771
|
+
sage: E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
|
|
772
|
+
sage: c4, c6 = E.c_invariants()
|
|
773
|
+
sage: check_Kraus_global(c4,c6,debug=True)
|
|
774
|
+
Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 3
|
|
775
|
+
Using b2=a + 1 gives a model integral at 3:
|
|
776
|
+
(0, 1/4*a + 1/4, 0, 10091/8*a - 128595/16, 4097171/64*a - 19392359/64)
|
|
777
|
+
Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 2
|
|
778
|
+
Using (a1,a3)=(3*a,0) gives a model integral at 2:
|
|
779
|
+
(3*a, 0, 0, 3784/3*a - 23606/3, 1999160/27*a - 9807634/27)
|
|
780
|
+
(a1, b2, a3) = (3*a, a + 1, 0)
|
|
781
|
+
Using (r, s, t)=(1/3*a - 133/6, 3/2*a, -89/2*a + 5) should give a global integral model...
|
|
782
|
+
...and it does!
|
|
783
|
+
Elliptic Curve defined by
|
|
784
|
+
y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
|
|
785
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
786
|
+
|
|
787
|
+
sage: # needs sage.rings.number_field
|
|
788
|
+
sage: K.<a> = NumberField(x^2 - 15)
|
|
789
|
+
sage: E = EllipticCurve([0, 0, 0, 4536*a + 14148, -163728*a - 474336])
|
|
790
|
+
sage: c4, c6 = E.c_invariants()
|
|
791
|
+
sage: check_Kraus_global(c4,c6)
|
|
792
|
+
Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
|
|
793
|
+
over Number Field in a with defining polynomial x^2 - 15
|
|
794
|
+
|
|
795
|
+
TESTS (see :issue:`17295`)::
|
|
796
|
+
|
|
797
|
+
sage: # needs sage.groups sage.rings.number_field
|
|
798
|
+
sage: K.<a> = NumberField(x^3 - 7*x - 5)
|
|
799
|
+
sage: E = EllipticCurve([a, 0, 1, 2*a^2 + 5*a + 3, -a^2 - 3*a - 2])
|
|
800
|
+
sage: assert E.conductor().norm() == 8
|
|
801
|
+
sage: G = K.galois_group(names='b')
|
|
802
|
+
sage: def conj_curve(E, sigma): return EllipticCurve([sigma(a) for a in E.ainvs()])
|
|
803
|
+
sage: EL = conj_curve(E,G[0])
|
|
804
|
+
sage: L = EL.base_field()
|
|
805
|
+
sage: assert L.class_number() == 2
|
|
806
|
+
sage: EL.isogeny_class() # long time (~10s)
|
|
807
|
+
Isogeny class of Elliptic Curve defined by
|
|
808
|
+
y^2 + (-1/90*b^4+7/18*b^2-1/2*b-98/45)*x*y + y = x^3 + (1/45*b^5-1/18*b^4-7/9*b^3+41/18*b^2+167/90*b-29/9)*x + (-1/90*b^5+1/30*b^4+7/18*b^3-4/3*b^2-61/90*b+11/5)
|
|
809
|
+
over Number Field in b with defining polynomial x^6 - 42*x^4 + 441*x^2 - 697
|
|
810
|
+
"""
|
|
811
|
+
if not assume_nonsingular:
|
|
812
|
+
if not c4c6_nonsingular(c4,c6):
|
|
813
|
+
return False
|
|
814
|
+
|
|
815
|
+
# Check all primes dividing 3; for each get the value of b2
|
|
816
|
+
K = c4.parent()
|
|
817
|
+
three = K.ideal(3)
|
|
818
|
+
Plist3 = K.primes_above(3)
|
|
819
|
+
dat = [check_Kraus_local_3(c4,c6,P,True) for P in Plist3]
|
|
820
|
+
if not all(d[0] for d in dat):
|
|
821
|
+
if debug:
|
|
822
|
+
print("Local Kraus condition for (c4,c6)=(%s,%s) fails at some prime dividing 3" % (c4,c6))
|
|
823
|
+
return False
|
|
824
|
+
if debug:
|
|
825
|
+
print("Local Kraus conditions for (c4,c6)=(%s,%s) pass at all primes dividing 3" % (c4,c6))
|
|
826
|
+
|
|
827
|
+
# OK at all primes dividing 3; now use CRT to combine the b2
|
|
828
|
+
# values to get a single residue class for b2 mod 3:
|
|
829
|
+
|
|
830
|
+
b2list = [d[1] for d in dat]
|
|
831
|
+
P3list = [P**three.valuation(P) for P in Plist3]
|
|
832
|
+
b2 = K.solve_CRT(b2list,P3list, check=True).mod(three)
|
|
833
|
+
|
|
834
|
+
# test that this b2 value works at all P|3:
|
|
835
|
+
if debug:
|
|
836
|
+
E = test_b2_global(c4,c6,b2)
|
|
837
|
+
if E:
|
|
838
|
+
print("Using b2=%s gives a model integral at 3:\n%s" % (b2,E.ainvs()))
|
|
839
|
+
else:
|
|
840
|
+
raise RuntimeError("Error in check_Kraus_global at some prime dividing 3")
|
|
841
|
+
|
|
842
|
+
# Check all primes dividing 2; for each get the value of a1, then
|
|
843
|
+
# CRT these to get a single a1 (mod 2) and use these to obtain
|
|
844
|
+
# local a3; finally CRT these
|
|
845
|
+
two = K.ideal(2)
|
|
846
|
+
Plist2 = K.primes_above(2)
|
|
847
|
+
dat = [check_Kraus_local_2(c4, c6, P, None, True) for P in Plist2]
|
|
848
|
+
if not all(d[0] for d in dat):
|
|
849
|
+
if debug:
|
|
850
|
+
print("Local Kraus condition for (c4,c6)=(%s,%s) fails at some prime dividing 2" % (c4, c6))
|
|
851
|
+
return False
|
|
852
|
+
if debug:
|
|
853
|
+
print("Local Kraus conditions for (c4,c6)=(%s,%s) pass at all primes dividing 2" % (c4,c6))
|
|
854
|
+
|
|
855
|
+
# OK at all primes dividing 2; now use CRT to combine the a1
|
|
856
|
+
# values to get the residue classes of a1 mod 2:
|
|
857
|
+
P2list = [P**(two.valuation(P)) for P in Plist2]
|
|
858
|
+
a1list = [d[1] for d in dat]
|
|
859
|
+
a1 = K.solve_CRT(a1list,P2list, check=True)
|
|
860
|
+
# See comment below: this is needed for when we combine with the primes above 3.
|
|
861
|
+
if a1 not in three: # three.divides(a1) causes a segfault
|
|
862
|
+
a1 = 3*a1
|
|
863
|
+
|
|
864
|
+
# Using this a1, recompute the local a3's:
|
|
865
|
+
dat = [check_Kraus_local_2(c4,c6,P,a1,True) for P in Plist2]
|
|
866
|
+
# Use CRT to combine these:
|
|
867
|
+
a3list = [d[2] for d in dat]
|
|
868
|
+
a3 = K.solve_CRT(a3list,P2list, check=True)
|
|
869
|
+
|
|
870
|
+
# test that these a1,a3 values work at all P|2:
|
|
871
|
+
if debug:
|
|
872
|
+
E = test_a1a3_global(c4,c6,a1,a3,debug)
|
|
873
|
+
if E:
|
|
874
|
+
print("Using (a1,a3)=(%s,%s) gives a model integral at 2:\n%s" % (a1,a3,E.ainvs()))
|
|
875
|
+
else:
|
|
876
|
+
raise RuntimeError("Error in check_Kraus_global at some prime dividing 2")
|
|
877
|
+
|
|
878
|
+
# Now we put together the 2-adic and 3-adic transforms to get a
|
|
879
|
+
# global (r,s,t)-transform from [0,0,0,-c4/48,-c6/864] to a global
|
|
880
|
+
# integral model.
|
|
881
|
+
|
|
882
|
+
# We need the combined transform (r,s,t) to have both the forms
|
|
883
|
+
# (r,s,t) = (a1^2/12,a1/2,a3/2)*(r2,0,0) with 2-integral r2, and
|
|
884
|
+
# (r,s,t) = (b2/12,0,0,0)*(r3,s3,t3) with 3-integral r3,s3,t3.
|
|
885
|
+
|
|
886
|
+
# A solution (assuming that a1,a3,b2 are globally integral) is
|
|
887
|
+
# r2=(b2-a1^2)/3, r3=(b2-a1^2)/4, s3=a1/2, t3=(a1*r2+a3)/2,
|
|
888
|
+
# provided that a1 =0 (mod 3), to make t3 3-integral. Since a1
|
|
889
|
+
# was only determined mod 2 this can be fixed first, simply by
|
|
890
|
+
# multiplying a1 by 3 if necessary. We did this above.
|
|
891
|
+
|
|
892
|
+
if debug:
|
|
893
|
+
print("(a1, b2, a3) = (%s, %s, %s)" % (a1,b2,a3))
|
|
894
|
+
assert a1.is_integral()
|
|
895
|
+
assert a3.is_integral()
|
|
896
|
+
assert b2.is_integral()
|
|
897
|
+
s = a1/2
|
|
898
|
+
r = b2/3 - s**2
|
|
899
|
+
t = s*(b2-a1**2)/3 + a3/2
|
|
900
|
+
if debug:
|
|
901
|
+
print("Using (r, s, t)=(%s, %s, %s) should give a global integral model..." % (r,s,t))
|
|
902
|
+
|
|
903
|
+
# Final computation of the curve E:
|
|
904
|
+
E = test_rst_global(c4,c6,r,s,t,debug)
|
|
905
|
+
if not E:
|
|
906
|
+
if debug:
|
|
907
|
+
print("Error in check_Kraus_global with combining mod-2 and mod-3 transforms")
|
|
908
|
+
E = c4c6_model(c4,c6).rst_transform(r,s,t)
|
|
909
|
+
print("Transformed model is %a" % (E.ainvs(),))
|
|
910
|
+
for P in Plist2+Plist3:
|
|
911
|
+
if not E.is_local_integral_model(P):
|
|
912
|
+
print("Not integral at P=%s" % P)
|
|
913
|
+
raise RuntimeError("Error in check_Kraus_global combining transforms at 2 and 3")
|
|
914
|
+
|
|
915
|
+
# Success!
|
|
916
|
+
if debug:
|
|
917
|
+
print("...and it does!")
|
|
918
|
+
return E
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
def semi_global_minimal_model(E, debug=False):
|
|
922
|
+
r"""
|
|
923
|
+
Return a global minimal model for this elliptic curve if it
|
|
924
|
+
exists, or a model minimal at all but one prime otherwise.
|
|
925
|
+
|
|
926
|
+
INPUT:
|
|
927
|
+
|
|
928
|
+
- ``E`` -- an elliptic curve over a number field
|
|
929
|
+
|
|
930
|
+
- ``debug`` -- boolean (default: ``False``); if ``True``, prints some
|
|
931
|
+
messages about the progress of the computation
|
|
932
|
+
|
|
933
|
+
OUTPUT:
|
|
934
|
+
|
|
935
|
+
A tuple ``(Emin, I)`` where ``Emin`` is an elliptic curve which is either a
|
|
936
|
+
global minimal model of `E` if one exists (i.e., an integral model
|
|
937
|
+
which is minimal at every prime), or a semi-global minimal model
|
|
938
|
+
(i.e., an integral model which is minimal at every prime except
|
|
939
|
+
one). `I` is the unit ideal of ``Emin`` is a global minimal model, else
|
|
940
|
+
is the unique prime at which ``Emin`` is not minimal. Thus in all
|
|
941
|
+
cases,
|
|
942
|
+
``Emin.minimal_discriminant_ideal() * I**12 == (E.discriminant())``.
|
|
943
|
+
|
|
944
|
+
.. NOTE::
|
|
945
|
+
|
|
946
|
+
This function is normally not called directly by users, who
|
|
947
|
+
will use the elliptic curve method :meth:`global_minimal_model`
|
|
948
|
+
instead; that method also applied various reductions after
|
|
949
|
+
minimising the model.
|
|
950
|
+
|
|
951
|
+
EXAMPLES::
|
|
952
|
+
|
|
953
|
+
sage: # needs sage.rings.number_field
|
|
954
|
+
sage: x = polygen(ZZ, 'x')
|
|
955
|
+
sage: K.<a> = NumberField(x^2 - 10)
|
|
956
|
+
sage: K.class_number()
|
|
957
|
+
2
|
|
958
|
+
sage: E = EllipticCurve([0,0,0,-186408*a - 589491, 78055704*a + 246833838])
|
|
959
|
+
sage: from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
|
|
960
|
+
sage: Emin, P = semi_global_minimal_model(E)
|
|
961
|
+
sage: Emin
|
|
962
|
+
Elliptic Curve defined by
|
|
963
|
+
y^2 + 3*x*y + (2*a-11)*y = x^3 + (a-10)*x^2 + (-152*a-415)*x + (1911*a+5920)
|
|
964
|
+
over Number Field in a with defining polynomial x^2 - 10
|
|
965
|
+
sage: E.minimal_discriminant_ideal()*P**12 == K.ideal(Emin.discriminant())
|
|
966
|
+
True
|
|
967
|
+
|
|
968
|
+
TESTS:
|
|
969
|
+
|
|
970
|
+
Consider (see :issue:`20737`) a curve with no global minimal model
|
|
971
|
+
whose non-minimality class has order 3 in the class group, which
|
|
972
|
+
has order 3315. The smallest prime in that ideal class has norm
|
|
973
|
+
23567::
|
|
974
|
+
|
|
975
|
+
sage: # long time, needs sage.rings.number_field
|
|
976
|
+
sage: K.<a> = NumberField(x^2 - x + 31821453)
|
|
977
|
+
sage: ainvs = (0, 0, 0, -382586771000351226384*a - 2498023791133552294513515,
|
|
978
|
+
....: 358777608829102441023422458989744*a + 1110881475104109582383304709231832166)
|
|
979
|
+
sage: E = EllipticCurve(ainvs)
|
|
980
|
+
sage: from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
|
|
981
|
+
sage: Emin, p = semi_global_minimal_model(E) # 25s
|
|
982
|
+
sage: p
|
|
983
|
+
Fractional ideal (23567, a + 2270)
|
|
984
|
+
sage: p.norm()
|
|
985
|
+
23567
|
|
986
|
+
sage: Emin.discriminant().norm().factor()
|
|
987
|
+
23567^12
|
|
988
|
+
"""
|
|
989
|
+
c = E.global_minimality_class()
|
|
990
|
+
I = c.ideal()
|
|
991
|
+
c4, c6 = E.c_invariants()
|
|
992
|
+
if c.is_one():
|
|
993
|
+
P = E.base_field().ideal(1)
|
|
994
|
+
else:
|
|
995
|
+
if debug:
|
|
996
|
+
print("No global minimal model, obstruction class = %s of order %s" % (c, c.order()))
|
|
997
|
+
bound = E.base_field().minkowski_bound().round() * 5
|
|
998
|
+
have_prime = False
|
|
999
|
+
while not have_prime:
|
|
1000
|
+
try:
|
|
1001
|
+
P = c.representative_prime(norm_bound=bound)
|
|
1002
|
+
have_prime = True
|
|
1003
|
+
except RuntimeError:
|
|
1004
|
+
bound *= 2
|
|
1005
|
+
if debug:
|
|
1006
|
+
print("Using prime {} of norm {} in that class".format(P, P.norm()))
|
|
1007
|
+
I = I / P
|
|
1008
|
+
u = I.gens_reduced()[0]
|
|
1009
|
+
rc4 = c4 / u**4
|
|
1010
|
+
rc6 = c6 / u**6
|
|
1011
|
+
Emin = check_Kraus_global(rc4, rc6, assume_nonsingular=True, debug=debug)
|
|
1012
|
+
if Emin:
|
|
1013
|
+
return Emin, P
|
|
1014
|
+
raise RuntimeError("failed to compute global minimal model")
|