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,2797 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Isogenies of small prime degree
|
|
4
|
+
|
|
5
|
+
Functions for the computation of isogenies of small primes degree. First: `l` =
|
|
6
|
+
2, 3, 5, 7, or 13, where the modular curve `X_0(l)` has genus 0. Second: `l` =
|
|
7
|
+
11, 17, 19, 23, 29, 31, 41, 47, 59, or 71, where `X_0^+(l)` has genus 0 and
|
|
8
|
+
`X_0(l)` is elliptic or hyperelliptic. Also: `l` = 11, 17, 19, 37, 43, 67 or
|
|
9
|
+
163 over `\QQ` (the sporadic cases with only finitely many `j`-invariants
|
|
10
|
+
each). All the above only require factorization of a polynomial of degree
|
|
11
|
+
`l+1`. Finally, a generic function which works for arbitrary odd primes `l`
|
|
12
|
+
(including the characteristic), but requires factorization of the `l`-division
|
|
13
|
+
polynomial, of degree `(l^2-1)/2`.
|
|
14
|
+
|
|
15
|
+
AUTHORS:
|
|
16
|
+
|
|
17
|
+
- John Cremona and Jenny Cooley: 2009-07..11: the genus 0 cases the sporadic
|
|
18
|
+
cases over `\QQ`.
|
|
19
|
+
|
|
20
|
+
- Kimi Tsukazaki and John Cremona: 2013-07: The 10 (hyper)-elliptic cases and
|
|
21
|
+
the generic algorithm. See [KT2013]_.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# ****************************************************************************
|
|
25
|
+
# Copyright (C) 2012-2013 John Cremona, Jenny Cooley, Kimi Tsukazaki
|
|
26
|
+
#
|
|
27
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
28
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
29
|
+
# the License, or (at your option) any later version.
|
|
30
|
+
# https://www.gnu.org/licenses/
|
|
31
|
+
# ****************************************************************************
|
|
32
|
+
|
|
33
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
34
|
+
from sage.rings.polynomial.polynomial_ring import polygen
|
|
35
|
+
from sage.rings.integer_ring import ZZ
|
|
36
|
+
from sage.rings.rational_field import QQ
|
|
37
|
+
from sage.schemes.elliptic_curves.constructor import EllipticCurve
|
|
38
|
+
|
|
39
|
+
from sage.misc.cachefunc import cached_function
|
|
40
|
+
|
|
41
|
+
##########################################################################
|
|
42
|
+
# The following section is all about computing l-isogenies, where l is
|
|
43
|
+
# a prime. The genus 0 cases `l` = 2, 3, 5, 7 and 13 are
|
|
44
|
+
# implemented over any field of characteristic not 2, 3 or `l`; over
|
|
45
|
+
# `\QQ` the "sporadic" cases `l` = 11, 17, 19, 37, 43, 67 or 163 with
|
|
46
|
+
# only finitely many `j`-invariants each. are also implemented.
|
|
47
|
+
##########################################################################
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@cached_function
|
|
51
|
+
def Fricke_polynomial(l):
|
|
52
|
+
r"""
|
|
53
|
+
Fricke polynomial for ``l`` =2,3,5,7,13.
|
|
54
|
+
|
|
55
|
+
For these primes (and these only) the modular curve `X_0(l)` has
|
|
56
|
+
genus zero, and its field is generated by a single modular
|
|
57
|
+
function called the Fricke module (or Hauptmodul), `t`. There is
|
|
58
|
+
a classical choice of such a generator `t` in each case, and the
|
|
59
|
+
`j`-function is a rational function of `t` of degree `l+1` of the
|
|
60
|
+
form `P(t)/t` where `P` is a polynomial of degree `l+1`. Up to
|
|
61
|
+
scaling, `t` is determined by the condition that the ramification
|
|
62
|
+
points above `j=\infty` are `t=0` (with ramification degree `1`)
|
|
63
|
+
and `t=\infty` (with degree `l`). The ramification above `j=0`
|
|
64
|
+
and `j=1728` may be seen in the factorizations of `j(t)` and
|
|
65
|
+
`k(t)` where `k=j-1728`.
|
|
66
|
+
|
|
67
|
+
OUTPUT:
|
|
68
|
+
|
|
69
|
+
The polynomial `P(t)` as an element of `\ZZ[t]`.
|
|
70
|
+
|
|
71
|
+
TESTS::
|
|
72
|
+
|
|
73
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_polynomial
|
|
74
|
+
sage: Fricke_polynomial(2)
|
|
75
|
+
t^3 + 48*t^2 + 768*t + 4096
|
|
76
|
+
sage: Fricke_polynomial(3)
|
|
77
|
+
t^4 + 36*t^3 + 270*t^2 + 756*t + 729
|
|
78
|
+
sage: Fricke_polynomial(5)
|
|
79
|
+
t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125
|
|
80
|
+
sage: Fricke_polynomial(7)
|
|
81
|
+
t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49
|
|
82
|
+
sage: Fricke_polynomial(13)
|
|
83
|
+
t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8
|
|
84
|
+
+ 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3
|
|
85
|
+
+ 15145*t^2 + 746*t + 13
|
|
86
|
+
"""
|
|
87
|
+
t = PolynomialRing(ZZ, 't').gen()
|
|
88
|
+
if l == 2:
|
|
89
|
+
return (t+16)**3
|
|
90
|
+
elif l == 3:
|
|
91
|
+
return (t+3)**3*(t+27)
|
|
92
|
+
elif l == 5:
|
|
93
|
+
return (t**2+10*t+5)**3
|
|
94
|
+
elif l == 7:
|
|
95
|
+
return (t**2+5*t+1)**3 * (t**2+13*t+49)
|
|
96
|
+
elif l == 13:
|
|
97
|
+
return (t**2+5*t+13)*(t**4+7*t**3+20*t**2+19*t+1)**3
|
|
98
|
+
else:
|
|
99
|
+
raise ValueError("The only genus zero primes are 2, 3, 5, 7 or 13.")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@cached_function
|
|
103
|
+
def Fricke_module(l):
|
|
104
|
+
r"""
|
|
105
|
+
Fricke module for ``l`` =2,3,5,7,13.
|
|
106
|
+
|
|
107
|
+
For these primes (and these only) the modular curve `X_0(l)` has
|
|
108
|
+
genus zero, and its field is generated by a single modular
|
|
109
|
+
function called the Fricke module (or Hauptmodul), `t`. There is
|
|
110
|
+
a classical choice of such a generator `t` in each case, and the
|
|
111
|
+
`j`-function is a rational function of `t` of degree `l+1` of the
|
|
112
|
+
form `P(t)/t` where `P` is a polynomial of degree `l+1`. Up to
|
|
113
|
+
scaling, `t` is determined by the condition that the ramification
|
|
114
|
+
points above `j=\infty` are `t=0` (with ramification degree `1`)
|
|
115
|
+
and `t=\infty` (with degree `l`). The ramification above `j=0`
|
|
116
|
+
and `j=1728` may be seen in the factorizations of `j(t)` and
|
|
117
|
+
`k(t)` where `k=j-1728`.
|
|
118
|
+
|
|
119
|
+
OUTPUT:
|
|
120
|
+
|
|
121
|
+
The rational function `P(t)/t`.
|
|
122
|
+
|
|
123
|
+
TESTS::
|
|
124
|
+
|
|
125
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_module
|
|
126
|
+
sage: Fricke_module(2)
|
|
127
|
+
(t^3 + 48*t^2 + 768*t + 4096)/t
|
|
128
|
+
sage: Fricke_module(3)
|
|
129
|
+
(t^4 + 36*t^3 + 270*t^2 + 756*t + 729)/t
|
|
130
|
+
sage: Fricke_module(5)
|
|
131
|
+
(t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125)/t
|
|
132
|
+
sage: Fricke_module(7)
|
|
133
|
+
(t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49)/t
|
|
134
|
+
sage: Fricke_module(13)
|
|
135
|
+
(t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10
|
|
136
|
+
+ 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6
|
|
137
|
+
+ 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13)/t
|
|
138
|
+
"""
|
|
139
|
+
t = PolynomialRing(QQ, 't').gen()
|
|
140
|
+
return Fricke_polynomial(l) / t
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@cached_function
|
|
144
|
+
def Psi(l, use_stored=True):
|
|
145
|
+
r"""
|
|
146
|
+
Generic kernel polynomial for genus zero primes.
|
|
147
|
+
|
|
148
|
+
For each of the primes `l` for which `X_0(l)` has genus zero
|
|
149
|
+
(namely `l=2,3,5,7,13`), we may define an elliptic curve `E_t`
|
|
150
|
+
over `\QQ(t)`, with coefficients in `\ZZ[t]`, which has good
|
|
151
|
+
reduction except at `t=0` and `t=\infty` (which lie above
|
|
152
|
+
`j=\infty`) and at certain other values of `t` above `j=0` when
|
|
153
|
+
`l=3` (one value) or `l\equiv1\pmod{3}` (two values) and above
|
|
154
|
+
`j=1728` when `l=2` (one value) or `l\equiv1 \pmod{4}` (two
|
|
155
|
+
values). (These exceptional values correspond to endomorphisms of
|
|
156
|
+
`E_t` of degree `l`.) The `l`-division polynomial of `E_t` has a
|
|
157
|
+
unique factor of degree `(l-1)/2` (or 1 when `l=2`), with
|
|
158
|
+
coefficients in `\ZZ[t]`, which we call the Generic Kernel
|
|
159
|
+
Polynomial for `l`. These are used, by specialising `t`, in the
|
|
160
|
+
function :meth:`isogenies_prime_degree_genus_0`, which also has to
|
|
161
|
+
take into account the twisting factor between `E_t` for a specific
|
|
162
|
+
value of `t` and the short Weierstrass form of an elliptic curve
|
|
163
|
+
with `j`-invariant `j(t)`. This enables the computation of the
|
|
164
|
+
kernel polynomials of isogenies without having to compute and
|
|
165
|
+
factor division polynomials.
|
|
166
|
+
|
|
167
|
+
All of this data is quickly computed from the Fricke modules, except
|
|
168
|
+
that for `l=13` the factorization of the Generic Division Polynomial
|
|
169
|
+
takes a long time, so the value have been precomputed and cached; by
|
|
170
|
+
default the cached values are used, but the code here will recompute
|
|
171
|
+
them when ``use_stored`` is ``False``, as in the doctests.
|
|
172
|
+
|
|
173
|
+
INPUT:
|
|
174
|
+
|
|
175
|
+
- ``l`` -- either 2, 3, 5, 7, or 13
|
|
176
|
+
|
|
177
|
+
- ``use_stored``-- boolean (default: ``True``); if ``True``, use
|
|
178
|
+
precomputed values, otherwise compute them on the fly
|
|
179
|
+
|
|
180
|
+
.. NOTE::
|
|
181
|
+
|
|
182
|
+
This computation takes a negligible time for `l=2,3,5,7`
|
|
183
|
+
but more than 100s for `l=13`. The reason
|
|
184
|
+
for allowing dynamic computation here instead of just using
|
|
185
|
+
precomputed values is for testing.
|
|
186
|
+
|
|
187
|
+
TESTS::
|
|
188
|
+
|
|
189
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_module, Psi
|
|
190
|
+
sage: assert Psi(2, use_stored=True) == Psi(2, use_stored=False)
|
|
191
|
+
sage: assert Psi(3, use_stored=True) == Psi(3, use_stored=False)
|
|
192
|
+
sage: assert Psi(5, use_stored=True) == Psi(5, use_stored=False)
|
|
193
|
+
sage: assert Psi(7, use_stored=True) == Psi(7, use_stored=False)
|
|
194
|
+
sage: assert Psi(13, use_stored=True) == Psi(13, use_stored=False) # long time (2s)
|
|
195
|
+
"""
|
|
196
|
+
if l not in [2, 3, 5, 7, 13]:
|
|
197
|
+
raise ValueError("Genus zero primes are 2, 3, 5, 7 or 13.")
|
|
198
|
+
|
|
199
|
+
R = PolynomialRing(ZZ, 2, 'Xt')
|
|
200
|
+
X, t = R.gens()
|
|
201
|
+
|
|
202
|
+
if use_stored:
|
|
203
|
+
if l == 2:
|
|
204
|
+
return X + t + 64
|
|
205
|
+
if l == 3:
|
|
206
|
+
return X + t + 27
|
|
207
|
+
if l == 5:
|
|
208
|
+
return X**2 + 2*X*(t**2 + 22*t + 125) + (t**2 + 22*t + 89) * (t**2 + 22*t + 125)
|
|
209
|
+
if l == 7:
|
|
210
|
+
return (X**3 + 3*(t**2 + 13*t + 49)*X**2
|
|
211
|
+
+ 3*(t**2 + 13*t + 33)*(t**2 + 13*t + 49)*X
|
|
212
|
+
+ (t**2 + 13*t + 49)*(t**4 + 26*t**3 + 219*t**2 + 778*t + 881))
|
|
213
|
+
if l == 13:
|
|
214
|
+
return (t**24 + 66*t**23 + 2091*t**22 + 6*X*t**20 + 42582*t**21 + 330*X*t**19 + 627603*t**20 + 8700*X*t**18 + 7134744*t**19 + 15*X**2*t**16 + 146886*X*t**17 + 65042724*t**18 + 660*X**2*t**15 + 1784532*X*t**16 + 487778988*t**17 + 13890*X**2*t**14 + 16594230*X*t**15 + 3061861065*t**16 + 20*X**3*t**12 + 186024*X**2*t**13 + 122552328*X*t**14 + 16280123754*t**15 + 660*X**3*t**11 + 1774887*X**2*t**12 + 735836862*X*t**13 + 73911331425*t**14 + 10380*X**3*t**10 + 12787272*X**2*t**11 + 3646188342*X*t**12 + 287938949178*t**13 + 15*X**4*t**8 + 102576*X**3*t**9 + 71909658*X**2*t**10 + 15047141292*X*t**11 + 964903805434*t**12 + 330*X**4*t**7 + 707604*X**3*t**8 + 321704316*X**2*t**9 + 51955096824*X*t**10 + 2781843718722*t**11 + 3435*X**4*t**6 + 3582876*X**3*t**7 + 1155971196*X**2*t**8 + 150205315932*X*t**9 + 6885805359741*t**10 + 6*X**5*t**4 + 21714*X**4*t**5 + 13632168*X**3*t**6 + 3343499244*X**2*t**7 + 362526695094*X*t**8 + 14569390179114*t**9 + 66*X**5*t**3 + 90660*X**4*t**4 + 39215388*X**3*t**5 + 7747596090*X**2*t**6 + 725403501318*X*t**7 + 26165223178293*t**8 + 336*X**5*t**2 + 255090*X**4*t**3 + 84525732*X**3*t**4 + 14206132008*X**2*t**5 + 1189398495432*X*t**6 + 39474479008356*t**7 + X**6 + 858*X**5*t + 472143*X**4*t**2 + 132886992*X**3*t**3 + 20157510639*X**2*t**4 + 1569568001646*X*t**5 + 49303015587132*t**6 + 1014*X**5 + 525954*X**4*t + 144222780*X**3*t**2 + 21320908440*X**2*t**3 + 1622460290100*X*t**4 + 49941619724976*t**5 + 272259*X**4 + 96482100*X**3*t + 15765293778*X**2*t**2 + 1260038295438*X*t**3 + 39836631701295*t**4 + 29641924*X**3 + 7210949460*X**2*t + 686651250012*X*t**2 + 23947528862166*t**3 + 1506392823*X**2 + 231462513906*X*t + 10114876838391*t**2 + 35655266790*X + 2644809206442*t + 317295487717)
|
|
215
|
+
# The coefficients for l=13 are:
|
|
216
|
+
# X**6: 1
|
|
217
|
+
# X**5: (6) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)
|
|
218
|
+
# X**4: (3) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13) * (5*t**4 + 55*t**3 + 260*t**2 + 583*t + 537)
|
|
219
|
+
# X**3: (4) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)**2 * (5*t**6 + 80*t**5 + 560*t**4 + 2214*t**3 + 5128*t**2 + 6568*t + 3373)
|
|
220
|
+
# X**2: (3) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**2 * (5*t**8 + 110*t**7 + 1045*t**6 + 5798*t**5 + 20508*t**4 + 47134*t**3 + 67685*t**2 + 54406*t + 17581)
|
|
221
|
+
# X**1: (6) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**10 + 27*t**9 + 316*t**8 + 2225*t**7 + 10463*t**6 + 34232*t**5 + 78299*t**4 + 122305*t**3 + 122892*t**2 + 69427*t + 16005)
|
|
222
|
+
# X**0: (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**14 + 38*t**13 + 649*t**12 + 6844*t**11 + 50216*t**10 + 271612*t**9 + 1115174*t**8 + 3520132*t**7 + 8549270*t**6 + 15812476*t**5 + 21764840*t**4 + 21384124*t**3 + 13952929*t**2 + 5282630*t + 854569)
|
|
223
|
+
|
|
224
|
+
# Here the generic kernel polynomials are actually calculated:
|
|
225
|
+
j = Fricke_module(l)
|
|
226
|
+
k = j - 1728
|
|
227
|
+
from sage.misc.misc_c import prod
|
|
228
|
+
f = prod([p for p, e in j.factor() if e == 3]
|
|
229
|
+
+ [p for p, e in k.factor() if e == 2])
|
|
230
|
+
A4 = -3*t**2*j*k // f**2
|
|
231
|
+
A6 = -2*t**3*j*k**2 // f**3
|
|
232
|
+
E = EllipticCurve([0, 0, 0, A4, A6])
|
|
233
|
+
assert E.j_invariant() == j
|
|
234
|
+
return E.division_polynomial(l, X).factor()[0][0]
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def isogenies_prime_degree_genus_0(E, l=None, minimal_models=True):
|
|
238
|
+
"""
|
|
239
|
+
Return list of ``l`` -isogenies with domain ``E``.
|
|
240
|
+
|
|
241
|
+
INPUT:
|
|
242
|
+
|
|
243
|
+
- ``E`` -- an elliptic curve
|
|
244
|
+
|
|
245
|
+
- ``l`` -- either ``None`` or 2, 3, 5, 7, or 13
|
|
246
|
+
|
|
247
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
248
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
249
|
+
fields of larger degree it can be expensive to compute these so
|
|
250
|
+
set to ``False``.
|
|
251
|
+
|
|
252
|
+
OUTPUT:
|
|
253
|
+
|
|
254
|
+
(list) When ``l`` is None a list of all isogenies of degree 2, 3,
|
|
255
|
+
5, 7 and 13, otherwise a list of isogenies of the given degree.
|
|
256
|
+
|
|
257
|
+
.. NOTE::
|
|
258
|
+
|
|
259
|
+
This function would normally be invoked indirectly via
|
|
260
|
+
``E.isogenies_prime_degree(l)``, which automatically calls the
|
|
261
|
+
appropriate function.
|
|
262
|
+
|
|
263
|
+
ALGORITHM:
|
|
264
|
+
|
|
265
|
+
Cremona and Watkins [CW2005]_. See also [KT2013]_, Chapter 4.
|
|
266
|
+
|
|
267
|
+
EXAMPLES::
|
|
268
|
+
|
|
269
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_0
|
|
270
|
+
sage: E = EllipticCurve([0,12])
|
|
271
|
+
sage: isogenies_prime_degree_genus_0(E, 5)
|
|
272
|
+
[]
|
|
273
|
+
|
|
274
|
+
sage: E = EllipticCurve('1450c1') # needs database_cremona_mini_ellcurve
|
|
275
|
+
sage: isogenies_prime_degree_genus_0(E) # needs database_cremona_mini_ellcurve
|
|
276
|
+
[Isogeny of degree 3
|
|
277
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 300*x - 1000
|
|
278
|
+
over Rational Field
|
|
279
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 5950*x - 182250
|
|
280
|
+
over Rational Field]
|
|
281
|
+
|
|
282
|
+
sage: E = EllipticCurve('50a1') # needs database_cremona_mini_ellcurve
|
|
283
|
+
sage: isogenies_prime_degree_genus_0(E) # needs database_cremona_mini_ellcurve
|
|
284
|
+
[Isogeny of degree 3
|
|
285
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
|
|
286
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field,
|
|
287
|
+
Isogeny of degree 5
|
|
288
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
|
|
289
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
|
|
290
|
+
"""
|
|
291
|
+
if l not in [2, 3, 5, 7, 13, None]:
|
|
292
|
+
raise ValueError("%s is not a genus 0 prime." % l)
|
|
293
|
+
F = E.base_ring()
|
|
294
|
+
j = E.j_invariant()
|
|
295
|
+
if F.characteristic() in [2, 3, l]:
|
|
296
|
+
raise NotImplementedError("2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.")
|
|
297
|
+
if l == 2:
|
|
298
|
+
return isogenies_2(E, minimal_models=minimal_models)
|
|
299
|
+
if l == 3:
|
|
300
|
+
return isogenies_3(E, minimal_models=minimal_models)
|
|
301
|
+
if j == F(0):
|
|
302
|
+
if l == 5:
|
|
303
|
+
return isogenies_5_0(E, minimal_models=minimal_models)
|
|
304
|
+
if l == 7:
|
|
305
|
+
return isogenies_7_0(E, minimal_models=minimal_models)
|
|
306
|
+
if l == 13:
|
|
307
|
+
return isogenies_13_0(E, minimal_models=minimal_models)
|
|
308
|
+
if j == F(1728):
|
|
309
|
+
if l == 5:
|
|
310
|
+
return isogenies_5_1728(E, minimal_models=minimal_models)
|
|
311
|
+
if l == 7:
|
|
312
|
+
return isogenies_7_1728(E, minimal_models=minimal_models)
|
|
313
|
+
if l == 13:
|
|
314
|
+
return isogenies_13_1728(E, minimal_models=minimal_models)
|
|
315
|
+
|
|
316
|
+
if l is not None:
|
|
317
|
+
R = PolynomialRing(F,'t')
|
|
318
|
+
t = R.gen()
|
|
319
|
+
f = R(Fricke_polynomial(l))
|
|
320
|
+
t_list = sorted((f-j*t).roots(multiplicities=False))
|
|
321
|
+
# The generic kernel polynomial applies to a standard curve
|
|
322
|
+
# E_t with the correct j-invariant; we must compute the
|
|
323
|
+
# appropriate twisting factor to scale X by:
|
|
324
|
+
c4, c6 = E.c_invariants()
|
|
325
|
+
T = c4/(3*c6)
|
|
326
|
+
jt = Fricke_module(l)
|
|
327
|
+
kt = jt-1728
|
|
328
|
+
from sage.misc.misc_c import prod
|
|
329
|
+
psi = Psi(l)
|
|
330
|
+
X = t
|
|
331
|
+
f = R(prod( [p for p,e in jt.factor() if e == 3]
|
|
332
|
+
+ [p for p,e in kt.factor() if e == 2]))
|
|
333
|
+
kernels = [R(psi(X*T*(j-1728)*t0/f(t0),t0)) for t0 in t_list]
|
|
334
|
+
kernels = [ker.monic() for ker in kernels]
|
|
335
|
+
E1 = EllipticCurve([-27*c4,-54*c6])
|
|
336
|
+
w = E.isomorphism_to(E1)
|
|
337
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
338
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
339
|
+
isogs = [E1.isogeny(kernel=ker, model=model) for ker in kernels]
|
|
340
|
+
isogs = [isog * w for isog in isogs]
|
|
341
|
+
return isogs
|
|
342
|
+
|
|
343
|
+
if l is None:
|
|
344
|
+
return sum([isogenies_prime_degree_genus_0(E, ell, minimal_models=minimal_models)
|
|
345
|
+
for ell in [2,3,5,7,13]],[])
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
# The following code computes data to be used in
|
|
349
|
+
# isogenies_sporadic_Q. Over Q there are only finitely many
|
|
350
|
+
# j-invariants of curves with l-isogenies where l is not equal to 2,
|
|
351
|
+
# 3, 5, 7 or 13. In these cases l is equal to 11, 17, 19, 37, 43, 67
|
|
352
|
+
# or 163. We refer to these l as "sporadic".
|
|
353
|
+
|
|
354
|
+
# sporadic_j is a dictionary holding for each possible sporadic
|
|
355
|
+
# j-invariant, the unique l such that an l-isogeny exists.
|
|
356
|
+
sporadic_j = {
|
|
357
|
+
QQ(-121) : 11,
|
|
358
|
+
QQ(-32768) : 11,
|
|
359
|
+
QQ(-24729001) : 11,
|
|
360
|
+
QQ(-297756989)/2 : 17,
|
|
361
|
+
QQ(-882216989)/131072 : 17,
|
|
362
|
+
QQ(-884736) : 19,
|
|
363
|
+
QQ(-9317) : 37,
|
|
364
|
+
QQ(-162677523113838677) : 37,
|
|
365
|
+
QQ(-884736000) : 43,
|
|
366
|
+
QQ(-147197952000) : 67,
|
|
367
|
+
QQ(-262537412640768000) : 163
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
@cached_function
|
|
372
|
+
def _sporadic_Q_data(j):
|
|
373
|
+
r"""
|
|
374
|
+
Return technical data used in computing sporadic isogenies over `\QQ`.
|
|
375
|
+
|
|
376
|
+
INPUT:
|
|
377
|
+
|
|
378
|
+
- ``j`` -- the `j`-invariant of a sporadic curve, i.e. one of the
|
|
379
|
+
keys of ``sporadic_j``
|
|
380
|
+
|
|
381
|
+
OUTPUT:
|
|
382
|
+
|
|
383
|
+
``([a4,a6],coeffs)`` where ``[a4,a6]`` are the coefficients of a
|
|
384
|
+
short Weierstrass equation of an elliptic curve E with j(E)=``j``,
|
|
385
|
+
and ``coeffs`` is a list of coefficients of a polynomial defining
|
|
386
|
+
the kernel of an l-isogeny from E. In all but one case this
|
|
387
|
+
polynomial is monic with integer coefficients. In one case
|
|
388
|
+
(`\ell=37`, `j=-162677523113838677`) the constant coefficient has
|
|
389
|
+
denominator 37.
|
|
390
|
+
|
|
391
|
+
Whenever we have a curve of j-invariant ``j``, we can compute the
|
|
392
|
+
corresponding l-isogeny by just scaling ``coeffs`` by the right
|
|
393
|
+
twisting factor and using the result as a kernel-polynomial.
|
|
394
|
+
|
|
395
|
+
ALGORITHM:
|
|
396
|
+
|
|
397
|
+
For small l it works fine to factor the l-division polynomial, but
|
|
398
|
+
this takes a long time for the larger l and is a very bad idea for
|
|
399
|
+
l=163; hence we use floating point arithmetic with a precision
|
|
400
|
+
which is known to work. This idea was suggested by Samir Siksek.
|
|
401
|
+
|
|
402
|
+
TESTS::
|
|
403
|
+
|
|
404
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import sporadic_j, _sporadic_Q_data
|
|
405
|
+
sage: [_sporadic_Q_data(j) for j in sorted(sporadic_j) if j != -262537412640768000]
|
|
406
|
+
[([-269675595, -1704553285050],
|
|
407
|
+
[-31653754873248632711650187487655160190139073510876609346911928661154296875/37,
|
|
408
|
+
-1469048260972089939455942042937882262144594798448952781325533511718750,
|
|
409
|
+
-1171741935131505774747142644126089902595908234671576131857702734375,
|
|
410
|
+
-574934780393177024547076427530739751753985644656221274606250000,
|
|
411
|
+
-193516922725803688001809624711400287605136013195315374687500,
|
|
412
|
+
-47085563820928456130325308223963045033502182349693125000,
|
|
413
|
+
-8472233937388712980597845725196873697064639957437500,
|
|
414
|
+
-1124815211213953261752081095348112305023653750000,
|
|
415
|
+
-105684015609077608033913080859605951322531250,
|
|
416
|
+
-5911406027236569746089675554748135312500,
|
|
417
|
+
22343907270397352965399097794968750,
|
|
418
|
+
43602171843758666292581116410000,
|
|
419
|
+
5054350766002463251474186500,
|
|
420
|
+
350135768194635636171000,
|
|
421
|
+
16633063574896677300,
|
|
422
|
+
549939627039600,
|
|
423
|
+
12182993865,
|
|
424
|
+
163170,
|
|
425
|
+
1]),
|
|
426
|
+
([-117920, 15585808],
|
|
427
|
+
[426552448394636714720553816389274308035895411389805883034985546818882031845376,
|
|
428
|
+
-55876556222880738651382959148329502876096075327084935039031884373558741172224,
|
|
429
|
+
3393295715290183821010552313572221545212247684503012173117764703828786020352,
|
|
430
|
+
-125729166452196578653551230178028570067747190427221869867485520072257044480,
|
|
431
|
+
3121342502030777257351089270834971957072933779704445667351054593298530304,
|
|
432
|
+
-52544031605544530265465344472543470442324636919759253720520768014516224,
|
|
433
|
+
532110915869155495738137756847596184665209453108323879594125221167104,
|
|
434
|
+
-399031158106622651277981701966309467713625045637309782055519780864,
|
|
435
|
+
-101914346170769215732007802723651742508893380955930030421292613632,
|
|
436
|
+
2296526155500449624398016447877283594461904009374321659789443072,
|
|
437
|
+
-31950871094301541469458501953701002806003991982768349794795520,
|
|
438
|
+
329792235011603804948028315065667439678526339671142107709440,
|
|
439
|
+
-2655636715955021784085217734679612378726442691190553837568,
|
|
440
|
+
16825164648840434987220620681420687654501026066872664064,
|
|
441
|
+
-81705027839007003131400500185224450729843244954288128,
|
|
442
|
+
273656504606483403474090105104132405333665144373248,
|
|
443
|
+
-320807702482945680116212224172370503903312084992,
|
|
444
|
+
-3166683390779345463318656135338172047199043584,
|
|
445
|
+
27871349428383710305216046431806697565585408,
|
|
446
|
+
-132774697798318602604125735604528772808704,
|
|
447
|
+
436096215568182871014215818309741314048,
|
|
448
|
+
-964687143341252402362763535357837312,
|
|
449
|
+
942144169187362941776488535425024,
|
|
450
|
+
2794850106281773765892648206336,
|
|
451
|
+
-17236916236678037389276086272,
|
|
452
|
+
50979778712911923486851072,
|
|
453
|
+
-105035658611718440992768,
|
|
454
|
+
161833913559276412928,
|
|
455
|
+
-188675698610077696,
|
|
456
|
+
163929317513984,
|
|
457
|
+
-102098677888,
|
|
458
|
+
42387952,
|
|
459
|
+
-10184,
|
|
460
|
+
1]),
|
|
461
|
+
([-13760, 621264],
|
|
462
|
+
[-1961864562041980324821547425314935668736,
|
|
463
|
+
784270445793223959453256359333693751296,
|
|
464
|
+
-120528107728500223255333768387027271680,
|
|
465
|
+
10335626145581464192664472924270362624,
|
|
466
|
+
-568426570575654606865505142156820480,
|
|
467
|
+
21261993723422650574629752537088000,
|
|
468
|
+
-544630471727787626557612832587776,
|
|
469
|
+
8870521306520473088172555763712,
|
|
470
|
+
-54993059067301585878494740480,
|
|
471
|
+
-1434261324709904840432549888,
|
|
472
|
+
50978938193065926383894528,
|
|
473
|
+
-845761855773797582372864,
|
|
474
|
+
8627493611216601088000,
|
|
475
|
+
-48299605284169187328,
|
|
476
|
+
-32782260293713920,
|
|
477
|
+
3415534989828096,
|
|
478
|
+
-34580115625984,
|
|
479
|
+
199359712512,
|
|
480
|
+
-730488128,
|
|
481
|
+
1658080,
|
|
482
|
+
-2064,
|
|
483
|
+
1]),
|
|
484
|
+
([-3940515, 3010787550],
|
|
485
|
+
[-6458213126940667330314375,
|
|
486
|
+
34699336325466068070000,
|
|
487
|
+
-72461450055340471500,
|
|
488
|
+
68342601718080000,
|
|
489
|
+
-15140380554450,
|
|
490
|
+
-25802960400,
|
|
491
|
+
23981220,
|
|
492
|
+
-8160,
|
|
493
|
+
1]),
|
|
494
|
+
([-38907, -2953962], [-20349931239, -424530315, -134838, 53658, 429, 1]),
|
|
495
|
+
([-608, 5776],
|
|
496
|
+
[-34162868224,
|
|
497
|
+
-8540717056,
|
|
498
|
+
6405537792,
|
|
499
|
+
-1123778560,
|
|
500
|
+
84283392,
|
|
501
|
+
-2033152,
|
|
502
|
+
-92416,
|
|
503
|
+
6992,
|
|
504
|
+
-152,
|
|
505
|
+
1]),
|
|
506
|
+
([-9504, 365904], [1294672896, -92835072, 1463616, 7920, -264, 1]),
|
|
507
|
+
([-10395, 444150],
|
|
508
|
+
[-38324677699334121599624973029296875,
|
|
509
|
+
-17868327793500376961572310472656250,
|
|
510
|
+
2569568362004197901139023084765625,
|
|
511
|
+
-95128267987528547588017818750000,
|
|
512
|
+
-822168183291347061312510937500,
|
|
513
|
+
134395594560592096297190625000,
|
|
514
|
+
-2881389756919344324888937500,
|
|
515
|
+
-2503855007083401977250000,
|
|
516
|
+
922779077075655997443750,
|
|
517
|
+
-11503912310262102937500,
|
|
518
|
+
-18237870962450291250,
|
|
519
|
+
1457822151548910000,
|
|
520
|
+
-10087015556047500,
|
|
521
|
+
-13677678063000,
|
|
522
|
+
490243338900,
|
|
523
|
+
-2461460400,
|
|
524
|
+
5198445,
|
|
525
|
+
-4410,
|
|
526
|
+
1]),
|
|
527
|
+
([-856035, -341748450],
|
|
528
|
+
[103687510635057329105625,
|
|
529
|
+
961598491955315190000,
|
|
530
|
+
1054634146768300500,
|
|
531
|
+
-6553122389064000,
|
|
532
|
+
-14554350284850,
|
|
533
|
+
-2046589200,
|
|
534
|
+
13185540,
|
|
535
|
+
8160,
|
|
536
|
+
1]),
|
|
537
|
+
([-3267, -280962], [1480352841, -56169531, -2829222, 10890, 429, 1])]
|
|
538
|
+
|
|
539
|
+
See :issue:`22328`. This used to fail on l=37,
|
|
540
|
+
j=-162677523113838677 for which the kernel polynomial is not
|
|
541
|
+
integral::
|
|
542
|
+
|
|
543
|
+
sage: R = PolynomialRing(QQ,'x')
|
|
544
|
+
sage: for j in sporadic_j:
|
|
545
|
+
....: ell = sporadic_j[j]
|
|
546
|
+
....: if ell==163: continue # takes 40s
|
|
547
|
+
....: E = EllipticCurve(j=j).short_weierstrass_model()
|
|
548
|
+
....: f = R(_sporadic_Q_data(j)[1])
|
|
549
|
+
....: g = E.division_polynomial(ell)
|
|
550
|
+
....: assert g % f == 0
|
|
551
|
+
"""
|
|
552
|
+
from sage.rings.real_mpfr import RealField
|
|
553
|
+
from sage.misc.misc_c import prod
|
|
554
|
+
ell = sporadic_j[j]
|
|
555
|
+
E = EllipticCurve(j=j).short_weierstrass_model()
|
|
556
|
+
a4a6 = list(E.ainvs())[3:]
|
|
557
|
+
L = E.period_lattice()
|
|
558
|
+
pr = 100
|
|
559
|
+
if ell == 163:
|
|
560
|
+
pr = 1000
|
|
561
|
+
elif ell > 30:
|
|
562
|
+
pr = 300
|
|
563
|
+
w1, w2 = L.basis(prec=pr)
|
|
564
|
+
X = polygen(RealField(pr),'X')
|
|
565
|
+
w = w1 # real period
|
|
566
|
+
if j in [-121, -24729001, -162677523113838677, QQ(-882216989)/131072]:
|
|
567
|
+
w = 2*w2-w1 # imaginary period
|
|
568
|
+
kerpol = prod([X-L.elliptic_exponential(n*w/ell)[0] for n in range(1,(ell+1)//2)])
|
|
569
|
+
if j == -162677523113838677:
|
|
570
|
+
kerpolcoeffs = [(37*c.real()).round()/37 for c in list(kerpol)]
|
|
571
|
+
else:
|
|
572
|
+
kerpolcoeffs = [c.real().round() for c in list(kerpol)]
|
|
573
|
+
return (a4a6,kerpolcoeffs)
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def isogenies_sporadic_Q(E, l=None, minimal_models=True):
|
|
577
|
+
r"""
|
|
578
|
+
Return a list of sporadic l-isogenies from E (l = 11, 17, 19, 37,
|
|
579
|
+
43, 67 or 163). Only for elliptic curves over `\QQ`.
|
|
580
|
+
|
|
581
|
+
INPUT:
|
|
582
|
+
|
|
583
|
+
- ``E`` -- an elliptic curve defined over `\QQ`
|
|
584
|
+
|
|
585
|
+
- ``l`` -- either ``None`` or a prime number
|
|
586
|
+
|
|
587
|
+
OUTPUT:
|
|
588
|
+
|
|
589
|
+
(list) If ``l`` is None, a list of all isogenies with domain ``E``
|
|
590
|
+
and of degree 11, 17, 19, 37, 43, 67 or 163; otherwise a list of
|
|
591
|
+
isogenies of the given degree.
|
|
592
|
+
|
|
593
|
+
.. NOTE::
|
|
594
|
+
|
|
595
|
+
This function would normally be invoked indirectly via
|
|
596
|
+
``E.isogenies_prime_degree(l)``, which automatically calls the appropriate
|
|
597
|
+
function.
|
|
598
|
+
|
|
599
|
+
EXAMPLES::
|
|
600
|
+
|
|
601
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_sporadic_Q
|
|
602
|
+
sage: E = EllipticCurve('121a1')
|
|
603
|
+
sage: isogenies_sporadic_Q(E, 11)
|
|
604
|
+
[Isogeny of degree 11
|
|
605
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76
|
|
606
|
+
over Rational Field
|
|
607
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888
|
|
608
|
+
over Rational Field]
|
|
609
|
+
sage: isogenies_sporadic_Q(E, 13)
|
|
610
|
+
[]
|
|
611
|
+
sage: isogenies_sporadic_Q(E, 17)
|
|
612
|
+
[]
|
|
613
|
+
sage: isogenies_sporadic_Q(E)
|
|
614
|
+
[Isogeny of degree 11
|
|
615
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76
|
|
616
|
+
over Rational Field
|
|
617
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888
|
|
618
|
+
over Rational Field]
|
|
619
|
+
|
|
620
|
+
sage: E = EllipticCurve([1, 1, 0, -660, -7600])
|
|
621
|
+
sage: isogenies_sporadic_Q(E, 17)
|
|
622
|
+
[Isogeny of degree 17
|
|
623
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600
|
|
624
|
+
over Rational Field
|
|
625
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750
|
|
626
|
+
over Rational Field]
|
|
627
|
+
sage: isogenies_sporadic_Q(E)
|
|
628
|
+
[Isogeny of degree 17
|
|
629
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600
|
|
630
|
+
over Rational Field
|
|
631
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750
|
|
632
|
+
over Rational Field]
|
|
633
|
+
sage: isogenies_sporadic_Q(E, 11)
|
|
634
|
+
[]
|
|
635
|
+
|
|
636
|
+
sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
|
|
637
|
+
sage: isogenies_sporadic_Q(E, 11)
|
|
638
|
+
[]
|
|
639
|
+
sage: isogenies_sporadic_Q(E, 19)
|
|
640
|
+
[Isogeny of degree 19
|
|
641
|
+
from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
|
|
642
|
+
over Rational Field
|
|
643
|
+
to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
|
|
644
|
+
over Rational Field]
|
|
645
|
+
sage: isogenies_sporadic_Q(E)
|
|
646
|
+
[Isogeny of degree 19
|
|
647
|
+
from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
|
|
648
|
+
over Rational Field
|
|
649
|
+
to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
|
|
650
|
+
over Rational Field]
|
|
651
|
+
|
|
652
|
+
sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
|
|
653
|
+
sage: E.conductor()
|
|
654
|
+
19600
|
|
655
|
+
sage: isogenies_sporadic_Q(E,37)
|
|
656
|
+
[Isogeny of degree 37
|
|
657
|
+
from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072
|
|
658
|
+
over Rational Field
|
|
659
|
+
to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728
|
|
660
|
+
over Rational Field]
|
|
661
|
+
|
|
662
|
+
sage: E = EllipticCurve([1, 1, 0, -25178045, 48616918750])
|
|
663
|
+
sage: E.conductor()
|
|
664
|
+
148225
|
|
665
|
+
sage: isogenies_sporadic_Q(E,37)
|
|
666
|
+
[Isogeny of degree 37
|
|
667
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 25178045*x + 48616918750
|
|
668
|
+
over Rational Field
|
|
669
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 970*x - 13075
|
|
670
|
+
over Rational Field]
|
|
671
|
+
|
|
672
|
+
sage: E = EllipticCurve([-3440, 77658])
|
|
673
|
+
sage: E.conductor()
|
|
674
|
+
118336
|
|
675
|
+
sage: isogenies_sporadic_Q(E,43)
|
|
676
|
+
[Isogeny of degree 43
|
|
677
|
+
from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658
|
|
678
|
+
over Rational Field
|
|
679
|
+
to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606
|
|
680
|
+
over Rational Field]
|
|
681
|
+
|
|
682
|
+
sage: E = EllipticCurve([-29480, -1948226])
|
|
683
|
+
sage: E.conductor()
|
|
684
|
+
287296
|
|
685
|
+
sage: isogenies_sporadic_Q(E,67)
|
|
686
|
+
[Isogeny of degree 67
|
|
687
|
+
from Elliptic Curve defined by y^2 = x^3 - 29480*x - 1948226
|
|
688
|
+
over Rational Field
|
|
689
|
+
to Elliptic Curve defined by y^2 = x^3 - 132335720*x + 585954296438
|
|
690
|
+
over Rational Field]
|
|
691
|
+
|
|
692
|
+
sage: E = EllipticCurve([-34790720, -78984748304])
|
|
693
|
+
sage: E.conductor()
|
|
694
|
+
425104
|
|
695
|
+
sage: isogenies_sporadic_Q(E,163)
|
|
696
|
+
[Isogeny of degree 163
|
|
697
|
+
from Elliptic Curve defined by y^2 = x^3 - 34790720*x - 78984748304
|
|
698
|
+
over Rational Field
|
|
699
|
+
to Elliptic Curve defined by y^2 = x^3 - 924354639680*x + 342062961763303088
|
|
700
|
+
over Rational Field]
|
|
701
|
+
"""
|
|
702
|
+
j = E.j_invariant()
|
|
703
|
+
j = QQ(j)
|
|
704
|
+
if (j not in sporadic_j or (l is not None and sporadic_j[j] != l)):
|
|
705
|
+
return []
|
|
706
|
+
|
|
707
|
+
F = E.base_field()
|
|
708
|
+
data = _sporadic_Q_data(j)
|
|
709
|
+
Ew = E.short_weierstrass_model()
|
|
710
|
+
E_to_Ew = E.isomorphism_to(Ew)
|
|
711
|
+
c4, c6 = Ew.c_invariants()
|
|
712
|
+
(a4, a6), f = data
|
|
713
|
+
d = (c6*a4)/(18*c4*a6) # twisting factor
|
|
714
|
+
R = PolynomialRing(F, 'X')
|
|
715
|
+
n = len(f)
|
|
716
|
+
ker = R([d**(n-i-1) * f[i] for i in range(n)])
|
|
717
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
718
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
719
|
+
isog = Ew.isogeny(kernel=ker, degree=l, model=model, check=False)
|
|
720
|
+
isog = isog * E_to_Ew
|
|
721
|
+
return [isog]
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
def isogenies_2(E, minimal_models=True):
|
|
725
|
+
r"""
|
|
726
|
+
Return a list of all 2-isogenies with domain ``E``.
|
|
727
|
+
|
|
728
|
+
INPUT:
|
|
729
|
+
|
|
730
|
+
- ``E`` -- an elliptic curve
|
|
731
|
+
|
|
732
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
733
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
734
|
+
fields of larger degree it can be expensive to compute these so
|
|
735
|
+
set to ``False``.
|
|
736
|
+
|
|
737
|
+
OUTPUT:
|
|
738
|
+
|
|
739
|
+
(list) 2-isogenies with domain ``E``. In general these are
|
|
740
|
+
normalised, but over `\QQ` and other number fields, the codomain
|
|
741
|
+
is a minimal model where possible.
|
|
742
|
+
|
|
743
|
+
EXAMPLES::
|
|
744
|
+
|
|
745
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_2
|
|
746
|
+
sage: E = EllipticCurve('14a1'); E
|
|
747
|
+
Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
|
|
748
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
|
|
749
|
+
[(1, 0, 1, -36, -70)]
|
|
750
|
+
|
|
751
|
+
sage: E = EllipticCurve([1,2,3,4,5]); E
|
|
752
|
+
Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
|
|
753
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
|
|
754
|
+
[]
|
|
755
|
+
sage: E = EllipticCurve(QQbar, [9,8]); E # needs sage.rings.number_field
|
|
756
|
+
Elliptic Curve defined by y^2 = x^3 + 9*x + 8 over Algebraic Field
|
|
757
|
+
sage: isogenies_2(E) # not implemented # needs sage.rings.number_field
|
|
758
|
+
"""
|
|
759
|
+
f2 = E.division_polynomial(2)
|
|
760
|
+
x2 = sorted(f2.roots(multiplicities=False))
|
|
761
|
+
x = f2.parent().gen()
|
|
762
|
+
ff = [x-x2i for x2i in x2]
|
|
763
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
764
|
+
model = "minimal" if minimal_models and isinstance(E.base_field(), NumberField) else None
|
|
765
|
+
isogs = [E.isogeny(f, model=model) for f in ff]
|
|
766
|
+
return isogs
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
def isogenies_3(E, minimal_models=True):
|
|
770
|
+
r"""
|
|
771
|
+
Return a list of all 3-isogenies with domain ``E``.
|
|
772
|
+
|
|
773
|
+
INPUT:
|
|
774
|
+
|
|
775
|
+
- ``E`` -- an elliptic curve
|
|
776
|
+
|
|
777
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
778
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
779
|
+
fields of larger degree it can be expensive to compute these so
|
|
780
|
+
set to ``False``.
|
|
781
|
+
|
|
782
|
+
OUTPUT:
|
|
783
|
+
|
|
784
|
+
(list) 3-isogenies with domain ``E``. In general these are
|
|
785
|
+
normalised, but over `\QQ` or a number field, the codomain is a
|
|
786
|
+
global minimal model where possible.
|
|
787
|
+
|
|
788
|
+
EXAMPLES::
|
|
789
|
+
|
|
790
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_3
|
|
791
|
+
sage: E = EllipticCurve(GF(17), [1,1])
|
|
792
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
|
|
793
|
+
[(0, 0, 0, 9, 7), (0, 0, 0, 0, 1)]
|
|
794
|
+
|
|
795
|
+
sage: E = EllipticCurve(GF(17^2,'a'), [1,1]) # needs sage.rings.finite_rings
|
|
796
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_3(E)] # needs sage.rings.finite_rings
|
|
797
|
+
[(0, 0, 0, 9, 7), (0, 0, 0, 0, 1), (0, 0, 0, 5*a + 1, a + 13), (0, 0, 0, 12*a + 6, 16*a + 14)]
|
|
798
|
+
|
|
799
|
+
sage: E = EllipticCurve('19a1')
|
|
800
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
|
|
801
|
+
[(0, 1, 1, 1, 0), (0, 1, 1, -769, -8470)]
|
|
802
|
+
|
|
803
|
+
sage: E = EllipticCurve([1,1])
|
|
804
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
|
|
805
|
+
[]
|
|
806
|
+
"""
|
|
807
|
+
f3 = E.division_polynomial(3)
|
|
808
|
+
x3 = sorted(f3.roots(multiplicities=False))
|
|
809
|
+
x = f3.parent().gen()
|
|
810
|
+
ff = [x - x3i for x3i in x3]
|
|
811
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
812
|
+
model = "minimal" if minimal_models and isinstance(E.base_field(), NumberField) else None
|
|
813
|
+
isogs = [E.isogeny(f, model=model) for f in ff]
|
|
814
|
+
return isogs
|
|
815
|
+
|
|
816
|
+
# 6 special cases: `l` = 5, 7, 13 and `j` = 0, 1728.
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def isogenies_5_0(E, minimal_models=True):
|
|
820
|
+
r"""
|
|
821
|
+
Return a list of all the 5-isogenies with domain ``E`` when the
|
|
822
|
+
j-invariant is 0.
|
|
823
|
+
|
|
824
|
+
INPUT:
|
|
825
|
+
|
|
826
|
+
- ``E`` -- an elliptic curve with j-invariant 0
|
|
827
|
+
|
|
828
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
829
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
830
|
+
fields of larger degree it can be expensive to compute these so
|
|
831
|
+
set to ``False``.
|
|
832
|
+
|
|
833
|
+
OUTPUT:
|
|
834
|
+
|
|
835
|
+
(list) 5-isogenies with codomain E. In general these are
|
|
836
|
+
normalised, but over `\QQ` or a number field, the codomain is a
|
|
837
|
+
global minimal model where possible.
|
|
838
|
+
|
|
839
|
+
.. NOTE::
|
|
840
|
+
|
|
841
|
+
This implementation requires that the characteristic is not 2,
|
|
842
|
+
3 or 5.
|
|
843
|
+
|
|
844
|
+
.. NOTE::
|
|
845
|
+
|
|
846
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
|
|
847
|
+
|
|
848
|
+
EXAMPLES::
|
|
849
|
+
|
|
850
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_0
|
|
851
|
+
sage: E = EllipticCurve([0,12])
|
|
852
|
+
sage: isogenies_5_0(E)
|
|
853
|
+
[]
|
|
854
|
+
|
|
855
|
+
sage: E = EllipticCurve(GF(13^2,'a'), [0,-3]) # needs sage.rings.finite_rings
|
|
856
|
+
sage: isogenies_5_0(E) # needs sage.rings.finite_rings
|
|
857
|
+
[Isogeny of degree 5
|
|
858
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
859
|
+
to Elliptic Curve defined by y^2 = x^3 + (4*a+6)*x + (2*a+10)
|
|
860
|
+
over Finite Field in a of size 13^2,
|
|
861
|
+
Isogeny of degree 5
|
|
862
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
863
|
+
to Elliptic Curve defined by y^2 = x^3 + (12*a+5)*x + (2*a+10)
|
|
864
|
+
over Finite Field in a of size 13^2,
|
|
865
|
+
Isogeny of degree 5
|
|
866
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
867
|
+
to Elliptic Curve defined by y^2 = x^3 + (10*a+2)*x + (2*a+10)
|
|
868
|
+
over Finite Field in a of size 13^2,
|
|
869
|
+
Isogeny of degree 5
|
|
870
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
871
|
+
to Elliptic Curve defined by y^2 = x^3 + (3*a+12)*x + (11*a+12)
|
|
872
|
+
over Finite Field in a of size 13^2,
|
|
873
|
+
Isogeny of degree 5
|
|
874
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
875
|
+
to Elliptic Curve defined by y^2 = x^3 + (a+4)*x + (11*a+12)
|
|
876
|
+
over Finite Field in a of size 13^2,
|
|
877
|
+
Isogeny of degree 5
|
|
878
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
879
|
+
to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12)
|
|
880
|
+
over Finite Field in a of size 13^2]
|
|
881
|
+
|
|
882
|
+
sage: x = polygen(QQ, 'x')
|
|
883
|
+
sage: K.<a> = NumberField(x**6 - 320*x**3 - 320) # needs sage.rings.number_field
|
|
884
|
+
sage: E = EllipticCurve(K, [0,0,1,0,0]) # needs sage.rings.number_field
|
|
885
|
+
sage: isogenies_5_0(E) # needs sage.rings.number_field
|
|
886
|
+
[Isogeny of degree 5
|
|
887
|
+
from Elliptic Curve defined by y^2 + y = x^3
|
|
888
|
+
over Number Field in a with defining polynomial x^6 - 320*x^3 - 320
|
|
889
|
+
to Elliptic Curve defined by
|
|
890
|
+
y^2 + y = x^3 + (643/8*a^5-15779/48*a^4-32939/24*a^3-71989/2*a^2+214321/6*a-112115/3)*x
|
|
891
|
+
+ (2901961/96*a^5+4045805/48*a^4+12594215/18*a^3-30029635/6*a^2+15341626/3*a-38944312/9)
|
|
892
|
+
over Number Field in a with defining polynomial x^6 - 320*x^3 - 320,
|
|
893
|
+
Isogeny of degree 5
|
|
894
|
+
from Elliptic Curve defined by y^2 + y = x^3
|
|
895
|
+
over Number Field in a with defining polynomial x^6 - 320*x^3 - 320
|
|
896
|
+
to Elliptic Curve defined by
|
|
897
|
+
y^2 + y = x^3 + (-1109/8*a^5-53873/48*a^4-180281/24*a^3-14491/2*a^2+35899/6*a-43745/3)*x
|
|
898
|
+
+ (-17790679/96*a^5-60439571/48*a^4-77680504/9*a^3+1286245/6*a^2-4961854/3*a-73854632/9)
|
|
899
|
+
over Number Field in a with defining polynomial x^6 - 320*x^3 - 320]
|
|
900
|
+
"""
|
|
901
|
+
F = E.base_field()
|
|
902
|
+
if E.j_invariant() != 0:
|
|
903
|
+
raise ValueError("j-invariant must be 0.")
|
|
904
|
+
if F.characteristic() in [2,3,5]:
|
|
905
|
+
raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
|
|
906
|
+
if not F(5).is_square():
|
|
907
|
+
return []
|
|
908
|
+
Ew = E.short_weierstrass_model()
|
|
909
|
+
a = Ew.a6()
|
|
910
|
+
x = polygen(F)
|
|
911
|
+
betas = sorted((x**6-160*a*x**3-80*a**2).roots(multiplicities=False))
|
|
912
|
+
if not betas:
|
|
913
|
+
return []
|
|
914
|
+
gammas = [(beta**2 * (beta**3-140*a))/(120*a) for beta in betas]
|
|
915
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
916
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
917
|
+
isogs = [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
|
|
918
|
+
iso = E.isomorphism_to(Ew)
|
|
919
|
+
isogs = [isog * iso for isog in isogs]
|
|
920
|
+
return isogs
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
def isogenies_5_1728(E, minimal_models=True):
|
|
924
|
+
r"""
|
|
925
|
+
Return a list of 5-isogenies with domain ``E`` when the j-invariant is
|
|
926
|
+
1728.
|
|
927
|
+
|
|
928
|
+
INPUT:
|
|
929
|
+
|
|
930
|
+
- ``E`` -- an elliptic curve with j-invariant 1728
|
|
931
|
+
|
|
932
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
933
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
934
|
+
fields of larger degree it can be expensive to compute these so
|
|
935
|
+
set to ``False``.
|
|
936
|
+
|
|
937
|
+
OUTPUT:
|
|
938
|
+
|
|
939
|
+
(list) 5-isogenies with codomain E. In general these are
|
|
940
|
+
normalised; but if `-1` is a square then there are two
|
|
941
|
+
endomorphisms of degree `5`, for which the codomain is the same as
|
|
942
|
+
the domain curve; and over `\QQ` or a number field, the codomain
|
|
943
|
+
is a global minimal model where possible.
|
|
944
|
+
|
|
945
|
+
.. NOTE::
|
|
946
|
+
|
|
947
|
+
This implementation requires that the characteristic is not 2,
|
|
948
|
+
3 or 5.
|
|
949
|
+
|
|
950
|
+
.. NOTE::
|
|
951
|
+
|
|
952
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
|
|
953
|
+
|
|
954
|
+
EXAMPLES::
|
|
955
|
+
|
|
956
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728
|
|
957
|
+
sage: E = EllipticCurve([7,0])
|
|
958
|
+
sage: isogenies_5_1728(E)
|
|
959
|
+
[]
|
|
960
|
+
|
|
961
|
+
sage: E = EllipticCurve(GF(13), [11,0])
|
|
962
|
+
sage: isogenies_5_1728(E)
|
|
963
|
+
[Isogeny of degree 5
|
|
964
|
+
from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13
|
|
965
|
+
to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13,
|
|
966
|
+
Isogeny of degree 5
|
|
967
|
+
from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13
|
|
968
|
+
to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13]
|
|
969
|
+
|
|
970
|
+
An example of endomorphisms of degree 5::
|
|
971
|
+
|
|
972
|
+
sage: # needs sage.rings.number_field
|
|
973
|
+
sage: K.<i> = QuadraticField(-1)
|
|
974
|
+
sage: E = EllipticCurve(K, [0,0,0,1,0])
|
|
975
|
+
sage: isogenies_5_1728(E)
|
|
976
|
+
[Isogeny of degree 5
|
|
977
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
|
|
978
|
+
with defining polynomial x^2 + 1 with i = 1*I
|
|
979
|
+
to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
|
|
980
|
+
with defining polynomial x^2 + 1 with i = 1*I,
|
|
981
|
+
Isogeny of degree 5
|
|
982
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
|
|
983
|
+
with defining polynomial x^2 + 1 with i = 1*I
|
|
984
|
+
to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i
|
|
985
|
+
with defining polynomial x^2 + 1 with i = 1*I]
|
|
986
|
+
sage: _[0].rational_maps()
|
|
987
|
+
(((4/25*i + 3/25)*x^5
|
|
988
|
+
+ (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)),
|
|
989
|
+
((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y
|
|
990
|
+
+ (141/125*i + 162/125)*x^2*y
|
|
991
|
+
+ (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4
|
|
992
|
+
+ (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125)))
|
|
993
|
+
|
|
994
|
+
An example of 5-isogenies over a number field::
|
|
995
|
+
|
|
996
|
+
sage: # needs sage.rings.number_field
|
|
997
|
+
sage: x = polygen(QQ, 'x')
|
|
998
|
+
sage: K.<a> = NumberField(x**4 + 20*x**2 - 80)
|
|
999
|
+
sage: K(5).is_square() # necessary but not sufficient!
|
|
1000
|
+
True
|
|
1001
|
+
sage: E = EllipticCurve(K, [0,0,0,1,0])
|
|
1002
|
+
sage: isogenies_5_1728(E)
|
|
1003
|
+
[Isogeny of degree 5
|
|
1004
|
+
from Elliptic Curve defined by y^2 = x^3 + x
|
|
1005
|
+
over Number Field in a with defining polynomial x^4 + 20*x^2 - 80
|
|
1006
|
+
to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (2779*a^3+65072*a)
|
|
1007
|
+
over Number Field in a with defining polynomial x^4 + 20*x^2 - 80,
|
|
1008
|
+
Isogeny of degree 5
|
|
1009
|
+
from Elliptic Curve defined by y^2 = x^3 + x
|
|
1010
|
+
over Number Field in a with defining polynomial x^4 + 20*x^2 - 80
|
|
1011
|
+
to Elliptic Curve defined by y^2 = x^3 + (-753/4*a^2-4399)*x + (-2779*a^3-65072*a)
|
|
1012
|
+
over Number Field in a with defining polynomial x^4 + 20*x^2 - 80]
|
|
1013
|
+
|
|
1014
|
+
See :issue:`19840`::
|
|
1015
|
+
|
|
1016
|
+
sage: # needs sage.rings.number_field
|
|
1017
|
+
sage: K.<a> = NumberField(x^4 - 5*x^2 + 5)
|
|
1018
|
+
sage: E = EllipticCurve([a^2 + a + 1, a^3 + a^2 + a + 1, a^2 + a,
|
|
1019
|
+
....: 17*a^3 + 34*a^2 - 16*a - 37,
|
|
1020
|
+
....: 54*a^3 + 105*a^2 - 66*a - 135])
|
|
1021
|
+
sage: len(E.isogenies_prime_degree(5))
|
|
1022
|
+
2
|
|
1023
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728
|
|
1024
|
+
sage: [phi.codomain().j_invariant() for phi in isogenies_5_1728(E)]
|
|
1025
|
+
[19691491018752*a^2 - 27212977933632, 19691491018752*a^2 - 27212977933632]
|
|
1026
|
+
"""
|
|
1027
|
+
F = E.base_field()
|
|
1028
|
+
if E.j_invariant() != 1728:
|
|
1029
|
+
raise ValueError("j-invariant must be 1728.")
|
|
1030
|
+
if F.characteristic() in [2,3,5]:
|
|
1031
|
+
raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
|
|
1032
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1033
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
1034
|
+
# quick test for a negative answer (from Fricke module)
|
|
1035
|
+
square5 = F(5).is_square()
|
|
1036
|
+
square1 = F(-1).is_square()
|
|
1037
|
+
if not square5 and not square1:
|
|
1038
|
+
return []
|
|
1039
|
+
Ew = E.short_weierstrass_model()
|
|
1040
|
+
iso = E.isomorphism_to(Ew)
|
|
1041
|
+
a = Ew.a4()
|
|
1042
|
+
x = polygen(F)
|
|
1043
|
+
isogs = []
|
|
1044
|
+
# 2 cases
|
|
1045
|
+
# Type 1: if -1 is a square we have 2 endomorphisms
|
|
1046
|
+
if square1:
|
|
1047
|
+
i = F(-1).sqrt()
|
|
1048
|
+
isogs = [Ew.isogeny(f) for f in [x**2+a/(1+2*i), x**2+a/(1-2*i)]]
|
|
1049
|
+
isogs = [isog.codomain().isomorphism_to(E) * isog for isog in isogs]
|
|
1050
|
+
# Type 2: if 5 is a square we have up to 4 (non-endomorphism) isogenies
|
|
1051
|
+
if square5:
|
|
1052
|
+
betas = sorted((x**4+20*a*x**2-80*a**2).roots(multiplicities=False))
|
|
1053
|
+
gammas = [(beta**2-2*a)/6 for beta in betas]
|
|
1054
|
+
isogs += [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
|
|
1055
|
+
isogs = [isog * iso for isog in isogs]
|
|
1056
|
+
return isogs
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
def isogenies_7_0(E, minimal_models=True):
|
|
1060
|
+
r"""
|
|
1061
|
+
Return list of all 7-isogenies from E when the j-invariant is 0.
|
|
1062
|
+
|
|
1063
|
+
INPUT:
|
|
1064
|
+
|
|
1065
|
+
- ``E`` -- an elliptic curve with j-invariant 0
|
|
1066
|
+
|
|
1067
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
1068
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
1069
|
+
fields of larger degree it can be expensive to compute these so
|
|
1070
|
+
set to ``False``.
|
|
1071
|
+
|
|
1072
|
+
OUTPUT:
|
|
1073
|
+
|
|
1074
|
+
(list) 7-isogenies with codomain E. In general these are
|
|
1075
|
+
normalised; but if `-3` is a square then there are two
|
|
1076
|
+
endomorphisms of degree `7`, for which the codomain is the same as
|
|
1077
|
+
the domain; and over `\QQ` or a number field, the codomain is a
|
|
1078
|
+
global minimal model where possible.
|
|
1079
|
+
|
|
1080
|
+
.. NOTE::
|
|
1081
|
+
|
|
1082
|
+
This implementation requires that the characteristic is not 2,
|
|
1083
|
+
3 or 7.
|
|
1084
|
+
|
|
1085
|
+
.. NOTE::
|
|
1086
|
+
|
|
1087
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
|
|
1088
|
+
|
|
1089
|
+
EXAMPLES:
|
|
1090
|
+
|
|
1091
|
+
First some examples of endomorphisms::
|
|
1092
|
+
|
|
1093
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0
|
|
1094
|
+
sage: K.<r> = QuadraticField(-3) # needs sage.rings.number_field
|
|
1095
|
+
sage: E = EllipticCurve(K, [0,1]) # needs sage.rings.number_field
|
|
1096
|
+
sage: isogenies_7_0(E) # needs sage.rings.number_field
|
|
1097
|
+
[Isogeny of degree 7
|
|
1098
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
|
|
1099
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1100
|
+
to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
|
|
1101
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I,
|
|
1102
|
+
Isogeny of degree 7
|
|
1103
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
|
|
1104
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1105
|
+
to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r
|
|
1106
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I]
|
|
1107
|
+
|
|
1108
|
+
sage: E = EllipticCurve(GF(13^2,'a'), [0,-3]) # needs sage.rings.finite_rings
|
|
1109
|
+
sage: isogenies_7_0(E) # needs sage.rings.finite_rings
|
|
1110
|
+
[Isogeny of degree 7
|
|
1111
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
1112
|
+
to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2,
|
|
1113
|
+
Isogeny of degree 7
|
|
1114
|
+
from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
|
|
1115
|
+
to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2]
|
|
1116
|
+
|
|
1117
|
+
Now some examples of 7-isogenies which are not endomorphisms::
|
|
1118
|
+
|
|
1119
|
+
sage: K = GF(101)
|
|
1120
|
+
sage: E = EllipticCurve(K, [0,1])
|
|
1121
|
+
sage: isogenies_7_0(E)
|
|
1122
|
+
[Isogeny of degree 7
|
|
1123
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101
|
|
1124
|
+
to Elliptic Curve defined by y^2 = x^3 + 55*x + 100 over Finite Field of size 101,
|
|
1125
|
+
Isogeny of degree 7
|
|
1126
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101
|
|
1127
|
+
to Elliptic Curve defined by y^2 = x^3 + 83*x + 26 over Finite Field of size 101]
|
|
1128
|
+
|
|
1129
|
+
Examples over a number field::
|
|
1130
|
+
|
|
1131
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0
|
|
1132
|
+
sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r')) # needs sage.rings.number_field
|
|
1133
|
+
sage: isogenies_7_0(E) # needs sage.rings.number_field
|
|
1134
|
+
[Isogeny of degree 7
|
|
1135
|
+
from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
|
|
1136
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1137
|
+
to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
|
|
1138
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I,
|
|
1139
|
+
Isogeny of degree 7
|
|
1140
|
+
from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
|
|
1141
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1142
|
+
to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r
|
|
1143
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I]
|
|
1144
|
+
|
|
1145
|
+
sage: # needs sage.rings.number_field sage.symbolic
|
|
1146
|
+
sage: x = polygen(QQ, 'x')
|
|
1147
|
+
sage: K.<a> = NumberField(x^6 + 1512*x^3 - 21168)
|
|
1148
|
+
sage: E = EllipticCurve(K, [0,1])
|
|
1149
|
+
sage: isogs = isogenies_7_0(E)
|
|
1150
|
+
sage: [phi.codomain().a_invariants() for phi in isogs]
|
|
1151
|
+
[(0,
|
|
1152
|
+
0,
|
|
1153
|
+
0,
|
|
1154
|
+
-415/98*a^5 - 675/14*a^4 + 2255/7*a^3 - 74700/7*a^2 - 25110*a - 66420,
|
|
1155
|
+
-141163/56*a^5 + 1443453/112*a^4 - 374275/2*a^3
|
|
1156
|
+
- 3500211/2*a^2 - 17871975/4*a - 7710065),
|
|
1157
|
+
(0,
|
|
1158
|
+
0,
|
|
1159
|
+
0,
|
|
1160
|
+
-24485/392*a^5 - 1080/7*a^4 - 2255/7*a^3 - 1340865/14*a^2 - 230040*a - 553500,
|
|
1161
|
+
1753037/56*a^5 + 8345733/112*a^4 + 374275/2*a^3
|
|
1162
|
+
+ 95377029/2*a^2 + 458385345/4*a + 275241835)]
|
|
1163
|
+
sage: [phi.codomain().j_invariant() for phi in isogs]
|
|
1164
|
+
[158428486656000/7*a^3 - 313976217600000,
|
|
1165
|
+
-158428486656000/7*a^3 - 34534529335296000]
|
|
1166
|
+
"""
|
|
1167
|
+
if E.j_invariant() != 0:
|
|
1168
|
+
raise ValueError("j-invariant must be 0.")
|
|
1169
|
+
F = E.base_field()
|
|
1170
|
+
if F.characteristic() in [2,3,7]:
|
|
1171
|
+
raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
|
|
1172
|
+
x = polygen(F)
|
|
1173
|
+
Ew = E.short_weierstrass_model()
|
|
1174
|
+
iso = E.isomorphism_to(Ew)
|
|
1175
|
+
a = Ew.a6()
|
|
1176
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1177
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
1178
|
+
|
|
1179
|
+
# there will be 2 endomorphisms if -3 is a square:
|
|
1180
|
+
|
|
1181
|
+
ts = sorted((x**2+3).roots(multiplicities=False))
|
|
1182
|
+
kers = [7*x-(2+6*t) for t in ts]
|
|
1183
|
+
kers = [k(x**3/a).monic() for k in kers]
|
|
1184
|
+
isogs = [Ew.isogeny(k,model=model) for k in kers]
|
|
1185
|
+
isogs = [endo.codomain().isomorphism_to(E) * endo for endo in isogs]
|
|
1186
|
+
|
|
1187
|
+
# we may have up to 6 other isogenies:
|
|
1188
|
+
ts = (x**2-21).roots(multiplicities=False)
|
|
1189
|
+
for t0 in ts:
|
|
1190
|
+
s3 = a/(28+6*t0)
|
|
1191
|
+
ss = sorted((x**3-s3).roots(multiplicities=False))
|
|
1192
|
+
ker = x**3 - 2*t0*x**2 - 4*t0*x + 4*t0 + 28
|
|
1193
|
+
kers = [ker(x/s).monic() for s in ss]
|
|
1194
|
+
isogs += [Ew.isogeny(k, model=model) for k in kers]
|
|
1195
|
+
|
|
1196
|
+
isogs = [isog * iso for isog in isogs]
|
|
1197
|
+
return isogs
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
def isogenies_7_1728(E, minimal_models=True):
|
|
1201
|
+
r"""
|
|
1202
|
+
Return list of all 7-isogenies from E when the j-invariant is 1728.
|
|
1203
|
+
|
|
1204
|
+
INPUT:
|
|
1205
|
+
|
|
1206
|
+
- ``E`` -- an elliptic curve with j-invariant 1728
|
|
1207
|
+
|
|
1208
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
1209
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
1210
|
+
fields of larger degree it can be expensive to compute these so
|
|
1211
|
+
set to ``False``.
|
|
1212
|
+
|
|
1213
|
+
OUTPUT:
|
|
1214
|
+
|
|
1215
|
+
(list) 7-isogenies with codomain E. In general these are
|
|
1216
|
+
normalised; but over `\QQ` or a number field, the codomain is a
|
|
1217
|
+
global minimal model where possible.
|
|
1218
|
+
|
|
1219
|
+
.. NOTE::
|
|
1220
|
+
|
|
1221
|
+
This implementation requires that the characteristic is not 2,
|
|
1222
|
+
3, or 7.
|
|
1223
|
+
|
|
1224
|
+
.. NOTE::
|
|
1225
|
+
|
|
1226
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
|
|
1227
|
+
|
|
1228
|
+
EXAMPLES::
|
|
1229
|
+
|
|
1230
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728
|
|
1231
|
+
sage: E = EllipticCurve(GF(47), [1, 0])
|
|
1232
|
+
sage: isogenies_7_1728(E)
|
|
1233
|
+
[Isogeny of degree 7
|
|
1234
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47
|
|
1235
|
+
to Elliptic Curve defined by y^2 = x^3 + 26 over Finite Field of size 47,
|
|
1236
|
+
Isogeny of degree 7
|
|
1237
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47
|
|
1238
|
+
to Elliptic Curve defined by y^2 = x^3 + 21 over Finite Field of size 47]
|
|
1239
|
+
|
|
1240
|
+
An example in characteristic 53 (for which an earlier implementation did not work)::
|
|
1241
|
+
|
|
1242
|
+
sage: # needs sage.rings.finite_rings
|
|
1243
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728
|
|
1244
|
+
sage: E = EllipticCurve(GF(53), [1, 0])
|
|
1245
|
+
sage: isogenies_7_1728(E)
|
|
1246
|
+
[]
|
|
1247
|
+
sage: E = EllipticCurve(GF(53^2,'a'), [1, 0])
|
|
1248
|
+
sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)]
|
|
1249
|
+
[(0, 0, 0, 36, 19*a + 15), (0, 0, 0, 36, 34*a + 38), (0, 0, 0, 33, 39*a + 28),
|
|
1250
|
+
(0, 0, 0, 33, 14*a + 25), (0, 0, 0, 19, 45*a + 16), (0, 0, 0, 19, 8*a + 37),
|
|
1251
|
+
(0, 0, 0, 3, 45*a + 16), (0, 0, 0, 3, 8*a + 37)]
|
|
1252
|
+
|
|
1253
|
+
::
|
|
1254
|
+
|
|
1255
|
+
sage: # needs sage.rings.number_field
|
|
1256
|
+
sage: x = polygen(QQ, 'x')
|
|
1257
|
+
sage: K.<a> = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567)
|
|
1258
|
+
sage: E = EllipticCurve(K, [1, 0])
|
|
1259
|
+
sage: isogs = isogenies_7_1728(E)
|
|
1260
|
+
sage: [phi.codomain().j_invariant() for phi in isogs]
|
|
1261
|
+
[-526110256146528/53*a^6 + 183649373229024*a^4
|
|
1262
|
+
- 3333881559996576/53*a^2 + 2910267397643616/53,
|
|
1263
|
+
-526110256146528/53*a^6 + 183649373229024*a^4
|
|
1264
|
+
- 3333881559996576/53*a^2 + 2910267397643616/53]
|
|
1265
|
+
sage: E1 = isogs[0].codomain()
|
|
1266
|
+
sage: E2 = isogs[1].codomain()
|
|
1267
|
+
sage: E1.is_isomorphic(E2)
|
|
1268
|
+
False
|
|
1269
|
+
sage: E1.is_quadratic_twist(E2)
|
|
1270
|
+
-1
|
|
1271
|
+
"""
|
|
1272
|
+
if E.j_invariant() != 1728:
|
|
1273
|
+
raise ValueError("j_invariant must be 1728 (in base field).")
|
|
1274
|
+
F = E.base_field()
|
|
1275
|
+
if F.characteristic() in [2,3,7]:
|
|
1276
|
+
raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
|
|
1277
|
+
Ew = E.short_weierstrass_model()
|
|
1278
|
+
iso = E.isomorphism_to(Ew)
|
|
1279
|
+
a = Ew.a4()
|
|
1280
|
+
|
|
1281
|
+
ts = (Fricke_module(7)-1728).numerator().roots(F,multiplicities=False)
|
|
1282
|
+
if not ts:
|
|
1283
|
+
return []
|
|
1284
|
+
ts.sort()
|
|
1285
|
+
isogs = []
|
|
1286
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1287
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
1288
|
+
x = polygen(F)
|
|
1289
|
+
for t0 in ts:
|
|
1290
|
+
s2 = a/t0
|
|
1291
|
+
ss = sorted((x**2-s2).roots(multiplicities=False))
|
|
1292
|
+
ker = 9*x**3 + (-3*t0**3 - 36*t0**2 - 123*t0)*x**2 + (-8*t0**3 - 101*t0**2 - 346*t0 + 35)*x - 7*t0**3 - 88*t0**2 - 296*t0 + 28
|
|
1293
|
+
|
|
1294
|
+
kers = [ker(x/s) for s in ss]
|
|
1295
|
+
isogs += [Ew.isogeny(k.monic(), model=model) for k in kers]
|
|
1296
|
+
isogs = [isog * iso for isog in isogs]
|
|
1297
|
+
return isogs
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
def isogenies_13_0(E, minimal_models=True):
|
|
1301
|
+
"""
|
|
1302
|
+
Return list of all 13-isogenies from E when the j-invariant is 0.
|
|
1303
|
+
|
|
1304
|
+
INPUT:
|
|
1305
|
+
|
|
1306
|
+
- ``E`` -- an elliptic curve with j-invariant 0
|
|
1307
|
+
|
|
1308
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
1309
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
1310
|
+
fields of larger degree it can be expensive to compute these so
|
|
1311
|
+
set to ``False``.
|
|
1312
|
+
|
|
1313
|
+
OUTPUT:
|
|
1314
|
+
|
|
1315
|
+
(list) 13-isogenies with codomain E. In general these are
|
|
1316
|
+
normalised; but if `-3` is a square then there are two
|
|
1317
|
+
endomorphisms of degree `13`, for which the codomain is the same
|
|
1318
|
+
as the domain.
|
|
1319
|
+
|
|
1320
|
+
.. NOTE::
|
|
1321
|
+
|
|
1322
|
+
This implementation requires that the characteristic is not 2,
|
|
1323
|
+
3 or 13.
|
|
1324
|
+
|
|
1325
|
+
.. NOTE::
|
|
1326
|
+
|
|
1327
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
|
|
1328
|
+
|
|
1329
|
+
EXAMPLES::
|
|
1330
|
+
|
|
1331
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_0
|
|
1332
|
+
|
|
1333
|
+
Endomorphisms of degree 13 will exist when -3 is a square::
|
|
1334
|
+
|
|
1335
|
+
sage: # needs sage.rings.number_field
|
|
1336
|
+
sage: K.<r> = QuadraticField(-3)
|
|
1337
|
+
sage: E = EllipticCurve(K, [0, r]); E
|
|
1338
|
+
Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
|
|
1339
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1340
|
+
sage: isogenies_13_0(E)
|
|
1341
|
+
[Isogeny of degree 13
|
|
1342
|
+
from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
|
|
1343
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1344
|
+
to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
|
|
1345
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I,
|
|
1346
|
+
Isogeny of degree 13
|
|
1347
|
+
from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
|
|
1348
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I
|
|
1349
|
+
to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r
|
|
1350
|
+
with defining polynomial x^2 + 3 with r = 1.732050807568878?*I]
|
|
1351
|
+
sage: isogenies_13_0(E)[0].rational_maps()
|
|
1352
|
+
(((7/338*r + 23/338)*x^13 + (-164/13*r - 420/13)*x^10
|
|
1353
|
+
+ (720/13*r + 3168/13)*x^7 + (3840/13*r - 576/13)*x^4
|
|
1354
|
+
+ (4608/13*r + 2304/13)*x)/(x^12 + (4*r + 36)*x^9 + (1080/13*r + 3816/13)*x^6
|
|
1355
|
+
+ (2112/13*r - 5184/13)*x^3 + (-17280/169*r - 1152/169)),
|
|
1356
|
+
((18/2197*r + 35/2197)*x^18*y + (23142/2197*r + 35478/2197)*x^15*y
|
|
1357
|
+
+ (-1127520/2197*r - 1559664/2197)*x^12*y + (-87744/2197*r + 5992704/2197)*x^9*y
|
|
1358
|
+
+ (-6625152/2197*r - 9085824/2197)*x^6*y + (-28919808/2197*r - 2239488/2197)*x^3*y
|
|
1359
|
+
+ (-1990656/2197*r - 3870720/2197)*y)/(x^18 + (6*r + 54)*x^15
|
|
1360
|
+
+ (3024/13*r + 11808/13)*x^12 + (31296/13*r + 51840/13)*x^9
|
|
1361
|
+
+ (487296/169*r - 2070144/169)*x^6 + (-940032/169*r + 248832/169)*x^3
|
|
1362
|
+
+ (1990656/2197*r + 3870720/2197)))
|
|
1363
|
+
|
|
1364
|
+
An example of endomorphisms over a finite field::
|
|
1365
|
+
|
|
1366
|
+
sage: # needs sage.rings.finite_rings
|
|
1367
|
+
sage: K = GF(19^2,'a')
|
|
1368
|
+
sage: E = EllipticCurve(j=K(0)); E
|
|
1369
|
+
Elliptic Curve defined by y^2 = x^3 + 1
|
|
1370
|
+
over Finite Field in a of size 19^2
|
|
1371
|
+
sage: isogenies_13_0(E)
|
|
1372
|
+
[Isogeny of degree 13
|
|
1373
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
|
|
1374
|
+
to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2,
|
|
1375
|
+
Isogeny of degree 13
|
|
1376
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
|
|
1377
|
+
to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2]
|
|
1378
|
+
sage: isogenies_13_0(E)[0].rational_maps()
|
|
1379
|
+
((6*x^13 - 6*x^10 - 3*x^7 + 6*x^4 + x)/(x^12 - 5*x^9 - 9*x^6 - 7*x^3 + 5),
|
|
1380
|
+
(-8*x^18*y - 9*x^15*y + 9*x^12*y - 5*x^9*y
|
|
1381
|
+
+ 5*x^6*y - 7*x^3*y + 7*y)/(x^18 + 2*x^15 + 3*x^12 - x^9 + 8*x^6 - 9*x^3 + 7))
|
|
1382
|
+
|
|
1383
|
+
A previous implementation did not work in some characteristics::
|
|
1384
|
+
|
|
1385
|
+
sage: K = GF(29)
|
|
1386
|
+
sage: E = EllipticCurve(j=K(0))
|
|
1387
|
+
sage: isogenies_13_0(E)
|
|
1388
|
+
[Isogeny of degree 13
|
|
1389
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29
|
|
1390
|
+
to Elliptic Curve defined by y^2 = x^3 + 26*x + 12 over Finite Field of size 29,
|
|
1391
|
+
Isogeny of degree 13
|
|
1392
|
+
from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29
|
|
1393
|
+
to Elliptic Curve defined by y^2 = x^3 + 16*x + 28 over Finite Field of size 29]
|
|
1394
|
+
|
|
1395
|
+
::
|
|
1396
|
+
|
|
1397
|
+
sage: K = GF(101)
|
|
1398
|
+
sage: E = EllipticCurve(j=K(0)); E.ainvs()
|
|
1399
|
+
(0, 0, 0, 0, 1)
|
|
1400
|
+
sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
|
|
1401
|
+
[(0, 0, 0, 64, 36), (0, 0, 0, 42, 66)]
|
|
1402
|
+
|
|
1403
|
+
::
|
|
1404
|
+
|
|
1405
|
+
sage: x = polygen(QQ)
|
|
1406
|
+
sage: f = x^12 + 78624*x^9 - 130308048*x^6 + 2270840832*x^3 - 54500179968
|
|
1407
|
+
sage: K.<a> = NumberField(f) # needs sage.rings.number_field
|
|
1408
|
+
sage: E = EllipticCurve(j=K(0)); E.ainvs() # needs sage.rings.number_field
|
|
1409
|
+
(0, 0, 0, 0, 1)
|
|
1410
|
+
sage: len([phi.codomain().ainvs() # long time # needs sage.rings.number_field
|
|
1411
|
+
....: for phi in isogenies_13_0(E)])
|
|
1412
|
+
2
|
|
1413
|
+
"""
|
|
1414
|
+
if E.j_invariant() != 0:
|
|
1415
|
+
raise ValueError("j-invariant must be 0.")
|
|
1416
|
+
F = E.base_field()
|
|
1417
|
+
if F.characteristic() in [2,3,13]:
|
|
1418
|
+
raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
|
|
1419
|
+
Ew = E.short_weierstrass_model()
|
|
1420
|
+
iso = E.isomorphism_to(Ew)
|
|
1421
|
+
a = Ew.a6()
|
|
1422
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1423
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
1424
|
+
x = polygen(F)
|
|
1425
|
+
|
|
1426
|
+
# there will be 2 endomorphisms if -3 is a square:
|
|
1427
|
+
ts = sorted((x**2+3).roots(multiplicities=False))
|
|
1428
|
+
kers = [13*x**2 + (78*t + 26)*x + 24*t + 40 for t in ts]
|
|
1429
|
+
kers = [k(x**3/a).monic() for k in kers]
|
|
1430
|
+
isogs = [Ew.isogeny(k,model=model) for k in kers]
|
|
1431
|
+
isogs = [endo.codomain().isomorphism_to(E) * endo for endo in isogs]
|
|
1432
|
+
|
|
1433
|
+
# we may have up to 12 other isogenies:
|
|
1434
|
+
ts = sorted((x**4 + 7*x**3 + 20*x**2 + 19*x + 1).roots(multiplicities=False))
|
|
1435
|
+
for t0 in ts:
|
|
1436
|
+
s3 = a / (6*t0**3 + 32*t0**2 + 68*t0 + 4)
|
|
1437
|
+
ss = sorted((x**3-s3).roots(multiplicities=False))
|
|
1438
|
+
ker = (x**6 + (20*t0**3 + 106*t0**2 + 218*t0 + 4)*x**5
|
|
1439
|
+
+ (-826*t0**3 - 4424*t0**2 - 9244*t0 - 494)*x**4
|
|
1440
|
+
+ (13514*t0**3 + 72416*t0**2 + 151416*t0 + 8238)*x**3
|
|
1441
|
+
+ (-101948*t0**3 - 546304*t0**2 - 1142288*t0 - 62116)*x**2
|
|
1442
|
+
+ (354472*t0**3 + 1899488*t0**2 + 3971680*t0 + 215960)*x
|
|
1443
|
+
- 459424*t0**3 - 2461888*t0**2 - 5147648*t0 - 279904)
|
|
1444
|
+
kers = [ker(x/s).monic() for s in ss]
|
|
1445
|
+
isogs += [Ew.isogeny(k, model=model) for k in kers]
|
|
1446
|
+
|
|
1447
|
+
isogs = [isog * iso for isog in isogs]
|
|
1448
|
+
|
|
1449
|
+
return isogs
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
def isogenies_13_1728(E, minimal_models=True):
|
|
1453
|
+
r"""
|
|
1454
|
+
Return list of all 13-isogenies from E when the j-invariant is 1728.
|
|
1455
|
+
|
|
1456
|
+
INPUT:
|
|
1457
|
+
|
|
1458
|
+
- ``E`` -- an elliptic curve with j-invariant 1728
|
|
1459
|
+
|
|
1460
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
1461
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
1462
|
+
fields of larger degree it can be expensive to compute these so
|
|
1463
|
+
set to ``False``.
|
|
1464
|
+
|
|
1465
|
+
OUTPUT:
|
|
1466
|
+
|
|
1467
|
+
(list) 13-isogenies with codomain E. In general these are
|
|
1468
|
+
normalised; but if `-1` is a square then there are two
|
|
1469
|
+
endomorphisms of degree `13`, for which the codomain is the same
|
|
1470
|
+
as the domain; and over `\QQ` or a number field, the codomain is a
|
|
1471
|
+
global minimal model where possible.
|
|
1472
|
+
|
|
1473
|
+
.. NOTE::
|
|
1474
|
+
|
|
1475
|
+
This implementation requires that the characteristic is not
|
|
1476
|
+
2, 3 or 13.
|
|
1477
|
+
|
|
1478
|
+
.. NOTE::
|
|
1479
|
+
|
|
1480
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
|
|
1481
|
+
|
|
1482
|
+
EXAMPLES::
|
|
1483
|
+
|
|
1484
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_1728
|
|
1485
|
+
|
|
1486
|
+
sage: K.<i> = QuadraticField(-1) # needs sage.rings.number_field
|
|
1487
|
+
sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs() # needs sage.rings.number_field
|
|
1488
|
+
(0, 0, 0, i, 0)
|
|
1489
|
+
sage: isogenies_13_1728(E) # needs sage.rings.number_field
|
|
1490
|
+
[Isogeny of degree 13
|
|
1491
|
+
from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
|
|
1492
|
+
with defining polynomial x^2 + 1 with i = 1*I
|
|
1493
|
+
to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
|
|
1494
|
+
with defining polynomial x^2 + 1 with i = 1*I,
|
|
1495
|
+
Isogeny of degree 13
|
|
1496
|
+
from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
|
|
1497
|
+
with defining polynomial x^2 + 1 with i = 1*I
|
|
1498
|
+
to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i
|
|
1499
|
+
with defining polynomial x^2 + 1 with i = 1*I]
|
|
1500
|
+
|
|
1501
|
+
::
|
|
1502
|
+
|
|
1503
|
+
sage: K = GF(83)
|
|
1504
|
+
sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
|
|
1505
|
+
(0, 0, 0, 5, 0)
|
|
1506
|
+
sage: isogenies_13_1728(E)
|
|
1507
|
+
[]
|
|
1508
|
+
sage: K = GF(89)
|
|
1509
|
+
sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
|
|
1510
|
+
(0, 0, 0, 5, 0)
|
|
1511
|
+
sage: isogenies_13_1728(E)
|
|
1512
|
+
[Isogeny of degree 13
|
|
1513
|
+
from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89
|
|
1514
|
+
to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89,
|
|
1515
|
+
Isogeny of degree 13
|
|
1516
|
+
from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89
|
|
1517
|
+
to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89]
|
|
1518
|
+
|
|
1519
|
+
::
|
|
1520
|
+
|
|
1521
|
+
sage: K = GF(23)
|
|
1522
|
+
sage: E = EllipticCurve(K, [1,0])
|
|
1523
|
+
sage: isogenies_13_1728(E)
|
|
1524
|
+
[Isogeny of degree 13
|
|
1525
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23
|
|
1526
|
+
to Elliptic Curve defined by y^2 = x^3 + 16 over Finite Field of size 23,
|
|
1527
|
+
Isogeny of degree 13
|
|
1528
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23
|
|
1529
|
+
to Elliptic Curve defined by y^2 = x^3 + 7 over Finite Field of size 23]
|
|
1530
|
+
|
|
1531
|
+
::
|
|
1532
|
+
|
|
1533
|
+
sage: x = polygen(QQ)
|
|
1534
|
+
sage: f = (x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6
|
|
1535
|
+
....: - 282896640*x^4 - 149879808*x^2 - 349360128)
|
|
1536
|
+
sage: K.<a> = NumberField(f) # needs sage.rings.number_field
|
|
1537
|
+
sage: E = EllipticCurve(K, [1,0]) # needs sage.rings.number_field
|
|
1538
|
+
sage: [phi.codomain().ainvs() # long time # needs sage.rings.number_field
|
|
1539
|
+
....: for phi in isogenies_13_1728(E)]
|
|
1540
|
+
[(0,
|
|
1541
|
+
0,
|
|
1542
|
+
0,
|
|
1543
|
+
-4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8
|
|
1544
|
+
+ 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4
|
|
1545
|
+
+ 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472,
|
|
1546
|
+
-363594277511/574456513088876544*a^11 - 7213386922793/2991961005671232*a^9
|
|
1547
|
+
- 2810970361185589/1329760446964992*a^7 + 281503836888046601/8975883017013696*a^5
|
|
1548
|
+
- 1287313166530075/848061509544*a^3 + 9768837984886039/6925835661276*a),
|
|
1549
|
+
(0,
|
|
1550
|
+
0,
|
|
1551
|
+
0,
|
|
1552
|
+
-4225010072113/3063768069807341568*a^10 - 24841071989413/15957125363579904*a^8
|
|
1553
|
+
+ 11179537789374271/21276167151439872*a^6 - 407474562289492049/47871376090739712*a^4
|
|
1554
|
+
+ 1608052769560747/4522994717568*a^2 + 7786720245212809/36937790193472,
|
|
1555
|
+
363594277511/574456513088876544*a^11 + 7213386922793/2991961005671232*a^9
|
|
1556
|
+
+ 2810970361185589/1329760446964992*a^7 - 281503836888046601/8975883017013696*a^5
|
|
1557
|
+
+ 1287313166530075/848061509544*a^3 - 9768837984886039/6925835661276*a)]
|
|
1558
|
+
"""
|
|
1559
|
+
if E.j_invariant() != 1728:
|
|
1560
|
+
raise ValueError("j-invariant must be 1728.")
|
|
1561
|
+
F = E.base_field()
|
|
1562
|
+
if F.characteristic() in [2, 3, 13]:
|
|
1563
|
+
raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
|
|
1564
|
+
Ew = E.short_weierstrass_model()
|
|
1565
|
+
iso = E.isomorphism_to(Ew)
|
|
1566
|
+
a = Ew.a4()
|
|
1567
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1568
|
+
model = "minimal" if minimal_models and isinstance(F, NumberField) else None
|
|
1569
|
+
x = polygen(F)
|
|
1570
|
+
|
|
1571
|
+
# we will have two endomorphisms if -1 is a square:
|
|
1572
|
+
ts = sorted((x**2+1).roots(multiplicities=False))
|
|
1573
|
+
kers = [13*x**3 + (-26*i - 13)*x**2 + (-52*i - 13)*x - 2*i - 3 for i in ts]
|
|
1574
|
+
kers = [k(x**2/a).monic() for k in kers]
|
|
1575
|
+
isogs = [Ew.isogeny(k,model=model) for k in kers]
|
|
1576
|
+
isogs = [endo.codomain().isomorphism_to(E) * endo for endo in isogs]
|
|
1577
|
+
|
|
1578
|
+
# we may have up to 12 other isogenies:
|
|
1579
|
+
|
|
1580
|
+
ts = sorted((x**6 + 10*x**5 + 46*x**4 + 108*x**3 + 122*x**2 + 38*x - 1).roots(multiplicities=False))
|
|
1581
|
+
for t0 in ts:
|
|
1582
|
+
s2 = a/(66*t0**5 + 630*t0**4 + 2750*t0**3 + 5882*t0**2 + 5414*t0 + 162)
|
|
1583
|
+
ss = sorted((x**2-s2).roots(multiplicities=False))
|
|
1584
|
+
ker = (x**6 + (-66*t0**5 - 630*t0**4 - 2750*t0**3 - 5882*t0**2
|
|
1585
|
+
- 5414*t0 - 162)*x**5 + (-21722*t0**5 - 205718*t0**4 -
|
|
1586
|
+
890146*t0**3 - 1873338*t0**2 - 1652478*t0 + 61610)*x**4
|
|
1587
|
+
+ (-3391376*t0**5 - 32162416*t0**4 - 139397232*t0**3 -
|
|
1588
|
+
294310576*t0**2 - 261885968*t0 + 6105552)*x**3 +
|
|
1589
|
+
(-241695080*t0**5 - 2291695976*t0**4 - 9930313256*t0**3
|
|
1590
|
+
- 20956609720*t0**2 - 18625380856*t0 + 469971320)*x**2 +
|
|
1591
|
+
(-8085170432*t0**5 - 76663232384*t0**4 -
|
|
1592
|
+
332202985024*t0**3 - 701103233152*t0**2 -
|
|
1593
|
+
623190845440*t0 + 15598973056)*x - 101980510208*t0**5 -
|
|
1594
|
+
966973468160*t0**4 - 4190156868352*t0**3 -
|
|
1595
|
+
8843158270336*t0**2 - 7860368751232*t0 + 196854655936)
|
|
1596
|
+
|
|
1597
|
+
kers = [ker(x/s).monic() for s in ss]
|
|
1598
|
+
isogs += [Ew.isogeny(k, model=model) for k in kers]
|
|
1599
|
+
|
|
1600
|
+
isogs = [isog * iso for isog in isogs]
|
|
1601
|
+
|
|
1602
|
+
return isogs
|
|
1603
|
+
|
|
1604
|
+
# List of primes l for which X_0(l) is (hyper)elliptic and X_0^+(l) has genus 0
|
|
1605
|
+
|
|
1606
|
+
|
|
1607
|
+
hyperelliptic_primes = [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
|
|
1608
|
+
|
|
1609
|
+
|
|
1610
|
+
@cached_function
|
|
1611
|
+
def _hyperelliptic_isogeny_data(l):
|
|
1612
|
+
r"""
|
|
1613
|
+
Helper function for elliptic curve isogenies.
|
|
1614
|
+
|
|
1615
|
+
INPUT:
|
|
1616
|
+
|
|
1617
|
+
- ``l`` -- a prime in [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
|
|
1618
|
+
|
|
1619
|
+
OUTPUT: a dict holding a collection of precomputed data needed for
|
|
1620
|
+
computing `l`-isogenies
|
|
1621
|
+
|
|
1622
|
+
EXAMPLES::
|
|
1623
|
+
|
|
1624
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _hyperelliptic_isogeny_data
|
|
1625
|
+
sage: HID = _hyperelliptic_isogeny_data(11)
|
|
1626
|
+
sage: HID['A2']
|
|
1627
|
+
55*u - 33
|
|
1628
|
+
sage: HID['A4']
|
|
1629
|
+
-183*u^2 + 738*u - 180*v - 135
|
|
1630
|
+
sage: HID['A6']
|
|
1631
|
+
1330*u^3 - 11466*u^2 + 1332*u*v + 2646*u - 1836*v + 1890
|
|
1632
|
+
sage: HID['alpha']
|
|
1633
|
+
u^11 - 55*u^10 + 1188*u^9 - 12716*u^8 + 69630*u^7 - 177408*u^6 + 133056*u^5 + 132066*u^4 - 187407*u^3 + 40095*u^2 + 24300*u - 6750
|
|
1634
|
+
sage: HID['beta']
|
|
1635
|
+
u^9 - 47*u^8 + 843*u^7 - 7187*u^6 + 29313*u^5 - 48573*u^4 + 10665*u^3 + 27135*u^2 - 12150*u
|
|
1636
|
+
sage: HID['hyper_poly']
|
|
1637
|
+
u^4 - 16*u^3 + 2*u^2 + 12*u - 7
|
|
1638
|
+
|
|
1639
|
+
sage: _hyperelliptic_isogeny_data(37)
|
|
1640
|
+
Traceback (most recent call last):
|
|
1641
|
+
...
|
|
1642
|
+
ValueError: 37 must be one of [11, 17, 19, 23, 29, 31, 41, 47, 59, 71].
|
|
1643
|
+
"""
|
|
1644
|
+
if l not in hyperelliptic_primes:
|
|
1645
|
+
raise ValueError("%s must be one of %s." % (l,hyperelliptic_primes))
|
|
1646
|
+
data = {}
|
|
1647
|
+
Zu = PolynomialRing(ZZ,'u')
|
|
1648
|
+
Zuv = PolynomialRing(ZZ,['u','v'])
|
|
1649
|
+
Zxuv = PolynomialRing(ZZ,['x','u','v'])
|
|
1650
|
+
x,u,v = Zxuv.gens()
|
|
1651
|
+
if l == 11:
|
|
1652
|
+
data['hyper_poly'] = Zu([-7, 12, 2, -16, 1])
|
|
1653
|
+
data['A2'] = Zu([-33, 55])
|
|
1654
|
+
data['A4'] = Zuv(Zu([-135, 738, -183])+v*Zu([-180]))
|
|
1655
|
+
data['A6'] = Zuv(Zu([1890, 2646, -11466, 1330]) + v*Zu([-1836, 1332]))
|
|
1656
|
+
data['alpha'] = Zu([-6750, 24300, 40095, -187407, 132066, 133056, -177408, 69630, -12716, 1188, -55, 1])
|
|
1657
|
+
data['beta'] = Zu([0, -12150, 27135, 10665, -48573, 29313, -7187, 843, -47, 1])
|
|
1658
|
+
#beta factors as (u - 15) * (u - 6) * (u - 3) * (u - 1) * u * (u**2 - 12*u - 9) * (u**2 - 10*u + 5)
|
|
1659
|
+
return data
|
|
1660
|
+
if l == 17:
|
|
1661
|
+
data['hyper_poly'] = Zu([-8, 4, -3, -10, 1])
|
|
1662
|
+
data['A2'] = Zu([68, -204, 136])
|
|
1663
|
+
data['A4'] = Zuv(Zu([60, 720, -2595, 2250, -435]) + v*Zu([-360, 792, -432]))
|
|
1664
|
+
data['A6'] = Zuv(Zu([-8512, 22608, -5064, -57528, 87288, -43704, 4912] ) + v*Zu( [2520, -15372, 28098, -20160, 4914]))
|
|
1665
|
+
data['alpha'] = Zu([16000, -67200, 2720, 557600, -1392232, 1073992, 1104830, -3131026, 2450210, 73746, -1454945, 1110355, -424065, 95659, -13243, 1105, -51, 1])
|
|
1666
|
+
data['beta'] = Zu([0, 22400, -105920, 146208, 111616, -593800, 680948, -102282, -457950, 468035, -219274, 58549, -9374, 889, -46, 1])
|
|
1667
|
+
#beta factors as (u - 10) * (u - 5) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 10*u + 7) * (u**2 - 6*u - 4) * (u**2 - 4*u + 2) * (u**3 - 9*u**2 + 8*u - 4)
|
|
1668
|
+
data['endo'] = 17*x**8 + 17*(-4*u + 4)*v*x**6 + 17*(4*u + 6)*v**2*x**4 + 17*(4*u + 4)*v**3*x**2 + (-4*u + 1)*v**4
|
|
1669
|
+
data['endo_u'] = 1
|
|
1670
|
+
return data
|
|
1671
|
+
if l == 19:
|
|
1672
|
+
data['hyper_poly'] = Zu([-8, 20, -8, -8, 1])
|
|
1673
|
+
data['A2'] = Zu([-114, 57, 171])
|
|
1674
|
+
data['A4'] = Zuv(Zu([-1020, 444, 2733, 726, -543]) + v*Zu([-180, -720, -540]))
|
|
1675
|
+
data['A6'] = Zuv(Zu([-10080, 21816, 54324, -37386, -86742, -20070, 6858]) + v*Zu([-2968, -13748, -11284, 6356, 6860]))
|
|
1676
|
+
data['alpha'] = Zu([16000, -22400, -337440, 475456, 1562104, -1988616, -3025294, 3245960, 2833014, -2420087, -1140950, 932406, 129580, -180443, 21090, 11153, -4066, 570, -38, 1])
|
|
1677
|
+
data['beta'] = Zu([0, 33600, -8160, -292400, 23472, 791244, 39282, -847909, -47024, 392654, -24046, -82469, 19162, 4833, -2652, 446, -34, 1])
|
|
1678
|
+
#beta factors as (u - 7) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u - 4) * (u**2 - 6*u - 15) * (u**2 - 5*u - 5) * (u**2 - 5*u + 2) * (u**2 - 2*u - 4) * (u**2 + u - 1)
|
|
1679
|
+
data['endo'] = 19*x**9 + 19*(-12*u - 24)*v*x**6 + 19*(-24*u - 24)*v**2*x**3 + (96*u - 224)*v**3
|
|
1680
|
+
data['endo_u'] = -1
|
|
1681
|
+
return data
|
|
1682
|
+
if l == 23:
|
|
1683
|
+
data['hyper_poly'] = Zu([-7, 10, -11, 2, 2, -8, 1])
|
|
1684
|
+
data['A2'] = Zu([69, -230, 253])
|
|
1685
|
+
data['A4'] = Zuv(Zu([405, 180, -930, 2820, -795]) + v*Zu([360, -792]))
|
|
1686
|
+
data['A6'] = Zuv(Zu([-15498, 34020, -36918, -8120, 51114, -72492, 12166]) + v*Zu([-1080, 7704, -24840, 12168]))
|
|
1687
|
+
data['alpha'] = Zu([-6750, 48600, -83835, -170775, 1115109, -2492280, 2732814, -116403, -4877702, 8362616, -6612454, 302266, 5423124, -6447728, 3209696, 336674, -1470068, 953856, -336927, 74221, -10465, 920, -46, 1])
|
|
1688
|
+
data['beta'] = Zu( [0, 12150, -72495, 168588, -144045, -254034, 930982, -1256170, 604358, 693650, -1563176, 1271974, -225188, -444070, 421050, -184350, 47754, -7696, 759, -42, 1])
|
|
1689
|
+
#beta factors as (u - 5) * (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u + 3) * (u**2 - 6*u - 9) * (u**3 - 7*u**2 + 3*u - 5) * (u**3 - 7*u**2 + 7*u - 3) * (u**4 - 4*u**3 - 1)
|
|
1690
|
+
return data
|
|
1691
|
+
if l == 29:
|
|
1692
|
+
data['hyper_poly'] = Zu([-7, 8, 8, 2, -12, -4, 1])
|
|
1693
|
+
data['A2'] = Zu([-174, -232, 348, 406])
|
|
1694
|
+
data['A4'] = Zuv(Zu([-1215, -3096, 132, 7614, 6504, -360, -1263] ) + v*Zu( [180, -720, -2160, -1260]))
|
|
1695
|
+
data['A6'] = Zuv(Zu([-18900, -63504, 24696, 285068, 285264, -185136, -506268, -275520, 504, 24388] ) + v*Zu( [4482, -2448, -59868, -94968, -18144, 48276, 24390]))
|
|
1696
|
+
data['alpha'] = Zu([-6750, -12150, 281880, 570024, -1754181, -5229135, 2357613, 19103721, 9708910, -31795426, -38397537, 19207947, 54103270, 9216142, -37142939, -18871083, 14041394, 10954634, -3592085, -3427365, 853818, 622398, -189399, -53679, 26680, -580, -1421, 319, -29, 1])
|
|
1697
|
+
data['beta'] = Zu([0, -24300, -57510, 257850, 839187, -373185, -3602119, -2371192, 5865017, 8434433, -2363779, -10263744, -2746015, 5976011, 3151075, -2093854, -1356433, 569525, 299477, -129484, -28279, 19043, -895, -1076, 273, -27, 1])
|
|
1698
|
+
#beta factors as (u - 3) * (u - 1) * u * (u + 1) * (u + 2) * (u**2 - 6*u + 2) * (u**2 - 5*u - 5) * (u**2 - 5*u + 3) * (u**2 - 3*u - 9) * (u**2 - u - 3) * (u**2 - u - 1) * (u**2 + u - 1) * (u**3 - 4*u**2 - 6*u - 5) * (u**4 - 2*u**3 - 5*u**2 - 4*u - 1)
|
|
1699
|
+
data['endo'] = 29*x**14 + 29*(-14*u + 3)*v*x**12 + 29*(-20*u + 73)*v**2*x**10 + 29*(-58*u + 115)*v**3*x**8 + 29*(-56*u + 59)*v**4*x**6 + 29*(30*u + 1)*v**5*x**4 + 29*(12*u - 5)*v**6*x**2 + (2*u + 5)*v**7
|
|
1700
|
+
data['endo_u'] = -1
|
|
1701
|
+
return data
|
|
1702
|
+
if l == 31:
|
|
1703
|
+
data['hyper_poly'] = Zu([-3, -14, -11, 18, 6, -8, 1])
|
|
1704
|
+
data['A2'] = Zu([558, 837, -1488, 465])
|
|
1705
|
+
data['A4'] = Zuv(Zu([-4140, -12468, 15189, 16956, -27054, 11184, -1443]) + v*Zu([2160, -7560, 6120, -1440]))
|
|
1706
|
+
data['A6'] = Zuv(Zu([71280, 592056, -108324, -2609730, 2373048, 1282266, -2793204, 1530882, -356976, 29790]) + v*Zu([-81312, 181664, 294728, -868392, 701400, -238840, 29792]))
|
|
1707
|
+
data['alpha'] = Zu([108000, 475200, -7053120, -27353408, 90884374, 303670296, -665806437, -1361301729, 3259359840, 2249261823, -9368721606, 2279583264, 13054272515, -12759480061, -4169029296, 14390047139, -7803693550, -2988803682, 6239473912, -3296588360, 134066754, 908915598, -685615437, 294482733, -87483178, 18983315, -3052818, 361336, -30659, 1767, -62, 1])
|
|
1708
|
+
data['beta'] = Zu([0, 712800, 1216080, -18430560, -15262464, 168899202, -12931221, -720077416, 624871714, 1239052988, -2259335558, 68648452, 2679085427, -2318039014, -229246628, 1710545918, -1243026758, 211524870, 296674626, -291810274, 145889932, -48916468, 11793961, -2085662, 269348, -24778, 1540, -58, 1])
|
|
1709
|
+
#beta factors as (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u + 11) * (u**2 - 7*u + 2) * (u**2 - 5*u - 2) * (u**2 - 5*u + 5) * (u**2 - 4*u - 4) * (u**2 - 4*u - 1) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**3 - 9*u**2 + 21*u - 15) * (u**4 - 8*u**3 + 8*u**2 + 12*u - 9)
|
|
1710
|
+
data['endo'] = 31*x**15 + 31*(-66*u + 86)*v*x**12 + 31*(168*u + 280)*v**2*x**9 + 31*(576*u + 1792)*v**3*x**6 + 31*(384*u + 896)*v**4*x**3 + (-3072*u - 2048)*v**5
|
|
1711
|
+
data['endo_u'] = 2
|
|
1712
|
+
return data
|
|
1713
|
+
if l == 41:
|
|
1714
|
+
data['hyper_poly'] = Zu([-8, -20, -15, 8, 20, 10, -8, -4, 1])
|
|
1715
|
+
data['A2'] = Zu([328, 656, -656, -1148, 820])
|
|
1716
|
+
data['A4'] = Zuv(Zu([-1380, -4008, 1701, 10872, 6144, -18378, -2160, 9732, -2523]) + v*Zu([720, -1440, -2160, 5400, -2520]))
|
|
1717
|
+
data['A6'] = Zuv(Zu([4480, 155616, 16080, -550720, -343968, 832680, 938632, -621648, -1468608, 953920, 427632, -413016, 68920]) + v*Zu([-14616, 6804, 96390, -2016, -324324, 184464, 260568, -276192, 68922]))
|
|
1718
|
+
data['alpha'] = Zu([16000, 67200, -465760, -2966432, -1742664, 20985112, 46140990, -31732934, -217030548, -147139488, 436080674, 745775322, -271341362, -1542677562, -605560447, 1832223375, 1772593672, -1270633050, -2400692229, 343522723, 2179745361, 282422801, -1503727029, -421357697, 879637411, 261059095, -462271351, -61715127, 193718727, -24135265, -49355103, 20512341, 3613289, -4706595, 1099661, 163057, -162483, 46617, -7544, 738, -41, 1])
|
|
1719
|
+
data['beta'] = Zu([0, 44800, 167040, -447040, -2734272, -1104272, 13488360, 21067652, -24681704, -83929974, -8986886, 169059382, 127641266, -196479899, -283039783, 124573790, 366614063, -12946368, -332987597, -58867672, 241909907, 60568430, -155045647, -17919564, 79114945, -12025938, -24060781, 11190142, 1979597, -2931764, 750233, 110144, -122263, 37484, -6439, 666, -39, 1])
|
|
1720
|
+
#beta factors as (u - 5) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 5) * (u**2 - 3*u - 7) * (u**2 - 2*u - 4) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**2 - 2) * (u**2 + u - 1) * (u**3 - 3*u**2 - 5*u - 2) * (u**3 - 2*u**2 - 2*u - 1) * (u**4 - 6*u**3 + 5*u**2 + 2*u - 1) * (u**4 - 5*u**3 + u**2 + 4) * (u**4 - 4*u**3 + 2)
|
|
1721
|
+
data['endo'] = 41*x**20 + 41*(-12*u - 22)*v*x**18 + 41*(-252*u - 247)*v**2*x**16 + 41*(-176*u - 424)*v**3*x**14 + 41*(464*u - 254)*v**4*x**12 + 41*(1688*u - 868)*v**5*x**10 + 41*(1720*u - 1190)*v**6*x**8 + 41*(528*u - 232)*v**7*x**6 + 41*(16*u + 29)*v**8*x**4 + 41*(20*u + 10)*v**9*x**2 + (4*u + 5)*v**10
|
|
1722
|
+
data['endo_u'] = 1
|
|
1723
|
+
return data
|
|
1724
|
+
if l == 47:
|
|
1725
|
+
data['hyper_poly'] = Zu([-11, 28, -38, 30, -13, -16, 19, -24, 11, -6, 1])
|
|
1726
|
+
data['A2'] = Zu([376, -1504, 2209, -1598, 1081])
|
|
1727
|
+
data['A4'] = Zuv(Zu([2400, -4080, -1440, 18000, -26355, 34740, -22050, 12900, -3315]) + v*Zu([1152, -3384, 3672, -3312]))
|
|
1728
|
+
data['A6'] = Zuv(Zu([-119504, 606336, -1505280, 2109392, -1509360, -515808, 2920702, -4614012, 4334322, -3260312, 1571442, -622428, 103822]) + v*Zu([2016, 48384, -235872, 438984, -627480, 503496, -311976, 103824]))
|
|
1729
|
+
data['alpha'] = Zu([-65536, 688128, -2502656, -96256, 38598656, -187217920, 508021120, -845669120, 552981696, 1469334304, -5945275904, 11705275552, -14673798654, 9100068184, 8421580132, -34288012648, 56657584158, -60426283952, 36612252089, 9942017442, -60791892299, 93046207239, -92028642340, 59196883097, -10454018992, -33364599371, 57280402355, -57873890484, 41879296232, -20241250112, 2065827049, 8435506655, -11611941072, 10182603298, -7040645261, 4071881378, -2013138357, 856757031, -313468474, 97893151, -25770006, 5617769, -990431, 136864, -14194, 1034, -47, 1])
|
|
1730
|
+
data['beta'] = Zu([0, 114688, -1114112, 4854784, -11205632, 7426048, 42663936, -182555136, 394092544, -508851472, 213245648, 743315936, -2203729384, 3409478688, -3280008936, 1139839970, 2576264698, -6272528962, 8005203155, -6671665088, 2744569094, 1996771588, -5520074039, 6637395180, -5455622885, 3028415830, -601645255, -1012737914, 1632999370, -1525982346, 1093778952, -644352392, 319489974, -134176208, 47566499, -14083902, 3424200, -667810, 101271, -11438, 901, -44, 1])
|
|
1731
|
+
#beta factors as (u - 4) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 2) * (u**2 - 2*u - 1) * (u**3 - 5*u**2 + 5*u - 7) * (u**3 - 4*u**2 + 3*u - 4) * (u**3 - 4*u**2 + 3*u - 1) * (u**3 - 3*u**2 + 2*u - 4) * (u**3 - 2*u**2 + 2*u - 2) * (u**3 + u + 1) * (u**4 - 4*u**3 - 2*u**2 - 4) * (u**5 - 5*u**4 + 5*u**3 - 11*u**2 + 6*u - 4) * (u**6 - 4*u**5 + 2*u**4 - 4*u**3 - u**2 + 4*u - 2)
|
|
1732
|
+
return data
|
|
1733
|
+
if l == 59:
|
|
1734
|
+
data['hyper_poly'] = Zu([-8, -4, 20, -24, -3, 40, -62, 40, 3, -28, 22, -8, 1])
|
|
1735
|
+
data['A2'] = Zu([590, -1475, -295, 4130, -4425, 1711])
|
|
1736
|
+
data['A4'] = Zuv(Zu([-2460, 8844, -3843, -20718, 57153, -50418, -12600, 72762, -69339, 30978, -5223]) + v*Zu([900, 360, -7560, 10800, -5220]))
|
|
1737
|
+
data['A6'] = Zuv(Zu([25760, -373560, 568020, 1147870, -4634370, 5318070, 1631996, -14270202, 21535998, -14119408, -2820102, 14275410, -13535292, 6790074, -1847898, 205378]) + v*Zu([-23688, 27972, 183708, -696024, 721980, 453600, -1925028, 2039184, -1027404, 205380]))
|
|
1738
|
+
data['alpha'] = Zu([16000, -67200, -783520, 5573376, -5127336, -60792184, 241324042, -170978932, -1262437160, 4310971231, -3953349811, -10887235780, 41679530185, -51342089572, -33068562195, 230682514316, -372641172307, 121615007703, 682044179678, -1549365239197, 1373184591667, 614906882627, -3566756201696, 4920423266916, -2342393877496, -3589340274442, 8772457933356, -8488557160148, 1742977715620, 7131088674129, -11643540780203, 8512399456274, -315658868113, -6917286294515, 8713332734648, -5190227733987, -54249978263, 3397583328372, -3658171840037, 1987950394792, -179519591637, -748989116551, 800595050760, -459184355769, 134398080099, 28871590941, -64236756338, 46651654354, -23352309386, 9059054346, -2830320860, 721829600, -150487052, 25475079, -3452149, 365800, -29205, 1652, -59, 1])
|
|
1739
|
+
data['beta'] = Zu([0, -56000, 320800, 391440, -7693120, 21125500, 11515130, -204780145, 486681785, -102547033, -2147060784, 5552726794, -4419031758, -9431888681, 33728080307, -42367773552, -2994127157, 105330637610, -188172973931, 127559513693, 123083802224, -421097252069, 490425751691, -161944881372, -408669953969, 799965143719, -668167261718, 69589638764, 563644022562, -787681290965, 505670881115, 2900924856, -364669742737, 407962360532, -223582547975, 9985786664, 102435489491, -105519055992, 58212400117, -14331637533, -6742538722, 10205452686, -6853903214, 3244679736, -1188153136, 347102566, -81626216, 15409226, -2307408, 268126, -23322, 1429, -55, 1])
|
|
1740
|
+
#beta factors as (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 4*u - 1) * (u**2 - 3*u - 5) * (u**2 - 3*u - 2) * (u**2 - 3*u + 1) * (u**2 - u - 1) * (u**3 - 6*u**2 + 10*u - 7) * (u**3 - 5*u**2 + 7*u - 5) * (u**3 - 3*u**2 + 2*u - 1) * (u**3 - u**2 + 1) * (u**4 - 5*u**3 + 4*u**2 - 1) * (u**4 - 4*u**3 + 3*u**2 + 2*u - 4) * (u**4 - 3*u**3 - u - 1) * (u**4 - u**3 + 2*u - 1) * (u**5 - 6*u**4 + 10*u**3 - 11*u**2 + 8*u - 4) * (u**6 - 5*u**5 + 5*u**4 - 5*u**2 + 5*u - 5)
|
|
1741
|
+
return data
|
|
1742
|
+
if l == 71:
|
|
1743
|
+
data['hyper_poly'] = Zu([-7, 6, -27, 40, -58, 66, -66, 40, 15, -48, 66, -66, 37, -10, 1])
|
|
1744
|
+
data['A2'] = Zu([213, -1420, 4260, -4970, 9940, -9088, 2485])
|
|
1745
|
+
data['A4'] = Zuv(Zu([2565, -10008, 18024, -26532, 23208, 7584, -104418, 189432, -251736, 275148, -182232, 60144, -7563]) + v*Zu([720, -4320, 7560, -20160, 23040, -7560]))
|
|
1746
|
+
data['A6'] = Zuv(Zu([-69930, 382536, -1898568, 5206124, -11813256, 23115792, -35705670, 44318064, -41531952, 20674360, 23881872, -77986944, 114989770, -124612152, 103122936, -59431204, 21485688, -4294416, 357910]) + v*Zu([18576, -53856, 57672, 161856, -961920, 3199176, -5706288, 8032896, -9352584, 6786720, -2505888, 357912]))
|
|
1747
|
+
data['alpha'] = Zu([-6750, 97200, -603855, 2263977, -4854483, -2486349, 75190491, -399596520, 1441975423, -4089818964, 9450153463, -17516526653, 23635982289, -11859874932, -53385529273, 230566737711, -585283867605, 1136695427037, -1753961304140, 2020891913264, -1147488305875, -1930304898882, 8102336330029, -17218530732347, 27006964902986, -32365758791872, 25902000374138, -468390635342, -46332664858222, 107139839089502, -162234735929274, 182582147217312, -140033523896938, 22513210292184, 152367877270246, -334009986053250, 451855980915164, -443144048889720, 284518400252142, -11142427766850, -289840331821002, 512373447321402, -576967281819172, 466024421705696, -230395084854230, -36287337331916, 241209603962570, -330646545417814, 304702155703516, -205131886553392, 87504290135653, 5131997859077, -54867900326127, 66216047255551, -54817285755105, 36239054778472, -20052219750661, 9464634765852, -3841191816845, 1343947848527, -405138280373, 104923131180, -23228729413, 4364552115, -689157169, 90223321, -9613968, 812240, -52327, 2414, -71, 1])
|
|
1748
|
+
data['beta'] = Zu([0, 12150, -163215, 1115640, -5311143, 18820224, -50700172, 99823812, -102454041, -183909134, 1354660714, -4462311942, 10695310224, -20015395554, 28262441676, -23240987282, -17879387475, 124501604946, -315187724212, 564766450688, -765154573538, 705985549104, -115433273216, -1206098873334, 3175185881748, -5228317292044, 6292310032120, -5077451367560, 719644756530, 6451571564682, -14460150103020, 19999710623352, -19681838601268, 11819712227412, 2180981559572, -17790742756618, 29025463386612, -31179247603548, 23207078145510, -8345354986332, -7468523752270, 18486966963350, -21719818051100, 17831212433536, -10100011266030, 2336962513536, 2906983627184, -4989755986066, 4711466210012, -3361479243242, 1952316811463, -948555371584, 389878900245, -136099552242, 40341734984, -10121407164, 2136756509, -376218102, 54551634, -6399080, 591884, -41538, 2078, -66, 1])
|
|
1749
|
+
#beta factors as (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 5) * (u**2 - 3*u + 1) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**3 - 5*u**2 + 5*u - 3) * (u**3 - 4*u**2 - 1) * (u**3 - 2*u**2 - 1) * (u**4 - 6*u**3 + 7*u**2 + 6*u - 9) * (u**4 - 5*u**3 + 4*u**2 + u + 3) * (u**4 - 5*u**3 + 6*u**2 - 3*u + 5) * (u**4 - 4*u**3 + u**2 - 4*u + 1) * (u**4 - 4*u**3 + 2*u**2 - u + 1) * (u**4 - 2*u**3 - 3*u**2 - 2*u - 1) * (u**4 - 2*u**3 + u - 1) * (u**6 - 5*u**5 + 8*u**4 - 7*u**3 + 6*u**2 - 3*u + 1) * (u**8 - 6*u**7 + 9*u**6 - 2*u**5 + 2*u**3 - 9*u**2 + 2*u - 1)
|
|
1750
|
+
return data
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
@cached_function
|
|
1754
|
+
def Psi2(l):
|
|
1755
|
+
"""
|
|
1756
|
+
Return the generic kernel polynomial for hyperelliptic `l`-isogenies.
|
|
1757
|
+
|
|
1758
|
+
INPUT:
|
|
1759
|
+
|
|
1760
|
+
- ``l`` -- either 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
|
|
1761
|
+
|
|
1762
|
+
OUTPUT: the generic `l`-kernel polynomial
|
|
1763
|
+
|
|
1764
|
+
EXAMPLES::
|
|
1765
|
+
|
|
1766
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2
|
|
1767
|
+
sage: Psi2(11)
|
|
1768
|
+
x^5 - 55*x^4*u + 994*x^3*u^2 - 8774*x^2*u^3 + 41453*x*u^4 - 928945/11*u^5
|
|
1769
|
+
+ 33*x^4 + 276*x^3*u - 7794*x^2*u^2 + 4452*x*u^3 + 1319331/11*u^4 + 216*x^3*v
|
|
1770
|
+
- 4536*x^2*u*v + 31752*x*u^2*v - 842616/11*u^3*v + 162*x^3 + 38718*x^2*u
|
|
1771
|
+
- 610578*x*u^2 + 33434694/11*u^3 - 4536*x^2*v + 73872*x*u*v - 2745576/11*u^2*v
|
|
1772
|
+
- 16470*x^2 + 580068*x*u - 67821354/11*u^2 - 185976*x*v + 14143896/11*u*v
|
|
1773
|
+
+ 7533*x - 20437029/11*u - 12389112/11*v + 19964151/11
|
|
1774
|
+
sage: p = Psi2(71) # long time
|
|
1775
|
+
sage: (x,u,v) = p.variables() # long time
|
|
1776
|
+
sage: p.coefficient({x: 0, u: 210, v: 0}) # long time
|
|
1777
|
+
-2209380711722505179506258739515288584116147237393815266468076436521/71
|
|
1778
|
+
sage: p.coefficient({x: 0, u: 0, v: 0}) # long time
|
|
1779
|
+
-14790739586438315394567393301990769678157425619440464678252277649/71
|
|
1780
|
+
|
|
1781
|
+
TESTS::
|
|
1782
|
+
|
|
1783
|
+
sage: Psi2(13)
|
|
1784
|
+
Traceback (most recent call last):
|
|
1785
|
+
...
|
|
1786
|
+
ValueError: 13 must be one of [11, 17, 19, 23, 29, 31, 41, 47, 59, 71].
|
|
1787
|
+
"""
|
|
1788
|
+
data = _hyperelliptic_isogeny_data(l)
|
|
1789
|
+
|
|
1790
|
+
R = PolynomialRing(QQ, 'u')
|
|
1791
|
+
L = PolynomialRing(R, 'v')
|
|
1792
|
+
v = L.gen()
|
|
1793
|
+
K = R.extension(v*v - R(data['hyper_poly']), 'v')
|
|
1794
|
+
v = K.gen()
|
|
1795
|
+
|
|
1796
|
+
from sage.categories.homset import Hom
|
|
1797
|
+
h = Hom(K,K)(-v)
|
|
1798
|
+
|
|
1799
|
+
A = K(data['A4'])
|
|
1800
|
+
B = K(data['A6'])
|
|
1801
|
+
Abar = h(A)*l**2
|
|
1802
|
+
Bbar = -h(B)*l**3
|
|
1803
|
+
s1 = K(data['A2'])
|
|
1804
|
+
|
|
1805
|
+
d = (l-1)//2
|
|
1806
|
+
s = [K(1)]
|
|
1807
|
+
t = [d, s1, ((1-10*d)*A - Abar) * QQ((1,30))]
|
|
1808
|
+
t.append(((1-28*d)*B - 42*t[1]*A - Bbar) * QQ((1,70)))
|
|
1809
|
+
c = [0, 6*t[2] + 2*A*t[0], 10*t[3] + 6*A*t[1] + 4*B*t[0]]
|
|
1810
|
+
for n in range(2,d):
|
|
1811
|
+
k = sum(c[i]*c[n-i] for i in range(1,n))
|
|
1812
|
+
c.append((3*k-(2*n-1)*(n-1)*A*c[n-1]-(2*n-2)*(n-2)*B*c[n-2]) * QQ((1,(2*n+5)*(n-1))))
|
|
1813
|
+
for n in range(3,d):
|
|
1814
|
+
t.append((c[n]-(4*n-2)*A*t[n-1]-(4*n-4)*B*t[n-2]) * QQ((1,4*n+2)))
|
|
1815
|
+
for n in range(1,d+1):
|
|
1816
|
+
s.append(QQ((-1,n)) * sum((-1)**i*t[i]*s[n-i] for i in range(1,n+1)))
|
|
1817
|
+
|
|
1818
|
+
R = PolynomialRing(QQ, ('x', 'u', 'v'))
|
|
1819
|
+
x = R.gen(0)
|
|
1820
|
+
return sum((-1)**i * x**(d-i) * R(s[i].lift()) for i in range(0,d+1))
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
def isogenies_prime_degree_genus_plus_0(E, l=None, minimal_models=True):
|
|
1824
|
+
"""
|
|
1825
|
+
Return list of ``l`` -isogenies with domain ``E``.
|
|
1826
|
+
|
|
1827
|
+
INPUT:
|
|
1828
|
+
|
|
1829
|
+
- ``E`` -- an elliptic curve
|
|
1830
|
+
|
|
1831
|
+
- ``l`` -- either ``None`` or 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
|
|
1832
|
+
|
|
1833
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
1834
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
1835
|
+
fields of larger degree it can be expensive to compute these so
|
|
1836
|
+
set to ``False``.
|
|
1837
|
+
|
|
1838
|
+
OUTPUT:
|
|
1839
|
+
|
|
1840
|
+
(list) When ``l`` is None a list of all isogenies of degree 11, 17, 19, 23,
|
|
1841
|
+
29, 31, 41, 47, 59, or 71, otherwise a list of isogenies of the given degree.
|
|
1842
|
+
|
|
1843
|
+
.. NOTE::
|
|
1844
|
+
|
|
1845
|
+
This function would normally be invoked indirectly via
|
|
1846
|
+
``E.isogenies_prime_degree(l)``, which automatically calls the appropriate function.
|
|
1847
|
+
|
|
1848
|
+
ALGORITHM:
|
|
1849
|
+
|
|
1850
|
+
See [KT2013]_, Chapter 5.
|
|
1851
|
+
|
|
1852
|
+
EXAMPLES::
|
|
1853
|
+
|
|
1854
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0
|
|
1855
|
+
|
|
1856
|
+
sage: E = EllipticCurve('121a1')
|
|
1857
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 11)
|
|
1858
|
+
[Isogeny of degree 11
|
|
1859
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76
|
|
1860
|
+
over Rational Field
|
|
1861
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888
|
|
1862
|
+
over Rational Field]
|
|
1863
|
+
|
|
1864
|
+
sage: E = EllipticCurve([1, 1, 0, -660, -7600])
|
|
1865
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 17)
|
|
1866
|
+
[Isogeny of degree 17
|
|
1867
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600
|
|
1868
|
+
over Rational Field
|
|
1869
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750
|
|
1870
|
+
over Rational Field]
|
|
1871
|
+
|
|
1872
|
+
sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
|
|
1873
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 19)
|
|
1874
|
+
[Isogeny of degree 19
|
|
1875
|
+
from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
|
|
1876
|
+
over Rational Field
|
|
1877
|
+
to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
|
|
1878
|
+
over Rational Field]
|
|
1879
|
+
|
|
1880
|
+
sage: # needs sage.rings.number_field
|
|
1881
|
+
sage: K = QuadraticField(-295,'a')
|
|
1882
|
+
sage: a = K.gen()
|
|
1883
|
+
sage: E = EllipticCurve_from_j(-484650135/16777216*a + 4549855725/16777216)
|
|
1884
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 23)
|
|
1885
|
+
[Isogeny of degree 23
|
|
1886
|
+
from Elliptic Curve defined by
|
|
1887
|
+
y^2 = x^3 + (-14460494784192904095/140737488355328*a+270742665778826768325/140737488355328)*x
|
|
1888
|
+
+ (37035998788154488846811217135/590295810358705651712*a-1447451882571839266752561148725/590295810358705651712)
|
|
1889
|
+
over Number Field in a with defining polynomial x^2 + 295
|
|
1890
|
+
with a = 17.17556403731767?*I
|
|
1891
|
+
to Elliptic Curve defined by
|
|
1892
|
+
y^2 = x^3 + (-5130542435555445498495/140737488355328*a+173233955029127361005925/140737488355328)*x
|
|
1893
|
+
+ (-1104699335561165691575396879260545/590295810358705651712*a+3169785826904210171629535101419675/590295810358705651712)
|
|
1894
|
+
over Number Field in a with defining polynomial x^2 + 295
|
|
1895
|
+
with a = 17.17556403731767?*I]
|
|
1896
|
+
|
|
1897
|
+
sage: # needs sage.rings.number_field
|
|
1898
|
+
sage: K = QuadraticField(-199,'a')
|
|
1899
|
+
sage: a = K.gen()
|
|
1900
|
+
sage: E = EllipticCurve_from_j(94743000*a + 269989875)
|
|
1901
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 29)
|
|
1902
|
+
[Isogeny of degree 29
|
|
1903
|
+
from Elliptic Curve defined by
|
|
1904
|
+
y^2 = x^3 + (-153477413215038000*a+5140130723072965125)*x
|
|
1905
|
+
+ (297036215130547008455526000*a+2854277047164317800973582250)
|
|
1906
|
+
over Number Field in a with defining polynomial x^2 + 199
|
|
1907
|
+
with a = 14.106735979665884?*I
|
|
1908
|
+
to Elliptic Curve defined by
|
|
1909
|
+
y^2 = x^3 + (251336161378040805000*a-3071093219933084341875)*x
|
|
1910
|
+
+ (-8411064283162168580187643221000*a+34804337770798389546017184785250)
|
|
1911
|
+
over Number Field in a with defining polynomial x^2 + 199
|
|
1912
|
+
with a = 14.106735979665884?*I]
|
|
1913
|
+
|
|
1914
|
+
sage: # needs sage.rings.number_field
|
|
1915
|
+
sage: K = QuadraticField(253,'a')
|
|
1916
|
+
sage: a = K.gen()
|
|
1917
|
+
sage: E = EllipticCurve_from_j(208438034112000*a - 3315409892960000)
|
|
1918
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 31)
|
|
1919
|
+
[Isogeny of degree 31
|
|
1920
|
+
from Elliptic Curve defined by
|
|
1921
|
+
y^2 = x^3 + (4146345122185433034677956608000*a-65951656549965037259634800640000)*x
|
|
1922
|
+
+ (-18329111516954473474583425393698245080252416000*a+291542366110383928366510368064204147260129280000)
|
|
1923
|
+
over Number Field in a with defining polynomial x^2 - 253
|
|
1924
|
+
with a = 15.905973720586867?
|
|
1925
|
+
to Elliptic Curve defined by
|
|
1926
|
+
y^2 = x^3 + (200339763852548615776123686912000*a-3186599019027216904280948275200000)*x
|
|
1927
|
+
+ (7443671791411479629112717260182286294850207744000*a-118398847898864757209685951728838895495168655360000)
|
|
1928
|
+
over Number Field in a with defining polynomial x^2 - 253
|
|
1929
|
+
with a = 15.905973720586867?]
|
|
1930
|
+
|
|
1931
|
+
sage: E = EllipticCurve_from_j(GF(5)(1))
|
|
1932
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 41)
|
|
1933
|
+
[Isogeny of degree 41
|
|
1934
|
+
from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5
|
|
1935
|
+
to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5,
|
|
1936
|
+
Isogeny of degree 41
|
|
1937
|
+
from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5
|
|
1938
|
+
to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5]
|
|
1939
|
+
|
|
1940
|
+
sage: # needs sage.rings.number_field
|
|
1941
|
+
sage: K = QuadraticField(5,'a')
|
|
1942
|
+
sage: a = K.gen()
|
|
1943
|
+
sage: E = EllipticCurve_from_j(184068066743177379840*a
|
|
1944
|
+
....: - 411588709724712960000)
|
|
1945
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 47) # long time
|
|
1946
|
+
[Isogeny of degree 47
|
|
1947
|
+
from Elliptic Curve defined by
|
|
1948
|
+
y^2 = x^3 + (454562028554080355857852049849975895490560*a-1016431595837124114668689286176511361024000)*x
|
|
1949
|
+
+ (-249456798429896080881440540950393713303830363999480904280965120*a+557802358738710443451273320227578156598454035482869042774016000)
|
|
1950
|
+
over Number Field in a with defining polynomial x^2 - 5
|
|
1951
|
+
with a = 2.236067977499790?
|
|
1952
|
+
to Elliptic Curve defined by
|
|
1953
|
+
y^2 = x^3 + (39533118442361013730577638493616965245992960*a-88398740199669828340617478832005245173760000)*x
|
|
1954
|
+
+ (214030321479466610282320528611562368963830105830555363061803253760*a-478586348074220699687616322532666163722004497458452316582576128000)
|
|
1955
|
+
over Number Field in a with defining polynomial x^2 - 5
|
|
1956
|
+
with a = 2.236067977499790?]
|
|
1957
|
+
|
|
1958
|
+
sage: K = QuadraticField(-66827,'a') # needs sage.rings.number_field
|
|
1959
|
+
sage: a = K.gen() # needs sage.rings.number_field
|
|
1960
|
+
sage: E = EllipticCurve_from_j(-98669236224000*a + 4401720074240000) # needs sage.rings.number_field
|
|
1961
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 59) # long time (5s)
|
|
1962
|
+
[Isogeny of degree 59
|
|
1963
|
+
from Elliptic Curve defined by
|
|
1964
|
+
y^2 = x^3 + (2605886146782144762297974784000*a+1893681048912773634944634716160000)*x
|
|
1965
|
+
+ (-116918454256410782232296183198067568744071168000*a+17012043538294664027185882358514011304812871680000)
|
|
1966
|
+
over Number Field in a with defining polynomial x^2 + 66827
|
|
1967
|
+
with a = 258.5091874576221?*I
|
|
1968
|
+
to Elliptic Curve defined by
|
|
1969
|
+
y^2 = x^3 + (-19387084027159786821400775098368000*a-4882059104868154225052787156713472000)*x
|
|
1970
|
+
+ (-25659862010101415428713331477227179429538847260672000*a-2596038148441293485938798119003462972840818381946880000)
|
|
1971
|
+
over Number Field in a with defining polynomial x^2 + 66827
|
|
1972
|
+
with a = 258.5091874576221?*I]
|
|
1973
|
+
|
|
1974
|
+
sage: E = EllipticCurve_from_j(GF(13)(5))
|
|
1975
|
+
sage: isogenies_prime_degree_genus_plus_0(E, 71)
|
|
1976
|
+
[Isogeny of degree 71
|
|
1977
|
+
from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13
|
|
1978
|
+
to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13,
|
|
1979
|
+
Isogeny of degree 71
|
|
1980
|
+
from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13
|
|
1981
|
+
to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13]
|
|
1982
|
+
|
|
1983
|
+
sage: E = EllipticCurve(GF(13), [0,1,1,1,0])
|
|
1984
|
+
sage: isogenies_prime_degree_genus_plus_0(E)
|
|
1985
|
+
[Isogeny of degree 17
|
|
1986
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
|
|
1987
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 1 over Finite Field of size 13,
|
|
1988
|
+
Isogeny of degree 17
|
|
1989
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
|
|
1990
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13,
|
|
1991
|
+
Isogeny of degree 29
|
|
1992
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
|
|
1993
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 6 over Finite Field of size 13,
|
|
1994
|
+
Isogeny of degree 29
|
|
1995
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
|
|
1996
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13,
|
|
1997
|
+
Isogeny of degree 41
|
|
1998
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
|
|
1999
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13,
|
|
2000
|
+
Isogeny of degree 41
|
|
2001
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13
|
|
2002
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13]
|
|
2003
|
+
"""
|
|
2004
|
+
if l is None:
|
|
2005
|
+
return sum([isogenies_prime_degree_genus_plus_0(E, ell, minimal_models=minimal_models)
|
|
2006
|
+
for ell in hyperelliptic_primes],[])
|
|
2007
|
+
|
|
2008
|
+
if l not in hyperelliptic_primes:
|
|
2009
|
+
raise ValueError("%s must be one of %s." % (l, hyperelliptic_primes))
|
|
2010
|
+
|
|
2011
|
+
F = E.base_ring()
|
|
2012
|
+
j = E.j_invariant()
|
|
2013
|
+
if F.characteristic() in [2, 3, l]:
|
|
2014
|
+
raise NotImplementedError("11, 17, 19, 23, 29, 31, 41, 47, 59, and 71-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.")
|
|
2015
|
+
|
|
2016
|
+
if j == F(0):
|
|
2017
|
+
return isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=minimal_models)
|
|
2018
|
+
if j == F(1728):
|
|
2019
|
+
return isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=minimal_models)
|
|
2020
|
+
|
|
2021
|
+
Fu = PolynomialRing(F,'u')
|
|
2022
|
+
u = Fu.gen()
|
|
2023
|
+
Fuv = PolynomialRing(F,['u','v'])
|
|
2024
|
+
Fxuv = PolynomialRing(F,['x','u','v'])
|
|
2025
|
+
X = u
|
|
2026
|
+
data = _hyperelliptic_isogeny_data(l)
|
|
2027
|
+
a = Fu(data['alpha'])
|
|
2028
|
+
b = Fu(data['beta'])
|
|
2029
|
+
f = Fu(data['hyper_poly'])
|
|
2030
|
+
P = a
|
|
2031
|
+
Q = Fu((a**2 - f*b**2)/Fu(4))
|
|
2032
|
+
u_list = (j**2-P*j+Q).roots(multiplicities=False)
|
|
2033
|
+
|
|
2034
|
+
S = []
|
|
2035
|
+
for u0 in u_list:
|
|
2036
|
+
if b(u0) == 0:
|
|
2037
|
+
S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
|
|
2038
|
+
else:
|
|
2039
|
+
S += [[u0,(2*j-a(u0))/b(u0)]]
|
|
2040
|
+
if not S:
|
|
2041
|
+
return []
|
|
2042
|
+
S.sort()
|
|
2043
|
+
|
|
2044
|
+
c4, c6 = E.c_invariants()
|
|
2045
|
+
b2 = E.b2()
|
|
2046
|
+
kernels = []
|
|
2047
|
+
|
|
2048
|
+
psi = Fxuv(Psi2(l))
|
|
2049
|
+
for u0, v0 in S:
|
|
2050
|
+
A4 = Fuv(data['A4'])(u0,v0) # nonzero since j!=0
|
|
2051
|
+
A6 = Fuv(data['A6'])(u0,v0) # nonzero since j!=1728
|
|
2052
|
+
T = (c4*A6)/(2*c6*A4)
|
|
2053
|
+
kernels += [psi((36*X+3*b2)*T,u0,v0).monic()]
|
|
2054
|
+
return [E.isogeny(ker) for ker in kernels]
|
|
2055
|
+
|
|
2056
|
+
|
|
2057
|
+
def isogenies_prime_degree_genus_plus_0_j0(E, l, minimal_models=True):
|
|
2058
|
+
"""
|
|
2059
|
+
Return a list of hyperelliptic ``l`` -isogenies with domain ``E`` when `j(E)=0`.
|
|
2060
|
+
|
|
2061
|
+
INPUT:
|
|
2062
|
+
|
|
2063
|
+
- ``E`` -- an elliptic curve with j-invariant 0
|
|
2064
|
+
|
|
2065
|
+
- ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
|
|
2066
|
+
|
|
2067
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
2068
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
2069
|
+
fields of larger degree it can be expensive to compute these so
|
|
2070
|
+
set to ``False``.
|
|
2071
|
+
|
|
2072
|
+
OUTPUT:
|
|
2073
|
+
|
|
2074
|
+
(list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
|
|
2075
|
+
|
|
2076
|
+
.. NOTE::
|
|
2077
|
+
|
|
2078
|
+
This implementation requires that the characteristic is not 2, 3 or ``l``.
|
|
2079
|
+
|
|
2080
|
+
.. NOTE::
|
|
2081
|
+
|
|
2082
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
|
|
2083
|
+
|
|
2084
|
+
EXAMPLES::
|
|
2085
|
+
|
|
2086
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j0
|
|
2087
|
+
|
|
2088
|
+
sage: u = polygen(QQ)
|
|
2089
|
+
sage: K.<a> = NumberField(u^4 + 228*u^3 + 486*u^2 - 540*u + 225) # needs sage.rings.number_field
|
|
2090
|
+
sage: E = EllipticCurve(K, [0, -121/5*a^3 - 20691/5*a^2 - 29403/5*a + 3267]) # needs sage.rings.number_field
|
|
2091
|
+
sage: isogenies_prime_degree_genus_plus_0_j0(E, 11) # needs sage.rings.number_field
|
|
2092
|
+
[Isogeny of degree 11
|
|
2093
|
+
from Elliptic Curve defined by
|
|
2094
|
+
y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over
|
|
2095
|
+
Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225
|
|
2096
|
+
to Elliptic Curve defined by
|
|
2097
|
+
y^2 = x^3 + (-44286*a^2+178596*a-32670)*x
|
|
2098
|
+
+ (-17863351/5*a^3+125072739/5*a^2-74353653/5*a-682803) over
|
|
2099
|
+
Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225,
|
|
2100
|
+
Isogeny of degree 11
|
|
2101
|
+
from Elliptic Curve defined by
|
|
2102
|
+
y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over
|
|
2103
|
+
Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225
|
|
2104
|
+
to Elliptic Curve defined by
|
|
2105
|
+
y^2 = x^3 + (-3267*a^3-740157*a^2+600039*a-277695)*x
|
|
2106
|
+
+ (-17863351/5*a^3-4171554981/5*a^2+3769467867/5*a-272366523) over
|
|
2107
|
+
Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225]
|
|
2108
|
+
|
|
2109
|
+
sage: E = EllipticCurve(GF(5^6,'a'),[0,1])
|
|
2110
|
+
sage: isogenies_prime_degree_genus_plus_0_j0(E,17)
|
|
2111
|
+
[Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6]
|
|
2112
|
+
"""
|
|
2113
|
+
if l not in hyperelliptic_primes:
|
|
2114
|
+
raise ValueError("%s must be one of %s." % (l,hyperelliptic_primes))
|
|
2115
|
+
F = E.base_field()
|
|
2116
|
+
if E.j_invariant() != 0:
|
|
2117
|
+
raise ValueError("j-invariant must be 0.")
|
|
2118
|
+
if F.characteristic() in [2,3,l]:
|
|
2119
|
+
raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
|
|
2120
|
+
|
|
2121
|
+
Fu = PolynomialRing(F,'u')
|
|
2122
|
+
u = Fu.gen()
|
|
2123
|
+
Fuv = PolynomialRing(F,['u','v'])
|
|
2124
|
+
Fxuv = PolynomialRing(F,['x','u','v'])
|
|
2125
|
+
X = u
|
|
2126
|
+
data = _hyperelliptic_isogeny_data(l)
|
|
2127
|
+
a = Fu(data['alpha'])
|
|
2128
|
+
b = Fu(data['beta'])
|
|
2129
|
+
f = Fu(data['hyper_poly'])
|
|
2130
|
+
Q = Fu((a**2 - f*b**2)/Fu(4))
|
|
2131
|
+
u_list = Q.roots(multiplicities=False)
|
|
2132
|
+
c6, b2 = E.c6(), E.b2()
|
|
2133
|
+
kernels = []
|
|
2134
|
+
|
|
2135
|
+
if l % 3 == 1 and F(-3).is_square():
|
|
2136
|
+
p = F(-3).sqrt()
|
|
2137
|
+
endo = Fxuv(data['endo'])
|
|
2138
|
+
kernels += [endo(36*X+3*b2,p,-54*c6).monic(), endo(36*X+3*b2,-p,-54*c6).monic()]
|
|
2139
|
+
|
|
2140
|
+
S = []
|
|
2141
|
+
for u0 in u_list:
|
|
2142
|
+
if l % 3 == 1 and u0 == F(data['endo_u']):
|
|
2143
|
+
continue
|
|
2144
|
+
if b(u0) == 0:
|
|
2145
|
+
S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
|
|
2146
|
+
else:
|
|
2147
|
+
S += [[u0,-a(u0)/b(u0)]]
|
|
2148
|
+
if not S and not kernels:
|
|
2149
|
+
return []
|
|
2150
|
+
S.sort()
|
|
2151
|
+
|
|
2152
|
+
psi = Fxuv(Psi2(l))
|
|
2153
|
+
for u0,v0 in S:
|
|
2154
|
+
A6 = Fuv(data['A6'])(u0,v0) # nonzero since j!=1728
|
|
2155
|
+
kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**3-A6/(-54*c6)).roots(multiplicities=False)]
|
|
2156
|
+
return [E.isogeny(ker) for ker in kernels]
|
|
2157
|
+
|
|
2158
|
+
|
|
2159
|
+
def isogenies_prime_degree_genus_plus_0_j1728(E, l, minimal_models=True):
|
|
2160
|
+
"""
|
|
2161
|
+
Return a list of ``l`` -isogenies with domain ``E`` when `j(E)=1728`.
|
|
2162
|
+
|
|
2163
|
+
INPUT:
|
|
2164
|
+
|
|
2165
|
+
- ``E`` -- an elliptic curve with j-invariant 1728
|
|
2166
|
+
|
|
2167
|
+
- ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71
|
|
2168
|
+
|
|
2169
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
2170
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
2171
|
+
fields of larger degree it can be expensive to compute these so
|
|
2172
|
+
set to ``False``.
|
|
2173
|
+
|
|
2174
|
+
OUTPUT:
|
|
2175
|
+
|
|
2176
|
+
(list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
|
|
2177
|
+
|
|
2178
|
+
.. NOTE::
|
|
2179
|
+
|
|
2180
|
+
This implementation requires that the characteristic is not 2, 3 or ``l``.
|
|
2181
|
+
|
|
2182
|
+
.. NOTE::
|
|
2183
|
+
|
|
2184
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
|
|
2185
|
+
|
|
2186
|
+
EXAMPLES::
|
|
2187
|
+
|
|
2188
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j1728
|
|
2189
|
+
|
|
2190
|
+
sage: # needs sage.rings.number_field
|
|
2191
|
+
sage: u = polygen(QQ)
|
|
2192
|
+
sage: K.<a> = NumberField(u^6 - 522*u^5 - 10017*u^4
|
|
2193
|
+
....: + 2484*u^3 - 5265*u^2 + 12150*u - 5103)
|
|
2194
|
+
sage: E = EllipticCurve(K, [-75295/1335852*a^5 + 13066735/445284*a^4
|
|
2195
|
+
....: + 44903485/74214*a^3 + 17086861/24738*a^2
|
|
2196
|
+
....: + 11373021/16492*a - 1246245/2356, 0])
|
|
2197
|
+
sage: isogenies_prime_degree_genus_plus_0_j1728(E, 11)
|
|
2198
|
+
[Isogeny of degree 11
|
|
2199
|
+
from Elliptic Curve defined by
|
|
2200
|
+
y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x
|
|
2201
|
+
over Number Field in a with defining polynomial
|
|
2202
|
+
x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103
|
|
2203
|
+
to Elliptic Curve defined by
|
|
2204
|
+
y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x
|
|
2205
|
+
+ (-3540460*a^3+30522492*a^2-7043652*a-5031180)
|
|
2206
|
+
over Number Field in a with defining polynomial
|
|
2207
|
+
x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103,
|
|
2208
|
+
Isogeny of degree 11
|
|
2209
|
+
from Elliptic Curve defined by
|
|
2210
|
+
y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x
|
|
2211
|
+
over Number Field in a with defining polynomial
|
|
2212
|
+
x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103
|
|
2213
|
+
to Elliptic Curve defined by
|
|
2214
|
+
y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x
|
|
2215
|
+
+ (3540460*a^3-30522492*a^2+7043652*a+5031180)
|
|
2216
|
+
over Number Field in a with defining polynomial
|
|
2217
|
+
x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103]
|
|
2218
|
+
sage: i = QuadraticField(-1,'i').gen()
|
|
2219
|
+
sage: E = EllipticCurve([-1 - 2*i, 0])
|
|
2220
|
+
sage: isogenies_prime_degree_genus_plus_0_j1728(E, 17)
|
|
2221
|
+
[Isogeny of degree 17
|
|
2222
|
+
from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x
|
|
2223
|
+
over Number Field in i with defining polynomial x^2 + 1 with i = 1*I
|
|
2224
|
+
to Elliptic Curve defined by y^2 = x^3 + (-82*i-641)*x
|
|
2225
|
+
over Number Field in i with defining polynomial x^2 + 1 with i = 1*I,
|
|
2226
|
+
Isogeny of degree 17
|
|
2227
|
+
from Elliptic Curve defined by y^2 = x^3 + (-2*i-1)*x
|
|
2228
|
+
over Number Field in i with defining polynomial x^2 + 1 with i = 1*I
|
|
2229
|
+
to Elliptic Curve defined by y^2 = x^3 + (-562*i+319)*x
|
|
2230
|
+
over Number Field in i with defining polynomial x^2 + 1 with i = 1*I]
|
|
2231
|
+
sage: Emin = E.global_minimal_model()
|
|
2232
|
+
sage: [(p, len(isogenies_prime_degree_genus_plus_0_j1728(Emin, p)))
|
|
2233
|
+
....: for p in [17, 29, 41]]
|
|
2234
|
+
[(17, 2), (29, 2), (41, 2)]
|
|
2235
|
+
"""
|
|
2236
|
+
if l not in hyperelliptic_primes:
|
|
2237
|
+
raise ValueError("%s must be one of %s." % (l,hyperelliptic_primes))
|
|
2238
|
+
F = E.base_ring()
|
|
2239
|
+
if E.j_invariant() != 1728:
|
|
2240
|
+
raise ValueError("j-invariant must be 1728.")
|
|
2241
|
+
if F.characteristic() in [2,3,l]:
|
|
2242
|
+
raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
|
|
2243
|
+
|
|
2244
|
+
Fu = PolynomialRing(F,'u')
|
|
2245
|
+
u = Fu.gen()
|
|
2246
|
+
Fuv = PolynomialRing(F,['u','v'])
|
|
2247
|
+
Fxuv = PolynomialRing(F,['x','u','v'])
|
|
2248
|
+
X = u
|
|
2249
|
+
data = _hyperelliptic_isogeny_data(l)
|
|
2250
|
+
a = Fu(data['alpha'])
|
|
2251
|
+
b = Fu(data['beta'])
|
|
2252
|
+
f = Fu(data['hyper_poly'])
|
|
2253
|
+
P = a
|
|
2254
|
+
Q = Fu((a**2 - f*b**2)/Fu(4))
|
|
2255
|
+
u_list = (1728**2-P*1728+Q).roots(multiplicities=False)
|
|
2256
|
+
c4, b2 = E.c4(), E.b2()
|
|
2257
|
+
kernels = []
|
|
2258
|
+
|
|
2259
|
+
if l % 4 == 1 and F(-1).is_square():
|
|
2260
|
+
i = F(-1).sqrt()
|
|
2261
|
+
endo = Fxuv(data['endo'])
|
|
2262
|
+
kernels += [endo(36*X+3*b2,i,-27*c4).monic(), endo(36*X+3*b2,-i,-27*c4).monic()]
|
|
2263
|
+
|
|
2264
|
+
S = []
|
|
2265
|
+
for u0 in u_list:
|
|
2266
|
+
if l % 4 == 1 and u0 == F(data['endo_u']):
|
|
2267
|
+
continue
|
|
2268
|
+
if b(u0) == 0:
|
|
2269
|
+
S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
|
|
2270
|
+
else:
|
|
2271
|
+
S += [[u0,(2*1728-a(u0))/b(u0)]]
|
|
2272
|
+
if not S and not kernels:
|
|
2273
|
+
return []
|
|
2274
|
+
S.sort()
|
|
2275
|
+
|
|
2276
|
+
psi = Fxuv(Psi2(l))
|
|
2277
|
+
for u0,v0 in S:
|
|
2278
|
+
A4 = Fuv(data['A4'])(u0,v0) # nonzero since j!=0
|
|
2279
|
+
kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**2-A4/(-27*c4)).roots(multiplicities=False)]
|
|
2280
|
+
return [E.isogeny(ker) for ker in kernels]
|
|
2281
|
+
|
|
2282
|
+
|
|
2283
|
+
@cached_function
|
|
2284
|
+
def _least_semi_primitive(p):
|
|
2285
|
+
r"""
|
|
2286
|
+
Return the smallest semi-primitive root modulo `p`, i.e., generator of the group `(\ZZ/p\ZZ)^*/\{1,-1\}`.
|
|
2287
|
+
|
|
2288
|
+
INPUT:
|
|
2289
|
+
|
|
2290
|
+
- ``p`` -- an odd prime power
|
|
2291
|
+
|
|
2292
|
+
OUTPUT: the smallest semi-primitive root modulo `p`
|
|
2293
|
+
|
|
2294
|
+
.. NOTE::
|
|
2295
|
+
|
|
2296
|
+
This function would normally be invoked indirectly via ``E.isogenies_prime_degree_general(l)``.
|
|
2297
|
+
|
|
2298
|
+
EXAMPLES::
|
|
2299
|
+
|
|
2300
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _least_semi_primitive
|
|
2301
|
+
sage: _least_semi_primitive(5)
|
|
2302
|
+
2
|
|
2303
|
+
sage: _least_semi_primitive(13)
|
|
2304
|
+
2
|
|
2305
|
+
sage: _least_semi_primitive(17)
|
|
2306
|
+
3
|
|
2307
|
+
sage: _least_semi_primitive(73)
|
|
2308
|
+
5
|
|
2309
|
+
sage: _least_semi_primitive(997)
|
|
2310
|
+
7
|
|
2311
|
+
"""
|
|
2312
|
+
if p % 2 == 0 or not p.is_prime_power():
|
|
2313
|
+
raise ValueError("{} is not an odd prime power".format(p))
|
|
2314
|
+
|
|
2315
|
+
from sage.arith.misc import euler_phi
|
|
2316
|
+
from sage.rings.finite_rings.integer_mod_ring import Integers
|
|
2317
|
+
phip = euler_phi(p)
|
|
2318
|
+
ord = phip if p % 4 == 1 else phip // 2
|
|
2319
|
+
R = Integers(p)
|
|
2320
|
+
return next((a for a in range(2, p) if p.gcd(a) == 1
|
|
2321
|
+
and R(a).multiplicative_order() >= ord), 0)
|
|
2322
|
+
|
|
2323
|
+
|
|
2324
|
+
def is_kernel_polynomial(E, m, f):
|
|
2325
|
+
r"""
|
|
2326
|
+
Test whether ``E`` has a cyclic isogeny of degree ``m`` with kernel
|
|
2327
|
+
polynomial ``f``.
|
|
2328
|
+
|
|
2329
|
+
INPUT:
|
|
2330
|
+
|
|
2331
|
+
- ``E`` -- an elliptic curve
|
|
2332
|
+
|
|
2333
|
+
- ``m`` -- positive integer
|
|
2334
|
+
|
|
2335
|
+
- ``f`` -- a polynomial over the base field of ``E``
|
|
2336
|
+
|
|
2337
|
+
OUTPUT:
|
|
2338
|
+
|
|
2339
|
+
boolean; ``True`` if ``E`` has a cyclic isogeny of degree ``m`` with
|
|
2340
|
+
kernel polynomial ``f``, else ``False``.
|
|
2341
|
+
|
|
2342
|
+
ALGORITHM:
|
|
2343
|
+
|
|
2344
|
+
`f` must have degree `(m-1)/2` (if `m` is odd) or degree `m/2` (if
|
|
2345
|
+
`m` is even), and have the property that for each root `x` of `f`,
|
|
2346
|
+
`\mu(x)` is also a root where `\mu` is the multiplication-by-`m`
|
|
2347
|
+
map on `E` and `m` runs over a set of generators of
|
|
2348
|
+
`(\ZZ/m\ZZ)^*/\{1,-1\}`.
|
|
2349
|
+
|
|
2350
|
+
EXAMPLES::
|
|
2351
|
+
|
|
2352
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import is_kernel_polynomial
|
|
2353
|
+
sage: E = EllipticCurve([0, -1, 1, -10, -20])
|
|
2354
|
+
sage: x = polygen(QQ)
|
|
2355
|
+
sage: is_kernel_polynomial(E, 5, x^2 + x - 29/5)
|
|
2356
|
+
True
|
|
2357
|
+
sage: is_kernel_polynomial(E, 5, (x - 16) * (x - 5))
|
|
2358
|
+
True
|
|
2359
|
+
|
|
2360
|
+
An example from [KT2013]_, where the 13-division polynomial splits
|
|
2361
|
+
into 14 factors each of degree 6, but only two of these is a
|
|
2362
|
+
kernel polynomial for a 13-isogeny::
|
|
2363
|
+
|
|
2364
|
+
sage: F = GF(3)
|
|
2365
|
+
sage: E = EllipticCurve(F, [0,0,0,-1,0])
|
|
2366
|
+
sage: f13 = E.division_polynomial(13)
|
|
2367
|
+
sage: factors = [f for f, e in f13.factor()]
|
|
2368
|
+
sage: all(f.degree() == 6 for f in factors)
|
|
2369
|
+
True
|
|
2370
|
+
sage: [is_kernel_polynomial(E, 13, f) for f in factors]
|
|
2371
|
+
[True,
|
|
2372
|
+
True,
|
|
2373
|
+
False,
|
|
2374
|
+
False,
|
|
2375
|
+
False,
|
|
2376
|
+
False,
|
|
2377
|
+
False,
|
|
2378
|
+
False,
|
|
2379
|
+
False,
|
|
2380
|
+
False,
|
|
2381
|
+
False,
|
|
2382
|
+
False,
|
|
2383
|
+
False,
|
|
2384
|
+
False]
|
|
2385
|
+
|
|
2386
|
+
See :issue:`22232`::
|
|
2387
|
+
|
|
2388
|
+
sage: # needs sage.rings.finite_rings
|
|
2389
|
+
sage: K = GF(47^2)
|
|
2390
|
+
sage: E = EllipticCurve([0, K.gen()])
|
|
2391
|
+
sage: psi7 = E.division_polynomial(7)
|
|
2392
|
+
sage: f = psi7.factor()[4][0]
|
|
2393
|
+
sage: f
|
|
2394
|
+
x^3 + (7*z2 + 11)*x^2 + (25*z2 + 33)*x + 25*z2
|
|
2395
|
+
sage: f.divides(psi7)
|
|
2396
|
+
True
|
|
2397
|
+
sage: is_kernel_polynomial(E, 7, f)
|
|
2398
|
+
False
|
|
2399
|
+
"""
|
|
2400
|
+
m2 = m // 2
|
|
2401
|
+
if f.degree() != m2:
|
|
2402
|
+
return False
|
|
2403
|
+
if m == 1:
|
|
2404
|
+
return True
|
|
2405
|
+
|
|
2406
|
+
# Compute the quotient polynomial ring mod (f)
|
|
2407
|
+
S = f.parent().quotient_ring(f)
|
|
2408
|
+
|
|
2409
|
+
# test if the m-division polynomial is a multiple of f by computing it in the quotient:
|
|
2410
|
+
if E.division_polynomial(m, x=S.gen()) != 0:
|
|
2411
|
+
return False
|
|
2412
|
+
|
|
2413
|
+
if m == 2 or m == 3:
|
|
2414
|
+
return True
|
|
2415
|
+
|
|
2416
|
+
# For each a in a set of generators of (Z/mZ)^*/{1,-1} we check
|
|
2417
|
+
# that the multiplication-by-a map permutes the roots of f.
|
|
2418
|
+
# If m is prime (or more generally, has a primitive root) then
|
|
2419
|
+
# only one a will be needed.
|
|
2420
|
+
|
|
2421
|
+
if m & 1 and m.is_prime_power():
|
|
2422
|
+
gens = _least_semi_primitive(m),
|
|
2423
|
+
else:
|
|
2424
|
+
from sage.rings.finite_rings.integer_mod_ring import Integers
|
|
2425
|
+
gens = Integers(m).unit_gens()
|
|
2426
|
+
|
|
2427
|
+
for a in gens:
|
|
2428
|
+
mu = E.multiplication_by_m(a, x_only=True)
|
|
2429
|
+
if f( S(mu.numerator()) / S(mu.denominator()) ) != 0:
|
|
2430
|
+
return False
|
|
2431
|
+
return True
|
|
2432
|
+
|
|
2433
|
+
|
|
2434
|
+
def isogenies_prime_degree_general(E, l, minimal_models=True):
|
|
2435
|
+
"""
|
|
2436
|
+
Return all separable ``l``-isogenies with domain ``E``.
|
|
2437
|
+
|
|
2438
|
+
INPUT:
|
|
2439
|
+
|
|
2440
|
+
- ``E`` -- an elliptic curve
|
|
2441
|
+
|
|
2442
|
+
- ``l`` -- a prime
|
|
2443
|
+
|
|
2444
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
2445
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
2446
|
+
fields of larger degree it can be expensive to compute these so
|
|
2447
|
+
set to ``False``.
|
|
2448
|
+
|
|
2449
|
+
OUTPUT:
|
|
2450
|
+
|
|
2451
|
+
A list of all separable isogenies of degree `l` with domain ``E``
|
|
2452
|
+
(up to post-isomorphism).
|
|
2453
|
+
|
|
2454
|
+
ALGORITHM:
|
|
2455
|
+
|
|
2456
|
+
This algorithm factors the ``l``-division polynomial, then
|
|
2457
|
+
combines its factors to obtain kernels.
|
|
2458
|
+
Originally this was done using [KT2013]_, Chapter 3, but nowadays
|
|
2459
|
+
the recombination step is instead delegated to
|
|
2460
|
+
:meth:`~sage.schemes.elliptic_curves.ell_field.EllipticCurve_field.kernel_polynomial_from_divisor`.
|
|
2461
|
+
|
|
2462
|
+
.. NOTE::
|
|
2463
|
+
|
|
2464
|
+
This function works for any prime `l`. Normally one should use
|
|
2465
|
+
the function :meth:`isogenies_prime_degree` which uses special
|
|
2466
|
+
functions for certain small primes.
|
|
2467
|
+
|
|
2468
|
+
EXAMPLES::
|
|
2469
|
+
|
|
2470
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
|
|
2471
|
+
sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) # needs sage.rings.finite_rings
|
|
2472
|
+
sage: isogenies_prime_degree_general(E, 7) # needs sage.rings.finite_rings
|
|
2473
|
+
[Isogeny of degree 7
|
|
2474
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + 1
|
|
2475
|
+
over Finite Field in a of size 2^6
|
|
2476
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x
|
|
2477
|
+
over Finite Field in a of size 2^6]
|
|
2478
|
+
sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) # needs sage.rings.finite_rings
|
|
2479
|
+
sage: isogenies_prime_degree_general(E, 17) # needs sage.rings.finite_rings
|
|
2480
|
+
[Isogeny of degree 17
|
|
2481
|
+
from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
|
|
2482
|
+
over Finite Field in a of size 3^12
|
|
2483
|
+
to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2
|
|
2484
|
+
over Finite Field in a of size 3^12,
|
|
2485
|
+
Isogeny of degree 17
|
|
2486
|
+
from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
|
|
2487
|
+
over Finite Field in a of size 3^12
|
|
2488
|
+
to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x
|
|
2489
|
+
over Finite Field in a of size 3^12]
|
|
2490
|
+
sage: E = EllipticCurve('50a1')
|
|
2491
|
+
sage: isogenies_prime_degree_general(E, 3)
|
|
2492
|
+
[Isogeny of degree 3
|
|
2493
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
|
|
2494
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552
|
|
2495
|
+
over Rational Field]
|
|
2496
|
+
sage: isogenies_prime_degree_general(E, 5)
|
|
2497
|
+
[Isogeny of degree 5
|
|
2498
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
|
|
2499
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298
|
|
2500
|
+
over Rational Field]
|
|
2501
|
+
sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
|
|
2502
|
+
sage: isogenies_prime_degree_general(E, 19)
|
|
2503
|
+
[Isogeny of degree 19
|
|
2504
|
+
from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
|
|
2505
|
+
over Rational Field
|
|
2506
|
+
to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
|
|
2507
|
+
over Rational Field]
|
|
2508
|
+
sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
|
|
2509
|
+
sage: isogenies_prime_degree_general(E, 37) # long time (2s)
|
|
2510
|
+
[Isogeny of degree 37
|
|
2511
|
+
from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072
|
|
2512
|
+
over Rational Field
|
|
2513
|
+
to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728
|
|
2514
|
+
over Rational Field]
|
|
2515
|
+
|
|
2516
|
+
sage: E = EllipticCurve([-3440, 77658])
|
|
2517
|
+
sage: isogenies_prime_degree_general(E, 43) # long time (2s)
|
|
2518
|
+
[Isogeny of degree 43
|
|
2519
|
+
from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field
|
|
2520
|
+
to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606
|
|
2521
|
+
over Rational Field]
|
|
2522
|
+
|
|
2523
|
+
Isogenies of degree equal to the characteristic are computed (but
|
|
2524
|
+
only the separable isogeny). In the following example we consider
|
|
2525
|
+
an elliptic curve which is supersingular in characteristic 2
|
|
2526
|
+
only::
|
|
2527
|
+
|
|
2528
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
|
|
2529
|
+
sage: ainvs = (0,1,1,-1,-1)
|
|
2530
|
+
sage: for l in prime_range(50):
|
|
2531
|
+
....: E = EllipticCurve(GF(l),ainvs)
|
|
2532
|
+
....: isogenies_prime_degree_general(E,l)
|
|
2533
|
+
[]
|
|
2534
|
+
[Isogeny of degree 3
|
|
2535
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2
|
|
2536
|
+
over Finite Field of size 3
|
|
2537
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3]
|
|
2538
|
+
[Isogeny of degree 5
|
|
2539
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4
|
|
2540
|
+
over Finite Field of size 5
|
|
2541
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4
|
|
2542
|
+
over Finite Field of size 5]
|
|
2543
|
+
[Isogeny of degree 7
|
|
2544
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6
|
|
2545
|
+
over Finite Field of size 7
|
|
2546
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7]
|
|
2547
|
+
[Isogeny of degree 11
|
|
2548
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10
|
|
2549
|
+
over Finite Field of size 11
|
|
2550
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1
|
|
2551
|
+
over Finite Field of size 11]
|
|
2552
|
+
[Isogeny of degree 13
|
|
2553
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12
|
|
2554
|
+
over Finite Field of size 13
|
|
2555
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12
|
|
2556
|
+
over Finite Field of size 13]
|
|
2557
|
+
[Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17]
|
|
2558
|
+
[Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19]
|
|
2559
|
+
[Isogeny of degree 23 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23]
|
|
2560
|
+
[Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29]
|
|
2561
|
+
[Isogeny of degree 31 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31]
|
|
2562
|
+
[Isogeny of degree 37 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37]
|
|
2563
|
+
[Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41]
|
|
2564
|
+
[Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
|
|
2565
|
+
[Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
|
|
2566
|
+
|
|
2567
|
+
Note that not all factors of degree `(l-1)/2` of the `l`-division
|
|
2568
|
+
polynomial are kernel polynomials. In this example, the
|
|
2569
|
+
13-division polynomial factors as a product of 14 irreducible
|
|
2570
|
+
factors of degree 6 each, but only two those are kernel
|
|
2571
|
+
polynomials::
|
|
2572
|
+
|
|
2573
|
+
sage: F3 = GF(3)
|
|
2574
|
+
sage: E = EllipticCurve(F3, [0,0,0,-1,0])
|
|
2575
|
+
sage: Psi13 = E.division_polynomial(13)
|
|
2576
|
+
sage: len([f for f, e in Psi13.factor() if f.degree() == 6])
|
|
2577
|
+
14
|
|
2578
|
+
sage: len(E.isogenies_prime_degree(13))
|
|
2579
|
+
2
|
|
2580
|
+
|
|
2581
|
+
Over GF(9) the other factors of degree 6 split into pairs of
|
|
2582
|
+
cubics which can be rearranged to give the remaining 12 kernel
|
|
2583
|
+
polynomials::
|
|
2584
|
+
|
|
2585
|
+
sage: len(E.change_ring(GF(3^2,'a')).isogenies_prime_degree(13)) # needs sage.rings.finite_rings
|
|
2586
|
+
14
|
|
2587
|
+
|
|
2588
|
+
See :issue:`18589`: the following example took 20s before, now only 4s::
|
|
2589
|
+
|
|
2590
|
+
sage: K.<i> = QuadraticField(-1) # needs sage.rings.number_field
|
|
2591
|
+
sage: E = EllipticCurve(K,[0,0,0,1,0]) # needs sage.rings.number_field
|
|
2592
|
+
sage: [phi.codomain().ainvs() # long time # needs sage.rings.number_field
|
|
2593
|
+
....: for phi in E.isogenies_prime_degree(37)]
|
|
2594
|
+
[(0, 0, 0, 840*i + 1081, 0),
|
|
2595
|
+
(0, 0, 0, -840*i + 1081, 0)]
|
|
2596
|
+
"""
|
|
2597
|
+
if not l.is_prime():
|
|
2598
|
+
raise ValueError("%s is not prime." % l)
|
|
2599
|
+
if l == 2:
|
|
2600
|
+
return isogenies_2(E, minimal_models=minimal_models)
|
|
2601
|
+
if l == 3:
|
|
2602
|
+
return isogenies_3(E, minimal_models=minimal_models)
|
|
2603
|
+
|
|
2604
|
+
psi_l = E.division_polynomial(l)
|
|
2605
|
+
|
|
2606
|
+
factors = [h for h,_ in psi_l.factor() if h.degree().divides(l//2)]
|
|
2607
|
+
|
|
2608
|
+
ker = [] # will store all kernel polynomials found
|
|
2609
|
+
|
|
2610
|
+
while factors:
|
|
2611
|
+
h = factors.pop()
|
|
2612
|
+
try:
|
|
2613
|
+
k = E.kernel_polynomial_from_divisor(h, l, check=False)
|
|
2614
|
+
except ValueError:
|
|
2615
|
+
continue
|
|
2616
|
+
assert k.degree() == l//2 and k.divides(psi_l)
|
|
2617
|
+
ker.append(k)
|
|
2618
|
+
factors = [h for h in factors if not h.divides(k)]
|
|
2619
|
+
|
|
2620
|
+
return [E.isogeny(k, check=False) for k in ker]
|
|
2621
|
+
|
|
2622
|
+
|
|
2623
|
+
def isogenies_prime_degree(E, l, minimal_models=True):
|
|
2624
|
+
"""
|
|
2625
|
+
Return all separable ``l``-isogenies with domain ``E``.
|
|
2626
|
+
|
|
2627
|
+
INPUT:
|
|
2628
|
+
|
|
2629
|
+
- ``E`` -- an elliptic curve
|
|
2630
|
+
|
|
2631
|
+
- ``l`` -- a prime
|
|
2632
|
+
|
|
2633
|
+
- ``minimal_models`` -- boolean (default: ``True``); if ``True``, all
|
|
2634
|
+
curves computed will be minimal or semi-minimal models. Over
|
|
2635
|
+
fields of larger degree it can be expensive to compute these so
|
|
2636
|
+
set to ``False``. Ignored except over number fields other than
|
|
2637
|
+
`QQ`.
|
|
2638
|
+
|
|
2639
|
+
OUTPUT: list of all separable isogenies of degree `l` with domain ``E``
|
|
2640
|
+
|
|
2641
|
+
EXAMPLES::
|
|
2642
|
+
|
|
2643
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
|
|
2644
|
+
sage: E = EllipticCurve_from_j(GF(2^6,'a')(1)) # needs sage.rings.finite_rings
|
|
2645
|
+
sage: isogenies_prime_degree(E, 7) # needs sage.rings.finite_rings
|
|
2646
|
+
[Isogeny of degree 7
|
|
2647
|
+
from Elliptic Curve defined by y^2 + x*y = x^3 + 1
|
|
2648
|
+
over Finite Field in a of size 2^6
|
|
2649
|
+
to Elliptic Curve defined by y^2 + x*y = x^3 + x
|
|
2650
|
+
over Finite Field in a of size 2^6]
|
|
2651
|
+
sage: E = EllipticCurve_from_j(GF(3^12,'a')(2)) # needs sage.rings.finite_rings
|
|
2652
|
+
sage: isogenies_prime_degree(E, 17) # needs sage.rings.finite_rings
|
|
2653
|
+
[Isogeny of degree 17
|
|
2654
|
+
from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
|
|
2655
|
+
over Finite Field in a of size 3^12
|
|
2656
|
+
to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2
|
|
2657
|
+
over Finite Field in a of size 3^12,
|
|
2658
|
+
Isogeny of degree 17
|
|
2659
|
+
from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2
|
|
2660
|
+
over Finite Field in a of size 3^12
|
|
2661
|
+
to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x
|
|
2662
|
+
over Finite Field in a of size 3^12]
|
|
2663
|
+
sage: E = EllipticCurve('50a1')
|
|
2664
|
+
sage: isogenies_prime_degree(E, 3)
|
|
2665
|
+
[Isogeny of degree 3
|
|
2666
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
|
|
2667
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field]
|
|
2668
|
+
sage: isogenies_prime_degree(E, 5)
|
|
2669
|
+
[Isogeny of degree 5
|
|
2670
|
+
from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field
|
|
2671
|
+
to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
|
|
2672
|
+
sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
|
|
2673
|
+
sage: isogenies_prime_degree(E, 19)
|
|
2674
|
+
[Isogeny of degree 19
|
|
2675
|
+
from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956
|
|
2676
|
+
over Rational Field
|
|
2677
|
+
to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489
|
|
2678
|
+
over Rational Field]
|
|
2679
|
+
sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
|
|
2680
|
+
sage: isogenies_prime_degree(E, 37)
|
|
2681
|
+
[Isogeny of degree 37
|
|
2682
|
+
from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072
|
|
2683
|
+
over Rational Field
|
|
2684
|
+
to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728
|
|
2685
|
+
over Rational Field]
|
|
2686
|
+
|
|
2687
|
+
Isogenies of degree equal to the characteristic are computed (but
|
|
2688
|
+
only the separable isogeny). In the following example we consider
|
|
2689
|
+
an elliptic curve which is supersingular in characteristic 2
|
|
2690
|
+
only::
|
|
2691
|
+
|
|
2692
|
+
sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
|
|
2693
|
+
sage: ainvs = (0,1,1,-1,-1)
|
|
2694
|
+
sage: for l in prime_range(50):
|
|
2695
|
+
....: E = EllipticCurve(GF(l), ainvs)
|
|
2696
|
+
....: isogenies_prime_degree(E, l)
|
|
2697
|
+
[]
|
|
2698
|
+
[Isogeny of degree 3
|
|
2699
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3
|
|
2700
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3]
|
|
2701
|
+
[Isogeny of degree 5
|
|
2702
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5
|
|
2703
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5]
|
|
2704
|
+
[Isogeny of degree 7
|
|
2705
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7
|
|
2706
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7]
|
|
2707
|
+
[Isogeny of degree 11
|
|
2708
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11
|
|
2709
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11]
|
|
2710
|
+
[Isogeny of degree 13
|
|
2711
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13
|
|
2712
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13]
|
|
2713
|
+
[Isogeny of degree 17
|
|
2714
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17
|
|
2715
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17]
|
|
2716
|
+
[Isogeny of degree 19
|
|
2717
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19
|
|
2718
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19]
|
|
2719
|
+
[Isogeny of degree 23
|
|
2720
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23
|
|
2721
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23]
|
|
2722
|
+
[Isogeny of degree 29
|
|
2723
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29
|
|
2724
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29]
|
|
2725
|
+
[Isogeny of degree 31
|
|
2726
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31
|
|
2727
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31]
|
|
2728
|
+
[Isogeny of degree 37
|
|
2729
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37
|
|
2730
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37]
|
|
2731
|
+
[Isogeny of degree 41
|
|
2732
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41
|
|
2733
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41]
|
|
2734
|
+
[Isogeny of degree 43
|
|
2735
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43
|
|
2736
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
|
|
2737
|
+
[Isogeny of degree 47
|
|
2738
|
+
from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47
|
|
2739
|
+
to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
|
|
2740
|
+
|
|
2741
|
+
Note that the computation is faster for degrees equal to one of
|
|
2742
|
+
the genus 0 primes (2, 3, 5, 7, 13) or one of the hyperelliptic
|
|
2743
|
+
primes (11, 17, 19, 23, 29, 31, 41, 47, 59, 71) than when the
|
|
2744
|
+
generic code must be used::
|
|
2745
|
+
|
|
2746
|
+
sage: E = EllipticCurve(GF(101), [-3440, 77658])
|
|
2747
|
+
sage: E.isogenies_prime_degree(71) # fast
|
|
2748
|
+
[]
|
|
2749
|
+
sage: E.isogenies_prime_degree(73) # long time
|
|
2750
|
+
[]
|
|
2751
|
+
|
|
2752
|
+
Test that :issue:`32269` is fixed::
|
|
2753
|
+
|
|
2754
|
+
sage: K = QuadraticField(-11) # needs sage.rings.number_field
|
|
2755
|
+
sage: E = EllipticCurve(K, [0,1,0,-117,-541]) # needs sage.rings.number_field
|
|
2756
|
+
sage: E.isogenies_prime_degree(37) # long time # needs sage.rings.number_field
|
|
2757
|
+
[Isogeny of degree 37
|
|
2758
|
+
from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541)
|
|
2759
|
+
over Number Field in a with defining polynomial x^2 + 11
|
|
2760
|
+
with a = 3.316624790355400?*I
|
|
2761
|
+
to Elliptic Curve defined by
|
|
2762
|
+
y^2 = x^3 + x^2 + (-30800*a+123963)*x + (-3931312*a-21805005)
|
|
2763
|
+
over Number Field in a with defining polynomial x^2 + 11
|
|
2764
|
+
with a = 3.316624790355400?*I,
|
|
2765
|
+
Isogeny of degree 37
|
|
2766
|
+
from Elliptic Curve defined by y^2 = x^3 + x^2 + (-117)*x + (-541)
|
|
2767
|
+
over Number Field in a with defining polynomial x^2 + 11
|
|
2768
|
+
with a = 3.316624790355400?*I
|
|
2769
|
+
to Elliptic Curve defined by
|
|
2770
|
+
y^2 = x^3 + x^2 + (30800*a+123963)*x + (3931312*a-21805005)
|
|
2771
|
+
over Number Field in a with defining polynomial x^2 + 11
|
|
2772
|
+
with a = 3.316624790355400?*I]
|
|
2773
|
+
"""
|
|
2774
|
+
if not l.is_prime():
|
|
2775
|
+
raise ValueError("%s is not prime." % l)
|
|
2776
|
+
if l == 2:
|
|
2777
|
+
return isogenies_2(E, minimal_models=minimal_models)
|
|
2778
|
+
if l == 3:
|
|
2779
|
+
return isogenies_3(E, minimal_models=minimal_models)
|
|
2780
|
+
|
|
2781
|
+
p = E.base_ring().characteristic()
|
|
2782
|
+
if l == p:
|
|
2783
|
+
return isogenies_prime_degree_general(E,l, minimal_models=minimal_models)
|
|
2784
|
+
|
|
2785
|
+
if l in [5,7,13] and p not in [2,3]:
|
|
2786
|
+
return isogenies_prime_degree_genus_0(E,l, minimal_models=minimal_models)
|
|
2787
|
+
|
|
2788
|
+
if l in hyperelliptic_primes and p not in [2,3]:
|
|
2789
|
+
return isogenies_prime_degree_genus_plus_0(E,l, minimal_models=minimal_models)
|
|
2790
|
+
|
|
2791
|
+
j = E.j_invariant()
|
|
2792
|
+
if j in QQ and E.base_field() is QQ:
|
|
2793
|
+
j = QQ(j)
|
|
2794
|
+
if j in sporadic_j:
|
|
2795
|
+
return isogenies_sporadic_Q(E,l, minimal_models=minimal_models)
|
|
2796
|
+
|
|
2797
|
+
return isogenies_prime_degree_general(E,l, minimal_models=minimal_models)
|