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,828 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.combinat
|
|
3
|
+
r"""
|
|
4
|
+
Graded quasimodular forms ring
|
|
5
|
+
|
|
6
|
+
Let `E_2` be the weight 2 Eisenstein series defined by
|
|
7
|
+
|
|
8
|
+
.. MATH::
|
|
9
|
+
|
|
10
|
+
E_2(z) = 1 - 24 \sum_{n=1}^{\infty} \sigma(n) q^n
|
|
11
|
+
|
|
12
|
+
where `\sigma` is the sum of divisors function and `q = \mathrm{exp}(2\pi i z)`
|
|
13
|
+
is the classical parameter at infinity, with `\mathrm{im}(z)>0`. This weight 2
|
|
14
|
+
Eisenstein series is not a modular form as it does not satisfy the
|
|
15
|
+
modularity condition:
|
|
16
|
+
|
|
17
|
+
.. MATH::
|
|
18
|
+
|
|
19
|
+
z^2 E_2(-1/z) = E_2(z) + \frac{6}{\pi i z}.
|
|
20
|
+
|
|
21
|
+
`E_2` is a quasimodular form of weight 2. General quasimodular forms of given
|
|
22
|
+
weight can also be defined. We denote by `QM` the graded ring of quasimodular
|
|
23
|
+
forms for the full modular group `\SL_2(\ZZ)`.
|
|
24
|
+
|
|
25
|
+
The SageMath implementation of the graded ring of quasimodular forms uses the
|
|
26
|
+
following isomorphism:
|
|
27
|
+
|
|
28
|
+
.. MATH::
|
|
29
|
+
|
|
30
|
+
QM \cong M_* [E_2]
|
|
31
|
+
|
|
32
|
+
where `M_* \cong \CC[E_4, E_6]` is the graded ring of modular forms for
|
|
33
|
+
`\SL_2(\ZZ)`. (see :class:`sage.modular.modform.ring.ModularFormsRing`).
|
|
34
|
+
|
|
35
|
+
More generally, if `\Gamma \leq \SL_2(\ZZ)` is a congruence subgroup,
|
|
36
|
+
then the graded ring of quasimodular forms for `\Gamma` is given by
|
|
37
|
+
`M_*(\Gamma)[E_2]` where `M_*(\Gamma)` is the ring of modular forms for
|
|
38
|
+
`\Gamma`.
|
|
39
|
+
|
|
40
|
+
The SageMath implementation of the graded quasimodular forms ring allows
|
|
41
|
+
computation of a set of generators and perform usual arithmetic operations.
|
|
42
|
+
|
|
43
|
+
EXAMPLES::
|
|
44
|
+
|
|
45
|
+
sage: QM = QuasiModularForms(1); QM
|
|
46
|
+
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
|
|
47
|
+
sage: QM.category()
|
|
48
|
+
Category of commutative graded algebras over Rational Field
|
|
49
|
+
sage: QM.gens()
|
|
50
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
51
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
|
|
52
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6))
|
|
53
|
+
sage: E2 = QM.0; E4 = QM.1; E6 = QM.2
|
|
54
|
+
sage: E2 * E4 + E6
|
|
55
|
+
2 - 288*q - 20304*q^2 - 185472*q^3 - 855216*q^4 - 2697408*q^5 + O(q^6)
|
|
56
|
+
sage: E2.parent()
|
|
57
|
+
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
|
|
58
|
+
|
|
59
|
+
The ``polygen`` method also return the weight-2 Eisenstein series as a
|
|
60
|
+
polynomial variable over the ring of modular forms::
|
|
61
|
+
|
|
62
|
+
sage: QM = QuasiModularForms(1)
|
|
63
|
+
sage: E2 = QM.polygen(); E2
|
|
64
|
+
E2
|
|
65
|
+
sage: E2.parent()
|
|
66
|
+
Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
|
|
67
|
+
|
|
68
|
+
An element of a ring of quasimodular forms can be created via a list of modular
|
|
69
|
+
forms or graded modular forms. The `i`-th index of the list will correspond to
|
|
70
|
+
the `i`-th coefficient of the polynomial in `E_2`::
|
|
71
|
+
|
|
72
|
+
sage: QM = QuasiModularForms(1)
|
|
73
|
+
sage: E2 = QM.0
|
|
74
|
+
sage: Delta = CuspForms(1, 12).0
|
|
75
|
+
sage: E4 = ModularForms(1, 4).0
|
|
76
|
+
sage: F = QM([Delta, E4, Delta + E4]); F
|
|
77
|
+
2 + 410*q - 12696*q^2 - 50424*q^3 + 1076264*q^4 + 10431996*q^5 + O(q^6)
|
|
78
|
+
sage: F == Delta + E4 * E2 + (Delta + E4) * E2^2
|
|
79
|
+
True
|
|
80
|
+
|
|
81
|
+
One may also create rings of quasimodular forms for certain congruence subgroups::
|
|
82
|
+
|
|
83
|
+
sage: QM = QuasiModularForms(Gamma0(5)); QM
|
|
84
|
+
Ring of Quasimodular Forms for Congruence Subgroup Gamma0(5) over Rational Field
|
|
85
|
+
sage: QM.ngens()
|
|
86
|
+
4
|
|
87
|
+
|
|
88
|
+
The first generator is the weight 2 Eisenstein series::
|
|
89
|
+
|
|
90
|
+
sage: E2 = QM.0; E2
|
|
91
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
92
|
+
|
|
93
|
+
The other generators correspond to the generators given by the method
|
|
94
|
+
:meth:`sage.modular.modform.ring.ModularFormsRing.gens`::
|
|
95
|
+
|
|
96
|
+
sage: QM.gens()
|
|
97
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
98
|
+
1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
|
|
99
|
+
1 + 240*q^5 + O(q^6),
|
|
100
|
+
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
|
|
101
|
+
sage: QM.modular_forms_subring().gens()
|
|
102
|
+
[1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
|
|
103
|
+
1 + 240*q^5 + O(q^6),
|
|
104
|
+
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6)]
|
|
105
|
+
|
|
106
|
+
It is possible to convert a graded quasimodular form into a polynomial where
|
|
107
|
+
each variable corresponds to a generator of the ring::
|
|
108
|
+
|
|
109
|
+
sage: QM = QuasiModularForms(1)
|
|
110
|
+
sage: E2, E4, E6 = QM.gens()
|
|
111
|
+
sage: F = E2*E4*E6 + E6^2; F
|
|
112
|
+
2 - 1296*q + 91584*q^2 + 14591808*q^3 + 464670432*q^4 + 6160281120*q^5 + O(q^6)
|
|
113
|
+
sage: p = F.polynomial('E2, E4, E6'); p
|
|
114
|
+
E2*E4*E6 + E6^2
|
|
115
|
+
sage: P = p.parent(); P
|
|
116
|
+
Multivariate Polynomial Ring in E2, E4, E6 over Rational Field
|
|
117
|
+
|
|
118
|
+
The generators of the polynomial ring have degree equal to the weight of the
|
|
119
|
+
corresponding form::
|
|
120
|
+
|
|
121
|
+
sage: P.inject_variables()
|
|
122
|
+
Defining E2, E4, E6
|
|
123
|
+
sage: E2.degree()
|
|
124
|
+
2
|
|
125
|
+
sage: E4.degree()
|
|
126
|
+
4
|
|
127
|
+
sage: E6.degree()
|
|
128
|
+
6
|
|
129
|
+
|
|
130
|
+
This works also for congruence subgroup::
|
|
131
|
+
|
|
132
|
+
sage: QM = QuasiModularForms(Gamma1(4))
|
|
133
|
+
sage: QM.ngens()
|
|
134
|
+
5
|
|
135
|
+
sage: QM.polynomial_ring()
|
|
136
|
+
Multivariate Polynomial Ring in E2, E2_0, E2_1, E3_0, E3_1 over Rational Field
|
|
137
|
+
sage: (QM.0 + QM.1*QM.0^2 + QM.3 + QM.4^3).polynomial()
|
|
138
|
+
E3_1^3 + E2^2*E2_0 + E3_0 + E2
|
|
139
|
+
|
|
140
|
+
One can also convert a multivariate polynomial into a quasimodular form::
|
|
141
|
+
|
|
142
|
+
sage: QM.polynomial_ring().inject_variables()
|
|
143
|
+
Defining E2, E2_0, E2_1, E3_0, E3_1
|
|
144
|
+
sage: QM.from_polynomial(E3_1^3 + E2^2*E2_0 + E3_0 + E2)
|
|
145
|
+
3 - 72*q + 396*q^2 + 2081*q^3 + 19752*q^4 + 98712*q^5 + O(q^6)
|
|
146
|
+
|
|
147
|
+
.. NOTE::
|
|
148
|
+
|
|
149
|
+
- Currently, the only supported base ring is the Rational Field;
|
|
150
|
+
- Spaces of quasimodular forms of fixed weight are not yet implemented.
|
|
151
|
+
|
|
152
|
+
REFERENCE:
|
|
153
|
+
|
|
154
|
+
See section 5.3 (page 58) of [Zag2008]_
|
|
155
|
+
|
|
156
|
+
AUTHORS:
|
|
157
|
+
|
|
158
|
+
- David Ayotte (2021-03-18): initial version
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
# ****************************************************************************
|
|
162
|
+
# Copyright (C) 2021 DAVID AYOTTE
|
|
163
|
+
#
|
|
164
|
+
# This program is free software: you can redistribute it and/or modify
|
|
165
|
+
# it under the terms of the GNU General Public License as published by
|
|
166
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
167
|
+
# (at your option) any later version.
|
|
168
|
+
# https://www.gnu.org/licenses/
|
|
169
|
+
# ****************************************************************************
|
|
170
|
+
|
|
171
|
+
from itertools import product, chain
|
|
172
|
+
|
|
173
|
+
from sage.categories.graded_algebras import GradedAlgebras
|
|
174
|
+
|
|
175
|
+
from sage.modular.arithgroup.congroup_gamma0 import Gamma0_constructor as Gamma0
|
|
176
|
+
from sage.modular.arithgroup.congroup_generic import CongruenceSubgroupBase
|
|
177
|
+
from sage.modular.modform.element import GradedModularFormElement, ModularFormElement
|
|
178
|
+
from sage.modular.modform.space import ModularFormsSpace
|
|
179
|
+
from sage.modular.modform.ring import ModularFormsRing
|
|
180
|
+
|
|
181
|
+
from sage.rings.integer import Integer
|
|
182
|
+
from sage.rings.polynomial.multi_polynomial import MPolynomial
|
|
183
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
184
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
185
|
+
from sage.rings.polynomial.term_order import TermOrder
|
|
186
|
+
from sage.rings.power_series_poly import PowerSeries_poly
|
|
187
|
+
from sage.rings.rational_field import QQ
|
|
188
|
+
|
|
189
|
+
from sage.structure.parent import Parent
|
|
190
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
191
|
+
|
|
192
|
+
from .element import QuasiModularFormsElement
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class QuasiModularForms(Parent, UniqueRepresentation):
|
|
196
|
+
r"""
|
|
197
|
+
The graded ring of quasimodular forms for the full modular group
|
|
198
|
+
`\SL_2(\ZZ)`, with coefficients in a ring.
|
|
199
|
+
|
|
200
|
+
EXAMPLES::
|
|
201
|
+
|
|
202
|
+
sage: QM = QuasiModularForms(1); QM
|
|
203
|
+
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
|
|
204
|
+
sage: QM.gens()
|
|
205
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
206
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
|
|
207
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6))
|
|
208
|
+
|
|
209
|
+
It is possible to access the weight 2 Eisenstein series::
|
|
210
|
+
|
|
211
|
+
sage: QM.weight_2_eisenstein_series()
|
|
212
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
213
|
+
|
|
214
|
+
Currently, the only supported base ring is the rational numbers::
|
|
215
|
+
|
|
216
|
+
sage: QuasiModularForms(1, GF(5))
|
|
217
|
+
Traceback (most recent call last):
|
|
218
|
+
...
|
|
219
|
+
NotImplementedError: base ring other than Q are not yet supported for quasimodular forms ring
|
|
220
|
+
"""
|
|
221
|
+
Element = QuasiModularFormsElement
|
|
222
|
+
|
|
223
|
+
def __init__(self, group=1, base_ring=QQ, name='E2'):
|
|
224
|
+
r"""
|
|
225
|
+
INPUT:
|
|
226
|
+
|
|
227
|
+
- ``group`` -- (default: `\SL_2(\ZZ)`) a congruence subgroup of
|
|
228
|
+
`\SL_2(\ZZ)`, or a positive integer `N` (interpreted as
|
|
229
|
+
`\Gamma_0(N)`)
|
|
230
|
+
|
|
231
|
+
- ``base_ring`` -- a base ring (default: `\QQ`); should be
|
|
232
|
+
`\QQ`, `\ZZ`, or the integers mod `p` for some prime `p`
|
|
233
|
+
|
|
234
|
+
- ``name`` -- string (default: ``'E2'``); a variable name corresponding to
|
|
235
|
+
the weight 2 Eisenstein series
|
|
236
|
+
|
|
237
|
+
TESTS:
|
|
238
|
+
|
|
239
|
+
sage: M = QuasiModularForms(1)
|
|
240
|
+
sage: M.group()
|
|
241
|
+
Modular Group SL(2,Z)
|
|
242
|
+
sage: M.base_ring()
|
|
243
|
+
Rational Field
|
|
244
|
+
sage: QuasiModularForms(Integers(5))
|
|
245
|
+
Traceback (most recent call last):
|
|
246
|
+
...
|
|
247
|
+
ValueError: Group (=Ring of integers modulo 5) should be a congruence subgroup
|
|
248
|
+
|
|
249
|
+
::
|
|
250
|
+
|
|
251
|
+
sage: TestSuite(QuasiModularForms(1)).run()
|
|
252
|
+
sage: TestSuite(QuasiModularForms(Gamma0(3))).run()
|
|
253
|
+
sage: TestSuite(QuasiModularForms(Gamma1(3))).run()
|
|
254
|
+
"""
|
|
255
|
+
if not isinstance(name, str):
|
|
256
|
+
raise TypeError("`name` must be a string")
|
|
257
|
+
# check if the group is SL2(Z)
|
|
258
|
+
if isinstance(group, (int, Integer)):
|
|
259
|
+
group = Gamma0(group)
|
|
260
|
+
elif not isinstance(group, CongruenceSubgroupBase):
|
|
261
|
+
raise ValueError("Group (=%s) should be a congruence subgroup" % group)
|
|
262
|
+
|
|
263
|
+
# Check if the base ring is the rational field
|
|
264
|
+
if base_ring != QQ:
|
|
265
|
+
raise NotImplementedError("base ring other than Q are not yet supported for quasimodular forms ring")
|
|
266
|
+
|
|
267
|
+
self.__group = group
|
|
268
|
+
self.__modular_forms_subring = ModularFormsRing(group, base_ring)
|
|
269
|
+
self.__polynomial_subring = self.__modular_forms_subring[name]
|
|
270
|
+
cat = GradedAlgebras(base_ring).Commutative()
|
|
271
|
+
Parent.__init__(self, base=base_ring, category=cat)
|
|
272
|
+
|
|
273
|
+
def group(self):
|
|
274
|
+
r"""
|
|
275
|
+
Return the congruence subgroup attached to the given quasimodular forms
|
|
276
|
+
ring.
|
|
277
|
+
|
|
278
|
+
EXAMPLES::
|
|
279
|
+
|
|
280
|
+
sage: QM = QuasiModularForms(1)
|
|
281
|
+
sage: QM.group()
|
|
282
|
+
Modular Group SL(2,Z)
|
|
283
|
+
sage: QM.group() is SL2Z
|
|
284
|
+
True
|
|
285
|
+
sage: QuasiModularForms(3).group()
|
|
286
|
+
Congruence Subgroup Gamma0(3)
|
|
287
|
+
sage: QuasiModularForms(Gamma1(5)).group()
|
|
288
|
+
Congruence Subgroup Gamma1(5)
|
|
289
|
+
"""
|
|
290
|
+
return self.__group
|
|
291
|
+
|
|
292
|
+
def modular_forms_subring(self):
|
|
293
|
+
r"""
|
|
294
|
+
Return the subring of modular forms of this ring of quasimodular forms.
|
|
295
|
+
|
|
296
|
+
EXAMPLES::
|
|
297
|
+
|
|
298
|
+
sage: QuasiModularForms(1).modular_forms_subring()
|
|
299
|
+
Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
|
|
300
|
+
sage: QuasiModularForms(5).modular_forms_subring()
|
|
301
|
+
Ring of Modular Forms for Congruence Subgroup Gamma0(5) over Rational Field
|
|
302
|
+
"""
|
|
303
|
+
return self.__modular_forms_subring
|
|
304
|
+
|
|
305
|
+
def modular_forms_of_weight(self, weight):
|
|
306
|
+
r"""
|
|
307
|
+
Return the space of modular forms on this group of the given weight.
|
|
308
|
+
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: QM = QuasiModularForms(1)
|
|
312
|
+
sage: QM.modular_forms_of_weight(12)
|
|
313
|
+
Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
|
|
314
|
+
sage: QM = QuasiModularForms(Gamma1(3))
|
|
315
|
+
sage: QM.modular_forms_of_weight(4)
|
|
316
|
+
Modular Forms space of dimension 2 for Congruence Subgroup Gamma1(3) of weight 4 over Rational Field
|
|
317
|
+
"""
|
|
318
|
+
return self.__modular_forms_subring.modular_forms_of_weight(weight)
|
|
319
|
+
|
|
320
|
+
def quasimodular_forms_of_weight(self, weight):
|
|
321
|
+
r"""
|
|
322
|
+
Return the space of quasimodular forms on this group of the given weight.
|
|
323
|
+
|
|
324
|
+
INPUT:
|
|
325
|
+
|
|
326
|
+
- ``weight`` -- integer
|
|
327
|
+
|
|
328
|
+
OUTPUT: a quasimodular forms space of the given weight
|
|
329
|
+
|
|
330
|
+
EXAMPLES::
|
|
331
|
+
|
|
332
|
+
sage: QuasiModularForms(1).quasimodular_forms_of_weight(4)
|
|
333
|
+
Traceback (most recent call last):
|
|
334
|
+
...
|
|
335
|
+
NotImplementedError: spaces of quasimodular forms of fixed weight not yet implemented
|
|
336
|
+
"""
|
|
337
|
+
raise NotImplementedError("spaces of quasimodular forms of fixed weight not yet implemented")
|
|
338
|
+
|
|
339
|
+
def _repr_(self):
|
|
340
|
+
r"""
|
|
341
|
+
String representation of ``self``.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: QuasiModularForms(1)._repr_()
|
|
346
|
+
'Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field'
|
|
347
|
+
"""
|
|
348
|
+
return "Ring of Quasimodular Forms for %s over %s" % (self.group(), self.base_ring())
|
|
349
|
+
|
|
350
|
+
def _coerce_map_from_(self, M):
|
|
351
|
+
r"""
|
|
352
|
+
Code to make QuasiModularForms work well with coercion framework.
|
|
353
|
+
|
|
354
|
+
TESTS::
|
|
355
|
+
|
|
356
|
+
sage: E2 = QuasiModularForms(1).0
|
|
357
|
+
sage: M = ModularFormsRing(1)
|
|
358
|
+
sage: E2 + M.0
|
|
359
|
+
2 + 216*q + 2088*q^2 + 6624*q^3 + 17352*q^4 + 30096*q^5 + O(q^6)
|
|
360
|
+
sage: M.0 + E2
|
|
361
|
+
2 + 216*q + 2088*q^2 + 6624*q^3 + 17352*q^4 + 30096*q^5 + O(q^6)
|
|
362
|
+
sage: 1 + E2
|
|
363
|
+
2 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
364
|
+
sage: E2 + 1
|
|
365
|
+
2 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
366
|
+
sage: f = ModularForms(1, 12).0
|
|
367
|
+
sage: E2 + f
|
|
368
|
+
1 - 23*q - 96*q^2 + 156*q^3 - 1640*q^4 + 4686*q^5 + O(q^6)
|
|
369
|
+
sage: f + E2
|
|
370
|
+
1 - 23*q - 96*q^2 + 156*q^3 - 1640*q^4 + 4686*q^5 + O(q^6)
|
|
371
|
+
"""
|
|
372
|
+
if isinstance(M, (ModularFormsRing, ModularFormsSpace)):
|
|
373
|
+
if M.group() == self.group() and self.has_coerce_map_from(M.base_ring()):
|
|
374
|
+
return True
|
|
375
|
+
if self.base_ring().has_coerce_map_from(M):
|
|
376
|
+
return True
|
|
377
|
+
return False
|
|
378
|
+
|
|
379
|
+
def _element_constructor_(self, datum):
|
|
380
|
+
r"""
|
|
381
|
+
The call method of ``self``.
|
|
382
|
+
|
|
383
|
+
INPUT:
|
|
384
|
+
|
|
385
|
+
- ``datum`` -- list; GradedModularFormElement, ModularFormElement,
|
|
386
|
+
Polynomial, base ring element
|
|
387
|
+
|
|
388
|
+
OUTPUT: QuasiModularFormElement
|
|
389
|
+
|
|
390
|
+
TESTS::
|
|
391
|
+
|
|
392
|
+
sage: QM = QuasiModularForms(1)
|
|
393
|
+
sage: M = QM.modular_forms_subring()
|
|
394
|
+
sage: m12 = QM.modular_forms_of_weight(12)
|
|
395
|
+
sage: QM([M.0, M.1])
|
|
396
|
+
2 - 288*q - 2448*q^2 + 319104*q^3 + 3681936*q^4 + 21775680*q^5 + O(q^6)
|
|
397
|
+
sage: QM([m12.0, m12.1])
|
|
398
|
+
1 + 49627/691*q + 132611664/691*q^2 + 8380115796/691*q^3 - 13290096200/691*q^4 - 4248043226454/691*q^5 + O(q^6)
|
|
399
|
+
sage: QM([])
|
|
400
|
+
Traceback (most recent call last):
|
|
401
|
+
...
|
|
402
|
+
ValueError: the given list should be non-empty
|
|
403
|
+
sage: QM(M.0)
|
|
404
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
|
|
405
|
+
sage: QM(m12.0)
|
|
406
|
+
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
|
|
407
|
+
sage: y = polygen(QQ)
|
|
408
|
+
sage: QM(y)
|
|
409
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
410
|
+
sage: QM(1 + y + y^2)
|
|
411
|
+
3 - 72*q + 360*q^2 + 3168*q^3 + 9288*q^4 + 21456*q^5 + O(q^6)
|
|
412
|
+
sage: QM(1)
|
|
413
|
+
1
|
|
414
|
+
sage: QM(1/2)
|
|
415
|
+
1/2
|
|
416
|
+
sage: QM('E2')
|
|
417
|
+
Traceback (most recent call last):
|
|
418
|
+
...
|
|
419
|
+
TypeError: no canonical coercion from <class 'str'> to Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
|
|
420
|
+
sage: P.<q> = PowerSeriesRing(QQ)
|
|
421
|
+
sage: QM(1 - 24 * q - 72 * q^2 - 96 * q^3 + O(q^4))
|
|
422
|
+
Traceback (most recent call last):
|
|
423
|
+
...
|
|
424
|
+
NotImplementedError: conversion from q-expansion not yet implemented
|
|
425
|
+
"""
|
|
426
|
+
if isinstance(datum, list):
|
|
427
|
+
if not datum:
|
|
428
|
+
raise ValueError("the given list should be non-empty")
|
|
429
|
+
for idx, f in enumerate(datum):
|
|
430
|
+
if not isinstance(f, (GradedModularFormElement, ModularFormElement)):
|
|
431
|
+
raise ValueError("one list element is not a modular form")
|
|
432
|
+
datum[idx] = self.__modular_forms_subring(f) # to ensure that every form is a GradedModularFormElement
|
|
433
|
+
datum = self.__polynomial_subring(datum)
|
|
434
|
+
elif isinstance(datum, (GradedModularFormElement, ModularFormElement)):
|
|
435
|
+
datum = self.__modular_forms_subring(datum) # GradedModularFormElement
|
|
436
|
+
datum = self.__polynomial_subring(datum)
|
|
437
|
+
elif isinstance(datum, Polynomial):
|
|
438
|
+
datum = self.__polynomial_subring(datum.coefficients(sparse=False))
|
|
439
|
+
elif isinstance(datum, PowerSeries_poly):
|
|
440
|
+
raise NotImplementedError("conversion from q-expansion not yet implemented")
|
|
441
|
+
else:
|
|
442
|
+
datum = self.__polynomial_subring.coerce(datum)
|
|
443
|
+
return self.element_class(self, datum)
|
|
444
|
+
|
|
445
|
+
def weight_2_eisenstein_series(self):
|
|
446
|
+
r"""
|
|
447
|
+
Return the weight 2 Eisenstein series.
|
|
448
|
+
|
|
449
|
+
EXAMPLES::
|
|
450
|
+
|
|
451
|
+
sage: QM = QuasiModularForms(1)
|
|
452
|
+
sage: E2 = QM.weight_2_eisenstein_series(); E2
|
|
453
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
454
|
+
sage: E2.parent()
|
|
455
|
+
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
|
|
456
|
+
"""
|
|
457
|
+
return self(self.__polynomial_subring.gen())
|
|
458
|
+
|
|
459
|
+
def gens(self) -> tuple:
|
|
460
|
+
r"""
|
|
461
|
+
Return a tuple of generators of the quasimodular forms ring.
|
|
462
|
+
|
|
463
|
+
Note that the generators of the modular forms subring are the one given
|
|
464
|
+
by the method :meth:`sage.modular.modform.ring.ModularFormsRing.gen_forms`
|
|
465
|
+
|
|
466
|
+
EXAMPLES::
|
|
467
|
+
|
|
468
|
+
sage: QM = QuasiModularForms(1)
|
|
469
|
+
sage: QM.gens()
|
|
470
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
471
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
|
|
472
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6))
|
|
473
|
+
sage: QM.modular_forms_subring().gen_forms()
|
|
474
|
+
[1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
|
|
475
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)]
|
|
476
|
+
sage: QM = QuasiModularForms(5)
|
|
477
|
+
sage: QM.gens()
|
|
478
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
479
|
+
1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
|
|
480
|
+
1 + 240*q^5 + O(q^6),
|
|
481
|
+
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
|
|
482
|
+
|
|
483
|
+
An alias of this method is ``generators``::
|
|
484
|
+
|
|
485
|
+
sage: QuasiModularForms(1).generators()
|
|
486
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
487
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
|
|
488
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6))
|
|
489
|
+
"""
|
|
490
|
+
gen_list = [self.weight_2_eisenstein_series()]
|
|
491
|
+
gen_list.extend(self(f)
|
|
492
|
+
for f in self.__modular_forms_subring.gen_forms())
|
|
493
|
+
return tuple(gen_list)
|
|
494
|
+
|
|
495
|
+
generators = gens # alias
|
|
496
|
+
|
|
497
|
+
def ngens(self):
|
|
498
|
+
r"""
|
|
499
|
+
Return the number of generators of the given graded quasimodular forms
|
|
500
|
+
ring.
|
|
501
|
+
|
|
502
|
+
EXAMPLES::
|
|
503
|
+
|
|
504
|
+
sage: QuasiModularForms(1).ngens()
|
|
505
|
+
3
|
|
506
|
+
"""
|
|
507
|
+
return len(self.gens())
|
|
508
|
+
|
|
509
|
+
def gen(self, n):
|
|
510
|
+
r"""
|
|
511
|
+
Return the `n`-th generator of the quasimodular forms ring.
|
|
512
|
+
|
|
513
|
+
EXAMPLES::
|
|
514
|
+
|
|
515
|
+
sage: QM = QuasiModularForms(1)
|
|
516
|
+
sage: QM.0
|
|
517
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
518
|
+
sage: QM.1
|
|
519
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
|
|
520
|
+
sage: QM.2
|
|
521
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)
|
|
522
|
+
sage: QM = QuasiModularForms(5)
|
|
523
|
+
sage: QM.0
|
|
524
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
525
|
+
sage: QM.1
|
|
526
|
+
1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6)
|
|
527
|
+
sage: QM.2
|
|
528
|
+
1 + 240*q^5 + O(q^6)
|
|
529
|
+
sage: QM.3
|
|
530
|
+
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6)
|
|
531
|
+
sage: QM.4
|
|
532
|
+
Traceback (most recent call last):
|
|
533
|
+
...
|
|
534
|
+
IndexError: tuple index out of range
|
|
535
|
+
"""
|
|
536
|
+
return self.gens()[n]
|
|
537
|
+
|
|
538
|
+
def zero(self):
|
|
539
|
+
r"""
|
|
540
|
+
Return the zero element of this ring.
|
|
541
|
+
|
|
542
|
+
EXAMPLES::
|
|
543
|
+
|
|
544
|
+
sage: QM = QuasiModularForms(1)
|
|
545
|
+
sage: QM.zero()
|
|
546
|
+
0
|
|
547
|
+
sage: QM.zero().is_zero()
|
|
548
|
+
True
|
|
549
|
+
"""
|
|
550
|
+
return self.element_class(self, self.__polynomial_subring.zero())
|
|
551
|
+
|
|
552
|
+
def one(self):
|
|
553
|
+
r"""
|
|
554
|
+
Return the one element of this ring.
|
|
555
|
+
|
|
556
|
+
EXAMPLES::
|
|
557
|
+
|
|
558
|
+
sage: QM = QuasiModularForms(1)
|
|
559
|
+
sage: QM.one()
|
|
560
|
+
1
|
|
561
|
+
sage: QM.one().is_one()
|
|
562
|
+
True
|
|
563
|
+
"""
|
|
564
|
+
return self.element_class(self, self.__polynomial_subring.one())
|
|
565
|
+
|
|
566
|
+
def some_elements(self):
|
|
567
|
+
r"""
|
|
568
|
+
Return a list of generators of ``self``.
|
|
569
|
+
|
|
570
|
+
EXAMPLES::
|
|
571
|
+
|
|
572
|
+
sage: QuasiModularForms(1).some_elements()
|
|
573
|
+
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
|
|
574
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
|
|
575
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6))
|
|
576
|
+
"""
|
|
577
|
+
return self.gens()
|
|
578
|
+
|
|
579
|
+
def polygen(self):
|
|
580
|
+
r"""
|
|
581
|
+
Return the generator of this quasimodular form space as a polynomial
|
|
582
|
+
ring over the modular form subring.
|
|
583
|
+
|
|
584
|
+
Note that this generator correspond to the weight-2 Eisenstein series.
|
|
585
|
+
The default name of this generator is ``E2``.
|
|
586
|
+
|
|
587
|
+
EXAMPLES::
|
|
588
|
+
|
|
589
|
+
sage: QM = QuasiModularForms(1)
|
|
590
|
+
sage: QM.polygen()
|
|
591
|
+
E2
|
|
592
|
+
sage: QuasiModularForms(1, name='X').polygen()
|
|
593
|
+
X
|
|
594
|
+
sage: QM.polygen().parent()
|
|
595
|
+
Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
|
|
596
|
+
"""
|
|
597
|
+
return self.__polynomial_subring.gen()
|
|
598
|
+
|
|
599
|
+
def polynomial_ring(self, names=None):
|
|
600
|
+
r"""
|
|
601
|
+
Return a multivariate polynomial ring of which the quasimodular forms
|
|
602
|
+
ring is a quotient.
|
|
603
|
+
|
|
604
|
+
In the case of the full modular group, this ring is `R[E_2, E_4, E_6]`
|
|
605
|
+
where `E_2`, `E_4` and `E_6` have degrees 2, 4 and 6 respectively.
|
|
606
|
+
|
|
607
|
+
INPUT:
|
|
608
|
+
|
|
609
|
+
- ``names``-- string (default: ``None``); list or tuple of names
|
|
610
|
+
(strings), or a comma separated string. Defines the names for the
|
|
611
|
+
generators of the multivariate polynomial ring. The default names are
|
|
612
|
+
of the following form:
|
|
613
|
+
|
|
614
|
+
- ``E2`` denotes the weight 2 Eisenstein series;
|
|
615
|
+
|
|
616
|
+
- ``Ek_i`` and ``Sk_i`` denote the `i`-th basis element of the weight
|
|
617
|
+
`k` Eisenstein subspace and cuspidal subspace respectively;
|
|
618
|
+
|
|
619
|
+
- If the level is one, the default names are ``E2``, ``E4`` and
|
|
620
|
+
``E6``;
|
|
621
|
+
|
|
622
|
+
- In any other cases, we use the letters ``Fk``, ``Gk``, ``Hk``, ...,
|
|
623
|
+
``FFk``, ``FGk``, ... to denote any generator of weight `k`.
|
|
624
|
+
|
|
625
|
+
OUTPUT: a multivariate polynomial ring in the variables ``names``
|
|
626
|
+
|
|
627
|
+
EXAMPLES::
|
|
628
|
+
|
|
629
|
+
sage: QM = QuasiModularForms(1)
|
|
630
|
+
sage: P = QM.polynomial_ring(); P
|
|
631
|
+
Multivariate Polynomial Ring in E2, E4, E6 over Rational Field
|
|
632
|
+
sage: P.inject_variables()
|
|
633
|
+
Defining E2, E4, E6
|
|
634
|
+
sage: E2.degree()
|
|
635
|
+
2
|
|
636
|
+
sage: E4.degree()
|
|
637
|
+
4
|
|
638
|
+
sage: E6.degree()
|
|
639
|
+
6
|
|
640
|
+
|
|
641
|
+
Example when the level is not one::
|
|
642
|
+
|
|
643
|
+
sage: QM = QuasiModularForms(Gamma0(29))
|
|
644
|
+
sage: P_29 = QM.polynomial_ring()
|
|
645
|
+
sage: P_29
|
|
646
|
+
Multivariate Polynomial Ring in E2, F2, S2_0, S2_1, E4_0, F4, G4, H4 over Rational Field
|
|
647
|
+
sage: P_29.inject_variables()
|
|
648
|
+
Defining E2, F2, S2_0, S2_1, E4_0, F4, G4, H4
|
|
649
|
+
sage: F2.degree()
|
|
650
|
+
2
|
|
651
|
+
sage: E4_0.degree()
|
|
652
|
+
4
|
|
653
|
+
|
|
654
|
+
The name ``Sk_i`` stands for the `i`-th basis element of the cuspidal subspace of weight `k`::
|
|
655
|
+
|
|
656
|
+
sage: F2 = QM.from_polynomial(S2_0)
|
|
657
|
+
sage: F2.qexp(10)
|
|
658
|
+
q - q^4 - q^5 - q^6 + 2*q^7 - 2*q^8 - 2*q^9 + O(q^10)
|
|
659
|
+
sage: CuspForms(Gamma0(29), 2).0.qexp(10)
|
|
660
|
+
q - q^4 - q^5 - q^6 + 2*q^7 - 2*q^8 - 2*q^9 + O(q^10)
|
|
661
|
+
sage: F2 == CuspForms(Gamma0(29), 2).0
|
|
662
|
+
True
|
|
663
|
+
|
|
664
|
+
The name ``Ek_i`` stands for the `i`-th basis element of the Eisenstein subspace of weight `k`::
|
|
665
|
+
|
|
666
|
+
sage: F4 = QM.from_polynomial(E4_0)
|
|
667
|
+
sage: F4.qexp(30)
|
|
668
|
+
1 + 240*q^29 + O(q^30)
|
|
669
|
+
sage: EisensteinForms(Gamma0(29), 4).0.qexp(30)
|
|
670
|
+
1 + 240*q^29 + O(q^30)
|
|
671
|
+
sage: F4 == EisensteinForms(Gamma0(29), 4).0
|
|
672
|
+
True
|
|
673
|
+
|
|
674
|
+
One may also choose the name of the variables::
|
|
675
|
+
|
|
676
|
+
sage: QM = QuasiModularForms(1)
|
|
677
|
+
sage: QM.polynomial_ring(names="P, Q, R")
|
|
678
|
+
Multivariate Polynomial Ring in P, Q, R over Rational Field
|
|
679
|
+
"""
|
|
680
|
+
gens = self.__modular_forms_subring.gen_forms()
|
|
681
|
+
weights = [f.weight() for f in gens]
|
|
682
|
+
gens = iter(gens)
|
|
683
|
+
if names is None:
|
|
684
|
+
if self.group() == Gamma0(1):
|
|
685
|
+
names = ["E2", "E4", "E6"]
|
|
686
|
+
else:
|
|
687
|
+
names = ["E2"]
|
|
688
|
+
letters = "FGHIJK"
|
|
689
|
+
for unique_weight in set(weights):
|
|
690
|
+
same_weights = [k for k in weights if k == unique_weight]
|
|
691
|
+
# create all the names of the form:
|
|
692
|
+
# F, G, H, I, J, K, FF, FG, FH,..., FFF, FFG,...
|
|
693
|
+
# the letters E and S are reserved for basis elements of the
|
|
694
|
+
# Eisenstein subspaces and cuspidal subspaces respectively.
|
|
695
|
+
iter_names = (product(letters, repeat=r)
|
|
696
|
+
for r in range(1, len(same_weights)//len(letters) + 2))
|
|
697
|
+
iter_names = chain(*iter_names)
|
|
698
|
+
for k in same_weights:
|
|
699
|
+
form = next(gens)
|
|
700
|
+
Mk = self.__modular_forms_subring.modular_forms_of_weight(k)
|
|
701
|
+
if form.is_eisenstein():
|
|
702
|
+
Ek_basis = Mk.eisenstein_subspace().basis()
|
|
703
|
+
# check if form is a basis element of the Eisenstein subspace of weight k
|
|
704
|
+
try:
|
|
705
|
+
n = Ek_basis.index(form)
|
|
706
|
+
name = f"E{str(k)}_{str(n)}"
|
|
707
|
+
except ValueError:
|
|
708
|
+
name = "".join(next(iter_names)) + str(k)
|
|
709
|
+
elif form.is_cuspidal():
|
|
710
|
+
Sk_basis = Mk.cuspidal_subspace().basis()
|
|
711
|
+
# check if form is a basis element of the cuspidal subspace of weight k
|
|
712
|
+
try:
|
|
713
|
+
n = Sk_basis.index(form)
|
|
714
|
+
name = f"S{str(k)}_{str(n)}"
|
|
715
|
+
except ValueError:
|
|
716
|
+
name = "".join(next(iter_names)) + str(k)
|
|
717
|
+
else:
|
|
718
|
+
name = "".join(next(iter_names)) + str(k)
|
|
719
|
+
names.append(name)
|
|
720
|
+
weights.insert(0, 2) # add the weight 2 Eisenstein series
|
|
721
|
+
return PolynomialRing(self.base_ring(), len(weights), names,
|
|
722
|
+
order=TermOrder('wdeglex', weights))
|
|
723
|
+
|
|
724
|
+
def from_polynomial(self, polynomial):
|
|
725
|
+
r"""
|
|
726
|
+
Convert the given polynomial `P(x,\ldots, y)` to the graded quasiform
|
|
727
|
+
`P(g_0, \ldots, g_n)` where the `g_i` are the generators given
|
|
728
|
+
by :meth:`~sage.modular.quasimodform.ring.QuasiModularForms.gens`.
|
|
729
|
+
|
|
730
|
+
INPUT:
|
|
731
|
+
|
|
732
|
+
- ``polynomial`` -- a multivariate polynomial
|
|
733
|
+
|
|
734
|
+
OUTPUT: the graded quasimodular forms `P(g_0, \ldots, g_n)`
|
|
735
|
+
|
|
736
|
+
EXAMPLES::
|
|
737
|
+
|
|
738
|
+
sage: QM = QuasiModularForms(1)
|
|
739
|
+
sage: P.<x, y, z> = QQ[]
|
|
740
|
+
sage: QM.from_polynomial(x)
|
|
741
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
742
|
+
sage: QM.from_polynomial(x) == QM.0
|
|
743
|
+
True
|
|
744
|
+
sage: QM.from_polynomial(y) == QM.1
|
|
745
|
+
True
|
|
746
|
+
sage: QM.from_polynomial(z) == QM.2
|
|
747
|
+
True
|
|
748
|
+
sage: QM.from_polynomial(x^2 + y + x*z + 1)
|
|
749
|
+
4 - 336*q - 2016*q^2 + 322368*q^3 + 3691392*q^4 + 21797280*q^5 + O(q^6)
|
|
750
|
+
sage: QM = QuasiModularForms(Gamma0(2))
|
|
751
|
+
sage: P = QM.polynomial_ring()
|
|
752
|
+
sage: P.inject_variables()
|
|
753
|
+
Defining E2, E2_0, E4_0
|
|
754
|
+
sage: QM.from_polynomial(E2)
|
|
755
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
|
|
756
|
+
sage: QM.from_polynomial(E2 + E4_0*E2_0) == QM.0 + QM.2*QM.1
|
|
757
|
+
True
|
|
758
|
+
|
|
759
|
+
Naturally, the number of variable must not exceed the number of generators::
|
|
760
|
+
|
|
761
|
+
sage: P = PolynomialRing(QQ, 'F', 4)
|
|
762
|
+
sage: P.inject_variables()
|
|
763
|
+
Defining F0, F1, F2, F3
|
|
764
|
+
sage: QM.from_polynomial(F0 + F1 + F2 + F3)
|
|
765
|
+
Traceback (most recent call last):
|
|
766
|
+
...
|
|
767
|
+
ValueError: the number of variables (4) of the given polynomial cannot exceed the number of generators (3) of the quasimodular forms ring
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
TESTS::
|
|
771
|
+
|
|
772
|
+
sage: QuasiModularForms(1).from_polynomial('x')
|
|
773
|
+
Traceback (most recent call last):
|
|
774
|
+
...
|
|
775
|
+
TypeError: the input must be a polynomial
|
|
776
|
+
"""
|
|
777
|
+
if not isinstance(polynomial, (MPolynomial, Polynomial)):
|
|
778
|
+
raise TypeError('the input must be a polynomial')
|
|
779
|
+
poly_parent = polynomial.parent()
|
|
780
|
+
nb_var = poly_parent.ngens()
|
|
781
|
+
if nb_var > self.ngens():
|
|
782
|
+
raise ValueError("the number of variables (%s) of the given polynomial cannot exceed the number of generators (%s) of the quasimodular forms ring" % (nb_var, self.ngens()))
|
|
783
|
+
gens_dict = {poly_parent.gen(i): self.gen(i) for i in range(nb_var)}
|
|
784
|
+
return self(polynomial.subs(gens_dict))
|
|
785
|
+
|
|
786
|
+
def basis_of_weight(self, weight):
|
|
787
|
+
r"""
|
|
788
|
+
Return a basis of elements generating the subspace of the given
|
|
789
|
+
weight.
|
|
790
|
+
|
|
791
|
+
INPUT:
|
|
792
|
+
|
|
793
|
+
- ``weight`` -- integer; the weight of the subspace
|
|
794
|
+
|
|
795
|
+
OUTPUT: list of quasimodular forms of the given weight
|
|
796
|
+
|
|
797
|
+
EXAMPLES::
|
|
798
|
+
|
|
799
|
+
sage: QM = QuasiModularForms(1)
|
|
800
|
+
sage: QM.basis_of_weight(12)
|
|
801
|
+
[q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6),
|
|
802
|
+
1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6),
|
|
803
|
+
1 - 288*q - 129168*q^2 - 1927296*q^3 + 65152656*q^4 + 1535768640*q^5 + O(q^6),
|
|
804
|
+
1 + 432*q + 39312*q^2 - 1711296*q^3 - 14159664*q^4 + 317412000*q^5 + O(q^6),
|
|
805
|
+
1 - 576*q + 21168*q^2 + 308736*q^3 - 15034608*q^4 - 39208320*q^5 + O(q^6),
|
|
806
|
+
1 + 144*q - 17712*q^2 + 524736*q^3 - 2279088*q^4 - 79760160*q^5 + O(q^6),
|
|
807
|
+
1 - 144*q + 8208*q^2 - 225216*q^3 + 2634192*q^4 + 1488672*q^5 + O(q^6)]
|
|
808
|
+
sage: QM = QuasiModularForms(Gamma1(3))
|
|
809
|
+
sage: QM.basis_of_weight(3)
|
|
810
|
+
[1 + 54*q^2 + 72*q^3 + 432*q^5 + O(q^6),
|
|
811
|
+
q + 3*q^2 + 9*q^3 + 13*q^4 + 24*q^5 + O(q^6)]
|
|
812
|
+
sage: QM.basis_of_weight(5)
|
|
813
|
+
[1 - 90*q^2 - 240*q^3 - 3744*q^5 + O(q^6),
|
|
814
|
+
q + 15*q^2 + 81*q^3 + 241*q^4 + 624*q^5 + O(q^6),
|
|
815
|
+
1 - 24*q - 18*q^2 - 1320*q^3 - 5784*q^4 - 10080*q^5 + O(q^6),
|
|
816
|
+
q - 21*q^2 - 135*q^3 - 515*q^4 - 1392*q^5 + O(q^6)]
|
|
817
|
+
"""
|
|
818
|
+
basis = []
|
|
819
|
+
E2 = self.weight_2_eisenstein_series()
|
|
820
|
+
M = self.__modular_forms_subring
|
|
821
|
+
E2_pow = self.one()
|
|
822
|
+
for j in range(weight // 2):
|
|
823
|
+
basis.extend(f * E2_pow
|
|
824
|
+
for f in M.modular_forms_of_weight(weight - 2*j).basis())
|
|
825
|
+
E2_pow *= E2
|
|
826
|
+
if not weight % 2:
|
|
827
|
+
basis.append(E2_pow)
|
|
828
|
+
return basis
|