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,653 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.libs.pari
|
|
3
|
+
r"""
|
|
4
|
+
Congruence subgroup `\Gamma_1(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
|
+
|
|
16
|
+
from sage.misc.cachefunc import cached_method
|
|
17
|
+
|
|
18
|
+
from sage.misc.misc_c import prod
|
|
19
|
+
from .congroup_gammaH import GammaH_class, is_GammaH, GammaH_constructor
|
|
20
|
+
from sage.rings.integer_ring import ZZ
|
|
21
|
+
from sage.arith.misc import euler_phi as phi, moebius, divisors
|
|
22
|
+
from sage.modular.dirichlet import DirichletGroup
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def is_Gamma1(x):
|
|
26
|
+
"""
|
|
27
|
+
Return ``True`` if x is a congruence subgroup of type Gamma1.
|
|
28
|
+
|
|
29
|
+
EXAMPLES::
|
|
30
|
+
|
|
31
|
+
sage: from sage.modular.arithgroup.all import is_Gamma1
|
|
32
|
+
sage: is_Gamma1(SL2Z)
|
|
33
|
+
doctest:warning...
|
|
34
|
+
DeprecationWarning: The function is_Gamma1 is deprecated; use 'isinstance(..., Gamma1_class)' instead.
|
|
35
|
+
See https://github.com/sagemath/sage/issues/38035 for details.
|
|
36
|
+
False
|
|
37
|
+
sage: is_Gamma1(Gamma1(13))
|
|
38
|
+
True
|
|
39
|
+
sage: is_Gamma1(Gamma0(6))
|
|
40
|
+
False
|
|
41
|
+
sage: is_Gamma1(GammaH(12, [])) # trick question!
|
|
42
|
+
True
|
|
43
|
+
sage: is_Gamma1(GammaH(12, [5]))
|
|
44
|
+
False
|
|
45
|
+
"""
|
|
46
|
+
from sage.misc.superseded import deprecation
|
|
47
|
+
deprecation(38035, "The function is_Gamma1 is deprecated; use 'isinstance(..., Gamma1_class)' instead.")
|
|
48
|
+
# from congroup_sl2z import is_SL2Z
|
|
49
|
+
# return (isinstance(x, Gamma1_class) or is_SL2Z(x))
|
|
50
|
+
return isinstance(x, Gamma1_class)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
_gamma1_cache = {}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def Gamma1_constructor(N):
|
|
57
|
+
r"""
|
|
58
|
+
Return the congruence subgroup `\Gamma_1(N)`.
|
|
59
|
+
|
|
60
|
+
EXAMPLES::
|
|
61
|
+
|
|
62
|
+
sage: Gamma1(5) # indirect doctest
|
|
63
|
+
Congruence Subgroup Gamma1(5)
|
|
64
|
+
sage: G = Gamma1(23)
|
|
65
|
+
sage: G is Gamma1(23)
|
|
66
|
+
True
|
|
67
|
+
sage: G is GammaH(23, [1])
|
|
68
|
+
True
|
|
69
|
+
sage: TestSuite(G).run()
|
|
70
|
+
sage: G is loads(dumps(G))
|
|
71
|
+
True
|
|
72
|
+
"""
|
|
73
|
+
if N == 1 or N == 2:
|
|
74
|
+
from .congroup_gamma0 import Gamma0_constructor
|
|
75
|
+
return Gamma0_constructor(N)
|
|
76
|
+
try:
|
|
77
|
+
return _gamma1_cache[N]
|
|
78
|
+
except KeyError:
|
|
79
|
+
_gamma1_cache[N] = Gamma1_class(N)
|
|
80
|
+
return _gamma1_cache[N]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class Gamma1_class(GammaH_class):
|
|
84
|
+
r"""
|
|
85
|
+
The congruence subgroup `\Gamma_1(N)`.
|
|
86
|
+
|
|
87
|
+
TESTS::
|
|
88
|
+
|
|
89
|
+
sage: [Gamma1(n).genus() for n in prime_range(2,100)]
|
|
90
|
+
[0, 0, 0, 0, 1, 2, 5, 7, 12, 22, 26, 40, 51, 57, 70, 92, 117, 126, 155, 176, 187, 222, 247, 287, 345]
|
|
91
|
+
sage: [Gamma1(n).index() for n in [1..10]]
|
|
92
|
+
[1, 3, 8, 12, 24, 24, 48, 48, 72, 72]
|
|
93
|
+
|
|
94
|
+
sage: [Gamma1(n).dimension_cusp_forms() for n in [1..20]]
|
|
95
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 1, 2, 5, 2, 7, 3]
|
|
96
|
+
sage: [Gamma1(n).dimension_cusp_forms(1) for n in [1..20]]
|
|
97
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
98
|
+
sage: [Gamma1(4).dimension_cusp_forms(k) for k in [1..20]]
|
|
99
|
+
[0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]
|
|
100
|
+
|
|
101
|
+
sage: Gamma1(23).dimension_cusp_forms(1)
|
|
102
|
+
1
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
def __init__(self, level):
|
|
106
|
+
r"""
|
|
107
|
+
The congruence subgroup `\Gamma_1(N)`.
|
|
108
|
+
|
|
109
|
+
EXAMPLES::
|
|
110
|
+
|
|
111
|
+
sage: G = Gamma1(11); G
|
|
112
|
+
Congruence Subgroup Gamma1(11)
|
|
113
|
+
sage: loads(G.dumps()) == G
|
|
114
|
+
True
|
|
115
|
+
"""
|
|
116
|
+
GammaH_class.__init__(self, level, [])
|
|
117
|
+
|
|
118
|
+
def _repr_(self):
|
|
119
|
+
"""
|
|
120
|
+
Return the string representation of ``self``.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: Gamma1(133)._repr_()
|
|
125
|
+
'Congruence Subgroup Gamma1(133)'
|
|
126
|
+
"""
|
|
127
|
+
return "Congruence Subgroup Gamma1(%s)" % self.level()
|
|
128
|
+
|
|
129
|
+
def __reduce__(self):
|
|
130
|
+
"""
|
|
131
|
+
Used for pickling ``self``.
|
|
132
|
+
|
|
133
|
+
EXAMPLES::
|
|
134
|
+
|
|
135
|
+
sage: Gamma1(82).__reduce__()
|
|
136
|
+
(<function Gamma1_constructor at ...>, (82,))
|
|
137
|
+
"""
|
|
138
|
+
return Gamma1_constructor, (self.level(),)
|
|
139
|
+
|
|
140
|
+
def _latex_(self) -> str:
|
|
141
|
+
r"""
|
|
142
|
+
Return the \LaTeX representation of ``self``.
|
|
143
|
+
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: Gamma1(3)._latex_()
|
|
147
|
+
'\\Gamma_1(3)'
|
|
148
|
+
sage: latex(Gamma1(3))
|
|
149
|
+
\Gamma_1(3)
|
|
150
|
+
"""
|
|
151
|
+
return "\\Gamma_1(%s)" % self.level()
|
|
152
|
+
|
|
153
|
+
def is_even(self) -> bool:
|
|
154
|
+
"""
|
|
155
|
+
Return ``True`` precisely if this subgroup contains the matrix -1.
|
|
156
|
+
|
|
157
|
+
EXAMPLES::
|
|
158
|
+
|
|
159
|
+
sage: Gamma1(1).is_even()
|
|
160
|
+
True
|
|
161
|
+
sage: Gamma1(2).is_even()
|
|
162
|
+
True
|
|
163
|
+
sage: Gamma1(15).is_even()
|
|
164
|
+
False
|
|
165
|
+
"""
|
|
166
|
+
return self.level() in [1, 2]
|
|
167
|
+
|
|
168
|
+
def is_subgroup(self, right) -> bool:
|
|
169
|
+
"""
|
|
170
|
+
Return ``True`` if ``self`` is a subgroup of ``right``.
|
|
171
|
+
|
|
172
|
+
EXAMPLES::
|
|
173
|
+
|
|
174
|
+
sage: Gamma1(3).is_subgroup(SL2Z)
|
|
175
|
+
True
|
|
176
|
+
sage: Gamma1(3).is_subgroup(Gamma1(5))
|
|
177
|
+
False
|
|
178
|
+
sage: Gamma1(3).is_subgroup(Gamma1(6))
|
|
179
|
+
False
|
|
180
|
+
sage: Gamma1(6).is_subgroup(Gamma1(3))
|
|
181
|
+
True
|
|
182
|
+
sage: Gamma1(6).is_subgroup(Gamma0(2))
|
|
183
|
+
True
|
|
184
|
+
sage: Gamma1(80).is_subgroup(GammaH(40, []))
|
|
185
|
+
True
|
|
186
|
+
sage: Gamma1(80).is_subgroup(GammaH(40, [21]))
|
|
187
|
+
True
|
|
188
|
+
"""
|
|
189
|
+
if right.level() == 1:
|
|
190
|
+
return True
|
|
191
|
+
if isinstance(right, GammaH_class):
|
|
192
|
+
return self.level() % right.level() == 0
|
|
193
|
+
else:
|
|
194
|
+
raise NotImplementedError
|
|
195
|
+
|
|
196
|
+
@cached_method
|
|
197
|
+
def generators(self, algorithm='farey'):
|
|
198
|
+
r"""
|
|
199
|
+
Return generators for this congruence subgroup. The result is cached.
|
|
200
|
+
|
|
201
|
+
INPUT:
|
|
202
|
+
|
|
203
|
+
- ``algorithm`` -- string; either ``'farey'`` (default) or
|
|
204
|
+
``'todd-coxeter'``
|
|
205
|
+
|
|
206
|
+
If ``algorithm`` is set to ``'farey'``, then the generators will be
|
|
207
|
+
calculated using Farey symbols, which will always return a *minimal*
|
|
208
|
+
generating set. See :mod:`~sage.modular.arithgroup.farey_symbol` for
|
|
209
|
+
more information.
|
|
210
|
+
|
|
211
|
+
If ``algorithm`` is set to ``'todd-coxeter'``, a simpler algorithm
|
|
212
|
+
based on Todd-Coxeter enumeration will be used. This tends to return
|
|
213
|
+
far larger sets of generators.
|
|
214
|
+
|
|
215
|
+
EXAMPLES::
|
|
216
|
+
|
|
217
|
+
sage: Gamma1(3).generators()
|
|
218
|
+
[
|
|
219
|
+
[1 1] [ 1 -1]
|
|
220
|
+
[0 1], [ 3 -2]
|
|
221
|
+
]
|
|
222
|
+
sage: Gamma1(3).generators(algorithm='todd-coxeter')
|
|
223
|
+
[
|
|
224
|
+
[1 1] [-2 1] [1 1] [ 1 -1] [1 0] [1 1] [-5 2] [ 1 0]
|
|
225
|
+
[0 1], [-3 1], [0 1], [ 0 1], [3 1], [0 1], [12 -5], [-3 1],
|
|
226
|
+
<BLANKLINE>
|
|
227
|
+
[ 1 -1] [ 1 -1] [ 4 -1] [ -5 3]
|
|
228
|
+
[ 3 -2], [ 3 -2], [ 9 -2], [-12 7]
|
|
229
|
+
]
|
|
230
|
+
"""
|
|
231
|
+
if algorithm == "farey":
|
|
232
|
+
return self.farey_symbol().generators()
|
|
233
|
+
elif algorithm == "todd-coxeter":
|
|
234
|
+
from sage.modular.modsym.g1list import G1list
|
|
235
|
+
from .congroup import generators_helper
|
|
236
|
+
level = self.level()
|
|
237
|
+
gen_list = generators_helper(G1list(level), level)
|
|
238
|
+
return [self(g, check=False) for g in gen_list]
|
|
239
|
+
else:
|
|
240
|
+
raise ValueError("Unknown algorithm '%s' (should be either 'farey' or 'todd-coxeter')" % algorithm)
|
|
241
|
+
|
|
242
|
+
def _contains_sl2(self, a, b, c, d):
|
|
243
|
+
r"""
|
|
244
|
+
Test whether x is an element of this group.
|
|
245
|
+
|
|
246
|
+
EXAMPLES::
|
|
247
|
+
|
|
248
|
+
sage: G = Gamma1(5)
|
|
249
|
+
sage: [1, 0, -10, 1] in G
|
|
250
|
+
True
|
|
251
|
+
sage: matrix(ZZ, 2, [6, 1, 5, 1]) in G
|
|
252
|
+
True
|
|
253
|
+
sage: SL2Z.0 in G
|
|
254
|
+
False
|
|
255
|
+
sage: G([1, 1, 6, 7]) # indirect doctest
|
|
256
|
+
Traceback (most recent call last):
|
|
257
|
+
...
|
|
258
|
+
TypeError: matrix [1 1]
|
|
259
|
+
[6 7] is not an element of Congruence Subgroup Gamma1(5)
|
|
260
|
+
"""
|
|
261
|
+
N = self.level()
|
|
262
|
+
# don't need to check d == 1 mod N as this is automatic from det
|
|
263
|
+
return ((a % N == 1) and (c % N == 0))
|
|
264
|
+
|
|
265
|
+
def nu2(self):
|
|
266
|
+
r"""
|
|
267
|
+
Calculate the number of orbits of elliptic points of order 2 for this
|
|
268
|
+
subgroup `\Gamma_1(N)`. This is known to be 0 if N > 2.
|
|
269
|
+
|
|
270
|
+
EXAMPLES::
|
|
271
|
+
|
|
272
|
+
sage: Gamma1(2).nu2()
|
|
273
|
+
1
|
|
274
|
+
sage: Gamma1(457).nu2()
|
|
275
|
+
0
|
|
276
|
+
sage: [Gamma1(n).nu2() for n in [1..16]]
|
|
277
|
+
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
278
|
+
"""
|
|
279
|
+
N = self.level()
|
|
280
|
+
if N > 2:
|
|
281
|
+
return 0
|
|
282
|
+
elif N == 2 or N == 1:
|
|
283
|
+
return 1
|
|
284
|
+
|
|
285
|
+
def nu3(self):
|
|
286
|
+
r"""
|
|
287
|
+
Calculate the number of orbits of elliptic points of order 3 for this
|
|
288
|
+
subgroup `\Gamma_1(N)`. This is known to be 0 if N > 3.
|
|
289
|
+
|
|
290
|
+
EXAMPLES::
|
|
291
|
+
|
|
292
|
+
sage: Gamma1(2).nu3()
|
|
293
|
+
0
|
|
294
|
+
sage: Gamma1(3).nu3()
|
|
295
|
+
1
|
|
296
|
+
sage: Gamma1(457).nu3()
|
|
297
|
+
0
|
|
298
|
+
sage: [Gamma1(n).nu3() for n in [1..10]]
|
|
299
|
+
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
|
|
300
|
+
"""
|
|
301
|
+
N = self.level()
|
|
302
|
+
if N > 3 or N == 2:
|
|
303
|
+
return 0
|
|
304
|
+
else:
|
|
305
|
+
return 1
|
|
306
|
+
|
|
307
|
+
def ncusps(self):
|
|
308
|
+
r"""
|
|
309
|
+
Return the number of cusps of this subgroup `\Gamma_1(N)`.
|
|
310
|
+
|
|
311
|
+
EXAMPLES::
|
|
312
|
+
|
|
313
|
+
sage: [Gamma1(n).ncusps() for n in [1..15]]
|
|
314
|
+
[1, 2, 2, 3, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 16]
|
|
315
|
+
sage: [Gamma1(n).ncusps() for n in prime_range(2, 100)]
|
|
316
|
+
[2, 2, 4, 6, 10, 12, 16, 18, 22, 28, 30, 36, 40, 42, 46, 52, 58, 60, 66, 70, 72, 78, 82, 88, 96]
|
|
317
|
+
"""
|
|
318
|
+
n = self.level()
|
|
319
|
+
if n <= 4:
|
|
320
|
+
return [None, 1, 2, 2, 3][n]
|
|
321
|
+
return ZZ(sum([phi(d)*phi(n/d)/ZZ(2) for d in n.divisors()]))
|
|
322
|
+
|
|
323
|
+
def index(self):
|
|
324
|
+
r"""
|
|
325
|
+
Return the index of ``self`` in the full modular group. This is given by the formula
|
|
326
|
+
|
|
327
|
+
.. MATH::
|
|
328
|
+
|
|
329
|
+
N^2 \prod_{\substack{p \mid N \\ \text{$p$ prime}}} \left( 1 - \frac{1}{p^2}\right).
|
|
330
|
+
|
|
331
|
+
EXAMPLES::
|
|
332
|
+
|
|
333
|
+
sage: Gamma1(180).index()
|
|
334
|
+
20736
|
|
335
|
+
sage: [Gamma1(n).projective_index() for n in [1..16]]
|
|
336
|
+
[1, 3, 4, 6, 12, 12, 24, 24, 36, 36, 60, 48, 84, 72, 96, 96]
|
|
337
|
+
"""
|
|
338
|
+
return prod([p**(2*e) - p**(2*e-2) for (p,e) in self.level().factor()])
|
|
339
|
+
|
|
340
|
+
##################################################################################
|
|
341
|
+
# Dimension formulas for Gamma1, accepting a Dirichlet character as an argument. #
|
|
342
|
+
##################################################################################
|
|
343
|
+
|
|
344
|
+
def dimension_modular_forms(self, k=2, eps=None, algorithm='CohenOesterle'):
|
|
345
|
+
r"""
|
|
346
|
+
Return the dimension of the space of modular forms for ``self``, or the
|
|
347
|
+
dimension of the subspace corresponding to the given character if one
|
|
348
|
+
is supplied.
|
|
349
|
+
|
|
350
|
+
INPUT:
|
|
351
|
+
|
|
352
|
+
- ``k`` -- integer (default: 2); the weight
|
|
353
|
+
|
|
354
|
+
- ``eps`` -- either ``None`` or a Dirichlet character modulo N, where N is
|
|
355
|
+
the level of this group. If this is ``None``, then the dimension of the
|
|
356
|
+
whole space is returned; otherwise, the dimension of the subspace of
|
|
357
|
+
forms of character eps.
|
|
358
|
+
|
|
359
|
+
- ``algorithm`` -- either ``'CohenOesterle'`` (the default) or
|
|
360
|
+
``'Quer'``. This specifies the method to use in the case of
|
|
361
|
+
nontrivial character: either the Cohen--Oesterle formula as described
|
|
362
|
+
in Stein's book, or by Möbius inversion using the subgroups GammaH (a
|
|
363
|
+
method due to Jordi Quer).
|
|
364
|
+
|
|
365
|
+
EXAMPLES::
|
|
366
|
+
|
|
367
|
+
sage: # needs sage.rings.number_field
|
|
368
|
+
sage: K = CyclotomicField(3)
|
|
369
|
+
sage: eps = DirichletGroup(7*43,K).0^2
|
|
370
|
+
sage: G = Gamma1(7*43)
|
|
371
|
+
sage: G.dimension_modular_forms(2, eps)
|
|
372
|
+
32
|
|
373
|
+
sage: G.dimension_modular_forms(2, eps, algorithm='Quer')
|
|
374
|
+
32
|
|
375
|
+
|
|
376
|
+
TESTS:
|
|
377
|
+
|
|
378
|
+
Check that :issue:`18436` is fixed::
|
|
379
|
+
|
|
380
|
+
sage: # needs sage.rings.number_field
|
|
381
|
+
sage: x = polygen(ZZ, 'x')
|
|
382
|
+
sage: K.<a> = NumberField(x^2 + x + 1)
|
|
383
|
+
sage: G = DirichletGroup(13, base_ring=K)
|
|
384
|
+
sage: Gamma1(13).dimension_modular_forms(2, G[1])
|
|
385
|
+
3
|
|
386
|
+
sage: Gamma1(13).dimension_modular_forms(2, G[1], algorithm='Quer')
|
|
387
|
+
3
|
|
388
|
+
sage: Gamma1(39).dimension_modular_forms(2, G[1])
|
|
389
|
+
7
|
|
390
|
+
sage: Gamma1(39).dimension_modular_forms(2, G[1], algorithm='Quer')
|
|
391
|
+
7
|
|
392
|
+
"""
|
|
393
|
+
return self.dimension_cusp_forms(k, eps, algorithm) + self.dimension_eis(k, eps, algorithm)
|
|
394
|
+
|
|
395
|
+
def dimension_cusp_forms(self, k=2, eps=None, algorithm='CohenOesterle'):
|
|
396
|
+
r"""
|
|
397
|
+
Return the dimension of the space of cusp forms for ``self``, or the
|
|
398
|
+
dimension of the subspace corresponding to the given character if one
|
|
399
|
+
is supplied.
|
|
400
|
+
|
|
401
|
+
INPUT:
|
|
402
|
+
|
|
403
|
+
- ``k`` -- integer (default: 2); the weight
|
|
404
|
+
|
|
405
|
+
- ``eps`` -- either ``None`` or a Dirichlet character modulo N, where N is
|
|
406
|
+
the level of this group. If this is ``None``, then the dimension of the
|
|
407
|
+
whole space is returned; otherwise, the dimension of the subspace of
|
|
408
|
+
forms of character eps.
|
|
409
|
+
|
|
410
|
+
- ``algorithm`` -- either ``'CohenOesterle'`` (the default) or
|
|
411
|
+
``'Quer'``. This specifies the method to use in the case of nontrivial
|
|
412
|
+
character: either the Cohen--Oesterle formula as described in Stein's
|
|
413
|
+
book, or by Möbius inversion using the subgroups GammaH (a method due
|
|
414
|
+
to Jordi Quer). Ignored for weight 1.
|
|
415
|
+
|
|
416
|
+
EXAMPLES:
|
|
417
|
+
|
|
418
|
+
We compute the same dimension in two different ways ::
|
|
419
|
+
|
|
420
|
+
sage: # needs sage.rings.number_field
|
|
421
|
+
sage: K = CyclotomicField(3)
|
|
422
|
+
sage: eps = DirichletGroup(7*43,K).0^2
|
|
423
|
+
sage: G = Gamma1(7*43)
|
|
424
|
+
|
|
425
|
+
Via Cohen--Oesterle::
|
|
426
|
+
|
|
427
|
+
sage: Gamma1(7*43).dimension_cusp_forms(2, eps) # needs sage.rings.number_field
|
|
428
|
+
28
|
|
429
|
+
|
|
430
|
+
Via Quer's method::
|
|
431
|
+
|
|
432
|
+
sage: Gamma1(7*43).dimension_cusp_forms(2, eps, algorithm='Quer') # needs sage.rings.number_field
|
|
433
|
+
28
|
|
434
|
+
|
|
435
|
+
Some more examples::
|
|
436
|
+
|
|
437
|
+
sage: G.<eps> = DirichletGroup(9)
|
|
438
|
+
sage: [Gamma1(9).dimension_cusp_forms(k, eps) for k in [1..10]]
|
|
439
|
+
[0, 0, 1, 0, 3, 0, 5, 0, 7, 0]
|
|
440
|
+
sage: [Gamma1(9).dimension_cusp_forms(k, eps^2) for k in [1..10]]
|
|
441
|
+
[0, 0, 0, 2, 0, 4, 0, 6, 0, 8]
|
|
442
|
+
|
|
443
|
+
In weight 1, we can sometimes rule out cusp forms existing via
|
|
444
|
+
Riemann-Roch, but if this does not work, we trigger computation of the
|
|
445
|
+
cusp forms space via Schaeffer's algorithm::
|
|
446
|
+
|
|
447
|
+
sage: chi = [u for u in DirichletGroup(40) if u(-1) == -1 and u(21) == 1][0]
|
|
448
|
+
sage: Gamma1(40).dimension_cusp_forms(1, chi)
|
|
449
|
+
0
|
|
450
|
+
sage: G = DirichletGroup(57); chi = (G.0) * (G.1)^6
|
|
451
|
+
sage: Gamma1(57).dimension_cusp_forms(1, chi)
|
|
452
|
+
1
|
|
453
|
+
"""
|
|
454
|
+
from .all import Gamma0
|
|
455
|
+
|
|
456
|
+
# first deal with special cases
|
|
457
|
+
|
|
458
|
+
if eps is None:
|
|
459
|
+
return GammaH_class.dimension_cusp_forms(self, k)
|
|
460
|
+
|
|
461
|
+
N = self.level()
|
|
462
|
+
K = eps.base_ring()
|
|
463
|
+
eps = DirichletGroup(N, K)(eps)
|
|
464
|
+
|
|
465
|
+
if K.characteristic() != 0:
|
|
466
|
+
raise NotImplementedError('dimension_cusp_forms() is only implemented for rings of characteristic 0')
|
|
467
|
+
|
|
468
|
+
if eps.is_trivial():
|
|
469
|
+
return Gamma0(N).dimension_cusp_forms(k)
|
|
470
|
+
|
|
471
|
+
if (k <= 0) or ((k % 2) == 1 and eps.is_even()) or ((k % 2) == 0 and eps.is_odd()):
|
|
472
|
+
return ZZ(0)
|
|
473
|
+
|
|
474
|
+
if k == 1:
|
|
475
|
+
from sage.modular.modform.weight1 import dimension_wt1_cusp_forms
|
|
476
|
+
return dimension_wt1_cusp_forms(eps)
|
|
477
|
+
|
|
478
|
+
# now the main part
|
|
479
|
+
|
|
480
|
+
if algorithm == "Quer":
|
|
481
|
+
n = eps.order()
|
|
482
|
+
dim = ZZ(0)
|
|
483
|
+
for d in n.divisors():
|
|
484
|
+
G = GammaH_constructor(N,(eps**d).kernel())
|
|
485
|
+
dim = dim + moebius(d)*G.dimension_cusp_forms(k)
|
|
486
|
+
return dim//phi(n)
|
|
487
|
+
|
|
488
|
+
elif algorithm == "CohenOesterle":
|
|
489
|
+
from sage.modular.dims import CohenOesterle
|
|
490
|
+
return ZZ( K(Gamma0(N).index() * (k-1)/ZZ(12)) + CohenOesterle(eps,k) )
|
|
491
|
+
|
|
492
|
+
else: # algorithm not in ["CohenOesterle", "Quer"]:
|
|
493
|
+
raise ValueError("Unrecognised algorithm in dimension_cusp_forms")
|
|
494
|
+
|
|
495
|
+
def dimension_eis(self, k=2, eps=None, algorithm='CohenOesterle'):
|
|
496
|
+
r"""
|
|
497
|
+
Return the dimension of the space of Eisenstein series forms for self,
|
|
498
|
+
or the dimension of the subspace corresponding to the given character
|
|
499
|
+
if one is supplied.
|
|
500
|
+
|
|
501
|
+
INPUT:
|
|
502
|
+
|
|
503
|
+
- ``k`` -- integer (default: 2); the weight
|
|
504
|
+
|
|
505
|
+
- ``eps`` -- either ``None`` or a Dirichlet character modulo N, where N is
|
|
506
|
+
the level of this group. If this is ``None``, then the dimension of the
|
|
507
|
+
whole space is returned; otherwise, the dimension of the subspace of
|
|
508
|
+
Eisenstein series of character eps.
|
|
509
|
+
|
|
510
|
+
- ``algorithm`` -- either ``'CohenOesterle'`` (the default) or
|
|
511
|
+
``'Quer'``. This specifies the method to use in the case of nontrivial
|
|
512
|
+
character: either the Cohen--Oesterle formula as described in Stein's
|
|
513
|
+
book, or by Möbius inversion using the subgroups GammaH (a method due
|
|
514
|
+
to Jordi Quer).
|
|
515
|
+
|
|
516
|
+
AUTHORS:
|
|
517
|
+
|
|
518
|
+
- William Stein - Cohen--Oesterle algorithm
|
|
519
|
+
|
|
520
|
+
- Jordi Quer - algorithm based on GammaH subgroups
|
|
521
|
+
|
|
522
|
+
- David Loeffler (2009) - code refactoring
|
|
523
|
+
|
|
524
|
+
EXAMPLES:
|
|
525
|
+
|
|
526
|
+
The following two computations use different algorithms::
|
|
527
|
+
|
|
528
|
+
sage: [Gamma1(36).dimension_eis(1,eps) for eps in DirichletGroup(36)]
|
|
529
|
+
[0, 4, 3, 0, 0, 2, 6, 0, 0, 2, 3, 0]
|
|
530
|
+
sage: [Gamma1(36).dimension_eis(1,eps,algorithm='Quer') for eps in DirichletGroup(36)]
|
|
531
|
+
[0, 4, 3, 0, 0, 2, 6, 0, 0, 2, 3, 0]
|
|
532
|
+
|
|
533
|
+
So do these::
|
|
534
|
+
|
|
535
|
+
sage: [Gamma1(48).dimension_eis(3,eps) for eps in DirichletGroup(48)]
|
|
536
|
+
[0, 12, 0, 4, 0, 8, 0, 4, 12, 0, 4, 0, 8, 0, 4, 0]
|
|
537
|
+
sage: [Gamma1(48).dimension_eis(3,eps,algorithm='Quer') for eps in DirichletGroup(48)]
|
|
538
|
+
[0, 12, 0, 4, 0, 8, 0, 4, 12, 0, 4, 0, 8, 0, 4, 0]
|
|
539
|
+
"""
|
|
540
|
+
from .all import Gamma0
|
|
541
|
+
|
|
542
|
+
# first deal with special cases
|
|
543
|
+
|
|
544
|
+
if eps is None:
|
|
545
|
+
return GammaH_class.dimension_eis(self, k)
|
|
546
|
+
|
|
547
|
+
N = self.level()
|
|
548
|
+
K = eps.base_ring()
|
|
549
|
+
eps = DirichletGroup(N, K)(eps)
|
|
550
|
+
|
|
551
|
+
if eps.is_trivial():
|
|
552
|
+
return Gamma0(N).dimension_eis(k)
|
|
553
|
+
|
|
554
|
+
# Note case of k = 0 and trivial character already dealt with separately, so k <= 0 here is valid:
|
|
555
|
+
if (k <= 0) or ((k % 2) == 1 and eps.is_even()) or ((k % 2) == 0 and eps.is_odd()):
|
|
556
|
+
return ZZ(0)
|
|
557
|
+
|
|
558
|
+
if algorithm == "Quer":
|
|
559
|
+
n = eps.order()
|
|
560
|
+
dim = ZZ(0)
|
|
561
|
+
for d in n.divisors():
|
|
562
|
+
G = GammaH_constructor(N,(eps**d).kernel())
|
|
563
|
+
dim = dim + moebius(d)*G.dimension_eis(k)
|
|
564
|
+
return dim//phi(n)
|
|
565
|
+
|
|
566
|
+
elif algorithm == "CohenOesterle":
|
|
567
|
+
from sage.modular.dims import CohenOesterle
|
|
568
|
+
j = 2-k
|
|
569
|
+
# We use the Cohen-Oesterle formula in a subtle way to
|
|
570
|
+
# compute dim M_k(N,eps) (see Ch. 6 of William Stein's book on
|
|
571
|
+
# computing with modular forms).
|
|
572
|
+
alpha = -ZZ( K(Gamma0(N).index()*(j-1)/ZZ(12)) + CohenOesterle(eps,j) )
|
|
573
|
+
if k == 1:
|
|
574
|
+
return alpha
|
|
575
|
+
else:
|
|
576
|
+
return alpha - self.dimension_cusp_forms(k, eps)
|
|
577
|
+
|
|
578
|
+
else: # algorithm not in ["CohenOesterle", "Quer"]:
|
|
579
|
+
raise ValueError("Unrecognised algorithm in dimension_eis")
|
|
580
|
+
|
|
581
|
+
def dimension_new_cusp_forms(self, k=2, eps=None, p=0, algorithm='CohenOesterle'):
|
|
582
|
+
r"""
|
|
583
|
+
Dimension of the new subspace (or `p`-new subspace) of cusp forms of
|
|
584
|
+
weight `k` and character `\varepsilon`.
|
|
585
|
+
|
|
586
|
+
INPUT:
|
|
587
|
+
|
|
588
|
+
- ``k`` -- integer (default: 2)
|
|
589
|
+
|
|
590
|
+
- ``eps`` -- a Dirichlet character
|
|
591
|
+
|
|
592
|
+
- ``p`` -- a prime (default: 0); just the `p`-new subspace if given
|
|
593
|
+
|
|
594
|
+
- ``algorithm`` -- either ``'CohenOesterle'`` (the default) or
|
|
595
|
+
``'Quer'``. This specifies the method to use in the case of nontrivial
|
|
596
|
+
character: either the Cohen--Oesterle formula as described in Stein's
|
|
597
|
+
book, or by Möbius inversion using the subgroups GammaH (a method due
|
|
598
|
+
to Jordi Quer).
|
|
599
|
+
|
|
600
|
+
EXAMPLES::
|
|
601
|
+
|
|
602
|
+
sage: G = DirichletGroup(9)
|
|
603
|
+
sage: eps = G.0^3
|
|
604
|
+
sage: eps.conductor()
|
|
605
|
+
3
|
|
606
|
+
sage: [Gamma1(9).dimension_new_cusp_forms(k, eps) for k in [2..10]]
|
|
607
|
+
[0, 0, 0, 2, 0, 2, 0, 2, 0]
|
|
608
|
+
sage: [Gamma1(9).dimension_cusp_forms(k, eps) for k in [2..10]]
|
|
609
|
+
[0, 0, 0, 2, 0, 4, 0, 6, 0]
|
|
610
|
+
sage: [Gamma1(9).dimension_new_cusp_forms(k, eps, 3) for k in [2..10]]
|
|
611
|
+
[0, 0, 0, 2, 0, 2, 0, 2, 0]
|
|
612
|
+
|
|
613
|
+
Double check using modular symbols (independent calculation)::
|
|
614
|
+
|
|
615
|
+
sage: [ModularSymbols(eps,k,sign=1).cuspidal_subspace().new_subspace().dimension() for k in [2..10]]
|
|
616
|
+
[0, 0, 0, 2, 0, 2, 0, 2, 0]
|
|
617
|
+
sage: [ModularSymbols(eps,k,sign=1).cuspidal_subspace().new_subspace(3).dimension() for k in [2..10]]
|
|
618
|
+
[0, 0, 0, 2, 0, 2, 0, 2, 0]
|
|
619
|
+
|
|
620
|
+
Another example at level 33::
|
|
621
|
+
|
|
622
|
+
sage: G = DirichletGroup(33)
|
|
623
|
+
sage: eps = G.1
|
|
624
|
+
sage: eps.conductor()
|
|
625
|
+
11
|
|
626
|
+
sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1) for k in [2..4]]
|
|
627
|
+
[0, 4, 0]
|
|
628
|
+
sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1, algorithm='Quer') for k in [2..4]]
|
|
629
|
+
[0, 4, 0]
|
|
630
|
+
sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1^2) for k in [2..4]]
|
|
631
|
+
[2, 0, 6]
|
|
632
|
+
sage: [Gamma1(33).dimension_new_cusp_forms(k, G.1^2, p=3) for k in [2..4]]
|
|
633
|
+
[2, 0, 6]
|
|
634
|
+
"""
|
|
635
|
+
|
|
636
|
+
if eps is None:
|
|
637
|
+
return GammaH_class.dimension_new_cusp_forms(self, k, p)
|
|
638
|
+
|
|
639
|
+
N = self.level()
|
|
640
|
+
eps = DirichletGroup(N, eps.base_ring())(eps)
|
|
641
|
+
|
|
642
|
+
if eps.is_trivial():
|
|
643
|
+
from .all import Gamma0
|
|
644
|
+
return Gamma0(N).dimension_new_cusp_forms(k, p)
|
|
645
|
+
|
|
646
|
+
from .congroup_gammaH import mumu
|
|
647
|
+
|
|
648
|
+
if p == 0 or N % p != 0 or eps.conductor().valuation(p) == N.valuation(p):
|
|
649
|
+
D = [eps.conductor()*d for d in divisors(N//eps.conductor())]
|
|
650
|
+
return sum([Gamma1_constructor(M).dimension_cusp_forms(k, eps.restrict(M), algorithm)*mumu(N//M) for M in D])
|
|
651
|
+
eps_p = eps.restrict(N//p)
|
|
652
|
+
old = Gamma1_constructor(N//p).dimension_cusp_forms(k, eps_p, algorithm)
|
|
653
|
+
return self.dimension_cusp_forms(k, eps, algorithm) - 2*old
|