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,692 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.libs.pari
|
|
3
|
+
r"""
|
|
4
|
+
Congruence subgroup `\Gamma_0(N)`
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# ****************************************************************************
|
|
8
|
+
# This program is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
# https://www.gnu.org/licenses/
|
|
13
|
+
# ****************************************************************************
|
|
14
|
+
|
|
15
|
+
from sage.arith.misc import kronecker_symbol, divisors, euler_phi, gcd, moebius
|
|
16
|
+
from sage.misc.cachefunc import cached_method
|
|
17
|
+
from sage.misc.misc_c import prod
|
|
18
|
+
from sage.modular.cusps import Cusp
|
|
19
|
+
from sage.modular.modsym.p1list import lift_to_sl2z, P1List
|
|
20
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
|
|
21
|
+
from sage.rings.integer_ring import ZZ
|
|
22
|
+
|
|
23
|
+
from .congroup_gamma1 import Gamma1_class
|
|
24
|
+
from .congroup_gammaH import GammaH_class
|
|
25
|
+
from .congroup_generic import CongruenceSubgroup
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def is_Gamma0(x):
|
|
29
|
+
"""
|
|
30
|
+
Return ``True`` if x is a congruence subgroup of type Gamma0.
|
|
31
|
+
|
|
32
|
+
EXAMPLES::
|
|
33
|
+
|
|
34
|
+
sage: from sage.modular.arithgroup.all import is_Gamma0
|
|
35
|
+
sage: is_Gamma0(SL2Z)
|
|
36
|
+
doctest:warning...
|
|
37
|
+
DeprecationWarning: The function is_Gamma0 is deprecated; use 'isinstance(..., Gamma0_class)' instead.
|
|
38
|
+
See https://github.com/sagemath/sage/issues/38035 for details.
|
|
39
|
+
True
|
|
40
|
+
sage: is_Gamma0(Gamma0(13))
|
|
41
|
+
True
|
|
42
|
+
sage: is_Gamma0(Gamma1(6))
|
|
43
|
+
False
|
|
44
|
+
"""
|
|
45
|
+
from sage.misc.superseded import deprecation
|
|
46
|
+
deprecation(38035, "The function is_Gamma0 is deprecated; use 'isinstance(..., Gamma0_class)' instead.")
|
|
47
|
+
return isinstance(x, Gamma0_class)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
_gamma0_cache = {}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def Gamma0_constructor(N):
|
|
54
|
+
"""
|
|
55
|
+
Return the congruence subgroup Gamma0(N).
|
|
56
|
+
|
|
57
|
+
EXAMPLES::
|
|
58
|
+
|
|
59
|
+
sage: G = Gamma0(51) ; G # indirect doctest
|
|
60
|
+
Congruence Subgroup Gamma0(51)
|
|
61
|
+
sage: G == Gamma0(51)
|
|
62
|
+
True
|
|
63
|
+
sage: G is Gamma0(51)
|
|
64
|
+
True
|
|
65
|
+
"""
|
|
66
|
+
from .all import SL2Z
|
|
67
|
+
if N == 1:
|
|
68
|
+
return SL2Z
|
|
69
|
+
try:
|
|
70
|
+
return _gamma0_cache[N]
|
|
71
|
+
except KeyError:
|
|
72
|
+
_gamma0_cache[N] = Gamma0_class(N)
|
|
73
|
+
return _gamma0_cache[N]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Gamma0_class(GammaH_class):
|
|
77
|
+
r"""
|
|
78
|
+
The congruence subgroup `\Gamma_0(N)`.
|
|
79
|
+
|
|
80
|
+
TESTS::
|
|
81
|
+
|
|
82
|
+
sage: Gamma0(11).dimension_cusp_forms(2)
|
|
83
|
+
1
|
|
84
|
+
sage: a = Gamma0(1).dimension_cusp_forms(2); a
|
|
85
|
+
0
|
|
86
|
+
sage: type(a)
|
|
87
|
+
<class 'sage.rings.integer.Integer'>
|
|
88
|
+
sage: Gamma0(5).dimension_cusp_forms(0)
|
|
89
|
+
0
|
|
90
|
+
sage: Gamma0(20).dimension_cusp_forms(1)
|
|
91
|
+
0
|
|
92
|
+
sage: Gamma0(20).dimension_cusp_forms(4)
|
|
93
|
+
6
|
|
94
|
+
|
|
95
|
+
sage: Gamma0(23).dimension_cusp_forms(2)
|
|
96
|
+
2
|
|
97
|
+
sage: Gamma0(1).dimension_cusp_forms(24)
|
|
98
|
+
2
|
|
99
|
+
sage: Gamma0(3).dimension_cusp_forms(3)
|
|
100
|
+
0
|
|
101
|
+
sage: Gamma0(11).dimension_cusp_forms(-1)
|
|
102
|
+
0
|
|
103
|
+
|
|
104
|
+
sage: Gamma0(22).dimension_new_cusp_forms()
|
|
105
|
+
0
|
|
106
|
+
sage: Gamma0(100).dimension_new_cusp_forms(2, 5)
|
|
107
|
+
5
|
|
108
|
+
|
|
109
|
+
Independently compute the dimension 5 above::
|
|
110
|
+
|
|
111
|
+
sage: m = ModularSymbols(100, 2, sign=1).cuspidal_subspace()
|
|
112
|
+
sage: m.new_subspace(5)
|
|
113
|
+
Modular Symbols subspace of dimension 5 of
|
|
114
|
+
Modular Symbols space of dimension 18 for Gamma_0(100)
|
|
115
|
+
of weight 2 with sign 1 over Rational Field
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def __init__(self, level):
|
|
119
|
+
r"""
|
|
120
|
+
The congruence subgroup `\Gamma_0(N)`.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: G = Gamma0(11); G
|
|
125
|
+
Congruence Subgroup Gamma0(11)
|
|
126
|
+
sage: TestSuite(G).run()
|
|
127
|
+
sage: G is loads(dumps(G))
|
|
128
|
+
True
|
|
129
|
+
|
|
130
|
+
TESTS::
|
|
131
|
+
|
|
132
|
+
sage: g = Gamma0(5)([1,1,0,1])
|
|
133
|
+
sage: g in Gamma0(7)
|
|
134
|
+
True
|
|
135
|
+
sage: g = Gamma0(5)([1,0,5,1])
|
|
136
|
+
sage: g in Gamma0(7)
|
|
137
|
+
False
|
|
138
|
+
sage: g = Gamma0(2)([1,0,0,1])
|
|
139
|
+
sage: g in SL2Z
|
|
140
|
+
True
|
|
141
|
+
"""
|
|
142
|
+
CongruenceSubgroup.__init__(self, level)
|
|
143
|
+
|
|
144
|
+
# We *don't* call the GammaH init script, as this requires calculating
|
|
145
|
+
# generators for the units modulo N which is time-consuming; this will
|
|
146
|
+
# be done if needed by the _generators_for_H and _list_of_elements_in_H
|
|
147
|
+
# methods.
|
|
148
|
+
#
|
|
149
|
+
# GammaH_class.__init__(self, level, [int(x) for x in IntegerModRing(level).unit_gens()])
|
|
150
|
+
|
|
151
|
+
def _repr_(self):
|
|
152
|
+
"""
|
|
153
|
+
Return the string representation of ``self``.
|
|
154
|
+
|
|
155
|
+
EXAMPLES::
|
|
156
|
+
|
|
157
|
+
sage: Gamma0(98)._repr_()
|
|
158
|
+
'Congruence Subgroup Gamma0(98)'
|
|
159
|
+
"""
|
|
160
|
+
return "Congruence Subgroup Gamma0(%s)" % self.level()
|
|
161
|
+
|
|
162
|
+
def __reduce__(self):
|
|
163
|
+
"""
|
|
164
|
+
Used for pickling ``self``.
|
|
165
|
+
|
|
166
|
+
EXAMPLES::
|
|
167
|
+
|
|
168
|
+
sage: Gamma0(22).__reduce__()
|
|
169
|
+
(<function Gamma0_constructor at ...>, (22,))
|
|
170
|
+
"""
|
|
171
|
+
return Gamma0_constructor, (self.level(),)
|
|
172
|
+
|
|
173
|
+
def _latex_(self):
|
|
174
|
+
r"""
|
|
175
|
+
Return the \LaTeX representation of ``self``.
|
|
176
|
+
|
|
177
|
+
EXAMPLES::
|
|
178
|
+
|
|
179
|
+
sage: Gamma0(20)._latex_()
|
|
180
|
+
'\\Gamma_0(20)'
|
|
181
|
+
sage: latex(Gamma0(20))
|
|
182
|
+
\Gamma_0(20)
|
|
183
|
+
"""
|
|
184
|
+
return "\\Gamma_0(%s)" % self.level()
|
|
185
|
+
|
|
186
|
+
@cached_method
|
|
187
|
+
def _generators_for_H(self):
|
|
188
|
+
"""
|
|
189
|
+
Return generators for the subgroup `H` of the units mod
|
|
190
|
+
``self.level()`` that defines ``self``.
|
|
191
|
+
|
|
192
|
+
EXAMPLES::
|
|
193
|
+
|
|
194
|
+
sage: Gamma0(15)._generators_for_H()
|
|
195
|
+
[11, 7]
|
|
196
|
+
"""
|
|
197
|
+
if self.level() in [1, 2]:
|
|
198
|
+
return []
|
|
199
|
+
return [ZZ(x) for x in IntegerModRing(self.level()).unit_gens()]
|
|
200
|
+
|
|
201
|
+
@cached_method
|
|
202
|
+
def _list_of_elements_in_H(self):
|
|
203
|
+
"""
|
|
204
|
+
Return a sorted list of Python ints that are representatives
|
|
205
|
+
between 0 and N-1 of the elements of H.
|
|
206
|
+
|
|
207
|
+
EXAMPLES::
|
|
208
|
+
|
|
209
|
+
sage: G = Gamma0(11)
|
|
210
|
+
sage: G._list_of_elements_in_H()
|
|
211
|
+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
212
|
+
|
|
213
|
+
sage: G = Gamma0(6)
|
|
214
|
+
sage: G._list_of_elements_in_H()
|
|
215
|
+
[1, 5]
|
|
216
|
+
|
|
217
|
+
sage: G = Gamma0(1)
|
|
218
|
+
sage: G._list_of_elements_in_H()
|
|
219
|
+
[1]
|
|
220
|
+
"""
|
|
221
|
+
N = self.level()
|
|
222
|
+
if N != 1:
|
|
223
|
+
H = [x for x in range(1, N) if gcd(x, N) == 1]
|
|
224
|
+
else:
|
|
225
|
+
H = [1]
|
|
226
|
+
|
|
227
|
+
return H
|
|
228
|
+
|
|
229
|
+
def divisor_subgroups(self):
|
|
230
|
+
r"""
|
|
231
|
+
Return the subgroups of SL2Z of the form Gamma0(M) that contain this subgroup,
|
|
232
|
+
i.e. those for M a divisor of N.
|
|
233
|
+
|
|
234
|
+
EXAMPLES::
|
|
235
|
+
|
|
236
|
+
sage: Gamma0(24).divisor_subgroups()
|
|
237
|
+
[Modular Group SL(2,Z),
|
|
238
|
+
Congruence Subgroup Gamma0(2),
|
|
239
|
+
Congruence Subgroup Gamma0(3),
|
|
240
|
+
Congruence Subgroup Gamma0(4),
|
|
241
|
+
Congruence Subgroup Gamma0(6),
|
|
242
|
+
Congruence Subgroup Gamma0(8),
|
|
243
|
+
Congruence Subgroup Gamma0(12),
|
|
244
|
+
Congruence Subgroup Gamma0(24)]
|
|
245
|
+
"""
|
|
246
|
+
return [Gamma0_constructor(M) for M in self.level().divisors()]
|
|
247
|
+
|
|
248
|
+
def is_even(self) -> bool:
|
|
249
|
+
r"""
|
|
250
|
+
Return ``True`` precisely if this subgroup contains the matrix -1.
|
|
251
|
+
|
|
252
|
+
Since `\Gamma0(N)` always contains the matrix -1, this always
|
|
253
|
+
returns ``True``.
|
|
254
|
+
|
|
255
|
+
EXAMPLES::
|
|
256
|
+
|
|
257
|
+
sage: Gamma0(12).is_even()
|
|
258
|
+
True
|
|
259
|
+
sage: SL2Z.is_even()
|
|
260
|
+
True
|
|
261
|
+
"""
|
|
262
|
+
return True
|
|
263
|
+
|
|
264
|
+
def is_subgroup(self, right) -> bool:
|
|
265
|
+
"""
|
|
266
|
+
Return ``True`` if ``self`` is a subgroup of ``right``.
|
|
267
|
+
|
|
268
|
+
EXAMPLES::
|
|
269
|
+
|
|
270
|
+
sage: G = Gamma0(20)
|
|
271
|
+
sage: G.is_subgroup(SL2Z)
|
|
272
|
+
True
|
|
273
|
+
sage: G.is_subgroup(Gamma0(4))
|
|
274
|
+
True
|
|
275
|
+
sage: G.is_subgroup(Gamma0(20))
|
|
276
|
+
True
|
|
277
|
+
sage: G.is_subgroup(Gamma0(7))
|
|
278
|
+
False
|
|
279
|
+
sage: G.is_subgroup(Gamma1(20))
|
|
280
|
+
False
|
|
281
|
+
sage: G.is_subgroup(GammaH(40, []))
|
|
282
|
+
False
|
|
283
|
+
sage: Gamma0(80).is_subgroup(GammaH(40, [31, 21, 17]))
|
|
284
|
+
True
|
|
285
|
+
sage: Gamma0(2).is_subgroup(Gamma1(2))
|
|
286
|
+
True
|
|
287
|
+
"""
|
|
288
|
+
if right.level() == 1:
|
|
289
|
+
return True
|
|
290
|
+
if isinstance(right, Gamma0_class):
|
|
291
|
+
return self.level() % right.level() == 0
|
|
292
|
+
if isinstance(right, Gamma1_class):
|
|
293
|
+
if right.level() >= 3:
|
|
294
|
+
return False
|
|
295
|
+
elif right.level() == 2:
|
|
296
|
+
return self.level() == 2
|
|
297
|
+
# case level 1 dealt with above
|
|
298
|
+
else:
|
|
299
|
+
return GammaH_class.is_subgroup(self, right)
|
|
300
|
+
|
|
301
|
+
def coset_reps(self):
|
|
302
|
+
r"""
|
|
303
|
+
Return representatives for the right cosets of this congruence
|
|
304
|
+
subgroup in `\SL_2(\ZZ)` as a generator object.
|
|
305
|
+
|
|
306
|
+
Use ``list(self.coset_reps())`` to obtain coset reps as a
|
|
307
|
+
list.
|
|
308
|
+
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: list(Gamma0(5).coset_reps())
|
|
312
|
+
[
|
|
313
|
+
[1 0] [ 0 -1] [1 0] [ 0 -1] [ 0 -1] [ 0 -1]
|
|
314
|
+
[0 1], [ 1 0], [1 1], [ 1 2], [ 1 3], [ 1 4]
|
|
315
|
+
]
|
|
316
|
+
sage: list(Gamma0(4).coset_reps())
|
|
317
|
+
[
|
|
318
|
+
[1 0] [ 0 -1] [1 0] [ 0 -1] [ 0 -1] [1 0]
|
|
319
|
+
[0 1], [ 1 0], [1 1], [ 1 2], [ 1 3], [2 1]
|
|
320
|
+
]
|
|
321
|
+
sage: list(Gamma0(1).coset_reps())
|
|
322
|
+
[
|
|
323
|
+
[1 0]
|
|
324
|
+
[0 1]
|
|
325
|
+
]
|
|
326
|
+
"""
|
|
327
|
+
from .all import SL2Z
|
|
328
|
+
N = self.level()
|
|
329
|
+
if N == 1: # P1List isn't very happy working modulo 1
|
|
330
|
+
yield SL2Z([1,0,0,1])
|
|
331
|
+
else:
|
|
332
|
+
for z in P1List(N):
|
|
333
|
+
yield SL2Z(lift_to_sl2z(z[0], z[1], N))
|
|
334
|
+
|
|
335
|
+
@cached_method
|
|
336
|
+
def generators(self, algorithm='farey'):
|
|
337
|
+
r"""
|
|
338
|
+
Return generators for this congruence subgroup.
|
|
339
|
+
|
|
340
|
+
INPUT:
|
|
341
|
+
|
|
342
|
+
- ``algorithm`` -- string; either ``'farey'`` (default) or
|
|
343
|
+
``'todd-coxeter'``
|
|
344
|
+
|
|
345
|
+
If ``algorithm`` is set to ``'farey'``, then the generators will be
|
|
346
|
+
calculated using Farey symbols, which will always return a *minimal*
|
|
347
|
+
generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for
|
|
348
|
+
more information.
|
|
349
|
+
|
|
350
|
+
If ``algorithm`` is set to ``'todd-coxeter'``, a simpler algorithm
|
|
351
|
+
based on Todd-Coxeter enumeration will be used. This tends to return
|
|
352
|
+
far larger sets of generators.
|
|
353
|
+
|
|
354
|
+
EXAMPLES::
|
|
355
|
+
|
|
356
|
+
sage: Gamma0(3).generators()
|
|
357
|
+
[
|
|
358
|
+
[1 1] [-1 1]
|
|
359
|
+
[0 1], [-3 2]
|
|
360
|
+
]
|
|
361
|
+
sage: Gamma0(3).generators(algorithm='todd-coxeter')
|
|
362
|
+
[
|
|
363
|
+
[1 1] [-1 0] [ 1 -1] [1 0] [1 1] [-1 0] [ 1 0]
|
|
364
|
+
[0 1], [ 0 -1], [ 0 1], [3 1], [0 1], [ 3 -1], [-3 1]
|
|
365
|
+
]
|
|
366
|
+
sage: SL2Z.gens()
|
|
367
|
+
(
|
|
368
|
+
[ 0 -1] [1 1]
|
|
369
|
+
[ 1 0], [0 1]
|
|
370
|
+
)
|
|
371
|
+
"""
|
|
372
|
+
if self.level() == 1:
|
|
373
|
+
# we return a fixed set of generators for SL2Z, for historical
|
|
374
|
+
# reasons, which aren't the ones the Farey symbol code gives
|
|
375
|
+
return [ self([0,-1,1,0]), self([1,1,0,1]) ]
|
|
376
|
+
|
|
377
|
+
elif algorithm == "farey":
|
|
378
|
+
return self.farey_symbol().generators()
|
|
379
|
+
|
|
380
|
+
elif algorithm == "todd-coxeter":
|
|
381
|
+
from sage.modular.modsym.p1list import P1List
|
|
382
|
+
from .congroup import generators_helper
|
|
383
|
+
level = self.level()
|
|
384
|
+
if level == 1: # P1List isn't very happy working mod 1
|
|
385
|
+
return [ self([0,-1,1,0]), self([1,1,0,1]) ]
|
|
386
|
+
gen_list = generators_helper(P1List(level), level)
|
|
387
|
+
return [self(g, check=False) for g in gen_list]
|
|
388
|
+
|
|
389
|
+
else:
|
|
390
|
+
raise ValueError("Unknown algorithm '%s' (should be either 'farey' or 'todd-coxeter')" % algorithm)
|
|
391
|
+
|
|
392
|
+
def gamma_h_subgroups(self):
|
|
393
|
+
r"""
|
|
394
|
+
Return the subgroups of the form `\Gamma_H(N)` contained
|
|
395
|
+
in ``self``, where `N` is the level of ``self``.
|
|
396
|
+
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: G = Gamma0(11)
|
|
400
|
+
sage: G.gamma_h_subgroups() # optional - gap_package_polycyclic
|
|
401
|
+
[Congruence Subgroup Gamma0(11),
|
|
402
|
+
Congruence Subgroup Gamma_H(11) with H generated by [3],
|
|
403
|
+
Congruence Subgroup Gamma_H(11) with H generated by [10],
|
|
404
|
+
Congruence Subgroup Gamma1(11)]
|
|
405
|
+
sage: G = Gamma0(12)
|
|
406
|
+
sage: G.gamma_h_subgroups() # optional - gap_package_polycyclic
|
|
407
|
+
[Congruence Subgroup Gamma0(12),
|
|
408
|
+
Congruence Subgroup Gamma_H(12) with H generated by [7],
|
|
409
|
+
Congruence Subgroup Gamma_H(12) with H generated by [11],
|
|
410
|
+
Congruence Subgroup Gamma_H(12) with H generated by [5],
|
|
411
|
+
Congruence Subgroup Gamma1(12)]
|
|
412
|
+
"""
|
|
413
|
+
from .all import GammaH
|
|
414
|
+
N = self.level()
|
|
415
|
+
R = IntegerModRing(N)
|
|
416
|
+
return [GammaH(N, H) for H in R.multiplicative_subgroups()]
|
|
417
|
+
|
|
418
|
+
def _contains_sl2(self, a, b, c, d):
|
|
419
|
+
r"""
|
|
420
|
+
Test whether x is an element of this group.
|
|
421
|
+
|
|
422
|
+
EXAMPLES::
|
|
423
|
+
|
|
424
|
+
sage: G = Gamma0(12)
|
|
425
|
+
sage: [1, 0, 24, 1] in G
|
|
426
|
+
True
|
|
427
|
+
sage: matrix(ZZ, 2, [1, 1, -12, -11]) in G
|
|
428
|
+
True
|
|
429
|
+
sage: SL2Z([0,-1,1,0]) in G
|
|
430
|
+
False
|
|
431
|
+
sage: 1 in G
|
|
432
|
+
True
|
|
433
|
+
sage: -1 in G
|
|
434
|
+
True
|
|
435
|
+
sage: 2 in G
|
|
436
|
+
False
|
|
437
|
+
|
|
438
|
+
The _element_constructor_ method calls this method::
|
|
439
|
+
|
|
440
|
+
sage: G([1, 0, 23, 1]) # indirect doctest
|
|
441
|
+
Traceback (most recent call last):
|
|
442
|
+
...
|
|
443
|
+
TypeError: matrix [ 1 0]
|
|
444
|
+
[23 1] is not an element of Congruence Subgroup Gamma0(12)
|
|
445
|
+
"""
|
|
446
|
+
return (c % self.level() == 0)
|
|
447
|
+
|
|
448
|
+
def _find_cusps(self):
|
|
449
|
+
r"""
|
|
450
|
+
Return an ordered list of inequivalent cusps for self, i.e. a
|
|
451
|
+
set of representatives for the orbits of ``self`` on
|
|
452
|
+
`\mathbb{P}^1(\QQ)`. These are returned in a reduced
|
|
453
|
+
form; see ``self.reduce_cusp`` for the definition of reduced.
|
|
454
|
+
|
|
455
|
+
ALGORITHM:
|
|
456
|
+
Uses explicit formulae specific to `\Gamma_0(N)`: a reduced cusp on
|
|
457
|
+
`\Gamma_0(N)` is always of the form `a/d` where `d | N`, and `a_1/d
|
|
458
|
+
\sim a_2/d` if and only if `a_1 \cong a_2 \bmod {\rm gcd}(d,
|
|
459
|
+
N/d)`.
|
|
460
|
+
|
|
461
|
+
EXAMPLES::
|
|
462
|
+
|
|
463
|
+
sage: Gamma0(90)._find_cusps()
|
|
464
|
+
[0, 1/45, 1/30, 1/18, 1/15, 1/10, 1/9, 2/15, 1/6, 1/5, 1/3, 11/30, 1/2, 2/3, 5/6, Infinity]
|
|
465
|
+
sage: Gamma0(1).cusps()
|
|
466
|
+
[Infinity]
|
|
467
|
+
sage: Gamma0(180).cusps() == Gamma0(180).cusps(algorithm='modsym')
|
|
468
|
+
True
|
|
469
|
+
"""
|
|
470
|
+
N = self.level()
|
|
471
|
+
s = []
|
|
472
|
+
|
|
473
|
+
for d in divisors(N):
|
|
474
|
+
w = gcd(d, N//d)
|
|
475
|
+
if w == 1:
|
|
476
|
+
if d == 1:
|
|
477
|
+
s.append(Cusp(1,0))
|
|
478
|
+
elif d == N:
|
|
479
|
+
s.append(Cusp(0,1))
|
|
480
|
+
else:
|
|
481
|
+
s.append(Cusp(1,d))
|
|
482
|
+
else:
|
|
483
|
+
for a in range(1, w):
|
|
484
|
+
if gcd(a, w) == 1:
|
|
485
|
+
while gcd(a, d//w) != 1:
|
|
486
|
+
a += w
|
|
487
|
+
s.append(Cusp(a,d))
|
|
488
|
+
return sorted(s)
|
|
489
|
+
|
|
490
|
+
def ncusps(self):
|
|
491
|
+
r"""
|
|
492
|
+
Return the number of cusps of this subgroup `\Gamma_0(N)`.
|
|
493
|
+
|
|
494
|
+
EXAMPLES::
|
|
495
|
+
|
|
496
|
+
sage: [Gamma0(n).ncusps() for n in [1..19]]
|
|
497
|
+
[1, 2, 2, 3, 2, 4, 2, 4, 4, 4, 2, 6, 2, 4, 4, 6, 2, 8, 2]
|
|
498
|
+
sage: [Gamma0(n).ncusps() for n in prime_range(2,100)]
|
|
499
|
+
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
500
|
+
"""
|
|
501
|
+
n = self.level()
|
|
502
|
+
return sum(euler_phi(gcd(d, n // d)) for d in n.divisors())
|
|
503
|
+
|
|
504
|
+
def nu2(self):
|
|
505
|
+
r"""
|
|
506
|
+
Return the number of elliptic points of order 2 for this congruence
|
|
507
|
+
subgroup `\Gamma_0(N)`.
|
|
508
|
+
|
|
509
|
+
The number of these is given by a standard formula:
|
|
510
|
+
0 if `N` is divisible by 4 or any prime congruent to -1 mod 4, and
|
|
511
|
+
otherwise `2^d` where d is the number of odd primes dividing `N`.
|
|
512
|
+
|
|
513
|
+
EXAMPLES::
|
|
514
|
+
|
|
515
|
+
sage: Gamma0(2).nu2()
|
|
516
|
+
1
|
|
517
|
+
sage: Gamma0(4).nu2()
|
|
518
|
+
0
|
|
519
|
+
sage: Gamma0(21).nu2()
|
|
520
|
+
0
|
|
521
|
+
sage: Gamma0(1105).nu2()
|
|
522
|
+
8
|
|
523
|
+
sage: [Gamma0(n).nu2() for n in [1..19]]
|
|
524
|
+
[1, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0]
|
|
525
|
+
"""
|
|
526
|
+
n = self.level()
|
|
527
|
+
if n % 4 == 0:
|
|
528
|
+
return ZZ(0)
|
|
529
|
+
return prod([ 1 + kronecker_symbol(-4, p) for p, _ in n.factor()])
|
|
530
|
+
|
|
531
|
+
def nu3(self):
|
|
532
|
+
r"""
|
|
533
|
+
Return the number of elliptic points of order 3 for this congruence
|
|
534
|
+
subgroup `\Gamma_0(N)`. The number of these is given by a standard formula:
|
|
535
|
+
0 if `N` is divisible by 9 or any prime congruent to -1 mod 3, and
|
|
536
|
+
otherwise `2^d` where d is the number of primes other than 3 dividing `N`.
|
|
537
|
+
|
|
538
|
+
EXAMPLES::
|
|
539
|
+
|
|
540
|
+
sage: Gamma0(2).nu3()
|
|
541
|
+
0
|
|
542
|
+
sage: Gamma0(3).nu3()
|
|
543
|
+
1
|
|
544
|
+
sage: Gamma0(9).nu3()
|
|
545
|
+
0
|
|
546
|
+
sage: Gamma0(7).nu3()
|
|
547
|
+
2
|
|
548
|
+
sage: Gamma0(21).nu3()
|
|
549
|
+
2
|
|
550
|
+
sage: Gamma0(1729).nu3()
|
|
551
|
+
8
|
|
552
|
+
"""
|
|
553
|
+
n = self.level()
|
|
554
|
+
if (n % 9 == 0):
|
|
555
|
+
return ZZ(0)
|
|
556
|
+
return prod([ 1 + kronecker_symbol(-3, p) for p, _ in n.factor()])
|
|
557
|
+
|
|
558
|
+
def index(self):
|
|
559
|
+
r"""
|
|
560
|
+
Return the index of ``self`` in the full modular group.
|
|
561
|
+
|
|
562
|
+
This is given by
|
|
563
|
+
|
|
564
|
+
.. MATH::
|
|
565
|
+
|
|
566
|
+
N \prod_{\substack{p \mid N \\ \text{$p$ prime}}}\left(1 + \frac{1}{p}\right).
|
|
567
|
+
|
|
568
|
+
EXAMPLES::
|
|
569
|
+
|
|
570
|
+
sage: [Gamma0(n).index() for n in [1..19]]
|
|
571
|
+
[1, 3, 4, 6, 6, 12, 8, 12, 12, 18, 12, 24, 14, 24, 24, 24, 18, 36, 20]
|
|
572
|
+
sage: Gamma0(32041).index()
|
|
573
|
+
32220
|
|
574
|
+
"""
|
|
575
|
+
return prod([p**e + p**(e-1) for (p,e) in self.level().factor()])
|
|
576
|
+
|
|
577
|
+
def dimension_new_cusp_forms(self, k=2, p=0):
|
|
578
|
+
r"""
|
|
579
|
+
Return the dimension of the space of new (or `p`-new)
|
|
580
|
+
weight `k` cusp forms for this congruence subgroup.
|
|
581
|
+
|
|
582
|
+
INPUT:
|
|
583
|
+
|
|
584
|
+
- ``k`` -- integer (default: 2); the weight. Not fully
|
|
585
|
+
implemented for `k = 1`.
|
|
586
|
+
- ``p`` -- integer (default: 0); if nonzero, compute the
|
|
587
|
+
`p`-new subspace
|
|
588
|
+
|
|
589
|
+
OUTPUT: integer
|
|
590
|
+
|
|
591
|
+
ALGORITHM:
|
|
592
|
+
|
|
593
|
+
This comes from the formula given in Theorem 1 of
|
|
594
|
+
http://www.math.ubc.ca/~gerg/papers/downloads/DSCFN.pdf
|
|
595
|
+
|
|
596
|
+
EXAMPLES::
|
|
597
|
+
|
|
598
|
+
sage: Gamma0(11000).dimension_new_cusp_forms()
|
|
599
|
+
240
|
|
600
|
+
sage: Gamma0(11000).dimension_new_cusp_forms(k=1)
|
|
601
|
+
0
|
|
602
|
+
sage: Gamma0(22).dimension_new_cusp_forms(k=4)
|
|
603
|
+
3
|
|
604
|
+
sage: Gamma0(389).dimension_new_cusp_forms(k=2,p=17)
|
|
605
|
+
32
|
|
606
|
+
|
|
607
|
+
TESTS::
|
|
608
|
+
|
|
609
|
+
sage: L = [1213, 1331, 2169, 2583, 2662, 2745, 3208,
|
|
610
|
+
....: 3232, 3465, 3608, 4040, 4302, 4338]
|
|
611
|
+
sage: all(Gamma0(N).dimension_new_cusp_forms(2)==100 for N in L)
|
|
612
|
+
True
|
|
613
|
+
"""
|
|
614
|
+
N = self.level()
|
|
615
|
+
k = ZZ(k)
|
|
616
|
+
|
|
617
|
+
if not (p == 0 or N % p):
|
|
618
|
+
return (self.dimension_cusp_forms(k) -
|
|
619
|
+
2 * self.restrict(N // p).dimension_new_cusp_forms(k))
|
|
620
|
+
|
|
621
|
+
if k < 2 or k % 2:
|
|
622
|
+
return ZZ.zero()
|
|
623
|
+
|
|
624
|
+
factors = list(N.factor())
|
|
625
|
+
|
|
626
|
+
def s0(q, a):
|
|
627
|
+
# function s_0^#
|
|
628
|
+
if a == 1:
|
|
629
|
+
return 1 - 1/q
|
|
630
|
+
elif a == 2:
|
|
631
|
+
return 1 - 1/q - 1/q**2
|
|
632
|
+
else:
|
|
633
|
+
return (1 - 1/q) * (1 - 1/q**2)
|
|
634
|
+
|
|
635
|
+
def vinf(q, a):
|
|
636
|
+
# function v_oo^#
|
|
637
|
+
if a % 2:
|
|
638
|
+
return 0
|
|
639
|
+
elif a == 2:
|
|
640
|
+
return q - 2
|
|
641
|
+
else:
|
|
642
|
+
return q**(a/2 - 2) * (q - 1)**2
|
|
643
|
+
|
|
644
|
+
def v2(q, a):
|
|
645
|
+
# function v_2^#
|
|
646
|
+
if q % 4 == 1:
|
|
647
|
+
if a == 2:
|
|
648
|
+
return -1
|
|
649
|
+
else:
|
|
650
|
+
return 0
|
|
651
|
+
elif q % 4 == 3:
|
|
652
|
+
if a == 1:
|
|
653
|
+
return -2
|
|
654
|
+
elif a == 2:
|
|
655
|
+
return 1
|
|
656
|
+
else:
|
|
657
|
+
return 0
|
|
658
|
+
elif a in (1, 2):
|
|
659
|
+
return -1
|
|
660
|
+
elif a == 3:
|
|
661
|
+
return 1
|
|
662
|
+
else:
|
|
663
|
+
return 0
|
|
664
|
+
|
|
665
|
+
def v3(q, a):
|
|
666
|
+
# function v_3^#
|
|
667
|
+
if q % 3 == 1:
|
|
668
|
+
if a == 2:
|
|
669
|
+
return -1
|
|
670
|
+
else:
|
|
671
|
+
return 0
|
|
672
|
+
elif q % 3 == 2:
|
|
673
|
+
if a == 1:
|
|
674
|
+
return -2
|
|
675
|
+
elif a == 2:
|
|
676
|
+
return 1
|
|
677
|
+
else:
|
|
678
|
+
return 0
|
|
679
|
+
elif a in (1, 2):
|
|
680
|
+
return -1
|
|
681
|
+
elif a == 3:
|
|
682
|
+
return 1
|
|
683
|
+
else:
|
|
684
|
+
return 0
|
|
685
|
+
|
|
686
|
+
res = (k - 1) / 12 * N * prod(s0(q, a) for q, a in factors)
|
|
687
|
+
res -= prod(vinf(q, a) for q, a in factors) / ZZ(2)
|
|
688
|
+
res += ((1 - k)/4 + k//4) * prod(v2(q, a) for q, a in factors)
|
|
689
|
+
res += ((1 - k)/3 + k//3) * prod(v3(q, a) for q, a in factors)
|
|
690
|
+
if k == 2:
|
|
691
|
+
res += moebius(N)
|
|
692
|
+
return res
|