passagemath-schemes 10.8.1a4__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.
- 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.8.1a4.dist-info/METADATA +203 -0
- passagemath_schemes-10.8.1a4.dist-info/METADATA.bak +204 -0
- passagemath_schemes-10.8.1a4.dist-info/RECORD +312 -0
- passagemath_schemes-10.8.1a4.dist-info/WHEEL +6 -0
- passagemath_schemes-10.8.1a4.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 +9556 -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 +2578 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +727 -0
- sage/lfunctions/pari.py +971 -0
- sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5132 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +414 -0
- sage/modular/abvar/abvar_newform.py +246 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +187 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +721 -0
- sage/modular/abvar/homspace.py +989 -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 +741 -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 +1406 -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 +361 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +659 -0
- sage/modular/arithgroup/congroup_gammaH.py +1491 -0
- sage/modular/arithgroup/congroup_generic.py +630 -0
- sage/modular/arithgroup/congroup_sl2z.py +266 -0
- sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1067 -0
- sage/modular/arithgroup/tests.py +425 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3736 -0
- sage/modular/btquotients/pautomorphicform.py +2564 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1107 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +571 -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 +1076 -0
- sage/modular/hecke/algebra.py +725 -0
- sage/modular/hecke/all.py +19 -0
- sage/modular/hecke/ambient_module.py +994 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +302 -0
- sage/modular/hecke/hecke_operator.py +736 -0
- sage/modular/hecke/homspace.py +185 -0
- sage/modular/hecke/module.py +1744 -0
- sage/modular/hecke/morphism.py +139 -0
- sage/modular/hecke/submodule.py +970 -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 +2020 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1070 -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 +817 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +120 -0
- sage/modular/modform/ambient_g1.py +199 -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 +487 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4105 -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 +127 -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 +1859 -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 +380 -0
- sage/modular/modform/weight1.py +221 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2527 -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 +3349 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1426 -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 +3844 -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 +1291 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -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 +376 -0
- sage/modular/multiple_zeta.py +2635 -0
- sage/modular/multiple_zeta_F_algebra.py +789 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1879 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +776 -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 +856 -0
- sage/modular/pollack_stevens/modsym.py +1590 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1078 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +846 -0
- sage/modular/quasimodform/ring.py +826 -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 +700 -0
- sage/schemes/curves/affine_curve.py +2924 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +397 -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 +3203 -0
- sage/schemes/curves/weighted_projective_curve.py +106 -0
- sage/schemes/curves/zariski_vankampen.py +1931 -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 +991 -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 +1103 -0
- sage/schemes/elliptic_curves/constructor.py +1530 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3971 -0
- sage/schemes/elliptic_curves/ell_egros.py +457 -0
- sage/schemes/elliptic_curves/ell_field.py +2837 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3249 -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 +4944 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7184 -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 +1663 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7328 -0
- sage/schemes/elliptic_curves/height.py +2108 -0
- sage/schemes/elliptic_curves/hom.py +1788 -0
- sage/schemes/elliptic_curves/hom_composite.py +1084 -0
- sage/schemes/elliptic_curves/hom_fractional.py +544 -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 +681 -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 +1523 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +247 -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 +915 -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 +716 -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 +369 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1948 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +936 -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 +312 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +437 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +878 -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 +3863 -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 +581 -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 +53 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4177 -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,1932 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.graphs
|
|
3
|
+
r"""
|
|
4
|
+
Graded rings of modular forms for Hecke triangle groups
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Jonas Jermann (2013): initial version
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
# Copyright (C) 2013-2014 Jonas Jermann <jjermann2@gmail.com>
|
|
13
|
+
#
|
|
14
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
15
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
16
|
+
# the License, or (at your option) any later version.
|
|
17
|
+
# https://www.gnu.org/licenses/
|
|
18
|
+
# ****************************************************************************
|
|
19
|
+
|
|
20
|
+
from sage.misc.cachefunc import cached_method
|
|
21
|
+
from sage.misc.lazy_import import lazy_import
|
|
22
|
+
from sage.rings.fraction_field import FractionField
|
|
23
|
+
from sage.rings.infinity import infinity
|
|
24
|
+
from sage.rings.integer_ring import ZZ
|
|
25
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
26
|
+
from sage.rings.power_series_ring import PowerSeriesRing
|
|
27
|
+
from sage.rings.rational_field import QQ
|
|
28
|
+
from sage.structure.parent import Parent
|
|
29
|
+
|
|
30
|
+
from .constructor import FormsRing, FormsSpace
|
|
31
|
+
from .series_constructor import MFSeriesConstructor
|
|
32
|
+
|
|
33
|
+
lazy_import('sage.algebras.free_algebra', 'FreeAlgebra')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class FormsRing_abstract(Parent):
|
|
37
|
+
r"""
|
|
38
|
+
Abstract (Hecke) forms ring.
|
|
39
|
+
|
|
40
|
+
This should never be called directly. Instead one should
|
|
41
|
+
instantiate one of the derived classes of this class.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
from .graded_ring_element import FormsRingElement
|
|
45
|
+
Element = FormsRingElement
|
|
46
|
+
|
|
47
|
+
from .analytic_type import AnalyticType
|
|
48
|
+
AT = AnalyticType()
|
|
49
|
+
|
|
50
|
+
def __init__(self, group, base_ring, red_hom, n):
|
|
51
|
+
r"""
|
|
52
|
+
Abstract (Hecke) forms ring.
|
|
53
|
+
|
|
54
|
+
INPUT:
|
|
55
|
+
|
|
56
|
+
- ``group`` -- the Hecke triangle group (default: ``HeckeTriangleGroup(3)``)
|
|
57
|
+
|
|
58
|
+
- ``base_ring`` -- the base_ring (default: `\Z`)
|
|
59
|
+
|
|
60
|
+
- ``red_hom`` -- if ``True`` then results of binary operations are
|
|
61
|
+
considered homogeneous whenever it makes sense (default: ``False``).
|
|
62
|
+
This is mainly used by the (Hecke) forms.
|
|
63
|
+
|
|
64
|
+
OUTPUT: the corresponding abstract (Hecke) forms ring
|
|
65
|
+
|
|
66
|
+
EXAMPLES::
|
|
67
|
+
|
|
68
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
69
|
+
sage: MR = ModularFormsRing(n=5, base_ring=ZZ, red_hom=True)
|
|
70
|
+
sage: MR
|
|
71
|
+
ModularFormsRing(n=5) over Integer Ring
|
|
72
|
+
sage: MR.group()
|
|
73
|
+
Hecke triangle group for n = 5
|
|
74
|
+
sage: MR.base_ring()
|
|
75
|
+
Integer Ring
|
|
76
|
+
sage: MR.has_reduce_hom()
|
|
77
|
+
True
|
|
78
|
+
sage: MR.is_homogeneous()
|
|
79
|
+
False
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
# from graded_ring import canonical_parameters
|
|
83
|
+
# group, base_ring, red_hom, n = canonical_parameters(group, base_ring, red_hom, n)
|
|
84
|
+
|
|
85
|
+
# if not group.is_arithmetic() and base_ring.characteristic()>0:
|
|
86
|
+
# raise NotImplementedError
|
|
87
|
+
# if base_ring.characteristic().divides(2*group.n()*(group.n()-2)):
|
|
88
|
+
# raise NotImplementedError
|
|
89
|
+
|
|
90
|
+
if base_ring.characteristic() > 0:
|
|
91
|
+
raise NotImplementedError("only characteristic 0 is supported")
|
|
92
|
+
self._group = group
|
|
93
|
+
self._red_hom = red_hom
|
|
94
|
+
self._base_ring = base_ring
|
|
95
|
+
self._coeff_ring = FractionField(PolynomialRing(base_ring, 'd'))
|
|
96
|
+
self._pol_ring = PolynomialRing(base_ring, 'x,y,z,d')
|
|
97
|
+
self._rat_field = FractionField(self._pol_ring)
|
|
98
|
+
|
|
99
|
+
# default values
|
|
100
|
+
self._weight = None
|
|
101
|
+
self._ep = None
|
|
102
|
+
self._analytic_type = self.AT(["quasi", "mero"])
|
|
103
|
+
|
|
104
|
+
self.default_prec(10)
|
|
105
|
+
self.disp_prec(5)
|
|
106
|
+
self.default_num_prec(53)
|
|
107
|
+
|
|
108
|
+
def _repr_(self):
|
|
109
|
+
r"""
|
|
110
|
+
Return the string representation of ``self``.
|
|
111
|
+
|
|
112
|
+
EXAMPLES::
|
|
113
|
+
|
|
114
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
|
|
115
|
+
sage: QuasiModularFormsRing(n=4)
|
|
116
|
+
QuasiModularFormsRing(n=4) over Integer Ring
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
return "{}FormsRing(n={}) over {}".format(self._analytic_type.analytic_space_name(), self._group.n(), self._base_ring)
|
|
120
|
+
|
|
121
|
+
def _latex_(self):
|
|
122
|
+
r"""
|
|
123
|
+
Return the LaTeX representation of ``self``.
|
|
124
|
+
|
|
125
|
+
EXAMPLES::
|
|
126
|
+
|
|
127
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiWeakModularFormsRing
|
|
128
|
+
sage: latex(QuasiWeakModularFormsRing())
|
|
129
|
+
\mathcal{ QM^! }_{n=3}(\Bold{Z})
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
from sage.misc.latex import latex
|
|
133
|
+
return "\\mathcal{{ {} }}_{{n={}}}({})".format(self._analytic_type.latex_space_name(), self._group.n(), latex(self._base_ring))
|
|
134
|
+
|
|
135
|
+
def _element_constructor_(self, el):
|
|
136
|
+
r"""
|
|
137
|
+
Return ``el`` coerced/converted into this forms ring.
|
|
138
|
+
|
|
139
|
+
EXAMPLES::
|
|
140
|
+
|
|
141
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
142
|
+
sage: MR = ModularFormsRing()
|
|
143
|
+
sage: x,y,z,d = MR.pol_ring().gens()
|
|
144
|
+
|
|
145
|
+
sage: MR(x^3)
|
|
146
|
+
f_rho^3
|
|
147
|
+
|
|
148
|
+
sage: el = MR.Delta().full_reduce()
|
|
149
|
+
sage: MR(el)
|
|
150
|
+
f_rho^3*d - f_i^2*d
|
|
151
|
+
sage: el.parent() == MR
|
|
152
|
+
False
|
|
153
|
+
sage: MR(el).parent() == MR
|
|
154
|
+
True
|
|
155
|
+
|
|
156
|
+
sage: el = MR.Delta().full_reduce()
|
|
157
|
+
sage: MRinf = ModularFormsRing(n=infinity)
|
|
158
|
+
sage: MRinf(el)
|
|
159
|
+
(E4*f_i^4 - 2*E4^2*f_i^2 + E4^3)/4096
|
|
160
|
+
sage: el.parent()
|
|
161
|
+
CuspForms(n=3, k=12, ep=1) over Integer Ring
|
|
162
|
+
sage: MRinf(el).parent()
|
|
163
|
+
ModularFormsRing(n=+Infinity) over Integer Ring
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
from .graded_ring_element import FormsRingElement
|
|
167
|
+
if isinstance(el, FormsRingElement):
|
|
168
|
+
if self.hecke_n() == infinity and el.hecke_n() == ZZ(3):
|
|
169
|
+
el_f = el._reduce_d()._rat
|
|
170
|
+
x, y, z, d = self.pol_ring().gens()
|
|
171
|
+
|
|
172
|
+
num_sub = el_f.numerator().subs(x=(y**2 + 3*x)/ZZ(4),
|
|
173
|
+
y=(9*x*y - y**3)/ZZ(8),
|
|
174
|
+
z=(3*z - y)/ZZ(2))
|
|
175
|
+
denom_sub = el_f.denominator().subs(x=(y**2 + 3*x)/ZZ(4),
|
|
176
|
+
y=(9*x*y - y**3)/ZZ(8),
|
|
177
|
+
z=(3*z - y)/ZZ(2))
|
|
178
|
+
new_num = num_sub.numerator() * denom_sub.denominator()
|
|
179
|
+
new_denom = denom_sub.numerator() * num_sub.denominator()
|
|
180
|
+
|
|
181
|
+
el = self._rat_field(new_num) / self._rat_field(new_denom)
|
|
182
|
+
elif self.group() == el.group():
|
|
183
|
+
el = self._rat_field(el._rat)
|
|
184
|
+
else:
|
|
185
|
+
raise ValueError("{} has group {} != {}".format(el, el.group(), self.group()))
|
|
186
|
+
else:
|
|
187
|
+
el = self._rat_field(el)
|
|
188
|
+
return self.element_class(self, el)
|
|
189
|
+
|
|
190
|
+
def _coerce_map_from_(self, S):
|
|
191
|
+
r"""
|
|
192
|
+
Return whether or not there exists a coercion from ``S`` to ``self``.
|
|
193
|
+
|
|
194
|
+
EXAMPLES::
|
|
195
|
+
|
|
196
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiWeakModularFormsRing, ModularFormsRing, CuspFormsRing
|
|
197
|
+
sage: MR1 = QuasiWeakModularFormsRing(base_ring=CC)
|
|
198
|
+
sage: MR2 = ModularFormsRing()
|
|
199
|
+
sage: MR3 = CuspFormsRing()
|
|
200
|
+
sage: MR4 = ModularFormsRing(n=infinity)
|
|
201
|
+
sage: MR5 = ModularFormsRing(n=4)
|
|
202
|
+
sage: MR3.has_coerce_map_from(MR2)
|
|
203
|
+
False
|
|
204
|
+
sage: MR1.has_coerce_map_from(MR2)
|
|
205
|
+
True
|
|
206
|
+
sage: MR2.has_coerce_map_from(MR3)
|
|
207
|
+
True
|
|
208
|
+
sage: MR3.has_coerce_map_from(ZZ)
|
|
209
|
+
False
|
|
210
|
+
sage: MR1.has_coerce_map_from(ZZ)
|
|
211
|
+
True
|
|
212
|
+
sage: MR4.has_coerce_map_from(MR2)
|
|
213
|
+
True
|
|
214
|
+
sage: MR4.has_coerce_map_from(MR5)
|
|
215
|
+
False
|
|
216
|
+
|
|
217
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, CuspForms
|
|
218
|
+
sage: MF2 = ModularForms(k=6, ep=-1)
|
|
219
|
+
sage: MF3 = CuspForms(k=12, ep=1)
|
|
220
|
+
sage: MR1.has_coerce_map_from(MF2)
|
|
221
|
+
True
|
|
222
|
+
sage: MR2.has_coerce_map_from(MF3)
|
|
223
|
+
True
|
|
224
|
+
sage: MR4.has_coerce_map_from(MF2)
|
|
225
|
+
True
|
|
226
|
+
"""
|
|
227
|
+
from .space import FormsSpace_abstract
|
|
228
|
+
from .functors import _common_subgroup
|
|
229
|
+
if (isinstance(S, FormsRing_abstract)
|
|
230
|
+
and self._group == _common_subgroup(self._group, S._group)
|
|
231
|
+
and self._analytic_type >= S._analytic_type
|
|
232
|
+
and self.base_ring().has_coerce_map_from(S.base_ring())):
|
|
233
|
+
return True
|
|
234
|
+
if isinstance(S, FormsRing_abstract):
|
|
235
|
+
return False
|
|
236
|
+
if isinstance(S, FormsSpace_abstract):
|
|
237
|
+
raise RuntimeError("this case should not occur")
|
|
238
|
+
# return self._coerce_map_from_(S.graded_ring())
|
|
239
|
+
return self.AT("holo") <= self._analytic_type and self.coeff_ring().has_coerce_map_from(S)
|
|
240
|
+
|
|
241
|
+
def _an_element_(self):
|
|
242
|
+
r"""
|
|
243
|
+
Return an element of ``self``.
|
|
244
|
+
|
|
245
|
+
EXAMPLES::
|
|
246
|
+
|
|
247
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import CuspFormsRing
|
|
248
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms
|
|
249
|
+
sage: CuspFormsRing().an_element()
|
|
250
|
+
f_rho^3*d - f_i^2*d
|
|
251
|
+
sage: CuspFormsRing().an_element() == CuspFormsRing().Delta()
|
|
252
|
+
True
|
|
253
|
+
sage: WeakModularForms().an_element()
|
|
254
|
+
O(q^5)
|
|
255
|
+
sage: WeakModularForms().an_element() == WeakModularForms().zero()
|
|
256
|
+
True
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
return self(self.Delta())
|
|
260
|
+
|
|
261
|
+
def default_prec(self, prec=None):
|
|
262
|
+
r"""
|
|
263
|
+
Set the default precision ``prec`` for the Fourier expansion.
|
|
264
|
+
If ``prec=None`` (default) then the current default precision is
|
|
265
|
+
returned instead.
|
|
266
|
+
|
|
267
|
+
INPUT:
|
|
268
|
+
|
|
269
|
+
- ``prec`` -- integer
|
|
270
|
+
|
|
271
|
+
.. NOTE::
|
|
272
|
+
|
|
273
|
+
This is also used as the default precision for the Fourier
|
|
274
|
+
expansion when evaluating forms.
|
|
275
|
+
|
|
276
|
+
EXAMPLES::
|
|
277
|
+
|
|
278
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
279
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms
|
|
280
|
+
sage: MR = ModularFormsRing()
|
|
281
|
+
sage: MR.default_prec(3)
|
|
282
|
+
sage: MR.default_prec()
|
|
283
|
+
3
|
|
284
|
+
sage: MR.Delta().q_expansion_fixed_d()
|
|
285
|
+
q - 24*q^2 + O(q^3)
|
|
286
|
+
sage: MF = ModularForms(k=4)
|
|
287
|
+
sage: MF.default_prec(2)
|
|
288
|
+
sage: MF.E4()
|
|
289
|
+
1 + 240*q + O(q^2)
|
|
290
|
+
sage: MF.default_prec()
|
|
291
|
+
2
|
|
292
|
+
"""
|
|
293
|
+
if prec is not None:
|
|
294
|
+
self._prec = ZZ(prec)
|
|
295
|
+
else:
|
|
296
|
+
return self._prec
|
|
297
|
+
|
|
298
|
+
def disp_prec(self, prec=None):
|
|
299
|
+
r"""
|
|
300
|
+
Set the maximal display precision to ``prec``.
|
|
301
|
+
If ``prec="max"`` the precision is set to the default precision.
|
|
302
|
+
If ``prec=None`` (default) then the current display precision is returned instead.
|
|
303
|
+
|
|
304
|
+
NOTE:
|
|
305
|
+
|
|
306
|
+
This is used for displaying/representing (elements of)
|
|
307
|
+
``self`` as Fourier expansions.
|
|
308
|
+
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms
|
|
312
|
+
sage: MF = ModularForms(k=4)
|
|
313
|
+
sage: MF.default_prec(5)
|
|
314
|
+
sage: MF.disp_prec(3)
|
|
315
|
+
sage: MF.disp_prec()
|
|
316
|
+
3
|
|
317
|
+
sage: MF.E4()
|
|
318
|
+
1 + 240*q + 2160*q^2 + O(q^3)
|
|
319
|
+
sage: MF.disp_prec("max")
|
|
320
|
+
sage: MF.E4()
|
|
321
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + O(q^5)
|
|
322
|
+
"""
|
|
323
|
+
if prec == "max":
|
|
324
|
+
self._disp_prec = self._prec
|
|
325
|
+
elif prec is not None:
|
|
326
|
+
self._disp_prec = ZZ(prec)
|
|
327
|
+
else:
|
|
328
|
+
return self._disp_prec
|
|
329
|
+
|
|
330
|
+
def default_num_prec(self, prec=None):
|
|
331
|
+
r"""
|
|
332
|
+
Set the default numerical precision to ``prec`` (default: ``53``).
|
|
333
|
+
If ``prec=None`` (default) the current default numerical
|
|
334
|
+
precision is returned instead.
|
|
335
|
+
|
|
336
|
+
EXAMPLES::
|
|
337
|
+
|
|
338
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms
|
|
339
|
+
sage: MF = ModularForms(k=6)
|
|
340
|
+
sage: MF.default_prec(20)
|
|
341
|
+
sage: MF.default_num_prec(10)
|
|
342
|
+
sage: MF.default_num_prec()
|
|
343
|
+
10
|
|
344
|
+
sage: E6 = MF.E6()
|
|
345
|
+
sage: E6(i + 10^(-1000))
|
|
346
|
+
0.002... - 6.7...e-1000*I
|
|
347
|
+
sage: MF.default_num_prec(100)
|
|
348
|
+
sage: E6(i + 10^(-1000))
|
|
349
|
+
3.9946838...e-1999 - 6.6578064...e-1000*I
|
|
350
|
+
|
|
351
|
+
sage: MF = ModularForms(n=5, k=4/3)
|
|
352
|
+
sage: f_rho = MF.f_rho()
|
|
353
|
+
sage: f_rho.q_expansion(prec=2)[1]
|
|
354
|
+
7/(100*d)
|
|
355
|
+
sage: MF.default_num_prec(15)
|
|
356
|
+
sage: f_rho.q_expansion_fixed_d(prec=2)[1]
|
|
357
|
+
9.9...
|
|
358
|
+
sage: MF.default_num_prec(100)
|
|
359
|
+
sage: f_rho.q_expansion_fixed_d(prec=2)[1]
|
|
360
|
+
9.92593243510795915276017782...
|
|
361
|
+
"""
|
|
362
|
+
if prec is not None:
|
|
363
|
+
self._num_prec = ZZ(prec)
|
|
364
|
+
else:
|
|
365
|
+
return self._num_prec
|
|
366
|
+
|
|
367
|
+
def change_ring(self, new_base_ring):
|
|
368
|
+
r"""
|
|
369
|
+
Return the same space as ``self`` but over a new base ring ``new_base_ring``.
|
|
370
|
+
|
|
371
|
+
EXAMPLES::
|
|
372
|
+
|
|
373
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
374
|
+
sage: ModularFormsRing().change_ring(CC)
|
|
375
|
+
ModularFormsRing(n=3) over Complex Field with 53 bits of precision
|
|
376
|
+
"""
|
|
377
|
+
|
|
378
|
+
return self.__class__.__base__(self._group, new_base_ring, self._red_hom)
|
|
379
|
+
|
|
380
|
+
def graded_ring(self):
|
|
381
|
+
r"""
|
|
382
|
+
Return the graded ring containing ``self``.
|
|
383
|
+
|
|
384
|
+
EXAMPLES::
|
|
385
|
+
|
|
386
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing, CuspFormsRing
|
|
387
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
388
|
+
|
|
389
|
+
sage: MR = ModularFormsRing(n=5)
|
|
390
|
+
sage: MR.graded_ring() == MR
|
|
391
|
+
True
|
|
392
|
+
|
|
393
|
+
sage: CF=CuspForms(k=12)
|
|
394
|
+
sage: CF.graded_ring() == CuspFormsRing()
|
|
395
|
+
False
|
|
396
|
+
sage: CF.graded_ring() == CuspFormsRing(red_hom=True)
|
|
397
|
+
True
|
|
398
|
+
|
|
399
|
+
sage: CF.subspace([CF.Delta()]).graded_ring() == CuspFormsRing(red_hom=True)
|
|
400
|
+
True
|
|
401
|
+
"""
|
|
402
|
+
|
|
403
|
+
return self.extend_type(ring=True)
|
|
404
|
+
|
|
405
|
+
def extend_type(self, analytic_type=None, ring=False):
|
|
406
|
+
r"""
|
|
407
|
+
Return a new space which contains (elements of) ``self`` with the analytic type
|
|
408
|
+
of ``self`` extended by ``analytic_type``, possibly extended to a graded ring
|
|
409
|
+
in case ``ring`` is ``True``.
|
|
410
|
+
|
|
411
|
+
INPUT:
|
|
412
|
+
|
|
413
|
+
- ``analytic_type`` -- an ``AnalyticType`` or something which
|
|
414
|
+
coerces into it (default: ``None``)
|
|
415
|
+
|
|
416
|
+
- ``ring`` -- whether to extend to a graded ring (default: ``False``)
|
|
417
|
+
|
|
418
|
+
OUTPUT: the new extended space
|
|
419
|
+
|
|
420
|
+
EXAMPLES::
|
|
421
|
+
|
|
422
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
423
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
424
|
+
|
|
425
|
+
sage: MR = ModularFormsRing(n=5)
|
|
426
|
+
sage: MR.extend_type(["quasi", "weak"])
|
|
427
|
+
QuasiWeakModularFormsRing(n=5) over Integer Ring
|
|
428
|
+
|
|
429
|
+
sage: CF=CuspForms(k=12)
|
|
430
|
+
sage: CF.extend_type("holo")
|
|
431
|
+
ModularForms(n=3, k=12, ep=1) over Integer Ring
|
|
432
|
+
sage: CF.extend_type("quasi", ring=True)
|
|
433
|
+
QuasiCuspFormsRing(n=3) over Integer Ring
|
|
434
|
+
|
|
435
|
+
sage: CF.subspace([CF.Delta()]).extend_type()
|
|
436
|
+
CuspForms(n=3, k=12, ep=1) over Integer Ring
|
|
437
|
+
"""
|
|
438
|
+
|
|
439
|
+
if analytic_type is None:
|
|
440
|
+
analytic_type = self._analytic_type
|
|
441
|
+
else:
|
|
442
|
+
analytic_type = self._analytic_type.extend_by(analytic_type)
|
|
443
|
+
|
|
444
|
+
if ring or not self.is_homogeneous():
|
|
445
|
+
return FormsRing(analytic_type, group=self.group(), base_ring=self.base_ring(), red_hom=self.has_reduce_hom())
|
|
446
|
+
else:
|
|
447
|
+
return FormsSpace(analytic_type, group=self.group(), base_ring=self.base_ring(), k=self.weight(), ep=self.ep())
|
|
448
|
+
|
|
449
|
+
def reduce_type(self, analytic_type=None, degree=None):
|
|
450
|
+
r"""
|
|
451
|
+
Return a new space with analytic properties shared by both ``self`` and ``analytic_type``,
|
|
452
|
+
possibly reduced to its space of homogeneous elements of the given ``degree`` (if ``degree`` is set).
|
|
453
|
+
Elements of the new space are contained in ``self``.
|
|
454
|
+
|
|
455
|
+
INPUT:
|
|
456
|
+
|
|
457
|
+
- ``analytic_type`` -- an ``AnalyticType`` or something which coerces
|
|
458
|
+
into it (default: ``None``)
|
|
459
|
+
|
|
460
|
+
- ``degree`` -- ``None`` (default) or the degree of the homogeneous
|
|
461
|
+
component to which ``self`` should be reduced
|
|
462
|
+
|
|
463
|
+
OUTPUT: the new reduced space
|
|
464
|
+
|
|
465
|
+
EXAMPLES::
|
|
466
|
+
|
|
467
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
|
|
468
|
+
sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
|
|
469
|
+
|
|
470
|
+
sage: MR = QuasiModularFormsRing()
|
|
471
|
+
sage: MR.reduce_type(["quasi", "cusp"])
|
|
472
|
+
QuasiCuspFormsRing(n=3) over Integer Ring
|
|
473
|
+
|
|
474
|
+
sage: MR.reduce_type("cusp", degree=(12,1))
|
|
475
|
+
CuspForms(n=3, k=12, ep=1) over Integer Ring
|
|
476
|
+
|
|
477
|
+
sage: MF=QuasiModularForms(k=6)
|
|
478
|
+
sage: MF.reduce_type("holo")
|
|
479
|
+
ModularForms(n=3, k=6, ep=-1) over Integer Ring
|
|
480
|
+
|
|
481
|
+
sage: MF.reduce_type([])
|
|
482
|
+
ZeroForms(n=3, k=6, ep=-1) over Integer Ring
|
|
483
|
+
"""
|
|
484
|
+
|
|
485
|
+
if analytic_type is None:
|
|
486
|
+
analytic_type = self._analytic_type
|
|
487
|
+
else:
|
|
488
|
+
analytic_type = self._analytic_type.reduce_to(analytic_type)
|
|
489
|
+
|
|
490
|
+
if degree is None and not self.is_homogeneous():
|
|
491
|
+
return FormsRing(analytic_type, group=self.group(), base_ring=self.base_ring(), red_hom=self.has_reduce_hom())
|
|
492
|
+
elif degree is None:
|
|
493
|
+
return FormsSpace(analytic_type, group=self.group(), base_ring=self.base_ring(), k=self.weight(), ep=self.ep())
|
|
494
|
+
else:
|
|
495
|
+
weight, ep = degree
|
|
496
|
+
if self.is_homogeneous() and (weight != self.weight() or ep != self.ep()):
|
|
497
|
+
analytic_type = self._analytic_type.reduce_to([])
|
|
498
|
+
return FormsSpace(analytic_type, group=self.group(), base_ring=self.base_ring(), k=weight, ep=ep)
|
|
499
|
+
|
|
500
|
+
@cached_method
|
|
501
|
+
def contains_coeff_ring(self):
|
|
502
|
+
r"""
|
|
503
|
+
Return whether ``self`` contains its coefficient ring.
|
|
504
|
+
|
|
505
|
+
EXAMPLES::
|
|
506
|
+
|
|
507
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import CuspFormsRing, ModularFormsRing
|
|
508
|
+
sage: CuspFormsRing(n=4).contains_coeff_ring()
|
|
509
|
+
False
|
|
510
|
+
sage: ModularFormsRing(n=5).contains_coeff_ring()
|
|
511
|
+
True
|
|
512
|
+
"""
|
|
513
|
+
|
|
514
|
+
return (self.AT("holo") <= self._analytic_type)
|
|
515
|
+
|
|
516
|
+
def construction(self):
|
|
517
|
+
r"""
|
|
518
|
+
Return a functor that constructs ``self`` (used by the coercion machinery).
|
|
519
|
+
|
|
520
|
+
EXAMPLES::
|
|
521
|
+
|
|
522
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
523
|
+
sage: ModularFormsRing().construction()
|
|
524
|
+
(ModularFormsRingFunctor(n=3), BaseFacade(Integer Ring))
|
|
525
|
+
"""
|
|
526
|
+
|
|
527
|
+
from .functors import FormsRingFunctor, BaseFacade
|
|
528
|
+
return FormsRingFunctor(self._analytic_type, self._group, self._red_hom), BaseFacade(self._base_ring)
|
|
529
|
+
|
|
530
|
+
@cached_method
|
|
531
|
+
def group(self):
|
|
532
|
+
r"""
|
|
533
|
+
Return the (Hecke triangle) group of ``self``.
|
|
534
|
+
|
|
535
|
+
EXAMPLES::
|
|
536
|
+
|
|
537
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
538
|
+
sage: MR = ModularFormsRing(n=7)
|
|
539
|
+
sage: MR.group()
|
|
540
|
+
Hecke triangle group for n = 7
|
|
541
|
+
|
|
542
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
543
|
+
sage: CF = CuspForms(n=7, k=4/5)
|
|
544
|
+
sage: CF.group()
|
|
545
|
+
Hecke triangle group for n = 7
|
|
546
|
+
"""
|
|
547
|
+
|
|
548
|
+
return self._group
|
|
549
|
+
|
|
550
|
+
@cached_method
|
|
551
|
+
def hecke_n(self):
|
|
552
|
+
r"""
|
|
553
|
+
Return the parameter ``n`` of the
|
|
554
|
+
(Hecke triangle) group of ``self``.
|
|
555
|
+
|
|
556
|
+
EXAMPLES::
|
|
557
|
+
|
|
558
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
559
|
+
sage: MR = ModularFormsRing(n=7)
|
|
560
|
+
sage: MR.hecke_n()
|
|
561
|
+
7
|
|
562
|
+
|
|
563
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
564
|
+
sage: CF = CuspForms(n=7, k=4/5)
|
|
565
|
+
sage: CF.hecke_n()
|
|
566
|
+
7
|
|
567
|
+
"""
|
|
568
|
+
|
|
569
|
+
return self._group.n()
|
|
570
|
+
|
|
571
|
+
@cached_method
|
|
572
|
+
def base_ring(self):
|
|
573
|
+
r"""
|
|
574
|
+
Return base ring of ``self``.
|
|
575
|
+
|
|
576
|
+
EXAMPLES::
|
|
577
|
+
|
|
578
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
579
|
+
sage: ModularFormsRing().base_ring()
|
|
580
|
+
Integer Ring
|
|
581
|
+
|
|
582
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
583
|
+
sage: CuspForms(k=12, base_ring=AA).base_ring()
|
|
584
|
+
Algebraic Real Field
|
|
585
|
+
"""
|
|
586
|
+
|
|
587
|
+
return self._base_ring
|
|
588
|
+
|
|
589
|
+
@cached_method
|
|
590
|
+
def coeff_ring(self):
|
|
591
|
+
r"""
|
|
592
|
+
Return coefficient ring of ``self``.
|
|
593
|
+
|
|
594
|
+
EXAMPLES::
|
|
595
|
+
|
|
596
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
597
|
+
sage: ModularFormsRing().coeff_ring()
|
|
598
|
+
Fraction Field of Univariate Polynomial Ring in d over Integer Ring
|
|
599
|
+
|
|
600
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
601
|
+
sage: CuspForms(k=12, base_ring=AA).coeff_ring()
|
|
602
|
+
Fraction Field of Univariate Polynomial Ring in d over Algebraic Real Field
|
|
603
|
+
"""
|
|
604
|
+
|
|
605
|
+
return self._coeff_ring
|
|
606
|
+
|
|
607
|
+
@cached_method
|
|
608
|
+
def pol_ring(self):
|
|
609
|
+
r"""
|
|
610
|
+
Return the underlying polynomial ring used
|
|
611
|
+
by ``self``.
|
|
612
|
+
|
|
613
|
+
EXAMPLES::
|
|
614
|
+
|
|
615
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
616
|
+
sage: ModularFormsRing().pol_ring()
|
|
617
|
+
Multivariate Polynomial Ring in x, y, z, d over Integer Ring
|
|
618
|
+
|
|
619
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
620
|
+
sage: CuspForms(k=12, base_ring=AA).pol_ring()
|
|
621
|
+
Multivariate Polynomial Ring in x, y, z, d over Algebraic Real Field
|
|
622
|
+
"""
|
|
623
|
+
|
|
624
|
+
return self._pol_ring
|
|
625
|
+
|
|
626
|
+
@cached_method
|
|
627
|
+
def rat_field(self):
|
|
628
|
+
r"""
|
|
629
|
+
Return the underlying rational field used by
|
|
630
|
+
``self`` to construct/represent elements.
|
|
631
|
+
|
|
632
|
+
EXAMPLES::
|
|
633
|
+
|
|
634
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
635
|
+
sage: ModularFormsRing().rat_field()
|
|
636
|
+
Fraction Field of Multivariate Polynomial Ring in x, y, z, d over Integer Ring
|
|
637
|
+
|
|
638
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
639
|
+
sage: CuspForms(k=12, base_ring=AA).rat_field()
|
|
640
|
+
Fraction Field of Multivariate Polynomial Ring in x, y, z, d over Algebraic Real Field
|
|
641
|
+
"""
|
|
642
|
+
|
|
643
|
+
return self._rat_field
|
|
644
|
+
|
|
645
|
+
def get_d(self, fix_d=False, d_num_prec=None):
|
|
646
|
+
r"""
|
|
647
|
+
Return the parameter ``d`` of ``self`` either as a formal
|
|
648
|
+
parameter or as a numerical approximation with the specified
|
|
649
|
+
precision (resp. an exact value in the arithmetic cases).
|
|
650
|
+
|
|
651
|
+
For an (exact) symbolic expression also see
|
|
652
|
+
``HeckeTriangleGroup().dvalue()``.
|
|
653
|
+
|
|
654
|
+
INPUT:
|
|
655
|
+
|
|
656
|
+
- ``fix_d`` -- if ``False`` (default) a formal parameter is
|
|
657
|
+
used for ``d``. If ``True`` then the numerical value of ``d`` is used
|
|
658
|
+
(or an exact value if the group is arithmetic). Otherwise, the given
|
|
659
|
+
value is used for ``d``.
|
|
660
|
+
|
|
661
|
+
- ``d_num_prec`` -- integer (default: ``None``); the numerical
|
|
662
|
+
precision of ``d``. By default, the default numerical precision of
|
|
663
|
+
``self.parent()`` is used.
|
|
664
|
+
|
|
665
|
+
OUTPUT:
|
|
666
|
+
|
|
667
|
+
The corresponding formal, numerical or exact parameter ``d`` of ``self``,
|
|
668
|
+
depending on the arguments and whether ``self.group()`` is arithmetic.
|
|
669
|
+
|
|
670
|
+
EXAMPLES::
|
|
671
|
+
|
|
672
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
673
|
+
sage: ModularFormsRing(n=8).get_d()
|
|
674
|
+
d
|
|
675
|
+
sage: ModularFormsRing(n=8).get_d().parent()
|
|
676
|
+
Fraction Field of Univariate Polynomial Ring in d over Integer Ring
|
|
677
|
+
sage: ModularFormsRing(n=infinity).get_d(fix_d = True)
|
|
678
|
+
1/64
|
|
679
|
+
sage: ModularFormsRing(n=infinity).get_d(fix_d = True).parent()
|
|
680
|
+
Rational Field
|
|
681
|
+
sage: ModularFormsRing(n=5).default_num_prec(40)
|
|
682
|
+
sage: ModularFormsRing(n=5).get_d(fix_d = True)
|
|
683
|
+
0.0070522341...
|
|
684
|
+
sage: ModularFormsRing(n=5).get_d(fix_d = True).parent()
|
|
685
|
+
Real Field with 40 bits of precision
|
|
686
|
+
sage: ModularFormsRing(n=5).get_d(fix_d = True, d_num_prec=100).parent()
|
|
687
|
+
Real Field with 100 bits of precision
|
|
688
|
+
sage: ModularFormsRing(n=5).get_d(fix_d=1).parent()
|
|
689
|
+
Integer Ring
|
|
690
|
+
"""
|
|
691
|
+
if d_num_prec is None:
|
|
692
|
+
d_num_prec = self.default_num_prec()
|
|
693
|
+
else:
|
|
694
|
+
d_num_prec = ZZ(d_num_prec)
|
|
695
|
+
|
|
696
|
+
if fix_d is True:
|
|
697
|
+
d = self._group.dvalue()
|
|
698
|
+
if self._group.is_arithmetic():
|
|
699
|
+
d = ~self.base_ring()(~d)
|
|
700
|
+
else:
|
|
701
|
+
d = self.group().dvalue().n(d_num_prec)
|
|
702
|
+
elif fix_d is False:
|
|
703
|
+
d = FractionField(PolynomialRing(self.base_ring(), "d")).gen()
|
|
704
|
+
else:
|
|
705
|
+
d = fix_d
|
|
706
|
+
|
|
707
|
+
return d
|
|
708
|
+
|
|
709
|
+
def get_q(self, prec=None, fix_d=False, d_num_prec=None):
|
|
710
|
+
r"""
|
|
711
|
+
Return the generator of the power series of the Fourier expansion of ``self``.
|
|
712
|
+
|
|
713
|
+
INPUT:
|
|
714
|
+
|
|
715
|
+
- ``prec`` -- an integer or ``None`` (default), namely the desired
|
|
716
|
+
default precision of the space of power series. If nothing is
|
|
717
|
+
specified the default precision of ``self`` is used.
|
|
718
|
+
|
|
719
|
+
- ``fix_d`` -- if ``False`` (default) a formal parameter is used for
|
|
720
|
+
``d``. If ``True`` then the numerical value of ``d`` is used (resp.
|
|
721
|
+
an exact value if the group is arithmetic). Otherwise the given value
|
|
722
|
+
is used for ``d``.
|
|
723
|
+
|
|
724
|
+
- ``d_num_prec`` -- the precision to be used if a numerical value for
|
|
725
|
+
``d`` is substituted (default: ``None``), otherwise the default
|
|
726
|
+
numerical precision of ``self.parent()`` is used
|
|
727
|
+
|
|
728
|
+
OUTPUT:
|
|
729
|
+
|
|
730
|
+
The generator of the ``PowerSeriesRing`` of corresponding to the given
|
|
731
|
+
parameters. The base ring of the power series ring is given by the corresponding
|
|
732
|
+
parent of ``self.get_d()`` with the same arguments.
|
|
733
|
+
|
|
734
|
+
EXAMPLES::
|
|
735
|
+
|
|
736
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
737
|
+
sage: ModularFormsRing(n=8).default_prec(5)
|
|
738
|
+
sage: ModularFormsRing(n=8).get_q().parent()
|
|
739
|
+
Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
|
|
740
|
+
sage: ModularFormsRing(n=8).get_q().parent().default_prec()
|
|
741
|
+
5
|
|
742
|
+
sage: ModularFormsRing(n=infinity).get_q(prec=12, fix_d = True).parent()
|
|
743
|
+
Power Series Ring in q over Rational Field
|
|
744
|
+
sage: ModularFormsRing(n=infinity).get_q(prec=12, fix_d = True).parent().default_prec()
|
|
745
|
+
12
|
|
746
|
+
sage: ModularFormsRing(n=5).default_num_prec(40)
|
|
747
|
+
sage: ModularFormsRing(n=5).get_q(fix_d = True).parent()
|
|
748
|
+
Power Series Ring in q over Real Field with 40 bits of precision
|
|
749
|
+
sage: ModularFormsRing(n=5).get_q(fix_d = True, d_num_prec=100).parent()
|
|
750
|
+
Power Series Ring in q over Real Field with 100 bits of precision
|
|
751
|
+
sage: ModularFormsRing(n=5).get_q(fix_d=1).parent()
|
|
752
|
+
Power Series Ring in q over Rational Field
|
|
753
|
+
"""
|
|
754
|
+
d = self.get_d(fix_d, d_num_prec)
|
|
755
|
+
if prec is None:
|
|
756
|
+
prec = self.default_prec()
|
|
757
|
+
|
|
758
|
+
base_ring = d.parent()
|
|
759
|
+
return PowerSeriesRing(FractionField(base_ring), 'q', default_prec=prec).gen()
|
|
760
|
+
|
|
761
|
+
@cached_method
|
|
762
|
+
def diff_alg(self):
|
|
763
|
+
r"""
|
|
764
|
+
Return the algebra of differential operators
|
|
765
|
+
(over QQ) which is used on rational functions
|
|
766
|
+
representing elements of ``self``.
|
|
767
|
+
|
|
768
|
+
EXAMPLES::
|
|
769
|
+
|
|
770
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
771
|
+
sage: ModularFormsRing().diff_alg()
|
|
772
|
+
Noncommutative Multivariate Polynomial Ring in X, Y, Z, dX, dY, dZ over Rational Field, nc-relations: {dX*X: X*dX + 1, dY*Y: Y*dY + 1, dZ*Z: Z*dZ + 1}
|
|
773
|
+
|
|
774
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms
|
|
775
|
+
sage: CuspForms(k=12, base_ring=AA).diff_alg()
|
|
776
|
+
Noncommutative Multivariate Polynomial Ring in X, Y, Z, dX, dY, dZ over Rational Field, nc-relations: {dX*X: X*dX + 1, dY*Y: Y*dY + 1, dZ*Z: Z*dZ + 1}
|
|
777
|
+
"""
|
|
778
|
+
# We only use two operators for now which do not involve 'd',
|
|
779
|
+
# so for performance reason and due to restrictions for
|
|
780
|
+
# possible rings that can be used with algebra relations we
|
|
781
|
+
# choose FractionField(base_ring) instead of
|
|
782
|
+
# self.coeff_ring(). For our purposes it is currently enough
|
|
783
|
+
# to define the operators over ZZ resp. QQ.
|
|
784
|
+
free_alg = FreeAlgebra(QQ, 6, 'X,Y,Z,dX,dY,dZ')
|
|
785
|
+
X, Y, Z, dX, dY, dZ = free_alg.gens()
|
|
786
|
+
return free_alg.g_algebra({dX * X: 1 + X * dX,
|
|
787
|
+
dY * Y: 1 + Y * dY,
|
|
788
|
+
dZ * Z: 1 + Z * dZ})
|
|
789
|
+
|
|
790
|
+
@cached_method
|
|
791
|
+
def _derivative_op(self):
|
|
792
|
+
r"""
|
|
793
|
+
Return the differential operator in ``self.diff_alg()``
|
|
794
|
+
corresponding to the derivative of forms.
|
|
795
|
+
|
|
796
|
+
EXAMPLES::
|
|
797
|
+
|
|
798
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
799
|
+
sage: ModularFormsRing(n=7)._derivative_op()
|
|
800
|
+
-1/2*X^6*dY - 5/28*X^5*dZ + 1/7*X*Z*dX + 1/2*Y*Z*dY + 5/28*Z^2*dZ - 1/7*Y*dX
|
|
801
|
+
|
|
802
|
+
sage: ModularFormsRing(n=infinity)._derivative_op()
|
|
803
|
+
-X*Y*dX + X*Z*dX + 1/2*Y*Z*dY + 1/4*Z^2*dZ - 1/2*X*dY - 1/4*X*dZ
|
|
804
|
+
"""
|
|
805
|
+
X, Y, Z, dX, dY, dZ = self.diff_alg().gens()
|
|
806
|
+
|
|
807
|
+
if self.hecke_n() == infinity:
|
|
808
|
+
return (X*Z-X*Y) * dX + ZZ(1) / 2 * (Y*Z-X) * dY \
|
|
809
|
+
+ ZZ(1) / 4 * (Z**2-X) * dZ
|
|
810
|
+
|
|
811
|
+
return 1/self._group.n() * (X*Z-Y) * dX \
|
|
812
|
+
+ ZZ(1) / 2 * (Y*Z-X**(self._group.n()-1)) * dY \
|
|
813
|
+
+ (self._group.n()-2) / (4*self._group.n()) * (Z**2-X**(self._group.n()-2)) * dZ
|
|
814
|
+
|
|
815
|
+
@cached_method
|
|
816
|
+
def _serre_derivative_op(self):
|
|
817
|
+
r"""
|
|
818
|
+
Return the differential operator in ``self.diff_alg()``
|
|
819
|
+
corresponding to the Serre derivative of forms.
|
|
820
|
+
|
|
821
|
+
EXAMPLES::
|
|
822
|
+
|
|
823
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
824
|
+
sage: ModularFormsRing(n=8)._serre_derivative_op()
|
|
825
|
+
-1/2*X^7*dY - 3/16*X^6*dZ - 3/16*Z^2*dZ - 1/8*Y*dX
|
|
826
|
+
|
|
827
|
+
sage: ModularFormsRing(n=infinity)._serre_derivative_op()
|
|
828
|
+
-X*Y*dX - 1/4*Z^2*dZ - 1/2*X*dY - 1/4*X*dZ
|
|
829
|
+
"""
|
|
830
|
+
X, Y, Z, dX, dY, dZ = self.diff_alg().gens()
|
|
831
|
+
|
|
832
|
+
if self.hecke_n() == infinity:
|
|
833
|
+
return - X * Y * dX - ZZ(1) / 2 * X * dY \
|
|
834
|
+
- ZZ(1) / 4 * (Z**2+X) * dZ
|
|
835
|
+
|
|
836
|
+
return - 1/self._group.n() * Y*dX \
|
|
837
|
+
- ZZ(1) / 2 * X**(self._group.n()-1) * dY \
|
|
838
|
+
- (self._group.n()-2) / (4*self._group.n()) * (Z**2+X**(self._group.n()-2)) * dZ
|
|
839
|
+
|
|
840
|
+
@cached_method
|
|
841
|
+
def has_reduce_hom(self) -> bool:
|
|
842
|
+
r"""
|
|
843
|
+
Return whether the method ``reduce`` should reduce
|
|
844
|
+
homogeneous elements to the corresponding space of homogeneous elements.
|
|
845
|
+
|
|
846
|
+
This is mainly used by binary operations on homogeneous
|
|
847
|
+
spaces which temporarily produce an element of ``self``
|
|
848
|
+
but want to consider it as a homogeneous element
|
|
849
|
+
(also see ``reduce``).
|
|
850
|
+
|
|
851
|
+
EXAMPLES::
|
|
852
|
+
|
|
853
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
854
|
+
sage: ModularFormsRing().has_reduce_hom()
|
|
855
|
+
False
|
|
856
|
+
sage: ModularFormsRing(red_hom=True).has_reduce_hom()
|
|
857
|
+
True
|
|
858
|
+
|
|
859
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms
|
|
860
|
+
sage: ModularForms(k=6).has_reduce_hom()
|
|
861
|
+
True
|
|
862
|
+
sage: ModularForms(k=6).graded_ring().has_reduce_hom()
|
|
863
|
+
True
|
|
864
|
+
"""
|
|
865
|
+
return self._red_hom
|
|
866
|
+
|
|
867
|
+
def is_homogeneous(self) -> bool:
|
|
868
|
+
r"""
|
|
869
|
+
Return whether ``self`` is homogeneous component.
|
|
870
|
+
|
|
871
|
+
EXAMPLES::
|
|
872
|
+
|
|
873
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
874
|
+
sage: ModularFormsRing().is_homogeneous()
|
|
875
|
+
False
|
|
876
|
+
|
|
877
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms
|
|
878
|
+
sage: ModularForms(k=6).is_homogeneous()
|
|
879
|
+
True
|
|
880
|
+
"""
|
|
881
|
+
return self._weight is not None
|
|
882
|
+
|
|
883
|
+
def is_modular(self) -> bool:
|
|
884
|
+
r"""
|
|
885
|
+
Return whether ``self`` only contains modular elements.
|
|
886
|
+
|
|
887
|
+
EXAMPLES::
|
|
888
|
+
|
|
889
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiWeakModularFormsRing, CuspFormsRing
|
|
890
|
+
sage: QuasiWeakModularFormsRing().is_modular()
|
|
891
|
+
False
|
|
892
|
+
sage: CuspFormsRing(n=7).is_modular()
|
|
893
|
+
True
|
|
894
|
+
|
|
895
|
+
sage: from sage.modular.modform_hecketriangle.space import QuasiWeakModularForms, CuspForms
|
|
896
|
+
sage: QuasiWeakModularForms(k=10).is_modular()
|
|
897
|
+
False
|
|
898
|
+
sage: CuspForms(n=7, k=12, base_ring=AA).is_modular()
|
|
899
|
+
True
|
|
900
|
+
"""
|
|
901
|
+
return not (self.AT("quasi") <= self._analytic_type)
|
|
902
|
+
|
|
903
|
+
def is_weakly_holomorphic(self) -> bool:
|
|
904
|
+
r"""
|
|
905
|
+
Return whether ``self`` only contains weakly
|
|
906
|
+
holomorphic modular elements.
|
|
907
|
+
|
|
908
|
+
EXAMPLES::
|
|
909
|
+
|
|
910
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, QuasiWeakModularFormsRing, CuspFormsRing
|
|
911
|
+
sage: QuasiMeromorphicModularFormsRing().is_weakly_holomorphic()
|
|
912
|
+
False
|
|
913
|
+
sage: QuasiWeakModularFormsRing().is_weakly_holomorphic()
|
|
914
|
+
True
|
|
915
|
+
|
|
916
|
+
sage: from sage.modular.modform_hecketriangle.space import MeromorphicModularForms, CuspForms
|
|
917
|
+
sage: MeromorphicModularForms(k=10).is_weakly_holomorphic()
|
|
918
|
+
False
|
|
919
|
+
sage: CuspForms(n=7, k=12, base_ring=AA).is_weakly_holomorphic()
|
|
920
|
+
True
|
|
921
|
+
"""
|
|
922
|
+
return (self.AT("weak", "quasi") >= self._analytic_type)
|
|
923
|
+
|
|
924
|
+
def is_holomorphic(self) -> bool:
|
|
925
|
+
r"""
|
|
926
|
+
Return whether ``self`` only contains holomorphic
|
|
927
|
+
modular elements.
|
|
928
|
+
|
|
929
|
+
EXAMPLES::
|
|
930
|
+
|
|
931
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiWeakModularFormsRing, QuasiModularFormsRing
|
|
932
|
+
sage: QuasiWeakModularFormsRing().is_holomorphic()
|
|
933
|
+
False
|
|
934
|
+
sage: QuasiModularFormsRing().is_holomorphic()
|
|
935
|
+
True
|
|
936
|
+
|
|
937
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms, CuspForms
|
|
938
|
+
sage: WeakModularForms(k=10).is_holomorphic()
|
|
939
|
+
False
|
|
940
|
+
sage: CuspForms(n=7, k=12, base_ring=AA).is_holomorphic()
|
|
941
|
+
True
|
|
942
|
+
"""
|
|
943
|
+
return (self.AT("holo", "quasi") >= self._analytic_type)
|
|
944
|
+
|
|
945
|
+
def is_cuspidal(self) -> bool:
|
|
946
|
+
r"""
|
|
947
|
+
Return whether ``self`` only contains cuspidal elements.
|
|
948
|
+
|
|
949
|
+
EXAMPLES::
|
|
950
|
+
|
|
951
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing, QuasiCuspFormsRing
|
|
952
|
+
sage: QuasiModularFormsRing().is_cuspidal()
|
|
953
|
+
False
|
|
954
|
+
sage: QuasiCuspFormsRing().is_cuspidal()
|
|
955
|
+
True
|
|
956
|
+
|
|
957
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, QuasiCuspForms
|
|
958
|
+
sage: ModularForms(k=12).is_cuspidal()
|
|
959
|
+
False
|
|
960
|
+
sage: QuasiCuspForms(k=12).is_cuspidal()
|
|
961
|
+
True
|
|
962
|
+
"""
|
|
963
|
+
return (self.AT("cusp", "quasi") >= self._analytic_type)
|
|
964
|
+
|
|
965
|
+
def is_zerospace(self) -> bool:
|
|
966
|
+
r"""
|
|
967
|
+
Return whether ``self`` is the (`0`-dimensional) zero space.
|
|
968
|
+
|
|
969
|
+
EXAMPLES::
|
|
970
|
+
|
|
971
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
|
|
972
|
+
sage: ModularFormsRing().is_zerospace()
|
|
973
|
+
False
|
|
974
|
+
|
|
975
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, CuspForms
|
|
976
|
+
sage: ModularForms(k=12).is_zerospace()
|
|
977
|
+
False
|
|
978
|
+
sage: CuspForms(k=12).reduce_type([]).is_zerospace()
|
|
979
|
+
True
|
|
980
|
+
"""
|
|
981
|
+
return (self.AT(["quasi"]) >= self._analytic_type)
|
|
982
|
+
|
|
983
|
+
def analytic_type(self):
|
|
984
|
+
r"""
|
|
985
|
+
Return the analytic type of ``self``.
|
|
986
|
+
|
|
987
|
+
EXAMPLES::
|
|
988
|
+
|
|
989
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, QuasiWeakModularFormsRing
|
|
990
|
+
sage: QuasiMeromorphicModularFormsRing().analytic_type()
|
|
991
|
+
quasi meromorphic modular
|
|
992
|
+
sage: QuasiWeakModularFormsRing().analytic_type()
|
|
993
|
+
quasi weakly holomorphic modular
|
|
994
|
+
|
|
995
|
+
sage: from sage.modular.modform_hecketriangle.space import MeromorphicModularForms, CuspForms
|
|
996
|
+
sage: MeromorphicModularForms(k=10).analytic_type()
|
|
997
|
+
meromorphic modular
|
|
998
|
+
sage: CuspForms(n=7, k=12, base_ring=AA).analytic_type()
|
|
999
|
+
cuspidal
|
|
1000
|
+
"""
|
|
1001
|
+
|
|
1002
|
+
return self._analytic_type
|
|
1003
|
+
|
|
1004
|
+
def homogeneous_part(self, k, ep):
|
|
1005
|
+
r"""
|
|
1006
|
+
Return the homogeneous component of degree (``k``, ``e``) of ``self``.
|
|
1007
|
+
|
|
1008
|
+
INPUT:
|
|
1009
|
+
|
|
1010
|
+
- ``k`` -- integer
|
|
1011
|
+
|
|
1012
|
+
- ``ep`` -- `+1` or `-1`
|
|
1013
|
+
|
|
1014
|
+
EXAMPLES::
|
|
1015
|
+
|
|
1016
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, QuasiWeakModularFormsRing
|
|
1017
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).homogeneous_part(k=2, ep=-1)
|
|
1018
|
+
QuasiMeromorphicModularForms(n=7, k=2, ep=-1) over Integer Ring
|
|
1019
|
+
"""
|
|
1020
|
+
return self.reduce_type(degree=(k, ep))
|
|
1021
|
+
|
|
1022
|
+
@cached_method
|
|
1023
|
+
def J_inv(self):
|
|
1024
|
+
r"""
|
|
1025
|
+
Return the J-invariant (Hauptmodul) of the group of ``self``.
|
|
1026
|
+
It is normalized such that ``J_inv(infinity) = infinity``,
|
|
1027
|
+
it has real Fourier coefficients starting with ``d > 0`` and ``J_inv(i) = 1``
|
|
1028
|
+
|
|
1029
|
+
It lies in a (weak) extension of the graded ring of ``self``.
|
|
1030
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1031
|
+
the corresponding space of homogeneous elements.
|
|
1032
|
+
|
|
1033
|
+
EXAMPLES::
|
|
1034
|
+
|
|
1035
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, WeakModularFormsRing, CuspFormsRing
|
|
1036
|
+
sage: MR = WeakModularFormsRing(n=7)
|
|
1037
|
+
sage: J_inv = MR.J_inv()
|
|
1038
|
+
sage: J_inv in MR
|
|
1039
|
+
True
|
|
1040
|
+
sage: CuspFormsRing(n=7).J_inv() == J_inv
|
|
1041
|
+
True
|
|
1042
|
+
sage: J_inv
|
|
1043
|
+
f_rho^7/(f_rho^7 - f_i^2)
|
|
1044
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).J_inv() == QuasiMeromorphicModularFormsRing(n=7)(J_inv)
|
|
1045
|
+
True
|
|
1046
|
+
|
|
1047
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms, CuspForms
|
|
1048
|
+
sage: MF = WeakModularForms(n=5, k=0)
|
|
1049
|
+
sage: J_inv = MF.J_inv()
|
|
1050
|
+
sage: J_inv in MF
|
|
1051
|
+
True
|
|
1052
|
+
sage: WeakModularFormsRing(n=5, red_hom=True).J_inv() == J_inv
|
|
1053
|
+
True
|
|
1054
|
+
sage: CuspForms(n=5, k=12).J_inv() == J_inv
|
|
1055
|
+
True
|
|
1056
|
+
sage: MF.disp_prec(3)
|
|
1057
|
+
sage: J_inv
|
|
1058
|
+
d*q^-1 + 79/200 + 42877/(640000*d)*q + 12957/(2000000*d^2)*q^2 + O(q^3)
|
|
1059
|
+
|
|
1060
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1061
|
+
sage: MF = WeakModularForms(n=5)
|
|
1062
|
+
sage: d = MF.get_d()
|
|
1063
|
+
sage: q = MF.get_q()
|
|
1064
|
+
sage: WeakModularForms(n=5).J_inv().q_expansion(prec=5) == MFC(group=5, prec=7).J_inv_ZZ()(q/d).add_bigoh(5)
|
|
1065
|
+
True
|
|
1066
|
+
sage: WeakModularForms(n=infinity).J_inv().q_expansion(prec=5) == MFC(group=infinity, prec=7).J_inv_ZZ()(q/d).add_bigoh(5)
|
|
1067
|
+
True
|
|
1068
|
+
sage: WeakModularForms(n=5).J_inv().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).J_inv_ZZ().add_bigoh(5)
|
|
1069
|
+
True
|
|
1070
|
+
sage: WeakModularForms(n=infinity).J_inv().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).J_inv_ZZ().add_bigoh(5)
|
|
1071
|
+
True
|
|
1072
|
+
|
|
1073
|
+
sage: WeakModularForms(n=infinity).J_inv()
|
|
1074
|
+
1/64*q^-1 + 3/8 + 69/16*q + 32*q^2 + 5601/32*q^3 + 768*q^4 + O(q^5)
|
|
1075
|
+
|
|
1076
|
+
sage: WeakModularForms().J_inv()
|
|
1077
|
+
1/1728*q^-1 + 31/72 + 1823/16*q + 335840/27*q^2 + 16005555/32*q^3 + 11716352*q^4 + O(q^5)
|
|
1078
|
+
"""
|
|
1079
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1080
|
+
|
|
1081
|
+
if self.hecke_n() == infinity:
|
|
1082
|
+
return self.extend_type("weak", ring=True)(x/(x-y**2)).reduce()
|
|
1083
|
+
else:
|
|
1084
|
+
return self.extend_type("weak", ring=True)(x**self._group.n()/(x**self._group.n()-y**2)).reduce()
|
|
1085
|
+
|
|
1086
|
+
@cached_method
|
|
1087
|
+
def j_inv(self):
|
|
1088
|
+
r"""
|
|
1089
|
+
Return the j-invariant (Hauptmodul) of the group of ``self``.
|
|
1090
|
+
It is normalized such that ``j_inv(infinity) = infinity``,
|
|
1091
|
+
and such that it has real Fourier coefficients starting with ``1``.
|
|
1092
|
+
|
|
1093
|
+
It lies in a (weak) extension of the graded ring of ``self``.
|
|
1094
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1095
|
+
the corresponding space of homogeneous elements.
|
|
1096
|
+
|
|
1097
|
+
EXAMPLES::
|
|
1098
|
+
|
|
1099
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, WeakModularFormsRing, CuspFormsRing
|
|
1100
|
+
sage: MR = WeakModularFormsRing(n=7)
|
|
1101
|
+
sage: j_inv = MR.j_inv()
|
|
1102
|
+
sage: j_inv in MR
|
|
1103
|
+
True
|
|
1104
|
+
sage: CuspFormsRing(n=7).j_inv() == j_inv
|
|
1105
|
+
True
|
|
1106
|
+
sage: j_inv
|
|
1107
|
+
f_rho^7/(f_rho^7*d - f_i^2*d)
|
|
1108
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).j_inv() == QuasiMeromorphicModularFormsRing(n=7)(j_inv)
|
|
1109
|
+
True
|
|
1110
|
+
|
|
1111
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms, CuspForms
|
|
1112
|
+
sage: MF = WeakModularForms(n=5, k=0)
|
|
1113
|
+
sage: j_inv = MF.j_inv()
|
|
1114
|
+
sage: j_inv in MF
|
|
1115
|
+
True
|
|
1116
|
+
sage: WeakModularFormsRing(n=5, red_hom=True).j_inv() == j_inv
|
|
1117
|
+
True
|
|
1118
|
+
sage: CuspForms(n=5, k=12).j_inv() == j_inv
|
|
1119
|
+
True
|
|
1120
|
+
sage: MF.disp_prec(3)
|
|
1121
|
+
sage: j_inv
|
|
1122
|
+
q^-1 + 79/(200*d) + 42877/(640000*d^2)*q + 12957/(2000000*d^3)*q^2 + O(q^3)
|
|
1123
|
+
|
|
1124
|
+
sage: WeakModularForms(n=infinity).j_inv()
|
|
1125
|
+
q^-1 + 24 + 276*q + 2048*q^2 + 11202*q^3 + 49152*q^4 + O(q^5)
|
|
1126
|
+
|
|
1127
|
+
sage: WeakModularForms().j_inv()
|
|
1128
|
+
q^-1 + 744 + 196884*q + 21493760*q^2 + 864299970*q^3 + 20245856256*q^4 + O(q^5)
|
|
1129
|
+
"""
|
|
1130
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1131
|
+
|
|
1132
|
+
if self.hecke_n() == infinity:
|
|
1133
|
+
return self.extend_type("weak", ring=True)(1/d*x/(x-y**2)).reduce()
|
|
1134
|
+
return self.extend_type("weak", ring=True)(1/d*x**self._group.n()/(x**self._group.n()-y**2)).reduce()
|
|
1135
|
+
|
|
1136
|
+
@cached_method
|
|
1137
|
+
def f_rho(self):
|
|
1138
|
+
r"""
|
|
1139
|
+
Return a normalized modular form ``f_rho`` with exactly one simple
|
|
1140
|
+
zero at ``rho`` (up to the group action).
|
|
1141
|
+
|
|
1142
|
+
It lies in a (holomorphic) extension of the graded ring of ``self``.
|
|
1143
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1144
|
+
the corresponding space of homogeneous elements.
|
|
1145
|
+
|
|
1146
|
+
The polynomial variable ``x`` exactly corresponds to ``f_rho``.
|
|
1147
|
+
|
|
1148
|
+
NOTE:
|
|
1149
|
+
|
|
1150
|
+
If ``n=infinity`` the situation is different, there we have:
|
|
1151
|
+
``f_rho=1`` (since that's the limit as ``n`` goes to infinity)
|
|
1152
|
+
and the polynomial variable ``x`` no longer refers to ``f_rho``.
|
|
1153
|
+
Instead it refers to ``E4`` which has exactly one simple zero
|
|
1154
|
+
at the cusp ``-1``. Also note that ``E4`` is the limit of
|
|
1155
|
+
``f_rho^(n-2)``.
|
|
1156
|
+
|
|
1157
|
+
EXAMPLES::
|
|
1158
|
+
|
|
1159
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, ModularFormsRing, CuspFormsRing
|
|
1160
|
+
sage: MR = ModularFormsRing(n=7)
|
|
1161
|
+
sage: f_rho = MR.f_rho()
|
|
1162
|
+
sage: f_rho in MR
|
|
1163
|
+
True
|
|
1164
|
+
sage: CuspFormsRing(n=7).f_rho() == f_rho
|
|
1165
|
+
True
|
|
1166
|
+
sage: f_rho
|
|
1167
|
+
f_rho
|
|
1168
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).f_rho() == QuasiMeromorphicModularFormsRing(n=7)(f_rho)
|
|
1169
|
+
True
|
|
1170
|
+
|
|
1171
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, CuspForms
|
|
1172
|
+
sage: MF = ModularForms(n=5, k=4/3)
|
|
1173
|
+
sage: f_rho = MF.f_rho()
|
|
1174
|
+
sage: f_rho in MF
|
|
1175
|
+
True
|
|
1176
|
+
sage: ModularFormsRing(n=5, red_hom=True).f_rho() == f_rho
|
|
1177
|
+
True
|
|
1178
|
+
sage: CuspForms(n=5, k=12).f_rho() == f_rho
|
|
1179
|
+
True
|
|
1180
|
+
sage: MF.disp_prec(3)
|
|
1181
|
+
sage: f_rho
|
|
1182
|
+
1 + 7/(100*d)*q + 21/(160000*d^2)*q^2 + O(q^3)
|
|
1183
|
+
|
|
1184
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1185
|
+
sage: MF = ModularForms(n=5)
|
|
1186
|
+
sage: d = MF.get_d()
|
|
1187
|
+
sage: q = MF.get_q()
|
|
1188
|
+
sage: ModularForms(n=5).f_rho().q_expansion(prec=5) == MFC(group=5, prec=7).f_rho_ZZ()(q/d).add_bigoh(5)
|
|
1189
|
+
True
|
|
1190
|
+
sage: ModularForms(n=infinity).f_rho().q_expansion(prec=5) == MFC(group=infinity, prec=7).f_rho_ZZ()(q/d).add_bigoh(5)
|
|
1191
|
+
True
|
|
1192
|
+
sage: ModularForms(n=5).f_rho().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).f_rho_ZZ().add_bigoh(5)
|
|
1193
|
+
True
|
|
1194
|
+
sage: ModularForms(n=infinity).f_rho().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).f_rho_ZZ().add_bigoh(5)
|
|
1195
|
+
True
|
|
1196
|
+
|
|
1197
|
+
sage: ModularForms(n=infinity, k=0).f_rho() == ModularForms(n=infinity, k=0)(1)
|
|
1198
|
+
True
|
|
1199
|
+
|
|
1200
|
+
sage: ModularForms(k=4).f_rho() == ModularForms(k=4).E4()
|
|
1201
|
+
True
|
|
1202
|
+
sage: ModularForms(k=4).f_rho()
|
|
1203
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + O(q^5)
|
|
1204
|
+
"""
|
|
1205
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1206
|
+
|
|
1207
|
+
if self.hecke_n() == infinity:
|
|
1208
|
+
return self.extend_type("holo", ring=True)(1).reduce()
|
|
1209
|
+
return self.extend_type("holo", ring=True)(x).reduce()
|
|
1210
|
+
|
|
1211
|
+
@cached_method
|
|
1212
|
+
def f_i(self):
|
|
1213
|
+
r"""
|
|
1214
|
+
Return a normalized modular form ``f_i`` with exactly one simple
|
|
1215
|
+
zero at ``i`` (up to the group action).
|
|
1216
|
+
|
|
1217
|
+
It lies in a (holomorphic) extension of the graded ring of ``self``.
|
|
1218
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1219
|
+
the corresponding space of homogeneous elements.
|
|
1220
|
+
|
|
1221
|
+
The polynomial variable ``y`` exactly corresponds to ``f_i``.
|
|
1222
|
+
|
|
1223
|
+
EXAMPLES::
|
|
1224
|
+
|
|
1225
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, ModularFormsRing, CuspFormsRing
|
|
1226
|
+
sage: MR = ModularFormsRing(n=7)
|
|
1227
|
+
sage: f_i = MR.f_i()
|
|
1228
|
+
sage: f_i in MR
|
|
1229
|
+
True
|
|
1230
|
+
sage: CuspFormsRing(n=7).f_i() == f_i
|
|
1231
|
+
True
|
|
1232
|
+
sage: f_i
|
|
1233
|
+
f_i
|
|
1234
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).f_i() == QuasiMeromorphicModularFormsRing(n=7)(f_i)
|
|
1235
|
+
True
|
|
1236
|
+
|
|
1237
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, CuspForms
|
|
1238
|
+
sage: MF = ModularForms(n=5, k=10/3)
|
|
1239
|
+
sage: f_i = MF.f_i()
|
|
1240
|
+
sage: f_i in MF
|
|
1241
|
+
True
|
|
1242
|
+
sage: ModularFormsRing(n=5, red_hom=True).f_i() == f_i
|
|
1243
|
+
True
|
|
1244
|
+
sage: CuspForms(n=5, k=12).f_i() == f_i
|
|
1245
|
+
True
|
|
1246
|
+
sage: MF.disp_prec(3)
|
|
1247
|
+
sage: f_i
|
|
1248
|
+
1 - 13/(40*d)*q - 351/(64000*d^2)*q^2 + O(q^3)
|
|
1249
|
+
|
|
1250
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1251
|
+
sage: MF = ModularForms(n=5)
|
|
1252
|
+
sage: d = MF.get_d()
|
|
1253
|
+
sage: q = MF.get_q()
|
|
1254
|
+
sage: ModularForms(n=5).f_i().q_expansion(prec=5) == MFC(group=5, prec=7).f_i_ZZ()(q/d).add_bigoh(5)
|
|
1255
|
+
True
|
|
1256
|
+
sage: ModularForms(n=infinity).f_i().q_expansion(prec=5) == MFC(group=infinity, prec=7).f_i_ZZ()(q/d).add_bigoh(5)
|
|
1257
|
+
True
|
|
1258
|
+
sage: ModularForms(n=5).f_i().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).f_i_ZZ().add_bigoh(5)
|
|
1259
|
+
True
|
|
1260
|
+
sage: ModularForms(n=infinity).f_i().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).f_i_ZZ().add_bigoh(5)
|
|
1261
|
+
True
|
|
1262
|
+
|
|
1263
|
+
sage: ModularForms(n=infinity, k=2).f_i()
|
|
1264
|
+
1 - 24*q + 24*q^2 - 96*q^3 + 24*q^4 + O(q^5)
|
|
1265
|
+
|
|
1266
|
+
sage: ModularForms(k=6).f_i() == ModularForms(k=4).E6()
|
|
1267
|
+
True
|
|
1268
|
+
sage: ModularForms(k=6).f_i()
|
|
1269
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 + O(q^5)
|
|
1270
|
+
"""
|
|
1271
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1272
|
+
|
|
1273
|
+
return self.extend_type("holo", ring=True)(y).reduce()
|
|
1274
|
+
|
|
1275
|
+
@cached_method
|
|
1276
|
+
def f_inf(self):
|
|
1277
|
+
r"""
|
|
1278
|
+
Return a normalized (according to its first nontrivial Fourier
|
|
1279
|
+
coefficient) cusp form ``f_inf`` with exactly one simple zero
|
|
1280
|
+
at ``infinity`` (up to the group action).
|
|
1281
|
+
|
|
1282
|
+
It lies in a (cuspidal) extension of the graded ring of
|
|
1283
|
+
``self``. In case ``has_reduce_hom`` is ``True`` it is given
|
|
1284
|
+
as an element of the corresponding space of homogeneous elements.
|
|
1285
|
+
|
|
1286
|
+
NOTE:
|
|
1287
|
+
|
|
1288
|
+
If ``n=infinity`` then ``f_inf`` is no longer a cusp form
|
|
1289
|
+
since it doesn't vanish at the cusp ``-1``. The first
|
|
1290
|
+
non-trivial cusp form is given by ``E4*f_inf``.
|
|
1291
|
+
|
|
1292
|
+
EXAMPLES::
|
|
1293
|
+
|
|
1294
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, CuspFormsRing
|
|
1295
|
+
sage: MR = CuspFormsRing(n=7)
|
|
1296
|
+
sage: f_inf = MR.f_inf()
|
|
1297
|
+
sage: f_inf in MR
|
|
1298
|
+
True
|
|
1299
|
+
sage: f_inf
|
|
1300
|
+
f_rho^7*d - f_i^2*d
|
|
1301
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).f_inf() == QuasiMeromorphicModularFormsRing(n=7)(f_inf)
|
|
1302
|
+
True
|
|
1303
|
+
|
|
1304
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms, ModularForms
|
|
1305
|
+
sage: MF = CuspForms(n=5, k=20/3)
|
|
1306
|
+
sage: f_inf = MF.f_inf()
|
|
1307
|
+
sage: f_inf in MF
|
|
1308
|
+
True
|
|
1309
|
+
sage: CuspFormsRing(n=5, red_hom=True).f_inf() == f_inf
|
|
1310
|
+
True
|
|
1311
|
+
sage: CuspForms(n=5, k=0).f_inf() == f_inf
|
|
1312
|
+
True
|
|
1313
|
+
sage: MF.disp_prec(3)
|
|
1314
|
+
sage: f_inf
|
|
1315
|
+
q - 9/(200*d)*q^2 + O(q^3)
|
|
1316
|
+
|
|
1317
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1318
|
+
sage: MF = ModularForms(n=5)
|
|
1319
|
+
sage: d = MF.get_d()
|
|
1320
|
+
sage: q = MF.get_q()
|
|
1321
|
+
sage: ModularForms(n=5).f_inf().q_expansion(prec=5) == (d*MFC(group=5, prec=7).f_inf_ZZ()(q/d)).add_bigoh(5)
|
|
1322
|
+
True
|
|
1323
|
+
sage: ModularForms(n=infinity).f_inf().q_expansion(prec=5) == (d*MFC(group=infinity, prec=7).f_inf_ZZ()(q/d)).add_bigoh(5)
|
|
1324
|
+
True
|
|
1325
|
+
sage: ModularForms(n=5).f_inf().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).f_inf_ZZ().add_bigoh(5)
|
|
1326
|
+
True
|
|
1327
|
+
sage: ModularForms(n=infinity).f_inf().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).f_inf_ZZ().add_bigoh(5)
|
|
1328
|
+
True
|
|
1329
|
+
|
|
1330
|
+
sage: ModularForms(n=infinity, k=4).f_inf().reduced_parent()
|
|
1331
|
+
ModularForms(n=+Infinity, k=4, ep=1) over Integer Ring
|
|
1332
|
+
sage: ModularForms(n=infinity, k=4).f_inf()
|
|
1333
|
+
q - 8*q^2 + 28*q^3 - 64*q^4 + O(q^5)
|
|
1334
|
+
|
|
1335
|
+
sage: CuspForms(k=12).f_inf() == CuspForms(k=12).Delta()
|
|
1336
|
+
True
|
|
1337
|
+
sage: CuspForms(k=12).f_inf()
|
|
1338
|
+
q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)
|
|
1339
|
+
"""
|
|
1340
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1341
|
+
|
|
1342
|
+
if self.hecke_n() == infinity:
|
|
1343
|
+
return self.extend_type("holo", ring=True)(d*(x-y**2)).reduce()
|
|
1344
|
+
return self.extend_type("cusp", ring=True)(d*(x**self._group.n()-y**2)).reduce()
|
|
1345
|
+
|
|
1346
|
+
@cached_method
|
|
1347
|
+
def G_inv(self):
|
|
1348
|
+
r"""
|
|
1349
|
+
If `2` divides `n`: Return the G-invariant of the group of ``self``.
|
|
1350
|
+
|
|
1351
|
+
The G-invariant is analogous to the J-invariant but has multiplier `-1`.
|
|
1352
|
+
I.e. ``G_inv(-1/t) = -G_inv(t)``. It is a holomorphic square root
|
|
1353
|
+
of ``J_inv*(J_inv-1)`` with real Fourier coefficients.
|
|
1354
|
+
|
|
1355
|
+
If `2` does not divide `n` the function does not exist and an
|
|
1356
|
+
exception is raised.
|
|
1357
|
+
|
|
1358
|
+
The G-invariant lies in a (weak) extension of the graded ring of ``self``.
|
|
1359
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1360
|
+
the corresponding space of homogeneous elements.
|
|
1361
|
+
|
|
1362
|
+
NOTE:
|
|
1363
|
+
|
|
1364
|
+
If ``n=infinity`` then ``G_inv`` is holomorphic everywhere except
|
|
1365
|
+
at the cusp ``-1`` where it isn't even meromorphic. Consequently
|
|
1366
|
+
this function raises an exception for ``n=infinity``.
|
|
1367
|
+
|
|
1368
|
+
EXAMPLES::
|
|
1369
|
+
|
|
1370
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, WeakModularFormsRing, CuspFormsRing
|
|
1371
|
+
sage: MR = WeakModularFormsRing(n=8)
|
|
1372
|
+
sage: G_inv = MR.G_inv()
|
|
1373
|
+
sage: G_inv in MR
|
|
1374
|
+
True
|
|
1375
|
+
sage: CuspFormsRing(n=8).G_inv() == G_inv
|
|
1376
|
+
True
|
|
1377
|
+
sage: G_inv
|
|
1378
|
+
f_rho^4*f_i*d/(f_rho^8 - f_i^2)
|
|
1379
|
+
sage: QuasiMeromorphicModularFormsRing(n=8).G_inv() == QuasiMeromorphicModularFormsRing(n=8)(G_inv)
|
|
1380
|
+
True
|
|
1381
|
+
|
|
1382
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms, CuspForms
|
|
1383
|
+
sage: MF = WeakModularForms(n=8, k=0, ep=-1)
|
|
1384
|
+
sage: G_inv = MF.G_inv()
|
|
1385
|
+
sage: G_inv in MF
|
|
1386
|
+
True
|
|
1387
|
+
sage: WeakModularFormsRing(n=8, red_hom=True).G_inv() == G_inv
|
|
1388
|
+
True
|
|
1389
|
+
sage: CuspForms(n=8, k=12, ep=1).G_inv() == G_inv
|
|
1390
|
+
True
|
|
1391
|
+
sage: MF.disp_prec(3)
|
|
1392
|
+
sage: G_inv
|
|
1393
|
+
d^2*q^-1 - 15*d/128 - 15139/262144*q - 11575/(1572864*d)*q^2 + O(q^3)
|
|
1394
|
+
|
|
1395
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1396
|
+
sage: MF = WeakModularForms(n=8)
|
|
1397
|
+
sage: d = MF.get_d()
|
|
1398
|
+
sage: q = MF.get_q()
|
|
1399
|
+
sage: WeakModularForms(n=8).G_inv().q_expansion(prec=5) == (d*MFC(group=8, prec=7).G_inv_ZZ()(q/d)).add_bigoh(5)
|
|
1400
|
+
True
|
|
1401
|
+
sage: WeakModularForms(n=8).G_inv().q_expansion(fix_d=1, prec=5) == MFC(group=8, prec=7).G_inv_ZZ().add_bigoh(5)
|
|
1402
|
+
True
|
|
1403
|
+
|
|
1404
|
+
sage: WeakModularForms(n=4, k=0, ep=-1).G_inv()
|
|
1405
|
+
1/65536*q^-1 - 3/8192 - 955/16384*q - 49/32*q^2 - 608799/32768*q^3 - 659/4*q^4 + O(q^5)
|
|
1406
|
+
|
|
1407
|
+
As explained above, the G-invariant exists only for even `n`::
|
|
1408
|
+
|
|
1409
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms
|
|
1410
|
+
sage: MF = WeakModularForms(n=9)
|
|
1411
|
+
sage: MF.G_inv()
|
|
1412
|
+
Traceback (most recent call last):
|
|
1413
|
+
...
|
|
1414
|
+
ArithmeticError: G_inv doesn't exist for odd n(=9).
|
|
1415
|
+
"""
|
|
1416
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1417
|
+
|
|
1418
|
+
if self.hecke_n() == infinity:
|
|
1419
|
+
raise ArithmeticError("G_inv doesn't exist for n={} (it is not meromorphic at -1).".format(self._group.n()))
|
|
1420
|
+
elif ZZ(2).divides(self._group.n()):
|
|
1421
|
+
return self.extend_type("weak", ring=True)(d*y*x**(self._group.n()/ZZ(2))/(x**self._group.n()-y**2)).reduce()
|
|
1422
|
+
else:
|
|
1423
|
+
raise ArithmeticError("G_inv doesn't exist for odd n(={}).".format(self._group.n()))
|
|
1424
|
+
|
|
1425
|
+
@cached_method
|
|
1426
|
+
def g_inv(self):
|
|
1427
|
+
r"""
|
|
1428
|
+
If `2` divides `n`: Return the g-invariant of the group of ``self``.
|
|
1429
|
+
|
|
1430
|
+
The g-invariant is analogous to the j-invariant but has
|
|
1431
|
+
multiplier ``-1``. I.e. ``g_inv(-1/t) = -g_inv(t)``. It is a
|
|
1432
|
+
(normalized) holomorphic square root of ``J_inv*(J_inv-1)``,
|
|
1433
|
+
normalized such that its first nontrivial Fourier coefficient
|
|
1434
|
+
is ``1``.
|
|
1435
|
+
|
|
1436
|
+
If `2` does not divide ``n`` the function does not exist and
|
|
1437
|
+
an exception is raised.
|
|
1438
|
+
|
|
1439
|
+
The g-invariant lies in a (weak) extension of the graded ring of ``self``.
|
|
1440
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1441
|
+
the corresponding space of homogeneous elements.
|
|
1442
|
+
|
|
1443
|
+
NOTE:
|
|
1444
|
+
|
|
1445
|
+
If ``n=infinity`` then ``g_inv`` is holomorphic everywhere except
|
|
1446
|
+
at the cusp ``-1`` where it isn't even meromorphic. Consequently
|
|
1447
|
+
this function raises an exception for ``n=infinity``.
|
|
1448
|
+
|
|
1449
|
+
EXAMPLES::
|
|
1450
|
+
|
|
1451
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, WeakModularFormsRing, CuspFormsRing
|
|
1452
|
+
sage: MR = WeakModularFormsRing(n=8)
|
|
1453
|
+
sage: g_inv = MR.g_inv()
|
|
1454
|
+
sage: g_inv in MR
|
|
1455
|
+
True
|
|
1456
|
+
sage: CuspFormsRing(n=8).g_inv() == g_inv
|
|
1457
|
+
True
|
|
1458
|
+
sage: g_inv
|
|
1459
|
+
f_rho^4*f_i/(f_rho^8*d - f_i^2*d)
|
|
1460
|
+
sage: QuasiMeromorphicModularFormsRing(n=8).g_inv() == QuasiMeromorphicModularFormsRing(n=8)(g_inv)
|
|
1461
|
+
True
|
|
1462
|
+
|
|
1463
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms, CuspForms
|
|
1464
|
+
sage: MF = WeakModularForms(n=8, k=0, ep=-1)
|
|
1465
|
+
sage: g_inv = MF.g_inv()
|
|
1466
|
+
sage: g_inv in MF
|
|
1467
|
+
True
|
|
1468
|
+
sage: WeakModularFormsRing(n=8, red_hom=True).g_inv() == g_inv
|
|
1469
|
+
True
|
|
1470
|
+
sage: CuspForms(n=8, k=12, ep=1).g_inv() == g_inv
|
|
1471
|
+
True
|
|
1472
|
+
sage: MF.disp_prec(3)
|
|
1473
|
+
sage: g_inv
|
|
1474
|
+
q^-1 - 15/(128*d) - 15139/(262144*d^2)*q - 11575/(1572864*d^3)*q^2 + O(q^3)
|
|
1475
|
+
|
|
1476
|
+
sage: WeakModularForms(n=4, k=0, ep=-1).g_inv()
|
|
1477
|
+
q^-1 - 24 - 3820*q - 100352*q^2 - 1217598*q^3 - 10797056*q^4 + O(q^5)
|
|
1478
|
+
|
|
1479
|
+
As explained above, the g-invariant exists only for even `n`::
|
|
1480
|
+
|
|
1481
|
+
sage: from sage.modular.modform_hecketriangle.space import WeakModularForms
|
|
1482
|
+
sage: MF = WeakModularForms(n=9)
|
|
1483
|
+
sage: MF.g_inv()
|
|
1484
|
+
Traceback (most recent call last):
|
|
1485
|
+
...
|
|
1486
|
+
ArithmeticError: g_inv doesn't exist for odd n(=9).
|
|
1487
|
+
"""
|
|
1488
|
+
if self.hecke_n() == infinity:
|
|
1489
|
+
raise ArithmeticError("g_inv doesn't exist for n={} (it is not meromorphic at -1).".format(self._group.n()))
|
|
1490
|
+
if ZZ(2).divides(self._group.n()):
|
|
1491
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1492
|
+
return self.extend_type("weak", ring=True)(1/d*y*x**(self._group.n()/ZZ(2))/(x**self._group.n()-y**2)).reduce()
|
|
1493
|
+
else:
|
|
1494
|
+
raise ArithmeticError("g_inv doesn't exist for odd n(={}).".format(self._group.n()))
|
|
1495
|
+
|
|
1496
|
+
@cached_method
|
|
1497
|
+
def E4(self):
|
|
1498
|
+
r"""
|
|
1499
|
+
Return the normalized Eisenstein series of weight `4`.
|
|
1500
|
+
|
|
1501
|
+
It lies in a (holomorphic) extension of the graded ring of ``self``.
|
|
1502
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1503
|
+
the corresponding space of homogeneous elements.
|
|
1504
|
+
|
|
1505
|
+
It is equal to ``f_rho^(n-2)``.
|
|
1506
|
+
|
|
1507
|
+
NOTE:
|
|
1508
|
+
|
|
1509
|
+
If ``n=infinity`` the situation is different, there we have:
|
|
1510
|
+
``f_rho=1`` (since that's the limit as ``n`` goes to infinity)
|
|
1511
|
+
and the polynomial variable ``x`` refers to ``E4`` instead of
|
|
1512
|
+
``f_rho``. In that case ``E4`` has exactly one simple zero
|
|
1513
|
+
at the cusp ``-1``. Also note that ``E4`` is the limit of ``f_rho^n``.
|
|
1514
|
+
|
|
1515
|
+
EXAMPLES::
|
|
1516
|
+
|
|
1517
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, ModularFormsRing, CuspFormsRing
|
|
1518
|
+
sage: MR = ModularFormsRing(n=7)
|
|
1519
|
+
sage: E4 = MR.E4()
|
|
1520
|
+
sage: E4 in MR
|
|
1521
|
+
True
|
|
1522
|
+
sage: CuspFormsRing(n=7).E4() == E4
|
|
1523
|
+
True
|
|
1524
|
+
sage: E4
|
|
1525
|
+
f_rho^5
|
|
1526
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).E4() == QuasiMeromorphicModularFormsRing(n=7)(E4)
|
|
1527
|
+
True
|
|
1528
|
+
|
|
1529
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, CuspForms
|
|
1530
|
+
sage: MF = ModularForms(n=5, k=4)
|
|
1531
|
+
sage: E4 = MF.E4()
|
|
1532
|
+
sage: E4 in MF
|
|
1533
|
+
True
|
|
1534
|
+
sage: ModularFormsRing(n=5, red_hom=True).E4() == E4
|
|
1535
|
+
True
|
|
1536
|
+
sage: CuspForms(n=5, k=12).E4() == E4
|
|
1537
|
+
True
|
|
1538
|
+
sage: MF.disp_prec(3)
|
|
1539
|
+
sage: E4
|
|
1540
|
+
1 + 21/(100*d)*q + 483/(32000*d^2)*q^2 + O(q^3)
|
|
1541
|
+
|
|
1542
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1543
|
+
sage: MF = ModularForms(n=5)
|
|
1544
|
+
sage: d = MF.get_d()
|
|
1545
|
+
sage: q = MF.get_q()
|
|
1546
|
+
sage: ModularForms(n=5, k=4).E4().q_expansion(prec=5) == MFC(group=5, prec=7).E4_ZZ()(q/d).add_bigoh(5)
|
|
1547
|
+
True
|
|
1548
|
+
sage: ModularForms(n=infinity, k=4).E4().q_expansion(prec=5) == MFC(group=infinity, prec=7).E4_ZZ()(q/d).add_bigoh(5)
|
|
1549
|
+
True
|
|
1550
|
+
sage: ModularForms(n=5, k=4).E4().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).E4_ZZ().add_bigoh(5)
|
|
1551
|
+
True
|
|
1552
|
+
sage: ModularForms(n=infinity, k=4).E4().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).E4_ZZ().add_bigoh(5)
|
|
1553
|
+
True
|
|
1554
|
+
|
|
1555
|
+
sage: ModularForms(n=infinity, k=4).E4()
|
|
1556
|
+
1 + 16*q + 112*q^2 + 448*q^3 + 1136*q^4 + O(q^5)
|
|
1557
|
+
|
|
1558
|
+
sage: ModularForms(k=4).f_rho() == ModularForms(k=4).E4()
|
|
1559
|
+
True
|
|
1560
|
+
sage: ModularForms(k=4).E4()
|
|
1561
|
+
1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + O(q^5)
|
|
1562
|
+
"""
|
|
1563
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1564
|
+
|
|
1565
|
+
if self.hecke_n() == infinity:
|
|
1566
|
+
return self.extend_type("holo", ring=True)(x).reduce()
|
|
1567
|
+
return self.extend_type("holo", ring=True)(x**(self._group.n()-2)).reduce()
|
|
1568
|
+
|
|
1569
|
+
@cached_method
|
|
1570
|
+
def E6(self):
|
|
1571
|
+
r"""
|
|
1572
|
+
Return the normalized Eisenstein series of weight `6`.
|
|
1573
|
+
|
|
1574
|
+
It lies in a (holomorphic) extension of the graded ring of ``self``.
|
|
1575
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1576
|
+
the corresponding space of homogeneous elements.
|
|
1577
|
+
|
|
1578
|
+
It is equal to ``f_rho^(n-3) * f_i``.
|
|
1579
|
+
|
|
1580
|
+
EXAMPLES::
|
|
1581
|
+
|
|
1582
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, ModularFormsRing, CuspFormsRing
|
|
1583
|
+
sage: MR = ModularFormsRing(n=7)
|
|
1584
|
+
sage: E6 = MR.E6()
|
|
1585
|
+
sage: E6 in MR
|
|
1586
|
+
True
|
|
1587
|
+
sage: CuspFormsRing(n=7).E6() == E6
|
|
1588
|
+
True
|
|
1589
|
+
sage: E6
|
|
1590
|
+
f_rho^4*f_i
|
|
1591
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).E6() == QuasiMeromorphicModularFormsRing(n=7)(E6)
|
|
1592
|
+
True
|
|
1593
|
+
|
|
1594
|
+
sage: from sage.modular.modform_hecketriangle.space import ModularForms, CuspForms
|
|
1595
|
+
sage: MF = ModularForms(n=5, k=6)
|
|
1596
|
+
sage: E6 = MF.E6()
|
|
1597
|
+
sage: E6 in MF
|
|
1598
|
+
True
|
|
1599
|
+
sage: ModularFormsRing(n=5, red_hom=True).E6() == E6
|
|
1600
|
+
True
|
|
1601
|
+
sage: CuspForms(n=5, k=12).E6() == E6
|
|
1602
|
+
True
|
|
1603
|
+
sage: MF.disp_prec(3)
|
|
1604
|
+
sage: E6
|
|
1605
|
+
1 - 37/(200*d)*q - 14663/(320000*d^2)*q^2 + O(q^3)
|
|
1606
|
+
|
|
1607
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1608
|
+
sage: MF = ModularForms(n=5, k=6)
|
|
1609
|
+
sage: d = MF.get_d()
|
|
1610
|
+
sage: q = MF.get_q()
|
|
1611
|
+
sage: ModularForms(n=5, k=6).E6().q_expansion(prec=5) == MFC(group=5, prec=7).E6_ZZ()(q/d).add_bigoh(5)
|
|
1612
|
+
True
|
|
1613
|
+
sage: ModularForms(n=infinity, k=6).E6().q_expansion(prec=5) == MFC(group=infinity, prec=7).E6_ZZ()(q/d).add_bigoh(5)
|
|
1614
|
+
True
|
|
1615
|
+
sage: ModularForms(n=5, k=6).E6().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).E6_ZZ().add_bigoh(5)
|
|
1616
|
+
True
|
|
1617
|
+
sage: ModularForms(n=infinity, k=6).E6().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).E6_ZZ().add_bigoh(5)
|
|
1618
|
+
True
|
|
1619
|
+
|
|
1620
|
+
sage: ModularForms(n=infinity, k=6).E6()
|
|
1621
|
+
1 - 8*q - 248*q^2 - 1952*q^3 - 8440*q^4 + O(q^5)
|
|
1622
|
+
|
|
1623
|
+
sage: ModularForms(k=6).f_i() == ModularForms(k=6).E6()
|
|
1624
|
+
True
|
|
1625
|
+
sage: ModularForms(k=6).E6()
|
|
1626
|
+
1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 + O(q^5)
|
|
1627
|
+
"""
|
|
1628
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1629
|
+
|
|
1630
|
+
if self.hecke_n() == infinity:
|
|
1631
|
+
return self.extend_type("holo", ring=True)(x*y).reduce()
|
|
1632
|
+
return self.extend_type("holo", ring=True)(x**(self._group.n()-3)*y).reduce()
|
|
1633
|
+
|
|
1634
|
+
@cached_method
|
|
1635
|
+
def Delta(self):
|
|
1636
|
+
r"""
|
|
1637
|
+
Return an analog of the Delta-function.
|
|
1638
|
+
|
|
1639
|
+
It lies in the graded ring of ``self``. In case
|
|
1640
|
+
``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1641
|
+
the corresponding space of homogeneous elements.
|
|
1642
|
+
|
|
1643
|
+
It is a cusp form of weight `12` and is equal to ``d*(E4^3 -
|
|
1644
|
+
E6^2)`` or (in terms of the generators) ``d*x^(2*n-6)*(x^n -
|
|
1645
|
+
y^2)``.
|
|
1646
|
+
|
|
1647
|
+
Note that ``Delta`` is also a cusp form for ``n=infinity``.
|
|
1648
|
+
|
|
1649
|
+
EXAMPLES::
|
|
1650
|
+
|
|
1651
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, CuspFormsRing
|
|
1652
|
+
sage: MR = CuspFormsRing(n=7)
|
|
1653
|
+
sage: Delta = MR.Delta()
|
|
1654
|
+
sage: Delta in MR
|
|
1655
|
+
True
|
|
1656
|
+
sage: Delta
|
|
1657
|
+
f_rho^15*d - f_rho^8*f_i^2*d
|
|
1658
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).Delta() == QuasiMeromorphicModularFormsRing(n=7)(Delta)
|
|
1659
|
+
True
|
|
1660
|
+
|
|
1661
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms, ModularForms
|
|
1662
|
+
sage: MF = CuspForms(n=5, k=12)
|
|
1663
|
+
sage: Delta = MF.Delta()
|
|
1664
|
+
sage: Delta in MF
|
|
1665
|
+
True
|
|
1666
|
+
sage: CuspFormsRing(n=5, red_hom=True).Delta() == Delta
|
|
1667
|
+
True
|
|
1668
|
+
sage: CuspForms(n=5, k=0).Delta() == Delta
|
|
1669
|
+
True
|
|
1670
|
+
sage: MF.disp_prec(3)
|
|
1671
|
+
sage: Delta
|
|
1672
|
+
q + 47/(200*d)*q^2 + O(q^3)
|
|
1673
|
+
|
|
1674
|
+
sage: d = ModularForms(n=5).get_d()
|
|
1675
|
+
sage: Delta == (d*(ModularForms(n=5).E4()^3-ModularForms(n=5).E6()^2))
|
|
1676
|
+
True
|
|
1677
|
+
|
|
1678
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1679
|
+
sage: MF = CuspForms(n=5, k=12)
|
|
1680
|
+
sage: d = MF.get_d()
|
|
1681
|
+
sage: q = MF.get_q()
|
|
1682
|
+
sage: CuspForms(n=5, k=12).Delta().q_expansion(prec=5) == (d*MFC(group=5, prec=7).Delta_ZZ()(q/d)).add_bigoh(5)
|
|
1683
|
+
True
|
|
1684
|
+
sage: CuspForms(n=infinity, k=12).Delta().q_expansion(prec=5) == (d*MFC(group=infinity, prec=7).Delta_ZZ()(q/d)).add_bigoh(5)
|
|
1685
|
+
True
|
|
1686
|
+
sage: CuspForms(n=5, k=12).Delta().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).Delta_ZZ().add_bigoh(5)
|
|
1687
|
+
True
|
|
1688
|
+
sage: CuspForms(n=infinity, k=12).Delta().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).Delta_ZZ().add_bigoh(5)
|
|
1689
|
+
True
|
|
1690
|
+
|
|
1691
|
+
sage: CuspForms(n=infinity, k=12).Delta()
|
|
1692
|
+
q + 24*q^2 + 252*q^3 + 1472*q^4 + O(q^5)
|
|
1693
|
+
|
|
1694
|
+
sage: CuspForms(k=12).f_inf() == CuspForms(k=12).Delta()
|
|
1695
|
+
True
|
|
1696
|
+
sage: CuspForms(k=12).Delta()
|
|
1697
|
+
q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)
|
|
1698
|
+
"""
|
|
1699
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1700
|
+
|
|
1701
|
+
if self.hecke_n() == infinity:
|
|
1702
|
+
return self.extend_type("cusp", ring=True)(d*x**2*(x-y**2)).reduce()
|
|
1703
|
+
return self.extend_type("cusp", ring=True)(d*x**(2*self._group.n()-6)*(x**self._group.n()-y**2)).reduce()
|
|
1704
|
+
|
|
1705
|
+
@cached_method
|
|
1706
|
+
def E2(self):
|
|
1707
|
+
r"""
|
|
1708
|
+
Return the normalized quasi holomorphic Eisenstein series of weight `2`.
|
|
1709
|
+
|
|
1710
|
+
It lies in a (quasi holomorphic) extension of the graded ring of ``self``.
|
|
1711
|
+
In case ``has_reduce_hom`` is ``True`` it is given as an element of
|
|
1712
|
+
the corresponding space of homogeneous elements.
|
|
1713
|
+
|
|
1714
|
+
It is in particular also a generator of the graded ring of
|
|
1715
|
+
``self`` and the polynomial variable ``z`` exactly corresponds to ``E2``.
|
|
1716
|
+
|
|
1717
|
+
EXAMPLES::
|
|
1718
|
+
|
|
1719
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing, QuasiModularFormsRing, CuspFormsRing
|
|
1720
|
+
sage: MR = QuasiModularFormsRing(n=7)
|
|
1721
|
+
sage: E2 = MR.E2()
|
|
1722
|
+
sage: E2 in MR
|
|
1723
|
+
True
|
|
1724
|
+
sage: CuspFormsRing(n=7).E2() == E2
|
|
1725
|
+
True
|
|
1726
|
+
sage: E2
|
|
1727
|
+
E2
|
|
1728
|
+
sage: QuasiMeromorphicModularFormsRing(n=7).E2() == QuasiMeromorphicModularFormsRing(n=7)(E2)
|
|
1729
|
+
True
|
|
1730
|
+
|
|
1731
|
+
sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms, CuspForms
|
|
1732
|
+
sage: MF = QuasiModularForms(n=5, k=2)
|
|
1733
|
+
sage: E2 = MF.E2()
|
|
1734
|
+
sage: E2 in MF
|
|
1735
|
+
True
|
|
1736
|
+
sage: QuasiModularFormsRing(n=5, red_hom=True).E2() == E2
|
|
1737
|
+
True
|
|
1738
|
+
sage: CuspForms(n=5, k=12, ep=1).E2() == E2
|
|
1739
|
+
True
|
|
1740
|
+
sage: MF.disp_prec(3)
|
|
1741
|
+
sage: E2
|
|
1742
|
+
1 - 9/(200*d)*q - 369/(320000*d^2)*q^2 + O(q^3)
|
|
1743
|
+
|
|
1744
|
+
sage: f_inf = MF.f_inf()
|
|
1745
|
+
sage: E2 == f_inf.derivative() / f_inf
|
|
1746
|
+
True
|
|
1747
|
+
|
|
1748
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1749
|
+
sage: MF = QuasiModularForms(n=5, k=2)
|
|
1750
|
+
sage: d = MF.get_d()
|
|
1751
|
+
sage: q = MF.get_q()
|
|
1752
|
+
sage: QuasiModularForms(n=5, k=2).E2().q_expansion(prec=5) == MFC(group=5, prec=7).E2_ZZ()(q/d).add_bigoh(5)
|
|
1753
|
+
True
|
|
1754
|
+
sage: QuasiModularForms(n=infinity, k=2).E2().q_expansion(prec=5) == MFC(group=infinity, prec=7).E2_ZZ()(q/d).add_bigoh(5)
|
|
1755
|
+
True
|
|
1756
|
+
sage: QuasiModularForms(n=5, k=2).E2().q_expansion(fix_d=1, prec=5) == MFC(group=5, prec=7).E2_ZZ().add_bigoh(5)
|
|
1757
|
+
True
|
|
1758
|
+
sage: QuasiModularForms(n=infinity, k=2).E2().q_expansion(fix_d=1, prec=5) == MFC(group=infinity, prec=7).E2_ZZ().add_bigoh(5)
|
|
1759
|
+
True
|
|
1760
|
+
|
|
1761
|
+
sage: QuasiModularForms(n=infinity, k=2).E2()
|
|
1762
|
+
1 - 8*q - 8*q^2 - 32*q^3 - 40*q^4 + O(q^5)
|
|
1763
|
+
|
|
1764
|
+
sage: QuasiModularForms(k=2).E2()
|
|
1765
|
+
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 + O(q^5)
|
|
1766
|
+
"""
|
|
1767
|
+
x, y, z, d = self._pol_ring.gens()
|
|
1768
|
+
return self.extend_type(["holo", "quasi"], ring=True)(z).reduce()
|
|
1769
|
+
|
|
1770
|
+
@cached_method
|
|
1771
|
+
def EisensteinSeries(self, k=None):
|
|
1772
|
+
r"""
|
|
1773
|
+
Return the normalized Eisenstein series of weight ``k``.
|
|
1774
|
+
|
|
1775
|
+
Only arithmetic groups or trivial weights (with corresponding
|
|
1776
|
+
one dimensional spaces) are supported.
|
|
1777
|
+
|
|
1778
|
+
INPUT:
|
|
1779
|
+
|
|
1780
|
+
- ``k`` -- a nonnegative even integer, namely the weight.
|
|
1781
|
+
If ``k`` is ``None`` (default) then the weight of ``self`` is chosen if
|
|
1782
|
+
``self`` is homogeneous and the weight is possible, otherwise ``k``
|
|
1783
|
+
is set to `0`.
|
|
1784
|
+
|
|
1785
|
+
OUTPUT:
|
|
1786
|
+
|
|
1787
|
+
A modular form element lying in a (holomorphic) extension of
|
|
1788
|
+
the graded ring of ``self``. In case ``has_reduce_hom`` is
|
|
1789
|
+
``True`` it is given as an element of the corresponding
|
|
1790
|
+
space of homogeneous elements.
|
|
1791
|
+
|
|
1792
|
+
EXAMPLES::
|
|
1793
|
+
|
|
1794
|
+
sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing, CuspFormsRing
|
|
1795
|
+
sage: MR = ModularFormsRing()
|
|
1796
|
+
sage: MR.EisensteinSeries() == MR.one()
|
|
1797
|
+
True
|
|
1798
|
+
sage: E8 = MR.EisensteinSeries(k=8)
|
|
1799
|
+
sage: E8 in MR
|
|
1800
|
+
True
|
|
1801
|
+
sage: E8
|
|
1802
|
+
f_rho^2
|
|
1803
|
+
|
|
1804
|
+
sage: from sage.modular.modform_hecketriangle.space import CuspForms, ModularForms
|
|
1805
|
+
sage: MF = ModularForms(n=4, k=12)
|
|
1806
|
+
sage: E12 = MF.EisensteinSeries()
|
|
1807
|
+
sage: E12 in MF
|
|
1808
|
+
True
|
|
1809
|
+
sage: CuspFormsRing(n=4, red_hom=True).EisensteinSeries(k=12).parent()
|
|
1810
|
+
ModularForms(n=4, k=12, ep=1) over Integer Ring
|
|
1811
|
+
sage: MF.disp_prec(4)
|
|
1812
|
+
sage: E12
|
|
1813
|
+
1 + 1008/691*q + 2129904/691*q^2 + 178565184/691*q^3 + O(q^4)
|
|
1814
|
+
|
|
1815
|
+
sage: from sage.modular.modform_hecketriangle.series_constructor import MFSeriesConstructor as MFC
|
|
1816
|
+
sage: d = MF.get_d()
|
|
1817
|
+
sage: q = MF.get_q()
|
|
1818
|
+
sage: ModularForms(n=3, k=2).EisensteinSeries().q_expansion(prec=5) == MFC(group=3, prec=7).EisensteinSeries_ZZ(k=2)(q/d).add_bigoh(5)
|
|
1819
|
+
True
|
|
1820
|
+
sage: ModularForms(n=3, k=4).EisensteinSeries().q_expansion(prec=5) == MFC(group=3, prec=7).EisensteinSeries_ZZ(k=4)(q/d).add_bigoh(5)
|
|
1821
|
+
True
|
|
1822
|
+
sage: ModularForms(n=3, k=6).EisensteinSeries().q_expansion(prec=5) == MFC(group=3, prec=7).EisensteinSeries_ZZ(k=6)(q/d).add_bigoh(5)
|
|
1823
|
+
True
|
|
1824
|
+
sage: ModularForms(n=3, k=8).EisensteinSeries().q_expansion(prec=5) == MFC(group=3, prec=7).EisensteinSeries_ZZ(k=8)(q/d).add_bigoh(5)
|
|
1825
|
+
True
|
|
1826
|
+
sage: ModularForms(n=4, k=2).EisensteinSeries().q_expansion(prec=5) == MFC(group=4, prec=7).EisensteinSeries_ZZ(k=2)(q/d).add_bigoh(5)
|
|
1827
|
+
True
|
|
1828
|
+
sage: ModularForms(n=4, k=4).EisensteinSeries().q_expansion(prec=5) == MFC(group=4, prec=7).EisensteinSeries_ZZ(k=4)(q/d).add_bigoh(5)
|
|
1829
|
+
True
|
|
1830
|
+
sage: ModularForms(n=4, k=6).EisensteinSeries().q_expansion(prec=5) == MFC(group=4, prec=7).EisensteinSeries_ZZ(k=6)(q/d).add_bigoh(5)
|
|
1831
|
+
True
|
|
1832
|
+
sage: ModularForms(n=4, k=8).EisensteinSeries().q_expansion(prec=5) == MFC(group=4, prec=7).EisensteinSeries_ZZ(k=8)(q/d).add_bigoh(5)
|
|
1833
|
+
True
|
|
1834
|
+
sage: ModularForms(n=6, k=2, ep=-1).EisensteinSeries().q_expansion(prec=5) == MFC(group=6, prec=7).EisensteinSeries_ZZ(k=2)(q/d).add_bigoh(5)
|
|
1835
|
+
True
|
|
1836
|
+
sage: ModularForms(n=6, k=4).EisensteinSeries().q_expansion(prec=5) == MFC(group=6, prec=7).EisensteinSeries_ZZ(k=4)(q/d).add_bigoh(5)
|
|
1837
|
+
True
|
|
1838
|
+
sage: ModularForms(n=6, k=6, ep=-1).EisensteinSeries().q_expansion(prec=5) == MFC(group=6, prec=7).EisensteinSeries_ZZ(k=6)(q/d).add_bigoh(5)
|
|
1839
|
+
True
|
|
1840
|
+
sage: ModularForms(n=6, k=8).EisensteinSeries().q_expansion(prec=5) == MFC(group=6, prec=7).EisensteinSeries_ZZ(k=8)(q/d).add_bigoh(5)
|
|
1841
|
+
True
|
|
1842
|
+
|
|
1843
|
+
sage: ModularForms(n=3, k=12).EisensteinSeries()
|
|
1844
|
+
1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + O(q^5)
|
|
1845
|
+
sage: ModularForms(n=4, k=12).EisensteinSeries()
|
|
1846
|
+
1 + 1008/691*q + 2129904/691*q^2 + 178565184/691*q^3 + O(q^4)
|
|
1847
|
+
sage: ModularForms(n=6, k=12).EisensteinSeries()
|
|
1848
|
+
1 + 6552/50443*q + 13425048/50443*q^2 + 1165450104/50443*q^3 + 27494504856/50443*q^4 + O(q^5)
|
|
1849
|
+
sage: ModularForms(n=3, k=20).EisensteinSeries()
|
|
1850
|
+
1 + 13200/174611*q + 6920614800/174611*q^2 + 15341851377600/174611*q^3 + 3628395292275600/174611*q^4 + O(q^5)
|
|
1851
|
+
sage: ModularForms(n=4).EisensteinSeries(k=8)
|
|
1852
|
+
1 + 480/17*q + 69600/17*q^2 + 1050240/17*q^3 + 8916960/17*q^4 + O(q^5)
|
|
1853
|
+
sage: ModularForms(n=6).EisensteinSeries(k=20)
|
|
1854
|
+
1 + 264/206215591*q + 138412296/206215591*q^2 + 306852616488/206215591*q^3 + 72567905845512/206215591*q^4 + O(q^5)
|
|
1855
|
+
"""
|
|
1856
|
+
|
|
1857
|
+
n = self.hecke_n()
|
|
1858
|
+
|
|
1859
|
+
# For now we completely disable Eisenstein series for n == infinity,
|
|
1860
|
+
# but leave some related basic variables intact.
|
|
1861
|
+
if n == infinity:
|
|
1862
|
+
raise NotImplementedError("In the case n=infinity, the Eisenstein series is not unique and more parameters are required.")
|
|
1863
|
+
|
|
1864
|
+
if k is None:
|
|
1865
|
+
try:
|
|
1866
|
+
if not self.is_homogeneous():
|
|
1867
|
+
raise TypeError(None)
|
|
1868
|
+
k = self.weight()
|
|
1869
|
+
if k < 0:
|
|
1870
|
+
raise TypeError(None)
|
|
1871
|
+
k = 2*ZZ(k/2)
|
|
1872
|
+
# if self.ep() != ZZ(-1)**ZZ(k/2):
|
|
1873
|
+
# raise TypeError
|
|
1874
|
+
except TypeError:
|
|
1875
|
+
k = ZZ.zero()
|
|
1876
|
+
|
|
1877
|
+
try:
|
|
1878
|
+
if k < 0:
|
|
1879
|
+
raise TypeError(None)
|
|
1880
|
+
k = 2*ZZ(k/2)
|
|
1881
|
+
except TypeError:
|
|
1882
|
+
raise TypeError("k={} must be a nonnegative even integer!".format(k))
|
|
1883
|
+
|
|
1884
|
+
# The case n=infinity is special (there are 2 cusps)
|
|
1885
|
+
# Until we/I get confirmation what is what sort of Eisenstein series
|
|
1886
|
+
# this case is excluded...
|
|
1887
|
+
if n == infinity:
|
|
1888
|
+
# We set the weight zero Eisenstein series to 1
|
|
1889
|
+
pass
|
|
1890
|
+
elif k == 0:
|
|
1891
|
+
return self.one()
|
|
1892
|
+
elif k == 2:
|
|
1893
|
+
# This is a bit problematic, e.g. for n=infinity there is a
|
|
1894
|
+
# classical Eisenstein series of weight 2
|
|
1895
|
+
return self.E2()
|
|
1896
|
+
elif k == 4:
|
|
1897
|
+
return self.E4()
|
|
1898
|
+
elif k == 6:
|
|
1899
|
+
return self.E6()
|
|
1900
|
+
|
|
1901
|
+
# Basic variables
|
|
1902
|
+
ep = (-ZZ(1))**(k/2)
|
|
1903
|
+
extended_self = self.extend_type(["holo"], ring=True)
|
|
1904
|
+
# reduced_self is a classical ModularForms space
|
|
1905
|
+
reduced_self = extended_self.reduce_type(["holo"], degree=(QQ(k), ep))
|
|
1906
|
+
|
|
1907
|
+
if n == infinity:
|
|
1908
|
+
l2 = ZZ.zero()
|
|
1909
|
+
l1 = ZZ((k-(1-ep)) / ZZ(4))
|
|
1910
|
+
else:
|
|
1911
|
+
num = ZZ((k-(1-ep)*n/(n-2)) * (n-2) / ZZ(4))
|
|
1912
|
+
l2 = num % n
|
|
1913
|
+
l1 = ((num-l2)/n).numerator()
|
|
1914
|
+
|
|
1915
|
+
# If the space is one dimensional we return the normalized generator
|
|
1916
|
+
if l1 == 0:
|
|
1917
|
+
return extended_self(reduced_self.F_basis(0)).reduce()
|
|
1918
|
+
|
|
1919
|
+
# The non-arithmetic remaining cases (incomplete, very hard in general)
|
|
1920
|
+
# TODO: the n = infinity case(s) (doable)
|
|
1921
|
+
# TODO: the n = 5 case (hard)
|
|
1922
|
+
if not self.group().is_arithmetic() or n == infinity:
|
|
1923
|
+
raise NotImplementedError("Eisenstein series are only supported in the finite arithmetic cases")
|
|
1924
|
+
|
|
1925
|
+
# The arithmetic cases
|
|
1926
|
+
prec = reduced_self._l1 + 1
|
|
1927
|
+
MFC = MFSeriesConstructor(group=self.group(), prec=prec)
|
|
1928
|
+
d = self.get_d()
|
|
1929
|
+
q = self.get_q()
|
|
1930
|
+
q_series = MFC.EisensteinSeries_ZZ(k=k)(q/d)
|
|
1931
|
+
|
|
1932
|
+
return extended_self(reduced_self.construct_form(q_series, check=False)).reduce()
|