passagemath-schemes 10.6.38__cp314-cp314t-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-schemes might be problematic. Click here for more details.
- passagemath_schemes/.dylibs/libflint.21.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.38.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.38.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314t-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-314t-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314t-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,1860 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.libs.pari
|
|
3
|
+
r"""
|
|
4
|
+
Generic spaces of modular forms
|
|
5
|
+
|
|
6
|
+
EXAMPLES (computation of base ring): Return the base ring of this
|
|
7
|
+
space of modular forms.
|
|
8
|
+
|
|
9
|
+
EXAMPLES: For spaces of modular forms for `\Gamma_0(N)` or
|
|
10
|
+
`\Gamma_1(N)`, the default base ring is
|
|
11
|
+
`\QQ`::
|
|
12
|
+
|
|
13
|
+
sage: ModularForms(11,2).base_ring()
|
|
14
|
+
Rational Field
|
|
15
|
+
sage: ModularForms(1,12).base_ring()
|
|
16
|
+
Rational Field
|
|
17
|
+
sage: CuspForms(Gamma1(13),3).base_ring()
|
|
18
|
+
Rational Field
|
|
19
|
+
|
|
20
|
+
The base ring can be explicitly specified in the constructor
|
|
21
|
+
function.
|
|
22
|
+
|
|
23
|
+
::
|
|
24
|
+
|
|
25
|
+
sage: ModularForms(11,2,base_ring=GF(13)).base_ring()
|
|
26
|
+
Finite Field of size 13
|
|
27
|
+
|
|
28
|
+
For modular forms with character the default base ring is the field
|
|
29
|
+
generated by the image of the character.
|
|
30
|
+
|
|
31
|
+
::
|
|
32
|
+
|
|
33
|
+
sage: ModularForms(DirichletGroup(13).0,3).base_ring()
|
|
34
|
+
Cyclotomic Field of order 12 and degree 4
|
|
35
|
+
|
|
36
|
+
For example, if the character is quadratic then the field is
|
|
37
|
+
`\QQ` (if the characteristic is `0`).
|
|
38
|
+
|
|
39
|
+
::
|
|
40
|
+
|
|
41
|
+
sage: ModularForms(DirichletGroup(13).0^6,3).base_ring()
|
|
42
|
+
Rational Field
|
|
43
|
+
|
|
44
|
+
An example in characteristic `7`::
|
|
45
|
+
|
|
46
|
+
sage: ModularForms(13,3,base_ring=GF(7)).base_ring()
|
|
47
|
+
Finite Field of size 7
|
|
48
|
+
|
|
49
|
+
AUTHORS:
|
|
50
|
+
|
|
51
|
+
- William Stein (2007): first version
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
#########################################################################
|
|
55
|
+
# Copyright (C) 2004--2006 William Stein <wstein@gmail.com>
|
|
56
|
+
#
|
|
57
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
58
|
+
#
|
|
59
|
+
# https://www.gnu.org/licenses/
|
|
60
|
+
#########################################################################
|
|
61
|
+
|
|
62
|
+
from sage.arith.misc import gcd
|
|
63
|
+
from sage.matrix.constructor import zero_matrix
|
|
64
|
+
from sage.misc.cachefunc import cached_method
|
|
65
|
+
|
|
66
|
+
import sage.modular.hecke.all as hecke
|
|
67
|
+
import sage.modular.arithgroup.all as arithgroup
|
|
68
|
+
import sage.modular.dirichlet as dirichlet
|
|
69
|
+
|
|
70
|
+
from sage.rings.infinity import PlusInfinity
|
|
71
|
+
from sage.rings.integer import Integer
|
|
72
|
+
from sage.rings.integer_ring import ZZ
|
|
73
|
+
from sage.rings.power_series_ring import PowerSeriesRing
|
|
74
|
+
from sage.rings.power_series_ring_element import PowerSeries
|
|
75
|
+
from sage.rings.rational_field import QQ
|
|
76
|
+
from sage.categories.rings import Rings
|
|
77
|
+
|
|
78
|
+
from sage.structure.all import Sequence
|
|
79
|
+
from sage.structure.richcmp import (richcmp_method, richcmp, rich_to_bool,
|
|
80
|
+
richcmp_not_equal)
|
|
81
|
+
|
|
82
|
+
from .element import ModularFormElement, Newform
|
|
83
|
+
from . import defaults
|
|
84
|
+
from . import hecke_operator_on_qexp
|
|
85
|
+
|
|
86
|
+
WARN = False
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def is_ModularFormsSpace(x):
|
|
90
|
+
r"""
|
|
91
|
+
Return ``True`` if x is a ``ModularFormsSpace``.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: from sage.modular.modform.space import is_ModularFormsSpace
|
|
96
|
+
sage: is_ModularFormsSpace(ModularForms(11,2))
|
|
97
|
+
doctest:warning...
|
|
98
|
+
DeprecationWarning: The function is_ModularFormsSpace is deprecated; use 'isinstance(..., ModularFormsSpace)' instead.
|
|
99
|
+
See https://github.com/sagemath/sage/issues/38035 for details.
|
|
100
|
+
True
|
|
101
|
+
sage: is_ModularFormsSpace(CuspForms(11,2))
|
|
102
|
+
True
|
|
103
|
+
sage: is_ModularFormsSpace(3)
|
|
104
|
+
False
|
|
105
|
+
"""
|
|
106
|
+
from sage.misc.superseded import deprecation
|
|
107
|
+
deprecation(38035, "The function is_ModularFormsSpace is deprecated; use 'isinstance(..., ModularFormsSpace)' instead.")
|
|
108
|
+
return isinstance(x, ModularFormsSpace)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@richcmp_method
|
|
112
|
+
class ModularFormsSpace(hecke.HeckeModule_generic):
|
|
113
|
+
"""
|
|
114
|
+
A generic space of modular forms.
|
|
115
|
+
"""
|
|
116
|
+
Element = ModularFormElement
|
|
117
|
+
|
|
118
|
+
def __init__(self, group, weight, character, base_ring, category=None):
|
|
119
|
+
r"""
|
|
120
|
+
Generic spaces of modular forms. For spaces of modular forms for
|
|
121
|
+
`\Gamma_0(N)` or `\Gamma_1(N)`, the default base
|
|
122
|
+
ring is `\QQ`.
|
|
123
|
+
|
|
124
|
+
EXAMPLES::
|
|
125
|
+
|
|
126
|
+
sage: ModularForms(11,2)
|
|
127
|
+
Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
|
|
128
|
+
|
|
129
|
+
::
|
|
130
|
+
|
|
131
|
+
sage: ModularForms(11,2,base_ring=GF(13))
|
|
132
|
+
Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Finite Field of size 13
|
|
133
|
+
|
|
134
|
+
::
|
|
135
|
+
|
|
136
|
+
sage: ModularForms(DirichletGroup(13).0,3)
|
|
137
|
+
Modular Forms space of dimension 3, character [zeta12] and weight 3 over Cyclotomic Field of order 12 and degree 4
|
|
138
|
+
|
|
139
|
+
::
|
|
140
|
+
|
|
141
|
+
sage: M = ModularForms(11,2)
|
|
142
|
+
sage: M == loads(dumps(M))
|
|
143
|
+
True
|
|
144
|
+
"""
|
|
145
|
+
global WARN
|
|
146
|
+
if WARN:
|
|
147
|
+
print("Modular forms -- under development -- do not trust yet.")
|
|
148
|
+
WARN = False
|
|
149
|
+
if not isinstance(group, arithgroup.CongruenceSubgroupBase):
|
|
150
|
+
raise TypeError("group (=%s) must be a congruence subgroup" % group)
|
|
151
|
+
weight = Integer(weight)
|
|
152
|
+
if not ((character is None) or isinstance(character, dirichlet.DirichletCharacter)):
|
|
153
|
+
raise TypeError("character must be a Dirichlet character")
|
|
154
|
+
if base_ring not in Rings():
|
|
155
|
+
raise TypeError("base_ring must be a ring")
|
|
156
|
+
self.__sturm_bound = None
|
|
157
|
+
self.__weight, self.__group, self.__character = weight, group, character
|
|
158
|
+
hecke.HeckeModule_generic.__init__(self, base_ring, group.level(), category=category)
|
|
159
|
+
|
|
160
|
+
def prec(self, new_prec=None):
|
|
161
|
+
"""
|
|
162
|
+
Return or set the default precision used for displaying
|
|
163
|
+
`q`-expansions of elements of this space.
|
|
164
|
+
|
|
165
|
+
INPUT:
|
|
166
|
+
|
|
167
|
+
- ``new_prec`` -- positive integer (default: ``None``)
|
|
168
|
+
|
|
169
|
+
OUTPUT: if new_prec is None, returns the current precision
|
|
170
|
+
|
|
171
|
+
EXAMPLES::
|
|
172
|
+
|
|
173
|
+
sage: M = ModularForms(1,12)
|
|
174
|
+
sage: S = M.cuspidal_subspace()
|
|
175
|
+
sage: S.prec()
|
|
176
|
+
6
|
|
177
|
+
sage: S.basis()
|
|
178
|
+
[q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)]
|
|
179
|
+
sage: S.prec(8)
|
|
180
|
+
8
|
|
181
|
+
sage: S.basis()
|
|
182
|
+
[q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8)]
|
|
183
|
+
"""
|
|
184
|
+
return self.ambient().prec(new_prec)
|
|
185
|
+
|
|
186
|
+
def set_precision(self, new_prec):
|
|
187
|
+
"""
|
|
188
|
+
Set the default precision used for displaying
|
|
189
|
+
`q`-expansions.
|
|
190
|
+
|
|
191
|
+
INPUT:
|
|
192
|
+
|
|
193
|
+
- ``new_prec`` -- positive integer
|
|
194
|
+
|
|
195
|
+
EXAMPLES::
|
|
196
|
+
|
|
197
|
+
sage: M = ModularForms(Gamma0(37),2)
|
|
198
|
+
sage: M.set_precision(10)
|
|
199
|
+
sage: S = M.cuspidal_subspace()
|
|
200
|
+
sage: S.basis()
|
|
201
|
+
[q + q^3 - 2*q^4 - q^7 - 2*q^9 + O(q^10),
|
|
202
|
+
q^2 + 2*q^3 - 2*q^4 + q^5 - 3*q^6 - 4*q^9 + O(q^10)]
|
|
203
|
+
|
|
204
|
+
::
|
|
205
|
+
|
|
206
|
+
sage: S.set_precision(0)
|
|
207
|
+
sage: S.basis()
|
|
208
|
+
[O(q^0), O(q^0)]
|
|
209
|
+
|
|
210
|
+
The precision of subspaces is the same as the precision of the
|
|
211
|
+
ambient space.
|
|
212
|
+
|
|
213
|
+
::
|
|
214
|
+
|
|
215
|
+
sage: S.set_precision(2)
|
|
216
|
+
sage: M.basis()
|
|
217
|
+
[q + O(q^2), O(q^2), 1 + 2/3*q + O(q^2)]
|
|
218
|
+
|
|
219
|
+
The precision must be nonnegative::
|
|
220
|
+
|
|
221
|
+
sage: S.set_precision(-1)
|
|
222
|
+
Traceback (most recent call last):
|
|
223
|
+
...
|
|
224
|
+
ValueError: n (=-1) must be >= 0
|
|
225
|
+
|
|
226
|
+
We do another example with nontrivial character.
|
|
227
|
+
|
|
228
|
+
::
|
|
229
|
+
|
|
230
|
+
sage: M = ModularForms(DirichletGroup(13).0^2)
|
|
231
|
+
sage: M.set_precision(10)
|
|
232
|
+
sage: M.cuspidal_subspace().0
|
|
233
|
+
q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)
|
|
234
|
+
"""
|
|
235
|
+
self.ambient().set_precision(new_prec)
|
|
236
|
+
|
|
237
|
+
def weight(self):
|
|
238
|
+
"""
|
|
239
|
+
Return the weight of this space of modular forms.
|
|
240
|
+
|
|
241
|
+
EXAMPLES::
|
|
242
|
+
|
|
243
|
+
sage: M = ModularForms(Gamma1(13),11)
|
|
244
|
+
sage: M.weight()
|
|
245
|
+
11
|
|
246
|
+
|
|
247
|
+
::
|
|
248
|
+
|
|
249
|
+
sage: M = ModularForms(Gamma0(997),100)
|
|
250
|
+
sage: M.weight()
|
|
251
|
+
100
|
|
252
|
+
|
|
253
|
+
::
|
|
254
|
+
|
|
255
|
+
sage: M = ModularForms(Gamma0(97),4)
|
|
256
|
+
sage: M.weight()
|
|
257
|
+
4
|
|
258
|
+
sage: M.eisenstein_submodule().weight()
|
|
259
|
+
4
|
|
260
|
+
"""
|
|
261
|
+
return self.__weight
|
|
262
|
+
|
|
263
|
+
def group(self):
|
|
264
|
+
r"""
|
|
265
|
+
Return the congruence subgroup associated to this space of modular
|
|
266
|
+
forms.
|
|
267
|
+
|
|
268
|
+
EXAMPLES::
|
|
269
|
+
|
|
270
|
+
sage: ModularForms(Gamma0(12),4).group()
|
|
271
|
+
Congruence Subgroup Gamma0(12)
|
|
272
|
+
|
|
273
|
+
::
|
|
274
|
+
|
|
275
|
+
sage: CuspForms(Gamma1(113),2).group()
|
|
276
|
+
Congruence Subgroup Gamma1(113)
|
|
277
|
+
|
|
278
|
+
Note that `\Gamma_1(1)` and `\Gamma_0(1)` are replaced by
|
|
279
|
+
`\SL_2(\ZZ)`.
|
|
280
|
+
|
|
281
|
+
::
|
|
282
|
+
|
|
283
|
+
sage: CuspForms(Gamma1(1),12).group()
|
|
284
|
+
Modular Group SL(2,Z)
|
|
285
|
+
sage: CuspForms(SL2Z,12).group()
|
|
286
|
+
Modular Group SL(2,Z)
|
|
287
|
+
"""
|
|
288
|
+
return self.__group
|
|
289
|
+
|
|
290
|
+
def character(self):
|
|
291
|
+
r"""
|
|
292
|
+
Return the Dirichlet character corresponding to this space of
|
|
293
|
+
modular forms. Returns None if there is no specific character
|
|
294
|
+
corresponding to this space, e.g., if this is a space of modular
|
|
295
|
+
forms on `\Gamma_1(N)` with `N>1`.
|
|
296
|
+
|
|
297
|
+
EXAMPLES: The trivial character::
|
|
298
|
+
|
|
299
|
+
sage: ModularForms(Gamma0(11),2).character()
|
|
300
|
+
Dirichlet character modulo 11 of conductor 1 mapping 2 |--> 1
|
|
301
|
+
|
|
302
|
+
Spaces of forms with nontrivial character::
|
|
303
|
+
|
|
304
|
+
sage: ModularForms(DirichletGroup(20).0,3).character()
|
|
305
|
+
Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1
|
|
306
|
+
|
|
307
|
+
sage: M = ModularForms(DirichletGroup(11).0, 3)
|
|
308
|
+
sage: M.character()
|
|
309
|
+
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta10
|
|
310
|
+
sage: s = M.cuspidal_submodule()
|
|
311
|
+
sage: s.character()
|
|
312
|
+
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta10
|
|
313
|
+
sage: CuspForms(DirichletGroup(11).0,3).character()
|
|
314
|
+
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta10
|
|
315
|
+
|
|
316
|
+
A space of forms with no particular character (hence None is
|
|
317
|
+
returned)::
|
|
318
|
+
|
|
319
|
+
sage: print(ModularForms(Gamma1(11),2).character())
|
|
320
|
+
None
|
|
321
|
+
|
|
322
|
+
If the level is one then the character is trivial.
|
|
323
|
+
|
|
324
|
+
::
|
|
325
|
+
|
|
326
|
+
sage: ModularForms(Gamma1(1),12).character()
|
|
327
|
+
Dirichlet character modulo 1 of conductor 1
|
|
328
|
+
"""
|
|
329
|
+
return self.__character
|
|
330
|
+
|
|
331
|
+
def has_character(self) -> bool:
|
|
332
|
+
r"""
|
|
333
|
+
Return ``True`` if this space of modular forms has a specific
|
|
334
|
+
character.
|
|
335
|
+
|
|
336
|
+
This is ``True`` exactly when the ``character()`` function does not
|
|
337
|
+
return ``None``.
|
|
338
|
+
|
|
339
|
+
EXAMPLES: A space for `\Gamma_0(N)` has trivial character,
|
|
340
|
+
hence has a character.
|
|
341
|
+
|
|
342
|
+
::
|
|
343
|
+
|
|
344
|
+
sage: CuspForms(Gamma0(11),2).has_character()
|
|
345
|
+
True
|
|
346
|
+
|
|
347
|
+
A space for `\Gamma_1(N)` (for `N\geq 2`) never
|
|
348
|
+
has a specific character.
|
|
349
|
+
|
|
350
|
+
::
|
|
351
|
+
|
|
352
|
+
sage: CuspForms(Gamma1(11),2).has_character()
|
|
353
|
+
False
|
|
354
|
+
sage: CuspForms(DirichletGroup(11).0,3).has_character()
|
|
355
|
+
True
|
|
356
|
+
"""
|
|
357
|
+
return self.character() is not None
|
|
358
|
+
|
|
359
|
+
def is_ambient(self) -> bool:
|
|
360
|
+
"""
|
|
361
|
+
Return ``True`` if this an ambient space of modular forms.
|
|
362
|
+
|
|
363
|
+
EXAMPLES::
|
|
364
|
+
|
|
365
|
+
sage: M = ModularForms(Gamma1(4),4)
|
|
366
|
+
sage: M.is_ambient()
|
|
367
|
+
True
|
|
368
|
+
|
|
369
|
+
::
|
|
370
|
+
|
|
371
|
+
sage: E = M.eisenstein_subspace()
|
|
372
|
+
sage: E.is_ambient()
|
|
373
|
+
False
|
|
374
|
+
"""
|
|
375
|
+
return False # returning True is defined in the derived AmbientSpace class.
|
|
376
|
+
|
|
377
|
+
def __normalize_prec(self, prec):
|
|
378
|
+
"""
|
|
379
|
+
If prec=None, return self.prec(). Otherwise, make sure prec is a
|
|
380
|
+
sensible choice of precision and return it.
|
|
381
|
+
|
|
382
|
+
EXAMPLES::
|
|
383
|
+
|
|
384
|
+
sage: N = ModularForms(6,4)
|
|
385
|
+
sage: N._ModularFormsSpace__normalize_prec(int(3))
|
|
386
|
+
3
|
|
387
|
+
|
|
388
|
+
::
|
|
389
|
+
|
|
390
|
+
sage: type(N._ModularFormsSpace__normalize_prec(int(3)))
|
|
391
|
+
<class 'sage.rings.integer.Integer'>
|
|
392
|
+
"""
|
|
393
|
+
if prec is None:
|
|
394
|
+
prec = self.prec()
|
|
395
|
+
else:
|
|
396
|
+
prec = Integer(prec)
|
|
397
|
+
if prec < 0:
|
|
398
|
+
raise ValueError("prec (=%s) must be at least 0" % prec)
|
|
399
|
+
return prec
|
|
400
|
+
|
|
401
|
+
@cached_method
|
|
402
|
+
def echelon_form(self):
|
|
403
|
+
r"""
|
|
404
|
+
Return a space of modular forms isomorphic to ``self`` but with basis
|
|
405
|
+
of `q`-expansions in reduced echelon form.
|
|
406
|
+
|
|
407
|
+
This is useful, e.g., the default basis for spaces of modular forms
|
|
408
|
+
is rarely in echelon form, but echelon form is useful for quickly
|
|
409
|
+
recognizing whether a `q`-expansion is in the space.
|
|
410
|
+
|
|
411
|
+
EXAMPLES: We first illustrate two ambient spaces and their echelon
|
|
412
|
+
forms.
|
|
413
|
+
|
|
414
|
+
::
|
|
415
|
+
|
|
416
|
+
sage: M = ModularForms(11)
|
|
417
|
+
sage: M.basis()
|
|
418
|
+
[q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6),
|
|
419
|
+
1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)]
|
|
420
|
+
sage: M.echelon_form().basis()
|
|
421
|
+
[1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6),
|
|
422
|
+
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)]
|
|
423
|
+
|
|
424
|
+
::
|
|
425
|
+
|
|
426
|
+
sage: M = ModularForms(Gamma1(6),4)
|
|
427
|
+
sage: M.basis()
|
|
428
|
+
[q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6),
|
|
429
|
+
1 + O(q^6),
|
|
430
|
+
q - 8*q^4 + 126*q^5 + O(q^6),
|
|
431
|
+
q^2 + 9*q^4 + O(q^6),
|
|
432
|
+
q^3 + O(q^6)]
|
|
433
|
+
sage: M.echelon_form().basis()
|
|
434
|
+
[1 + O(q^6),
|
|
435
|
+
q + 94*q^5 + O(q^6),
|
|
436
|
+
q^2 + 36*q^5 + O(q^6),
|
|
437
|
+
q^3 + O(q^6),
|
|
438
|
+
q^4 - 4*q^5 + O(q^6)]
|
|
439
|
+
|
|
440
|
+
We create a space with a funny basis then compute the corresponding
|
|
441
|
+
echelon form.
|
|
442
|
+
|
|
443
|
+
::
|
|
444
|
+
|
|
445
|
+
sage: M = ModularForms(11,4)
|
|
446
|
+
sage: M.basis()
|
|
447
|
+
[q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6),
|
|
448
|
+
q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6),
|
|
449
|
+
1 + O(q^6),
|
|
450
|
+
q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)]
|
|
451
|
+
sage: F = M.span_of_basis([M.0 + 1/3*M.1, M.2 + M.3]); F.basis()
|
|
452
|
+
[q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6),
|
|
453
|
+
1 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)]
|
|
454
|
+
sage: E = F.echelon_form(); E.basis()
|
|
455
|
+
[1 + 26/3*q^2 + 79/3*q^3 + 235/3*q^4 + 391/3*q^5 + O(q^6),
|
|
456
|
+
q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6)]
|
|
457
|
+
"""
|
|
458
|
+
return self.span_of_basis(self.echelon_basis())
|
|
459
|
+
|
|
460
|
+
@cached_method
|
|
461
|
+
def echelon_basis(self):
|
|
462
|
+
"""
|
|
463
|
+
Return a basis for ``self`` in reduced echelon form. This means that if
|
|
464
|
+
we view the `q`-expansions of the basis as defining rows of
|
|
465
|
+
a matrix (with infinitely many columns), then this matrix is in
|
|
466
|
+
reduced echelon form.
|
|
467
|
+
|
|
468
|
+
EXAMPLES::
|
|
469
|
+
|
|
470
|
+
sage: M = ModularForms(Gamma0(11),4)
|
|
471
|
+
sage: M.echelon_basis()
|
|
472
|
+
[1 + O(q^6),
|
|
473
|
+
q - 9*q^4 - 10*q^5 + O(q^6),
|
|
474
|
+
q^2 + 6*q^4 + 12*q^5 + O(q^6),
|
|
475
|
+
q^3 + q^4 + q^5 + O(q^6)]
|
|
476
|
+
sage: M.cuspidal_subspace().echelon_basis()
|
|
477
|
+
[q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6)]
|
|
478
|
+
|
|
479
|
+
::
|
|
480
|
+
|
|
481
|
+
sage: M = ModularForms(SL2Z, 12)
|
|
482
|
+
sage: M.echelon_basis()
|
|
483
|
+
[1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6),
|
|
484
|
+
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)]
|
|
485
|
+
|
|
486
|
+
::
|
|
487
|
+
|
|
488
|
+
sage: M = CuspForms(Gamma0(17),4, prec=10)
|
|
489
|
+
sage: M.echelon_basis()
|
|
490
|
+
[q + 2*q^5 - 8*q^7 - 8*q^8 + 7*q^9 + O(q^10),
|
|
491
|
+
q^2 - 3/2*q^5 - 7/2*q^6 + 9/2*q^7 + q^8 - 4*q^9 + O(q^10),
|
|
492
|
+
q^3 - 2*q^6 + q^7 - 4*q^8 - 2*q^9 + O(q^10),
|
|
493
|
+
q^4 - 1/2*q^5 - 5/2*q^6 + 3/2*q^7 + 2*q^9 + O(q^10)]
|
|
494
|
+
"""
|
|
495
|
+
F = self.free_module()
|
|
496
|
+
W = self._q_expansion_module()
|
|
497
|
+
pr = W.degree()
|
|
498
|
+
B = self.q_echelon_basis(pr)
|
|
499
|
+
E = [self(F.linear_combination_of_basis(W.coordinates(f.padded_list(pr))))
|
|
500
|
+
for f in B]
|
|
501
|
+
return Sequence(E, cr=True, immutable=True)
|
|
502
|
+
|
|
503
|
+
@cached_method
|
|
504
|
+
def integral_basis(self):
|
|
505
|
+
"""
|
|
506
|
+
Return an integral basis for this space of modular forms.
|
|
507
|
+
|
|
508
|
+
EXAMPLES:
|
|
509
|
+
|
|
510
|
+
In this example the integral and echelon bases are
|
|
511
|
+
different. ::
|
|
512
|
+
|
|
513
|
+
sage: m = ModularForms(97,2,prec=10)
|
|
514
|
+
sage: s = m.cuspidal_subspace()
|
|
515
|
+
sage: s.integral_basis()
|
|
516
|
+
[q + 2*q^7 + 4*q^8 - 2*q^9 + O(q^10),
|
|
517
|
+
q^2 + q^4 + q^7 + 3*q^8 - 3*q^9 + O(q^10),
|
|
518
|
+
q^3 + q^4 - 3*q^8 + q^9 + O(q^10),
|
|
519
|
+
2*q^4 - 2*q^8 + O(q^10),
|
|
520
|
+
q^5 - 2*q^8 + 2*q^9 + O(q^10),
|
|
521
|
+
q^6 + 2*q^7 + 5*q^8 - 5*q^9 + O(q^10),
|
|
522
|
+
3*q^7 + 6*q^8 - 4*q^9 + O(q^10)]
|
|
523
|
+
sage: s.echelon_basis()
|
|
524
|
+
[q + 2/3*q^9 + O(q^10),
|
|
525
|
+
q^2 + 2*q^8 - 5/3*q^9 + O(q^10),
|
|
526
|
+
q^3 - 2*q^8 + q^9 + O(q^10),
|
|
527
|
+
q^4 - q^8 + O(q^10),
|
|
528
|
+
q^5 - 2*q^8 + 2*q^9 + O(q^10),
|
|
529
|
+
q^6 + q^8 - 7/3*q^9 + O(q^10),
|
|
530
|
+
q^7 + 2*q^8 - 4/3*q^9 + O(q^10)]
|
|
531
|
+
|
|
532
|
+
Here's another example where there is a big gap in the valuations::
|
|
533
|
+
|
|
534
|
+
sage: m = CuspForms(64,2)
|
|
535
|
+
sage: m.integral_basis()
|
|
536
|
+
[q + O(q^6), q^2 + O(q^6), q^5 + O(q^6)]
|
|
537
|
+
|
|
538
|
+
TESTS::
|
|
539
|
+
|
|
540
|
+
sage: m = CuspForms(11*2^4,2, prec=13); m
|
|
541
|
+
Cuspidal subspace of dimension 19 of Modular Forms space of dimension 30 for Congruence Subgroup Gamma0(176) of weight 2 over Rational Field
|
|
542
|
+
sage: m.integral_basis() # takes a long time (3 or 4 seconds)
|
|
543
|
+
[q + O(q^13),
|
|
544
|
+
q^2 + O(q^13),
|
|
545
|
+
q^3 + O(q^13),
|
|
546
|
+
q^4 + O(q^13),
|
|
547
|
+
q^5 + O(q^13),
|
|
548
|
+
q^6 + O(q^13),
|
|
549
|
+
q^7 + O(q^13),
|
|
550
|
+
q^8 + O(q^13),
|
|
551
|
+
q^9 + O(q^13),
|
|
552
|
+
q^10 + O(q^13),
|
|
553
|
+
q^11 + O(q^13),
|
|
554
|
+
q^12 + O(q^13),
|
|
555
|
+
O(q^13),
|
|
556
|
+
O(q^13),
|
|
557
|
+
O(q^13),
|
|
558
|
+
O(q^13),
|
|
559
|
+
O(q^13),
|
|
560
|
+
O(q^13),
|
|
561
|
+
O(q^13)]
|
|
562
|
+
"""
|
|
563
|
+
W = self._q_expansion_module()
|
|
564
|
+
pr = W.degree()
|
|
565
|
+
B = self.q_integral_basis(pr)
|
|
566
|
+
I = [self.linear_combination_of_basis(
|
|
567
|
+
W.coordinates(f.padded_list(pr))) for f in B]
|
|
568
|
+
return Sequence(I, cr=True, immutable=True)
|
|
569
|
+
|
|
570
|
+
@cached_method
|
|
571
|
+
def _q_expansion_module(self):
|
|
572
|
+
"""
|
|
573
|
+
Return module spanned by coefficients of `q`-expansions to sufficient
|
|
574
|
+
precision to determine elements of this space.
|
|
575
|
+
|
|
576
|
+
EXAMPLES::
|
|
577
|
+
|
|
578
|
+
sage: M = ModularForms(11,2)
|
|
579
|
+
sage: M._q_expansion_module()
|
|
580
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
581
|
+
User basis matrix:
|
|
582
|
+
[ 0 1 -2]
|
|
583
|
+
[ 1 12/5 36/5]
|
|
584
|
+
sage: CuspForms(1,12)._q_expansion_module()
|
|
585
|
+
Vector space of degree 2 and dimension 1 over Rational Field
|
|
586
|
+
User basis matrix:
|
|
587
|
+
[0 1]
|
|
588
|
+
"""
|
|
589
|
+
prec = self.sturm_bound()
|
|
590
|
+
C = self.q_expansion_basis(prec)
|
|
591
|
+
V = self.base_ring()**prec
|
|
592
|
+
return V.span_of_basis([f.padded_list(prec) for f in C])
|
|
593
|
+
|
|
594
|
+
def q_expansion_basis(self, prec=None):
|
|
595
|
+
"""
|
|
596
|
+
Return a sequence of `q`-expansions for the basis of this space
|
|
597
|
+
computed to the given input precision.
|
|
598
|
+
|
|
599
|
+
INPUT:
|
|
600
|
+
|
|
601
|
+
- ``prec`` -- integer (>=0) or None
|
|
602
|
+
|
|
603
|
+
If prec is None, the prec is computed to be *at least* large
|
|
604
|
+
enough so that each `q`-expansion determines the form as an element
|
|
605
|
+
of this space.
|
|
606
|
+
|
|
607
|
+
.. NOTE::
|
|
608
|
+
|
|
609
|
+
In fact, the `q`-expansion basis is always computed to
|
|
610
|
+
*at least* ``self.prec()``.
|
|
611
|
+
|
|
612
|
+
EXAMPLES::
|
|
613
|
+
|
|
614
|
+
sage: S = ModularForms(11,2).cuspidal_submodule()
|
|
615
|
+
sage: S.q_expansion_basis()
|
|
616
|
+
[q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)]
|
|
617
|
+
sage: S.q_expansion_basis(5)
|
|
618
|
+
[q - 2*q^2 - q^3 + 2*q^4 + O(q^5)]
|
|
619
|
+
sage: S = ModularForms(1,24).cuspidal_submodule()
|
|
620
|
+
sage: S.q_expansion_basis(8)
|
|
621
|
+
[q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 - 982499328*q^6 - 147247240*q^7 + O(q^8),
|
|
622
|
+
q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + 143820*q^6 - 985824*q^7 + O(q^8)]
|
|
623
|
+
|
|
624
|
+
An example which used to be buggy::
|
|
625
|
+
|
|
626
|
+
sage: M = CuspForms(128, 2, prec=3)
|
|
627
|
+
sage: M.q_expansion_basis()
|
|
628
|
+
[q - q^17 + O(q^22),
|
|
629
|
+
q^2 - 3*q^18 + O(q^22),
|
|
630
|
+
q^3 - q^11 + q^19 + O(q^22),
|
|
631
|
+
q^4 - 2*q^20 + O(q^22),
|
|
632
|
+
q^5 - 3*q^21 + O(q^22),
|
|
633
|
+
q^7 - q^15 + O(q^22),
|
|
634
|
+
q^9 - q^17 + O(q^22),
|
|
635
|
+
q^10 + O(q^22),
|
|
636
|
+
q^13 - q^21 + O(q^22)]
|
|
637
|
+
"""
|
|
638
|
+
if prec is None:
|
|
639
|
+
try: # don't care about precision -- just must be big enough to determine forms
|
|
640
|
+
return self.__q_expansion_basis[1]
|
|
641
|
+
except AttributeError:
|
|
642
|
+
pass
|
|
643
|
+
prec = -1 # big enough to determine forms
|
|
644
|
+
else:
|
|
645
|
+
prec = Integer(self.__normalize_prec(prec))
|
|
646
|
+
|
|
647
|
+
if prec == 0:
|
|
648
|
+
z = self._q_expansion_ring()(0, prec)
|
|
649
|
+
return Sequence([z] * int(self.dimension()), immutable=True, cr=True)
|
|
650
|
+
elif prec != -1:
|
|
651
|
+
try:
|
|
652
|
+
current_prec, B = self.__q_expansion_basis
|
|
653
|
+
if current_prec == prec:
|
|
654
|
+
return B
|
|
655
|
+
elif current_prec > prec:
|
|
656
|
+
return Sequence([f.add_bigoh(prec) for f in B], immutable=True, cr=True)
|
|
657
|
+
except AttributeError:
|
|
658
|
+
pass
|
|
659
|
+
|
|
660
|
+
d = self.dimension()
|
|
661
|
+
current_prec = max(prec, self.prec(), int(1.2 * d) + 3) # +3 for luck.
|
|
662
|
+
tries = 0
|
|
663
|
+
while True:
|
|
664
|
+
B = [f for f in self._compute_q_expansion_basis(current_prec) if f != 0]
|
|
665
|
+
if len(B) == d:
|
|
666
|
+
break
|
|
667
|
+
tries += 1
|
|
668
|
+
current_prec += d
|
|
669
|
+
if tries > 5:
|
|
670
|
+
print("WARNING: possible bug in q_expansion_basis for modular forms space %s" % self)
|
|
671
|
+
if prec == -1:
|
|
672
|
+
prec = current_prec
|
|
673
|
+
B = Sequence(B, immutable=True, cr=True)
|
|
674
|
+
self.__q_expansion_basis = (current_prec, B)
|
|
675
|
+
if current_prec == prec:
|
|
676
|
+
return B
|
|
677
|
+
return Sequence([f.add_bigoh(prec) for f in B], immutable=True, cr=True)
|
|
678
|
+
|
|
679
|
+
def _compute_q_expansion_basis(self, prec):
|
|
680
|
+
"""
|
|
681
|
+
EXAMPLES::
|
|
682
|
+
|
|
683
|
+
sage: # needs sage.rings.number_field
|
|
684
|
+
sage: sage.modular.modform.space.ModularFormsSpace(Gamma0(11), 2, DirichletGroup(1)[0], QQ)._compute_q_expansion_basis(5)
|
|
685
|
+
Traceback (most recent call last):
|
|
686
|
+
...
|
|
687
|
+
NotImplementedError: this must be implemented in the derived class
|
|
688
|
+
"""
|
|
689
|
+
raise NotImplementedError("this must be implemented in the derived class")
|
|
690
|
+
|
|
691
|
+
def q_echelon_basis(self, prec=None):
|
|
692
|
+
r"""
|
|
693
|
+
Return the echelon form of the basis of `q`-expansions of
|
|
694
|
+
``self`` up to precision ``prec``.
|
|
695
|
+
|
|
696
|
+
The `q`-expansions are power series (not actual modular
|
|
697
|
+
forms). The number of `q`-expansions returned equals the
|
|
698
|
+
dimension.
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: M = ModularForms(11,2)
|
|
703
|
+
sage: M.q_expansion_basis()
|
|
704
|
+
[q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6),
|
|
705
|
+
1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)]
|
|
706
|
+
|
|
707
|
+
::
|
|
708
|
+
|
|
709
|
+
sage: M.q_echelon_basis()
|
|
710
|
+
[1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6),
|
|
711
|
+
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)]
|
|
712
|
+
"""
|
|
713
|
+
prec = self.__normalize_prec(prec)
|
|
714
|
+
if prec == 0:
|
|
715
|
+
z = self._q_expansion_ring()(0, 0)
|
|
716
|
+
return Sequence([z] * int(self.dimension()), cr=True)
|
|
717
|
+
try:
|
|
718
|
+
current_prec, B = self.__q_echelon_basis
|
|
719
|
+
except AttributeError:
|
|
720
|
+
current_prec, B = -1, []
|
|
721
|
+
if current_prec == prec:
|
|
722
|
+
return B
|
|
723
|
+
elif current_prec > prec:
|
|
724
|
+
return Sequence([f.add_bigoh(prec) for f in B], cr=True)
|
|
725
|
+
|
|
726
|
+
B = self.q_expansion_basis(prec)
|
|
727
|
+
R = self.base_ring()
|
|
728
|
+
A = R**prec
|
|
729
|
+
gens = [f.padded_list(prec) for f in B]
|
|
730
|
+
C = A.span(gens)
|
|
731
|
+
|
|
732
|
+
T = self._q_expansion_ring()
|
|
733
|
+
S = [T(f.list(), prec) for f in C.basis()]
|
|
734
|
+
for _ in range(self.dimension() - len(S)):
|
|
735
|
+
S.append(T(0, prec))
|
|
736
|
+
S = Sequence(S, immutable=True, cr=True)
|
|
737
|
+
self.__q_echelon_basis = (prec, S)
|
|
738
|
+
return S
|
|
739
|
+
|
|
740
|
+
def q_integral_basis(self, prec=None):
|
|
741
|
+
r"""
|
|
742
|
+
Return a `\ZZ`-reduced echelon basis of
|
|
743
|
+
`q`-expansions for ``self``.
|
|
744
|
+
|
|
745
|
+
The `q`-expansions are power series with coefficients in
|
|
746
|
+
`\ZZ`; they are *not* actual modular forms.
|
|
747
|
+
|
|
748
|
+
The base ring of ``self`` must be `\QQ`. The number of
|
|
749
|
+
`q`-expansions returned equals the dimension.
|
|
750
|
+
|
|
751
|
+
EXAMPLES::
|
|
752
|
+
|
|
753
|
+
sage: S = CuspForms(11,2)
|
|
754
|
+
sage: S.q_integral_basis(5)
|
|
755
|
+
[q - 2*q^2 - q^3 + 2*q^4 + O(q^5)]
|
|
756
|
+
"""
|
|
757
|
+
if not self.base_ring() == QQ:
|
|
758
|
+
raise TypeError("the base ring must be Q")
|
|
759
|
+
prec = self.__normalize_prec(prec)
|
|
760
|
+
R = PowerSeriesRing(ZZ, name=defaults.DEFAULT_VARIABLE)
|
|
761
|
+
if prec == 0:
|
|
762
|
+
z = R(0, prec)
|
|
763
|
+
return Sequence([z] * int(self.dimension()), cr=True)
|
|
764
|
+
try:
|
|
765
|
+
current_prec, B = self.__q_integral_basis
|
|
766
|
+
except AttributeError:
|
|
767
|
+
current_prec, B = -1, Sequence([], cr=True, immutable=True)
|
|
768
|
+
|
|
769
|
+
if current_prec == prec:
|
|
770
|
+
return B
|
|
771
|
+
elif current_prec > prec:
|
|
772
|
+
return Sequence([f.add_bigoh(prec) for f in B], cr=True)
|
|
773
|
+
|
|
774
|
+
B = self.q_expansion_basis(prec)
|
|
775
|
+
|
|
776
|
+
# It's over Q; we just need to intersect it with ZZ^n.
|
|
777
|
+
A = ZZ**prec
|
|
778
|
+
gens = [f.padded_list(prec) for f in B]
|
|
779
|
+
C = A.span(gens)
|
|
780
|
+
D = C.saturation()
|
|
781
|
+
S = [R(f.list(),prec) for f in D.basis()]
|
|
782
|
+
for _ in range(self.dimension() - len(S)):
|
|
783
|
+
S.append(R(0,prec))
|
|
784
|
+
S = Sequence(S, immutable=True, cr=True)
|
|
785
|
+
self.__q_integral_basis = (prec, S)
|
|
786
|
+
return S
|
|
787
|
+
|
|
788
|
+
@cached_method
|
|
789
|
+
def _q_expansion_ring(self):
|
|
790
|
+
"""
|
|
791
|
+
Return the parent for `q`-expansions of modular forms in ``self``.
|
|
792
|
+
|
|
793
|
+
EXAMPLES::
|
|
794
|
+
|
|
795
|
+
sage: M = ModularForms(11,2)
|
|
796
|
+
sage: M._q_expansion_ring()
|
|
797
|
+
Power Series Ring in q over Rational Field
|
|
798
|
+
"""
|
|
799
|
+
return PowerSeriesRing(self.base_ring(), name=defaults.DEFAULT_VARIABLE)
|
|
800
|
+
|
|
801
|
+
@cached_method
|
|
802
|
+
def _q_expansion_zero(self):
|
|
803
|
+
"""
|
|
804
|
+
Return the `q`-expansion of the modular form 0.
|
|
805
|
+
|
|
806
|
+
EXAMPLES::
|
|
807
|
+
|
|
808
|
+
sage: M = ModularForms(11,2)
|
|
809
|
+
sage: M._q_expansion_zero()
|
|
810
|
+
0
|
|
811
|
+
sage: M._q_expansion_zero() == M._q_expansion_ring()(0)
|
|
812
|
+
True
|
|
813
|
+
"""
|
|
814
|
+
return self._q_expansion_ring()(0)
|
|
815
|
+
|
|
816
|
+
def _q_expansion(self, element, prec):
|
|
817
|
+
"""
|
|
818
|
+
Take an element of ``self`` (specified as a list, tuple, or vector),
|
|
819
|
+
and return the corresponding `q`-expansion.
|
|
820
|
+
|
|
821
|
+
EXAMPLES::
|
|
822
|
+
|
|
823
|
+
sage: m = ModularForms(Gamma0(23),2); m
|
|
824
|
+
Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Rational Field
|
|
825
|
+
sage: m.basis()
|
|
826
|
+
[q - q^3 - q^4 + O(q^6),
|
|
827
|
+
q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6),
|
|
828
|
+
1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6)]
|
|
829
|
+
sage: m._q_expansion([1,2,0], 5)
|
|
830
|
+
q + 2*q^2 - 5*q^3 - 3*q^4 + O(q^5)
|
|
831
|
+
"""
|
|
832
|
+
return self.ambient_module()._q_expansion(element, prec)
|
|
833
|
+
|
|
834
|
+
def __add__(self, right):
|
|
835
|
+
"""
|
|
836
|
+
If ``self`` and ``right`` live inside the same ambient module, return the
|
|
837
|
+
sum of the two spaces (as modules).
|
|
838
|
+
|
|
839
|
+
EXAMPLES::
|
|
840
|
+
|
|
841
|
+
sage: N = CuspForms(44,2) ; ls = [N.submodule([N(u) for u in x.q_expansion_basis(20)]) for x in N.modular_symbols().decomposition()]; ls
|
|
842
|
+
[Modular Forms subspace of dimension 1 of Modular Forms space of dimension 9 for Congruence Subgroup Gamma0(44) of weight 2 over Rational Field,
|
|
843
|
+
Modular Forms subspace of dimension 3 of Modular Forms space of dimension 9 for Congruence Subgroup Gamma0(44) of weight 2 over Rational Field]
|
|
844
|
+
|
|
845
|
+
::
|
|
846
|
+
|
|
847
|
+
sage: N1 = ls[0] ; N2 = ls[1]
|
|
848
|
+
sage: N1 + N2 # indirect doctest
|
|
849
|
+
Modular Forms subspace of dimension 4 of Modular Forms space of dimension 9 for Congruence Subgroup Gamma0(44) of weight 2 over Rational Field
|
|
850
|
+
"""
|
|
851
|
+
from sage.modular.modform.submodule import ModularFormsSubmodule
|
|
852
|
+
if self.ambient_module() != right.ambient_module():
|
|
853
|
+
raise ArithmeticError(("Sum of %s and %s not defined because " +
|
|
854
|
+
"they do not lie in a common ambient space.") %
|
|
855
|
+
(self, right))
|
|
856
|
+
if self.is_ambient():
|
|
857
|
+
return self
|
|
858
|
+
if right.is_ambient():
|
|
859
|
+
return right
|
|
860
|
+
V = self.free_module() + right.free_module()
|
|
861
|
+
return ModularFormsSubmodule(self.ambient_module(), V)
|
|
862
|
+
|
|
863
|
+
def _has_natural_inclusion_map_to(self, right):
|
|
864
|
+
"""
|
|
865
|
+
Return true if there is a natural inclusion map from modular forms
|
|
866
|
+
in ``self`` to modular forms in right.
|
|
867
|
+
|
|
868
|
+
INPUT:
|
|
869
|
+
|
|
870
|
+
- ``self``, ``right`` -- spaces of modular forms
|
|
871
|
+
|
|
872
|
+
OUTPUT: ``True`` if ``self`` embeds in ``right``, ``False`` otherwise
|
|
873
|
+
|
|
874
|
+
TODO: Barring a few trivial cases, this only works in the case that
|
|
875
|
+
right.is_ambient() returns True.
|
|
876
|
+
|
|
877
|
+
EXAMPLES::
|
|
878
|
+
|
|
879
|
+
sage: N = ModularForms(6,4) ; S = N.cuspidal_subspace()
|
|
880
|
+
|
|
881
|
+
::
|
|
882
|
+
|
|
883
|
+
sage: N._has_natural_inclusion_map_to(S)
|
|
884
|
+
Traceback (most recent call last):
|
|
885
|
+
...
|
|
886
|
+
NotImplementedError
|
|
887
|
+
|
|
888
|
+
::
|
|
889
|
+
|
|
890
|
+
sage: S._has_natural_inclusion_map_to(N)
|
|
891
|
+
True
|
|
892
|
+
|
|
893
|
+
::
|
|
894
|
+
|
|
895
|
+
sage: M = ModularForms(11,2)
|
|
896
|
+
sage: N._has_natural_inclusion_map_to(M)
|
|
897
|
+
False
|
|
898
|
+
"""
|
|
899
|
+
if not right.group().is_subgroup(self.group()):
|
|
900
|
+
return False
|
|
901
|
+
if right.character() is None:
|
|
902
|
+
# It's the full Gamma_1(N).
|
|
903
|
+
return True
|
|
904
|
+
if right.is_ambient():
|
|
905
|
+
e = self.character()
|
|
906
|
+
f = right.character()
|
|
907
|
+
return f.parent()(e) == f
|
|
908
|
+
raise NotImplementedError
|
|
909
|
+
|
|
910
|
+
def _coerce_map_from_(self, from_par):
|
|
911
|
+
"""
|
|
912
|
+
Code to make ModularFormsSpace work well with coercion framework.
|
|
913
|
+
|
|
914
|
+
EXAMPLES::
|
|
915
|
+
|
|
916
|
+
sage: M = ModularForms(22,2)
|
|
917
|
+
sage: M.has_coerce_map_from(M.cuspidal_subspace())
|
|
918
|
+
True
|
|
919
|
+
sage: M.has_coerce_map_from(ModularForms(22,4))
|
|
920
|
+
False
|
|
921
|
+
"""
|
|
922
|
+
if isinstance(from_par, ModularFormsSpace):
|
|
923
|
+
if from_par.ambient() == self:
|
|
924
|
+
return True
|
|
925
|
+
elif self.is_ambient() and self.group().is_subgroup(from_par.group()) and self.weight() == from_par.weight():
|
|
926
|
+
return True
|
|
927
|
+
|
|
928
|
+
return False
|
|
929
|
+
|
|
930
|
+
def _element_constructor_(self, x, check=True):
|
|
931
|
+
"""
|
|
932
|
+
Try to coerce ``x`` into ``self``. If ``x`` is a vector of length
|
|
933
|
+
``self.dimension()``, interpret it as a list of coefficients for
|
|
934
|
+
``self.basis()`` and return that linear combination. If ``x`` is a power
|
|
935
|
+
series, it tries to determine whether or not ``x`` lives in ``self``. If
|
|
936
|
+
so, it returns ``x`` as an element of M, and throws an error if not.
|
|
937
|
+
|
|
938
|
+
EXAMPLES::
|
|
939
|
+
|
|
940
|
+
sage: M = ModularForms(13,4)
|
|
941
|
+
sage: M.dimension()
|
|
942
|
+
5
|
|
943
|
+
|
|
944
|
+
::
|
|
945
|
+
|
|
946
|
+
sage: M([1,2,3,4,5])
|
|
947
|
+
4 + 6*q + 47*q^2 + 143*q^3 + 358*q^4 + 630*q^5 + O(q^6)
|
|
948
|
+
|
|
949
|
+
::
|
|
950
|
+
|
|
951
|
+
sage: M([1,3])
|
|
952
|
+
Traceback (most recent call last):
|
|
953
|
+
...
|
|
954
|
+
TypeError: entries must be a list of length 5
|
|
955
|
+
|
|
956
|
+
::
|
|
957
|
+
|
|
958
|
+
sage: R = M._q_expansion_ring()
|
|
959
|
+
sage: M(R([0,1,0,0,0,-2,-4,-2,-12]).add_bigoh(9))
|
|
960
|
+
q - 2*q^5 + O(q^6)
|
|
961
|
+
|
|
962
|
+
::
|
|
963
|
+
|
|
964
|
+
sage: M.set_precision(9)
|
|
965
|
+
sage: M(R([0,1,0,0,0,-2,-4,-2,-12]).add_bigoh(9))
|
|
966
|
+
q - 2*q^5 - 4*q^6 - 2*q^7 - 12*q^8 + O(q^9)
|
|
967
|
+
|
|
968
|
+
Note that one only needs coefficients up to self.sturm_bound() to
|
|
969
|
+
determine the form::
|
|
970
|
+
|
|
971
|
+
sage: M(R([0,1,0,0,0,-2,-4,-2,-12]).add_bigoh(8))
|
|
972
|
+
q - 2*q^5 - 4*q^6 - 2*q^7 - 12*q^8 + O(q^9)
|
|
973
|
+
|
|
974
|
+
::
|
|
975
|
+
|
|
976
|
+
sage: M(R([0,1,1,0,0,0,-4,-2,-12]).add_bigoh(9))
|
|
977
|
+
Traceback (most recent call last):
|
|
978
|
+
...
|
|
979
|
+
ValueError: q-expansion does not correspond to a form in self
|
|
980
|
+
|
|
981
|
+
::
|
|
982
|
+
|
|
983
|
+
sage: S = CuspForms(1,12) ; R = PowerSeriesRing(QQ,'q') ; q = R.0
|
|
984
|
+
sage: f = q+O(q^2) ; S(f)
|
|
985
|
+
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
|
|
986
|
+
sage: f = q+2*q^2+O(q^3) ; S(f)
|
|
987
|
+
Traceback (most recent call last):
|
|
988
|
+
...
|
|
989
|
+
ValueError: q-expansion does not correspond to a form in self
|
|
990
|
+
sage: f = q-24*q^2+O(q^3) ; S(f)
|
|
991
|
+
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
|
|
992
|
+
|
|
993
|
+
Test that :issue:`13156` is fixed::
|
|
994
|
+
|
|
995
|
+
sage: R.<q> = QQ[[]]
|
|
996
|
+
sage: ModularForms(1, 12)(R(0))
|
|
997
|
+
0
|
|
998
|
+
sage: ModularForms(1, 12)(R(1))
|
|
999
|
+
Traceback (most recent call last):
|
|
1000
|
+
...
|
|
1001
|
+
TypeError: unable to create modular form from exact nonzero polynomial
|
|
1002
|
+
|
|
1003
|
+
sage: E = ModularForms(3,12).cuspidal_subspace()
|
|
1004
|
+
sage: f = E.gens()[0]
|
|
1005
|
+
sage: g = f - f
|
|
1006
|
+
sage: g.is_old()
|
|
1007
|
+
True
|
|
1008
|
+
|
|
1009
|
+
Test that :issue:`32168` is fixed::
|
|
1010
|
+
|
|
1011
|
+
sage: M0 = ModularForms(Gamma0(8), 10)
|
|
1012
|
+
sage: M1 = ModularForms(Gamma1(8), 10)
|
|
1013
|
+
sage: f = M0.0; g = M1.0
|
|
1014
|
+
sage: f + g
|
|
1015
|
+
2*q + O(q^6)
|
|
1016
|
+
sage: M1(f)
|
|
1017
|
+
q + O(q^6)
|
|
1018
|
+
|
|
1019
|
+
::
|
|
1020
|
+
|
|
1021
|
+
sage: M = ModularForms(22,2) ; S = CuspForms(22,2)
|
|
1022
|
+
sage: sum(S.basis())
|
|
1023
|
+
q + q^2 - q^3 - 4*q^4 + q^5 + O(q^6)
|
|
1024
|
+
sage: sum(S.basis() + M.basis())
|
|
1025
|
+
1 + 3*q + 3*q^2 + 2*q^3 - 7*q^4 + 8*q^5 + O(q^6)
|
|
1026
|
+
sage: M.coerce(S.basis()[0])
|
|
1027
|
+
q - q^3 - 2*q^4 + q^5 + O(q^6)
|
|
1028
|
+
|
|
1029
|
+
::
|
|
1030
|
+
|
|
1031
|
+
sage: M = ModularForms(Gamma0(22)) ; N = ModularForms(Gamma0(44))
|
|
1032
|
+
sage: M.basis()[0]
|
|
1033
|
+
q - q^3 - 2*q^4 + q^5 + O(q^6)
|
|
1034
|
+
sage: N(M.basis()[0])
|
|
1035
|
+
q - q^3 - 2*q^4 + q^5 + O(q^6)
|
|
1036
|
+
|
|
1037
|
+
TESTS::
|
|
1038
|
+
|
|
1039
|
+
sage: M = ModularForms(13, 4)
|
|
1040
|
+
sage: M(M([1, 2, 3, 4, 5]), check=True)
|
|
1041
|
+
4 + 6*q + 47*q^2 + 143*q^3 + 358*q^4 + 630*q^5 + O(q^6)
|
|
1042
|
+
"""
|
|
1043
|
+
if isinstance(x, ModularFormElement):
|
|
1044
|
+
|
|
1045
|
+
if not check:
|
|
1046
|
+
from copy import copy
|
|
1047
|
+
f = copy(x)
|
|
1048
|
+
f._set_parent(self)
|
|
1049
|
+
return f
|
|
1050
|
+
|
|
1051
|
+
if x.parent().ambient() == self:
|
|
1052
|
+
return self(x.element())
|
|
1053
|
+
|
|
1054
|
+
return self(x.q_expansion(self._q_expansion_module().degree()))
|
|
1055
|
+
|
|
1056
|
+
elif isinstance(x, PowerSeries):
|
|
1057
|
+
if x.prec() == PlusInfinity():
|
|
1058
|
+
if x == 0:
|
|
1059
|
+
return self.element_class(self, self.free_module().zero())
|
|
1060
|
+
else:
|
|
1061
|
+
raise TypeError("unable to create modular form from exact nonzero polynomial")
|
|
1062
|
+
W = self._q_expansion_module()
|
|
1063
|
+
if W.degree() <= x.prec():
|
|
1064
|
+
try:
|
|
1065
|
+
x_potential = W.coordinates(x.padded_list(W.degree()))
|
|
1066
|
+
except ArithmeticError:
|
|
1067
|
+
raise ValueError("q-expansion does not correspond to a form in self")
|
|
1068
|
+
x_potential = self.free_module().linear_combination_of_basis(x_potential)
|
|
1069
|
+
x_potential = self.element_class(self, x_potential)
|
|
1070
|
+
for i in range(int(W.degree()), x.prec()):
|
|
1071
|
+
if x_potential[i] != x[i]:
|
|
1072
|
+
raise ValueError("q-expansion does not correspond to a form in self")
|
|
1073
|
+
return x_potential
|
|
1074
|
+
else:
|
|
1075
|
+
raise TypeError("q-expansion needed to at least precision %s" % W.degree())
|
|
1076
|
+
|
|
1077
|
+
return self.element_class(self, self.free_module()(x, check))
|
|
1078
|
+
|
|
1079
|
+
def _pushout_(self, other):
|
|
1080
|
+
r"""
|
|
1081
|
+
Implement the pushout of ``self`` and ``other``.
|
|
1082
|
+
|
|
1083
|
+
INPUT:
|
|
1084
|
+
|
|
1085
|
+
- ``other`` -- ``ModularFormSpace`` or a ``ModularFormRing``
|
|
1086
|
+
|
|
1087
|
+
OUTPUT: if ``self`` and ``other`` have the same groups and base rings, then this method returns
|
|
1088
|
+
``self`` if the weights of the two spaces are equal, otherwise it returns a ``ModularFormsRing``.
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
TESTS::
|
|
1092
|
+
|
|
1093
|
+
sage: e4 = ModularForms(1,4).0; e6 = ModularForms(1,6).0;
|
|
1094
|
+
sage: M = ModularFormsRing(1)
|
|
1095
|
+
sage: e4 + e6
|
|
1096
|
+
2 - 264*q - 14472*q^2 - 116256*q^3 - 515208*q^4 - 1545264*q^5 + O(q^6)
|
|
1097
|
+
sage: (e4 + e6).parent()
|
|
1098
|
+
Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
|
|
1099
|
+
sage: (M(e4)*e6).parent()
|
|
1100
|
+
Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
|
|
1101
|
+
sage: f = ModularForms(5,12).0
|
|
1102
|
+
sage: f+e4
|
|
1103
|
+
Traceback (most recent call last):
|
|
1104
|
+
...
|
|
1105
|
+
TypeError: unsupported operand parent(s) for +: 'Modular Forms space of dimension 7 for Congruence Subgroup Gamma0(5) of weight 12 over Rational Field' and 'Modular Forms space of dimension 1 for Modular Group SL(2,Z) of weight 4 over Rational Field'
|
|
1106
|
+
"""
|
|
1107
|
+
from .ring import ModularFormsRing
|
|
1108
|
+
if isinstance(other, ModularFormsSpace):
|
|
1109
|
+
if self.group() == other.group() and self.base_ring() == other.base_ring():
|
|
1110
|
+
if self.weight() == other.weight():
|
|
1111
|
+
return self
|
|
1112
|
+
else:
|
|
1113
|
+
return ModularFormsRing(self.group(), base_ring=self.base_ring())
|
|
1114
|
+
if isinstance(other, ModularFormsRing) and other.has_coerce_map_from(self):
|
|
1115
|
+
return other
|
|
1116
|
+
|
|
1117
|
+
def __richcmp__(self, x, op):
|
|
1118
|
+
"""
|
|
1119
|
+
Compare ``self`` and ``x``.
|
|
1120
|
+
|
|
1121
|
+
For spaces of modular forms, we order first by signature, then by
|
|
1122
|
+
dimension, and then by the ordering on the underlying free
|
|
1123
|
+
modules.
|
|
1124
|
+
|
|
1125
|
+
EXAMPLES::
|
|
1126
|
+
|
|
1127
|
+
sage: N = ModularForms(6,4) ; S = N.cuspidal_subspace()
|
|
1128
|
+
sage: S < N
|
|
1129
|
+
True
|
|
1130
|
+
sage: N > S
|
|
1131
|
+
True
|
|
1132
|
+
sage: N == N
|
|
1133
|
+
True
|
|
1134
|
+
sage: M = ModularForms(11,2)
|
|
1135
|
+
sage: N < M
|
|
1136
|
+
True
|
|
1137
|
+
sage: M > N
|
|
1138
|
+
True
|
|
1139
|
+
"""
|
|
1140
|
+
from sage.modular.modform.constructor import canonical_parameters as params
|
|
1141
|
+
|
|
1142
|
+
if self is x:
|
|
1143
|
+
return rich_to_bool(op, 0)
|
|
1144
|
+
if not isinstance(x, ModularFormsSpace):
|
|
1145
|
+
return NotImplemented
|
|
1146
|
+
|
|
1147
|
+
left_ambient = self.ambient()
|
|
1148
|
+
right_ambient = x.ambient()
|
|
1149
|
+
lx = params(left_ambient.character(), left_ambient.level(),
|
|
1150
|
+
left_ambient.weight(), left_ambient.base_ring())
|
|
1151
|
+
rx = params(right_ambient.character(), right_ambient.level(),
|
|
1152
|
+
right_ambient.weight(), right_ambient.base_ring())
|
|
1153
|
+
if lx != rx:
|
|
1154
|
+
return richcmp_not_equal(lx, rx, op)
|
|
1155
|
+
if self.is_ambient() or x.is_ambient():
|
|
1156
|
+
return richcmp(self.dimension(), x.dimension(), op)
|
|
1157
|
+
else:
|
|
1158
|
+
return self.free_module()._echelon_matrix_richcmp(x.free_module(), op)
|
|
1159
|
+
|
|
1160
|
+
def span_of_basis(self, B):
|
|
1161
|
+
"""
|
|
1162
|
+
Take a set B of forms, and return the subspace of ``self`` with B as a
|
|
1163
|
+
basis.
|
|
1164
|
+
|
|
1165
|
+
EXAMPLES::
|
|
1166
|
+
|
|
1167
|
+
sage: N = ModularForms(6,4) ; N
|
|
1168
|
+
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1169
|
+
|
|
1170
|
+
::
|
|
1171
|
+
|
|
1172
|
+
sage: N.span_of_basis([N.basis()[0]])
|
|
1173
|
+
Modular Forms subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1174
|
+
|
|
1175
|
+
::
|
|
1176
|
+
|
|
1177
|
+
sage: N.span_of_basis([N.basis()[0], N.basis()[1]])
|
|
1178
|
+
Modular Forms subspace of dimension 2 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1179
|
+
|
|
1180
|
+
::
|
|
1181
|
+
|
|
1182
|
+
sage: N.span_of_basis( N.basis() )
|
|
1183
|
+
Modular Forms subspace of dimension 5 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1184
|
+
"""
|
|
1185
|
+
from .submodule import ModularFormsSubmoduleWithBasis
|
|
1186
|
+
W = self._q_expansion_module()
|
|
1187
|
+
F = self.free_module()
|
|
1188
|
+
prec = W.degree()
|
|
1189
|
+
C = [F.linear_combination_of_basis(W.coordinates(f.padded_list(prec))) for f in B]
|
|
1190
|
+
S = F.span_of_basis(C)
|
|
1191
|
+
return ModularFormsSubmoduleWithBasis(self.ambient(), S)
|
|
1192
|
+
|
|
1193
|
+
span = span_of_basis
|
|
1194
|
+
|
|
1195
|
+
def __submodule_from_subset_of_basis(self, x):
|
|
1196
|
+
"""
|
|
1197
|
+
Return the submodule of ``self`` generated by the elements of x.
|
|
1198
|
+
|
|
1199
|
+
EXAMPLES::
|
|
1200
|
+
|
|
1201
|
+
sage: N = ModularForms(6,4)
|
|
1202
|
+
sage: N._ModularFormsSpace__submodule_from_subset_of_basis( [0,2] )
|
|
1203
|
+
Vector space of degree 5 and dimension 2 over Rational Field
|
|
1204
|
+
Basis matrix:
|
|
1205
|
+
[1 0 0 0 0]
|
|
1206
|
+
[0 0 1 0 0]
|
|
1207
|
+
"""
|
|
1208
|
+
V = self.free_module()
|
|
1209
|
+
return V.submodule([V.gen(i) for i in x], check=False)
|
|
1210
|
+
|
|
1211
|
+
def _compute_hecke_matrix_prime(self, p, prec=None):
|
|
1212
|
+
"""
|
|
1213
|
+
Compute the matrix of the Hecke operator `T_p` acting on ``self``.
|
|
1214
|
+
|
|
1215
|
+
EXAMPLES::
|
|
1216
|
+
|
|
1217
|
+
sage: M = ModularForms(11,2)
|
|
1218
|
+
sage: M._compute_hecke_matrix_prime(2)
|
|
1219
|
+
[-2 0]
|
|
1220
|
+
[ 0 3]
|
|
1221
|
+
|
|
1222
|
+
::
|
|
1223
|
+
|
|
1224
|
+
sage: M = ModularForms(11,2)
|
|
1225
|
+
sage: M2 = M.span([M.0 + M.1])
|
|
1226
|
+
sage: M2.hecke_matrix(2)
|
|
1227
|
+
Traceback (most recent call last):
|
|
1228
|
+
...
|
|
1229
|
+
ArithmeticError: vector is not in free module
|
|
1230
|
+
"""
|
|
1231
|
+
if prec is None:
|
|
1232
|
+
# Initial guess -- will increase if need be.
|
|
1233
|
+
# We add on a few dimensions, so we are likely to
|
|
1234
|
+
# detect non-invariant subspaces (if they accidentally occur).
|
|
1235
|
+
prec = p*self.dimension() + 8
|
|
1236
|
+
try:
|
|
1237
|
+
cur, _ = self.__q_expansion_basis
|
|
1238
|
+
except AttributeError:
|
|
1239
|
+
pass
|
|
1240
|
+
else:
|
|
1241
|
+
prec = max(prec, cur)
|
|
1242
|
+
B = self.q_expansion_basis(prec)
|
|
1243
|
+
eps = self.character()
|
|
1244
|
+
if eps is None:
|
|
1245
|
+
raise NotImplementedError
|
|
1246
|
+
try:
|
|
1247
|
+
return hecke_operator_on_qexp.hecke_operator_on_basis(B, p,
|
|
1248
|
+
self.weight(), eps, already_echelonized=False)
|
|
1249
|
+
except ValueError:
|
|
1250
|
+
# Double the precision.
|
|
1251
|
+
return self._compute_hecke_matrix_prime(p, prec=2 * prec + 1)
|
|
1252
|
+
|
|
1253
|
+
def _compute_hecke_matrix(self, n):
|
|
1254
|
+
"""
|
|
1255
|
+
Compute the matrix of the Hecke operator `T_n` acting on ``self``.
|
|
1256
|
+
|
|
1257
|
+
EXAMPLES::
|
|
1258
|
+
|
|
1259
|
+
sage: M = ModularForms(11,2)
|
|
1260
|
+
sage: M._compute_hecke_matrix(6)
|
|
1261
|
+
[ 2 0]
|
|
1262
|
+
[ 0 12]
|
|
1263
|
+
|
|
1264
|
+
::
|
|
1265
|
+
|
|
1266
|
+
sage: M = ModularForms(11,2)
|
|
1267
|
+
sage: M2 = M.span([M.0 + M.1])
|
|
1268
|
+
sage: M2.hecke_matrix(2)
|
|
1269
|
+
Traceback (most recent call last):
|
|
1270
|
+
...
|
|
1271
|
+
ArithmeticError: vector is not in free module
|
|
1272
|
+
|
|
1273
|
+
We check that :issue:`10450` is fixed::
|
|
1274
|
+
|
|
1275
|
+
sage: M = CuspForms(Gamma1(22), 2).new_submodule() # long time (3s on sage.math, 2011)
|
|
1276
|
+
sage: M.hecke_matrix(3) # long time
|
|
1277
|
+
[ 0 -2 3 0]
|
|
1278
|
+
[ 0 -3 5 -1]
|
|
1279
|
+
[ 1 -1 0 -1]
|
|
1280
|
+
[ 0 -2 3 -1]
|
|
1281
|
+
sage: M.hecke_matrix(9) # long time
|
|
1282
|
+
[ 3 3 -4 -4]
|
|
1283
|
+
[ 2 6 -9 -4]
|
|
1284
|
+
[ 0 3 -2 -1]
|
|
1285
|
+
[ 3 2 -7 0]
|
|
1286
|
+
"""
|
|
1287
|
+
# For spaces with character, we calculate a basis of q-expansions and
|
|
1288
|
+
# use that. For Gamma1 and GammaH spaces, we would need to compute
|
|
1289
|
+
# diamond operators, which is quite slow; so we just compute on the
|
|
1290
|
+
# whole space and restrict.
|
|
1291
|
+
|
|
1292
|
+
# TODO: If we know the subspace of the modular *symbols* space to which
|
|
1293
|
+
# this modular forms space corresponds, then that might give a quicker
|
|
1294
|
+
# way of doing this step.
|
|
1295
|
+
|
|
1296
|
+
if hasattr(self, '_compute_q_expansion_basis') and self.character() is not None:
|
|
1297
|
+
return hecke.HeckeModule_generic._compute_hecke_matrix(self, n)
|
|
1298
|
+
|
|
1299
|
+
else:
|
|
1300
|
+
# Try to avoid doing unnecessary computations where possible.
|
|
1301
|
+
if self.is_cuspidal():
|
|
1302
|
+
M = self.ambient().cuspidal_submodule().hecke_matrix(n).block_sum(zero_matrix(self.base_ring(), self.ambient().eisenstein_submodule().rank()))
|
|
1303
|
+
elif self.is_eisenstein():
|
|
1304
|
+
M = zero_matrix(self.base_ring(), self.ambient().cuspidal_submodule().rank()).block_sum(self.ambient().eisenstein_submodule().hecke_matrix(n))
|
|
1305
|
+
else:
|
|
1306
|
+
M = self.ambient().hecke_matrix(n)
|
|
1307
|
+
return M.restrict(self.free_module(), check=(gcd(n, self.level()) > 1))
|
|
1308
|
+
|
|
1309
|
+
@cached_method
|
|
1310
|
+
def basis(self):
|
|
1311
|
+
"""
|
|
1312
|
+
Return a basis for ``self``.
|
|
1313
|
+
|
|
1314
|
+
EXAMPLES::
|
|
1315
|
+
|
|
1316
|
+
sage: MM = ModularForms(11,2)
|
|
1317
|
+
sage: MM.basis()
|
|
1318
|
+
[q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6),
|
|
1319
|
+
1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)]
|
|
1320
|
+
"""
|
|
1321
|
+
return Sequence([self.element_class(self, x)
|
|
1322
|
+
for x in self.free_module().basis()],
|
|
1323
|
+
immutable=True, cr=True)
|
|
1324
|
+
|
|
1325
|
+
def gen(self, n):
|
|
1326
|
+
"""
|
|
1327
|
+
Return the `n`-th generator of ``self``.
|
|
1328
|
+
|
|
1329
|
+
EXAMPLES::
|
|
1330
|
+
|
|
1331
|
+
sage: N = ModularForms(6,4)
|
|
1332
|
+
sage: N.basis()
|
|
1333
|
+
[q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6),
|
|
1334
|
+
1 + O(q^6),
|
|
1335
|
+
q - 8*q^4 + 126*q^5 + O(q^6),
|
|
1336
|
+
q^2 + 9*q^4 + O(q^6),
|
|
1337
|
+
q^3 + O(q^6)]
|
|
1338
|
+
|
|
1339
|
+
::
|
|
1340
|
+
|
|
1341
|
+
sage: N.gen(0)
|
|
1342
|
+
q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6)
|
|
1343
|
+
|
|
1344
|
+
::
|
|
1345
|
+
|
|
1346
|
+
sage: N.gen(4)
|
|
1347
|
+
q^3 + O(q^6)
|
|
1348
|
+
|
|
1349
|
+
::
|
|
1350
|
+
|
|
1351
|
+
sage: N.gen(5)
|
|
1352
|
+
Traceback (most recent call last):
|
|
1353
|
+
...
|
|
1354
|
+
ValueError: Generator 5 not defined
|
|
1355
|
+
"""
|
|
1356
|
+
try:
|
|
1357
|
+
return self.basis()[int(n)]
|
|
1358
|
+
except IndexError:
|
|
1359
|
+
raise ValueError("Generator %s not defined" % n)
|
|
1360
|
+
|
|
1361
|
+
def gens(self) -> tuple:
|
|
1362
|
+
"""
|
|
1363
|
+
Return a complete set of generators for ``self``.
|
|
1364
|
+
|
|
1365
|
+
EXAMPLES::
|
|
1366
|
+
|
|
1367
|
+
sage: N = ModularForms(6,4)
|
|
1368
|
+
sage: N.gens()
|
|
1369
|
+
(q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6),
|
|
1370
|
+
1 + O(q^6),
|
|
1371
|
+
q - 8*q^4 + 126*q^5 + O(q^6),
|
|
1372
|
+
q^2 + 9*q^4 + O(q^6),
|
|
1373
|
+
q^3 + O(q^6))
|
|
1374
|
+
"""
|
|
1375
|
+
return tuple(self.basis())
|
|
1376
|
+
|
|
1377
|
+
def sturm_bound(self, M=None):
|
|
1378
|
+
r"""
|
|
1379
|
+
For a space M of modular forms, this function returns an integer B
|
|
1380
|
+
such that two modular forms in either ``self`` or M are equal if and
|
|
1381
|
+
only if their `q`-expansions are equal to precision B (note that this
|
|
1382
|
+
is 1+ the usual Sturm bound, since `O(q^\mathrm{prec})` has
|
|
1383
|
+
precision ``prec``). If M is none, then M is set equal to ``self``.
|
|
1384
|
+
|
|
1385
|
+
EXAMPLES::
|
|
1386
|
+
|
|
1387
|
+
sage: S37=CuspForms(37,2)
|
|
1388
|
+
sage: S37.sturm_bound()
|
|
1389
|
+
8
|
|
1390
|
+
sage: M = ModularForms(11,2)
|
|
1391
|
+
sage: M.sturm_bound()
|
|
1392
|
+
3
|
|
1393
|
+
sage: ModularForms(Gamma1(15),2).sturm_bound()
|
|
1394
|
+
33
|
|
1395
|
+
|
|
1396
|
+
sage: CuspForms(Gamma1(144), 3).sturm_bound()
|
|
1397
|
+
3457
|
|
1398
|
+
sage: CuspForms(DirichletGroup(144).1^2, 3).sturm_bound()
|
|
1399
|
+
73
|
|
1400
|
+
sage: CuspForms(Gamma0(144), 3).sturm_bound()
|
|
1401
|
+
73
|
|
1402
|
+
|
|
1403
|
+
REFERENCES:
|
|
1404
|
+
|
|
1405
|
+
- [Stu1987]_
|
|
1406
|
+
|
|
1407
|
+
NOTE:
|
|
1408
|
+
|
|
1409
|
+
Kevin Buzzard pointed out to me (William Stein) in Fall 2002 that
|
|
1410
|
+
the above bound is fine for Gamma1 with character, as one sees by
|
|
1411
|
+
taking a power of `f`. More precisely, if
|
|
1412
|
+
`f\cong 0\pmod{p}` for first `s` coefficients, then
|
|
1413
|
+
`f^r = 0 \pmod{p}` for first `s r` coefficients.
|
|
1414
|
+
Since the weight of `f^r` is
|
|
1415
|
+
`r \text{weight}(f)`, it follows that if
|
|
1416
|
+
`s \geq` the Sturm bound for `\Gamma_0` at
|
|
1417
|
+
weight(f), then `f^r` has valuation large enough to be
|
|
1418
|
+
forced to be `0` at `r\cdot` weight(f) by Sturm
|
|
1419
|
+
bound (which is valid if we choose `r` right). Thus
|
|
1420
|
+
`f \cong 0 \pmod{p}`. Conclusion: For `\Gamma_1`
|
|
1421
|
+
with fixed character, the Sturm bound is *exactly* the same as for
|
|
1422
|
+
`\Gamma_0`. A key point is that we are finding
|
|
1423
|
+
`\ZZ[\varepsilon]` generators for the Hecke algebra
|
|
1424
|
+
here, not `\ZZ`-generators. So if one wants
|
|
1425
|
+
generators for the Hecke algebra over `\ZZ`, this
|
|
1426
|
+
bound is wrong.
|
|
1427
|
+
|
|
1428
|
+
This bound works over any base, even a finite field. There might be
|
|
1429
|
+
much better bounds over `\QQ`, or for comparing two
|
|
1430
|
+
eigenforms.
|
|
1431
|
+
"""
|
|
1432
|
+
if M is not None:
|
|
1433
|
+
raise NotImplementedError
|
|
1434
|
+
if self.__sturm_bound is None:
|
|
1435
|
+
G = self.group()
|
|
1436
|
+
from sage.modular.arithgroup.all import Gamma1_class
|
|
1437
|
+
if isinstance(G, Gamma1_class) and self.character() is not None:
|
|
1438
|
+
from sage.modular.arithgroup.all import Gamma0
|
|
1439
|
+
G = Gamma0(self.level())
|
|
1440
|
+
# the +1 below is because O(q^prec) has precision prec.
|
|
1441
|
+
self.__sturm_bound = G.sturm_bound(self.weight())+1
|
|
1442
|
+
return self.__sturm_bound
|
|
1443
|
+
|
|
1444
|
+
def cuspidal_submodule(self):
|
|
1445
|
+
"""
|
|
1446
|
+
Return the cuspidal submodule of ``self``.
|
|
1447
|
+
|
|
1448
|
+
EXAMPLES::
|
|
1449
|
+
|
|
1450
|
+
sage: N = ModularForms(6,4) ; N
|
|
1451
|
+
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1452
|
+
sage: N.eisenstein_subspace().dimension()
|
|
1453
|
+
4
|
|
1454
|
+
|
|
1455
|
+
::
|
|
1456
|
+
|
|
1457
|
+
sage: N.cuspidal_submodule()
|
|
1458
|
+
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1459
|
+
|
|
1460
|
+
::
|
|
1461
|
+
|
|
1462
|
+
sage: N.cuspidal_submodule().dimension()
|
|
1463
|
+
1
|
|
1464
|
+
|
|
1465
|
+
We check that a bug noticed on :issue:`10450` is fixed::
|
|
1466
|
+
|
|
1467
|
+
sage: M = ModularForms(6, 10)
|
|
1468
|
+
sage: W = M.span_of_basis(M.basis()[0:2])
|
|
1469
|
+
sage: W.cuspidal_submodule()
|
|
1470
|
+
Modular Forms subspace of dimension 2 of Modular Forms space of dimension 11 for Congruence Subgroup Gamma0(6) of weight 10 over Rational Field
|
|
1471
|
+
"""
|
|
1472
|
+
try:
|
|
1473
|
+
if self.__is_cuspidal:
|
|
1474
|
+
return self
|
|
1475
|
+
except AttributeError:
|
|
1476
|
+
pass
|
|
1477
|
+
if self.is_ambient():
|
|
1478
|
+
raise NotImplementedError("ambient modular forms spaces must override cuspidal_submodule")
|
|
1479
|
+
C = self.ambient_module().cuspidal_submodule()
|
|
1480
|
+
S = self.intersection(C)
|
|
1481
|
+
if S.dimension() < self.dimension():
|
|
1482
|
+
self.__is_cuspidal = False
|
|
1483
|
+
else:
|
|
1484
|
+
assert S.dimension() == self.dimension()
|
|
1485
|
+
self.__is_cuspidal = True
|
|
1486
|
+
S.is_eisenstein.set_cache(S.dimension() == 0)
|
|
1487
|
+
S.__is_cuspidal = True
|
|
1488
|
+
return S
|
|
1489
|
+
|
|
1490
|
+
def cuspidal_subspace(self):
|
|
1491
|
+
"""
|
|
1492
|
+
Synonym for cuspidal_submodule.
|
|
1493
|
+
|
|
1494
|
+
EXAMPLES::
|
|
1495
|
+
|
|
1496
|
+
sage: N = ModularForms(6,4) ; N
|
|
1497
|
+
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1498
|
+
sage: N.eisenstein_subspace().dimension()
|
|
1499
|
+
4
|
|
1500
|
+
|
|
1501
|
+
::
|
|
1502
|
+
|
|
1503
|
+
sage: N.cuspidal_subspace()
|
|
1504
|
+
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1505
|
+
|
|
1506
|
+
::
|
|
1507
|
+
|
|
1508
|
+
sage: N.cuspidal_submodule().dimension()
|
|
1509
|
+
1
|
|
1510
|
+
"""
|
|
1511
|
+
return self.cuspidal_submodule()
|
|
1512
|
+
|
|
1513
|
+
def is_cuspidal(self) -> bool:
|
|
1514
|
+
r"""
|
|
1515
|
+
Return ``True`` if this space is cuspidal.
|
|
1516
|
+
|
|
1517
|
+
EXAMPLES::
|
|
1518
|
+
|
|
1519
|
+
sage: M = ModularForms(Gamma0(11), 2).new_submodule()
|
|
1520
|
+
sage: M.is_cuspidal()
|
|
1521
|
+
False
|
|
1522
|
+
sage: M.cuspidal_submodule().is_cuspidal()
|
|
1523
|
+
True
|
|
1524
|
+
"""
|
|
1525
|
+
return (self.cuspidal_submodule() == self)
|
|
1526
|
+
|
|
1527
|
+
@cached_method
|
|
1528
|
+
def is_eisenstein(self) -> bool:
|
|
1529
|
+
r"""
|
|
1530
|
+
Return ``True`` if this space is Eisenstein.
|
|
1531
|
+
|
|
1532
|
+
EXAMPLES::
|
|
1533
|
+
|
|
1534
|
+
sage: M = ModularForms(Gamma0(11), 2).new_submodule()
|
|
1535
|
+
sage: M.is_eisenstein()
|
|
1536
|
+
False
|
|
1537
|
+
sage: M.eisenstein_submodule().is_eisenstein()
|
|
1538
|
+
True
|
|
1539
|
+
"""
|
|
1540
|
+
return (self.eisenstein_submodule() == self)
|
|
1541
|
+
|
|
1542
|
+
def new_submodule(self, p=None):
|
|
1543
|
+
"""
|
|
1544
|
+
Return the new submodule of ``self``.
|
|
1545
|
+
|
|
1546
|
+
If `p` is specified, return the `p`-new submodule of ``self``.
|
|
1547
|
+
|
|
1548
|
+
.. NOTE::
|
|
1549
|
+
|
|
1550
|
+
This function should be overridden by all derived classes.
|
|
1551
|
+
|
|
1552
|
+
EXAMPLES::
|
|
1553
|
+
|
|
1554
|
+
sage: # needs sage.rings.number_field
|
|
1555
|
+
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11), 2, DirichletGroup(1)[0], base_ring=QQ); M.new_submodule()
|
|
1556
|
+
Traceback (most recent call last):
|
|
1557
|
+
...
|
|
1558
|
+
NotImplementedError: computation of new submodule not yet implemented
|
|
1559
|
+
"""
|
|
1560
|
+
raise NotImplementedError("computation of new submodule not yet implemented")
|
|
1561
|
+
|
|
1562
|
+
def new_subspace(self, p=None):
|
|
1563
|
+
"""
|
|
1564
|
+
Synonym for new_submodule.
|
|
1565
|
+
|
|
1566
|
+
EXAMPLES::
|
|
1567
|
+
|
|
1568
|
+
sage: # needs sage.rings.number_field
|
|
1569
|
+
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11), 2, DirichletGroup(1)[0], base_ring=QQ); M.new_subspace()
|
|
1570
|
+
Traceback (most recent call last):
|
|
1571
|
+
...
|
|
1572
|
+
NotImplementedError: computation of new submodule not yet implemented
|
|
1573
|
+
"""
|
|
1574
|
+
return self.new_submodule(p)
|
|
1575
|
+
|
|
1576
|
+
def eisenstein_series(self):
|
|
1577
|
+
"""
|
|
1578
|
+
Compute the Eisenstein series associated to this space.
|
|
1579
|
+
|
|
1580
|
+
.. NOTE::
|
|
1581
|
+
|
|
1582
|
+
This function should be overridden by all derived classes.
|
|
1583
|
+
|
|
1584
|
+
EXAMPLES::
|
|
1585
|
+
|
|
1586
|
+
sage: # needs sage.rings.number_field
|
|
1587
|
+
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11), 2, DirichletGroup(1)[0], base_ring=QQ); M.eisenstein_series()
|
|
1588
|
+
Traceback (most recent call last):
|
|
1589
|
+
...
|
|
1590
|
+
NotImplementedError: computation of Eisenstein series in this space not yet implemented
|
|
1591
|
+
"""
|
|
1592
|
+
raise NotImplementedError("computation of Eisenstein series in this space not yet implemented")
|
|
1593
|
+
|
|
1594
|
+
def decomposition(self):
|
|
1595
|
+
"""
|
|
1596
|
+
This function returns a list of submodules `V(f_i,t)`
|
|
1597
|
+
corresponding to newforms `f_i` of some level dividing the
|
|
1598
|
+
level of self, such that the direct sum of the submodules equals
|
|
1599
|
+
self, if possible. The space `V(f_i,t)` is the image under
|
|
1600
|
+
`g(q)` maps to `g(q^t)` of the intersection with
|
|
1601
|
+
`R[[q]]` of the space spanned by the conjugates of
|
|
1602
|
+
`f_i`, where `R` is the base ring of ``self``.
|
|
1603
|
+
|
|
1604
|
+
TODO: Implement this function.
|
|
1605
|
+
|
|
1606
|
+
EXAMPLES::
|
|
1607
|
+
|
|
1608
|
+
sage: M = ModularForms(11,2); M.decomposition()
|
|
1609
|
+
Traceback (most recent call last):
|
|
1610
|
+
...
|
|
1611
|
+
NotImplementedError
|
|
1612
|
+
"""
|
|
1613
|
+
raise NotImplementedError
|
|
1614
|
+
|
|
1615
|
+
def newforms(self, names=None):
|
|
1616
|
+
"""
|
|
1617
|
+
Return all newforms in the cuspidal subspace of ``self``.
|
|
1618
|
+
|
|
1619
|
+
EXAMPLES::
|
|
1620
|
+
|
|
1621
|
+
sage: CuspForms(18,4).newforms()
|
|
1622
|
+
[q + 2*q^2 + 4*q^4 - 6*q^5 + O(q^6)]
|
|
1623
|
+
sage: CuspForms(32,4).newforms()
|
|
1624
|
+
[q - 8*q^3 - 10*q^5 + O(q^6), q + 22*q^5 + O(q^6), q + 8*q^3 - 10*q^5 + O(q^6)]
|
|
1625
|
+
sage: CuspForms(23).newforms('b')
|
|
1626
|
+
[q + b0*q^2 + (-2*b0 - 1)*q^3 + (-b0 - 1)*q^4 + 2*b0*q^5 + O(q^6)]
|
|
1627
|
+
sage: CuspForms(23).newforms()
|
|
1628
|
+
Traceback (most recent call last):
|
|
1629
|
+
...
|
|
1630
|
+
ValueError: Please specify a name to be used when generating names for generators of Hecke eigenvalue fields corresponding to the newforms.
|
|
1631
|
+
"""
|
|
1632
|
+
M = self.modular_symbols(sign=1)
|
|
1633
|
+
factors = M.cuspidal_subspace().new_subspace().decomposition()
|
|
1634
|
+
large_dims = [X.dimension() for X in factors if X.dimension() != 1]
|
|
1635
|
+
if large_dims and names is None:
|
|
1636
|
+
raise ValueError("Please specify a name to be used when generating names for generators of Hecke eigenvalue fields corresponding to the newforms.")
|
|
1637
|
+
elif names is None:
|
|
1638
|
+
# In this case, we don't need a variable name, so insert
|
|
1639
|
+
# something to get passed along below
|
|
1640
|
+
names = 'a'
|
|
1641
|
+
return [Newform(self, factors[i], names=names + str(i))
|
|
1642
|
+
for i in range(len(factors))]
|
|
1643
|
+
|
|
1644
|
+
@cached_method
|
|
1645
|
+
def eisenstein_submodule(self):
|
|
1646
|
+
"""
|
|
1647
|
+
Return the Eisenstein submodule for this space of modular forms.
|
|
1648
|
+
|
|
1649
|
+
EXAMPLES::
|
|
1650
|
+
|
|
1651
|
+
sage: M = ModularForms(11,2)
|
|
1652
|
+
sage: M.eisenstein_submodule()
|
|
1653
|
+
Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
|
|
1654
|
+
|
|
1655
|
+
We check that a bug noticed on :issue:`10450` is fixed::
|
|
1656
|
+
|
|
1657
|
+
sage: M = ModularForms(6, 10)
|
|
1658
|
+
sage: W = M.span_of_basis(M.basis()[0:2])
|
|
1659
|
+
sage: W.eisenstein_submodule()
|
|
1660
|
+
Modular Forms subspace of dimension 0 of Modular Forms space of dimension 11 for Congruence Subgroup Gamma0(6) of weight 10 over Rational Field
|
|
1661
|
+
"""
|
|
1662
|
+
if self.is_eisenstein.cache is True:
|
|
1663
|
+
return self
|
|
1664
|
+
|
|
1665
|
+
if self.is_ambient():
|
|
1666
|
+
raise NotImplementedError("ambient modular forms spaces must override eisenstein_submodule")
|
|
1667
|
+
A = self.ambient_module().eisenstein_submodule()
|
|
1668
|
+
E = self.intersection(A)
|
|
1669
|
+
if E.dimension() < self.dimension():
|
|
1670
|
+
self.is_eisenstein.set_cache(False)
|
|
1671
|
+
else:
|
|
1672
|
+
assert E.dimension() == self.dimension()
|
|
1673
|
+
self.is_eisenstein.set_cache(True)
|
|
1674
|
+
E.__is_cuspidal = (E.dimension() == 0)
|
|
1675
|
+
E.is_eisenstein.set_cache(True)
|
|
1676
|
+
return E
|
|
1677
|
+
|
|
1678
|
+
def eisenstein_subspace(self):
|
|
1679
|
+
"""
|
|
1680
|
+
Synonym for :meth:`eisenstein_submodule`.
|
|
1681
|
+
|
|
1682
|
+
EXAMPLES::
|
|
1683
|
+
|
|
1684
|
+
sage: M = ModularForms(11,2)
|
|
1685
|
+
sage: M.eisenstein_subspace()
|
|
1686
|
+
Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
|
|
1687
|
+
"""
|
|
1688
|
+
return self.eisenstein_submodule()
|
|
1689
|
+
|
|
1690
|
+
def embedded_submodule(self):
|
|
1691
|
+
"""
|
|
1692
|
+
Return the underlying module of ``self``.
|
|
1693
|
+
|
|
1694
|
+
EXAMPLES::
|
|
1695
|
+
|
|
1696
|
+
sage: N = ModularForms(6,4)
|
|
1697
|
+
sage: N.dimension()
|
|
1698
|
+
5
|
|
1699
|
+
|
|
1700
|
+
::
|
|
1701
|
+
|
|
1702
|
+
sage: N.embedded_submodule()
|
|
1703
|
+
Vector space of dimension 5 over Rational Field
|
|
1704
|
+
"""
|
|
1705
|
+
return self.free_module()
|
|
1706
|
+
|
|
1707
|
+
# intersect method commented out since it is a duplicate of the intersection method in sage.modular.hecke.submodule
|
|
1708
|
+
# -- David Loeffler, 2009-04-30
|
|
1709
|
+
#
|
|
1710
|
+
# def intersect(self, right):
|
|
1711
|
+
# """
|
|
1712
|
+
# If self and right live in the same ambient module, return the
|
|
1713
|
+
# intersection of self and right (as submodules).
|
|
1714
|
+
#
|
|
1715
|
+
# EXAMPLES::
|
|
1716
|
+
#
|
|
1717
|
+
# sage: N = ModularForms(6,4); S = N.cuspidal_subspace()
|
|
1718
|
+
#
|
|
1719
|
+
# ::
|
|
1720
|
+
#
|
|
1721
|
+
# sage: N.intersect(S)
|
|
1722
|
+
# Modular Forms subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1723
|
+
#
|
|
1724
|
+
# ::
|
|
1725
|
+
#
|
|
1726
|
+
# sage: S.intersect(N)
|
|
1727
|
+
# Modular Forms subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1728
|
+
#
|
|
1729
|
+
# ::
|
|
1730
|
+
#
|
|
1731
|
+
# sage: S.intersect(N.eisenstein_subspace())
|
|
1732
|
+
# Modular Forms subspace of dimension 0 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
|
|
1733
|
+
# """
|
|
1734
|
+
# from sage.modular.modform.all import ModularForms
|
|
1735
|
+
# if self.ambient_module() != right.ambient_module():
|
|
1736
|
+
# raise ArithmeticError("Intersection of %s and %s not defined." %
|
|
1737
|
+
# (self, right))
|
|
1738
|
+
# V = self.embedded_submodule().intersection(right.embedded_submodule())
|
|
1739
|
+
# return ModularForms(self.ambient_module(),V)
|
|
1740
|
+
# return self.span([ self(b) for b in V.basis() ])
|
|
1741
|
+
|
|
1742
|
+
# def _key(self):
|
|
1743
|
+
# if self.is_ambient():
|
|
1744
|
+
# return self.__key
|
|
1745
|
+
# return self.__ambient
|
|
1746
|
+
|
|
1747
|
+
def level(self):
|
|
1748
|
+
"""
|
|
1749
|
+
Return the level of ``self``.
|
|
1750
|
+
|
|
1751
|
+
EXAMPLES::
|
|
1752
|
+
|
|
1753
|
+
sage: M = ModularForms(47,3)
|
|
1754
|
+
sage: M.level()
|
|
1755
|
+
47
|
|
1756
|
+
"""
|
|
1757
|
+
return self.group().level()
|
|
1758
|
+
|
|
1759
|
+
def modular_symbols(self, sign=0):
|
|
1760
|
+
"""
|
|
1761
|
+
Return the space of modular symbols corresponding to ``self`` with the
|
|
1762
|
+
given sign.
|
|
1763
|
+
|
|
1764
|
+
.. NOTE::
|
|
1765
|
+
|
|
1766
|
+
This function should be overridden by all derived classes.
|
|
1767
|
+
|
|
1768
|
+
EXAMPLES::
|
|
1769
|
+
|
|
1770
|
+
sage: # needs sage.rings.number_field
|
|
1771
|
+
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11), 2, DirichletGroup(1)[0], base_ring=QQ); M.modular_symbols()
|
|
1772
|
+
Traceback (most recent call last):
|
|
1773
|
+
...
|
|
1774
|
+
NotImplementedError: computation of associated modular symbols space not yet implemented
|
|
1775
|
+
"""
|
|
1776
|
+
raise NotImplementedError("computation of associated modular symbols space not yet implemented")
|
|
1777
|
+
|
|
1778
|
+
def find_in_space(self, f, forms=None, prec=None, indep=True):
|
|
1779
|
+
"""
|
|
1780
|
+
INPUT:
|
|
1781
|
+
|
|
1782
|
+
- ``f`` -- a modular form or power series
|
|
1783
|
+
|
|
1784
|
+
- ``forms`` -- (default: ``None``) a specific list of
|
|
1785
|
+
modular forms or `q`-expansions
|
|
1786
|
+
|
|
1787
|
+
- ``prec`` -- if forms are given, compute with them to
|
|
1788
|
+
the given precision
|
|
1789
|
+
|
|
1790
|
+
- ``indep`` -- boolean (default: ``True``); whether the given list
|
|
1791
|
+
of forms are assumed to form a basis
|
|
1792
|
+
|
|
1793
|
+
OUTPUT: list of numbers that give f as a linear combination of
|
|
1794
|
+
the basis for this space or of the given forms if
|
|
1795
|
+
independent=True.
|
|
1796
|
+
|
|
1797
|
+
.. NOTE::
|
|
1798
|
+
|
|
1799
|
+
If the list of forms is given, they do *not* have to be in
|
|
1800
|
+
``self``.
|
|
1801
|
+
|
|
1802
|
+
EXAMPLES::
|
|
1803
|
+
|
|
1804
|
+
sage: M = ModularForms(11,2)
|
|
1805
|
+
sage: N = ModularForms(10,2)
|
|
1806
|
+
sage: M.find_in_space( M.basis()[0] )
|
|
1807
|
+
[1, 0]
|
|
1808
|
+
|
|
1809
|
+
::
|
|
1810
|
+
|
|
1811
|
+
sage: M.find_in_space( N.basis()[0], forms=N.basis() )
|
|
1812
|
+
[1, 0, 0]
|
|
1813
|
+
|
|
1814
|
+
::
|
|
1815
|
+
|
|
1816
|
+
sage: M.find_in_space( N.basis()[0] )
|
|
1817
|
+
Traceback (most recent call last):
|
|
1818
|
+
...
|
|
1819
|
+
ArithmeticError: vector is not in free module
|
|
1820
|
+
"""
|
|
1821
|
+
if forms is None or (forms == []):
|
|
1822
|
+
B = self._q_expansion_module()
|
|
1823
|
+
V = B.ambient_module()
|
|
1824
|
+
n = B.degree()
|
|
1825
|
+
else:
|
|
1826
|
+
if not isinstance(forms, (list, tuple)):
|
|
1827
|
+
raise TypeError("forms must be a list or tuple")
|
|
1828
|
+
if prec is None:
|
|
1829
|
+
n = forms[0].parent().prec()
|
|
1830
|
+
else:
|
|
1831
|
+
n = prec
|
|
1832
|
+
V = self.base_ring()**n
|
|
1833
|
+
w = [V(g.padded_list(n)) for g in forms]
|
|
1834
|
+
if indep:
|
|
1835
|
+
B = V.span_of_basis(w)
|
|
1836
|
+
else:
|
|
1837
|
+
B = V.span(w)
|
|
1838
|
+
if isinstance(f, PowerSeries) and f.prec() < n:
|
|
1839
|
+
raise ValueError("you need at least %s terms of precision" % n)
|
|
1840
|
+
x = V(f.padded_list(n))
|
|
1841
|
+
return B.coordinates(x)
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
def contains_each(V, B):
|
|
1845
|
+
"""
|
|
1846
|
+
Determine whether or not V contains every element of B. Used here
|
|
1847
|
+
for linear algebra, but works very generally.
|
|
1848
|
+
|
|
1849
|
+
EXAMPLES::
|
|
1850
|
+
|
|
1851
|
+
sage: contains_each = sage.modular.modform.space.contains_each
|
|
1852
|
+
sage: contains_each( range(20), prime_range(20) )
|
|
1853
|
+
True
|
|
1854
|
+
sage: contains_each( range(20), range(30) )
|
|
1855
|
+
False
|
|
1856
|
+
"""
|
|
1857
|
+
for b in B:
|
|
1858
|
+
if b not in V:
|
|
1859
|
+
return False
|
|
1860
|
+
return True
|