passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-schemes might be problematic. Click here for more details.
- passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Helper functions for reduction of binary forms.
|
|
4
|
+
|
|
5
|
+
The algorithm for reducing is from Stoll and Cremona's "On the Reduction Theory of
|
|
6
|
+
Binary Forms" [CS2003]_. This takes a two variable homogeneous polynomial and finds a
|
|
7
|
+
reduced form. This is an `SL(2,\ZZ)`-equivalent binary form whose covariant in
|
|
8
|
+
the upper half plane is in the fundamental domain. Further, the algorithm
|
|
9
|
+
from Hutz and Stoll [HS2018]_ allows the form to be further minimized so that
|
|
10
|
+
the coefficients have either smallest height or smallest `L_2` norm.
|
|
11
|
+
|
|
12
|
+
AUTHORS:
|
|
13
|
+
|
|
14
|
+
- Rebecca Lauren Miller -- initial version of reduction as part of GSOC 2016
|
|
15
|
+
|
|
16
|
+
- Ben Hutz (2018-7) -- improvements to reduce and implement smallest coefficient model
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# ****************************************************************************
|
|
20
|
+
# Copyright (C) 2018 Benjamin Hutz <bn4941#gmail.com>
|
|
21
|
+
#
|
|
22
|
+
# This program is free software: you can redistribute it and/or modify
|
|
23
|
+
# it under the terms of the GNU General Public License as published by
|
|
24
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
25
|
+
# (at your option) any later version.
|
|
26
|
+
# https://www.gnu.org/licenses/
|
|
27
|
+
# ****************************************************************************
|
|
28
|
+
|
|
29
|
+
from sage.matrix.constructor import matrix
|
|
30
|
+
from sage.misc.lazy_import import lazy_import
|
|
31
|
+
from sage.misc.misc_c import prod
|
|
32
|
+
from sage.modules.free_module_element import vector
|
|
33
|
+
from sage.rings.cc import CC
|
|
34
|
+
from sage.rings.complex_mpfr import ComplexField
|
|
35
|
+
from sage.rings.complex_interval_field import ComplexIntervalField
|
|
36
|
+
from sage.rings.integer_ring import ZZ
|
|
37
|
+
from sage.rings.laurent_series_ring import LaurentSeriesRing
|
|
38
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
39
|
+
from sage.rings.rational_field import QQ
|
|
40
|
+
from sage.rings.real_mpfr import RealField
|
|
41
|
+
|
|
42
|
+
lazy_import("sage.calculus.functions", "jacobian")
|
|
43
|
+
lazy_import("sage.functions.hyperbolic", ["cosh", "sinh"])
|
|
44
|
+
lazy_import("sage.functions.log", "exp")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def covariant_z0(F, z0_cov=False, prec=53, emb=None, error_limit=0.000001):
|
|
48
|
+
r"""
|
|
49
|
+
Return the covariant and Julia invariant from Cremona-Stoll [CS2003]_.
|
|
50
|
+
|
|
51
|
+
In [CS2003]_ and [HS2018]_ the Julia invariant is denoted as `\Theta(F)`
|
|
52
|
+
or `R(F, z(F))`. Note that you may get faster convergence if you first move
|
|
53
|
+
`z_0(F)` to the fundamental domain before computing the true covariant
|
|
54
|
+
|
|
55
|
+
INPUT:
|
|
56
|
+
|
|
57
|
+
- ``F`` -- binary form of degree at least 3 with no multiple roots
|
|
58
|
+
|
|
59
|
+
- ``z0_cov`` -- boolean, compute only the `z_0` invariant. Otherwise, solve
|
|
60
|
+
the minimization problem
|
|
61
|
+
|
|
62
|
+
- ``prec`` -- positive integer. precision to use in CC
|
|
63
|
+
|
|
64
|
+
- ``emb`` -- embedding into CC
|
|
65
|
+
|
|
66
|
+
- ``error_limit`` -- sets the error tolerance (default: 0.000001)
|
|
67
|
+
|
|
68
|
+
OUTPUT: a complex number, a real number
|
|
69
|
+
|
|
70
|
+
EXAMPLES::
|
|
71
|
+
|
|
72
|
+
sage: from sage.rings.polynomial.binary_form_reduce import covariant_z0
|
|
73
|
+
sage: R.<x,y> = QQ[]
|
|
74
|
+
sage: F = 19*x^8 - 262*x^7*y + 1507*x^6*y^2 - 4784*x^5*y^3 + 9202*x^4*y^4\
|
|
75
|
+
....: - 10962*x^3*y^5 + 7844*x^2*y^6 - 3040*x*y^7 + 475*y^8
|
|
76
|
+
sage: covariant_z0(F, prec=80, z0_cov=True)
|
|
77
|
+
(1.3832330115323681438175 + 0.31233552177413614978744*I,
|
|
78
|
+
3358.4074848663492819259)
|
|
79
|
+
sage: F = -x^8 + 6*x^7*y - 7*x^6*y^2 - 12*x^5*y^3 + 27*x^4*y^4\
|
|
80
|
+
....: - 4*x^3*y^5 - 19*x^2*y^6 + 10*x*y^7 - 5*y^8
|
|
81
|
+
sage: covariant_z0(F, prec=80)
|
|
82
|
+
(0.64189877107807122203366 + 1.1852516565091601348355*I,
|
|
83
|
+
3134.5148284344627168276)
|
|
84
|
+
|
|
85
|
+
::
|
|
86
|
+
|
|
87
|
+
sage: R.<x,y> = QQ[]
|
|
88
|
+
sage: covariant_z0(x^3 + 2*x^2*y - 3*x*y^2, z0_cov=True)[0]
|
|
89
|
+
0.230769230769231 + 0.799408065031789*I
|
|
90
|
+
sage: -1/covariant_z0(-y^3 + 2*y^2*x + 3*y*x^2, z0_cov=True)[0]
|
|
91
|
+
0.230769230769231 + 0.799408065031789*I
|
|
92
|
+
|
|
93
|
+
::
|
|
94
|
+
|
|
95
|
+
sage: R.<x,y> = QQ[]
|
|
96
|
+
sage: covariant_z0(2*x^2*y - 3*x*y^2, z0_cov=True)[0]
|
|
97
|
+
0.750000000000000 + 1.29903810567666*I
|
|
98
|
+
sage: -1/covariant_z0(-x^3 - x^2*y + 2*x*y^2, z0_cov=True)[0] + 1
|
|
99
|
+
0.750000000000000 + 1.29903810567666*I
|
|
100
|
+
|
|
101
|
+
::
|
|
102
|
+
|
|
103
|
+
sage: R.<x,y> = QQ[]
|
|
104
|
+
sage: covariant_z0(x^2*y - x*y^2, prec=100) # tol 1e-28
|
|
105
|
+
(0.50000000000000000000000000003 + 0.86602540378443864676372317076*I,
|
|
106
|
+
1.5396007178390020386910634147)
|
|
107
|
+
|
|
108
|
+
TESTS::
|
|
109
|
+
|
|
110
|
+
sage: R.<x,y>=QQ[]
|
|
111
|
+
sage: covariant_z0(x^2 + 24*x*y + y^2)
|
|
112
|
+
Traceback (most recent call last):
|
|
113
|
+
...
|
|
114
|
+
ValueError: must be at least degree 3
|
|
115
|
+
sage: covariant_z0((x+y)^3, z0_cov=True)
|
|
116
|
+
Traceback (most recent call last):
|
|
117
|
+
...
|
|
118
|
+
ValueError: cannot have multiple roots for z0 invariant
|
|
119
|
+
sage: covariant_z0(x^3 + 3*x*y + y)
|
|
120
|
+
Traceback (most recent call last):
|
|
121
|
+
...
|
|
122
|
+
TypeError: must be a binary form
|
|
123
|
+
sage: covariant_z0(-2*x^2*y^3 + 3*x*y^4 + 127*y^5)
|
|
124
|
+
Traceback (most recent call last):
|
|
125
|
+
...
|
|
126
|
+
ValueError: cannot have a root with multiplicity >= 5/2
|
|
127
|
+
sage: covariant_z0((x^2+2*y^2)^2)
|
|
128
|
+
Traceback (most recent call last):
|
|
129
|
+
...
|
|
130
|
+
ValueError: must have at least 3 distinct roots
|
|
131
|
+
"""
|
|
132
|
+
R = F.parent()
|
|
133
|
+
d = ZZ(F.degree())
|
|
134
|
+
if R.ngens() != 2 or any(sum(t) != d for t in F.exponents()):
|
|
135
|
+
raise TypeError('must be a binary form')
|
|
136
|
+
if d < 3:
|
|
137
|
+
raise ValueError('must be at least degree 3')
|
|
138
|
+
|
|
139
|
+
f = F.subs({R.gen(1): 1}).univariate_polynomial()
|
|
140
|
+
if f.degree() < d:
|
|
141
|
+
# we have a root at infinity
|
|
142
|
+
if f.constant_coefficient() != 0:
|
|
143
|
+
# invert so we find all roots!
|
|
144
|
+
mat = matrix(ZZ, 2, 2, [0, -1, 1, 0])
|
|
145
|
+
else:
|
|
146
|
+
t = 0
|
|
147
|
+
while f(t) == 0:
|
|
148
|
+
t += 1
|
|
149
|
+
mat = matrix(ZZ, 2, 2, [t, -1, 1, 0])
|
|
150
|
+
else:
|
|
151
|
+
mat = matrix(ZZ, 2, 2, [1, 0, 0, 1])
|
|
152
|
+
f = F(list(mat * vector(R.gens()))).subs({R.gen(1): 1}).univariate_polynomial()
|
|
153
|
+
# now we have a single variable polynomial with all the roots of F
|
|
154
|
+
K = ComplexField(prec=prec)
|
|
155
|
+
if f.base_ring() != K:
|
|
156
|
+
if emb is None:
|
|
157
|
+
f = f.change_ring(K)
|
|
158
|
+
else:
|
|
159
|
+
f = f.change_ring(emb)
|
|
160
|
+
roots = f.roots()
|
|
161
|
+
if max(ex for _, ex in roots) > 1 or f.degree() < d - 1:
|
|
162
|
+
if z0_cov:
|
|
163
|
+
raise ValueError('cannot have multiple roots for z0 invariant')
|
|
164
|
+
else:
|
|
165
|
+
# just need a starting point for Newton's method
|
|
166
|
+
f = f.lc() * prod(p for p, ex in f.factor()) # removes multiple roots
|
|
167
|
+
if f.degree() < 3:
|
|
168
|
+
raise ValueError('must have at least 3 distinct roots')
|
|
169
|
+
roots = f.roots()
|
|
170
|
+
roots = [p for p, _ in roots]
|
|
171
|
+
|
|
172
|
+
# finding quadratic Q_0, gives us our covariant, z_0
|
|
173
|
+
dF = f.derivative()
|
|
174
|
+
n = ZZ(f.degree())
|
|
175
|
+
PR = PolynomialRing(K, 'x,y')
|
|
176
|
+
x, y = PR.gens()
|
|
177
|
+
# finds Stoll and Cremona's Q_0
|
|
178
|
+
q = sum([(1/(dF(r).abs()**(2/(n-2)))) * ((x-(r*y)) * (x-(r.conjugate()*y)))
|
|
179
|
+
for r in roots])
|
|
180
|
+
# this is Q_0 , always positive def as long as F has distinct roots
|
|
181
|
+
A = q.monomial_coefficient(x**2)
|
|
182
|
+
B = q.monomial_coefficient(x * y)
|
|
183
|
+
C = q.monomial_coefficient(y**2)
|
|
184
|
+
# need positive root
|
|
185
|
+
try:
|
|
186
|
+
z = ((-B + ((B**2)-(4*A*C)).sqrt()) / (2 * A))
|
|
187
|
+
except ValueError:
|
|
188
|
+
raise ValueError("not enough precision")
|
|
189
|
+
if z.imag() < 0:
|
|
190
|
+
z = (-B - ((B**2)-(4*A*C)).sqrt()) / (2 * A)
|
|
191
|
+
|
|
192
|
+
if z0_cov:
|
|
193
|
+
FM = f # for Julia's invariant
|
|
194
|
+
else:
|
|
195
|
+
# solve the minimization problem for 'true' covariant
|
|
196
|
+
CF = ComplexIntervalField(prec=prec) # keeps track of our precision error
|
|
197
|
+
z = CF(z)
|
|
198
|
+
FM = F(list(mat * vector(R.gens()))).subs({R.gen(1): 1}).univariate_polynomial()
|
|
199
|
+
from sage.rings.polynomial.complex_roots import complex_roots
|
|
200
|
+
L1 = complex_roots(FM, min_prec=prec)
|
|
201
|
+
L = []
|
|
202
|
+
# making sure multiplicity isn't too large using convergence conditions in paper
|
|
203
|
+
for p, e in L1:
|
|
204
|
+
if e >= d / 2:
|
|
205
|
+
raise ValueError('cannot have a root with multiplicity >= %s/2' % d)
|
|
206
|
+
L.extend(p for _ in range(e))
|
|
207
|
+
RCF = PolynomialRing(CF, 'u,t')
|
|
208
|
+
a = RCF.zero()
|
|
209
|
+
c = RCF.zero()
|
|
210
|
+
u, t = RCF.gens()
|
|
211
|
+
for l in L:
|
|
212
|
+
denom = ((t - l) * (t - l.conjugate()) + u**2)
|
|
213
|
+
a += u**2 / denom
|
|
214
|
+
c += (t - l.real()) / denom
|
|
215
|
+
# Newton's Method, to find solutions. Error bound is less than diameter of our z
|
|
216
|
+
err = z.diameter()
|
|
217
|
+
zz = z.diameter()
|
|
218
|
+
g1 = a.numerator() - d / 2 * a.denominator()
|
|
219
|
+
g2 = c.numerator()
|
|
220
|
+
G = vector([g1, g2])
|
|
221
|
+
J = jacobian(G, [u, t])
|
|
222
|
+
v0 = vector([z.imag(), z.real()]) # z0 as starting point
|
|
223
|
+
# finds our correct z
|
|
224
|
+
while err <= zz:
|
|
225
|
+
NJ = J.subs({u: v0[0], t: v0[1]})
|
|
226
|
+
NJinv = NJ.inverse()
|
|
227
|
+
# inverse for CIF matrix seems to return fractions not CIF elements, fix them
|
|
228
|
+
if NJinv.base_ring() != CF:
|
|
229
|
+
NJinv = matrix(CF, 2, 2, [CF(zw.numerator() / zw.denominator())
|
|
230
|
+
for zw in NJinv.list()])
|
|
231
|
+
w = z
|
|
232
|
+
v0 = v0 - NJinv*G.subs({u: v0[0], t: v0[1]})
|
|
233
|
+
z = v0[1].constant_coefficient() + v0[0].constant_coefficient()*CF.gen(0)
|
|
234
|
+
err = z.diameter() # precision
|
|
235
|
+
zz = (w - z).abs().lower() # difference in w and z
|
|
236
|
+
# despite there is no break, this happens
|
|
237
|
+
if err > error_limit or err.is_NaN():
|
|
238
|
+
raise ValueError("accuracy of Newton's root not within tolerance(%s > %s), increase precision" % (err, error_limit))
|
|
239
|
+
if z.imag().upper() <= z.diameter():
|
|
240
|
+
raise ArithmeticError("Newton's method converged to z not in the upper half plane")
|
|
241
|
+
z = z.center()
|
|
242
|
+
|
|
243
|
+
# Julia's invariant
|
|
244
|
+
if FM.base_ring() != ComplexField(prec=prec):
|
|
245
|
+
FM = FM.change_ring(ComplexField(prec=prec))
|
|
246
|
+
tF = z.real()
|
|
247
|
+
uF = z.imag()
|
|
248
|
+
th = FM.lc().abs()**2
|
|
249
|
+
for r, ex in FM.roots():
|
|
250
|
+
for _ in range(ex):
|
|
251
|
+
th = th * ((((r-tF).abs())**2 + uF**2)/uF)
|
|
252
|
+
|
|
253
|
+
# undo shift and invert (if needed)
|
|
254
|
+
# since F \cdot m ~ m^(-1)\cdot z
|
|
255
|
+
# we apply m to z to undo m acting on F
|
|
256
|
+
l = mat * vector([z, 1])
|
|
257
|
+
return l[0] / l[1], th
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
# // compute inverse of eps_F
|
|
261
|
+
# from Michael Stoll
|
|
262
|
+
def epsinv(F, target, prec=53, target_tol=0.001, z=None, emb=None):
|
|
263
|
+
"""
|
|
264
|
+
Compute a bound on the hyperbolic distance.
|
|
265
|
+
|
|
266
|
+
The true minimum will be within the computed bound.
|
|
267
|
+
It is computed as the inverse of epsilon_F from [HS2018]_.
|
|
268
|
+
|
|
269
|
+
INPUT:
|
|
270
|
+
|
|
271
|
+
- ``F`` -- binary form of degree at least 3 with no multiple roots
|
|
272
|
+
|
|
273
|
+
- ``target`` -- positive real number; the value we want to attain, i.e.,
|
|
274
|
+
the value we are taking the inverse of
|
|
275
|
+
|
|
276
|
+
- ``prec`` -- positive integer; precision to use in CC
|
|
277
|
+
|
|
278
|
+
- ``target_tol`` -- positive real number; the tolerance with which we
|
|
279
|
+
attain the target value
|
|
280
|
+
|
|
281
|
+
- ``z`` -- complex number; ``z_0`` covariant for F
|
|
282
|
+
|
|
283
|
+
- ``emb`` -- embedding into CC
|
|
284
|
+
|
|
285
|
+
OUTPUT: a real number delta satisfying target + target_tol > eps_F(delta) > target.
|
|
286
|
+
|
|
287
|
+
EXAMPLES::
|
|
288
|
+
|
|
289
|
+
sage: from sage.rings.polynomial.binary_form_reduce import epsinv
|
|
290
|
+
sage: R.<x,y> = QQ[]
|
|
291
|
+
sage: epsinv(-2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3, 31.5022020249597) # tol 1e-12
|
|
292
|
+
4.02520895942207
|
|
293
|
+
"""
|
|
294
|
+
def RQ(delta):
|
|
295
|
+
# this is the quotient R(F_0,z)/R(F_0,z(F)) for a generic z
|
|
296
|
+
# at distance delta from j. See Lemma 4.2 in [HS2018].
|
|
297
|
+
cd = cosh(delta).n(prec=prec)
|
|
298
|
+
sd = sinh(delta).n(prec=prec)
|
|
299
|
+
return prod([cd + (cost * phi[0] + sint * phi[1]) * sd for phi in phis])
|
|
300
|
+
|
|
301
|
+
def epsF(delta):
|
|
302
|
+
pol = RQ(delta) # get R quotient in terms of z
|
|
303
|
+
S = PolynomialRing(C, 'v')
|
|
304
|
+
g = S([(i - d) * pol[i - d] for i in range(2 * d + 1)]) # take derivative
|
|
305
|
+
drts = [e for e in g.roots(ring=C, multiplicities=False)
|
|
306
|
+
if (e.norm() - 1).abs() < 0.1]
|
|
307
|
+
# find min
|
|
308
|
+
return min([pol(r / r.abs()).real() for r in drts])
|
|
309
|
+
|
|
310
|
+
C = ComplexField(prec=prec)
|
|
311
|
+
R = F.parent()
|
|
312
|
+
d = F.degree()
|
|
313
|
+
if z is None:
|
|
314
|
+
z, th = covariant_z0(F, prec=prec, emb=emb)
|
|
315
|
+
else: # need to do our own input checking
|
|
316
|
+
if R.ngens() != 2 or any(sum(t) != d for t in F.exponents()):
|
|
317
|
+
raise TypeError('must be a binary form')
|
|
318
|
+
if d < 3:
|
|
319
|
+
raise ValueError('must be at least degree 3')
|
|
320
|
+
|
|
321
|
+
f = F.subs({R.gen(1): 1}).univariate_polynomial()
|
|
322
|
+
# now we have a single variable polynomial
|
|
323
|
+
if (max(ex for p, ex in f.roots(ring=C)) >= QQ(d)/2 or
|
|
324
|
+
f.degree() < QQ(d)/2):
|
|
325
|
+
raise ValueError('cannot have root with multiplicity >= deg(F)/2')
|
|
326
|
+
|
|
327
|
+
R = RealField(prec=prec)
|
|
328
|
+
PR = PolynomialRing(R, 't')
|
|
329
|
+
t = PR.gen(0)
|
|
330
|
+
# compute phi_1, ..., phi_k
|
|
331
|
+
# first find F_0 and its roots
|
|
332
|
+
# this change of variables on f moves z(f) to j, i.e. produces F_0
|
|
333
|
+
rts = f(z.imag()*t + z.real()).roots(ring=C)
|
|
334
|
+
phis = [] # stereographic projection of roots
|
|
335
|
+
for r, e in rts:
|
|
336
|
+
phis.extend([[2*r.real()/(r.norm()+1), (r.norm()-1)/(r.norm()+1)]])
|
|
337
|
+
if d != f.degree(): # include roots at infinity
|
|
338
|
+
phis.extend([(d - f.degree()) * [0, 1]])
|
|
339
|
+
|
|
340
|
+
# for writing RQ in terms of generic z to minimize
|
|
341
|
+
LC = LaurentSeriesRing(C, 'u', default_prec=2 * d + 2)
|
|
342
|
+
u = LC.gen(0)
|
|
343
|
+
cost = (u + u**(-1)) / 2
|
|
344
|
+
sint = (u - u**(-1)) / (2 * C.gen(0))
|
|
345
|
+
|
|
346
|
+
# first find an interval containing the desired value
|
|
347
|
+
# then use regula falsi on log eps_F
|
|
348
|
+
# d -> delta value in interval [0,1]
|
|
349
|
+
# v in value in interval [1,epsF(1)]
|
|
350
|
+
dl = R(0.0)
|
|
351
|
+
vl = R(1.0)
|
|
352
|
+
du = R(1.0)
|
|
353
|
+
vu = epsF(du)
|
|
354
|
+
while vu < target:
|
|
355
|
+
# compute the next value of epsF for delta = 2*delta
|
|
356
|
+
dl = du
|
|
357
|
+
vl = vu
|
|
358
|
+
du *= 2
|
|
359
|
+
vu = epsF(du)
|
|
360
|
+
# now dl < delta <= du
|
|
361
|
+
logt = target.log()
|
|
362
|
+
l2 = (vu.log() - logt).n(prec=prec)
|
|
363
|
+
l1 = (vl.log() - logt).n(prec=prec)
|
|
364
|
+
dn = (dl*l2 - du*l1)/(l2 - l1)
|
|
365
|
+
vn = epsF(dn)
|
|
366
|
+
dl = du
|
|
367
|
+
vl = vu
|
|
368
|
+
du = dn
|
|
369
|
+
vu = vn
|
|
370
|
+
while (du - dl).abs() >= target_tol or max(vl, vu) < target:
|
|
371
|
+
l2 = (vu.log() - logt).n(prec=prec)
|
|
372
|
+
l1 = (vl.log() - logt).n(prec=prec)
|
|
373
|
+
dn = (dl * l2 - du * l1) / (l2 - l1)
|
|
374
|
+
vn = epsF(dn)
|
|
375
|
+
dl = du
|
|
376
|
+
vl = vu
|
|
377
|
+
du = dn
|
|
378
|
+
vu = vn
|
|
379
|
+
return max(dl, du)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def get_bound_poly(F, prec=53, norm_type='norm', emb=None):
|
|
383
|
+
"""
|
|
384
|
+
The hyperbolic distance from `j` which must contain the smallest poly.
|
|
385
|
+
|
|
386
|
+
This defines the maximum possible distance from `j` to the `z_0` covariant
|
|
387
|
+
in the hyperbolic 3-space for which the associated `F` could have smaller
|
|
388
|
+
coefficients.
|
|
389
|
+
|
|
390
|
+
INPUT:
|
|
391
|
+
|
|
392
|
+
- ``F`` -- binary form of degree at least 3 with no multiple roots
|
|
393
|
+
|
|
394
|
+
- ``prec`` -- positive integer. precision to use in CC
|
|
395
|
+
|
|
396
|
+
- ``norm_type`` -- string, either norm or height
|
|
397
|
+
|
|
398
|
+
- ``emb`` -- embedding into CC
|
|
399
|
+
|
|
400
|
+
OUTPUT: a positive real number
|
|
401
|
+
|
|
402
|
+
EXAMPLES::
|
|
403
|
+
|
|
404
|
+
sage: from sage.rings.polynomial.binary_form_reduce import get_bound_poly
|
|
405
|
+
sage: R.<x,y> = QQ[]
|
|
406
|
+
sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3
|
|
407
|
+
sage: get_bound_poly(F) # tol 1e-12
|
|
408
|
+
28.0049336543295
|
|
409
|
+
sage: get_bound_poly(F, norm_type='height') # tol 1e-11
|
|
410
|
+
111.890642019092
|
|
411
|
+
"""
|
|
412
|
+
if F.base_ring() != ComplexField(prec=prec):
|
|
413
|
+
if emb is None:
|
|
414
|
+
compF = F.change_ring(ComplexField(prec=prec))
|
|
415
|
+
else:
|
|
416
|
+
compF = F.change_ring(emb)
|
|
417
|
+
else:
|
|
418
|
+
compF = F
|
|
419
|
+
n = F.degree()
|
|
420
|
+
assert (n > 2), "degree 2 polynomial"
|
|
421
|
+
|
|
422
|
+
z0F, thetaF = covariant_z0(compF, prec=prec, emb=emb)
|
|
423
|
+
if norm_type == 'norm':
|
|
424
|
+
# euclidean norm squared
|
|
425
|
+
normF = (sum([abs(i)**2 for i in compF.coefficients()]))
|
|
426
|
+
target = (2**(n - 1)) * normF / thetaF
|
|
427
|
+
elif norm_type == 'height':
|
|
428
|
+
hF = exp(max([c.global_height(prec=prec) for c in F.coefficients()])) # height
|
|
429
|
+
target = (2**(n - 1)) * (n + 1) * (hF**2) / thetaF
|
|
430
|
+
else:
|
|
431
|
+
raise ValueError('type must be norm or height')
|
|
432
|
+
return cosh(epsinv(F, target, prec=prec))
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
def smallest_poly(F, prec=53, norm_type='norm', emb=None):
|
|
436
|
+
r"""
|
|
437
|
+
Determine the poly with smallest coefficients in `SL(2,\Z)` orbit of ``F``.
|
|
438
|
+
|
|
439
|
+
Smallest can be in the sense of `L_2` norm or height.
|
|
440
|
+
The method is the algorithm in Hutz-Stoll [HS2018]_.
|
|
441
|
+
|
|
442
|
+
``F`` needs to be a binary form with no multiple roots of degree
|
|
443
|
+
at least 3. It should already be reduced in the sense of
|
|
444
|
+
Cremona-Stoll [CS2003]_.
|
|
445
|
+
|
|
446
|
+
INPUT:
|
|
447
|
+
|
|
448
|
+
- ``F`` -- binary form of degree at least 3 with no multiple roots
|
|
449
|
+
|
|
450
|
+
- ``norm_type`` -- string; ``'norm'`` or ``'height'`` controlling what
|
|
451
|
+
``smallest`` means for the coefficients
|
|
452
|
+
|
|
453
|
+
OUTPUT: pair [poly, matrix]
|
|
454
|
+
|
|
455
|
+
EXAMPLES::
|
|
456
|
+
|
|
457
|
+
sage: from sage.rings.polynomial.binary_form_reduce import smallest_poly
|
|
458
|
+
sage: R.<x,y> = QQ[]
|
|
459
|
+
sage: F = -x^8 + 6*x^7*y - 7*x^6*y^2 - 12*x^5*y^3 + 27*x^4*y^4\
|
|
460
|
+
....: - 4*x^3*y^5 - 19*x^2*y^6 + 10*x*y^7 - 5*y^8
|
|
461
|
+
sage: smallest_poly(F, prec=100) #long time
|
|
462
|
+
[
|
|
463
|
+
-x^8 - 2*x^7*y + 7*x^6*y^2 + 16*x^5*y^3 + 2*x^4*y^4 - 2*x^3*y^5 + 4*x^2*y^6 - 5*y^8,
|
|
464
|
+
<BLANKLINE>
|
|
465
|
+
[1 1]
|
|
466
|
+
[0 1]
|
|
467
|
+
]
|
|
468
|
+
|
|
469
|
+
::
|
|
470
|
+
|
|
471
|
+
sage: from sage.rings.polynomial.binary_form_reduce import smallest_poly, get_bound_poly
|
|
472
|
+
sage: R.<x,y> = QQ[]
|
|
473
|
+
sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3
|
|
474
|
+
sage: smallest_poly(F)
|
|
475
|
+
[
|
|
476
|
+
[1 4]
|
|
477
|
+
-2*x^3 - 22*x^2*y - 77*x*y^2 + 43*y^3, [0 1]
|
|
478
|
+
]
|
|
479
|
+
sage: F0, M = smallest_poly(F, norm_type='height')
|
|
480
|
+
sage: F0, M # random
|
|
481
|
+
(
|
|
482
|
+
[5 4]
|
|
483
|
+
-58*x^3 - 47*x^2*y + 52*x*y^2 + 43*y^3, [1 1]
|
|
484
|
+
)
|
|
485
|
+
sage: M in SL2Z, F0 == R.hom(M * vector([x, y]))(F)
|
|
486
|
+
(True, True)
|
|
487
|
+
sage: get_bound_poly(F0, norm_type='height') # tol 1e-12
|
|
488
|
+
23.3402702199809
|
|
489
|
+
|
|
490
|
+
An example with a multiple root::
|
|
491
|
+
|
|
492
|
+
sage: R.<x,y> = QQ[]
|
|
493
|
+
sage: F = -16*x^7 - 114*x^6*y - 345*x^5*y^2 - 599*x^4*y^3 - 666*x^3*y^4\
|
|
494
|
+
....: - 481*x^2*y^5 - 207*x*y^6 - 40*y^7
|
|
495
|
+
sage: F.reduced_form()
|
|
496
|
+
(
|
|
497
|
+
[-1 -1]
|
|
498
|
+
-x^5*y^2 - 24*x^3*y^4 - 3*x^2*y^5 - 2*x*y^6 + 16*y^7, [ 1 0]
|
|
499
|
+
)
|
|
500
|
+
"""
|
|
501
|
+
def insert_item(pts, item, index):
|
|
502
|
+
# binary insertion to maintain list of points left to consider
|
|
503
|
+
N = len(pts)
|
|
504
|
+
if N == 0:
|
|
505
|
+
return [item]
|
|
506
|
+
elif N == 1:
|
|
507
|
+
if item[index] > pts[0][index]:
|
|
508
|
+
pts.insert(0, item)
|
|
509
|
+
else:
|
|
510
|
+
pts.append(item)
|
|
511
|
+
return pts
|
|
512
|
+
else: # binary insertion
|
|
513
|
+
left = 1
|
|
514
|
+
right = N
|
|
515
|
+
mid = (left + right) // 2 # these are ints so this is .floor()
|
|
516
|
+
if item[index] > pts[mid][index]: # item goes into first half
|
|
517
|
+
return insert_item(pts[:mid], item, index) + pts[mid:N]
|
|
518
|
+
else: # item goes into second half
|
|
519
|
+
return pts[:mid] + insert_item(pts[mid:N], item, index)
|
|
520
|
+
|
|
521
|
+
def coshdelta(z):
|
|
522
|
+
# The cosh of the hyperbolic distance from z = t+uj to j
|
|
523
|
+
return (z.norm() + 1)/(2*z.imag()) # reduce in the sense of Cremona-Stoll
|
|
524
|
+
G = F
|
|
525
|
+
MG = matrix(ZZ, 2, 2, [1, 0, 0, 1])
|
|
526
|
+
x, y = G.parent().gens()
|
|
527
|
+
if norm_type == 'norm':
|
|
528
|
+
current_size = sum([abs(i)**2 for i in G.coefficients()]) # euclidean norm squared
|
|
529
|
+
elif norm_type == 'height': # height
|
|
530
|
+
current_size = exp(max([c.global_height(prec=prec) for c in G.coefficients()]))
|
|
531
|
+
else:
|
|
532
|
+
raise ValueError('type must be norm or height')
|
|
533
|
+
v0, th = covariant_z0(G, prec=prec, emb=emb)
|
|
534
|
+
rep = 2 * CC.gen(0) # representative point in fundamental domain
|
|
535
|
+
from math import isnan
|
|
536
|
+
if isnan(v0.abs()):
|
|
537
|
+
raise ValueError("invalid covariant: %s" % v0)
|
|
538
|
+
R = get_bound_poly(G, prec=prec, norm_type=norm_type)
|
|
539
|
+
|
|
540
|
+
# check orbit
|
|
541
|
+
S = matrix(ZZ, 2, 2, [0, -1, 1, 0])
|
|
542
|
+
T = matrix(ZZ, 2, 2, [1, 1, 0, 1])
|
|
543
|
+
TI = matrix(ZZ, 2, 2, [1, -1, 0, 1])
|
|
544
|
+
|
|
545
|
+
count = 0
|
|
546
|
+
pts = [[G, v0, rep, MG, coshdelta(v0), 0]] # label - 0:None, 1:S, 2:T, 3:T^(-1)
|
|
547
|
+
current_min = [G, v0, rep, MG, coshdelta(v0)]
|
|
548
|
+
while pts:
|
|
549
|
+
G, v, rep, M, D, label = pts.pop()
|
|
550
|
+
# apply ST and keep z, Sz
|
|
551
|
+
if D > R:
|
|
552
|
+
break # all remaining pts are too far away
|
|
553
|
+
# check if it is smaller. If so, we can improve the bound
|
|
554
|
+
count += 1
|
|
555
|
+
if norm_type == 'norm':
|
|
556
|
+
new_size = sum([abs(i)**2 for i in G.coefficients()]) # euclidean norm squared
|
|
557
|
+
else: # height
|
|
558
|
+
new_size = exp(max([c.global_height(prec=prec) for c in G.coefficients()]))
|
|
559
|
+
if new_size < current_size:
|
|
560
|
+
current_min = [G, v, rep, M, coshdelta(v)]
|
|
561
|
+
current_size = new_size
|
|
562
|
+
R = get_bound_poly(G, norm_type=norm_type, prec=prec, emb=emb)
|
|
563
|
+
|
|
564
|
+
# add new points to check
|
|
565
|
+
if label != 1 and min((rep+1).norm(), (rep-1).norm()) >= 1: # don't undo S
|
|
566
|
+
# the 2nd condition is equivalent to |\Re(-1/rep)| <= 1/2
|
|
567
|
+
# this means that rep can have resulted from an inversion step in
|
|
568
|
+
# the shift-and-invert procedure, so don't invert
|
|
569
|
+
|
|
570
|
+
# do inversion
|
|
571
|
+
z = -1 / v
|
|
572
|
+
new_pt = [G.subs({x: -y, y: x}), z, -1/rep, M*S, coshdelta(z), 1]
|
|
573
|
+
pts = insert_item(pts, new_pt, 4)
|
|
574
|
+
if label != 3: # don't undo TI
|
|
575
|
+
# do right shift
|
|
576
|
+
z = v - 1
|
|
577
|
+
new_pt = [G.subs({x: x + y}), z, rep-1, M*T, coshdelta(z), 2]
|
|
578
|
+
pts = insert_item(pts, new_pt, 4)
|
|
579
|
+
if label != 2: # don't undo T
|
|
580
|
+
# do left shift
|
|
581
|
+
z = v + 1
|
|
582
|
+
new_pt = [G.subs({x: x - y}), z, rep + 1, M * TI, coshdelta(z), 3]
|
|
583
|
+
pts = insert_item(pts, new_pt, 4)
|
|
584
|
+
|
|
585
|
+
return [current_min[0], current_min[3]]
|
sage/schemes/all.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
"""
|
|
3
|
+
all.py -- export of schemes to Sage
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# *****************************************************************************
|
|
7
|
+
#
|
|
8
|
+
# Sage: Open Source Mathematical Software
|
|
9
|
+
#
|
|
10
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
11
|
+
#
|
|
12
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
13
|
+
#
|
|
14
|
+
# This code is distributed in the hope that it will be useful,
|
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
17
|
+
# General Public License for more details.
|
|
18
|
+
#
|
|
19
|
+
# The full text of the GPL is available at:
|
|
20
|
+
#
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# *****************************************************************************
|
|
23
|
+
|
|
24
|
+
from sage.schemes.all__sagemath_categories import *
|
|
25
|
+
from sage.schemes.all__sagemath_polyhedra import *
|
|
26
|
+
|
|
27
|
+
from sage.schemes.jacobians.all import *
|
|
28
|
+
|
|
29
|
+
from sage.schemes.hyperelliptic_curves.all import *
|
|
30
|
+
|
|
31
|
+
from sage.schemes.curves.all import *
|
|
32
|
+
|
|
33
|
+
from sage.schemes.plane_conics.all import *
|
|
34
|
+
|
|
35
|
+
from sage.schemes.elliptic_curves.all import *
|
|
36
|
+
|
|
37
|
+
from sage.schemes.plane_quartics.all import *
|
|
38
|
+
|
|
39
|
+
from sage.schemes.cyclic_covers.all import *
|
|
40
|
+
|
|
41
|
+
from sage.schemes.berkovich.all import *
|