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,1767 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.libs.flint sage.libs.pari
|
|
3
|
+
"""
|
|
4
|
+
Hecke modules
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# ****************************************************************************
|
|
8
|
+
# Copyright (C) 2004,2005,2006 William Stein <wstein@gmail.com>
|
|
9
|
+
#
|
|
10
|
+
# This program is free software: you can redistribute it and/or modify
|
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
|
12
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
13
|
+
# (at your option) any later version.
|
|
14
|
+
# https://www.gnu.org/licenses/
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
|
|
17
|
+
import sage.misc.prandom as random
|
|
18
|
+
|
|
19
|
+
from sage.arith.misc import is_prime, factor, prime_divisors, gcd, primes, valuation, GCD, next_prime
|
|
20
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
21
|
+
from sage.misc.verbose import verbose
|
|
22
|
+
from sage.modules.free_module import FreeModule
|
|
23
|
+
from sage.modules.module import Module
|
|
24
|
+
from sage.rings.integer_ring import ZZ
|
|
25
|
+
from sage.rings.rational_field import QQ
|
|
26
|
+
from sage.categories.commutative_rings import CommutativeRings
|
|
27
|
+
from sage.structure.sequence import Sequence
|
|
28
|
+
|
|
29
|
+
from . import algebra
|
|
30
|
+
from . import element
|
|
31
|
+
from . import hecke_operator
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def is_HeckeModule(x):
|
|
35
|
+
r"""
|
|
36
|
+
Return ``True`` if ``x`` is a Hecke module.
|
|
37
|
+
|
|
38
|
+
EXAMPLES::
|
|
39
|
+
|
|
40
|
+
sage: from sage.modular.hecke.module import is_HeckeModule
|
|
41
|
+
sage: is_HeckeModule(ModularForms(Gamma0(7), 4))
|
|
42
|
+
doctest:warning...
|
|
43
|
+
DeprecationWarning: the function is_HeckeModule is deprecated;
|
|
44
|
+
use 'isinstance(..., HeckeModule_generic)' instead
|
|
45
|
+
See https://github.com/sagemath/sage/issues/37895 for details.
|
|
46
|
+
True
|
|
47
|
+
sage: is_HeckeModule(QQ^3)
|
|
48
|
+
False
|
|
49
|
+
sage: is_HeckeModule(J0(37).homology())
|
|
50
|
+
True
|
|
51
|
+
"""
|
|
52
|
+
from sage.misc.superseded import deprecation
|
|
53
|
+
deprecation(37895, "the function is_HeckeModule is deprecated; use 'isinstance(..., HeckeModule_generic)' instead")
|
|
54
|
+
return isinstance(x, HeckeModule_generic)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class HeckeModule_generic(Module):
|
|
58
|
+
r"""
|
|
59
|
+
A very general base class for Hecke modules.
|
|
60
|
+
|
|
61
|
+
We define a Hecke module of weight `k` to be a module over a commutative
|
|
62
|
+
ring equipped with an action of operators `T_m` for all positive integers `m`
|
|
63
|
+
coprime to some integer `n`(the level), which satisfy `T_r T_s = T_{rs}` for
|
|
64
|
+
`r,s` coprime, and for powers of a prime `p`, `T_{p^r} = T_{p} T_{p^{r-1}} -
|
|
65
|
+
\varepsilon(p) p^{k-1} T_{p^{r-2}}`, where `\varepsilon(p)` is some
|
|
66
|
+
endomorphism of the module which commutes with the `T_m`.
|
|
67
|
+
|
|
68
|
+
We distinguish between *full* Hecke modules, which also have an action of
|
|
69
|
+
operators `T_m` for `m` not assumed to be coprime to the level, and
|
|
70
|
+
*anemic* Hecke modules, for which this does not hold.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
Element = element.HeckeModuleElement
|
|
74
|
+
|
|
75
|
+
def __init__(self, base_ring, level, category=None):
|
|
76
|
+
r"""
|
|
77
|
+
Create a Hecke module. Not intended to be called directly.
|
|
78
|
+
|
|
79
|
+
EXAMPLES::
|
|
80
|
+
|
|
81
|
+
sage: CuspForms(Gamma0(17),2) # indirect doctest
|
|
82
|
+
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(17) of weight 2 over Rational Field
|
|
83
|
+
sage: ModularForms(3, 3).category()
|
|
84
|
+
Category of Hecke modules over Rational Field
|
|
85
|
+
"""
|
|
86
|
+
if base_ring not in CommutativeRings():
|
|
87
|
+
raise TypeError("base_ring must be commutative ring")
|
|
88
|
+
|
|
89
|
+
from sage.categories.hecke_modules import HeckeModules
|
|
90
|
+
default_category = HeckeModules(base_ring)
|
|
91
|
+
if category is None:
|
|
92
|
+
category = default_category
|
|
93
|
+
else:
|
|
94
|
+
assert category.is_subcategory(default_category), "%s is not a subcategory of %s" % (category, default_category)
|
|
95
|
+
|
|
96
|
+
Module.__init__(self, base_ring, category=category)
|
|
97
|
+
|
|
98
|
+
level = ZZ(level)
|
|
99
|
+
if level <= 0:
|
|
100
|
+
raise ValueError("level (=%s) must be positive" % level)
|
|
101
|
+
self.__level = level
|
|
102
|
+
self._hecke_matrices = {}
|
|
103
|
+
self._diamond_matrices = {}
|
|
104
|
+
|
|
105
|
+
def __setstate__(self, state):
|
|
106
|
+
r"""
|
|
107
|
+
Ensure that the category is initialized correctly on unpickling.
|
|
108
|
+
|
|
109
|
+
EXAMPLES::
|
|
110
|
+
|
|
111
|
+
sage: loads(dumps(ModularSymbols(11))).category() # indirect doctest
|
|
112
|
+
Category of Hecke modules over Rational Field
|
|
113
|
+
"""
|
|
114
|
+
if not self._is_category_initialized():
|
|
115
|
+
from sage.categories.hecke_modules import HeckeModules
|
|
116
|
+
self._init_category_(HeckeModules(state['_base']))
|
|
117
|
+
Module.__setstate__(self, state)
|
|
118
|
+
|
|
119
|
+
def __hash__(self):
|
|
120
|
+
r"""
|
|
121
|
+
The hash is determined by the base ring and the level.
|
|
122
|
+
|
|
123
|
+
EXAMPLES::
|
|
124
|
+
|
|
125
|
+
sage: MS = sage.modular.hecke.module.HeckeModule_generic(QQ,1)
|
|
126
|
+
sage: hash(MS) == hash((MS.base_ring(), MS.level()))
|
|
127
|
+
True
|
|
128
|
+
"""
|
|
129
|
+
return hash((self.base_ring(), self.__level))
|
|
130
|
+
|
|
131
|
+
def _compute_hecke_matrix_prime_power(self, p, r, **kwds):
|
|
132
|
+
r"""
|
|
133
|
+
Compute the Hecke matrix T_{p^r}, where `p` is prime and `r \ge 2`, assuming that
|
|
134
|
+
`T_p` is known.
|
|
135
|
+
|
|
136
|
+
This is carried out by recursion.
|
|
137
|
+
|
|
138
|
+
All derived classes must override either this function or
|
|
139
|
+
``self.character()``.
|
|
140
|
+
|
|
141
|
+
EXAMPLES::
|
|
142
|
+
|
|
143
|
+
sage: M = ModularForms(SL2Z, 24)
|
|
144
|
+
sage: M._compute_hecke_matrix_prime_power(3, 3)
|
|
145
|
+
[ -4112503986561480 53074162446443642880 0]
|
|
146
|
+
[ 2592937954080 -1312130996155080 0]
|
|
147
|
+
[ 0 0 834385168339943471891603972970040]
|
|
148
|
+
"""
|
|
149
|
+
# convert input arguments to int's.
|
|
150
|
+
p, r = (int(p), int(r))
|
|
151
|
+
if not is_prime(p):
|
|
152
|
+
raise ArithmeticError("p must be a prime")
|
|
153
|
+
# T_{p^r} := T_p * T_{p^{r-1}} - eps(p)p^{k-1} T_{p^{r-2}}.
|
|
154
|
+
pow = p**(r - 1)
|
|
155
|
+
if pow not in self._hecke_matrices:
|
|
156
|
+
# The following will force computation of T_{p^s}
|
|
157
|
+
# for all s<=r-1, except possibly s=0.
|
|
158
|
+
self._hecke_matrices[pow] = self._compute_hecke_matrix(pow)
|
|
159
|
+
if 1 not in self._hecke_matrices:
|
|
160
|
+
self._hecke_matrices[1] = self._compute_hecke_matrix(1)
|
|
161
|
+
Tp = self._hecke_matrices[p]
|
|
162
|
+
Tpr1 = self._hecke_matrices[pow]
|
|
163
|
+
eps = self.character()
|
|
164
|
+
if eps is None:
|
|
165
|
+
raise NotImplementedError("either character or _compute_hecke_matrix_prime_power must be overloaded in a derived class")
|
|
166
|
+
k = self.weight()
|
|
167
|
+
Tpr2 = self._hecke_matrices[pow // p]
|
|
168
|
+
return Tp * Tpr1 - eps(p) * (p**(k - 1)) * Tpr2
|
|
169
|
+
|
|
170
|
+
def _compute_hecke_matrix_general_product(self, F, **kwds):
|
|
171
|
+
r"""
|
|
172
|
+
Compute the matrix of a general Hecke operator acting on this space, by
|
|
173
|
+
factorising n into prime powers and multiplying together the Hecke
|
|
174
|
+
operators for each of these.
|
|
175
|
+
|
|
176
|
+
EXAMPLES::
|
|
177
|
+
|
|
178
|
+
sage: M = ModularSymbols(Gamma0(3), 4)
|
|
179
|
+
sage: M._compute_hecke_matrix_general_product(factor(10))
|
|
180
|
+
[1134 0]
|
|
181
|
+
[ 0 1134]
|
|
182
|
+
"""
|
|
183
|
+
prod = None
|
|
184
|
+
for p, r in F:
|
|
185
|
+
pow = int(p**r)
|
|
186
|
+
if pow not in self._hecke_matrices:
|
|
187
|
+
self._hecke_matrices[pow] = self._compute_hecke_matrix(pow)
|
|
188
|
+
if prod is None:
|
|
189
|
+
prod = self._hecke_matrices[pow]
|
|
190
|
+
else:
|
|
191
|
+
prod *= self._hecke_matrices[pow]
|
|
192
|
+
return prod
|
|
193
|
+
|
|
194
|
+
def _compute_dual_hecke_matrix(self, n):
|
|
195
|
+
r"""
|
|
196
|
+
Compute the matrix of the Hecke operator `T_n` acting on the dual of ``self``.
|
|
197
|
+
|
|
198
|
+
EXAMPLES::
|
|
199
|
+
|
|
200
|
+
sage: M = ModularSymbols(Gamma0(3), 4)
|
|
201
|
+
sage: M._compute_dual_hecke_matrix(10)
|
|
202
|
+
[1134 0]
|
|
203
|
+
[ 0 1134]
|
|
204
|
+
"""
|
|
205
|
+
return self.hecke_matrix(n).transpose()
|
|
206
|
+
|
|
207
|
+
def _compute_hecke_matrix(self, n, **kwds):
|
|
208
|
+
r"""
|
|
209
|
+
Compute the matrix of the Hecke operator `T_n` acting on ``self``.
|
|
210
|
+
|
|
211
|
+
EXAMPLES::
|
|
212
|
+
|
|
213
|
+
sage: M = EisensteinForms(DirichletGroup(3).0, 3)
|
|
214
|
+
sage: M._compute_hecke_matrix(16)
|
|
215
|
+
[205 0]
|
|
216
|
+
[ 0 205]
|
|
217
|
+
"""
|
|
218
|
+
n = int(n)
|
|
219
|
+
if n < 1:
|
|
220
|
+
raise ValueError("Hecke operator T_%s is not defined." % n)
|
|
221
|
+
if n == 1:
|
|
222
|
+
Mat = MatrixSpace(self.base_ring(), self.rank())
|
|
223
|
+
return Mat(1)
|
|
224
|
+
|
|
225
|
+
if is_prime(n):
|
|
226
|
+
return self._compute_hecke_matrix_prime(n, **kwds)
|
|
227
|
+
|
|
228
|
+
F = factor(n)
|
|
229
|
+
if len(F) == 1: # nontrivial prime power case
|
|
230
|
+
return self._compute_hecke_matrix_prime_power(F[0][0], F[0][1], **kwds)
|
|
231
|
+
|
|
232
|
+
else:
|
|
233
|
+
return self._compute_hecke_matrix_general_product(F, **kwds)
|
|
234
|
+
|
|
235
|
+
def _compute_hecke_matrix_prime(self, p, **kwds):
|
|
236
|
+
"""
|
|
237
|
+
Compute and return the matrix of the `p`-th Hecke operator for `p` prime.
|
|
238
|
+
|
|
239
|
+
Derived classes should overload this function, and they will inherit
|
|
240
|
+
the machinery for calculating general Hecke operators.
|
|
241
|
+
|
|
242
|
+
EXAMPLES::
|
|
243
|
+
|
|
244
|
+
sage: M = EisensteinForms(DirichletGroup(3).0, 3)
|
|
245
|
+
sage: sage.modular.hecke.module.HeckeModule_generic._compute_hecke_matrix_prime(M, 3)
|
|
246
|
+
Traceback (most recent call last):
|
|
247
|
+
...
|
|
248
|
+
NotImplementedError: All subclasses must implement _compute_hecke_matrix_prime
|
|
249
|
+
"""
|
|
250
|
+
raise NotImplementedError("All subclasses must implement _compute_hecke_matrix_prime")
|
|
251
|
+
|
|
252
|
+
def _compute_diamond_matrix(self, d):
|
|
253
|
+
r"""
|
|
254
|
+
Compute the matrix of the diamond bracket operator `\langle d \rangle` on this space,
|
|
255
|
+
in cases where this is not self-evident (i.e. when this is not a space
|
|
256
|
+
with fixed character).
|
|
257
|
+
|
|
258
|
+
EXAMPLES::
|
|
259
|
+
|
|
260
|
+
sage: M = EisensteinForms(Gamma1(5), 3)
|
|
261
|
+
sage: sage.modular.hecke.module.HeckeModule_generic._compute_diamond_matrix(M, 2)
|
|
262
|
+
Traceback (most recent call last):
|
|
263
|
+
...
|
|
264
|
+
NotImplementedError: All subclasses without fixed character must implement _compute_diamond_matrix
|
|
265
|
+
"""
|
|
266
|
+
raise NotImplementedError("All subclasses without fixed character must implement _compute_diamond_matrix")
|
|
267
|
+
|
|
268
|
+
def _hecke_operator_class(self):
|
|
269
|
+
"""
|
|
270
|
+
Return the class to be used for instantiating Hecke operators
|
|
271
|
+
acting on ``self``.
|
|
272
|
+
|
|
273
|
+
EXAMPLES::
|
|
274
|
+
|
|
275
|
+
sage: sage.modular.hecke.module.HeckeModule_generic(QQ,1)._hecke_operator_class()
|
|
276
|
+
<class 'sage.modular.hecke.hecke_operator.HeckeOperator'>
|
|
277
|
+
sage: ModularSymbols(1,12)._hecke_operator_class()
|
|
278
|
+
<class 'sage.modular.modsym.hecke_operator.HeckeOperator'>
|
|
279
|
+
"""
|
|
280
|
+
return hecke_operator.HeckeOperator
|
|
281
|
+
|
|
282
|
+
def _diamond_operator_class(self):
|
|
283
|
+
r"""
|
|
284
|
+
Return the class to be used for instantiating diamond bracket operators
|
|
285
|
+
acting on ``self``.
|
|
286
|
+
|
|
287
|
+
EXAMPLES::
|
|
288
|
+
|
|
289
|
+
sage: sage.modular.hecke.module.HeckeModule_generic(QQ,1)._diamond_operator_class()
|
|
290
|
+
<class 'sage.modular.hecke.hecke_operator.DiamondBracketOperator'>
|
|
291
|
+
sage: ModularSymbols(1,12)._diamond_operator_class()
|
|
292
|
+
<class 'sage.modular.hecke.hecke_operator.DiamondBracketOperator'>
|
|
293
|
+
"""
|
|
294
|
+
return hecke_operator.DiamondBracketOperator
|
|
295
|
+
|
|
296
|
+
def anemic_hecke_algebra(self):
|
|
297
|
+
"""
|
|
298
|
+
Return the Hecke algebra associated to this Hecke module.
|
|
299
|
+
|
|
300
|
+
EXAMPLES::
|
|
301
|
+
|
|
302
|
+
sage: T = ModularSymbols(1,12).hecke_algebra()
|
|
303
|
+
sage: A = ModularSymbols(1,12).anemic_hecke_algebra()
|
|
304
|
+
sage: T == A
|
|
305
|
+
False
|
|
306
|
+
sage: A
|
|
307
|
+
Anemic Hecke algebra acting on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
|
|
308
|
+
sage: A.is_anemic()
|
|
309
|
+
True
|
|
310
|
+
"""
|
|
311
|
+
return algebra.AnemicHeckeAlgebra(self)
|
|
312
|
+
|
|
313
|
+
def character(self):
|
|
314
|
+
r"""
|
|
315
|
+
Return the character of this space.
|
|
316
|
+
|
|
317
|
+
As this is an abstract base class, return ``None``.
|
|
318
|
+
|
|
319
|
+
EXAMPLES::
|
|
320
|
+
|
|
321
|
+
sage: sage.modular.hecke.module.HeckeModule_generic(QQ, 10).character() is None
|
|
322
|
+
True
|
|
323
|
+
"""
|
|
324
|
+
return
|
|
325
|
+
|
|
326
|
+
def dimension(self):
|
|
327
|
+
r"""
|
|
328
|
+
Synonym for :meth:`rank`.
|
|
329
|
+
|
|
330
|
+
EXAMPLES::
|
|
331
|
+
|
|
332
|
+
sage: M = sage.modular.hecke.module.HeckeModule_generic(QQ, 10).dimension()
|
|
333
|
+
Traceback (most recent call last):
|
|
334
|
+
...
|
|
335
|
+
NotImplementedError: Derived subclasses must implement rank
|
|
336
|
+
"""
|
|
337
|
+
return self.rank()
|
|
338
|
+
|
|
339
|
+
def hecke_algebra(self):
|
|
340
|
+
"""
|
|
341
|
+
Return the Hecke algebra associated to this Hecke module.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: T = ModularSymbols(Gamma1(5),3).hecke_algebra()
|
|
346
|
+
sage: T
|
|
347
|
+
Full Hecke algebra acting on Modular Symbols space of dimension 4 for Gamma_1(5) of weight 3 with sign 0 over Rational Field
|
|
348
|
+
sage: T.is_anemic()
|
|
349
|
+
False
|
|
350
|
+
|
|
351
|
+
::
|
|
352
|
+
|
|
353
|
+
sage: M = ModularSymbols(37,sign=1)
|
|
354
|
+
sage: E, A, B = M.decomposition()
|
|
355
|
+
sage: A.hecke_algebra() == B.hecke_algebra()
|
|
356
|
+
False
|
|
357
|
+
"""
|
|
358
|
+
return algebra.HeckeAlgebra(self)
|
|
359
|
+
|
|
360
|
+
def is_zero(self) -> bool:
|
|
361
|
+
"""
|
|
362
|
+
Return ``True`` if this Hecke module has dimension 0.
|
|
363
|
+
|
|
364
|
+
EXAMPLES::
|
|
365
|
+
|
|
366
|
+
sage: ModularSymbols(11).is_zero()
|
|
367
|
+
False
|
|
368
|
+
sage: ModularSymbols(11).old_submodule().is_zero()
|
|
369
|
+
True
|
|
370
|
+
sage: CuspForms(10).is_zero()
|
|
371
|
+
True
|
|
372
|
+
sage: CuspForms(1,12).is_zero()
|
|
373
|
+
False
|
|
374
|
+
"""
|
|
375
|
+
return self.dimension() == 0
|
|
376
|
+
|
|
377
|
+
def is_full_hecke_module(self) -> bool:
|
|
378
|
+
"""
|
|
379
|
+
Return ``True`` if this space is invariant under all Hecke operators.
|
|
380
|
+
|
|
381
|
+
Since ``self`` is guaranteed to be an anemic Hecke module, the
|
|
382
|
+
significance of this function is that it also ensures
|
|
383
|
+
invariance under Hecke operators of index that divide the level.
|
|
384
|
+
|
|
385
|
+
EXAMPLES::
|
|
386
|
+
|
|
387
|
+
sage: M = ModularSymbols(22); M.is_full_hecke_module()
|
|
388
|
+
True
|
|
389
|
+
sage: M.submodule(M.free_module().span([M.0.list()]), check=False).is_full_hecke_module()
|
|
390
|
+
False
|
|
391
|
+
"""
|
|
392
|
+
try:
|
|
393
|
+
return self._is_full_hecke_module
|
|
394
|
+
except AttributeError:
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
# now compute whether invariant under Hecke operators of index
|
|
398
|
+
# dividing the level
|
|
399
|
+
verbose("Determining if Hecke module is full.")
|
|
400
|
+
N = self.level()
|
|
401
|
+
for p in prime_divisors(N):
|
|
402
|
+
if not self.is_hecke_invariant(p):
|
|
403
|
+
self._is_full_hecke_module = False
|
|
404
|
+
return False
|
|
405
|
+
self._is_full_hecke_module = True
|
|
406
|
+
return True
|
|
407
|
+
|
|
408
|
+
def is_hecke_invariant(self, n) -> bool:
|
|
409
|
+
"""
|
|
410
|
+
Return ``True`` if ``self`` is invariant under the Hecke operator `T_n`.
|
|
411
|
+
|
|
412
|
+
Since ``self`` is guaranteed to be an anemic Hecke module it is only
|
|
413
|
+
interesting to call this function when `n` is not coprime
|
|
414
|
+
to the level.
|
|
415
|
+
|
|
416
|
+
EXAMPLES::
|
|
417
|
+
|
|
418
|
+
sage: M = ModularSymbols(22).cuspidal_subspace()
|
|
419
|
+
sage: M.is_hecke_invariant(2)
|
|
420
|
+
True
|
|
421
|
+
|
|
422
|
+
We use ``check=False`` to create a nasty "module" that is not invariant
|
|
423
|
+
under `T_2`::
|
|
424
|
+
|
|
425
|
+
sage: S = M.submodule(M.free_module().span([M.0.list()]), check=False); S
|
|
426
|
+
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 7 for Gamma_0(22) of weight 2 with sign 0 over Rational Field
|
|
427
|
+
sage: S.is_hecke_invariant(2)
|
|
428
|
+
False
|
|
429
|
+
sage: [n for n in range(1,12) if S.is_hecke_invariant(n)]
|
|
430
|
+
[1, 3, 5, 7, 9, 11]
|
|
431
|
+
"""
|
|
432
|
+
if gcd(n, self.level()) == 1:
|
|
433
|
+
return True
|
|
434
|
+
if self.is_ambient():
|
|
435
|
+
return True
|
|
436
|
+
try:
|
|
437
|
+
self.hecke_operator(n).matrix()
|
|
438
|
+
except ArithmeticError:
|
|
439
|
+
return False
|
|
440
|
+
return True
|
|
441
|
+
|
|
442
|
+
def level(self):
|
|
443
|
+
"""
|
|
444
|
+
Return the level of this modular symbols space.
|
|
445
|
+
|
|
446
|
+
INPUT:
|
|
447
|
+
|
|
448
|
+
- ``ModularSymbols self`` -- an arbitrary space of modular symbols
|
|
449
|
+
|
|
450
|
+
OUTPUT: integer; the level
|
|
451
|
+
|
|
452
|
+
EXAMPLES::
|
|
453
|
+
|
|
454
|
+
sage: m = ModularSymbols(20)
|
|
455
|
+
sage: m.level()
|
|
456
|
+
20
|
|
457
|
+
"""
|
|
458
|
+
return self.__level
|
|
459
|
+
|
|
460
|
+
def rank(self):
|
|
461
|
+
r"""
|
|
462
|
+
Return the rank of this module over its base ring.
|
|
463
|
+
|
|
464
|
+
This raises a :exc:`NotImplementedError`, since this is an
|
|
465
|
+
abstract base class.
|
|
466
|
+
|
|
467
|
+
EXAMPLES::
|
|
468
|
+
|
|
469
|
+
sage: sage.modular.hecke.module.HeckeModule_generic(QQ, 10).rank()
|
|
470
|
+
Traceback (most recent call last):
|
|
471
|
+
...
|
|
472
|
+
NotImplementedError: Derived subclasses must implement rank
|
|
473
|
+
"""
|
|
474
|
+
raise NotImplementedError("Derived subclasses must implement rank")
|
|
475
|
+
|
|
476
|
+
def submodule(self, X):
|
|
477
|
+
r"""
|
|
478
|
+
Return the submodule of ``self`` corresponding to ``X``.
|
|
479
|
+
|
|
480
|
+
As this is an abstract base class, this raises a
|
|
481
|
+
:exc:`NotImplementedError`.
|
|
482
|
+
|
|
483
|
+
EXAMPLES::
|
|
484
|
+
|
|
485
|
+
sage: sage.modular.hecke.module.HeckeModule_generic(QQ, 10).submodule(0)
|
|
486
|
+
Traceback (most recent call last):
|
|
487
|
+
...
|
|
488
|
+
NotImplementedError: Derived subclasses should implement submodule
|
|
489
|
+
"""
|
|
490
|
+
raise NotImplementedError("Derived subclasses should implement submodule")
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
class HeckeModule_free_module(HeckeModule_generic):
|
|
494
|
+
"""
|
|
495
|
+
A Hecke module modeled on a free module over a commutative ring.
|
|
496
|
+
"""
|
|
497
|
+
def __init__(self, base_ring, level, weight, category=None):
|
|
498
|
+
r"""
|
|
499
|
+
Initialise a module.
|
|
500
|
+
|
|
501
|
+
EXAMPLES::
|
|
502
|
+
|
|
503
|
+
sage: M = sage.modular.hecke.module.HeckeModule_free_module(QQ, 12, -4); M
|
|
504
|
+
<class 'sage.modular.hecke.module.HeckeModule_free_module_with_category'>
|
|
505
|
+
sage: skipped = ["_test_additive_associativity",
|
|
506
|
+
....: "_test_an_element", "_test_elements",
|
|
507
|
+
....: "_test_elements_eq_reflexive",
|
|
508
|
+
....: "_test_elements_eq_symmetric",
|
|
509
|
+
....: "_test_elements_eq_transitive", "_test_elements_neq",
|
|
510
|
+
....: "_test_pickling", "_test_some_elements",
|
|
511
|
+
....: "_test_zero", "_test_eq"]
|
|
512
|
+
sage: TestSuite(M).run(skip=skipped)
|
|
513
|
+
|
|
514
|
+
.. NOTE:: Is this supposed to be an abstract parent without elements?
|
|
515
|
+
"""
|
|
516
|
+
HeckeModule_generic.__init__(self, base_ring, level, category=category)
|
|
517
|
+
self.__weight = weight
|
|
518
|
+
|
|
519
|
+
def _repr_(self):
|
|
520
|
+
r"""
|
|
521
|
+
|
|
522
|
+
EXAMPLES::
|
|
523
|
+
|
|
524
|
+
sage: M = sage.modular.hecke.module.HeckeModule_free_module(QQ, 12, -4); M
|
|
525
|
+
<class 'sage.modular.hecke.module.HeckeModule_free_module_with_category'>
|
|
526
|
+
|
|
527
|
+
.. TODO::
|
|
528
|
+
|
|
529
|
+
Implement a nicer repr, or implement the methods required
|
|
530
|
+
by :class:`ModulesWithBasis` to benefit from
|
|
531
|
+
:meth:`ModulesWithBasis.ParentMethods._repr_`.
|
|
532
|
+
"""
|
|
533
|
+
return repr(type(self))
|
|
534
|
+
|
|
535
|
+
def __getitem__(self, n):
|
|
536
|
+
r"""
|
|
537
|
+
Return the `n`-th term in the decomposition of ``self``.
|
|
538
|
+
|
|
539
|
+
See the docstring for :meth:`decomposition` for further information.
|
|
540
|
+
|
|
541
|
+
EXAMPLES::
|
|
542
|
+
|
|
543
|
+
sage: ModularSymbols(22)[0]
|
|
544
|
+
Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 7 for Gamma_0(22) of weight 2 with sign 0 over Rational Field
|
|
545
|
+
"""
|
|
546
|
+
n = int(n)
|
|
547
|
+
D = self.decomposition()
|
|
548
|
+
if n < 0 or n >= len(D):
|
|
549
|
+
raise IndexError("index (=%s) must be between 0 and %s" % (n, len(D) - 1))
|
|
550
|
+
return D[n]
|
|
551
|
+
|
|
552
|
+
def __hash__(self):
|
|
553
|
+
r"""
|
|
554
|
+
The hash is determined by the weight, the level and the base ring.
|
|
555
|
+
|
|
556
|
+
EXAMPLES::
|
|
557
|
+
|
|
558
|
+
sage: MS = ModularSymbols(22)
|
|
559
|
+
sage: hash(MS) == hash((MS.weight(), MS.level(), MS.base_ring()))
|
|
560
|
+
True
|
|
561
|
+
"""
|
|
562
|
+
return hash((self.__weight, self.level(), self.base_ring()))
|
|
563
|
+
|
|
564
|
+
def __len__(self):
|
|
565
|
+
r"""
|
|
566
|
+
Return the number of factors in the decomposition of ``self``.
|
|
567
|
+
|
|
568
|
+
EXAMPLES::
|
|
569
|
+
|
|
570
|
+
sage: len(ModularSymbols(22))
|
|
571
|
+
2
|
|
572
|
+
"""
|
|
573
|
+
return len(self.decomposition())
|
|
574
|
+
|
|
575
|
+
def _eigen_nonzero(self):
|
|
576
|
+
"""
|
|
577
|
+
Return the smallest integer `i` such that the `i`-th entries of
|
|
578
|
+
the entries of a basis for the dual vector space are not all 0.
|
|
579
|
+
|
|
580
|
+
EXAMPLES::
|
|
581
|
+
|
|
582
|
+
sage: M = ModularSymbols(31,2)
|
|
583
|
+
sage: M._eigen_nonzero()
|
|
584
|
+
0
|
|
585
|
+
sage: M.dual_free_module().basis()
|
|
586
|
+
[(1, 0, 0, 0, 0),
|
|
587
|
+
(0, 1, 0, 0, 0),
|
|
588
|
+
(0, 0, 1, 0, 0),
|
|
589
|
+
(0, 0, 0, 1, 0),
|
|
590
|
+
(0, 0, 0, 0, 1)]
|
|
591
|
+
sage: M.cuspidal_submodule().minus_submodule()._eigen_nonzero()
|
|
592
|
+
1
|
|
593
|
+
sage: M.cuspidal_submodule().minus_submodule().dual_free_module().basis()
|
|
594
|
+
[(0, 1, 0, 0, 0), (0, 0, 1, 0, 0)]
|
|
595
|
+
"""
|
|
596
|
+
try:
|
|
597
|
+
return self.__eigen_nonzero
|
|
598
|
+
except AttributeError:
|
|
599
|
+
pass
|
|
600
|
+
V = self.dual_free_module()
|
|
601
|
+
B = V.basis()
|
|
602
|
+
for i in range(V.degree()):
|
|
603
|
+
for b in B:
|
|
604
|
+
if b[i] != 0:
|
|
605
|
+
self.__eigen_nonzero = i
|
|
606
|
+
return i
|
|
607
|
+
assert False, 'bug in _eigen_nonzero'
|
|
608
|
+
|
|
609
|
+
def _eigen_nonzero_element(self, n=1):
|
|
610
|
+
r"""
|
|
611
|
+
Return `T_n(x)` where `x` is a sparse modular
|
|
612
|
+
symbol such that the image of `x` is nonzero under the dual
|
|
613
|
+
projection map associated to this space, and `T_n` is the
|
|
614
|
+
`n`-th Hecke operator.
|
|
615
|
+
|
|
616
|
+
Used in the :meth:`dual_eigenvector` and :meth:`eigenvalue` methods.
|
|
617
|
+
|
|
618
|
+
EXAMPLES::
|
|
619
|
+
|
|
620
|
+
sage: ModularSymbols(22)._eigen_nonzero_element(3)
|
|
621
|
+
4*(1,0) + (2,21) - (11,1) + (11,2)
|
|
622
|
+
"""
|
|
623
|
+
if self.rank() == 0:
|
|
624
|
+
raise ArithmeticError("the rank of self must be positive")
|
|
625
|
+
A = self.ambient_hecke_module()
|
|
626
|
+
i = self._eigen_nonzero()
|
|
627
|
+
return A._hecke_image_of_ith_basis_vector(n, i)
|
|
628
|
+
|
|
629
|
+
def _hecke_image_of_ith_basis_vector(self, n, i):
|
|
630
|
+
r"""
|
|
631
|
+
Return `T_n(e_i)`, where `e_i` is the `i`-th basis vector
|
|
632
|
+
of the ambient space.
|
|
633
|
+
|
|
634
|
+
EXAMPLES::
|
|
635
|
+
|
|
636
|
+
sage: ModularSymbols(Gamma0(3))._hecke_image_of_ith_basis_vector(4, 0)
|
|
637
|
+
7*(1,0)
|
|
638
|
+
sage: ModularForms(Gamma0(3))._hecke_image_of_ith_basis_vector(4, 0)
|
|
639
|
+
7 + 84*q + 252*q^2 + 84*q^3 + 588*q^4 + 504*q^5 + O(q^6)
|
|
640
|
+
"""
|
|
641
|
+
T = self.hecke_operator(n)
|
|
642
|
+
return T.apply_sparse(self.gen(i))
|
|
643
|
+
|
|
644
|
+
def _element_eigenvalue(self, x, name='alpha'):
|
|
645
|
+
r"""
|
|
646
|
+
Return the dot product of ``self`` with the eigenvector returned by dual_eigenvector.
|
|
647
|
+
|
|
648
|
+
EXAMPLES::
|
|
649
|
+
|
|
650
|
+
sage: M = ModularSymbols(11)[0]
|
|
651
|
+
sage: M._element_eigenvalue(M.0)
|
|
652
|
+
1
|
|
653
|
+
"""
|
|
654
|
+
if not isinstance(x, element.HeckeModuleElement):
|
|
655
|
+
raise TypeError("x must be a Hecke module element.")
|
|
656
|
+
if x not in self.ambient_hecke_module():
|
|
657
|
+
raise ArithmeticError("x must be in the ambient Hecke module.")
|
|
658
|
+
v = self.dual_eigenvector(names=name)
|
|
659
|
+
return v.dot_product(x.element())
|
|
660
|
+
|
|
661
|
+
def _is_hecke_equivariant_free_module(self, submodule):
|
|
662
|
+
"""
|
|
663
|
+
Return ``True`` if the given free submodule of the ambient free module
|
|
664
|
+
is invariant under all Hecke operators.
|
|
665
|
+
|
|
666
|
+
EXAMPLES::
|
|
667
|
+
|
|
668
|
+
sage: M = ModularSymbols(11); V = M.free_module()
|
|
669
|
+
sage: M._is_hecke_equivariant_free_module(V.span([V.0]))
|
|
670
|
+
False
|
|
671
|
+
sage: M._is_hecke_equivariant_free_module(V)
|
|
672
|
+
True
|
|
673
|
+
sage: M._is_hecke_equivariant_free_module(M.cuspidal_submodule().free_module())
|
|
674
|
+
True
|
|
675
|
+
|
|
676
|
+
We do the same as above, but with a modular forms space::
|
|
677
|
+
|
|
678
|
+
sage: M = ModularForms(11); V = M.free_module()
|
|
679
|
+
sage: M._is_hecke_equivariant_free_module(V.span([V.0 + V.1]))
|
|
680
|
+
False
|
|
681
|
+
sage: M._is_hecke_equivariant_free_module(V)
|
|
682
|
+
True
|
|
683
|
+
sage: M._is_hecke_equivariant_free_module(M.cuspidal_submodule().free_module())
|
|
684
|
+
True
|
|
685
|
+
"""
|
|
686
|
+
verbose("Determining if free module is Hecke equivariant.")
|
|
687
|
+
bound = self.hecke_bound()
|
|
688
|
+
for p in primes(bound + 1):
|
|
689
|
+
try:
|
|
690
|
+
self.T(p).matrix().restrict(submodule, check=True)
|
|
691
|
+
except ArithmeticError:
|
|
692
|
+
return False
|
|
693
|
+
return True
|
|
694
|
+
|
|
695
|
+
def _set_factor_number(self, i):
|
|
696
|
+
r"""
|
|
697
|
+
For internal use. If this Hecke module was computed via a decomposition of another
|
|
698
|
+
Hecke module, this method stores the index of this space in that decomposition.
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: ModularSymbols(Gamma0(3))[0].factor_number() # indirect doctest
|
|
703
|
+
0
|
|
704
|
+
"""
|
|
705
|
+
self.__factor_number = i
|
|
706
|
+
|
|
707
|
+
def ambient(self):
|
|
708
|
+
r"""
|
|
709
|
+
Return the ambient module associated to this module.
|
|
710
|
+
|
|
711
|
+
Synonym for :meth:`ambient_hecke_module`.
|
|
712
|
+
|
|
713
|
+
EXAMPLES::
|
|
714
|
+
|
|
715
|
+
sage: CuspForms(1, 12).ambient()
|
|
716
|
+
Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
|
|
717
|
+
"""
|
|
718
|
+
return self.ambient_hecke_module()
|
|
719
|
+
|
|
720
|
+
def ambient_module(self):
|
|
721
|
+
r"""
|
|
722
|
+
Return the ambient module associated to this module.
|
|
723
|
+
|
|
724
|
+
Synonym for :meth:`ambient_hecke_module`.
|
|
725
|
+
|
|
726
|
+
EXAMPLES::
|
|
727
|
+
|
|
728
|
+
sage: CuspForms(1, 12).ambient_module()
|
|
729
|
+
Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
|
|
730
|
+
sage: sage.modular.hecke.module.HeckeModule_free_module(QQ, 10, 3).ambient_module()
|
|
731
|
+
Traceback (most recent call last):
|
|
732
|
+
...
|
|
733
|
+
NotImplementedError
|
|
734
|
+
"""
|
|
735
|
+
return self.ambient_hecke_module()
|
|
736
|
+
|
|
737
|
+
def ambient_hecke_module(self):
|
|
738
|
+
r"""
|
|
739
|
+
Return the ambient module associated to this module.
|
|
740
|
+
|
|
741
|
+
As this is an abstract base class, raise :exc:`NotImplementedError`.
|
|
742
|
+
|
|
743
|
+
EXAMPLES::
|
|
744
|
+
|
|
745
|
+
sage: sage.modular.hecke.module.HeckeModule_free_module(QQ, 10, 3).ambient_hecke_module()
|
|
746
|
+
Traceback (most recent call last):
|
|
747
|
+
...
|
|
748
|
+
NotImplementedError
|
|
749
|
+
"""
|
|
750
|
+
raise NotImplementedError
|
|
751
|
+
|
|
752
|
+
def atkin_lehner_operator(self, d=None):
|
|
753
|
+
r"""
|
|
754
|
+
Return the Atkin-Lehner operator `W_d` on this space, if defined, where
|
|
755
|
+
`d` is a divisor of the level `N` such that `N/d` and `d` are coprime.
|
|
756
|
+
If `d` is not given, we take `d = N`. If `N/d` is not coprime to `d`,
|
|
757
|
+
then we replace `d` with the unique integer having this property which
|
|
758
|
+
has the same prime factors as `d`.
|
|
759
|
+
|
|
760
|
+
.. NOTE::
|
|
761
|
+
|
|
762
|
+
The operator `W_d` is given by the action of any matrix of the form
|
|
763
|
+
|
|
764
|
+
.. math::
|
|
765
|
+
|
|
766
|
+
W_d = \begin{pmatrix} dx & y \\ Nz & dw \end{pmatrix}
|
|
767
|
+
|
|
768
|
+
with `\det W_d = d` and such that `x = 1 \bmod N/d`, `y = 1 \bmod
|
|
769
|
+
d`, as in [AL1978]_. However, our definition of the weight `k`
|
|
770
|
+
action differs from theirs by a power of the determinant, so our
|
|
771
|
+
operator `W_d` is `d^{k/2 - 1}` times the operator of Atkin-Li. In
|
|
772
|
+
particular, if `k = 2` our conventions are identical to Atkin and
|
|
773
|
+
Li's.
|
|
774
|
+
|
|
775
|
+
With Sage's conventions, the operator `W_d` satisfies
|
|
776
|
+
|
|
777
|
+
.. math::
|
|
778
|
+
|
|
779
|
+
W_d^2 = d^{k - 2} \langle x^{-1} \rangle
|
|
780
|
+
|
|
781
|
+
where `x` is congruent to `d` modulo `N/d` and to `-1` modulo `d`.
|
|
782
|
+
In particular, the operator is an involution in weight 2 and
|
|
783
|
+
trivial character (but not in most other situations).
|
|
784
|
+
|
|
785
|
+
EXAMPLES::
|
|
786
|
+
|
|
787
|
+
sage: M = ModularSymbols(11)
|
|
788
|
+
sage: w = M.atkin_lehner_operator()
|
|
789
|
+
sage: w
|
|
790
|
+
Hecke module morphism Atkin-Lehner operator W_11 defined by the matrix
|
|
791
|
+
[-1 0 0]
|
|
792
|
+
[ 0 -1 0]
|
|
793
|
+
[ 0 0 -1]
|
|
794
|
+
Domain: Modular Symbols space of dimension 3 for Gamma_0(11) of weight ...
|
|
795
|
+
Codomain: Modular Symbols space of dimension 3 for Gamma_0(11) of weight ...
|
|
796
|
+
sage: M = ModularSymbols(Gamma1(13))
|
|
797
|
+
sage: w = M.atkin_lehner_operator()
|
|
798
|
+
sage: w.fcp('x')
|
|
799
|
+
(x - 1)^7 * (x + 1)^8
|
|
800
|
+
|
|
801
|
+
::
|
|
802
|
+
|
|
803
|
+
sage: M = ModularSymbols(33)
|
|
804
|
+
sage: S = M.cuspidal_submodule()
|
|
805
|
+
sage: S.atkin_lehner_operator()
|
|
806
|
+
Hecke module morphism Atkin-Lehner operator W_33 defined by the matrix
|
|
807
|
+
[ 0 -1 0 1 -1 0]
|
|
808
|
+
[ 0 -1 0 0 0 0]
|
|
809
|
+
[ 0 -1 0 0 -1 1]
|
|
810
|
+
[ 1 -1 0 0 -1 0]
|
|
811
|
+
[ 0 0 0 0 -1 0]
|
|
812
|
+
[ 0 -1 1 0 -1 0]
|
|
813
|
+
Domain: Modular Symbols subspace of dimension 6 of Modular Symbols space ...
|
|
814
|
+
Codomain: Modular Symbols subspace of dimension 6 of Modular Symbols space ...
|
|
815
|
+
|
|
816
|
+
::
|
|
817
|
+
|
|
818
|
+
sage: S.atkin_lehner_operator(3)
|
|
819
|
+
Hecke module morphism Atkin-Lehner operator W_3 defined by the matrix
|
|
820
|
+
[ 0 1 0 -1 1 0]
|
|
821
|
+
[ 0 1 0 0 0 0]
|
|
822
|
+
[ 0 1 0 0 1 -1]
|
|
823
|
+
[-1 1 0 0 1 0]
|
|
824
|
+
[ 0 0 0 0 1 0]
|
|
825
|
+
[ 0 1 -1 0 1 0]
|
|
826
|
+
Domain: Modular Symbols subspace of dimension 6 of Modular Symbols space ...
|
|
827
|
+
Codomain: Modular Symbols subspace of dimension 6 of Modular Symbols space ...
|
|
828
|
+
|
|
829
|
+
::
|
|
830
|
+
|
|
831
|
+
sage: N = M.new_submodule()
|
|
832
|
+
sage: N.atkin_lehner_operator()
|
|
833
|
+
Hecke module morphism Atkin-Lehner operator W_33 defined by the matrix
|
|
834
|
+
[ 1 2/5 4/5]
|
|
835
|
+
[ 0 -1 0]
|
|
836
|
+
[ 0 0 -1]
|
|
837
|
+
Domain: Modular Symbols subspace of dimension 3 of Modular Symbols space ...
|
|
838
|
+
Codomain: Modular Symbols subspace of dimension 3 of Modular Symbols space ...
|
|
839
|
+
"""
|
|
840
|
+
if d is None:
|
|
841
|
+
d = self.level()
|
|
842
|
+
d = int(d)
|
|
843
|
+
if self.level() % d:
|
|
844
|
+
raise ArithmeticError("d (=%s) must be a divisor of the level (=%s)" % (d, self.level()))
|
|
845
|
+
|
|
846
|
+
N = self.level()
|
|
847
|
+
for p, e in factor(d):
|
|
848
|
+
v = valuation(N, p)
|
|
849
|
+
if e < v:
|
|
850
|
+
d *= p**(v - e)
|
|
851
|
+
d = int(d)
|
|
852
|
+
try:
|
|
853
|
+
return self.__atkin_lehner_operator[d]
|
|
854
|
+
except AttributeError:
|
|
855
|
+
self.__atkin_lehner_operator = {}
|
|
856
|
+
except KeyError:
|
|
857
|
+
pass
|
|
858
|
+
Wmat = self._compute_atkin_lehner_matrix(d)
|
|
859
|
+
H = self.endomorphism_ring()
|
|
860
|
+
W = H(Wmat, "Atkin-Lehner operator W_%s" % d)
|
|
861
|
+
self.__atkin_lehner_operator[d] = W
|
|
862
|
+
return W
|
|
863
|
+
|
|
864
|
+
def basis(self):
|
|
865
|
+
"""
|
|
866
|
+
Return a basis for ``self``.
|
|
867
|
+
|
|
868
|
+
EXAMPLES::
|
|
869
|
+
|
|
870
|
+
sage: m = ModularSymbols(43)
|
|
871
|
+
sage: m.basis()
|
|
872
|
+
((1,0), (1,31), (1,32), (1,38), (1,39), (1,40), (1,41))
|
|
873
|
+
"""
|
|
874
|
+
try:
|
|
875
|
+
return self.__basis
|
|
876
|
+
except AttributeError:
|
|
877
|
+
self.__basis = self.gens()
|
|
878
|
+
return self.__basis
|
|
879
|
+
|
|
880
|
+
def basis_matrix(self):
|
|
881
|
+
r"""
|
|
882
|
+
Return the matrix of the basis vectors of ``self`` (as vectors in some
|
|
883
|
+
ambient module)
|
|
884
|
+
|
|
885
|
+
EXAMPLES::
|
|
886
|
+
|
|
887
|
+
sage: CuspForms(1, 12).basis_matrix()
|
|
888
|
+
[1 0]
|
|
889
|
+
"""
|
|
890
|
+
return self.free_module().basis_matrix()
|
|
891
|
+
|
|
892
|
+
def coordinate_vector(self, x):
|
|
893
|
+
"""
|
|
894
|
+
Write ``x`` as a vector with respect to the basis given by
|
|
895
|
+
self.basis().
|
|
896
|
+
|
|
897
|
+
EXAMPLES::
|
|
898
|
+
|
|
899
|
+
sage: S = ModularSymbols(11,2).cuspidal_submodule()
|
|
900
|
+
sage: S.0
|
|
901
|
+
(1,8)
|
|
902
|
+
sage: S.basis()
|
|
903
|
+
((1,8), (1,9))
|
|
904
|
+
sage: S.coordinate_vector(S.0)
|
|
905
|
+
(1, 0)
|
|
906
|
+
"""
|
|
907
|
+
return self.free_module().coordinate_vector(x.element())
|
|
908
|
+
|
|
909
|
+
def decomposition(self, bound=None, anemic=True, height_guess=1,
|
|
910
|
+
sort_by_basis=False, proof=None):
|
|
911
|
+
"""
|
|
912
|
+
Return the maximal decomposition of this Hecke module under the
|
|
913
|
+
action of Hecke operators of index coprime to the level.
|
|
914
|
+
|
|
915
|
+
This is the finest decomposition of ``self`` that we can obtain
|
|
916
|
+
using factors obtained by taking kernels of Hecke operators.
|
|
917
|
+
|
|
918
|
+
Each factor in the decomposition is a Hecke submodule obtained as
|
|
919
|
+
the kernel of `f(T_n)^r` acting on self, where n is
|
|
920
|
+
coprime to the level and `r=1`. If anemic is False, instead
|
|
921
|
+
choose `r` so that `f(X)^r` exactly divides the
|
|
922
|
+
characteristic polynomial.
|
|
923
|
+
|
|
924
|
+
INPUT:
|
|
925
|
+
|
|
926
|
+
- ``anemic`` -- boolean (default: ``True``); if ``True``, use only
|
|
927
|
+
Hecke operators of index coprime to the level
|
|
928
|
+
|
|
929
|
+
- ``bound`` -- integer or ``None`` (default: ``None``); if ``None``,
|
|
930
|
+
use all Hecke operators up to the Sturm bound, and hence obtain the
|
|
931
|
+
same result as one would obtain by using every element of the Hecke
|
|
932
|
+
ring. If a fixed integer, decompose using only Hecke operators
|
|
933
|
+
`T_p`, with `p` prime, up to bound.
|
|
934
|
+
- ``sort_by_basis`` -- boolean (default: ``False``); if ``True`` the
|
|
935
|
+
resulting decomposition will be sorted as if it was free modules,
|
|
936
|
+
ignoring the Hecke module structure. This will save a lot of time.
|
|
937
|
+
|
|
938
|
+
OUTPUT: list of subspaces of ``self``
|
|
939
|
+
|
|
940
|
+
EXAMPLES::
|
|
941
|
+
|
|
942
|
+
sage: ModularSymbols(17,2).decomposition()
|
|
943
|
+
[Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(17) of weight 2 with sign 0 over Rational Field,
|
|
944
|
+
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(17) of weight 2 with sign 0 over Rational Field]
|
|
945
|
+
sage: ModularSymbols(Gamma1(10),4).decomposition()
|
|
946
|
+
[Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field,
|
|
947
|
+
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field,
|
|
948
|
+
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field,
|
|
949
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field,
|
|
950
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field,
|
|
951
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field]
|
|
952
|
+
sage: ModularSymbols(GammaH(12, [11])).decomposition()
|
|
953
|
+
[Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field,
|
|
954
|
+
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field,
|
|
955
|
+
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field,
|
|
956
|
+
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field,
|
|
957
|
+
Modular Symbols subspace of dimension 5 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field]
|
|
958
|
+
|
|
959
|
+
TESTS::
|
|
960
|
+
|
|
961
|
+
sage: M = ModularSymbols(1000,2,sign=1).new_subspace().cuspidal_subspace()
|
|
962
|
+
sage: M.decomposition(3, sort_by_basis = True)
|
|
963
|
+
[Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field,
|
|
964
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field,
|
|
965
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field,
|
|
966
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field,
|
|
967
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field,
|
|
968
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field]
|
|
969
|
+
"""
|
|
970
|
+
if not isinstance(anemic, bool):
|
|
971
|
+
raise TypeError("anemic must be of type bool.")
|
|
972
|
+
|
|
973
|
+
key = (bound, anemic)
|
|
974
|
+
|
|
975
|
+
try:
|
|
976
|
+
if self.__decomposition[key] is not None:
|
|
977
|
+
return self.__decomposition[key]
|
|
978
|
+
except AttributeError:
|
|
979
|
+
self.__decomposition = {}
|
|
980
|
+
except KeyError:
|
|
981
|
+
pass
|
|
982
|
+
if self.rank() == 0:
|
|
983
|
+
self.__decomposition[key] = Sequence([], immutable=True, cr=True)
|
|
984
|
+
return self.__decomposition[key]
|
|
985
|
+
|
|
986
|
+
is_rational = self.base_ring() == QQ
|
|
987
|
+
|
|
988
|
+
time = verbose("Decomposing %s" % self)
|
|
989
|
+
T = self.ambient_hecke_module().hecke_algebra()
|
|
990
|
+
if bound is None:
|
|
991
|
+
bound = self.ambient_hecke_module().hecke_bound()
|
|
992
|
+
D = Sequence([], cr=True)
|
|
993
|
+
U = [self.free_module()]
|
|
994
|
+
p = 2
|
|
995
|
+
while U and p <= bound:
|
|
996
|
+
verbose(mesg="p=%s" % p, t=time)
|
|
997
|
+
if anemic:
|
|
998
|
+
while GCD(p, self.level()) != 1:
|
|
999
|
+
p = next_prime(p)
|
|
1000
|
+
verbose("Decomposition using p=%s" % p)
|
|
1001
|
+
t = T.hecke_operator(p).matrix()
|
|
1002
|
+
Uprime = []
|
|
1003
|
+
for i in range(len(U)):
|
|
1004
|
+
is_diagonalizable = (not self.base_ring().characteristic() and
|
|
1005
|
+
self.level() % p)
|
|
1006
|
+
if is_rational:
|
|
1007
|
+
X = t.decomposition_of_subspace(U[i], check_restrict=False,
|
|
1008
|
+
algorithm='multimodular',
|
|
1009
|
+
height_guess=height_guess, proof=proof)
|
|
1010
|
+
else:
|
|
1011
|
+
X = t.decomposition_of_subspace(U[i], check_restrict=False,
|
|
1012
|
+
is_diagonalizable=is_diagonalizable)
|
|
1013
|
+
for Xi in X:
|
|
1014
|
+
W, is_irred = Xi
|
|
1015
|
+
if is_irred:
|
|
1016
|
+
A = self.submodule(W, check=False)
|
|
1017
|
+
D.append(A)
|
|
1018
|
+
else:
|
|
1019
|
+
Uprime.append(W)
|
|
1020
|
+
# end for
|
|
1021
|
+
p = next_prime(p)
|
|
1022
|
+
U = Uprime
|
|
1023
|
+
# end while
|
|
1024
|
+
for i in range(len(U)):
|
|
1025
|
+
A = self.submodule(U[i], check=False)
|
|
1026
|
+
D.append(A)
|
|
1027
|
+
for A in D:
|
|
1028
|
+
if anemic:
|
|
1029
|
+
A.__is_splittable_anemic = False
|
|
1030
|
+
A.__is_splittable = False
|
|
1031
|
+
else:
|
|
1032
|
+
A.__is_splittable = False
|
|
1033
|
+
self.__is_splittable = len(D) > 1
|
|
1034
|
+
if anemic:
|
|
1035
|
+
self.__is_splittable_anemic = len(D) > 1
|
|
1036
|
+
from sage.modules.free_module import EchelonMatrixKey
|
|
1037
|
+
D.sort(key=None if not sort_by_basis
|
|
1038
|
+
else lambda ss: EchelonMatrixKey(ss.free_module()))
|
|
1039
|
+
D.set_immutable()
|
|
1040
|
+
self.__decomposition[key] = D
|
|
1041
|
+
for i in range(len(D)):
|
|
1042
|
+
self.__decomposition[key][i]._set_factor_number(i)
|
|
1043
|
+
return self.__decomposition[key]
|
|
1044
|
+
|
|
1045
|
+
def degree(self):
|
|
1046
|
+
r"""
|
|
1047
|
+
Return the degree of this Hecke module.
|
|
1048
|
+
|
|
1049
|
+
This is the rank of the ambient free module.
|
|
1050
|
+
|
|
1051
|
+
EXAMPLES::
|
|
1052
|
+
|
|
1053
|
+
sage: CuspForms(1, 12).degree()
|
|
1054
|
+
2
|
|
1055
|
+
"""
|
|
1056
|
+
return self.free_module().degree()
|
|
1057
|
+
|
|
1058
|
+
def dual_eigenvector(self, names='alpha', lift=True, nz=None):
|
|
1059
|
+
"""
|
|
1060
|
+
Return an eigenvector for the Hecke operators acting on the linear
|
|
1061
|
+
dual of this space.
|
|
1062
|
+
|
|
1063
|
+
This eigenvector will have entries in an extension of the base
|
|
1064
|
+
ring of degree equal to the dimension of this space.
|
|
1065
|
+
|
|
1066
|
+
.. WARNING::
|
|
1067
|
+
|
|
1068
|
+
The input space must be simple.
|
|
1069
|
+
|
|
1070
|
+
INPUT:
|
|
1071
|
+
|
|
1072
|
+
- ``name`` -- print name of generator for eigenvalue
|
|
1073
|
+
field
|
|
1074
|
+
|
|
1075
|
+
- ``lift`` -- boolean (default: ``True``)
|
|
1076
|
+
|
|
1077
|
+
- ``nz`` -- if not ``None``, then normalize vector so dot
|
|
1078
|
+
product with this basis vector of ambient space is 1
|
|
1079
|
+
|
|
1080
|
+
OUTPUT:
|
|
1081
|
+
|
|
1082
|
+
A vector with entries possibly in an extension of the base
|
|
1083
|
+
ring. This vector is an eigenvector for all Hecke operators acting
|
|
1084
|
+
via their transpose.
|
|
1085
|
+
|
|
1086
|
+
If lift = False, instead return an eigenvector in the subspace for
|
|
1087
|
+
the Hecke operators on the dual space. I.e., this is an eigenvector
|
|
1088
|
+
for the restrictions of Hecke operators to the dual space.
|
|
1089
|
+
|
|
1090
|
+
.. NOTE::
|
|
1091
|
+
|
|
1092
|
+
#. The answer is cached so subsequent calls always return
|
|
1093
|
+
the same vector. However, the algorithm is randomized,
|
|
1094
|
+
so calls during another session may yield a different
|
|
1095
|
+
eigenvector. This function is used mainly for computing
|
|
1096
|
+
systems of Hecke eigenvalues.
|
|
1097
|
+
|
|
1098
|
+
#. One can also view a dual eigenvector as defining (via
|
|
1099
|
+
dot product) a functional phi from the ambient space of
|
|
1100
|
+
modular symbols to a field. This functional phi is an
|
|
1101
|
+
eigenvector for the dual action of Hecke operators on
|
|
1102
|
+
functionals.
|
|
1103
|
+
|
|
1104
|
+
EXAMPLES::
|
|
1105
|
+
|
|
1106
|
+
sage: SF = ModularSymbols(14).cuspidal_subspace().simple_factors()
|
|
1107
|
+
sage: sorted([u.dual_eigenvector() for u in SF])
|
|
1108
|
+
[(0, 1, 0, 0, 0), (1, 0, -3, 2, -1)]
|
|
1109
|
+
"""
|
|
1110
|
+
# TODO -- optimize by computing the answer for i not None in terms
|
|
1111
|
+
# of the answer for a given i if known !!
|
|
1112
|
+
try:
|
|
1113
|
+
w, w_lift = self.__dual_eigenvector[(names, nz)]
|
|
1114
|
+
if lift:
|
|
1115
|
+
return w_lift
|
|
1116
|
+
else:
|
|
1117
|
+
return w
|
|
1118
|
+
except KeyError:
|
|
1119
|
+
pass
|
|
1120
|
+
except AttributeError:
|
|
1121
|
+
self.__dual_eigenvector = {}
|
|
1122
|
+
|
|
1123
|
+
if not self.is_simple():
|
|
1124
|
+
raise ArithmeticError("self must be simple")
|
|
1125
|
+
|
|
1126
|
+
# Find a Hecke operator that acts irreducibly on this space:
|
|
1127
|
+
p = 2
|
|
1128
|
+
t = self.dual_hecke_matrix(p)
|
|
1129
|
+
while True:
|
|
1130
|
+
f = t.charpoly('x')
|
|
1131
|
+
if f.is_irreducible():
|
|
1132
|
+
break
|
|
1133
|
+
p = next_prime(p)
|
|
1134
|
+
t += random.choice([-2, -1, 1, 2]) * self.dual_hecke_matrix(p)
|
|
1135
|
+
|
|
1136
|
+
# Write down the eigenvector.
|
|
1137
|
+
# Write f(x) = (x-alpha)*g(x), where alpha is a root
|
|
1138
|
+
# of f(x).
|
|
1139
|
+
n = f.degree()
|
|
1140
|
+
if n > 1:
|
|
1141
|
+
R = f.parent()
|
|
1142
|
+
K = R.base_ring().extension(f, names=names)
|
|
1143
|
+
alpha = K.gen()
|
|
1144
|
+
beta = ~alpha # multiplicative inverse of alpha
|
|
1145
|
+
c = [-f[0] * beta]
|
|
1146
|
+
for i in range(1, n - 1):
|
|
1147
|
+
c.append((c[i - 1] - f[i]) * beta)
|
|
1148
|
+
c.append(K.one())
|
|
1149
|
+
else:
|
|
1150
|
+
K = self.base_ring()
|
|
1151
|
+
c = [1]
|
|
1152
|
+
|
|
1153
|
+
# The entries of c are the coefficients of g (as stated in
|
|
1154
|
+
# William Stein's Ph.D. thesis, Section 3.5.3). We compute
|
|
1155
|
+
# g(t)v for a some vector v, and get an eigenvector.
|
|
1156
|
+
V = FreeModule(K, n)
|
|
1157
|
+
t = t.change_ring(K) # coerce t to be over K.
|
|
1158
|
+
for j in range(n):
|
|
1159
|
+
v = V.gen(j)
|
|
1160
|
+
I = t.iterates(v, n) # iterates v, v*t, v*t^2, ...
|
|
1161
|
+
w = V(0)
|
|
1162
|
+
for i in range(n):
|
|
1163
|
+
w += c[i] * V(I.row(i).list())
|
|
1164
|
+
if w != 0:
|
|
1165
|
+
break
|
|
1166
|
+
|
|
1167
|
+
# Now w is an eigenvector for the action of the Hecke
|
|
1168
|
+
# operators on the subspace. We need an eigenvector
|
|
1169
|
+
# in the original space, so we take the linear combination
|
|
1170
|
+
# of the basis for the embedded dual vector space given
|
|
1171
|
+
# by the entries of w.
|
|
1172
|
+
Vdual = self.dual_free_module().change_ring(K)
|
|
1173
|
+
w_lift = Vdual.linear_combination_of_basis(w)
|
|
1174
|
+
|
|
1175
|
+
# Finally rescale so the dot product of this vector and
|
|
1176
|
+
# the _eigen_nonzero_element is 1.
|
|
1177
|
+
if nz is not None:
|
|
1178
|
+
x = self.ambient().gen(nz)
|
|
1179
|
+
else:
|
|
1180
|
+
x = self._eigen_nonzero_element()
|
|
1181
|
+
alpha = w_lift.dot_product(x.element())
|
|
1182
|
+
beta = ~alpha
|
|
1183
|
+
w_lift = w_lift * beta
|
|
1184
|
+
w = w * beta
|
|
1185
|
+
|
|
1186
|
+
self.__dual_eigenvector[(names, nz)] = (w, w_lift)
|
|
1187
|
+
if lift:
|
|
1188
|
+
return w_lift
|
|
1189
|
+
else:
|
|
1190
|
+
return w
|
|
1191
|
+
|
|
1192
|
+
def dual_hecke_matrix(self, n):
|
|
1193
|
+
"""
|
|
1194
|
+
Return the matrix of the `n`-th Hecke operator acting on the dual
|
|
1195
|
+
embedded representation of ``self``.
|
|
1196
|
+
|
|
1197
|
+
EXAMPLES::
|
|
1198
|
+
|
|
1199
|
+
sage: CuspForms(1, 24).dual_hecke_matrix(5)
|
|
1200
|
+
[ 44656110 -15040]
|
|
1201
|
+
[-307849789440 28412910]
|
|
1202
|
+
"""
|
|
1203
|
+
n = int(n)
|
|
1204
|
+
try:
|
|
1205
|
+
self._dual_hecke_matrices
|
|
1206
|
+
except AttributeError:
|
|
1207
|
+
self._dual_hecke_matrices = {}
|
|
1208
|
+
if n not in self._dual_hecke_matrices:
|
|
1209
|
+
T = self._compute_dual_hecke_matrix(n)
|
|
1210
|
+
self._dual_hecke_matrices[n] = T
|
|
1211
|
+
return self._dual_hecke_matrices[n]
|
|
1212
|
+
|
|
1213
|
+
def eigenvalue(self, n, name='alpha'):
|
|
1214
|
+
r"""
|
|
1215
|
+
Assuming that ``self`` is a simple space, return the eigenvalue of the
|
|
1216
|
+
`n`-th Hecke operator on ``self``.
|
|
1217
|
+
|
|
1218
|
+
INPUT:
|
|
1219
|
+
|
|
1220
|
+
- ``n`` -- index of Hecke operator
|
|
1221
|
+
|
|
1222
|
+
- ``name`` -- print representation of generator of
|
|
1223
|
+
eigenvalue field
|
|
1224
|
+
|
|
1225
|
+
EXAMPLES::
|
|
1226
|
+
|
|
1227
|
+
sage: A = ModularSymbols(125,sign=1).new_subspace()[0]
|
|
1228
|
+
sage: A.eigenvalue(7)
|
|
1229
|
+
-3
|
|
1230
|
+
sage: A.eigenvalue(3)
|
|
1231
|
+
-alpha - 2
|
|
1232
|
+
sage: A.eigenvalue(3,'w')
|
|
1233
|
+
-w - 2
|
|
1234
|
+
sage: A.eigenvalue(3,'z').charpoly('x')
|
|
1235
|
+
x^2 + 3*x + 1
|
|
1236
|
+
sage: A.hecke_polynomial(3)
|
|
1237
|
+
x^2 + 3*x + 1
|
|
1238
|
+
|
|
1239
|
+
::
|
|
1240
|
+
|
|
1241
|
+
sage: M = ModularSymbols(Gamma1(17)).decomposition()[8].plus_submodule()
|
|
1242
|
+
sage: M.eigenvalue(2,'a')
|
|
1243
|
+
a
|
|
1244
|
+
sage: M.eigenvalue(4,'a')
|
|
1245
|
+
4/3*a^3 + 17/3*a^2 + 28/3*a + 8/3
|
|
1246
|
+
|
|
1247
|
+
.. NOTE::
|
|
1248
|
+
|
|
1249
|
+
#. In fact there are `d` systems of eigenvalues
|
|
1250
|
+
associated to self, where `d` is the rank of
|
|
1251
|
+
``self``. Each of the systems of eigenvalues is conjugate
|
|
1252
|
+
over the base field. This function chooses one of the
|
|
1253
|
+
systems and consistently returns eigenvalues from that
|
|
1254
|
+
system. Thus these are the coefficients `a_n` for
|
|
1255
|
+
`n\geq 1` of a modular eigenform attached to ``self``.
|
|
1256
|
+
|
|
1257
|
+
#. This function works even for Eisenstein subspaces,
|
|
1258
|
+
though it will not give the constant coefficient of one
|
|
1259
|
+
of the corresponding Eisenstein series (i.e., the
|
|
1260
|
+
generalized Bernoulli number).
|
|
1261
|
+
|
|
1262
|
+
TESTS:
|
|
1263
|
+
|
|
1264
|
+
This checks that :issue:`15201` is fixed::
|
|
1265
|
+
|
|
1266
|
+
sage: M = ModularSymbols(5, 6, sign=1)
|
|
1267
|
+
sage: f = M.decomposition()[0]
|
|
1268
|
+
sage: f.eigenvalue(10)
|
|
1269
|
+
50
|
|
1270
|
+
"""
|
|
1271
|
+
if not self.is_simple():
|
|
1272
|
+
raise ArithmeticError("self must be simple")
|
|
1273
|
+
n = int(n)
|
|
1274
|
+
try:
|
|
1275
|
+
return self.__eigenvalues[n][name]
|
|
1276
|
+
except AttributeError:
|
|
1277
|
+
self.__eigenvalues = {}
|
|
1278
|
+
except KeyError:
|
|
1279
|
+
pass
|
|
1280
|
+
if n <= 0:
|
|
1281
|
+
raise IndexError("n must be a positive integer")
|
|
1282
|
+
|
|
1283
|
+
ev = self.__eigenvalues
|
|
1284
|
+
|
|
1285
|
+
if n == 1 or is_prime(n):
|
|
1286
|
+
Tn_e = self._eigen_nonzero_element(n)
|
|
1287
|
+
an = self._element_eigenvalue(Tn_e, name=name)
|
|
1288
|
+
_dict_set(ev, n, name, an)
|
|
1289
|
+
return an
|
|
1290
|
+
|
|
1291
|
+
# Now use the Hecke eigenvalue recurrence, since arithmetic in
|
|
1292
|
+
# a field is faster than computing Heilbronn matrices for
|
|
1293
|
+
# non-prime n and doing some big sum (i.e., computing T_n(e)).
|
|
1294
|
+
# Also by computing using the recurrence on eigenvalues
|
|
1295
|
+
# we use information about divisors.
|
|
1296
|
+
F = factor(n)
|
|
1297
|
+
prod = None
|
|
1298
|
+
for p, r in F:
|
|
1299
|
+
(p, r) = (int(p), int(r))
|
|
1300
|
+
pow = p**r
|
|
1301
|
+
if not (pow in ev and name in ev[pow]):
|
|
1302
|
+
# TODO: Optimization -- do something much more
|
|
1303
|
+
# intelligent in case character is not defined. For
|
|
1304
|
+
# example, compute it using the diamond operators <d>
|
|
1305
|
+
eps = self.character()
|
|
1306
|
+
if eps is None:
|
|
1307
|
+
Tn_e = self._eigen_nonzero_element(pow)
|
|
1308
|
+
_dict_set(ev, pow, name, self._element_eigenvalue(Tn_e, name=name))
|
|
1309
|
+
else:
|
|
1310
|
+
# a_{p^r} := a_p * a_{p^{r-1}} - eps(p)p^{k-1} a_{p^{r-2}}
|
|
1311
|
+
ap = self.eigenvalue(p, name=name)
|
|
1312
|
+
if r == 1:
|
|
1313
|
+
apow = ap
|
|
1314
|
+
else:
|
|
1315
|
+
apr1 = self.eigenvalue(pow // p, name=name)
|
|
1316
|
+
k = self.weight()
|
|
1317
|
+
apr2 = self.eigenvalue(pow // (p * p), name=name)
|
|
1318
|
+
apow = ap * apr1 - eps(p) * (p**(k - 1)) * apr2
|
|
1319
|
+
_dict_set(ev, pow, name, apow)
|
|
1320
|
+
if prod is None:
|
|
1321
|
+
prod = ev[pow][name]
|
|
1322
|
+
else:
|
|
1323
|
+
prod *= ev[pow][name]
|
|
1324
|
+
_dict_set(ev, n, name, prod)
|
|
1325
|
+
return prod
|
|
1326
|
+
|
|
1327
|
+
def factor_number(self):
|
|
1328
|
+
"""
|
|
1329
|
+
If this Hecke module was computed via a decomposition of another
|
|
1330
|
+
Hecke module, this is the corresponding number. Otherwise return
|
|
1331
|
+
-1.
|
|
1332
|
+
|
|
1333
|
+
EXAMPLES::
|
|
1334
|
+
|
|
1335
|
+
sage: ModularSymbols(23)[0].factor_number()
|
|
1336
|
+
0
|
|
1337
|
+
sage: ModularSymbols(23).factor_number()
|
|
1338
|
+
-1
|
|
1339
|
+
"""
|
|
1340
|
+
try:
|
|
1341
|
+
return self.__factor_number
|
|
1342
|
+
except AttributeError:
|
|
1343
|
+
return -1
|
|
1344
|
+
|
|
1345
|
+
def gens(self) -> tuple:
|
|
1346
|
+
"""
|
|
1347
|
+
Return a tuple of basis elements of ``self``.
|
|
1348
|
+
|
|
1349
|
+
EXAMPLES::
|
|
1350
|
+
|
|
1351
|
+
sage: ModularSymbols(23).gens()
|
|
1352
|
+
((1,0), (1,17), (1,19), (1,20), (1,21))
|
|
1353
|
+
"""
|
|
1354
|
+
return tuple(self(x) for x in self.free_module().gens())
|
|
1355
|
+
|
|
1356
|
+
def gen(self, n):
|
|
1357
|
+
r"""
|
|
1358
|
+
Return the `n`-th basis vector of the space.
|
|
1359
|
+
|
|
1360
|
+
EXAMPLES::
|
|
1361
|
+
|
|
1362
|
+
sage: ModularSymbols(23).gen(1)
|
|
1363
|
+
(1,17)
|
|
1364
|
+
"""
|
|
1365
|
+
return self(self.free_module().gen(n))
|
|
1366
|
+
|
|
1367
|
+
def hecke_matrix(self, n):
|
|
1368
|
+
"""
|
|
1369
|
+
Return the matrix of the `n`-th Hecke operator acting on given basis.
|
|
1370
|
+
|
|
1371
|
+
EXAMPLES::
|
|
1372
|
+
|
|
1373
|
+
sage: C = CuspForms(1, 16)
|
|
1374
|
+
sage: C.hecke_matrix(3)
|
|
1375
|
+
[-3348]
|
|
1376
|
+
"""
|
|
1377
|
+
n = int(n)
|
|
1378
|
+
if n <= 0:
|
|
1379
|
+
raise IndexError("n must be positive.")
|
|
1380
|
+
if n not in self._hecke_matrices:
|
|
1381
|
+
T = self._compute_hecke_matrix(n)
|
|
1382
|
+
T.set_immutable()
|
|
1383
|
+
self._hecke_matrices[n] = T
|
|
1384
|
+
return self._hecke_matrices[n]
|
|
1385
|
+
|
|
1386
|
+
def hecke_operator(self, n):
|
|
1387
|
+
"""
|
|
1388
|
+
Return the `n`-th Hecke operator `T_n`.
|
|
1389
|
+
|
|
1390
|
+
INPUT:
|
|
1391
|
+
|
|
1392
|
+
- ``n`` -- integer at least 1
|
|
1393
|
+
|
|
1394
|
+
EXAMPLES::
|
|
1395
|
+
|
|
1396
|
+
sage: M = ModularSymbols(11,2)
|
|
1397
|
+
sage: T = M.hecke_operator(3) ; T
|
|
1398
|
+
Hecke operator T_3 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
|
|
1399
|
+
sage: T.matrix()
|
|
1400
|
+
[ 4 0 -1]
|
|
1401
|
+
[ 0 -1 0]
|
|
1402
|
+
[ 0 0 -1]
|
|
1403
|
+
sage: T(M.0)
|
|
1404
|
+
4*(1,0) - (1,9)
|
|
1405
|
+
sage: S = M.cuspidal_submodule()
|
|
1406
|
+
sage: T = S.hecke_operator(3) ; T
|
|
1407
|
+
Hecke operator T_3 on Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
|
|
1408
|
+
sage: T.matrix()
|
|
1409
|
+
[-1 0]
|
|
1410
|
+
[ 0 -1]
|
|
1411
|
+
sage: T(S.0)
|
|
1412
|
+
-(1,8)
|
|
1413
|
+
"""
|
|
1414
|
+
return self.hecke_algebra().hecke_operator(n)
|
|
1415
|
+
|
|
1416
|
+
def diamond_bracket_matrix(self, d):
|
|
1417
|
+
r"""
|
|
1418
|
+
Return the matrix of the diamond bracket operator `\langle d \rangle` on ``self``.
|
|
1419
|
+
|
|
1420
|
+
EXAMPLES::
|
|
1421
|
+
|
|
1422
|
+
sage: M = ModularSymbols(DirichletGroup(5).0, 3)
|
|
1423
|
+
sage: M.diamond_bracket_matrix(3)
|
|
1424
|
+
[-zeta4 0]
|
|
1425
|
+
[ 0 -zeta4]
|
|
1426
|
+
sage: ModularSymbols(Gamma1(5), 3).diamond_bracket_matrix(3)
|
|
1427
|
+
[ 0 1 0 0]
|
|
1428
|
+
[-1 0 0 0]
|
|
1429
|
+
[ 0 0 0 1]
|
|
1430
|
+
[ 0 0 -1 0]
|
|
1431
|
+
"""
|
|
1432
|
+
d = int(d) % self.level()
|
|
1433
|
+
if d not in self._diamond_matrices:
|
|
1434
|
+
if self.character() is not None:
|
|
1435
|
+
D = MatrixSpace(self.base_ring(), self.rank())(self.character()(d))
|
|
1436
|
+
else:
|
|
1437
|
+
D = self._compute_diamond_matrix(d)
|
|
1438
|
+
D.set_immutable()
|
|
1439
|
+
self._diamond_matrices[d] = D
|
|
1440
|
+
return self._diamond_matrices[d]
|
|
1441
|
+
|
|
1442
|
+
def diamond_bracket_operator(self, d):
|
|
1443
|
+
r"""
|
|
1444
|
+
Return the diamond bracket operator `\langle d \rangle` on ``self``.
|
|
1445
|
+
|
|
1446
|
+
EXAMPLES::
|
|
1447
|
+
|
|
1448
|
+
sage: M = ModularSymbols(DirichletGroup(5).0, 3)
|
|
1449
|
+
sage: M.diamond_bracket_operator(3)
|
|
1450
|
+
Diamond bracket operator <3> on Modular Symbols space of dimension 2 and level 5, weight 3, character [zeta4], sign 0, over Cyclotomic Field of order 4 and degree 2
|
|
1451
|
+
"""
|
|
1452
|
+
return self.hecke_algebra().diamond_bracket_operator(d)
|
|
1453
|
+
|
|
1454
|
+
def T(self, n):
|
|
1455
|
+
r"""
|
|
1456
|
+
Return the `n`-th Hecke operator `T_n`.
|
|
1457
|
+
|
|
1458
|
+
This function is a synonym for :meth:`hecke_operator`.
|
|
1459
|
+
|
|
1460
|
+
EXAMPLES::
|
|
1461
|
+
|
|
1462
|
+
sage: M = ModularSymbols(11,2)
|
|
1463
|
+
sage: M.T(3)
|
|
1464
|
+
Hecke operator T_3 on Modular Symbols ...
|
|
1465
|
+
"""
|
|
1466
|
+
return self.hecke_operator(n)
|
|
1467
|
+
|
|
1468
|
+
def hecke_polynomial(self, n, var='x'):
|
|
1469
|
+
"""
|
|
1470
|
+
Return the characteristic polynomial of the `n`-th Hecke operator
|
|
1471
|
+
acting on this space.
|
|
1472
|
+
|
|
1473
|
+
INPUT:
|
|
1474
|
+
|
|
1475
|
+
- ``n`` -- integer
|
|
1476
|
+
|
|
1477
|
+
OUTPUT: a polynomial
|
|
1478
|
+
|
|
1479
|
+
EXAMPLES::
|
|
1480
|
+
|
|
1481
|
+
sage: ModularSymbols(11,2).hecke_polynomial(3)
|
|
1482
|
+
x^3 - 2*x^2 - 7*x - 4
|
|
1483
|
+
"""
|
|
1484
|
+
return self.hecke_operator(n).charpoly(var)
|
|
1485
|
+
|
|
1486
|
+
def is_simple(self) -> bool:
|
|
1487
|
+
r"""
|
|
1488
|
+
Return ``True`` if this space is simple as a module for the
|
|
1489
|
+
corresponding Hecke algebra.
|
|
1490
|
+
|
|
1491
|
+
This raises :exc:`NotImplementedError`, as this is an abstract base
|
|
1492
|
+
class.
|
|
1493
|
+
|
|
1494
|
+
EXAMPLES::
|
|
1495
|
+
|
|
1496
|
+
sage: sage.modular.hecke.module.HeckeModule_free_module(QQ, 10, 3).is_simple()
|
|
1497
|
+
Traceback (most recent call last):
|
|
1498
|
+
...
|
|
1499
|
+
NotImplementedError
|
|
1500
|
+
"""
|
|
1501
|
+
raise NotImplementedError
|
|
1502
|
+
|
|
1503
|
+
def is_splittable(self) -> bool:
|
|
1504
|
+
"""
|
|
1505
|
+
Return ``True`` if and only if only it is possible to split
|
|
1506
|
+
off a nontrivial generalized eigenspace of ``self`` as the
|
|
1507
|
+
kernel of some Hecke operator (not necessarily prime to the level).
|
|
1508
|
+
|
|
1509
|
+
Note that the direct sum of several copies of the same simple
|
|
1510
|
+
module is not splittable in this sense.
|
|
1511
|
+
|
|
1512
|
+
EXAMPLES::
|
|
1513
|
+
|
|
1514
|
+
sage: M = ModularSymbols(Gamma0(64)).cuspidal_subspace()
|
|
1515
|
+
sage: M.is_splittable()
|
|
1516
|
+
True
|
|
1517
|
+
sage: M.simple_factors()[0].is_splittable()
|
|
1518
|
+
False
|
|
1519
|
+
"""
|
|
1520
|
+
if not hasattr(self, "__is_splittable"):
|
|
1521
|
+
self.decomposition(anemic=False)
|
|
1522
|
+
return self.__is_splittable
|
|
1523
|
+
|
|
1524
|
+
def is_submodule(self, other) -> bool:
|
|
1525
|
+
r"""
|
|
1526
|
+
Return ``True`` if ``self`` is a submodule of ``other``.
|
|
1527
|
+
|
|
1528
|
+
EXAMPLES::
|
|
1529
|
+
|
|
1530
|
+
sage: M = ModularSymbols(Gamma0(64))
|
|
1531
|
+
sage: M[0].is_submodule(M)
|
|
1532
|
+
True
|
|
1533
|
+
sage: CuspForms(1, 24).is_submodule(ModularForms(1, 24))
|
|
1534
|
+
True
|
|
1535
|
+
sage: CuspForms(1, 12).is_submodule(CuspForms(3, 12))
|
|
1536
|
+
False
|
|
1537
|
+
"""
|
|
1538
|
+
if not isinstance(other, HeckeModule_free_module):
|
|
1539
|
+
return False
|
|
1540
|
+
return (self.ambient_free_module() == other.ambient_free_module() and
|
|
1541
|
+
self.free_module().is_submodule(other.free_module()))
|
|
1542
|
+
|
|
1543
|
+
def is_splittable_anemic(self) -> bool:
|
|
1544
|
+
"""
|
|
1545
|
+
Return ``True`` if and only if only it is possible to split off a
|
|
1546
|
+
nontrivial generalized eigenspace of ``self`` as the kernel of some
|
|
1547
|
+
Hecke operator of index coprime to the level.
|
|
1548
|
+
|
|
1549
|
+
Note that the direct sum of several copies of the same simple
|
|
1550
|
+
module is not splittable in this sense.
|
|
1551
|
+
|
|
1552
|
+
EXAMPLES::
|
|
1553
|
+
|
|
1554
|
+
sage: M = ModularSymbols(Gamma0(64)).cuspidal_subspace()
|
|
1555
|
+
sage: M.is_splittable_anemic()
|
|
1556
|
+
True
|
|
1557
|
+
sage: M.simple_factors()[0].is_splittable_anemic()
|
|
1558
|
+
False
|
|
1559
|
+
"""
|
|
1560
|
+
if not hasattr(self, "__is_splittable_anemic"):
|
|
1561
|
+
self.decomposition(anemic=True)
|
|
1562
|
+
return self.__is_splittable_anemic
|
|
1563
|
+
|
|
1564
|
+
def ngens(self):
|
|
1565
|
+
r"""
|
|
1566
|
+
Return the number of generators of ``self``.
|
|
1567
|
+
|
|
1568
|
+
This is equal to the rank.
|
|
1569
|
+
|
|
1570
|
+
EXAMPLES::
|
|
1571
|
+
|
|
1572
|
+
sage: ModularForms(1, 12).ngens()
|
|
1573
|
+
2
|
|
1574
|
+
"""
|
|
1575
|
+
return self.rank()
|
|
1576
|
+
|
|
1577
|
+
def projection(self):
|
|
1578
|
+
r"""
|
|
1579
|
+
Return the projection map from the ambient space to ``self``.
|
|
1580
|
+
|
|
1581
|
+
ALGORITHM: Let `B` be the matrix whose columns are obtained
|
|
1582
|
+
by concatenating together a basis for the factors of the ambient
|
|
1583
|
+
space. Then the projection matrix onto ``self`` is the submatrix of
|
|
1584
|
+
`B^{-1}` obtained from the rows corresponding to self,
|
|
1585
|
+
i.e., if the basis vectors for ``self`` appear as columns `n`
|
|
1586
|
+
through `m` of `B`, then the projection matrix is
|
|
1587
|
+
got from rows `n` through `m` of `B^{-1}`.
|
|
1588
|
+
This is because projection with respect to the B basis is just
|
|
1589
|
+
given by an `m-n+1` row slice `P` of a diagonal
|
|
1590
|
+
matrix D with 1s in the `n` through `m` positions,
|
|
1591
|
+
so projection with respect to the standard basis is given by
|
|
1592
|
+
`P\cdot B^{-1}`, which is just rows `n`
|
|
1593
|
+
through `m` of `B^{-1}`.
|
|
1594
|
+
|
|
1595
|
+
EXAMPLES::
|
|
1596
|
+
|
|
1597
|
+
sage: # needs database_cremona_mini_ellcurve
|
|
1598
|
+
sage: e = EllipticCurve('34a')
|
|
1599
|
+
sage: m = ModularSymbols(34); s = m.cuspidal_submodule()
|
|
1600
|
+
sage: d = s.decomposition(7)
|
|
1601
|
+
sage: d
|
|
1602
|
+
[Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field,
|
|
1603
|
+
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field]
|
|
1604
|
+
sage: a = d[0]; a
|
|
1605
|
+
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field
|
|
1606
|
+
sage: pi = a.projection()
|
|
1607
|
+
sage: pi(m([0,oo]))
|
|
1608
|
+
-1/6*(2,7) + 1/6*(2,13) - 1/6*(2,31) + 1/6*(2,33)
|
|
1609
|
+
sage: M = ModularSymbols(53,sign=1)
|
|
1610
|
+
sage: S = M.cuspidal_subspace()[1] ; S
|
|
1611
|
+
Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 5 for Gamma_0(53) of weight 2 with sign 1 over Rational Field
|
|
1612
|
+
sage: p = S.projection()
|
|
1613
|
+
sage: S.basis()
|
|
1614
|
+
((1,43) - (1,45), (1,47), (1,50))
|
|
1615
|
+
sage: [ p(x) for x in S.basis() ]
|
|
1616
|
+
[(1,43) - (1,45), (1,47), (1,50)]
|
|
1617
|
+
sage: all(p(x)==x for x in S.basis())
|
|
1618
|
+
True
|
|
1619
|
+
"""
|
|
1620
|
+
|
|
1621
|
+
# Compute the Hecke-stable projection map pi from the ambient
|
|
1622
|
+
# space of M to M. Computing the projection map is the same
|
|
1623
|
+
# as writing the ambient space as a direct sum of M and its
|
|
1624
|
+
# Hecke-stable complement, which is the old subspace plus the
|
|
1625
|
+
# other new factors, then *inverting*. With the projection
|
|
1626
|
+
# map in hand, we can compute Hecke operators directly on M
|
|
1627
|
+
# fairly quickly without having to compute them on the whole
|
|
1628
|
+
# ambient space. Of course, computing this inverse is way too
|
|
1629
|
+
# much work to be useful in general (!). (I sort of learned
|
|
1630
|
+
# this trick from Joe Wetherell, or at least he was aware of
|
|
1631
|
+
# it when I mentioned it to him in an airport once. It's also
|
|
1632
|
+
# sort of like a trick Cremona uses in his book for elliptic
|
|
1633
|
+
# curves.) It's not a very good trick though.
|
|
1634
|
+
|
|
1635
|
+
try:
|
|
1636
|
+
return self.__projection
|
|
1637
|
+
except AttributeError:
|
|
1638
|
+
i = self.factor_number()
|
|
1639
|
+
if i == -1:
|
|
1640
|
+
raise NotImplementedError("Computation of projection only implemented "
|
|
1641
|
+
"for decomposition factors.")
|
|
1642
|
+
A = self.ambient_hecke_module()
|
|
1643
|
+
B = A.decomposition_matrix_inverse()
|
|
1644
|
+
i = A.decomposition().index(self)
|
|
1645
|
+
n = sum([A[j].rank() for j in range(i)])
|
|
1646
|
+
C = B.matrix_from_columns(range(n, n + self.rank()))
|
|
1647
|
+
H = A.Hom(self)
|
|
1648
|
+
pi = H(C, "Projection" % self)
|
|
1649
|
+
self.__projection = pi
|
|
1650
|
+
return self.__projection
|
|
1651
|
+
|
|
1652
|
+
def system_of_eigenvalues(self, n, name='alpha'):
|
|
1653
|
+
r"""
|
|
1654
|
+
Assuming that ``self`` is a simple space of modular symbols, return the
|
|
1655
|
+
eigenvalues `[a_1, \ldots, a_nmax]` of the Hecke
|
|
1656
|
+
operators on ``self``. See ``self.eigenvalue(n)`` for more
|
|
1657
|
+
details.
|
|
1658
|
+
|
|
1659
|
+
INPUT:
|
|
1660
|
+
|
|
1661
|
+
- ``n`` -- number of eigenvalues
|
|
1662
|
+
|
|
1663
|
+
- ``alpha`` -- name of generate for eigenvalue field
|
|
1664
|
+
|
|
1665
|
+
EXAMPLES:
|
|
1666
|
+
|
|
1667
|
+
The outputs of the following tests are very unstable. The algorithms
|
|
1668
|
+
are randomized and depend on cached results. A slight change in the
|
|
1669
|
+
sequence of pseudo-random numbers or a modification in caching is
|
|
1670
|
+
likely to modify the results. We reset the random number generator and
|
|
1671
|
+
clear some caches for reproducibility::
|
|
1672
|
+
|
|
1673
|
+
sage: set_random_seed(0)
|
|
1674
|
+
sage: ModularSymbols_clear_cache()
|
|
1675
|
+
|
|
1676
|
+
We compute eigenvalues for newforms of level 62::
|
|
1677
|
+
|
|
1678
|
+
sage: M = ModularSymbols(62,2,sign=-1)
|
|
1679
|
+
sage: S = M.cuspidal_submodule().new_submodule()
|
|
1680
|
+
sage: [[o.minpoly() for o in A.system_of_eigenvalues(3)] for A in S.decomposition()]
|
|
1681
|
+
[[x - 1, x - 1, x], [x - 1, x + 1, x^2 - 2*x - 2]]
|
|
1682
|
+
|
|
1683
|
+
Next we define a function that does the above::
|
|
1684
|
+
|
|
1685
|
+
sage: def b(N, k=2):
|
|
1686
|
+
....: S = ModularSymbols(N,k,sign=-1).cuspidal_submodule().new_submodule()
|
|
1687
|
+
....: for A in S.decomposition():
|
|
1688
|
+
....: print("{} {}".format(N, A.system_of_eigenvalues(5)))
|
|
1689
|
+
|
|
1690
|
+
::
|
|
1691
|
+
|
|
1692
|
+
sage: b(63)
|
|
1693
|
+
63 [1, 1, 0, -1, 2]
|
|
1694
|
+
63 [1, alpha, 0, 1, -2*alpha]
|
|
1695
|
+
|
|
1696
|
+
This example illustrates finding field over which the eigenvalues
|
|
1697
|
+
are defined::
|
|
1698
|
+
|
|
1699
|
+
sage: M = ModularSymbols(23,2,sign=1).cuspidal_submodule().new_submodule()
|
|
1700
|
+
sage: v = M.system_of_eigenvalues(10); v
|
|
1701
|
+
[1, alpha, -2*alpha - 1, -alpha - 1, 2*alpha, alpha - 2, 2*alpha + 2, -2*alpha - 1, 2, -2*alpha + 2]
|
|
1702
|
+
sage: v[0].parent()
|
|
1703
|
+
Number Field in alpha with defining polynomial x^2 + x - 1
|
|
1704
|
+
|
|
1705
|
+
This example illustrates setting the print name of the eigenvalue
|
|
1706
|
+
field.
|
|
1707
|
+
|
|
1708
|
+
::
|
|
1709
|
+
|
|
1710
|
+
sage: A = ModularSymbols(125,sign=1).new_subspace()[0]
|
|
1711
|
+
sage: A.system_of_eigenvalues(10)
|
|
1712
|
+
[1, alpha, -alpha - 2, -alpha - 1, 0, -alpha - 1, -3, -2*alpha - 1, 3*alpha + 2, 0]
|
|
1713
|
+
sage: A.system_of_eigenvalues(10,'x')
|
|
1714
|
+
[1, x, -x - 2, -x - 1, 0, -x - 1, -3, -2*x - 1, 3*x + 2, 0]
|
|
1715
|
+
"""
|
|
1716
|
+
return [self.eigenvalue(m, name=name) for m in range(1, n + 1)]
|
|
1717
|
+
|
|
1718
|
+
def weight(self):
|
|
1719
|
+
"""
|
|
1720
|
+
Return the weight of this Hecke module.
|
|
1721
|
+
|
|
1722
|
+
INPUT:
|
|
1723
|
+
|
|
1724
|
+
- ``self`` -- an arbitrary Hecke module
|
|
1725
|
+
|
|
1726
|
+
OUTPUT: integer; the weight
|
|
1727
|
+
|
|
1728
|
+
EXAMPLES::
|
|
1729
|
+
|
|
1730
|
+
sage: m = ModularSymbols(20, weight=2)
|
|
1731
|
+
sage: m.weight()
|
|
1732
|
+
2
|
|
1733
|
+
"""
|
|
1734
|
+
return self.__weight
|
|
1735
|
+
|
|
1736
|
+
def zero_submodule(self):
|
|
1737
|
+
"""
|
|
1738
|
+
Return the zero submodule of ``self``.
|
|
1739
|
+
|
|
1740
|
+
EXAMPLES::
|
|
1741
|
+
|
|
1742
|
+
sage: ModularSymbols(11,4).zero_submodule()
|
|
1743
|
+
Modular Symbols subspace of dimension 0 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field
|
|
1744
|
+
sage: CuspForms(11,4).zero_submodule()
|
|
1745
|
+
Modular Forms subspace of dimension 0 of Modular Forms space of dimension 4 for Congruence Subgroup Gamma0(11) of weight 4 over Rational Field
|
|
1746
|
+
"""
|
|
1747
|
+
return self.submodule(self.free_module().zero_submodule(), check=False)
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
def _dict_set(v, n, key, val):
|
|
1751
|
+
r"""
|
|
1752
|
+
Rough-and-ready implementation of a two-layer-deep dictionary.
|
|
1753
|
+
|
|
1754
|
+
EXAMPLES::
|
|
1755
|
+
|
|
1756
|
+
sage: from sage.modular.hecke.module import _dict_set
|
|
1757
|
+
sage: v = {}
|
|
1758
|
+
sage: _dict_set(v, 1, 2, 3)
|
|
1759
|
+
sage: v
|
|
1760
|
+
{1: {2: 3}}
|
|
1761
|
+
sage: _dict_set(v, 1, 3, 4); v
|
|
1762
|
+
{1: {2: 3, 3: 4}}
|
|
1763
|
+
"""
|
|
1764
|
+
if n in v:
|
|
1765
|
+
v[n][key] = val
|
|
1766
|
+
else:
|
|
1767
|
+
v[n] = {key: val}
|