passagemath-schemes 10.8.1a4__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.
- 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.8.1a4.dist-info/METADATA +203 -0
- passagemath_schemes-10.8.1a4.dist-info/METADATA.bak +204 -0
- passagemath_schemes-10.8.1a4.dist-info/RECORD +312 -0
- passagemath_schemes-10.8.1a4.dist-info/WHEEL +6 -0
- passagemath_schemes-10.8.1a4.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 +9556 -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 +2578 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +727 -0
- sage/lfunctions/pari.py +971 -0
- sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5132 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +414 -0
- sage/modular/abvar/abvar_newform.py +246 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +187 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +721 -0
- sage/modular/abvar/homspace.py +989 -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 +741 -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 +1406 -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 +361 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +659 -0
- sage/modular/arithgroup/congroup_gammaH.py +1491 -0
- sage/modular/arithgroup/congroup_generic.py +630 -0
- sage/modular/arithgroup/congroup_sl2z.py +266 -0
- sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1067 -0
- sage/modular/arithgroup/tests.py +425 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3736 -0
- sage/modular/btquotients/pautomorphicform.py +2564 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1107 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +571 -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 +1076 -0
- sage/modular/hecke/algebra.py +725 -0
- sage/modular/hecke/all.py +19 -0
- sage/modular/hecke/ambient_module.py +994 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +302 -0
- sage/modular/hecke/hecke_operator.py +736 -0
- sage/modular/hecke/homspace.py +185 -0
- sage/modular/hecke/module.py +1744 -0
- sage/modular/hecke/morphism.py +139 -0
- sage/modular/hecke/submodule.py +970 -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 +2020 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1070 -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 +817 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +120 -0
- sage/modular/modform/ambient_g1.py +199 -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 +487 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4105 -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 +127 -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 +1859 -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 +380 -0
- sage/modular/modform/weight1.py +221 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2527 -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 +3349 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1426 -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 +3844 -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 +1291 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-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 +376 -0
- sage/modular/multiple_zeta.py +2635 -0
- sage/modular/multiple_zeta_F_algebra.py +789 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1879 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +776 -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 +856 -0
- sage/modular/pollack_stevens/modsym.py +1590 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1078 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +846 -0
- sage/modular/quasimodform/ring.py +826 -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 +700 -0
- sage/schemes/curves/affine_curve.py +2924 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +397 -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 +3203 -0
- sage/schemes/curves/weighted_projective_curve.py +106 -0
- sage/schemes/curves/zariski_vankampen.py +1931 -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 +991 -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 +1103 -0
- sage/schemes/elliptic_curves/constructor.py +1530 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3971 -0
- sage/schemes/elliptic_curves/ell_egros.py +457 -0
- sage/schemes/elliptic_curves/ell_field.py +2837 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3249 -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 +4944 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7184 -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 +1663 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7328 -0
- sage/schemes/elliptic_curves/height.py +2108 -0
- sage/schemes/elliptic_curves/hom.py +1788 -0
- sage/schemes/elliptic_curves/hom_composite.py +1084 -0
- sage/schemes/elliptic_curves/hom_fractional.py +544 -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 +681 -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 +1523 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +247 -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 +915 -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 +716 -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 +369 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1948 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +936 -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 +312 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +437 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +878 -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 +3863 -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 +581 -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 +53 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4177 -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,544 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Fractional morphisms of elliptic curves
|
|
4
|
+
|
|
5
|
+
Algorithms involving advanced computations with endomorphisms
|
|
6
|
+
or isogenies of elliptic curves sometimes involve divisions of
|
|
7
|
+
elliptic-curve morphisms by integers.
|
|
8
|
+
This operation yields another well-defined morphism whenever the
|
|
9
|
+
kernel of the numerator contains the kernel of the denominator.
|
|
10
|
+
|
|
11
|
+
The class :class:`EllipticCurveHom_fractional` represents symbolic
|
|
12
|
+
fractions `\varphi / n` where `\varphi\colon E\to E'` is any
|
|
13
|
+
:class:`~sage.schemes.elliptic_curves.hom.EllipticCurveHom` whose
|
|
14
|
+
kernel contains the `n`-torsion subgroup of `E`.
|
|
15
|
+
Functionality for converting this fraction to a more explicit form
|
|
16
|
+
is provided (:meth:`~EllipticCurveHom_fractional.to_isogeny_chain`).
|
|
17
|
+
|
|
18
|
+
EXAMPLES:
|
|
19
|
+
|
|
20
|
+
Division by an integer::
|
|
21
|
+
|
|
22
|
+
sage: E = EllipticCurve(GF(419), [-1, 0])
|
|
23
|
+
sage: phi = (E.frobenius_isogeny() + 1) / 2
|
|
24
|
+
sage: phi
|
|
25
|
+
Fractional elliptic-curve morphism of degree 105:
|
|
26
|
+
Numerator: Sum morphism:
|
|
27
|
+
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
28
|
+
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
29
|
+
Via: (Frobenius endomorphism of degree 419:
|
|
30
|
+
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
31
|
+
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419,
|
|
32
|
+
Scalar-multiplication endomorphism [1]
|
|
33
|
+
of Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419)
|
|
34
|
+
Denominator: 2
|
|
35
|
+
sage: phi.degree()
|
|
36
|
+
105
|
|
37
|
+
sage: phi.to_isogeny_chain()
|
|
38
|
+
Composite morphism of degree 105 = 1*3*5*7:
|
|
39
|
+
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
40
|
+
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
41
|
+
|
|
42
|
+
Right division of isogenies::
|
|
43
|
+
|
|
44
|
+
sage: E = EllipticCurve(GF(419), [1, 0])
|
|
45
|
+
sage: ker = E(125, 70)
|
|
46
|
+
sage: phi = E.isogeny(ker); phi
|
|
47
|
+
Isogeny of degree 35
|
|
48
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
|
|
49
|
+
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
|
|
50
|
+
sage: psi = E.isogeny(5*ker); psi
|
|
51
|
+
Isogeny of degree 7
|
|
52
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
|
|
53
|
+
to Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
|
|
54
|
+
sage: chi = phi.divide_right(psi); chi
|
|
55
|
+
Fractional elliptic-curve morphism of degree 5:
|
|
56
|
+
Numerator: Composite morphism of degree 245 = 7*35:
|
|
57
|
+
From: Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
|
|
58
|
+
To: Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
|
|
59
|
+
Denominator: 7
|
|
60
|
+
sage: phi == chi * psi
|
|
61
|
+
True
|
|
62
|
+
|
|
63
|
+
Left division of isogenies::
|
|
64
|
+
|
|
65
|
+
sage: E = EllipticCurve(GF(419), [1, 0])
|
|
66
|
+
sage: ker = E(125, 70)
|
|
67
|
+
sage: phi = E.isogeny(ker); phi
|
|
68
|
+
Isogeny of degree 35
|
|
69
|
+
from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
|
|
70
|
+
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
|
|
71
|
+
sage: tmp = E.isogeny(7*ker)
|
|
72
|
+
sage: psi = tmp.codomain().isogeny(tmp(ker)); psi
|
|
73
|
+
Isogeny of degree 7
|
|
74
|
+
from Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
|
|
75
|
+
to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
|
|
76
|
+
sage: chi = phi.divide_left(psi); chi
|
|
77
|
+
Fractional elliptic-curve morphism of degree 5:
|
|
78
|
+
Numerator: Composite morphism of degree 245 = 35*7:
|
|
79
|
+
From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
|
|
80
|
+
To: Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
|
|
81
|
+
Denominator: 7
|
|
82
|
+
sage: phi == psi * chi
|
|
83
|
+
True
|
|
84
|
+
|
|
85
|
+
AUTHORS:
|
|
86
|
+
|
|
87
|
+
- Lorenz Panny (2024)
|
|
88
|
+
"""
|
|
89
|
+
from sage.misc.cachefunc import cached_method
|
|
90
|
+
from sage.structure.sequence import Sequence
|
|
91
|
+
|
|
92
|
+
from sage.rings.integer_ring import ZZ
|
|
93
|
+
|
|
94
|
+
from sage.schemes.elliptic_curves.hom import EllipticCurveHom
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class EllipticCurveHom_fractional(EllipticCurveHom):
|
|
98
|
+
r"""
|
|
99
|
+
This class represents a (symbolic) quotient of an isogeny divided by an integer.
|
|
100
|
+
|
|
101
|
+
EXAMPLES::
|
|
102
|
+
|
|
103
|
+
sage: from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional
|
|
104
|
+
sage: phi = EllipticCurve([1,1]).scalar_multiplication(-2)
|
|
105
|
+
sage: EllipticCurveHom_fractional(phi, 2)
|
|
106
|
+
Fractional elliptic-curve morphism of degree 1:
|
|
107
|
+
Numerator: Scalar-multiplication endomorphism [-2]
|
|
108
|
+
of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
|
|
109
|
+
Denominator: 2
|
|
110
|
+
sage: EllipticCurveHom_fractional(phi, 3)
|
|
111
|
+
Traceback (most recent call last):
|
|
112
|
+
...
|
|
113
|
+
ValueError: Scalar-multiplication endomorphism [-2]
|
|
114
|
+
of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
|
|
115
|
+
is not divisible by 3
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def __init__(self, phi, d, *, check=True) -> None:
|
|
119
|
+
r"""
|
|
120
|
+
Construct a (symbolic) quotient of an isogeny divided by an integer.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional
|
|
125
|
+
sage: phi = EllipticCurve(GF(11), [1,1]).scalar_multiplication(-3)
|
|
126
|
+
sage: EllipticCurveHom_fractional(phi, 3)
|
|
127
|
+
Fractional elliptic-curve morphism of degree 1:
|
|
128
|
+
Numerator: Scalar-multiplication endomorphism [-3]
|
|
129
|
+
of Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11
|
|
130
|
+
Denominator: 3
|
|
131
|
+
"""
|
|
132
|
+
if not isinstance(phi, EllipticCurveHom):
|
|
133
|
+
raise TypeError('not an elliptic-curve morphism')
|
|
134
|
+
|
|
135
|
+
d = ZZ(d)
|
|
136
|
+
if d < 0:
|
|
137
|
+
phi = -phi
|
|
138
|
+
d = -d
|
|
139
|
+
if not d:
|
|
140
|
+
raise ZeroDivisionError('cannot divide isogeny by zero')
|
|
141
|
+
|
|
142
|
+
if check:
|
|
143
|
+
if not (d**2).divides(phi.degree()):
|
|
144
|
+
raise ValueError(f'{phi} is not divisible by {d}')
|
|
145
|
+
|
|
146
|
+
E = phi.domain()
|
|
147
|
+
for l, e in d.factor():
|
|
148
|
+
F = E.division_field(l**e)
|
|
149
|
+
EE = E.change_ring(F)
|
|
150
|
+
|
|
151
|
+
psi = E.division_polynomial(l**e).radical()
|
|
152
|
+
psi //= psi.gcd(E.division_polynomial(l**(e-1)))
|
|
153
|
+
if psi.degree() < l**2//2:
|
|
154
|
+
assert l == E.base_field().characteristic()
|
|
155
|
+
if psi.is_one():
|
|
156
|
+
# supersingular, hence [p] is the only p^2-isogeny up to isomorphism
|
|
157
|
+
continue
|
|
158
|
+
# ordinary, hence [p] is Frobenius times its dual
|
|
159
|
+
insep = phi.inseparable_degree().valuation(l)
|
|
160
|
+
sep = phi.degree().valuation(l) - insep
|
|
161
|
+
if sep < e or insep < e:
|
|
162
|
+
raise ValueError(f'{phi} is not divisible by {l**e}')
|
|
163
|
+
continue
|
|
164
|
+
|
|
165
|
+
P, Q = _torsion_gens(E, EE, l, e, psi=psi)
|
|
166
|
+
|
|
167
|
+
if phi._eval(P) or phi._eval(Q):
|
|
168
|
+
raise ValueError(f'{phi} is not divisible by {l**e}')
|
|
169
|
+
|
|
170
|
+
self._phi = phi
|
|
171
|
+
self._d = d
|
|
172
|
+
self._degree = self._phi.degree() // d**2
|
|
173
|
+
self._domain = phi.domain()
|
|
174
|
+
self._codomain = phi.codomain()
|
|
175
|
+
EllipticCurveHom.__init__(self, self._domain, self._codomain)
|
|
176
|
+
|
|
177
|
+
def _call_(self, P):
|
|
178
|
+
r"""
|
|
179
|
+
Evaluate this fractional elliptic-curve morphism at a point.
|
|
180
|
+
|
|
181
|
+
EXAMPLES::
|
|
182
|
+
|
|
183
|
+
sage: E = EllipticCurve(GF(13), [9,0])
|
|
184
|
+
sage: pi = E.frobenius_isogeny()
|
|
185
|
+
sage: phi = (1 + pi) / 2
|
|
186
|
+
sage: phi.degree()
|
|
187
|
+
2
|
|
188
|
+
sage: P, Q = E(6,7), E(2, 0)
|
|
189
|
+
sage: phi(P)
|
|
190
|
+
(4 : 3 : 1)
|
|
191
|
+
sage: phi(Q)
|
|
192
|
+
(0 : 0 : 1)
|
|
193
|
+
"""
|
|
194
|
+
return self._eval(P)
|
|
195
|
+
|
|
196
|
+
def _eval(self, P):
|
|
197
|
+
r"""
|
|
198
|
+
Less strict evaluation method for internal use.
|
|
199
|
+
|
|
200
|
+
In particular, this can be used to evaluate ``self`` at a
|
|
201
|
+
point defined over an extension field.
|
|
202
|
+
|
|
203
|
+
INPUT: a sequence of 3 coordinates defining a point on ``self``
|
|
204
|
+
|
|
205
|
+
OUTPUT: the result of evaluating ``self`` at the given point
|
|
206
|
+
|
|
207
|
+
EXAMPLES::
|
|
208
|
+
|
|
209
|
+
sage: E = EllipticCurve(GF(13), [9,0])
|
|
210
|
+
sage: pi = E.frobenius_isogeny()
|
|
211
|
+
sage: phi = (1 + pi) / 2
|
|
212
|
+
sage: phi.degree()
|
|
213
|
+
2
|
|
214
|
+
sage: EE = E.change_ring(GF(13^3))
|
|
215
|
+
sage: EE.base_field().inject_variables()
|
|
216
|
+
Defining z3
|
|
217
|
+
sage: P = EE(4*z3^2 + 11*z3, 8*z3^2 + 11*z3 + 8)
|
|
218
|
+
sage: Q = EE(z3^2 + 7*z3 + 6, 3*z3^2 + 7*z3 + 10)
|
|
219
|
+
sage: phi._eval(P)
|
|
220
|
+
(9*z3^2 + 6*z3 + 6 : 4*z3^2 + 9*z3 + 3 : 1)
|
|
221
|
+
sage: phi._eval(Q)
|
|
222
|
+
(z3^2 + 9*z3 : 10*z3^2 + 6*z3 + 10 : 1)
|
|
223
|
+
"""
|
|
224
|
+
if self._domain.defining_polynomial()(*P):
|
|
225
|
+
raise ValueError(f'{P} not on {self._domain}')
|
|
226
|
+
k = Sequence(P).universe()
|
|
227
|
+
|
|
228
|
+
if not P:
|
|
229
|
+
return self._codomain.base_extend(k).zero()
|
|
230
|
+
|
|
231
|
+
# TODO this should really be a "divide point by possibly
|
|
232
|
+
# extending the base field" method
|
|
233
|
+
F = k
|
|
234
|
+
n = P.order()
|
|
235
|
+
m = self._d.prime_to_m_part(n)
|
|
236
|
+
P *= m.inverse_mod(n)
|
|
237
|
+
for q, e in (self._d//m).factor():
|
|
238
|
+
for _ in range(e):
|
|
239
|
+
f = P.division_points(q, poly_only=True)
|
|
240
|
+
try:
|
|
241
|
+
f.any_root(assume_squarefree=True)
|
|
242
|
+
except ValueError:
|
|
243
|
+
g = f.factor()[0][0]
|
|
244
|
+
F = F.extension(g.degree())
|
|
245
|
+
g.any_root(ring=F)
|
|
246
|
+
P = P.change_ring(F).division_points(q)[0]
|
|
247
|
+
|
|
248
|
+
Q = self._phi._eval(P).change_ring(k)
|
|
249
|
+
|
|
250
|
+
return self._codomain.base_extend(k)(*Q)
|
|
251
|
+
|
|
252
|
+
def _repr_(self) -> str:
|
|
253
|
+
r"""
|
|
254
|
+
Return a description of this fractional elliptic-curve morphism.
|
|
255
|
+
|
|
256
|
+
EXAMPLES::
|
|
257
|
+
|
|
258
|
+
sage: E = EllipticCurve(GF(13), [9,0])
|
|
259
|
+
sage: pi = E.frobenius_isogeny()
|
|
260
|
+
sage: (1 + pi) / 2
|
|
261
|
+
Fractional elliptic-curve morphism of degree 2:
|
|
262
|
+
Numerator: Sum morphism:
|
|
263
|
+
From: Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 13
|
|
264
|
+
To: Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 13
|
|
265
|
+
Via: (Scalar-multiplication endomorphism [1]
|
|
266
|
+
of Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 13,
|
|
267
|
+
Frobenius endomorphism of degree 13:
|
|
268
|
+
From: Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 13
|
|
269
|
+
To: Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 13)
|
|
270
|
+
Denominator: 2
|
|
271
|
+
"""
|
|
272
|
+
return f'Fractional elliptic-curve morphism of degree {self._degree}:' \
|
|
273
|
+
f'\n Numerator: {self._phi}' \
|
|
274
|
+
f'\n Denominator: {self._d}'
|
|
275
|
+
|
|
276
|
+
@cached_method
|
|
277
|
+
def to_isogeny_chain(self):
|
|
278
|
+
r"""
|
|
279
|
+
Convert this fractional elliptic-curve morphism into a (non-fractional)
|
|
280
|
+
:class:`~sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite`
|
|
281
|
+
object representing the same morphism.
|
|
282
|
+
|
|
283
|
+
EXAMPLES::
|
|
284
|
+
|
|
285
|
+
sage: p = 419
|
|
286
|
+
sage: E = EllipticCurve(GF(p^2), [1,0])
|
|
287
|
+
sage: iota = E.automorphisms()[2] # sqrt(-1)
|
|
288
|
+
sage: pi = E.frobenius_isogeny() # sqrt(-p)
|
|
289
|
+
sage: endo = (iota + pi) / 2
|
|
290
|
+
sage: endo.degree()
|
|
291
|
+
105
|
|
292
|
+
sage: endo.to_isogeny_chain()
|
|
293
|
+
Composite morphism of degree 105 = 1*3*5*7:
|
|
294
|
+
From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2
|
|
295
|
+
To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2
|
|
296
|
+
sage: endo.to_isogeny_chain() == endo
|
|
297
|
+
True
|
|
298
|
+
"""
|
|
299
|
+
E = self._domain
|
|
300
|
+
|
|
301
|
+
ker = []
|
|
302
|
+
insep = 0
|
|
303
|
+
for l, e in self._phi.degree().factor():
|
|
304
|
+
F = E.division_field(l**e)
|
|
305
|
+
EE = E.change_ring(F)
|
|
306
|
+
|
|
307
|
+
psi = E.division_polynomial(l**e).radical()
|
|
308
|
+
psi //= psi.gcd(E.division_polynomial(l**(e-1)))
|
|
309
|
+
if psi.degree() < l**2//2:
|
|
310
|
+
assert l == E.base_field().characteristic()
|
|
311
|
+
if psi.is_one():
|
|
312
|
+
# supersingular, hence [p] is the only p^2-isogeny up to isomorphism
|
|
313
|
+
insep += 2*self._d.valuation(l)
|
|
314
|
+
else:
|
|
315
|
+
# ordinary, hence [p] is Frobenius times its dual
|
|
316
|
+
insep += self._d.valuation(l)
|
|
317
|
+
ker.append(self._d.p_primary_part(l) * EE.lift_x(psi.any_root(ring=F)))
|
|
318
|
+
continue
|
|
319
|
+
|
|
320
|
+
P, Q = _torsion_gens(E, EE, l, e, psi=psi)
|
|
321
|
+
if self.is_endomorphism():
|
|
322
|
+
RS = None
|
|
323
|
+
else:
|
|
324
|
+
RS = _torsion_gens(self._codomain, self._codomain.change_ring(F), l, e)
|
|
325
|
+
|
|
326
|
+
mat = self._phi.matrix_on_subgroup((P, Q), RS)
|
|
327
|
+
for row in filter(bool, self._d.p_primary_part(l) * mat.left_kernel_matrix()):
|
|
328
|
+
K = sum(ZZ(c)*T for c, T in zip(row, (P, Q)))
|
|
329
|
+
K.set_order(multiple=l**e)
|
|
330
|
+
assert self._eval(K) == 0
|
|
331
|
+
ker.append(K)
|
|
332
|
+
|
|
333
|
+
from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite
|
|
334
|
+
chain = EllipticCurveHom_composite(E, [])
|
|
335
|
+
ker = ker[::-1]
|
|
336
|
+
while ker:
|
|
337
|
+
if not (P := ker.pop()):
|
|
338
|
+
continue
|
|
339
|
+
(l, e), = P.order().factor()
|
|
340
|
+
K = l**(e-1)*P
|
|
341
|
+
if e > 1:
|
|
342
|
+
ker.append(P)
|
|
343
|
+
poly = E.kernel_polynomial_from_point(K, algorithm='basic') # FIXME algorithm='basic' is a workaround for #34907
|
|
344
|
+
step = E.isogeny(poly)
|
|
345
|
+
chain = step * chain
|
|
346
|
+
ker = [step._eval(T) for T in ker]
|
|
347
|
+
E = chain.codomain()
|
|
348
|
+
|
|
349
|
+
for iso in E.isomorphisms(self._codomain):
|
|
350
|
+
if self.scaling_factor() == iso.scaling_factor() * chain.scaling_factor():
|
|
351
|
+
break
|
|
352
|
+
else:
|
|
353
|
+
assert False, 'bug in converting fractional isogeny to isogeny chain'
|
|
354
|
+
|
|
355
|
+
return iso * chain
|
|
356
|
+
|
|
357
|
+
# EllipticCurveHom methods
|
|
358
|
+
|
|
359
|
+
@staticmethod
|
|
360
|
+
def _composition_impl(left, right):
|
|
361
|
+
r"""
|
|
362
|
+
Specialized composition method for fractional elliptic-curve morphisms.
|
|
363
|
+
|
|
364
|
+
TESTS::
|
|
365
|
+
|
|
366
|
+
sage: E = EllipticCurve(GF(419), [-1,0])
|
|
367
|
+
sage: pi = E.frobenius_isogeny()
|
|
368
|
+
sage: endo = (1 + pi) / 2
|
|
369
|
+
sage: 12 * endo
|
|
370
|
+
Composite morphism of degree 15120 = 420*36:
|
|
371
|
+
From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
372
|
+
To: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
|
|
373
|
+
"""
|
|
374
|
+
from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar
|
|
375
|
+
if isinstance(left, EllipticCurveHom_scalar):
|
|
376
|
+
left, right = right, left
|
|
377
|
+
if isinstance(left, EllipticCurveHom_fractional) and isinstance(right, EllipticCurveHom_scalar):
|
|
378
|
+
r = right._m / left._d
|
|
379
|
+
num, den = r.numerator(), r.denominator()
|
|
380
|
+
if num.is_one():
|
|
381
|
+
f = left._phi
|
|
382
|
+
elif (-num).is_one():
|
|
383
|
+
f = -left._phi
|
|
384
|
+
else:
|
|
385
|
+
f = num * left._phi
|
|
386
|
+
if den.is_one():
|
|
387
|
+
return f
|
|
388
|
+
return EllipticCurveHom_fractional(f, den)
|
|
389
|
+
return NotImplemented
|
|
390
|
+
|
|
391
|
+
@staticmethod
|
|
392
|
+
def _comparison_impl(left, right, op):
|
|
393
|
+
r"""
|
|
394
|
+
Compare a fractional elliptic-curve morphism to another elliptic-curve morphism.
|
|
395
|
+
|
|
396
|
+
Called by :meth:`EllipticCurveHom._richcmp_`.
|
|
397
|
+
|
|
398
|
+
TESTS::
|
|
399
|
+
|
|
400
|
+
sage: E = EllipticCurve(GF(419), [-1,0])
|
|
401
|
+
sage: pi = E.frobenius_isogeny()
|
|
402
|
+
sage: endo = (1 + pi) / 2
|
|
403
|
+
sage: 2 * endo - 1 == pi
|
|
404
|
+
True
|
|
405
|
+
sage: 1 - 2 * endo == pi
|
|
406
|
+
False
|
|
407
|
+
"""
|
|
408
|
+
assert isinstance(left, EllipticCurveHom_fractional) or isinstance(right, EllipticCurveHom_fractional)
|
|
409
|
+
if isinstance(left, EllipticCurveHom_fractional):
|
|
410
|
+
right = left._d * right
|
|
411
|
+
left = left._phi
|
|
412
|
+
if isinstance(right, EllipticCurveHom_fractional):
|
|
413
|
+
left = right._d * left
|
|
414
|
+
right = right._phi
|
|
415
|
+
return EllipticCurveHom._richcmp_(left, right, op)
|
|
416
|
+
|
|
417
|
+
def rational_maps(self):
|
|
418
|
+
r"""
|
|
419
|
+
Return the pair of explicit rational maps defining this fractional isogeny.
|
|
420
|
+
|
|
421
|
+
EXAMPLES::
|
|
422
|
+
|
|
423
|
+
sage: E = EllipticCurve(GF(419), [1,0])
|
|
424
|
+
sage: phi = E.isogeny(E(185, 73)); phi.rational_maps()
|
|
425
|
+
((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155),
|
|
426
|
+
(x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
|
|
427
|
+
sage: ((phi + phi) / 2).rational_maps()
|
|
428
|
+
((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155),
|
|
429
|
+
(x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
|
|
430
|
+
"""
|
|
431
|
+
return self.to_isogeny_chain().rational_maps()
|
|
432
|
+
|
|
433
|
+
def x_rational_map(self):
|
|
434
|
+
r"""
|
|
435
|
+
Return the `x`-coordinate rational map of this fractional isogeny.
|
|
436
|
+
|
|
437
|
+
EXAMPLES::
|
|
438
|
+
|
|
439
|
+
sage: E = EllipticCurve(GF(419), [1,0])
|
|
440
|
+
sage: phi = E.isogeny(E(185, 73)); phi.x_rational_map()
|
|
441
|
+
(x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
|
|
442
|
+
sage: ((phi + phi) / 2).x_rational_map()
|
|
443
|
+
(x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
|
|
444
|
+
"""
|
|
445
|
+
return self.to_isogeny_chain().x_rational_map()
|
|
446
|
+
|
|
447
|
+
def kernel_polynomial(self):
|
|
448
|
+
r"""
|
|
449
|
+
Return the kernel polynomial of this fractional isogeny.
|
|
450
|
+
|
|
451
|
+
EXAMPLES::
|
|
452
|
+
|
|
453
|
+
sage: E = EllipticCurve(GF(419), [1,0])
|
|
454
|
+
sage: phi = E.isogeny(E(185, 73)); phi.kernel_polynomial()
|
|
455
|
+
x^2 + 304*x + 39
|
|
456
|
+
sage: ((phi + phi) / 2).kernel_polynomial()
|
|
457
|
+
x^2 + 304*x + 39
|
|
458
|
+
"""
|
|
459
|
+
return self.to_isogeny_chain().kernel_polynomial()
|
|
460
|
+
|
|
461
|
+
@cached_method
|
|
462
|
+
def dual(self):
|
|
463
|
+
r"""
|
|
464
|
+
Return the dual of this fractional isogeny.
|
|
465
|
+
|
|
466
|
+
EXAMPLES::
|
|
467
|
+
|
|
468
|
+
sage: E = EllipticCurve(GF(419), [1,0])
|
|
469
|
+
sage: phi = E.isogeny(E(185, 73))
|
|
470
|
+
sage: ((phi + phi) / 2).dual() == phi.dual()
|
|
471
|
+
True
|
|
472
|
+
"""
|
|
473
|
+
psi = EllipticCurveHom_fractional(self._phi.dual(), self._d)
|
|
474
|
+
psi.dual.set_cache(self)
|
|
475
|
+
return psi
|
|
476
|
+
|
|
477
|
+
def formal(self, *args):
|
|
478
|
+
r"""
|
|
479
|
+
Return the formal isogeny corresponding to this fractional
|
|
480
|
+
isogeny as a power series in the variable `t=-x/y` on the
|
|
481
|
+
domain curve.
|
|
482
|
+
|
|
483
|
+
EXAMPLES::
|
|
484
|
+
|
|
485
|
+
sage: E = EllipticCurve(GF(419), [-1,0])
|
|
486
|
+
sage: pi = E.frobenius_isogeny()
|
|
487
|
+
sage: ((1 + pi) / 2).formal()
|
|
488
|
+
210*t + 26*t^5 + 254*t^9 + 227*t^13 + 36*t^17 + 74*t^21 + O(t^23)
|
|
489
|
+
"""
|
|
490
|
+
return self.to_isogeny_chain().formal(*args)
|
|
491
|
+
|
|
492
|
+
def scaling_factor(self):
|
|
493
|
+
r"""
|
|
494
|
+
Return the Weierstrass scaling factor associated to this
|
|
495
|
+
fractional isogeny.
|
|
496
|
+
|
|
497
|
+
The scaling factor is the constant `u` (in the base field)
|
|
498
|
+
such that `\varphi^* \omega_2 = u \omega_1`, where
|
|
499
|
+
`\varphi: E_1\to E_2` is this morphism and `\omega_i` are
|
|
500
|
+
the standard Weierstrass differentials on `E_i` defined by
|
|
501
|
+
`\mathrm dx/(2y+a_1x+a_3)`.
|
|
502
|
+
|
|
503
|
+
EXAMPLES::
|
|
504
|
+
|
|
505
|
+
sage: E = EllipticCurve(GF(419), [-1,0])
|
|
506
|
+
sage: pi = E.frobenius_isogeny()
|
|
507
|
+
sage: ((1 + pi) / 2).scaling_factor()
|
|
508
|
+
210
|
|
509
|
+
"""
|
|
510
|
+
# FIXME this can crash when p | d
|
|
511
|
+
return self._phi.scaling_factor() / self._d
|
|
512
|
+
|
|
513
|
+
def inseparable_degree(self):
|
|
514
|
+
r"""
|
|
515
|
+
Return the inseparable degree of this morphism.
|
|
516
|
+
|
|
517
|
+
EXAMPLES::
|
|
518
|
+
|
|
519
|
+
sage: E = EllipticCurve(GF(419), [-1,0])
|
|
520
|
+
sage: pi = E.frobenius_isogeny()
|
|
521
|
+
sage: ((1 + pi) / 2).inseparable_degree()
|
|
522
|
+
1
|
|
523
|
+
sage: E = EllipticCurve(GF(419), [-1,0])
|
|
524
|
+
sage: pi = E.frobenius_isogeny()
|
|
525
|
+
sage: ((3*pi - pi) / 2).inseparable_degree()
|
|
526
|
+
419
|
|
527
|
+
"""
|
|
528
|
+
return self._phi.inseparable_degree() / self._domain.scalar_multiplication(self._d).inseparable_degree()
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
def _torsion_gens(E, EE, l, e, psi=None):
|
|
532
|
+
if psi is None:
|
|
533
|
+
psi = E.division_polynomial(l**e).radical()
|
|
534
|
+
psi //= psi.gcd(E.division_polynomial(l**(e-1)))
|
|
535
|
+
|
|
536
|
+
xs = iter(psi.roots(ring=EE.base_field(), multiplicities=False))
|
|
537
|
+
P = EE.lift_x(next(xs))
|
|
538
|
+
while True:
|
|
539
|
+
Q = EE.lift_x(next(xs))
|
|
540
|
+
if not (P.weil_pairing(Q, l**e)**(l**(e-1))).is_one():
|
|
541
|
+
break
|
|
542
|
+
else:
|
|
543
|
+
assert False, f'bug in finding {l**e}-torsion basis'
|
|
544
|
+
return P, Q
|