passagemath-schemes 10.6.38__cp314-cp314t-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.21.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.38.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.38.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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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-314t-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,522 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
Frobenius isogenies of elliptic curves
|
|
5
|
+
|
|
6
|
+
Frobenius isogenies only exist in positive characteristic `p`. They
|
|
7
|
+
are given by `\pi_n:(x,y)\mapsto (x^{p^n},y^{p^n})`.
|
|
8
|
+
|
|
9
|
+
This class implements `\pi_n` for `n \geq 0`. Together with existing
|
|
10
|
+
tools for composing isogenies (see :class:`EllipticCurveHom_composite`),
|
|
11
|
+
we can therefore represent arbitrary inseparable isogenies in Sage.
|
|
12
|
+
|
|
13
|
+
EXAMPLES:
|
|
14
|
+
|
|
15
|
+
Constructing a Frobenius isogeny is straightforward::
|
|
16
|
+
|
|
17
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
18
|
+
sage: z5, = GF(17^5).gens()
|
|
19
|
+
sage: E = EllipticCurve([z5,1])
|
|
20
|
+
sage: pi = EllipticCurveHom_frobenius(E); pi
|
|
21
|
+
Frobenius isogeny of degree 17:
|
|
22
|
+
From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1
|
|
23
|
+
over Finite Field in z5 of size 17^5
|
|
24
|
+
To: Elliptic Curve defined by y^2 = x^3 + (9*z5^4+7*z5^3+10*z5^2+z5+14)*x + 1
|
|
25
|
+
over Finite Field in z5 of size 17^5
|
|
26
|
+
|
|
27
|
+
By passing `n`, we can also construct higher-power Frobenius maps,
|
|
28
|
+
such as the Frobenius *endo*\morphism::
|
|
29
|
+
|
|
30
|
+
sage: z5, = GF(7^5).gens()
|
|
31
|
+
sage: E = EllipticCurve([z5,1])
|
|
32
|
+
sage: pi = EllipticCurveHom_frobenius(E, 5); pi
|
|
33
|
+
Frobenius endomorphism of degree 16807 = 7^5:
|
|
34
|
+
From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1
|
|
35
|
+
over Finite Field in z5 of size 7^5
|
|
36
|
+
To: Elliptic Curve defined by y^2 = x^3 + z5*x + 1
|
|
37
|
+
over Finite Field in z5 of size 7^5
|
|
38
|
+
|
|
39
|
+
The usual :class:`EllipticCurveHom` methods are supported::
|
|
40
|
+
|
|
41
|
+
sage: z5, = GF(7^5).gens()
|
|
42
|
+
sage: E = EllipticCurve([z5,1])
|
|
43
|
+
sage: pi = EllipticCurveHom_frobenius(E,5)
|
|
44
|
+
sage: pi.degree()
|
|
45
|
+
16807
|
|
46
|
+
sage: pi.rational_maps()
|
|
47
|
+
(x^16807, y^16807)
|
|
48
|
+
sage: pi.formal() # known bug
|
|
49
|
+
...
|
|
50
|
+
sage: pi.is_normalized() # known bug
|
|
51
|
+
...
|
|
52
|
+
sage: pi.is_separable()
|
|
53
|
+
False
|
|
54
|
+
sage: pi.is_injective()
|
|
55
|
+
True
|
|
56
|
+
sage: pi.is_surjective()
|
|
57
|
+
True
|
|
58
|
+
|
|
59
|
+
Computing the dual of Frobenius is supported as well::
|
|
60
|
+
|
|
61
|
+
sage: E = EllipticCurve([GF(17^6).gen(), 0])
|
|
62
|
+
sage: pi = EllipticCurveHom_frobenius(E)
|
|
63
|
+
sage: pihat = pi.dual(); pihat
|
|
64
|
+
Isogeny of degree 17
|
|
65
|
+
from Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)*x
|
|
66
|
+
over Finite Field in z6 of size 17^6
|
|
67
|
+
to Elliptic Curve defined by y^2 = x^3 + z6*x
|
|
68
|
+
over Finite Field in z6 of size 17^6
|
|
69
|
+
sage: pihat.is_separable()
|
|
70
|
+
True
|
|
71
|
+
sage: pihat * pi == EllipticCurveHom_scalar(E,17) # known bug -- #6413
|
|
72
|
+
True
|
|
73
|
+
|
|
74
|
+
A supersingular example (with purely inseparable dual)::
|
|
75
|
+
|
|
76
|
+
sage: E = EllipticCurve([0, GF(17^6).gen()])
|
|
77
|
+
sage: E.is_supersingular()
|
|
78
|
+
True
|
|
79
|
+
sage: pi1 = EllipticCurveHom_frobenius(E)
|
|
80
|
+
sage: pi1hat = pi1.dual(); pi1hat
|
|
81
|
+
Composite morphism of degree 17 = 17*1:
|
|
82
|
+
From: Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)
|
|
83
|
+
over Finite Field in z6 of size 17^6
|
|
84
|
+
To: Elliptic Curve defined by y^2 = x^3 + z6
|
|
85
|
+
over Finite Field in z6 of size 17^6
|
|
86
|
+
sage: pi6 = EllipticCurveHom_frobenius(E,6)
|
|
87
|
+
sage: pi6hat = pi6.dual(); pi6hat
|
|
88
|
+
Composite morphism of degree 24137569 = 24137569*1:
|
|
89
|
+
From: Elliptic Curve defined by y^2 = x^3 + z6
|
|
90
|
+
over Finite Field in z6 of size 17^6
|
|
91
|
+
To: Elliptic Curve defined by y^2 = x^3 + z6
|
|
92
|
+
over Finite Field in z6 of size 17^6
|
|
93
|
+
sage: pi6hat.factors()
|
|
94
|
+
(Frobenius endomorphism of degree 24137569 = 17^6:
|
|
95
|
+
From: Elliptic Curve defined by y^2 = x^3 + z6
|
|
96
|
+
over Finite Field in z6 of size 17^6
|
|
97
|
+
To: Elliptic Curve defined by y^2 = x^3 + z6
|
|
98
|
+
over Finite Field in z6 of size 17^6,
|
|
99
|
+
Elliptic-curve endomorphism of
|
|
100
|
+
Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6
|
|
101
|
+
Via: (u,r,s,t) = (2*z6^5 + 10*z6^3 + z6^2 + 8, 0, 0, 0))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
TESTS::
|
|
105
|
+
|
|
106
|
+
sage: z5, = GF(17^5).gens()
|
|
107
|
+
sage: E = EllipticCurve([z5,1])
|
|
108
|
+
sage: fs = [EllipticCurveHom_frobenius(E)]
|
|
109
|
+
sage: while fs[-1].codomain() != E:
|
|
110
|
+
....: fs.append(EllipticCurveHom_frobenius(fs[-1].codomain()))
|
|
111
|
+
sage: fs
|
|
112
|
+
[Frobenius isogeny of degree 17:
|
|
113
|
+
From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 17^5
|
|
114
|
+
To: Elliptic Curve defined by y^2 = x^3 + (9*z5^4+7*z5^3+10*z5^2+z5+14)*x + 1 over Finite Field in z5 of size 17^5,
|
|
115
|
+
Frobenius isogeny of degree 17:
|
|
116
|
+
From: Elliptic Curve defined by y^2 = x^3 + (9*z5^4+7*z5^3+10*z5^2+z5+14)*x + 1 over Finite Field in z5 of size 17^5
|
|
117
|
+
To: Elliptic Curve defined by y^2 = x^3 + (14*z5^4+7*z5^3+16*z5^2+14*z5+1)*x + 1 over Finite Field in z5 of size 17^5,
|
|
118
|
+
Frobenius isogeny of degree 17:
|
|
119
|
+
From: Elliptic Curve defined by y^2 = x^3 + (14*z5^4+7*z5^3+16*z5^2+14*z5+1)*x + 1 over Finite Field in z5 of size 17^5
|
|
120
|
+
To: Elliptic Curve defined by y^2 = x^3 + (16*z5^4+6*z5^3+7*z5^2+14*z5+6)*x + 1 over Finite Field in z5 of size 17^5,
|
|
121
|
+
Frobenius isogeny of degree 17:
|
|
122
|
+
From: Elliptic Curve defined by y^2 = x^3 + (16*z5^4+6*z5^3+7*z5^2+14*z5+6)*x + 1 over Finite Field in z5 of size 17^5
|
|
123
|
+
To: Elliptic Curve defined by y^2 = x^3 + (12*z5^4+14*z5^3+z5^2+4*z5+13)*x + 1 over Finite Field in z5 of size 17^5,
|
|
124
|
+
Frobenius isogeny of degree 17:
|
|
125
|
+
From: Elliptic Curve defined by y^2 = x^3 + (12*z5^4+14*z5^3+z5^2+4*z5+13)*x + 1 over Finite Field in z5 of size 17^5
|
|
126
|
+
To: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 17^5]
|
|
127
|
+
sage: prod(fs[::-1])
|
|
128
|
+
Composite morphism of degree 1419857 = 17^5:
|
|
129
|
+
From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 17^5
|
|
130
|
+
To: Elliptic Curve defined by y^2 = x^3 + z5*x + 1 over Finite Field in z5 of size 17^5
|
|
131
|
+
|
|
132
|
+
::
|
|
133
|
+
|
|
134
|
+
sage: EllipticCurveHom_frobenius(EllipticCurve(GF(5),[1,1]), -1)
|
|
135
|
+
Traceback (most recent call last):
|
|
136
|
+
...
|
|
137
|
+
ValueError: negative powers of Frobenius are not isogenies
|
|
138
|
+
|
|
139
|
+
::
|
|
140
|
+
|
|
141
|
+
sage: EllipticCurveHom_frobenius(EllipticCurve('11a1'))
|
|
142
|
+
Traceback (most recent call last):
|
|
143
|
+
...
|
|
144
|
+
ValueError: Frobenius isogenies do not exist in characteristic zero
|
|
145
|
+
|
|
146
|
+
AUTHORS:
|
|
147
|
+
|
|
148
|
+
- Lorenz Panny (2021): implement :class:`EllipticCurveHom_frobenius`
|
|
149
|
+
- Mickaël Montessinos (2021): computing the dual of a Frobenius isogeny
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
from sage.misc.cachefunc import cached_method
|
|
153
|
+
from sage.structure.sequence import Sequence
|
|
154
|
+
|
|
155
|
+
from sage.rings.integer_ring import ZZ
|
|
156
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
157
|
+
|
|
158
|
+
from sage.rings.finite_rings.finite_field_base import FiniteField
|
|
159
|
+
|
|
160
|
+
from sage.schemes.elliptic_curves.ell_generic import EllipticCurve_generic
|
|
161
|
+
from sage.schemes.elliptic_curves.constructor import EllipticCurve
|
|
162
|
+
|
|
163
|
+
from sage.schemes.elliptic_curves.hom import EllipticCurveHom, find_post_isomorphism
|
|
164
|
+
from sage.schemes.elliptic_curves.ell_curve_isogeny import EllipticCurveIsogeny
|
|
165
|
+
from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite
|
|
166
|
+
from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class EllipticCurveHom_frobenius(EllipticCurveHom):
|
|
170
|
+
|
|
171
|
+
_degree = None
|
|
172
|
+
|
|
173
|
+
def __init__(self, E, power=1):
|
|
174
|
+
r"""
|
|
175
|
+
Construct a Frobenius isogeny on a given curve with a given
|
|
176
|
+
power of the base-ring characteristic.
|
|
177
|
+
|
|
178
|
+
Writing `n` for the parameter ``power`` (default: `1`), the
|
|
179
|
+
isogeny is defined by `(x,y) \to (x^{p^n}, y^{p^n})` where
|
|
180
|
+
`p` is the characteristic of the base ring.
|
|
181
|
+
|
|
182
|
+
EXAMPLES::
|
|
183
|
+
|
|
184
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
185
|
+
sage: E = EllipticCurve(j=GF(11^2).gen())
|
|
186
|
+
sage: EllipticCurveHom_frobenius(E)
|
|
187
|
+
Frobenius isogeny of degree 11:
|
|
188
|
+
From: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
|
|
189
|
+
To: Elliptic Curve defined by y^2 = x^3 + (9*z2+3)*x + (3*z2+7) over Finite Field in z2 of size 11^2
|
|
190
|
+
sage: EllipticCurveHom_frobenius(E, 2)
|
|
191
|
+
Frobenius endomorphism of degree 121 = 11^2:
|
|
192
|
+
From: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
|
|
193
|
+
To: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
|
|
194
|
+
|
|
195
|
+
TESTS::
|
|
196
|
+
|
|
197
|
+
sage: EllipticCurveHom_frobenius(EllipticCurve('11a1'))
|
|
198
|
+
Traceback (most recent call last):
|
|
199
|
+
...
|
|
200
|
+
ValueError: Frobenius isogenies do not exist in characteristic zero
|
|
201
|
+
|
|
202
|
+
::
|
|
203
|
+
|
|
204
|
+
sage: EllipticCurveHom_frobenius(E, -1)
|
|
205
|
+
Traceback (most recent call last):
|
|
206
|
+
...
|
|
207
|
+
ValueError: negative powers of Frobenius are not isogenies
|
|
208
|
+
"""
|
|
209
|
+
if not isinstance(E, EllipticCurve_generic):
|
|
210
|
+
raise ValueError(f'not an elliptic curve: {E}')
|
|
211
|
+
|
|
212
|
+
self._base_ring = E.base_ring()
|
|
213
|
+
|
|
214
|
+
self._p = self._base_ring.characteristic()
|
|
215
|
+
if self._p == 0:
|
|
216
|
+
raise ValueError('Frobenius isogenies do not exist in characteristic zero')
|
|
217
|
+
|
|
218
|
+
self._n = ZZ(power)
|
|
219
|
+
if self._n < 0:
|
|
220
|
+
raise ValueError('negative powers of Frobenius are not isogenies')
|
|
221
|
+
|
|
222
|
+
self._degree = self._p ** self._n
|
|
223
|
+
|
|
224
|
+
self._domain = E
|
|
225
|
+
as_ = [a**self._degree for a in self._domain.a_invariants()]
|
|
226
|
+
self._codomain = EllipticCurve(as_)
|
|
227
|
+
|
|
228
|
+
EllipticCurveHom.__init__(self, self._domain, self._codomain)
|
|
229
|
+
|
|
230
|
+
# over finite fields, isogenous curves have the same number of points
|
|
231
|
+
# (see #32786)
|
|
232
|
+
if isinstance(self._base_ring, FiniteField):
|
|
233
|
+
self._domain._fetch_cached_order(self._codomain)
|
|
234
|
+
self._codomain._fetch_cached_order(self._domain)
|
|
235
|
+
|
|
236
|
+
self._poly_ring = PolynomialRing(self._base_ring, ['x'], sparse=True)
|
|
237
|
+
self._mpoly_ring = PolynomialRing(self._base_ring, ['x','y'], sparse=True)
|
|
238
|
+
self._xfield = self._poly_ring.fraction_field()
|
|
239
|
+
self._xyfield = self._mpoly_ring.fraction_field()
|
|
240
|
+
|
|
241
|
+
def _call_(self, P):
|
|
242
|
+
"""
|
|
243
|
+
Evaluate this Frobenius isogeny at a point `P`.
|
|
244
|
+
|
|
245
|
+
EXAMPLES::
|
|
246
|
+
|
|
247
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
248
|
+
sage: z2 = GF(11^2).gen()
|
|
249
|
+
sage: E = EllipticCurve(j=z2)
|
|
250
|
+
sage: pi = EllipticCurveHom_frobenius(E)
|
|
251
|
+
sage: P = E(7, 9*z2+4)
|
|
252
|
+
sage: pi(P) # implicit doctest
|
|
253
|
+
(7 : 2*z2 + 7 : 1)
|
|
254
|
+
"""
|
|
255
|
+
return self._codomain(*(c**self._degree for c in P))
|
|
256
|
+
|
|
257
|
+
def _eval(self, P):
|
|
258
|
+
"""
|
|
259
|
+
Less strict evaluation method for internal use.
|
|
260
|
+
|
|
261
|
+
In particular, this can be used to evaluate ``self`` at a
|
|
262
|
+
point defined over an extension field.
|
|
263
|
+
|
|
264
|
+
INPUT: a sequence of 3 coordinates defining a point on ``self``
|
|
265
|
+
|
|
266
|
+
OUTPUT: the result of evaluating ``self`` at the given point
|
|
267
|
+
|
|
268
|
+
EXAMPLES::
|
|
269
|
+
|
|
270
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
271
|
+
sage: E = EllipticCurve(GF(11), [1,1])
|
|
272
|
+
sage: pi = EllipticCurveHom_frobenius(E)
|
|
273
|
+
sage: Ebar = E.change_ring(GF(11^6))
|
|
274
|
+
sage: z6 = GF(11^6).gen()
|
|
275
|
+
sage: P = Ebar.lift_x(GF(11^3).gen())
|
|
276
|
+
sage: p = Ebar(6*z6^5 + 8*z6^4 + 8*z6^3 + 6*z6^2 + 10*z6 + 5, 2*z6^5 + 2*z6^4 + 2*z6^3 + 4*z6 + 6, 1)
|
|
277
|
+
sage: Q = pi._eval(P)
|
|
278
|
+
sage: q = Ebar(z6^5 + 3*z6^4 + 3*z6^3 + 6*z6^2 + 9, z6^5 + 10*z6^4 + 10*z6^3 + 5*z6^2 + 4*z6 + 8, 1)
|
|
279
|
+
sage: (P == p and Q == q) or (P == -p and Q == -q)
|
|
280
|
+
True
|
|
281
|
+
"""
|
|
282
|
+
if self._domain.defining_polynomial()(*P):
|
|
283
|
+
raise ValueError(f'{P} not on {self._domain}')
|
|
284
|
+
k = Sequence(P).universe()
|
|
285
|
+
return self._codomain.base_extend(k)(*(c**self._degree for c in P))
|
|
286
|
+
|
|
287
|
+
def _repr_(self):
|
|
288
|
+
"""
|
|
289
|
+
Return basic facts about this Frobenius isogeny as a string.
|
|
290
|
+
|
|
291
|
+
TESTS::
|
|
292
|
+
|
|
293
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
294
|
+
sage: z2 = GF(11^2).gen()
|
|
295
|
+
sage: E = EllipticCurve(j=z2)
|
|
296
|
+
sage: EllipticCurveHom_frobenius(E)
|
|
297
|
+
Frobenius isogeny of degree 11:
|
|
298
|
+
From: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
|
|
299
|
+
To: Elliptic Curve defined by y^2 = x^3 + (9*z2+3)*x + (3*z2+7) over Finite Field in z2 of size 11^2
|
|
300
|
+
sage: EllipticCurveHom_frobenius(E, E.base_field().degree())
|
|
301
|
+
Frobenius endomorphism of degree 121 = 11^2:
|
|
302
|
+
From: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
|
|
303
|
+
To: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
|
|
304
|
+
"""
|
|
305
|
+
kind = 'endomorphism' if self._codomain == self._domain else 'isogeny'
|
|
306
|
+
degs_str = '' if self._n == 1 else f' = {self._p}^{self._n}'
|
|
307
|
+
return f'Frobenius {kind} of degree {self._degree}{degs_str}:' \
|
|
308
|
+
f'\n From: {self._domain}' \
|
|
309
|
+
f'\n To: {self._codomain}'
|
|
310
|
+
|
|
311
|
+
# EllipticCurveHom methods
|
|
312
|
+
|
|
313
|
+
def rational_maps(self):
|
|
314
|
+
"""
|
|
315
|
+
Return the explicit rational maps defining this Frobenius
|
|
316
|
+
isogeny as (sparse) bivariate rational maps in `x` and `y`.
|
|
317
|
+
|
|
318
|
+
EXAMPLES::
|
|
319
|
+
|
|
320
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
321
|
+
sage: E = EllipticCurve(GF(11), [1,1])
|
|
322
|
+
sage: pi = EllipticCurveHom_frobenius(E, 4)
|
|
323
|
+
sage: pi.rational_maps()
|
|
324
|
+
(x^14641, y^14641)
|
|
325
|
+
|
|
326
|
+
TESTS:
|
|
327
|
+
|
|
328
|
+
See :issue:`34811`::
|
|
329
|
+
|
|
330
|
+
sage: pi.rational_maps()[0].parent()
|
|
331
|
+
Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 11
|
|
332
|
+
sage: pi.rational_maps()[1].parent()
|
|
333
|
+
Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 11
|
|
334
|
+
"""
|
|
335
|
+
x,y = self._xyfield.gens()
|
|
336
|
+
return (x**self._degree, y**self._degree)
|
|
337
|
+
|
|
338
|
+
def x_rational_map(self):
|
|
339
|
+
"""
|
|
340
|
+
Return the `x`-coordinate rational map of this Frobenius
|
|
341
|
+
isogeny as a (sparse) univariate rational map in `x`.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
346
|
+
sage: E = EllipticCurve(GF(11), [1,1])
|
|
347
|
+
sage: pi = EllipticCurveHom_frobenius(E, 4)
|
|
348
|
+
sage: pi.x_rational_map()
|
|
349
|
+
x^14641
|
|
350
|
+
|
|
351
|
+
TESTS:
|
|
352
|
+
|
|
353
|
+
See :issue:`34811`::
|
|
354
|
+
|
|
355
|
+
sage: pi.x_rational_map().parent()
|
|
356
|
+
Fraction Field of Sparse Univariate Polynomial Ring in x over Finite Field of size 11
|
|
357
|
+
"""
|
|
358
|
+
x, = self._xfield.gens()
|
|
359
|
+
return x**self._degree
|
|
360
|
+
|
|
361
|
+
def scaling_factor(self):
|
|
362
|
+
r"""
|
|
363
|
+
Return the Weierstrass scaling factor associated to this
|
|
364
|
+
Frobenius morphism.
|
|
365
|
+
|
|
366
|
+
The scaling factor is the constant `u` (in the base field)
|
|
367
|
+
such that `\varphi^* \omega_2 = u \omega_1`, where
|
|
368
|
+
`\varphi: E_1\to E_2` is this morphism and `\omega_i` are
|
|
369
|
+
the standard Weierstrass differentials on `E_i` defined by
|
|
370
|
+
`\mathrm dx/(2y+a_1x+a_3)`.
|
|
371
|
+
|
|
372
|
+
EXAMPLES::
|
|
373
|
+
|
|
374
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
375
|
+
sage: E = EllipticCurve(GF(11), [1,1])
|
|
376
|
+
sage: pi = EllipticCurveHom_frobenius(E)
|
|
377
|
+
sage: pi.formal()
|
|
378
|
+
t^11 + O(t^33)
|
|
379
|
+
sage: pi.scaling_factor()
|
|
380
|
+
0
|
|
381
|
+
sage: pi = EllipticCurveHom_frobenius(E, 3)
|
|
382
|
+
sage: pi.formal()
|
|
383
|
+
t^1331 + O(t^1353)
|
|
384
|
+
sage: pi.scaling_factor()
|
|
385
|
+
0
|
|
386
|
+
sage: pi = EllipticCurveHom_frobenius(E, 0)
|
|
387
|
+
sage: pi == E.scalar_multiplication(1)
|
|
388
|
+
True
|
|
389
|
+
sage: pi.scaling_factor()
|
|
390
|
+
1
|
|
391
|
+
|
|
392
|
+
The scaling factor lives in the base ring::
|
|
393
|
+
|
|
394
|
+
sage: pi.scaling_factor().parent()
|
|
395
|
+
Finite Field of size 11
|
|
396
|
+
|
|
397
|
+
ALGORITHM: Inseparable isogenies of degree `>1` have scaling
|
|
398
|
+
factor `0`.
|
|
399
|
+
"""
|
|
400
|
+
if self._degree == 1:
|
|
401
|
+
return self._base_ring.one()
|
|
402
|
+
return self._base_ring.zero()
|
|
403
|
+
|
|
404
|
+
def kernel_polynomial(self):
|
|
405
|
+
"""
|
|
406
|
+
Return the kernel polynomial of this Frobenius isogeny
|
|
407
|
+
as a polynomial in `x`. This method always returns `1`.
|
|
408
|
+
|
|
409
|
+
EXAMPLES::
|
|
410
|
+
|
|
411
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
412
|
+
sage: E = EllipticCurve(GF(11), [1,1])
|
|
413
|
+
sage: pi = EllipticCurveHom_frobenius(E, 5)
|
|
414
|
+
sage: pi.kernel_polynomial()
|
|
415
|
+
1
|
|
416
|
+
"""
|
|
417
|
+
return self._poly_ring(1)
|
|
418
|
+
|
|
419
|
+
@cached_method
|
|
420
|
+
def dual(self):
|
|
421
|
+
"""
|
|
422
|
+
Compute the dual of this Frobenius isogeny.
|
|
423
|
+
|
|
424
|
+
This method returns an :class:`EllipticCurveHom` object.
|
|
425
|
+
|
|
426
|
+
EXAMPLES:
|
|
427
|
+
|
|
428
|
+
An ordinary example::
|
|
429
|
+
|
|
430
|
+
sage: from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar
|
|
431
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
432
|
+
sage: E = EllipticCurve(GF(31), [0,1])
|
|
433
|
+
sage: f = EllipticCurveHom_frobenius(E)
|
|
434
|
+
sage: f.dual() * f == EllipticCurveHom_scalar(f.domain(), 31) # needs sage.symbolic
|
|
435
|
+
True
|
|
436
|
+
sage: f * f.dual() == EllipticCurveHom_scalar(f.codomain(), 31) # needs sage.symbolic
|
|
437
|
+
True
|
|
438
|
+
|
|
439
|
+
A supersingular example::
|
|
440
|
+
|
|
441
|
+
sage: E = EllipticCurve(GF(31), [1,0])
|
|
442
|
+
sage: f = EllipticCurveHom_frobenius(E)
|
|
443
|
+
sage: f.dual() * f == EllipticCurveHom_scalar(f.domain(), 31) # needs sage.symbolic
|
|
444
|
+
True
|
|
445
|
+
sage: f * f.dual() == EllipticCurveHom_scalar(f.codomain(), 31) # needs sage.symbolic
|
|
446
|
+
True
|
|
447
|
+
|
|
448
|
+
TESTS:
|
|
449
|
+
|
|
450
|
+
Some random testing (including small characteristic)::
|
|
451
|
+
|
|
452
|
+
sage: p = random_prime(50)
|
|
453
|
+
sage: q = p**randrange(1,10)
|
|
454
|
+
sage: n = randrange(20)
|
|
455
|
+
sage: while True:
|
|
456
|
+
....: try:
|
|
457
|
+
....: E = EllipticCurve([GF(q).random_element() for _ in range(5)])
|
|
458
|
+
....: break
|
|
459
|
+
....: except ArithmeticError:
|
|
460
|
+
....: pass
|
|
461
|
+
sage: f = EllipticCurveHom_frobenius(E, n)
|
|
462
|
+
sage: f.dual() * f == EllipticCurveHom_scalar(E, p**n) # needs sage.symbolic
|
|
463
|
+
True
|
|
464
|
+
sage: f * f.dual() == EllipticCurveHom_scalar(f.codomain(), p**n) # needs sage.symbolic
|
|
465
|
+
True
|
|
466
|
+
sage: f.dual().dual() == f # known bug -- broken in characteristic 2,3 # needs sage.symbolic
|
|
467
|
+
True
|
|
468
|
+
sage: p in (2,3) or f.dual().dual() == f # needs sage.symbolic
|
|
469
|
+
True
|
|
470
|
+
|
|
471
|
+
ALGORITHM:
|
|
472
|
+
|
|
473
|
+
- For supersingular curves, the dual of Frobenius is again purely
|
|
474
|
+
inseparable, so we start out with a Frobenius isogeny of equal
|
|
475
|
+
degree in the opposite direction.
|
|
476
|
+
|
|
477
|
+
- For ordinary curves, we immediately reduce to the case of prime
|
|
478
|
+
degree. The kernel of the dual is the unique subgroup of size `p`,
|
|
479
|
+
which we compute from the `p`-division polynomial.
|
|
480
|
+
|
|
481
|
+
In both cases, we then search for the correct post-isomorphism
|
|
482
|
+
using :meth:`find_post_isomorphism`.
|
|
483
|
+
"""
|
|
484
|
+
if self._degree == 1:
|
|
485
|
+
return self
|
|
486
|
+
|
|
487
|
+
if self._domain.is_supersingular():
|
|
488
|
+
Phi = EllipticCurveHom_frobenius(self._codomain, self._n)
|
|
489
|
+
|
|
490
|
+
else:
|
|
491
|
+
E = self._domain
|
|
492
|
+
poly = self._domain.division_polynomial(self._p)
|
|
493
|
+
ker = self._poly_ring(list(poly)[::self._p]).monic()
|
|
494
|
+
Phis = []
|
|
495
|
+
for _ in range(self._n):
|
|
496
|
+
Ep = EllipticCurve([a**self._p for a in E.a_invariants()])
|
|
497
|
+
Phis.append(EllipticCurveIsogeny(Ep, ker, codomain=E))
|
|
498
|
+
E, ker = Ep, ker.map_coefficients(lambda c: c**self._p)
|
|
499
|
+
Phi = EllipticCurveHom_composite.from_factors(Phis[::-1], self._codomain)
|
|
500
|
+
|
|
501
|
+
scalar_mul = EllipticCurveHom_scalar(self._domain, self._degree)
|
|
502
|
+
iso = find_post_isomorphism(Phi * self, scalar_mul)
|
|
503
|
+
return iso * Phi
|
|
504
|
+
|
|
505
|
+
def inseparable_degree(self):
|
|
506
|
+
"""
|
|
507
|
+
Return the inseparable degree of this Frobenius isogeny.
|
|
508
|
+
|
|
509
|
+
Since this class implements only purely inseparable isogenies,
|
|
510
|
+
the inseparable degree equals the degree.
|
|
511
|
+
|
|
512
|
+
EXAMPLES::
|
|
513
|
+
|
|
514
|
+
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
|
|
515
|
+
sage: E = EllipticCurve(GF(11), [1,1])
|
|
516
|
+
sage: pi = EllipticCurveHom_frobenius(E, 4)
|
|
517
|
+
sage: pi.inseparable_degree()
|
|
518
|
+
14641
|
|
519
|
+
sage: pi.inseparable_degree() == pi.degree()
|
|
520
|
+
True
|
|
521
|
+
"""
|
|
522
|
+
return self._degree
|