passagemath-schemes 10.6.38__cp314-cp314t-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-schemes might be problematic. Click here for more details.
- passagemath_schemes/.dylibs/libflint.21.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.38.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.38.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314t-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-314t-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314t-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.libs.flint sage.libs.gap sage.libs.pari
|
|
3
|
+
r"""
|
|
4
|
+
Congruence arithmetic subgroups of `\SL_2(\ZZ)`
|
|
5
|
+
|
|
6
|
+
Sage can compute extensively with the standard congruence subgroups
|
|
7
|
+
`\Gamma_0(N)`, `\Gamma_1(N)`, and `\Gamma_H(N)`.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- William Stein
|
|
12
|
+
- David Loeffler (2009, 10) -- modifications to work with more general arithmetic subgroups
|
|
13
|
+
"""
|
|
14
|
+
################################################################################
|
|
15
|
+
#
|
|
16
|
+
# Copyright (C) 2004, 2006 William Stein <wstein@gmail.com>
|
|
17
|
+
#
|
|
18
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
19
|
+
#
|
|
20
|
+
# The full text of the GPL is available at:
|
|
21
|
+
#
|
|
22
|
+
# https://www.gnu.org/licenses/
|
|
23
|
+
#
|
|
24
|
+
################################################################################
|
|
25
|
+
|
|
26
|
+
from sage.arith.misc import gcd
|
|
27
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
28
|
+
from sage.misc.misc_c import prod
|
|
29
|
+
from sage.rings.finite_rings.integer_mod_ring import Zmod
|
|
30
|
+
from sage.rings.integer_ring import ZZ
|
|
31
|
+
from sage.rings.rational_field import QQ
|
|
32
|
+
from sage.sets.set import Set
|
|
33
|
+
|
|
34
|
+
from .arithgroup_generic import ArithmeticSubgroup
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def CongruenceSubgroup_constructor(*args):
|
|
38
|
+
r"""
|
|
39
|
+
Attempt to create a congruence subgroup from the given data.
|
|
40
|
+
|
|
41
|
+
The allowed inputs are as follows:
|
|
42
|
+
|
|
43
|
+
- A :class:`~sage.groups.matrix_gps.matrix_group.MatrixGroup` object. This
|
|
44
|
+
must be a group of matrices over `\ZZ / N\ZZ` for some `N`, with
|
|
45
|
+
determinant 1, in which case the function will return the group of
|
|
46
|
+
matrices in `SL(2, \ZZ)` whose reduction mod `N` is in the given group.
|
|
47
|
+
|
|
48
|
+
- A list of matrices over `\ZZ / N\ZZ` for some `N`. The function will then
|
|
49
|
+
compute the subgroup of `SL(2, \ZZ)` generated by these matrices, and
|
|
50
|
+
proceed as above.
|
|
51
|
+
|
|
52
|
+
- An integer `N` and a list of matrices (over any ring coercible to `\ZZ /
|
|
53
|
+
N\ZZ`, e.g. over `\ZZ`). The matrices will then be coerced to `\ZZ /
|
|
54
|
+
N\ZZ`.
|
|
55
|
+
|
|
56
|
+
The function checks that the input G is valid. It then tests to see if
|
|
57
|
+
`G` is the preimage mod `N` of some group of matrices modulo a proper
|
|
58
|
+
divisor `M` of `N`, in which case it replaces `G` with this group before
|
|
59
|
+
continuing.
|
|
60
|
+
|
|
61
|
+
EXAMPLES::
|
|
62
|
+
|
|
63
|
+
sage: from sage.modular.arithgroup.congroup_generic import CongruenceSubgroup_constructor as CS
|
|
64
|
+
sage: CS(2, [[1,1,0,1]])
|
|
65
|
+
Congruence subgroup of SL(2,Z) of level 2, preimage of:
|
|
66
|
+
Matrix group over Ring of integers modulo 2 with 1 generators (
|
|
67
|
+
[1 1]
|
|
68
|
+
[0 1]
|
|
69
|
+
)
|
|
70
|
+
sage: CS([matrix(Zmod(2), 2, [1,1,0,1])])
|
|
71
|
+
Congruence subgroup of SL(2,Z) of level 2, preimage of:
|
|
72
|
+
Matrix group over Ring of integers modulo 2 with 1 generators (
|
|
73
|
+
[1 1]
|
|
74
|
+
[0 1]
|
|
75
|
+
)
|
|
76
|
+
sage: CS(MatrixGroup([matrix(Zmod(2), 2, [1,1,0,1])]))
|
|
77
|
+
Congruence subgroup of SL(2,Z) of level 2, preimage of:
|
|
78
|
+
Matrix group over Ring of integers modulo 2 with 1 generators (
|
|
79
|
+
[1 1]
|
|
80
|
+
[0 1]
|
|
81
|
+
)
|
|
82
|
+
sage: CS(SL(2, 2))
|
|
83
|
+
Modular Group SL(2,Z)
|
|
84
|
+
|
|
85
|
+
Some invalid inputs::
|
|
86
|
+
|
|
87
|
+
sage: CS(SU(2, 7))
|
|
88
|
+
Traceback (most recent call last):
|
|
89
|
+
...
|
|
90
|
+
TypeError: Ring of definition must be Z / NZ for some N
|
|
91
|
+
"""
|
|
92
|
+
from sage.groups.matrix_gps.finitely_generated import MatrixGroup
|
|
93
|
+
from sage.groups.matrix_gps.matrix_group import MatrixGroup_base
|
|
94
|
+
|
|
95
|
+
if isinstance(args[0], MatrixGroup_base):
|
|
96
|
+
G = args[0]
|
|
97
|
+
|
|
98
|
+
elif isinstance(args[0], list):
|
|
99
|
+
G = MatrixGroup(args[0])
|
|
100
|
+
|
|
101
|
+
elif args[0] in ZZ:
|
|
102
|
+
M = MatrixSpace(Zmod(args[0]), 2)
|
|
103
|
+
G = MatrixGroup([M(x) for x in args[1]])
|
|
104
|
+
|
|
105
|
+
R = G.matrix_space().base_ring()
|
|
106
|
+
if not hasattr(R, "cover_ring") or R.cover_ring() != ZZ:
|
|
107
|
+
raise TypeError("Ring of definition must be Z / NZ for some N")
|
|
108
|
+
|
|
109
|
+
if not all(x.matrix().det() == 1 for x in G.gens()):
|
|
110
|
+
raise ValueError("Group must be contained in SL(2, Z / N)")
|
|
111
|
+
GG = _minimize_level(G)
|
|
112
|
+
if GG in ZZ:
|
|
113
|
+
from .all import Gamma
|
|
114
|
+
return Gamma(GG)
|
|
115
|
+
else:
|
|
116
|
+
return CongruenceSubgroupFromGroup(GG)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def is_CongruenceSubgroup(x):
|
|
120
|
+
r"""
|
|
121
|
+
Return ``True`` if x is of type CongruenceSubgroup.
|
|
122
|
+
|
|
123
|
+
Note that this may be False even if `x` really is a congruence subgroup --
|
|
124
|
+
it tests whether `x` is "obviously" congruence, i.e.~whether it has a
|
|
125
|
+
congruence subgroup datatype. To test whether or not an arithmetic subgroup
|
|
126
|
+
of `SL(2, \ZZ)` is congruence, use the ``is_congruence()`` method instead.
|
|
127
|
+
|
|
128
|
+
EXAMPLES::
|
|
129
|
+
|
|
130
|
+
sage: from sage.modular.arithgroup.congroup_generic import is_CongruenceSubgroup
|
|
131
|
+
sage: is_CongruenceSubgroup(SL2Z)
|
|
132
|
+
doctest:warning...
|
|
133
|
+
DeprecationWarning: The function is_CongruenceSubgroup is deprecated; use 'isinstance(..., CongruenceSubgroupBase)' instead.
|
|
134
|
+
See https://github.com/sagemath/sage/issues/38035 for details.
|
|
135
|
+
True
|
|
136
|
+
sage: is_CongruenceSubgroup(Gamma0(13))
|
|
137
|
+
True
|
|
138
|
+
sage: is_CongruenceSubgroup(Gamma1(6))
|
|
139
|
+
True
|
|
140
|
+
sage: is_CongruenceSubgroup(GammaH(11, [3]))
|
|
141
|
+
True
|
|
142
|
+
sage: G = ArithmeticSubgroup_Permutation(L = "(1, 2)", R = "(1, 2)"); is_CongruenceSubgroup(G)
|
|
143
|
+
False
|
|
144
|
+
sage: G.is_congruence()
|
|
145
|
+
True
|
|
146
|
+
sage: is_CongruenceSubgroup(SymmetricGroup(3))
|
|
147
|
+
False
|
|
148
|
+
"""
|
|
149
|
+
from sage.misc.superseded import deprecation
|
|
150
|
+
deprecation(38035, "The function is_CongruenceSubgroup is deprecated; use 'isinstance(..., CongruenceSubgroupBase)' instead.")
|
|
151
|
+
return isinstance(x, CongruenceSubgroupBase)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class CongruenceSubgroupBase(ArithmeticSubgroup):
|
|
155
|
+
|
|
156
|
+
def __init__(self, level):
|
|
157
|
+
"""
|
|
158
|
+
Create a congruence subgroup with given level.
|
|
159
|
+
|
|
160
|
+
EXAMPLES::
|
|
161
|
+
|
|
162
|
+
sage: Gamma0(500)
|
|
163
|
+
Congruence Subgroup Gamma0(500)
|
|
164
|
+
"""
|
|
165
|
+
level = ZZ(level)
|
|
166
|
+
if level <= 0:
|
|
167
|
+
raise ArithmeticError("Congruence groups only defined for positive levels.")
|
|
168
|
+
self.__level = level
|
|
169
|
+
ArithmeticSubgroup.__init__(self)
|
|
170
|
+
|
|
171
|
+
def _an_element_(self):
|
|
172
|
+
r"""
|
|
173
|
+
Return an element of ``self`` (mainly for use by the test suite).
|
|
174
|
+
|
|
175
|
+
EXAMPLES::
|
|
176
|
+
|
|
177
|
+
sage: Gamma(3).an_element() # indirect doctest
|
|
178
|
+
[-2 -3]
|
|
179
|
+
[ 3 4]
|
|
180
|
+
"""
|
|
181
|
+
N = self.level()
|
|
182
|
+
return self([1-N, -N, N, 1+N])
|
|
183
|
+
|
|
184
|
+
def is_congruence(self) -> bool:
|
|
185
|
+
r"""
|
|
186
|
+
Return ``True``, since this is a congruence subgroup.
|
|
187
|
+
|
|
188
|
+
EXAMPLES::
|
|
189
|
+
|
|
190
|
+
sage: Gamma0(7).is_congruence()
|
|
191
|
+
True
|
|
192
|
+
"""
|
|
193
|
+
return True
|
|
194
|
+
|
|
195
|
+
def level(self):
|
|
196
|
+
"""
|
|
197
|
+
Return the level of this congruence subgroup.
|
|
198
|
+
|
|
199
|
+
EXAMPLES::
|
|
200
|
+
|
|
201
|
+
sage: SL2Z.level()
|
|
202
|
+
1
|
|
203
|
+
sage: Gamma0(20).level()
|
|
204
|
+
20
|
|
205
|
+
sage: Gamma1(11).level()
|
|
206
|
+
11
|
|
207
|
+
sage: GammaH(14, [5]).level()
|
|
208
|
+
14
|
|
209
|
+
"""
|
|
210
|
+
return self.__level
|
|
211
|
+
|
|
212
|
+
def __eq__(self, other):
|
|
213
|
+
r"""
|
|
214
|
+
Check that ``self`` is equal to ``other``.
|
|
215
|
+
|
|
216
|
+
EXAMPLES::
|
|
217
|
+
|
|
218
|
+
sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) == Gamma1(3)
|
|
219
|
+
True
|
|
220
|
+
sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) == Gamma(3)
|
|
221
|
+
False
|
|
222
|
+
sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) == QQ
|
|
223
|
+
False
|
|
224
|
+
"""
|
|
225
|
+
# This is carefully laid out so it can be called early on in the Sage
|
|
226
|
+
# startup process when we want to create the standard generators of
|
|
227
|
+
# SL2Z for use in arithgroup_perm. Hence it must work in this case
|
|
228
|
+
# without being able to import the arithgroup_perm module. That's why
|
|
229
|
+
# the most general case is *first*, not last.
|
|
230
|
+
# Note that lazy_import doesn't work here, because it doesn't play
|
|
231
|
+
# nicely with isinstance().
|
|
232
|
+
if not isinstance(other, ArithmeticSubgroup):
|
|
233
|
+
return False
|
|
234
|
+
|
|
235
|
+
elif isinstance(other, CongruenceSubgroupBase):
|
|
236
|
+
if self.level() == other.level() == 1:
|
|
237
|
+
return True
|
|
238
|
+
# shouldn't come up except with pickling/unpickling
|
|
239
|
+
return (self.level() == other.level() and
|
|
240
|
+
self.index() == other.index() and
|
|
241
|
+
self.image_mod_n() == other.image_mod_n())
|
|
242
|
+
|
|
243
|
+
from sage.modular.arithgroup.arithgroup_perm import ArithmeticSubgroup_Permutation_class
|
|
244
|
+
if isinstance(other, ArithmeticSubgroup_Permutation_class):
|
|
245
|
+
return self.as_permutation_group() == other
|
|
246
|
+
|
|
247
|
+
else:
|
|
248
|
+
# we shouldn't ever get here
|
|
249
|
+
raise NotImplementedError
|
|
250
|
+
|
|
251
|
+
def __ne__(self, other):
|
|
252
|
+
"""
|
|
253
|
+
Check that ``self`` is not equal to ``other``.
|
|
254
|
+
|
|
255
|
+
EXAMPLES::
|
|
256
|
+
|
|
257
|
+
sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) != Gamma1(3)
|
|
258
|
+
False
|
|
259
|
+
sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) != Gamma(3)
|
|
260
|
+
True
|
|
261
|
+
sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) != QQ
|
|
262
|
+
True
|
|
263
|
+
"""
|
|
264
|
+
return not (self == other)
|
|
265
|
+
|
|
266
|
+
def __hash__(self):
|
|
267
|
+
"""
|
|
268
|
+
Return the hash of ``self``.
|
|
269
|
+
|
|
270
|
+
EXAMPLES::
|
|
271
|
+
|
|
272
|
+
sage: hash(CongruenceSubgroup(3,[ [1,1,0,1] ])) == hash(Gamma1(3))
|
|
273
|
+
True
|
|
274
|
+
sage: hash(CongruenceSubgroup(3,[ [1,1,0,1] ])) == hash(Gamma(3))
|
|
275
|
+
False
|
|
276
|
+
"""
|
|
277
|
+
return hash((self.level(), self.index()))
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class CongruenceSubgroupFromGroup(CongruenceSubgroupBase):
|
|
281
|
+
r"""
|
|
282
|
+
A congruence subgroup, defined by the data of an integer `N` and a subgroup
|
|
283
|
+
`G` of the finite group `SL(2, \ZZ / N\ZZ)`; the congruence subgroup
|
|
284
|
+
consists of all the matrices in `SL(2, \ZZ)` whose reduction modulo `N`
|
|
285
|
+
lies in `G`.
|
|
286
|
+
|
|
287
|
+
This class should not be instantiated directly, but created using the
|
|
288
|
+
factory function
|
|
289
|
+
:func:`~sage.modular.arithgroup.congroup_generic.CongruenceSubgroup_constructor`,
|
|
290
|
+
which accepts much more flexible input, and checks the input to make sure
|
|
291
|
+
it is valid.
|
|
292
|
+
|
|
293
|
+
TESTS::
|
|
294
|
+
|
|
295
|
+
sage: G = CongruenceSubgroup(5, [[0,-1,1,0]]); G
|
|
296
|
+
Congruence subgroup of SL(2,Z) of level 5, preimage of:
|
|
297
|
+
Matrix group over Ring of integers modulo 5 with 1 generators (
|
|
298
|
+
[0 4]
|
|
299
|
+
[1 0]
|
|
300
|
+
)
|
|
301
|
+
sage: TestSuite(G).run()
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
def __init__(self, G):
|
|
305
|
+
r"""
|
|
306
|
+
Standard init function.
|
|
307
|
+
|
|
308
|
+
TESTS::
|
|
309
|
+
|
|
310
|
+
sage: from sage.modular.arithgroup.congroup_generic import CongruenceSubgroupFromGroup
|
|
311
|
+
sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])
|
|
312
|
+
sage: CongruenceSubgroupFromGroup(G).index() # indirect doctest
|
|
313
|
+
2
|
|
314
|
+
"""
|
|
315
|
+
N = G.base_ring().characteristic()
|
|
316
|
+
self.__G = G
|
|
317
|
+
CongruenceSubgroupBase.__init__(self, N)
|
|
318
|
+
|
|
319
|
+
def __reduce__(self):
|
|
320
|
+
r"""
|
|
321
|
+
Data defining ``self`` (for pickling).
|
|
322
|
+
|
|
323
|
+
EXAMPLES::
|
|
324
|
+
|
|
325
|
+
sage: G = CongruenceSubgroup(5, [[0,-1,1,0]])
|
|
326
|
+
sage: G.__reduce__()
|
|
327
|
+
(<function CongruenceSubgroup_constructor at ...>,
|
|
328
|
+
(Matrix group over Ring of integers modulo 5 with 1 generators (
|
|
329
|
+
[0 4]
|
|
330
|
+
[1 0]
|
|
331
|
+
),))
|
|
332
|
+
"""
|
|
333
|
+
return CongruenceSubgroup_constructor, (self.image_mod_n(),)
|
|
334
|
+
|
|
335
|
+
def _contains_sl2(self, a, b, c, d):
|
|
336
|
+
r"""
|
|
337
|
+
Test whether ``[a,b;c,d]`` is an element of ``self``.
|
|
338
|
+
|
|
339
|
+
EXAMPLES::
|
|
340
|
+
|
|
341
|
+
sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])
|
|
342
|
+
sage: H = sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(G)
|
|
343
|
+
sage: H(1)
|
|
344
|
+
[1 0]
|
|
345
|
+
[0 1]
|
|
346
|
+
sage: H([0,-1,1,0])
|
|
347
|
+
Traceback (most recent call last):
|
|
348
|
+
...
|
|
349
|
+
TypeError: matrix [ 0 -1]
|
|
350
|
+
[ 1 0] is not an element of Congruence subgroup of SL(2,Z) of level 2, preimage of:
|
|
351
|
+
Matrix group over Ring of integers modulo 2 with 1 generators (
|
|
352
|
+
[1 1]
|
|
353
|
+
[1 0]
|
|
354
|
+
)
|
|
355
|
+
sage: H([1,2,0,1])
|
|
356
|
+
[1 2]
|
|
357
|
+
[0 1]
|
|
358
|
+
sage: H(SL2Z([0,-1,1,0]), check=False)
|
|
359
|
+
[ 0 -1]
|
|
360
|
+
[ 1 0]
|
|
361
|
+
sage: H([1,2,0,1]).parent()
|
|
362
|
+
Modular Group SL(2,Z)
|
|
363
|
+
"""
|
|
364
|
+
try:
|
|
365
|
+
self.image_mod_n()([a, b, c, d])
|
|
366
|
+
except (TypeError, ValueError):
|
|
367
|
+
return False
|
|
368
|
+
return True
|
|
369
|
+
|
|
370
|
+
def to_even_subgroup(self):
|
|
371
|
+
r"""
|
|
372
|
+
Return the smallest even subgroup of `SL(2, \ZZ)` containing ``self``.
|
|
373
|
+
|
|
374
|
+
EXAMPLES::
|
|
375
|
+
|
|
376
|
+
sage: G = Gamma(3)
|
|
377
|
+
sage: G.to_even_subgroup()
|
|
378
|
+
Congruence subgroup of SL(2,Z) of level 3, preimage of:
|
|
379
|
+
Matrix group over Ring of integers modulo 3 with 1 generators (
|
|
380
|
+
[2 0]
|
|
381
|
+
[0 2]
|
|
382
|
+
)
|
|
383
|
+
"""
|
|
384
|
+
if self.is_even():
|
|
385
|
+
return self
|
|
386
|
+
else:
|
|
387
|
+
from sage.groups.matrix_gps.finitely_generated import MatrixGroup
|
|
388
|
+
|
|
389
|
+
G = self.image_mod_n()
|
|
390
|
+
H = MatrixGroup([ g.matrix() for g in G.gens()] + [G.matrix_space()(-1)])
|
|
391
|
+
return CongruenceSubgroup_constructor(H)
|
|
392
|
+
|
|
393
|
+
def _repr_(self):
|
|
394
|
+
r"""
|
|
395
|
+
String representation of ``self``.
|
|
396
|
+
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])]))._repr_()
|
|
400
|
+
'Congruence subgroup of SL(2,Z) of level 2, preimage of:\n Matrix group over Ring of integers modulo 2 with 1 generators (\n[1 1]\n[1 0]\n)'
|
|
401
|
+
"""
|
|
402
|
+
return "Congruence subgroup of SL(2,Z) of level %s, preimage of:\n %s" % (self.level(), self.image_mod_n())
|
|
403
|
+
|
|
404
|
+
def index(self):
|
|
405
|
+
r"""
|
|
406
|
+
Return the index of ``self`` in the full modular group. This is equal to
|
|
407
|
+
the index in `SL(2, \ZZ / N\ZZ)` of the image of this group modulo
|
|
408
|
+
`\Gamma(N)`.
|
|
409
|
+
|
|
410
|
+
EXAMPLES::
|
|
411
|
+
|
|
412
|
+
sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])).index()
|
|
413
|
+
2
|
|
414
|
+
"""
|
|
415
|
+
return prod([p**(3*e-2)*(p*p-1) for (p,e) in self.level().factor()]) // self.image_mod_n().order()
|
|
416
|
+
|
|
417
|
+
def image_mod_n(self):
|
|
418
|
+
r"""
|
|
419
|
+
Return the subgroup of `SL(2, \ZZ / N\ZZ)` of which this is the
|
|
420
|
+
preimage, where `N` is the level of ``self``.
|
|
421
|
+
|
|
422
|
+
EXAMPLES::
|
|
423
|
+
|
|
424
|
+
sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])
|
|
425
|
+
sage: H = sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(G); H.image_mod_n()
|
|
426
|
+
Matrix group over Ring of integers modulo 2 with 1 generators (
|
|
427
|
+
[1 1]
|
|
428
|
+
[1 0]
|
|
429
|
+
)
|
|
430
|
+
sage: H.image_mod_n() == G
|
|
431
|
+
True
|
|
432
|
+
"""
|
|
433
|
+
return self.__G
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
class CongruenceSubgroup(CongruenceSubgroupFromGroup):
|
|
437
|
+
r"""
|
|
438
|
+
One of the "standard" congruence subgroups `\Gamma_0(N)`, `\Gamma_1(N)`,
|
|
439
|
+
`\Gamma(N)`, or `\Gamma_H(N)` (for some `H`).
|
|
440
|
+
|
|
441
|
+
This class is not intended to be instantiated directly. Derived subclasses
|
|
442
|
+
must override ``_contains_sl2``, ``_repr_``, and ``image_mod_n``.
|
|
443
|
+
"""
|
|
444
|
+
|
|
445
|
+
def image_mod_n(self):
|
|
446
|
+
r"""
|
|
447
|
+
Raise an error: all derived subclasses should override this function.
|
|
448
|
+
|
|
449
|
+
EXAMPLES::
|
|
450
|
+
|
|
451
|
+
sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5).image_mod_n()
|
|
452
|
+
Traceback (most recent call last):
|
|
453
|
+
...
|
|
454
|
+
NotImplementedError
|
|
455
|
+
"""
|
|
456
|
+
raise NotImplementedError
|
|
457
|
+
|
|
458
|
+
def __init__(self, *args, **kwds):
|
|
459
|
+
r"""
|
|
460
|
+
Bypass the init function of the CongruenceSubgroupFromGroup class.
|
|
461
|
+
|
|
462
|
+
EXAMPLES::
|
|
463
|
+
|
|
464
|
+
sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5) # indirect doctest
|
|
465
|
+
Generic congruence subgroup of level 5
|
|
466
|
+
"""
|
|
467
|
+
CongruenceSubgroupBase.__init__(self, *args, **kwds)
|
|
468
|
+
|
|
469
|
+
def _repr_(self):
|
|
470
|
+
"""
|
|
471
|
+
Return the string representation of ``self``.
|
|
472
|
+
|
|
473
|
+
NOTE: This function should be overridden by all subclasses.
|
|
474
|
+
|
|
475
|
+
EXAMPLES::
|
|
476
|
+
|
|
477
|
+
sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5)._repr_()
|
|
478
|
+
'Generic congruence subgroup of level 5'
|
|
479
|
+
"""
|
|
480
|
+
return "Generic congruence subgroup of level %s" % self.level()
|
|
481
|
+
|
|
482
|
+
def modular_symbols(self, sign=0, weight=2, base_ring=QQ):
|
|
483
|
+
"""
|
|
484
|
+
Return the space of modular symbols of the specified weight and sign
|
|
485
|
+
on the congruence subgroup ``self``.
|
|
486
|
+
|
|
487
|
+
EXAMPLES::
|
|
488
|
+
|
|
489
|
+
sage: G = Gamma0(23)
|
|
490
|
+
sage: G.modular_symbols()
|
|
491
|
+
Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field
|
|
492
|
+
sage: G.modular_symbols(weight=4)
|
|
493
|
+
Modular Symbols space of dimension 12 for Gamma_0(23) of weight 4 with sign 0 over Rational Field
|
|
494
|
+
sage: G.modular_symbols(base_ring=GF(7))
|
|
495
|
+
Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Finite Field of size 7
|
|
496
|
+
sage: G.modular_symbols(sign=1)
|
|
497
|
+
Modular Symbols space of dimension 3 for Gamma_0(23) of weight 2 with sign 1 over Rational Field
|
|
498
|
+
"""
|
|
499
|
+
from sage.modular.modsym.modsym import ModularSymbols
|
|
500
|
+
return ModularSymbols(self, sign=sign, weight=weight, base_ring=base_ring)
|
|
501
|
+
|
|
502
|
+
def modular_abelian_variety(self):
|
|
503
|
+
"""
|
|
504
|
+
Return the modular abelian variety corresponding to the congruence
|
|
505
|
+
subgroup ``self``.
|
|
506
|
+
|
|
507
|
+
EXAMPLES::
|
|
508
|
+
|
|
509
|
+
sage: Gamma0(11).modular_abelian_variety()
|
|
510
|
+
Abelian variety J0(11) of dimension 1
|
|
511
|
+
sage: Gamma1(11).modular_abelian_variety()
|
|
512
|
+
Abelian variety J1(11) of dimension 1
|
|
513
|
+
sage: GammaH(11,[3]).modular_abelian_variety()
|
|
514
|
+
Abelian variety JH(11,[3]) of dimension 1
|
|
515
|
+
"""
|
|
516
|
+
from sage.modular.abvar.abvar_ambient_jacobian import ModAbVar_ambient_jacobian
|
|
517
|
+
return ModAbVar_ambient_jacobian(self)
|
|
518
|
+
|
|
519
|
+
def _new_group_from_level(self, level):
|
|
520
|
+
r"""
|
|
521
|
+
Return a new group of the same type (Gamma0, Gamma1, or
|
|
522
|
+
GammaH) as ``self`` of the given level. In the case that ``self`` is of type
|
|
523
|
+
GammaH, we take the largest H inside `(\ZZ/ \text{level}\ZZ)^\times`
|
|
524
|
+
which maps to H, namely its inverse image under the natural reduction
|
|
525
|
+
map.
|
|
526
|
+
|
|
527
|
+
EXAMPLES::
|
|
528
|
+
|
|
529
|
+
sage: G = Gamma0(20)
|
|
530
|
+
sage: G._new_group_from_level(4)
|
|
531
|
+
Congruence Subgroup Gamma0(4)
|
|
532
|
+
sage: G._new_group_from_level(40)
|
|
533
|
+
Congruence Subgroup Gamma0(40)
|
|
534
|
+
|
|
535
|
+
sage: G = Gamma1(10)
|
|
536
|
+
sage: G._new_group_from_level(6)
|
|
537
|
+
Traceback (most recent call last):
|
|
538
|
+
...
|
|
539
|
+
ValueError: one level must divide the other
|
|
540
|
+
|
|
541
|
+
sage: G = GammaH(50,[7]); G
|
|
542
|
+
Congruence Subgroup Gamma_H(50) with H generated by [7]
|
|
543
|
+
sage: G._new_group_from_level(25)
|
|
544
|
+
Congruence Subgroup Gamma_H(25) with H generated by [7]
|
|
545
|
+
sage: G._new_group_from_level(10)
|
|
546
|
+
Congruence Subgroup Gamma0(10)
|
|
547
|
+
sage: G._new_group_from_level(100)
|
|
548
|
+
Congruence Subgroup Gamma_H(100) with H generated by [7, 57]
|
|
549
|
+
"""
|
|
550
|
+
from .congroup_gamma0 import Gamma0_class
|
|
551
|
+
from .congroup_gamma1 import Gamma1_class
|
|
552
|
+
from .congroup_gammaH import GammaH_class
|
|
553
|
+
from .all import Gamma0, Gamma1, GammaH
|
|
554
|
+
N = self.level()
|
|
555
|
+
if (level % N) and (N % level):
|
|
556
|
+
raise ValueError("one level must divide the other")
|
|
557
|
+
if isinstance(self, Gamma0_class):
|
|
558
|
+
return Gamma0(level)
|
|
559
|
+
elif isinstance(self, Gamma1_class):
|
|
560
|
+
return Gamma1(level)
|
|
561
|
+
elif isinstance(self, GammaH_class):
|
|
562
|
+
H = self._generators_for_H()
|
|
563
|
+
if level > N:
|
|
564
|
+
d = level // N
|
|
565
|
+
diffs = [ N*i for i in range(d) ]
|
|
566
|
+
newH = [ h + diff for h in H for diff in diffs ]
|
|
567
|
+
return GammaH(level, [x for x in newH if gcd(level, x) == 1])
|
|
568
|
+
else:
|
|
569
|
+
return GammaH(level, [ h % level for h in H ])
|
|
570
|
+
else:
|
|
571
|
+
raise NotImplementedError
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def _minimize_level(G):
|
|
575
|
+
r"""
|
|
576
|
+
Utility function. Given a matrix group `G` contained in `SL(2, \ZZ / N\ZZ)`
|
|
577
|
+
for some `N`, test whether or not `G` is the preimage of a subgroup of
|
|
578
|
+
smaller level, and if so, return that subgroup.
|
|
579
|
+
|
|
580
|
+
The trivial group is handled specially: instead of returning a group, it
|
|
581
|
+
returns an integer `N`, representing the trivial subgroup of `SL(2, \ZZ /
|
|
582
|
+
N\ZZ)`.
|
|
583
|
+
|
|
584
|
+
EXAMPLES::
|
|
585
|
+
|
|
586
|
+
sage: M = MatrixSpace(Zmod(9), 2, 2)
|
|
587
|
+
sage: G = MatrixGroup([M(x) for x in [[1,1,0,1],[1,3,0,1],[1,0,3,1],[4,0,0,7]]]); G
|
|
588
|
+
Matrix group over Ring of integers modulo 9 with 4 generators (
|
|
589
|
+
[1 1] [1 3] [1 0] [4 0]
|
|
590
|
+
[0 1], [0 1], [3 1], [0 7]
|
|
591
|
+
)
|
|
592
|
+
sage: sage.modular.arithgroup.congroup_generic._minimize_level(G)
|
|
593
|
+
Matrix group over Ring of integers modulo 3 with 1 generators (
|
|
594
|
+
[1 1]
|
|
595
|
+
[0 1]
|
|
596
|
+
)
|
|
597
|
+
sage: G = MatrixGroup([M(x) for x in [[1,3,0,1],[1,0,3,1],[4,0,0,7]]]); G
|
|
598
|
+
Matrix group over Ring of integers modulo 9 with 3 generators (
|
|
599
|
+
[1 3] [1 0] [4 0]
|
|
600
|
+
[0 1], [3 1], [0 7]
|
|
601
|
+
)
|
|
602
|
+
sage: sage.modular.arithgroup.congroup_generic._minimize_level(G)
|
|
603
|
+
3
|
|
604
|
+
"""
|
|
605
|
+
from sage.groups.matrix_gps.finitely_generated import MatrixGroup
|
|
606
|
+
from .congroup_gamma import Gamma_constructor as Gamma
|
|
607
|
+
|
|
608
|
+
Glist = list(G)
|
|
609
|
+
N = G.base_ring().characteristic()
|
|
610
|
+
i = Gamma(N).index()
|
|
611
|
+
|
|
612
|
+
for d in N.divisors()[:-1]:
|
|
613
|
+
j = Gamma(d).index()
|
|
614
|
+
k = len([g for g in Glist if g.matrix().change_ring(Zmod(d)) == 1])
|
|
615
|
+
if k == i // j:
|
|
616
|
+
if d == 1:
|
|
617
|
+
return ZZ(1)
|
|
618
|
+
G = MatrixGroup([g.matrix().change_ring(Zmod(d)) for g in G.gens()])
|
|
619
|
+
N = d
|
|
620
|
+
break
|
|
621
|
+
|
|
622
|
+
# now sanitize the generators (remove duplicates and copies of the identity)
|
|
623
|
+
new_gens = [x.matrix() for x in G.gens() if x.matrix() != 1]
|
|
624
|
+
all(x.set_immutable() for x in new_gens)
|
|
625
|
+
new_gens = list(Set(new_gens))
|
|
626
|
+
if not new_gens:
|
|
627
|
+
return ZZ(N)
|
|
628
|
+
return MatrixGroup(new_gens)
|