passagemath-schemes 10.6.47__cp312-cp312-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
- passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,954 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
"""
|
|
3
|
+
Hyperelliptic curves over a general ring
|
|
4
|
+
|
|
5
|
+
EXAMPLES::
|
|
6
|
+
|
|
7
|
+
sage: P.<x> = GF(5)[]
|
|
8
|
+
sage: f = x^5 - 3*x^4 - 2*x^3 + 6*x^2 + 3*x - 1
|
|
9
|
+
sage: C = HyperellipticCurve(f); C
|
|
10
|
+
Hyperelliptic Curve over Finite Field of size 5
|
|
11
|
+
defined by y^2 = x^5 + 2*x^4 + 3*x^3 + x^2 + 3*x + 4
|
|
12
|
+
|
|
13
|
+
::
|
|
14
|
+
|
|
15
|
+
sage: P.<x> = QQ[]
|
|
16
|
+
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
|
|
17
|
+
sage: C = HyperellipticCurve(f); C
|
|
18
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
|
|
19
|
+
sage: C.genus()
|
|
20
|
+
2
|
|
21
|
+
|
|
22
|
+
sage: D = C.affine_patch(0)
|
|
23
|
+
sage: D.defining_polynomials()[0].parent()
|
|
24
|
+
Multivariate Polynomial Ring in x1, x2 over Rational Field
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
#*****************************************************************************
|
|
28
|
+
# Copyright (C) 2006 David Kohel <kohel@maths.usyd.edu>
|
|
29
|
+
#
|
|
30
|
+
# This program is free software: you can redistribute it and/or modify
|
|
31
|
+
# it under the terms of the GNU General Public License as published by
|
|
32
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
33
|
+
# (at your option) any later version.
|
|
34
|
+
# http://www.gnu.org/licenses/
|
|
35
|
+
#*****************************************************************************
|
|
36
|
+
|
|
37
|
+
import sage.schemes.curves.projective_curve as plane_curve
|
|
38
|
+
|
|
39
|
+
from sage.misc.lazy_import import lazy_import
|
|
40
|
+
from sage.rings.big_oh import O
|
|
41
|
+
from sage.rings.laurent_series_ring import LaurentSeriesRing
|
|
42
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
43
|
+
from sage.rings.power_series_ring import PowerSeriesRing
|
|
44
|
+
from sage.rings.real_mpfr import RR
|
|
45
|
+
from sage.structure.category_object import normalize_names
|
|
46
|
+
|
|
47
|
+
lazy_import("sage.functions.all", "log")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def is_HyperellipticCurve(C):
|
|
51
|
+
"""
|
|
52
|
+
EXAMPLES::
|
|
53
|
+
|
|
54
|
+
sage: from sage.schemes.hyperelliptic_curves.hyperelliptic_generic import is_HyperellipticCurve
|
|
55
|
+
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1); C
|
|
56
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + x - 1
|
|
57
|
+
sage: is_HyperellipticCurve(C)
|
|
58
|
+
doctest:warning...
|
|
59
|
+
DeprecationWarning: The function is_HyperellipticCurve is deprecated; use 'isinstance(..., HyperellipticCurve_generic)' instead.
|
|
60
|
+
See https://github.com/sagemath/sage/issues/38022 for details.
|
|
61
|
+
True
|
|
62
|
+
"""
|
|
63
|
+
from sage.misc.superseded import deprecation
|
|
64
|
+
deprecation(38022, "The function is_HyperellipticCurve is deprecated; use 'isinstance(..., HyperellipticCurve_generic)' instead.")
|
|
65
|
+
return isinstance(C, HyperellipticCurve_generic)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class HyperellipticCurve_generic(plane_curve.ProjectivePlaneCurve):
|
|
69
|
+
"""
|
|
70
|
+
TESTS::
|
|
71
|
+
|
|
72
|
+
sage: P.<x> = QQ[]
|
|
73
|
+
sage: f0 = 4*x^5 - 30*x^3 + 45*x - 22
|
|
74
|
+
sage: C0 = HyperellipticCurve(f0)
|
|
75
|
+
sage: f1 = x^5 - x^3 + x - 22
|
|
76
|
+
sage: C1 = HyperellipticCurve(f1)
|
|
77
|
+
sage: C0 == C1
|
|
78
|
+
False
|
|
79
|
+
sage: C0 == C0
|
|
80
|
+
True
|
|
81
|
+
|
|
82
|
+
sage: P.<x> = QQ[]
|
|
83
|
+
sage: f0 = 4*x^5 - 30*x^3 + 45*x - 22
|
|
84
|
+
sage: C0 = HyperellipticCurve(f0)
|
|
85
|
+
sage: f1 = x^5 - x^3 + x - 22
|
|
86
|
+
sage: C1 = HyperellipticCurve(f1)
|
|
87
|
+
sage: C0 != C1
|
|
88
|
+
True
|
|
89
|
+
sage: C0 != C0
|
|
90
|
+
False
|
|
91
|
+
|
|
92
|
+
sage: P.<x> = QQ[]
|
|
93
|
+
sage: f0 = 4*x^5 - 30*x^3 + 45*x - 22
|
|
94
|
+
sage: C0 = HyperellipticCurve(f0)
|
|
95
|
+
sage: f1 = x^5 - x^3 + x - 22
|
|
96
|
+
sage: C1 = HyperellipticCurve(f1)
|
|
97
|
+
sage: Q.<y> = GF(5)[]
|
|
98
|
+
sage: f2 = y^5 - y^3 + y - 22
|
|
99
|
+
sage: C2 = HyperellipticCurve(f2)
|
|
100
|
+
sage: hash(C0) == hash(C0)
|
|
101
|
+
True
|
|
102
|
+
sage: hash(C0) == hash(C1)
|
|
103
|
+
False
|
|
104
|
+
sage: hash(C1) == hash(C2)
|
|
105
|
+
False
|
|
106
|
+
"""
|
|
107
|
+
def __init__(self, PP, f, h=None, names=None, genus=None):
|
|
108
|
+
x, y, z = PP.gens()
|
|
109
|
+
df = f.degree()
|
|
110
|
+
F1 = sum([ f[i]*x**i*z**(df-i) for i in range(df+1) ])
|
|
111
|
+
if h is None:
|
|
112
|
+
F = y**2*z**(df-2) - F1
|
|
113
|
+
else:
|
|
114
|
+
dh = h.degree()
|
|
115
|
+
deg = max(df,dh+1)
|
|
116
|
+
F0 = sum([ h[i]*x**i*z**(dh-i) for i in range(dh+1) ])
|
|
117
|
+
F = y**2*z**(deg-2) + F0*y*z**(deg-dh-1) - F1*z**(deg-df)
|
|
118
|
+
plane_curve.ProjectivePlaneCurve.__init__(self,PP,F)
|
|
119
|
+
R = PP.base_ring()
|
|
120
|
+
if names is None:
|
|
121
|
+
names = ("x", "y")
|
|
122
|
+
else:
|
|
123
|
+
names = normalize_names(2, names)
|
|
124
|
+
self._names = names
|
|
125
|
+
P1 = PolynomialRing(R, name=names[0])
|
|
126
|
+
P2 = PolynomialRing(P1, name=names[1])
|
|
127
|
+
self._PP = PP
|
|
128
|
+
self._printing_ring = P2
|
|
129
|
+
self._hyperelliptic_polynomials = (f,h)
|
|
130
|
+
self._genus = genus
|
|
131
|
+
|
|
132
|
+
def change_ring(self, R):
|
|
133
|
+
"""
|
|
134
|
+
Return this HyperellipticCurve over a new base ring ``R``.
|
|
135
|
+
|
|
136
|
+
EXAMPLES::
|
|
137
|
+
|
|
138
|
+
sage: # needs sage.rings.padics
|
|
139
|
+
sage: R.<x> = QQ[]
|
|
140
|
+
sage: H = HyperellipticCurve(x^5 - 10*x + 9)
|
|
141
|
+
sage: K = Qp(3, 5)
|
|
142
|
+
sage: L.<a> = K.extension(x^30 - 3)
|
|
143
|
+
sage: HK = H.change_ring(K)
|
|
144
|
+
sage: HL = HK.change_ring(L); HL
|
|
145
|
+
Hyperelliptic Curve
|
|
146
|
+
over 3-adic Eisenstein Extension Field in a defined by x^30 - 3
|
|
147
|
+
defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^5
|
|
148
|
+
+ (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210)
|
|
149
|
+
|
|
150
|
+
sage: R.<x> = FiniteField(7)[]
|
|
151
|
+
sage: H = HyperellipticCurve(x^8 + x + 5)
|
|
152
|
+
sage: H.base_extend(FiniteField(7^2, 'a')) # needs sage.rings.finite_rings
|
|
153
|
+
Hyperelliptic Curve over Finite Field in a of size 7^2
|
|
154
|
+
defined by y^2 = x^8 + x + 5
|
|
155
|
+
"""
|
|
156
|
+
from .constructor import HyperellipticCurve
|
|
157
|
+
f, h = self._hyperelliptic_polynomials
|
|
158
|
+
y = self._printing_ring.variable_name()
|
|
159
|
+
x = self._printing_ring.base_ring().variable_name()
|
|
160
|
+
return HyperellipticCurve(f.change_ring(R), h.change_ring(R), "%s,%s" % (x,y))
|
|
161
|
+
|
|
162
|
+
base_extend = change_ring
|
|
163
|
+
|
|
164
|
+
def _repr_(self):
|
|
165
|
+
"""
|
|
166
|
+
String representation of hyperelliptic curves.
|
|
167
|
+
|
|
168
|
+
EXAMPLES::
|
|
169
|
+
|
|
170
|
+
sage: P.<x> = QQ[]
|
|
171
|
+
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
|
|
172
|
+
sage: C = HyperellipticCurve(f); C
|
|
173
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
|
|
174
|
+
sage: C = HyperellipticCurve(f,names='u,v'); C
|
|
175
|
+
Hyperelliptic Curve over Rational Field defined by v^2 = 4*u^5 - 30*u^3 + 45*u - 22
|
|
176
|
+
sage: C = HyperellipticCurve(x^5 + 1, x^3 + 2); C
|
|
177
|
+
Hyperelliptic Curve over Rational Field defined by y^2 + (x^3 + 2)*y = x^5 + 1
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
f, h = self._hyperelliptic_polynomials
|
|
181
|
+
R = self.base_ring()
|
|
182
|
+
y = self._printing_ring.gen()
|
|
183
|
+
x = self._printing_ring.base_ring().gen()
|
|
184
|
+
if h.is_zero():
|
|
185
|
+
return "Hyperelliptic Curve over %s defined by %s = %s" % (R, y**2, f(x))
|
|
186
|
+
return "Hyperelliptic Curve over %s defined by %s + %s = %s" % (R, y**2, h(x)*y, f(x))
|
|
187
|
+
|
|
188
|
+
def _latex_(self):
|
|
189
|
+
r"""
|
|
190
|
+
LaTeX representation of hyperelliptic curves.
|
|
191
|
+
|
|
192
|
+
EXAMPLES::
|
|
193
|
+
|
|
194
|
+
sage: P.<x> = QQ[]
|
|
195
|
+
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
|
|
196
|
+
sage: C = HyperellipticCurve(f); latex(C)
|
|
197
|
+
\text{Hyperelliptic Curve over $\Bold{Q}$ defined by $y^{2} = 4 x^{5} - 30 x^{3} + 45 x - 22$}
|
|
198
|
+
sage: C = HyperellipticCurve(f,names='u,v'); latex(C)
|
|
199
|
+
\text{Hyperelliptic Curve over $\Bold{Q}$ defined by $v^{2} = 4 u^{5} - 30 u^{3} + 45 u - 22$}
|
|
200
|
+
sage: C = HyperellipticCurve(x^5 + 1, x^2 + 3); latex(C)
|
|
201
|
+
\text{Hyperelliptic Curve over $\Bold{Q}$ defined by $y^{2} + \left(x^{2} + 3\right) y = x^{5} + 1$}
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
f, h = self._hyperelliptic_polynomials
|
|
205
|
+
R = self.base_ring()
|
|
206
|
+
y = self._printing_ring.gen()
|
|
207
|
+
x = self._printing_ring.base_ring().gen()
|
|
208
|
+
if h.is_zero():
|
|
209
|
+
return (fr'\text{{Hyperelliptic Curve over ${R._latex_()}$ '
|
|
210
|
+
f'defined by ${(y**2)._latex_()} = {(f(x))._latex_()}$}}')
|
|
211
|
+
return (fr'\text{{Hyperelliptic Curve over ${R._latex_()}$ '
|
|
212
|
+
f'defined by ${(y**2)._latex_()} + {(h(x)*y)._latex_()} = '
|
|
213
|
+
f'{(f(x))._latex_()}$}}')
|
|
214
|
+
|
|
215
|
+
def hyperelliptic_polynomials(self, K=None, var='x'):
|
|
216
|
+
"""
|
|
217
|
+
EXAMPLES::
|
|
218
|
+
|
|
219
|
+
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1, x^3/5); C
|
|
220
|
+
Hyperelliptic Curve over Rational Field defined by y^2 + 1/5*x^3*y = x^3 + x - 1
|
|
221
|
+
sage: C.hyperelliptic_polynomials()
|
|
222
|
+
(x^3 + x - 1, 1/5*x^3)
|
|
223
|
+
"""
|
|
224
|
+
if K is None:
|
|
225
|
+
return self._hyperelliptic_polynomials
|
|
226
|
+
else:
|
|
227
|
+
f, h = self._hyperelliptic_polynomials
|
|
228
|
+
P = PolynomialRing(K, var)
|
|
229
|
+
return (P(f), P(h))
|
|
230
|
+
|
|
231
|
+
def is_singular(self):
|
|
232
|
+
r"""
|
|
233
|
+
Return ``False``, because hyperelliptic curves are smooth projective
|
|
234
|
+
curves, as checked on construction.
|
|
235
|
+
|
|
236
|
+
EXAMPLES::
|
|
237
|
+
|
|
238
|
+
sage: R.<x> = QQ[]
|
|
239
|
+
sage: H = HyperellipticCurve(x^5 + 1)
|
|
240
|
+
sage: H.is_singular()
|
|
241
|
+
False
|
|
242
|
+
|
|
243
|
+
A hyperelliptic curve with genus at least 2 always has a singularity at
|
|
244
|
+
infinity when viewed as a *plane* projective curve. This can be seen in
|
|
245
|
+
the following example.::
|
|
246
|
+
|
|
247
|
+
sage: R.<x> = QQ[]
|
|
248
|
+
sage: H = HyperellipticCurve(x^5 + 2)
|
|
249
|
+
sage: from sage.misc.verbose import set_verbose
|
|
250
|
+
sage: set_verbose(-1)
|
|
251
|
+
sage: H.is_singular()
|
|
252
|
+
False
|
|
253
|
+
sage: from sage.schemes.curves.projective_curve import ProjectivePlaneCurve
|
|
254
|
+
sage: ProjectivePlaneCurve.is_singular(H)
|
|
255
|
+
True
|
|
256
|
+
"""
|
|
257
|
+
return False
|
|
258
|
+
|
|
259
|
+
def is_smooth(self):
|
|
260
|
+
r"""
|
|
261
|
+
Return ``True``, because hyperelliptic curves are smooth projective
|
|
262
|
+
curves, as checked on construction.
|
|
263
|
+
|
|
264
|
+
EXAMPLES::
|
|
265
|
+
|
|
266
|
+
sage: R.<x> = GF(13)[]
|
|
267
|
+
sage: H = HyperellipticCurve(x^8 + 1)
|
|
268
|
+
sage: H.is_smooth()
|
|
269
|
+
True
|
|
270
|
+
|
|
271
|
+
A hyperelliptic curve with genus at least 2 always has a singularity at
|
|
272
|
+
infinity when viewed as a *plane* projective curve. This can be seen in
|
|
273
|
+
the following example.::
|
|
274
|
+
|
|
275
|
+
sage: # needs sage.rings.finite_rings
|
|
276
|
+
sage: R.<x> = GF(27, 'a')[]
|
|
277
|
+
sage: H = HyperellipticCurve(x^10 + 2)
|
|
278
|
+
sage: from sage.misc.verbose import set_verbose
|
|
279
|
+
sage: set_verbose(-1)
|
|
280
|
+
sage: H.is_smooth()
|
|
281
|
+
True
|
|
282
|
+
sage: from sage.schemes.curves.projective_curve import ProjectivePlaneCurve
|
|
283
|
+
sage: ProjectivePlaneCurve.is_smooth(H)
|
|
284
|
+
False
|
|
285
|
+
"""
|
|
286
|
+
return True
|
|
287
|
+
|
|
288
|
+
def is_x_coord(self, x):
|
|
289
|
+
"""
|
|
290
|
+
Return ``True`` if ``x`` is the `x`-coordinate of a point on this curve.
|
|
291
|
+
|
|
292
|
+
.. SEEALSO::
|
|
293
|
+
|
|
294
|
+
See also :meth:`lift_x` to find the point(s) with a given
|
|
295
|
+
`x`-coordinate. This function may be useful in cases where
|
|
296
|
+
testing an element of the base field for being a square is
|
|
297
|
+
faster than finding its square root.
|
|
298
|
+
|
|
299
|
+
INPUT:
|
|
300
|
+
|
|
301
|
+
- ``x`` -- an element of the base ring of the curve
|
|
302
|
+
|
|
303
|
+
OUTPUT: boolean stating whether or not `x` is a x-coordinate of a point
|
|
304
|
+
on the curve
|
|
305
|
+
|
|
306
|
+
EXAMPLES:
|
|
307
|
+
|
|
308
|
+
When `x` is the `x`-coordinate of a rational point on the
|
|
309
|
+
curve, we can request these::
|
|
310
|
+
|
|
311
|
+
sage: R.<x> = PolynomialRing(QQ)
|
|
312
|
+
sage: f = x^5 + x^3 + 1
|
|
313
|
+
sage: H = HyperellipticCurve(f)
|
|
314
|
+
sage: H.is_x_coord(0)
|
|
315
|
+
True
|
|
316
|
+
|
|
317
|
+
There are no rational points with `x`-coordinate 3::
|
|
318
|
+
|
|
319
|
+
sage: H.is_x_coord(3)
|
|
320
|
+
False
|
|
321
|
+
|
|
322
|
+
The function also handles the case when `h(x)` is not zero::
|
|
323
|
+
|
|
324
|
+
sage: R.<x> = PolynomialRing(QQ)
|
|
325
|
+
sage: f = x^5 + x^3 + 1
|
|
326
|
+
sage: h = x + 1
|
|
327
|
+
sage: H = HyperellipticCurve(f, h)
|
|
328
|
+
sage: H.is_x_coord(1)
|
|
329
|
+
True
|
|
330
|
+
|
|
331
|
+
We can perform these operations over finite fields too::
|
|
332
|
+
|
|
333
|
+
sage: # needs sage.rings.finite_rings
|
|
334
|
+
sage: R.<x> = PolynomialRing(GF(163))
|
|
335
|
+
sage: f = x^7 + x + 1
|
|
336
|
+
sage: H = HyperellipticCurve(f)
|
|
337
|
+
sage: H.is_x_coord(13)
|
|
338
|
+
True
|
|
339
|
+
|
|
340
|
+
Including the case of characteristic two::
|
|
341
|
+
|
|
342
|
+
sage: # needs sage.rings.finite_rings
|
|
343
|
+
sage: F.<z4> = GF(2^4)
|
|
344
|
+
sage: R.<x> = PolynomialRing(F)
|
|
345
|
+
sage: f = x^7 + x^3 + 1
|
|
346
|
+
sage: h = x + 1
|
|
347
|
+
sage: H = HyperellipticCurve(f, h)
|
|
348
|
+
sage: H.is_x_coord(z4^3 + z4^2 + z4)
|
|
349
|
+
True
|
|
350
|
+
|
|
351
|
+
AUTHORS:
|
|
352
|
+
|
|
353
|
+
- Giacomo Pope (2024): adapted from :meth:`lift_x`
|
|
354
|
+
|
|
355
|
+
TESTS:
|
|
356
|
+
|
|
357
|
+
The `x`-coordinate must be defined over the base field of the curve::
|
|
358
|
+
|
|
359
|
+
sage: p = 11
|
|
360
|
+
sage: F = GF(11)
|
|
361
|
+
sage: F_ext = GF(11^2)
|
|
362
|
+
sage: R.<x> = PolynomialRing(F)
|
|
363
|
+
sage: f = x^7 + x^3 + 1
|
|
364
|
+
sage: H = HyperellipticCurve(f)
|
|
365
|
+
sage: H.is_x_coord(F_ext.gen())
|
|
366
|
+
Traceback (most recent call last):
|
|
367
|
+
...
|
|
368
|
+
TypeError: x must be coercible into the base ring of the curve
|
|
369
|
+
"""
|
|
370
|
+
f, h = self.hyperelliptic_polynomials()
|
|
371
|
+
K = self.base_ring()
|
|
372
|
+
try:
|
|
373
|
+
x = K(x)
|
|
374
|
+
except (ValueError, TypeError):
|
|
375
|
+
raise TypeError('x must be coercible into the base ring of the curve')
|
|
376
|
+
|
|
377
|
+
# When h is zero then x is a valid coordinate if y2 is square
|
|
378
|
+
if not h:
|
|
379
|
+
y2 = f(x)
|
|
380
|
+
return y2.is_square()
|
|
381
|
+
# Generic case for h != 0
|
|
382
|
+
a = f(x)
|
|
383
|
+
b = h(x)
|
|
384
|
+
# Special case for char 2
|
|
385
|
+
if K.characteristic() == 2:
|
|
386
|
+
R = f.parent() # Polynomial ring K[x]
|
|
387
|
+
F = R([-a, b, 1])
|
|
388
|
+
return bool(F.roots())
|
|
389
|
+
# Otherwise x is a point on the curve if the discriminant is a square
|
|
390
|
+
D = b*b + 4*a
|
|
391
|
+
return D.is_square()
|
|
392
|
+
|
|
393
|
+
def lift_x(self, x, all=False):
|
|
394
|
+
"""
|
|
395
|
+
Return one or all points with given `x`-coordinate.
|
|
396
|
+
|
|
397
|
+
This method is deterministic: It returns the same data each
|
|
398
|
+
time when called again with the same `x`.
|
|
399
|
+
|
|
400
|
+
INPUT:
|
|
401
|
+
|
|
402
|
+
- ``x`` -- an element of the base ring of the curve
|
|
403
|
+
|
|
404
|
+
- ``all`` -- boolean (default: ``False``); if ``True``, return a
|
|
405
|
+
(possibly empty) list of all points. If ``False``, return
|
|
406
|
+
just one point, or raise a :exc:`ValueError` if there are none.
|
|
407
|
+
|
|
408
|
+
OUTPUT: a point or list of up to two points on this curve
|
|
409
|
+
|
|
410
|
+
.. SEEALSO::
|
|
411
|
+
|
|
412
|
+
:meth:`is_x_coord`
|
|
413
|
+
|
|
414
|
+
AUTHORS:
|
|
415
|
+
|
|
416
|
+
- Giacomo Pope (2024): Allowed for the case of characteristic two
|
|
417
|
+
|
|
418
|
+
EXAMPLES:
|
|
419
|
+
|
|
420
|
+
When `x` is the `x`-coordinate of a rational point on the
|
|
421
|
+
curve, we can request these::
|
|
422
|
+
|
|
423
|
+
sage: R.<x> = PolynomialRing(QQ)
|
|
424
|
+
sage: f = x^5 + x^3 + 1
|
|
425
|
+
sage: H = HyperellipticCurve(f)
|
|
426
|
+
sage: H.lift_x(0)
|
|
427
|
+
(0 : -1 : 1)
|
|
428
|
+
sage: H.lift_x(4, all=True)
|
|
429
|
+
[(4 : -33 : 1), (4 : 33 : 1)]
|
|
430
|
+
|
|
431
|
+
There are no rational points with `x`-coordinate 3::
|
|
432
|
+
|
|
433
|
+
sage: H.lift_x(3)
|
|
434
|
+
Traceback (most recent call last):
|
|
435
|
+
...
|
|
436
|
+
ValueError: No point with x-coordinate 3 on Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x^3 + 1
|
|
437
|
+
|
|
438
|
+
An empty list is returned when there are no points and ``all=True``::
|
|
439
|
+
|
|
440
|
+
sage: H.lift_x(3, all=True)
|
|
441
|
+
[]
|
|
442
|
+
|
|
443
|
+
The function also handles the case when `h(x)` is not zero::
|
|
444
|
+
|
|
445
|
+
sage: R.<x> = PolynomialRing(QQ)
|
|
446
|
+
sage: f = x^5 + x^3 + 1
|
|
447
|
+
sage: h = x + 1
|
|
448
|
+
sage: H = HyperellipticCurve(f, h)
|
|
449
|
+
sage: H.lift_x(1)
|
|
450
|
+
(1 : -3 : 1)
|
|
451
|
+
|
|
452
|
+
We can perform these operations over finite fields too::
|
|
453
|
+
|
|
454
|
+
sage: # needs sage.rings.finite_rings
|
|
455
|
+
sage: R.<x> = PolynomialRing(GF(163))
|
|
456
|
+
sage: f = x^7 + x + 1
|
|
457
|
+
sage: H = HyperellipticCurve(f)
|
|
458
|
+
sage: H.lift_x(13)
|
|
459
|
+
(13 : 41 : 1)
|
|
460
|
+
|
|
461
|
+
Including the case of characteristic two::
|
|
462
|
+
|
|
463
|
+
sage: # needs sage.rings.finite_rings
|
|
464
|
+
sage: F.<z4> = GF(2^4)
|
|
465
|
+
sage: R.<x> = PolynomialRing(F)
|
|
466
|
+
sage: f = x^7 + x^3 + 1
|
|
467
|
+
sage: h = x + 1
|
|
468
|
+
sage: H = HyperellipticCurve(f, h)
|
|
469
|
+
sage: H.lift_x(z4^3 + z4^2 + z4, all=True)
|
|
470
|
+
[(z4^3 + z4^2 + z4 : z4^2 + z4 + 1 : 1), (z4^3 + z4^2 + z4 : z4^3 : 1)]
|
|
471
|
+
|
|
472
|
+
TESTS::
|
|
473
|
+
|
|
474
|
+
sage: # needs sage.rings.finite_rings
|
|
475
|
+
sage: F1 = GF(11)
|
|
476
|
+
sage: F2 = GF(13)
|
|
477
|
+
sage: R.<x> = PolynomialRing(F1)
|
|
478
|
+
sage: f = x^7 + x^3 + 1
|
|
479
|
+
sage: H = HyperellipticCurve(f)
|
|
480
|
+
sage: H.lift_x(F2.random_element())
|
|
481
|
+
Traceback (most recent call last):
|
|
482
|
+
...
|
|
483
|
+
ValueError: x must have a common parent with the base ring
|
|
484
|
+
|
|
485
|
+
Ensure that :issue:`37097` is fixed::
|
|
486
|
+
|
|
487
|
+
sage: # needs sage.rings.finite_rings
|
|
488
|
+
sage: F.<z4> = GF(2^4)
|
|
489
|
+
sage: R.<x> = PolynomialRing(F)
|
|
490
|
+
sage: f = x^7 + x^3 + 1
|
|
491
|
+
sage: h = x + 1
|
|
492
|
+
sage: H = HyperellipticCurve(f, h)
|
|
493
|
+
sage: H.lift_x(z4^3 + z4^2 + z4, all=True)
|
|
494
|
+
[(z4^3 + z4^2 + z4 : z4^2 + z4 + 1 : 1), (z4^3 + z4^2 + z4 : z4^3 : 1)]
|
|
495
|
+
"""
|
|
496
|
+
from sage.structure.element import get_coercion_model
|
|
497
|
+
cm = get_coercion_model()
|
|
498
|
+
|
|
499
|
+
f, h = self.hyperelliptic_polynomials()
|
|
500
|
+
K = self.base_ring()
|
|
501
|
+
|
|
502
|
+
# Compute the common parent between the base ring of the curve and
|
|
503
|
+
# the parent of the input x-coordinate.
|
|
504
|
+
try:
|
|
505
|
+
L = cm.common_parent(x.parent(), K)
|
|
506
|
+
x = L(x)
|
|
507
|
+
except (TypeError, ValueError):
|
|
508
|
+
raise ValueError('x must have a common parent with the base ring')
|
|
509
|
+
|
|
510
|
+
# First we compute the y-coordinates the given x-coordinate
|
|
511
|
+
ys = []
|
|
512
|
+
one = L.one()
|
|
513
|
+
|
|
514
|
+
# When h is zero we find all y-coordinates with a single sqrt
|
|
515
|
+
if not h:
|
|
516
|
+
y2 = f(x)
|
|
517
|
+
# When y2 is not a square, ys will be an empty list
|
|
518
|
+
ys = y2.sqrt(all=True, extend=False)
|
|
519
|
+
# Otherwise we need roots of the discriminant
|
|
520
|
+
else:
|
|
521
|
+
a = f(x)
|
|
522
|
+
b = h(x)
|
|
523
|
+
# Special case for char 2
|
|
524
|
+
if K.characteristic() == 2:
|
|
525
|
+
R = f.parent()
|
|
526
|
+
F = R([-a, b, 1])
|
|
527
|
+
ys = F.roots(L, multiplicities=False)
|
|
528
|
+
else:
|
|
529
|
+
D = b*b + 4*a
|
|
530
|
+
# When D is not a square, ys will be an empty list
|
|
531
|
+
ys = [(-b+d)/2 for d in D.sqrt(all=True, extend=False)]
|
|
532
|
+
|
|
533
|
+
if ys:
|
|
534
|
+
ys.sort() # Make lifting deterministic
|
|
535
|
+
if all:
|
|
536
|
+
return [self.point([x, y, one], check=False) for y in ys]
|
|
537
|
+
else:
|
|
538
|
+
return self.point([x, ys[0], one], check=False)
|
|
539
|
+
|
|
540
|
+
if all:
|
|
541
|
+
return []
|
|
542
|
+
else:
|
|
543
|
+
raise ValueError(f"No point with x-coordinate {x} on {self}")
|
|
544
|
+
|
|
545
|
+
def genus(self):
|
|
546
|
+
return self._genus
|
|
547
|
+
|
|
548
|
+
def jacobian(self):
|
|
549
|
+
from . import jacobian_generic
|
|
550
|
+
return jacobian_generic.HyperellipticJacobian_generic(self)
|
|
551
|
+
|
|
552
|
+
def odd_degree_model(self):
|
|
553
|
+
r"""
|
|
554
|
+
Return an odd degree model of ``self``, or raise :exc:`ValueError` if
|
|
555
|
+
one does not exist over the field of definition.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: x = QQ['x'].gen()
|
|
560
|
+
sage: H = HyperellipticCurve((x^2 + 2)*(x^2 + 3)*(x^2 + 5)); H
|
|
561
|
+
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 10*x^4 + 31*x^2 + 30
|
|
562
|
+
sage: H.odd_degree_model()
|
|
563
|
+
Traceback (most recent call last):
|
|
564
|
+
...
|
|
565
|
+
ValueError: No odd degree model exists over field of definition
|
|
566
|
+
|
|
567
|
+
sage: K2 = QuadraticField(-2, 'a') # needs sage.rings.number_field
|
|
568
|
+
sage: Hp2 = H.change_ring(K2).odd_degree_model(); Hp2 # needs sage.rings.number_field
|
|
569
|
+
Hyperelliptic Curve over Number Field in a
|
|
570
|
+
with defining polynomial x^2 + 2 with a = 1.414213562373095?*I
|
|
571
|
+
defined by y^2 = 6*a*x^5 - 29*x^4 - 20*x^2 + 6*a*x + 1
|
|
572
|
+
|
|
573
|
+
sage: K3 = QuadraticField(-3, 'b') # needs sage.rings.number_field
|
|
574
|
+
sage: Hp3 = H.change_ring(QuadraticField(-3, 'b')).odd_degree_model(); Hp3 # needs sage.rings.number_field
|
|
575
|
+
Hyperelliptic Curve over Number Field in b
|
|
576
|
+
with defining polynomial x^2 + 3 with b = 1.732050807568878?*I
|
|
577
|
+
defined by y^2 = -4*b*x^5 - 14*x^4 - 20*b*x^3 - 35*x^2 + 6*b*x + 1
|
|
578
|
+
|
|
579
|
+
Of course, ``Hp2`` and ``Hp3`` are isomorphic over the composite
|
|
580
|
+
extension. One consequence of this is that odd degree models
|
|
581
|
+
reduced over "different" fields should have the same number of
|
|
582
|
+
points on their reductions. 43 and 67 split completely in the
|
|
583
|
+
compositum, so when we reduce we find:
|
|
584
|
+
|
|
585
|
+
sage: # needs sage.rings.number_field
|
|
586
|
+
sage: P2 = K2.factor(43)[0][0]
|
|
587
|
+
sage: P3 = K3.factor(43)[0][0]
|
|
588
|
+
sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial()
|
|
589
|
+
x^4 - 16*x^3 + 134*x^2 - 688*x + 1849
|
|
590
|
+
sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial()
|
|
591
|
+
x^4 - 16*x^3 + 134*x^2 - 688*x + 1849
|
|
592
|
+
|
|
593
|
+
sage: H.change_ring(GF(43)).odd_degree_model().frobenius_polynomial() # needs sage.rings.finite_rings
|
|
594
|
+
x^4 - 16*x^3 + 134*x^2 - 688*x + 1849
|
|
595
|
+
|
|
596
|
+
sage: # needs sage.rings.number_field
|
|
597
|
+
sage: P2 = K2.factor(67)[0][0]
|
|
598
|
+
sage: P3 = K3.factor(67)[0][0]
|
|
599
|
+
sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial()
|
|
600
|
+
x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
|
|
601
|
+
sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial()
|
|
602
|
+
x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
|
|
603
|
+
|
|
604
|
+
sage: H.change_ring(GF(67)).odd_degree_model().frobenius_polynomial() # needs sage.rings.finite_rings
|
|
605
|
+
x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
|
|
606
|
+
|
|
607
|
+
TESTS::
|
|
608
|
+
|
|
609
|
+
sage: HyperellipticCurve(x^5 + 1, 1).odd_degree_model()
|
|
610
|
+
Traceback (most recent call last):
|
|
611
|
+
...
|
|
612
|
+
NotImplementedError: odd_degree_model only implemented for curves in Weierstrass form
|
|
613
|
+
|
|
614
|
+
sage: HyperellipticCurve(x^5 + 1, names="U, V").odd_degree_model()
|
|
615
|
+
Hyperelliptic Curve over Rational Field defined by V^2 = U^5 + 1
|
|
616
|
+
"""
|
|
617
|
+
f, h = self._hyperelliptic_polynomials
|
|
618
|
+
if h:
|
|
619
|
+
raise NotImplementedError("odd_degree_model only implemented for curves in Weierstrass form")
|
|
620
|
+
if f.degree() % 2:
|
|
621
|
+
# already odd, so just yield self
|
|
622
|
+
return self
|
|
623
|
+
|
|
624
|
+
rts = f.roots(multiplicities=False)
|
|
625
|
+
if not rts:
|
|
626
|
+
raise ValueError("No odd degree model exists over field of definition")
|
|
627
|
+
rt = rts[0]
|
|
628
|
+
x = f.parent().gen()
|
|
629
|
+
fnew = f((x * rt + 1) / x).numerator() # move rt to "infinity"
|
|
630
|
+
|
|
631
|
+
from .constructor import HyperellipticCurve
|
|
632
|
+
return HyperellipticCurve(fnew, 0, names=self._names, PP=self._PP)
|
|
633
|
+
|
|
634
|
+
def has_odd_degree_model(self) -> bool:
|
|
635
|
+
r"""
|
|
636
|
+
Return ``True`` if an odd degree model of ``self`` exists over the
|
|
637
|
+
field of definition; ``False`` otherwise.
|
|
638
|
+
|
|
639
|
+
Use ``odd_degree_model`` to calculate an odd degree model.
|
|
640
|
+
|
|
641
|
+
EXAMPLES::
|
|
642
|
+
|
|
643
|
+
sage: x = QQ['x'].0
|
|
644
|
+
sage: HyperellipticCurve(x^5 + x).has_odd_degree_model()
|
|
645
|
+
True
|
|
646
|
+
sage: HyperellipticCurve(x^6 + x).has_odd_degree_model()
|
|
647
|
+
True
|
|
648
|
+
sage: HyperellipticCurve(x^6 + x + 1).has_odd_degree_model()
|
|
649
|
+
False
|
|
650
|
+
"""
|
|
651
|
+
try:
|
|
652
|
+
return bool(self.odd_degree_model())
|
|
653
|
+
except ValueError:
|
|
654
|
+
return False
|
|
655
|
+
|
|
656
|
+
def _magma_init_(self, magma):
|
|
657
|
+
"""
|
|
658
|
+
Internal function. Returns a string to initialize this elliptic
|
|
659
|
+
curve in the Magma subsystem.
|
|
660
|
+
|
|
661
|
+
EXAMPLES::
|
|
662
|
+
|
|
663
|
+
sage: # optional - magma
|
|
664
|
+
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1, x); C
|
|
665
|
+
Hyperelliptic Curve over Rational Field
|
|
666
|
+
defined by y^2 + x*y = x^3 + x - 1
|
|
667
|
+
sage: magma(C)
|
|
668
|
+
Hyperelliptic Curve defined by y^2 + x*y = x^3 + x - 1 over Rational Field
|
|
669
|
+
sage: R.<x> = GF(9,'a')[]; C = HyperellipticCurve(x^3 + x - 1, x^10); C # needs sage.rings.finite_rings
|
|
670
|
+
Hyperelliptic Curve over Finite Field in a of size 3^2
|
|
671
|
+
defined by y^2 + x^10*y = x^3 + x + 2
|
|
672
|
+
sage: D = magma(C); D # needs sage.rings.finite_rings
|
|
673
|
+
Hyperelliptic Curve defined by y^2 + x^10*y = x^3 + x + 2 over GF(3^2)
|
|
674
|
+
sage: D.sage() # needs sage.rings.finite_rings
|
|
675
|
+
Hyperelliptic Curve over Finite Field in a of size 3^2
|
|
676
|
+
defined by y^2 + x^10*y = x^3 + x + 2
|
|
677
|
+
"""
|
|
678
|
+
f, h = self._hyperelliptic_polynomials
|
|
679
|
+
return 'HyperellipticCurve(%s, %s)' % (f._magma_init_(magma), h._magma_init_(magma))
|
|
680
|
+
|
|
681
|
+
def monsky_washnitzer_gens(self):
|
|
682
|
+
import sage.schemes.hyperelliptic_curves.monsky_washnitzer as monsky_washnitzer
|
|
683
|
+
S = monsky_washnitzer.SpecialHyperellipticQuotientRing(self)
|
|
684
|
+
return S.gens()
|
|
685
|
+
|
|
686
|
+
def invariant_differential(self):
|
|
687
|
+
"""
|
|
688
|
+
Return `dx/2y`, as an element of the Monsky-Washnitzer cohomology
|
|
689
|
+
of ``self``.
|
|
690
|
+
|
|
691
|
+
EXAMPLES::
|
|
692
|
+
|
|
693
|
+
sage: R.<x> = QQ['x']
|
|
694
|
+
sage: C = HyperellipticCurve(x^5 - 4*x + 4)
|
|
695
|
+
sage: C.invariant_differential()
|
|
696
|
+
1 dx/2y
|
|
697
|
+
"""
|
|
698
|
+
import sage.schemes.hyperelliptic_curves.monsky_washnitzer as m_w
|
|
699
|
+
S = m_w.SpecialHyperellipticQuotientRing(self)
|
|
700
|
+
MW = m_w.MonskyWashnitzerDifferentialRing(S)
|
|
701
|
+
return MW.invariant_differential()
|
|
702
|
+
|
|
703
|
+
def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'):
|
|
704
|
+
"""
|
|
705
|
+
For a non-Weierstrass point `P = (a,b)` on the hyperelliptic
|
|
706
|
+
curve `y^2 = f(x)`, return `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`,
|
|
707
|
+
where `t = x - a` is the local parameter.
|
|
708
|
+
|
|
709
|
+
INPUT:
|
|
710
|
+
|
|
711
|
+
- ``P = (a, b)`` -- a non-Weierstrass point on ``self``
|
|
712
|
+
- ``prec`` -- desired precision of the local coordinates
|
|
713
|
+
- ``name`` -- gen of the power series ring (default: ``t``)
|
|
714
|
+
|
|
715
|
+
OUTPUT:
|
|
716
|
+
|
|
717
|
+
`(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x - a`
|
|
718
|
+
is the local parameter at `P`
|
|
719
|
+
|
|
720
|
+
EXAMPLES::
|
|
721
|
+
|
|
722
|
+
sage: R.<x> = QQ['x']
|
|
723
|
+
sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x)
|
|
724
|
+
sage: P = H(1, 6)
|
|
725
|
+
sage: x, y = H.local_coordinates_at_nonweierstrass(P, prec=5)
|
|
726
|
+
sage: x
|
|
727
|
+
1 + t + O(t^5)
|
|
728
|
+
sage: y
|
|
729
|
+
6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5)
|
|
730
|
+
sage: Q = H(-2, 12)
|
|
731
|
+
sage: x, y = H.local_coordinates_at_nonweierstrass(Q, prec=5)
|
|
732
|
+
sage: x
|
|
733
|
+
-2 + t + O(t^5)
|
|
734
|
+
sage: y
|
|
735
|
+
12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5)
|
|
736
|
+
|
|
737
|
+
AUTHOR:
|
|
738
|
+
|
|
739
|
+
- Jennifer Balakrishnan (2007-12)
|
|
740
|
+
"""
|
|
741
|
+
d = P[1]
|
|
742
|
+
if d == 0:
|
|
743
|
+
raise TypeError("P = %s is a Weierstrass point. Use local_coordinates_at_weierstrass instead!" % P)
|
|
744
|
+
pol = self.hyperelliptic_polynomials()[0]
|
|
745
|
+
L = PowerSeriesRing(self.base_ring(), name, default_prec=prec)
|
|
746
|
+
t = L.gen()
|
|
747
|
+
K = PowerSeriesRing(L, 'x')
|
|
748
|
+
pol = K(pol)
|
|
749
|
+
b = P[0]
|
|
750
|
+
f = pol(t+b)
|
|
751
|
+
for i in range((RR(log(prec)/log(2))).ceil()):
|
|
752
|
+
d = (d + f/d)/2
|
|
753
|
+
return t+b+O(t**(prec)), d + O(t**(prec))
|
|
754
|
+
|
|
755
|
+
def local_coordinates_at_weierstrass(self, P, prec=20, name='t'):
|
|
756
|
+
"""
|
|
757
|
+
For a finite Weierstrass point on the hyperelliptic
|
|
758
|
+
curve `y^2 = f(x)`, returns `(x(t), y(t))` such that
|
|
759
|
+
`(y(t))^2 = f(x(t))`, where `t = y` is the local parameter.
|
|
760
|
+
|
|
761
|
+
INPUT:
|
|
762
|
+
|
|
763
|
+
- ``P`` -- a finite Weierstrass point on ``self``
|
|
764
|
+
- ``prec`` -- desired precision of the local coordinates
|
|
765
|
+
- ``name`` -- gen of the power series ring (default: `t`)
|
|
766
|
+
|
|
767
|
+
OUTPUT:
|
|
768
|
+
|
|
769
|
+
`(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = y`
|
|
770
|
+
is the local parameter at `P`
|
|
771
|
+
|
|
772
|
+
EXAMPLES::
|
|
773
|
+
|
|
774
|
+
sage: R.<x> = QQ['x']
|
|
775
|
+
sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x)
|
|
776
|
+
sage: A = H(4, 0)
|
|
777
|
+
sage: x, y = H.local_coordinates_at_weierstrass(A, prec=7)
|
|
778
|
+
sage: x
|
|
779
|
+
4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7)
|
|
780
|
+
sage: y
|
|
781
|
+
t + O(t^7)
|
|
782
|
+
sage: B = H(-5, 0)
|
|
783
|
+
sage: x, y = H.local_coordinates_at_weierstrass(B, prec=5)
|
|
784
|
+
sage: x
|
|
785
|
+
-5 + 1/1260*t^2 + 887/2000376000*t^4 + O(t^5)
|
|
786
|
+
sage: y
|
|
787
|
+
t + O(t^5)
|
|
788
|
+
|
|
789
|
+
AUTHOR:
|
|
790
|
+
- Jennifer Balakrishnan (2007-12)
|
|
791
|
+
|
|
792
|
+
- Francis Clarke (2012-08-26)
|
|
793
|
+
"""
|
|
794
|
+
if P[1] != 0:
|
|
795
|
+
raise TypeError("P = %s is not a finite Weierstrass point. Use local_coordinates_at_nonweierstrass instead!" % P)
|
|
796
|
+
L = PowerSeriesRing(self.base_ring(), name)
|
|
797
|
+
t = L.gen()
|
|
798
|
+
pol = self.hyperelliptic_polynomials()[0]
|
|
799
|
+
pol_prime = pol.derivative()
|
|
800
|
+
b = P[0]
|
|
801
|
+
t2 = t**2
|
|
802
|
+
c = b + t2/pol_prime(b)
|
|
803
|
+
c = c.add_bigoh(prec)
|
|
804
|
+
for _ in range(int(1 + log(prec, 2))):
|
|
805
|
+
c -= (pol(c) - t2)/pol_prime(c)
|
|
806
|
+
return (c, t.add_bigoh(prec))
|
|
807
|
+
|
|
808
|
+
def local_coordinates_at_infinity(self, prec=20, name='t'):
|
|
809
|
+
"""
|
|
810
|
+
For the genus `g` hyperelliptic curve `y^2 = f(x)`, return
|
|
811
|
+
`(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x^g/y` is
|
|
812
|
+
the local parameter at infinity
|
|
813
|
+
|
|
814
|
+
INPUT:
|
|
815
|
+
|
|
816
|
+
- ``prec`` -- desired precision of the local coordinates
|
|
817
|
+
- ``name`` -- generator of the power series ring (default: ``t``)
|
|
818
|
+
|
|
819
|
+
OUTPUT:
|
|
820
|
+
|
|
821
|
+
`(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x^g/y`
|
|
822
|
+
is the local parameter at infinity
|
|
823
|
+
|
|
824
|
+
EXAMPLES::
|
|
825
|
+
|
|
826
|
+
sage: R.<x> = QQ['x']
|
|
827
|
+
sage: H = HyperellipticCurve(x^5 - 5*x^2 + 1)
|
|
828
|
+
sage: x, y = H.local_coordinates_at_infinity(10)
|
|
829
|
+
sage: x
|
|
830
|
+
t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12)
|
|
831
|
+
sage: y
|
|
832
|
+
t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12)
|
|
833
|
+
|
|
834
|
+
::
|
|
835
|
+
|
|
836
|
+
sage: R.<x> = QQ['x']
|
|
837
|
+
sage: H = HyperellipticCurve(x^3 - x + 1)
|
|
838
|
+
sage: x, y = H.local_coordinates_at_infinity(10)
|
|
839
|
+
sage: x
|
|
840
|
+
t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12)
|
|
841
|
+
sage: y
|
|
842
|
+
t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12)
|
|
843
|
+
|
|
844
|
+
AUTHOR:
|
|
845
|
+
|
|
846
|
+
- Jennifer Balakrishnan (2007-12)
|
|
847
|
+
"""
|
|
848
|
+
g = self.genus()
|
|
849
|
+
pol = self.hyperelliptic_polynomials()[0]
|
|
850
|
+
K = LaurentSeriesRing(self.base_ring(), name, default_prec=prec+2)
|
|
851
|
+
t = K.gen()
|
|
852
|
+
L = PolynomialRing(K,'x')
|
|
853
|
+
x = L.gen()
|
|
854
|
+
i = 0
|
|
855
|
+
w = (x**g/t)**2-pol
|
|
856
|
+
wprime = w.derivative(x)
|
|
857
|
+
x = t**-2
|
|
858
|
+
for i in range((RR(log(prec+2)/log(2))).ceil()):
|
|
859
|
+
x = x - w(x)/wprime(x)
|
|
860
|
+
y = x**g/t
|
|
861
|
+
return x+O(t**(prec+2)) , y+O(t**(prec+2))
|
|
862
|
+
|
|
863
|
+
def local_coord(self, P, prec=20, name='t'):
|
|
864
|
+
"""
|
|
865
|
+
Call the appropriate local_coordinates function.
|
|
866
|
+
|
|
867
|
+
INPUT:
|
|
868
|
+
|
|
869
|
+
- ``P`` -- a point on ``self``
|
|
870
|
+
- ``prec`` -- desired precision of the local coordinates
|
|
871
|
+
- ``name`` -- generator of the power series ring (default: ``t``)
|
|
872
|
+
|
|
873
|
+
OUTPUT:
|
|
874
|
+
|
|
875
|
+
`(x(t),y(t))` such that `y(t)^2 = f(x(t))`, where `t`
|
|
876
|
+
is the local parameter at `P`
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: R.<x> = QQ['x']
|
|
881
|
+
sage: H = HyperellipticCurve(x^5 - 23*x^3 + 18*x^2 + 40*x)
|
|
882
|
+
sage: H.local_coord(H(1 ,6), prec=5)
|
|
883
|
+
(1 + t + O(t^5), 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5))
|
|
884
|
+
sage: H.local_coord(H(4, 0), prec=7)
|
|
885
|
+
(4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7), t + O(t^7))
|
|
886
|
+
sage: H.local_coord(H(0, 1, 0), prec=5)
|
|
887
|
+
(t^-2 + 23*t^2 - 18*t^4 - 569*t^6 + O(t^7),
|
|
888
|
+
t^-5 + 46*t^-1 - 36*t - 609*t^3 + 1656*t^5 + O(t^6))
|
|
889
|
+
|
|
890
|
+
AUTHOR:
|
|
891
|
+
|
|
892
|
+
- Jennifer Balakrishnan (2007-12)
|
|
893
|
+
"""
|
|
894
|
+
if P[1] == 0:
|
|
895
|
+
return self.local_coordinates_at_weierstrass(P, prec, name)
|
|
896
|
+
elif P[2] == 0:
|
|
897
|
+
return self.local_coordinates_at_infinity(prec, name)
|
|
898
|
+
else:
|
|
899
|
+
return self.local_coordinates_at_nonweierstrass(P, prec, name)
|
|
900
|
+
|
|
901
|
+
def rational_points(self, **kwds):
|
|
902
|
+
r"""
|
|
903
|
+
Find rational points on the hyperelliptic curve, all arguments are passed
|
|
904
|
+
on to :meth:`sage.schemes.generic.algebraic_scheme.rational_points`.
|
|
905
|
+
|
|
906
|
+
EXAMPLES:
|
|
907
|
+
|
|
908
|
+
For the LMFDB genus 2 curve `932.a.3728.1 <https://www.lmfdb.org/Genus2Curve/Q/932/a/3728/1>`_::
|
|
909
|
+
|
|
910
|
+
sage: R.<x> = PolynomialRing(QQ)
|
|
911
|
+
sage: C = HyperellipticCurve(R([0, -1, 1, 0, 1, -2, 1]), R([1]))
|
|
912
|
+
sage: C.rational_points(bound=8)
|
|
913
|
+
[(-1 : -3 : 1),
|
|
914
|
+
(-1 : 2 : 1),
|
|
915
|
+
(0 : -1 : 1),
|
|
916
|
+
(0 : 0 : 1),
|
|
917
|
+
(0 : 1 : 0),
|
|
918
|
+
(1/2 : -5/8 : 1),
|
|
919
|
+
(1/2 : -3/8 : 1),
|
|
920
|
+
(1 : -1 : 1),
|
|
921
|
+
(1 : 0 : 1)]
|
|
922
|
+
|
|
923
|
+
Check that :issue:`29509` is fixed for the LMFDB genus 2 curve
|
|
924
|
+
`169.a.169.1 <https://www.lmfdb.org/Genus2Curve/Q/169/a/169/1>`_::
|
|
925
|
+
|
|
926
|
+
sage: C = HyperellipticCurve(R([0, 0, 0, 0, 1, 1]), R([1, 1, 0, 1]))
|
|
927
|
+
sage: C.rational_points(bound=10)
|
|
928
|
+
[(-1 : 0 : 1),
|
|
929
|
+
(-1 : 1 : 1),
|
|
930
|
+
(0 : -1 : 1),
|
|
931
|
+
(0 : 0 : 1),
|
|
932
|
+
(0 : 1 : 0)]
|
|
933
|
+
|
|
934
|
+
An example over a number field::
|
|
935
|
+
|
|
936
|
+
sage: R.<x> = PolynomialRing(QuadraticField(2)) # needs sage.rings.number_field
|
|
937
|
+
sage: C = HyperellipticCurve(R([1, 0, 0, 0, 0, 1])) # needs sage.rings.number_field
|
|
938
|
+
sage: C.rational_points(bound=2) # needs sage.rings.number_field
|
|
939
|
+
[(-1 : 0 : 1),
|
|
940
|
+
(0 : -1 : 1),
|
|
941
|
+
(0 : 1 : 0),
|
|
942
|
+
(0 : 1 : 1),
|
|
943
|
+
(1 : -a : 1),
|
|
944
|
+
(1 : a : 1)]
|
|
945
|
+
"""
|
|
946
|
+
from sage.schemes.curves.constructor import Curve
|
|
947
|
+
# we change C to be a plane curve to allow the generic rational
|
|
948
|
+
# points code to reduce mod any prime, whereas a HyperellipticCurve
|
|
949
|
+
# can only be base changed to good primes.
|
|
950
|
+
C = self
|
|
951
|
+
if 'F' in kwds:
|
|
952
|
+
C = C.change_ring(kwds['F'])
|
|
953
|
+
|
|
954
|
+
return [C(pt) for pt in Curve(self).rational_points(**kwds)]
|