passagemath-schemes 10.6.47__cp312-cp312-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.
Files changed (311) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
  9. passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list_nf.py +1241 -0
  154. sage/modular/modsym/relation_matrix.py +591 -0
  155. sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
  156. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  157. sage/modular/modsym/space.py +2468 -0
  158. sage/modular/modsym/subspace.py +455 -0
  159. sage/modular/modsym/tests.py +375 -0
  160. sage/modular/multiple_zeta.py +2632 -0
  161. sage/modular/multiple_zeta_F_algebra.py +786 -0
  162. sage/modular/overconvergent/all.py +6 -0
  163. sage/modular/overconvergent/genus0.py +1878 -0
  164. sage/modular/overconvergent/hecke_series.py +1187 -0
  165. sage/modular/overconvergent/weightspace.py +778 -0
  166. sage/modular/pollack_stevens/all.py +4 -0
  167. sage/modular/pollack_stevens/distributions.py +874 -0
  168. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  169. sage/modular/pollack_stevens/manin_map.py +859 -0
  170. sage/modular/pollack_stevens/modsym.py +1593 -0
  171. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  172. sage/modular/pollack_stevens/sigma0.py +534 -0
  173. sage/modular/pollack_stevens/space.py +1076 -0
  174. sage/modular/quasimodform/all.py +3 -0
  175. sage/modular/quasimodform/element.py +845 -0
  176. sage/modular/quasimodform/ring.py +828 -0
  177. sage/modular/quatalg/all.py +3 -0
  178. sage/modular/quatalg/brandt.py +1642 -0
  179. sage/modular/ssmod/all.py +8 -0
  180. sage/modular/ssmod/ssmod.py +827 -0
  181. sage/rings/all__sagemath_schemes.py +1 -0
  182. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  183. sage/rings/polynomial/binary_form_reduce.py +585 -0
  184. sage/schemes/all.py +41 -0
  185. sage/schemes/berkovich/all.py +6 -0
  186. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  187. sage/schemes/berkovich/berkovich_space.py +748 -0
  188. sage/schemes/curves/affine_curve.py +2928 -0
  189. sage/schemes/curves/all.py +33 -0
  190. sage/schemes/curves/closed_point.py +434 -0
  191. sage/schemes/curves/constructor.py +381 -0
  192. sage/schemes/curves/curve.py +542 -0
  193. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  194. sage/schemes/curves/point.py +463 -0
  195. sage/schemes/curves/projective_curve.py +3026 -0
  196. sage/schemes/curves/zariski_vankampen.py +1932 -0
  197. sage/schemes/cyclic_covers/all.py +2 -0
  198. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  199. sage/schemes/cyclic_covers/constructor.py +137 -0
  200. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  201. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  202. sage/schemes/elliptic_curves/BSD.py +1036 -0
  203. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  204. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  205. sage/schemes/elliptic_curves/all.py +49 -0
  206. sage/schemes/elliptic_curves/cardinality.py +609 -0
  207. sage/schemes/elliptic_curves/cm.py +1102 -0
  208. sage/schemes/elliptic_curves/constructor.py +1552 -0
  209. sage/schemes/elliptic_curves/ec_database.py +175 -0
  210. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  211. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  212. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  213. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  214. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  215. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  216. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  217. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  218. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  219. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  220. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  221. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  222. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  223. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  224. sage/schemes/elliptic_curves/formal_group.py +760 -0
  225. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  226. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  227. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  228. sage/schemes/elliptic_curves/heegner.py +7335 -0
  229. sage/schemes/elliptic_curves/height.py +2109 -0
  230. sage/schemes/elliptic_curves/hom.py +1406 -0
  231. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  232. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  233. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  234. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  235. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  236. sage/schemes/elliptic_curves/homset.py +271 -0
  237. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  238. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  239. sage/schemes/elliptic_curves/jacobian.py +237 -0
  240. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  241. sage/schemes/elliptic_curves/kraus.py +1014 -0
  242. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  243. sage/schemes/elliptic_curves/mod5family.py +105 -0
  244. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  245. sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
  246. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  247. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  248. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  249. sage/schemes/elliptic_curves/padics.py +1816 -0
  250. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  251. sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
  252. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  253. sage/schemes/elliptic_curves/saturation.py +715 -0
  254. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  255. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  256. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  257. sage/schemes/hyperelliptic_curves/all.py +6 -0
  258. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  259. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  260. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  261. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  264. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  265. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  266. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  267. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  270. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  271. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  272. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  273. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  274. sage/schemes/jacobians/all.py +2 -0
  275. sage/schemes/overview.py +161 -0
  276. sage/schemes/plane_conics/all.py +22 -0
  277. sage/schemes/plane_conics/con_field.py +1296 -0
  278. sage/schemes/plane_conics/con_finite_field.py +158 -0
  279. sage/schemes/plane_conics/con_number_field.py +456 -0
  280. sage/schemes/plane_conics/con_rational_field.py +406 -0
  281. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  282. sage/schemes/plane_conics/constructor.py +249 -0
  283. sage/schemes/plane_quartics/all.py +2 -0
  284. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  285. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  286. sage/schemes/riemann_surfaces/all.py +1 -0
  287. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  288. sage_wheels/share/cremona/cremona_mini.db +0 -0
  289. sage_wheels/share/ellcurves/rank0 +30427 -0
  290. sage_wheels/share/ellcurves/rank1 +31871 -0
  291. sage_wheels/share/ellcurves/rank10 +6 -0
  292. sage_wheels/share/ellcurves/rank11 +6 -0
  293. sage_wheels/share/ellcurves/rank12 +1 -0
  294. sage_wheels/share/ellcurves/rank14 +1 -0
  295. sage_wheels/share/ellcurves/rank15 +1 -0
  296. sage_wheels/share/ellcurves/rank17 +1 -0
  297. sage_wheels/share/ellcurves/rank19 +1 -0
  298. sage_wheels/share/ellcurves/rank2 +2388 -0
  299. sage_wheels/share/ellcurves/rank20 +1 -0
  300. sage_wheels/share/ellcurves/rank21 +1 -0
  301. sage_wheels/share/ellcurves/rank22 +1 -0
  302. sage_wheels/share/ellcurves/rank23 +1 -0
  303. sage_wheels/share/ellcurves/rank24 +1 -0
  304. sage_wheels/share/ellcurves/rank28 +1 -0
  305. sage_wheels/share/ellcurves/rank3 +836 -0
  306. sage_wheels/share/ellcurves/rank4 +10 -0
  307. sage_wheels/share/ellcurves/rank5 +5 -0
  308. sage_wheels/share/ellcurves/rank6 +5 -0
  309. sage_wheels/share/ellcurves/rank7 +5 -0
  310. sage_wheels/share/ellcurves/rank8 +6 -0
  311. 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()