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,200 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
"""
|
|
3
|
+
Morphism to bring a genus-one curve into Weierstrass form
|
|
4
|
+
|
|
5
|
+
You should use
|
|
6
|
+
:func:`~sage.schemes.elliptic_curves.constructor.EllipticCurve_from_cubic`
|
|
7
|
+
or
|
|
8
|
+
:func:`~sage.schemes.elliptic_curves.constructor.EllipticCurve_from_curve`
|
|
9
|
+
to construct the transformation starting with a cubic or with a genus
|
|
10
|
+
one curve.
|
|
11
|
+
|
|
12
|
+
EXAMPLES::
|
|
13
|
+
|
|
14
|
+
sage: R.<u,v,w> = QQ[]
|
|
15
|
+
sage: f = EllipticCurve_from_cubic(u^3 + v^3 + w^3, [1,-1,0], morphism=True); f
|
|
16
|
+
Scheme morphism:
|
|
17
|
+
From: Projective Plane Curve over Rational Field defined by u^3 + v^3 + w^3
|
|
18
|
+
To: Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field
|
|
19
|
+
Defn: Defined on coordinates by sending (u : v : w) to
|
|
20
|
+
(-w : 3*u : 1/3*u + 1/3*v)
|
|
21
|
+
|
|
22
|
+
sage: finv = f.inverse(); finv
|
|
23
|
+
Scheme morphism:
|
|
24
|
+
From: Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field
|
|
25
|
+
To: Projective Plane Curve over Rational Field defined by u^3 + v^3 + w^3
|
|
26
|
+
Defn: Defined on coordinates by sending (x : y : z) to
|
|
27
|
+
(1/3*y : -1/3*y + 3*z : -x)
|
|
28
|
+
|
|
29
|
+
sage: (u^3 + v^3 + w^3)(f.inverse().defining_polynomials()) * f.inverse().post_rescaling()
|
|
30
|
+
-x^3 + y^2*z - 9*y*z^2 + 27*z^3
|
|
31
|
+
|
|
32
|
+
sage: E = finv.domain()
|
|
33
|
+
sage: E.defining_polynomial()(f.defining_polynomials()) * f.post_rescaling()
|
|
34
|
+
u^3 + v^3 + w^3
|
|
35
|
+
|
|
36
|
+
sage: f([1,-1,0])
|
|
37
|
+
(0 : 1 : 0)
|
|
38
|
+
sage: f([1,0,-1])
|
|
39
|
+
(3 : 9 : 1)
|
|
40
|
+
sage: f([0,1,-1])
|
|
41
|
+
(3 : 0 : 1)
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
##############################################################################
|
|
45
|
+
# Copyright (C) 2013 Volker Braun <vbraun.name@gmail.com>
|
|
46
|
+
#
|
|
47
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
48
|
+
#
|
|
49
|
+
# The full text of the GPL is available at:
|
|
50
|
+
#
|
|
51
|
+
# http://www.gnu.org/licenses/
|
|
52
|
+
##############################################################################
|
|
53
|
+
|
|
54
|
+
from sage.schemes.generic.morphism import SchemeMorphism_polynomial
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class WeierstrassTransformation(SchemeMorphism_polynomial):
|
|
58
|
+
|
|
59
|
+
def __init__(self, domain, codomain, defining_polynomials, post_multiplication):
|
|
60
|
+
r"""
|
|
61
|
+
A morphism of a genus-one curve to/from the Weierstrass form.
|
|
62
|
+
|
|
63
|
+
INPUT:
|
|
64
|
+
|
|
65
|
+
- ``domain``, ``codomain`` -- two schemes, one of which is an
|
|
66
|
+
elliptic curve
|
|
67
|
+
|
|
68
|
+
- ``defining_polynomials`` -- triplet of polynomials that
|
|
69
|
+
define the transformation
|
|
70
|
+
|
|
71
|
+
- ``post_multiplication`` -- a polynomial to homogeneously
|
|
72
|
+
rescale after substituting the defining polynomials
|
|
73
|
+
|
|
74
|
+
EXAMPLES::
|
|
75
|
+
|
|
76
|
+
sage: P2.<u,v,w> = ProjectiveSpace(2,QQ)
|
|
77
|
+
sage: C = P2.subscheme(u^3 + v^3 + w^3)
|
|
78
|
+
sage: E = EllipticCurve([2, -1, -1/3, 1/3, -1/27])
|
|
79
|
+
sage: from sage.schemes.elliptic_curves.weierstrass_transform import WeierstrassTransformation
|
|
80
|
+
sage: f = WeierstrassTransformation(C, E, [w, -v-w, -3*u-3*v], 1); f
|
|
81
|
+
Scheme morphism:
|
|
82
|
+
From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
|
|
83
|
+
u^3 + v^3 + w^3
|
|
84
|
+
To: Elliptic Curve defined by y^2 + 2*x*y - 1/3*y = x^3 - x^2 + 1/3*x - 1/27
|
|
85
|
+
over Rational Field
|
|
86
|
+
Defn: Defined on coordinates by sending (u : v : w) to
|
|
87
|
+
(w : -v - w : -3*u - 3*v)
|
|
88
|
+
|
|
89
|
+
sage: f([-1, 1, 0])
|
|
90
|
+
(0 : 1 : 0)
|
|
91
|
+
sage: f([-1, 0, 1])
|
|
92
|
+
(1/3 : -1/3 : 1)
|
|
93
|
+
sage: f([ 0,-1, 1])
|
|
94
|
+
(1/3 : 0 : 1)
|
|
95
|
+
|
|
96
|
+
sage: A2.<a,b> = AffineSpace(2,QQ)
|
|
97
|
+
sage: C = A2.subscheme(a^3 + b^3 + 1)
|
|
98
|
+
sage: f = WeierstrassTransformation(C, E, [1, -b-1, -3*a-3*b], 1); f
|
|
99
|
+
Scheme morphism:
|
|
100
|
+
From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
|
|
101
|
+
a^3 + b^3 + 1
|
|
102
|
+
To: Elliptic Curve defined by y^2 + 2*x*y - 1/3*y
|
|
103
|
+
= x^3 - x^2 + 1/3*x - 1/27 over Rational Field
|
|
104
|
+
Defn: Defined on coordinates by sending (a, b) to
|
|
105
|
+
(1 : -b - 1 : -3*a - 3*b)
|
|
106
|
+
sage: f([-1,0])
|
|
107
|
+
(1/3 : -1/3 : 1)
|
|
108
|
+
sage: f([0,-1])
|
|
109
|
+
(1/3 : 0 : 1)
|
|
110
|
+
"""
|
|
111
|
+
Hom = domain.Hom(codomain)
|
|
112
|
+
super().__init__(Hom, defining_polynomials)
|
|
113
|
+
self._post = post_multiplication
|
|
114
|
+
|
|
115
|
+
def post_rescaling(self):
|
|
116
|
+
"""
|
|
117
|
+
Return the homogeneous rescaling to apply after the coordinate
|
|
118
|
+
substitution.
|
|
119
|
+
|
|
120
|
+
OUTPUT: a polynomial; see the example below
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: R.<a,b,c> = QQ[]
|
|
125
|
+
sage: cubic = a^3+7*b^3+64*c^3
|
|
126
|
+
sage: P = [2,2,-1]
|
|
127
|
+
sage: f = EllipticCurve_from_cubic(cubic, P, morphism=True).inverse()
|
|
128
|
+
sage: f.post_rescaling()
|
|
129
|
+
-1/7
|
|
130
|
+
|
|
131
|
+
So here is what it does. If we just plug in the coordinate
|
|
132
|
+
transformation, we get the defining polynomial up to
|
|
133
|
+
scale. This method returns the overall rescaling of the
|
|
134
|
+
equation to bring the result into the standard form::
|
|
135
|
+
|
|
136
|
+
sage: cubic(f.defining_polynomials())
|
|
137
|
+
7*x^3 - 7*y^2*z + 1806336*y*z^2 - 155373797376*z^3
|
|
138
|
+
sage: cubic(f.defining_polynomials()) * f.post_rescaling()
|
|
139
|
+
-x^3 + y^2*z - 258048*y*z^2 + 22196256768*z^3
|
|
140
|
+
"""
|
|
141
|
+
return self._post
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def WeierstrassTransformationWithInverse(domain, codomain,
|
|
145
|
+
defining_polynomials, post_multiplication,
|
|
146
|
+
inv_defining_polynomials, inv_post_multiplication):
|
|
147
|
+
"""
|
|
148
|
+
Construct morphism of a genus-one curve to/from the Weierstrass
|
|
149
|
+
form with its inverse.
|
|
150
|
+
|
|
151
|
+
EXAMPLES::
|
|
152
|
+
|
|
153
|
+
sage: R.<u,v,w> = QQ[]
|
|
154
|
+
sage: f = EllipticCurve_from_cubic(u^3 + v^3 + w^3, [1,-1,0], morphism=True); f
|
|
155
|
+
Scheme morphism:
|
|
156
|
+
From: Projective Plane Curve over Rational Field defined by u^3 + v^3 + w^3
|
|
157
|
+
To: Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field
|
|
158
|
+
Defn: Defined on coordinates by sending (u : v : w) to
|
|
159
|
+
(-w : 3*u : 1/3*u + 1/3*v)
|
|
160
|
+
|
|
161
|
+
Scheme morphism:
|
|
162
|
+
From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
|
|
163
|
+
u^3 + v^3 + w^3
|
|
164
|
+
To: Elliptic Curve defined by y^2 + 2*x*y + 1/3*y
|
|
165
|
+
= x^3 - x^2 - 1/3*x - 1/27 over Rational Field
|
|
166
|
+
Defn: Defined on coordinates by sending (u : v : w) to
|
|
167
|
+
(-w : -v + w : 3*u + 3*v)
|
|
168
|
+
"""
|
|
169
|
+
fwd = WeierstrassTransformationWithInverse_class(
|
|
170
|
+
domain, codomain, defining_polynomials, post_multiplication)
|
|
171
|
+
inv = WeierstrassTransformationWithInverse_class(
|
|
172
|
+
codomain, domain, inv_defining_polynomials, inv_post_multiplication)
|
|
173
|
+
fwd._inverse = inv
|
|
174
|
+
inv._inverse = fwd
|
|
175
|
+
return fwd
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class WeierstrassTransformationWithInverse_class(WeierstrassTransformation):
|
|
179
|
+
|
|
180
|
+
def inverse(self):
|
|
181
|
+
"""
|
|
182
|
+
Return the inverse.
|
|
183
|
+
|
|
184
|
+
OUTPUT:
|
|
185
|
+
|
|
186
|
+
A morphism in the opposite direction. This may be a rational
|
|
187
|
+
inverse or an analytic inverse.
|
|
188
|
+
|
|
189
|
+
EXAMPLES::
|
|
190
|
+
|
|
191
|
+
sage: R.<u,v,w> = QQ[]
|
|
192
|
+
sage: f = EllipticCurve_from_cubic(u^3 + v^3 + w^3, [1,-1,0], morphism=True)
|
|
193
|
+
sage: f.inverse()
|
|
194
|
+
Scheme morphism:
|
|
195
|
+
From: Elliptic Curve defined by y^2 - 9*y = x^3 - 27 over Rational Field
|
|
196
|
+
To: Projective Plane Curve over Rational Field defined by u^3 + v^3 + w^3
|
|
197
|
+
Defn: Defined on coordinates by sending (x : y : z) to
|
|
198
|
+
(1/3*y : -1/3*y + 3*z : -x)
|
|
199
|
+
"""
|
|
200
|
+
return self._inverse
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve
|
|
3
|
+
from sage.schemes.hyperelliptic_curves.kummer_surface import KummerSurface
|
|
4
|
+
from sage.schemes.hyperelliptic_curves.mestre import (
|
|
5
|
+
Mestre_conic, HyperellipticCurve_from_invariants)
|
|
6
|
+
from sage.schemes.hyperelliptic_curves import monsky_washnitzer
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
"""
|
|
3
|
+
Hyperelliptic curve constructor
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- David Kohel (2006): initial version
|
|
8
|
+
|
|
9
|
+
- Anna Somoza (2019-04): dynamic class creation
|
|
10
|
+
"""
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
# Copyright (C) 2006 David Kohel <kohel@maths.usyd.edu>
|
|
13
|
+
# 2019 Anna Somoza <anna.somoza.henares@gmail.com>
|
|
14
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
15
|
+
# https://www.gnu.org/licenses/
|
|
16
|
+
# ****************************************************************************
|
|
17
|
+
|
|
18
|
+
from .hyperelliptic_generic import HyperellipticCurve_generic
|
|
19
|
+
from .hyperelliptic_finite_field import HyperellipticCurve_finite_field
|
|
20
|
+
from .hyperelliptic_rational_field import HyperellipticCurve_rational_field
|
|
21
|
+
from .hyperelliptic_padic_field import HyperellipticCurve_padic_field
|
|
22
|
+
from .hyperelliptic_g2 import HyperellipticCurve_g2
|
|
23
|
+
|
|
24
|
+
import sage.rings.abc
|
|
25
|
+
|
|
26
|
+
from sage.rings.finite_rings.finite_field_base import FiniteField
|
|
27
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
28
|
+
from sage.rings.rational_field import RationalField
|
|
29
|
+
from sage.schemes.projective.projective_space import ProjectiveSpace
|
|
30
|
+
from sage.structure.dynamic_class import dynamic_class
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _parse_multivariate_defining_equation(g):
|
|
34
|
+
"""
|
|
35
|
+
Parse a defining equation for a hyperelliptic curve.
|
|
36
|
+
The input `g` should have the form `g(x, y) = y^2 + h(x) y - f(x)`,
|
|
37
|
+
or a constant multiple of that.
|
|
38
|
+
|
|
39
|
+
OUTPUT: tuple (f, h), each of them given as a list of coefficients.
|
|
40
|
+
|
|
41
|
+
TESTS::
|
|
42
|
+
|
|
43
|
+
sage: from sage.schemes.hyperelliptic_curves.constructor import _parse_multivariate_defining_equation
|
|
44
|
+
sage: R.<x,y> = QQ[]
|
|
45
|
+
sage: _parse_multivariate_defining_equation(y^2 + 3*x^2*y - (x^5 + x + 1))
|
|
46
|
+
([1, 1, 0, 0, 0, 1], [0, 0, 3])
|
|
47
|
+
sage: _parse_multivariate_defining_equation(2*y^2 + 3*x^2*y - (x^5 + x + 1))
|
|
48
|
+
([1/2, 1/2, 0, 0, 0, 1/2], [0, 0, 3/2])
|
|
49
|
+
|
|
50
|
+
The variable names are arbitrary::
|
|
51
|
+
|
|
52
|
+
sage: S.<z,t> = GF(13)[]
|
|
53
|
+
sage: _parse_multivariate_defining_equation(2*t^2 + 3*z^2*t - (z^5 + z + 1))
|
|
54
|
+
([7, 7, 0, 0, 0, 7], [0, 0, 8])
|
|
55
|
+
"""
|
|
56
|
+
from sage.rings.polynomial.multi_polynomial import MPolynomial
|
|
57
|
+
if not isinstance(g, MPolynomial):
|
|
58
|
+
raise ValueError("must be a multivariate polynomial")
|
|
59
|
+
|
|
60
|
+
variables = g.variables()
|
|
61
|
+
if len(variables) != 2:
|
|
62
|
+
raise ValueError("must be a polynomial in two variables")
|
|
63
|
+
|
|
64
|
+
y, x = sorted(variables, key=g.degree)
|
|
65
|
+
if g.degree(y) != 2:
|
|
66
|
+
raise ValueError("must be a polynomial of degree 2 in a variable")
|
|
67
|
+
|
|
68
|
+
f = []
|
|
69
|
+
h = []
|
|
70
|
+
for k, v in g:
|
|
71
|
+
dx = v.degree(x)
|
|
72
|
+
dy = v.degree(y)
|
|
73
|
+
if dy == 2:
|
|
74
|
+
if dx != 0:
|
|
75
|
+
raise ValueError(f"cannot have a term y*x^{dx}")
|
|
76
|
+
y2 = k
|
|
77
|
+
elif dy == 1:
|
|
78
|
+
while len(h) <= dx:
|
|
79
|
+
h.append(0)
|
|
80
|
+
h[dx] = k
|
|
81
|
+
else:
|
|
82
|
+
assert dy == 0
|
|
83
|
+
while len(f) <= dx:
|
|
84
|
+
f.append(0)
|
|
85
|
+
f[dx] = -k
|
|
86
|
+
|
|
87
|
+
if not y2.is_one():
|
|
88
|
+
y2_inv = y2.inverse_of_unit()
|
|
89
|
+
f = [c * y2_inv for c in f]
|
|
90
|
+
h = [c * y2_inv for c in h]
|
|
91
|
+
|
|
92
|
+
return f, h
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def HyperellipticCurve(f, h=None, names=None, PP=None, check_squarefree=True):
|
|
96
|
+
r"""
|
|
97
|
+
Return the hyperelliptic curve `y^2 + h y = f`, for
|
|
98
|
+
univariate polynomials `h` and `f`. If `h`
|
|
99
|
+
is not given, then it defaults to 0.
|
|
100
|
+
|
|
101
|
+
INPUT:
|
|
102
|
+
|
|
103
|
+
- ``f`` -- univariate polynomial
|
|
104
|
+
|
|
105
|
+
- ``h`` -- (optional) univariate polynomial
|
|
106
|
+
|
|
107
|
+
- ``names`` -- (default: ``["x","y"]``) names for the coordinate functions
|
|
108
|
+
|
|
109
|
+
- ``check_squarefree`` -- boolean (default: ``True``); test if the input
|
|
110
|
+
defines a hyperelliptic curve when f is homogenized to degree `2g+2` and
|
|
111
|
+
h to degree `g+1` for some `g`
|
|
112
|
+
|
|
113
|
+
.. WARNING::
|
|
114
|
+
|
|
115
|
+
When setting ``check_squarefree=False`` or using a base ring that is
|
|
116
|
+
not a field, the output curves are not to be trusted. For example, the
|
|
117
|
+
output of ``is_singular`` is always ``False``, without this being
|
|
118
|
+
properly tested in that case.
|
|
119
|
+
|
|
120
|
+
.. NOTE::
|
|
121
|
+
|
|
122
|
+
The words "hyperelliptic curve" are normally only used for curves of
|
|
123
|
+
genus at least two, but this class allows more general smooth double
|
|
124
|
+
covers of the projective line (conics and elliptic curves), even though
|
|
125
|
+
the class is not meant for those and some outputs may be incorrect.
|
|
126
|
+
|
|
127
|
+
EXAMPLES:
|
|
128
|
+
|
|
129
|
+
Basic examples::
|
|
130
|
+
|
|
131
|
+
sage: R.<x> = QQ[]
|
|
132
|
+
sage: HyperellipticCurve(x^5 + x + 1)
|
|
133
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x + 1
|
|
134
|
+
sage: HyperellipticCurve(x^19 + x + 1, x - 2)
|
|
135
|
+
Hyperelliptic Curve over Rational Field defined by y^2 + (x - 2)*y = x^19 + x + 1
|
|
136
|
+
|
|
137
|
+
sage: k.<a> = GF(9); R.<x> = k[] # needs sage.rings.finite_rings
|
|
138
|
+
sage: HyperellipticCurve(x^3 + x - 1, x+a) # needs sage.rings.finite_rings
|
|
139
|
+
Hyperelliptic Curve over Finite Field in a of size 3^2
|
|
140
|
+
defined by y^2 + (x + a)*y = x^3 + x + 2
|
|
141
|
+
|
|
142
|
+
Construct from defining polynomial::
|
|
143
|
+
|
|
144
|
+
sage: R.<x,y> = QQ[]
|
|
145
|
+
sage: HyperellipticCurve(y^2 + 3*x^2*y - (x^5 + x + 1))
|
|
146
|
+
Hyperelliptic Curve over Rational Field defined by y^2 + 3*x^2*y = x^5 + x + 1
|
|
147
|
+
|
|
148
|
+
Characteristic two::
|
|
149
|
+
|
|
150
|
+
sage: # needs sage.rings.finite_rings
|
|
151
|
+
sage: P.<x> = GF(8, 'a')[]
|
|
152
|
+
sage: HyperellipticCurve(x^7 + 1, x)
|
|
153
|
+
Hyperelliptic Curve over Finite Field in a of size 2^3
|
|
154
|
+
defined by y^2 + x*y = x^7 + 1
|
|
155
|
+
sage: HyperellipticCurve(x^8 + x^7 + 1, x^4 + 1)
|
|
156
|
+
Hyperelliptic Curve over Finite Field in a of size 2^3
|
|
157
|
+
defined by y^2 + (x^4 + 1)*y = x^8 + x^7 + 1
|
|
158
|
+
sage: HyperellipticCurve(x^8 + 1, x)
|
|
159
|
+
Traceback (most recent call last):
|
|
160
|
+
...
|
|
161
|
+
ValueError: not a hyperelliptic curve: highly singular at infinity
|
|
162
|
+
sage: HyperellipticCurve(x^8 + x^7 + 1, x^4)
|
|
163
|
+
Traceback (most recent call last):
|
|
164
|
+
...
|
|
165
|
+
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
|
|
166
|
+
|
|
167
|
+
sage: F.<t> = PowerSeriesRing(FiniteField(2))
|
|
168
|
+
sage: P.<x> = PolynomialRing(FractionField(F))
|
|
169
|
+
sage: HyperellipticCurve(x^5 + t, x)
|
|
170
|
+
Hyperelliptic Curve over Laurent Series Ring in t over Finite Field of size 2
|
|
171
|
+
defined by y^2 + x*y = x^5 + t
|
|
172
|
+
|
|
173
|
+
We can change the names of the variables in the output::
|
|
174
|
+
|
|
175
|
+
sage: k.<a> = GF(9); R.<x> = k[] # needs sage.rings.finite_rings
|
|
176
|
+
sage: HyperellipticCurve(x^3 + x - 1, x + a, names=['X','Y']) # needs sage.rings.finite_rings
|
|
177
|
+
Hyperelliptic Curve over Finite Field in a of size 3^2
|
|
178
|
+
defined by Y^2 + (X + a)*Y = X^3 + X + 2
|
|
179
|
+
|
|
180
|
+
This class also allows curves of genus zero or one, which are strictly
|
|
181
|
+
speaking not hyperelliptic::
|
|
182
|
+
|
|
183
|
+
sage: P.<x> = QQ[]
|
|
184
|
+
sage: HyperellipticCurve(x^2 + 1)
|
|
185
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^2 + 1
|
|
186
|
+
sage: HyperellipticCurve(x^4 - 1)
|
|
187
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^4 - 1
|
|
188
|
+
sage: HyperellipticCurve(x^3 + 2*x + 2)
|
|
189
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + 2*x + 2
|
|
190
|
+
|
|
191
|
+
Double roots::
|
|
192
|
+
|
|
193
|
+
sage: P.<x> = GF(7)[]
|
|
194
|
+
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))
|
|
195
|
+
Traceback (most recent call last):
|
|
196
|
+
...
|
|
197
|
+
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
|
|
198
|
+
|
|
199
|
+
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)
|
|
200
|
+
Hyperelliptic Curve over Finite Field of size 7 defined by
|
|
201
|
+
y^2 = x^12 + 5*x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^6 + 2*x^4 + 3*x^3 + 6*x^2 + 4*x + 3
|
|
202
|
+
|
|
203
|
+
The input for a (smooth) hyperelliptic curve of genus `g` should not
|
|
204
|
+
contain polynomials of degree greater than `2g+2`. In the following
|
|
205
|
+
example, the hyperelliptic curve has genus 2 and there exists a model
|
|
206
|
+
`y^2 = F` of degree 6, so the model `y^2 + yh = f` of degree 200 is not
|
|
207
|
+
allowed.::
|
|
208
|
+
|
|
209
|
+
sage: P.<x> = QQ[]
|
|
210
|
+
sage: h = x^100
|
|
211
|
+
sage: F = x^6 + 1
|
|
212
|
+
sage: f = F - h^2/4
|
|
213
|
+
sage: HyperellipticCurve(f, h)
|
|
214
|
+
Traceback (most recent call last):
|
|
215
|
+
...
|
|
216
|
+
ValueError: not a hyperelliptic curve: highly singular at infinity
|
|
217
|
+
|
|
218
|
+
sage: HyperellipticCurve(F)
|
|
219
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1
|
|
220
|
+
|
|
221
|
+
An example with a singularity over an inseparable extension of the
|
|
222
|
+
base field::
|
|
223
|
+
|
|
224
|
+
sage: F.<t> = GF(5)[]
|
|
225
|
+
sage: P.<x> = F[]
|
|
226
|
+
sage: HyperellipticCurve(x^5 + t)
|
|
227
|
+
Traceback (most recent call last):
|
|
228
|
+
...
|
|
229
|
+
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
|
|
230
|
+
|
|
231
|
+
Input with integer coefficients creates objects with the integers
|
|
232
|
+
as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).
|
|
233
|
+
In other words, it is checked that the discriminant is nonzero, but it is
|
|
234
|
+
not checked whether the discriminant is a unit in `\ZZ^*`.::
|
|
235
|
+
|
|
236
|
+
sage: P.<x> = ZZ[]
|
|
237
|
+
sage: HyperellipticCurve(3*x^7 + 6*x + 6)
|
|
238
|
+
Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
|
|
239
|
+
|
|
240
|
+
TESTS:
|
|
241
|
+
|
|
242
|
+
Check that `f` can be a constant (see :issue:`15516`)::
|
|
243
|
+
|
|
244
|
+
sage: R.<u> = PolynomialRing(Rationals())
|
|
245
|
+
sage: HyperellipticCurve(-12, u^4 + 7)
|
|
246
|
+
Hyperelliptic Curve over Rational Field defined by y^2 + (x^4 + 7)*y = -12
|
|
247
|
+
|
|
248
|
+
Check that two curves with the same class name have the same class type::
|
|
249
|
+
|
|
250
|
+
sage: # needs sage.rings.finite_rings
|
|
251
|
+
sage: R.<t> = PolynomialRing(GF(next_prime(10^9)))
|
|
252
|
+
sage: C = HyperellipticCurve(t^5 + t + 1)
|
|
253
|
+
sage: C2 = HyperellipticCurve(t^5 + 3*t + 1)
|
|
254
|
+
sage: type(C2) == type(C)
|
|
255
|
+
True
|
|
256
|
+
|
|
257
|
+
Check that the inheritance is correct::
|
|
258
|
+
|
|
259
|
+
sage: # needs sage.rings.finite_rings
|
|
260
|
+
sage: R.<t> = PolynomialRing(GF(next_prime(10^9)))
|
|
261
|
+
sage: C = HyperellipticCurve(t^5 + t + 1)
|
|
262
|
+
sage: type(C).mro()
|
|
263
|
+
[<class 'sage.schemes.hyperelliptic_curves.constructor.HyperellipticCurve_g2_FiniteField_with_category'>,
|
|
264
|
+
<class 'sage.schemes.hyperelliptic_curves.constructor.HyperellipticCurve_g2_FiniteField'>,
|
|
265
|
+
<class 'sage.schemes.hyperelliptic_curves.hyperelliptic_g2.HyperellipticCurve_g2'>,
|
|
266
|
+
<class 'sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field.HyperellipticCurve_finite_field'>,
|
|
267
|
+
<class 'sage.schemes.hyperelliptic_curves.hyperelliptic_generic.HyperellipticCurve_generic'>,
|
|
268
|
+
...]
|
|
269
|
+
"""
|
|
270
|
+
# F is the discriminant; use this for the type check
|
|
271
|
+
# rather than f and h, one of which might be constant.
|
|
272
|
+
if h is None:
|
|
273
|
+
from sage.rings.polynomial.multi_polynomial import MPolynomial
|
|
274
|
+
if isinstance(f, MPolynomial) and len(f.parent().gens()) == 2:
|
|
275
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
276
|
+
P = PolynomialRing(f.base_ring(), 'x')
|
|
277
|
+
f, h = _parse_multivariate_defining_equation(f)
|
|
278
|
+
f, h = P(f), P(h)
|
|
279
|
+
else:
|
|
280
|
+
h = 0
|
|
281
|
+
|
|
282
|
+
F = h**2 + 4 * f
|
|
283
|
+
if not isinstance(F, Polynomial):
|
|
284
|
+
raise TypeError(f"arguments f = {f} and h = {h} must be polynomials")
|
|
285
|
+
P = F.parent()
|
|
286
|
+
f = P(f)
|
|
287
|
+
h = P(h)
|
|
288
|
+
df = f.degree()
|
|
289
|
+
dh_2 = 2 * h.degree()
|
|
290
|
+
if dh_2 < df:
|
|
291
|
+
g = (df - 1) // 2
|
|
292
|
+
else:
|
|
293
|
+
g = (dh_2 - 1) // 2
|
|
294
|
+
if check_squarefree:
|
|
295
|
+
# Assuming we are working over a field, this checks that after
|
|
296
|
+
# resolving the singularity at infinity, we get a smooth double cover
|
|
297
|
+
# of P^1.
|
|
298
|
+
if P(2) == 0:
|
|
299
|
+
# characteristic 2
|
|
300
|
+
if h == 0:
|
|
301
|
+
raise ValueError(
|
|
302
|
+
f"for characteristic 2, argument h = {h} must be nonzero"
|
|
303
|
+
)
|
|
304
|
+
if h[g + 1] == 0 and f[2 * g + 1] ** 2 == f[2 * g + 2] * h[g] ** 2:
|
|
305
|
+
raise ValueError(
|
|
306
|
+
"not a hyperelliptic curve: highly singular at infinity"
|
|
307
|
+
)
|
|
308
|
+
should_be_coprime = [h, f * h.derivative() ** 2 + f.derivative() ** 2]
|
|
309
|
+
else:
|
|
310
|
+
# characteristic not 2
|
|
311
|
+
if F.degree() not in [2 * g + 1, 2 * g + 2]:
|
|
312
|
+
raise ValueError(
|
|
313
|
+
"not a hyperelliptic curve: highly singular at infinity"
|
|
314
|
+
)
|
|
315
|
+
should_be_coprime = [F, F.derivative()]
|
|
316
|
+
try:
|
|
317
|
+
smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree() == 0
|
|
318
|
+
except (AttributeError, NotImplementedError, TypeError):
|
|
319
|
+
try:
|
|
320
|
+
smooth = should_be_coprime[0].resultant(should_be_coprime[1]) != 0
|
|
321
|
+
except (AttributeError, NotImplementedError, TypeError):
|
|
322
|
+
raise NotImplementedError(
|
|
323
|
+
"cannot determine whether "
|
|
324
|
+
f"polynomials {should_be_coprime} have a common root, use "
|
|
325
|
+
"check_squarefree=False to skip this check"
|
|
326
|
+
)
|
|
327
|
+
if not smooth:
|
|
328
|
+
raise ValueError(
|
|
329
|
+
"not a hyperelliptic curve: singularity in the provided affine patch"
|
|
330
|
+
)
|
|
331
|
+
R = P.base_ring()
|
|
332
|
+
PP = ProjectiveSpace(2, R)
|
|
333
|
+
if names is None:
|
|
334
|
+
names = ["x", "y"]
|
|
335
|
+
|
|
336
|
+
bases = []
|
|
337
|
+
cls_name = ["HyperellipticCurve"]
|
|
338
|
+
|
|
339
|
+
# For certain genus we specialise to subclasses with
|
|
340
|
+
# optimised methods
|
|
341
|
+
genus_classes = {2: HyperellipticCurve_g2}
|
|
342
|
+
if g in genus_classes:
|
|
343
|
+
bases.append(genus_classes[g])
|
|
344
|
+
cls_name.append(f"g{g}")
|
|
345
|
+
|
|
346
|
+
# For certain base fields, we specialise to subclasses
|
|
347
|
+
# with special case methods
|
|
348
|
+
fields = [
|
|
349
|
+
("FiniteField", FiniteField, HyperellipticCurve_finite_field),
|
|
350
|
+
("RationalField", RationalField, HyperellipticCurve_rational_field),
|
|
351
|
+
("pAdicField", sage.rings.abc.pAdicField, HyperellipticCurve_padic_field),
|
|
352
|
+
]
|
|
353
|
+
|
|
354
|
+
for name, base_ring_cls, cls in fields:
|
|
355
|
+
if isinstance(R, base_ring_cls):
|
|
356
|
+
bases.append(cls)
|
|
357
|
+
cls_name.append(name)
|
|
358
|
+
break
|
|
359
|
+
|
|
360
|
+
# If no specialised subclasses are identified, we simply use the
|
|
361
|
+
# generic class in the class construction
|
|
362
|
+
if not bases:
|
|
363
|
+
bases = [HyperellipticCurve_generic]
|
|
364
|
+
|
|
365
|
+
# Dynamically build a class from multiple inheritance. Note that
|
|
366
|
+
# all classes we select from are subclasses of HyperellipticCurve_generic
|
|
367
|
+
class_name = "_".join(cls_name)
|
|
368
|
+
cls = dynamic_class(class_name, tuple(bases), doccls=HyperellipticCurve)
|
|
369
|
+
return cls(PP, f, h, names=names, genus=g)
|