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,845 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.combinat sage.libs.flint
3
+ """
4
+ Elements of quasimodular forms rings
5
+
6
+ AUTHORS:
7
+
8
+ - DAVID AYOTTE (2021-03-18): initial version
9
+ - Seewoo Lee (2023-09): coefficients method
10
+ """
11
+ # ****************************************************************************
12
+ # Copyright (C) 2021 David Ayotte
13
+ # 2023 Seewoo Lee <seewoo5@berkeley.edu>
14
+ #
15
+ #
16
+ # This program is free software: you can redistribute it and/or modify
17
+ # it under the terms of the GNU General Public License as published by
18
+ # the Free Software Foundation, either version 2 of the License, or
19
+ # (at your option) any later version.
20
+ # https://www.gnu.org/licenses/
21
+ # ****************************************************************************
22
+
23
+ from sage.modular.arithgroup.congroup_sl2z import SL2Z_class
24
+ from sage.modular.modform.constructor import EisensteinForms
25
+ from sage.modular.modform.eis_series import eisenstein_series_qexp
26
+ from sage.modular.modform.element import GradedModularFormElement
27
+
28
+ from sage.structure.element import ModuleElement
29
+ from sage.structure.richcmp import richcmp, op_NE, op_EQ
30
+
31
+ from sage.rings.integer import Integer
32
+ from sage.rings.polynomial.polynomial_element import Polynomial
33
+ from sage.rings.integer_ring import ZZ
34
+
35
+
36
+ class QuasiModularFormsElement(ModuleElement):
37
+ r"""
38
+ A quasimodular forms ring element. Such an element is described by
39
+ SageMath as a polynomial
40
+
41
+ .. MATH::
42
+
43
+ F = f_0 + f_1 E_2 + f_2 E_2^2 + \cdots + f_m E_2^m
44
+
45
+ where each `f_i` a graded modular form element
46
+ (see :class:`~sage.modular.modform.element.GradedModularFormElement`)
47
+
48
+ For an integer `k`, we say that `F` is homogeneous of weight `k` if
49
+ it lies in an homogeneous component of degree `k` of the graded ring
50
+ of quasimodular forms.
51
+
52
+ EXAMPLES::
53
+
54
+ sage: QM = QuasiModularForms(1)
55
+ sage: QM.gens()
56
+ (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
57
+ 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
58
+ 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6))
59
+ sage: QM.0 + QM.1
60
+ 2 + 216*q + 2088*q^2 + 6624*q^3 + 17352*q^4 + 30096*q^5 + O(q^6)
61
+ sage: QM.0 * QM.1
62
+ 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6)
63
+ sage: (QM.0)^2
64
+ 1 - 48*q + 432*q^2 + 3264*q^3 + 9456*q^4 + 21600*q^5 + O(q^6)
65
+ sage: QM.0 == QM.1
66
+ False
67
+
68
+ Quasimodular forms ring element can be created via a polynomial in `E2` over the ring of modular forms::
69
+
70
+ sage: E2 = QM.polygen()
71
+ sage: E2.parent()
72
+ Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
73
+ sage: QM(E2)
74
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
75
+ sage: M = QM.modular_forms_subring()
76
+ sage: QM(M.0 * E2 + M.1 * E2^2)
77
+ 2 - 336*q + 4320*q^2 + 398400*q^3 - 3772992*q^4 - 89283168*q^5 + O(q^6)
78
+
79
+ One may convert a quasimodular form into a multivariate polynomial in the
80
+ generators of the ring by calling
81
+ :meth:`~sage.modular.quasimodform.element.QuasiModularFormsElement.polynomial`::
82
+
83
+ sage: QM = QuasiModularForms(1)
84
+ sage: F = QM.0^2 + QM.1^2 + QM.0*QM.1*QM.2
85
+ sage: F.polynomial()
86
+ E2*E4*E6 + E4^2 + E2^2
87
+
88
+ If the group is not the full modular group, the default names of the
89
+ generators are given by ``Ek_i`` and ``Sk_i`` to denote the `i`-th basis
90
+ element of the weight `k` Eisenstein subspace and cuspidal subspace
91
+ respectively (for more details, see the documentation of
92
+ :meth:`~sage.modular.quasimodform.ring.QuasiModularFormsRing.polynomial_ring`) ::
93
+
94
+ sage: QM = QuasiModularForms(Gamma1(4))
95
+ sage: F = (QM.0^4)*(QM.1^3) + QM.3
96
+ sage: F.polynomial()
97
+ -512*E2^4*E2_1^3 + E2^4*E3_0^2 + 48*E2^4*E3_1^2 + E3_0
98
+ """
99
+ def __init__(self, parent, polynomial):
100
+ r"""
101
+ INPUT:
102
+
103
+ - ``parent`` -- a quasimodular forms ring
104
+ - ``polynomial`` -- a polynomial `f_0 + f_1 E_2 + ... + f_n E_2^n` where
105
+ each `f_i` are modular forms ring elements and `E_2` correspond to the
106
+ weight 2 Eisenstein series
107
+
108
+ OUTPUT: ``QuasiModularFormsElement``
109
+
110
+ TESTS::
111
+
112
+ sage: QM = QuasiModularForms(1)
113
+ sage: QM.element_class(QM, 'E2')
114
+ Traceback (most recent call last):
115
+ ...
116
+ TypeError: 'polynomial' argument should be of type 'Polynomial'
117
+ sage: x = polygen(QQ)
118
+ sage: QM.element_class(QM, x^2 + 1)
119
+ Traceback (most recent call last):
120
+ ...
121
+ ValueError: at least one coefficient is not a 'GradedModularFormElement'
122
+ """
123
+ if not isinstance(polynomial, Polynomial):
124
+ raise TypeError("'polynomial' argument should be of type 'Polynomial'")
125
+ for f in polynomial.coefficients():
126
+ if not isinstance(f, GradedModularFormElement):
127
+ raise ValueError("at least one coefficient is not a 'GradedModularFormElement'")
128
+ self._polynomial = polynomial
129
+ ModuleElement.__init__(self, parent)
130
+
131
+ def q_expansion(self, prec=6):
132
+ r"""
133
+ Return the `q`-expansion of the given quasimodular form up to precision
134
+ ``prec`` (default: 6).
135
+
136
+ An alias of this method is ``qexp``.
137
+
138
+ EXAMPLES::
139
+
140
+ sage: QM = QuasiModularForms()
141
+ sage: E2 = QM.0
142
+ sage: E2.q_expansion()
143
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
144
+ sage: E2.q_expansion(prec=10)
145
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10)
146
+ """
147
+ E2 = eisenstein_series_qexp(2, prec=prec, K=self.base_ring(), normalization='constant') # normalization -> to force integer coefficients
148
+ coefficients = self._polynomial.coefficients(sparse=False)
149
+ return sum(f.q_expansion(prec=prec) * E2**idx for idx, f in enumerate(coefficients))
150
+
151
+ qexp = q_expansion # alias
152
+
153
+ def _repr_(self):
154
+ r"""
155
+ String representation of ``self``.
156
+
157
+ TESTS::
158
+
159
+ sage: QM = QuasiModularForms()
160
+ sage: QM.0
161
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
162
+ sage: QM.1
163
+ 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
164
+ sage: QM.2
165
+ 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)
166
+ """
167
+ return str(self.q_expansion())
168
+
169
+ def _latex_(self):
170
+ r"""
171
+ Return a latex representation of ``self``.
172
+
173
+ TESTS::
174
+
175
+ sage: QM = QuasiModularForms(1)
176
+ sage: latex(QM.0)
177
+ 1 - 24 q - 72 q^{2} - 96 q^{3} - 168 q^{4} - 144 q^{5} + O(q^{6})
178
+ """
179
+ return self.q_expansion()._latex_()
180
+
181
+ def _richcmp_(self, other, op):
182
+ r"""
183
+ Compare ``self`` with ``other``.
184
+
185
+ TESTS::
186
+
187
+ sage: QM = QuasiModularForms(1)
188
+ sage: QM.0 == QM.1
189
+ False
190
+ sage: QM.0 == QM.0
191
+ True
192
+ sage: QM.0 != QM.1
193
+ True
194
+ sage: QM.0 != QM.0
195
+ False
196
+ sage: QM.0 < QM.1
197
+ Traceback (most recent call last):
198
+ ...
199
+ TypeError: invalid comparison between quasimodular forms ring elements
200
+ """
201
+ if op != op_EQ and op != op_NE:
202
+ raise TypeError('invalid comparison between quasimodular forms ring elements')
203
+ return richcmp(self._polynomial, other._polynomial, op)
204
+
205
+ def _add_(self, other):
206
+ r"""
207
+ Addition of two ``QuasiModularFormElement``.
208
+
209
+ INPUT:
210
+
211
+ - ``other`` -- ``QuasiModularFormElement``
212
+
213
+ OUTPUT: a ``QuasiModularFormElement``
214
+
215
+ TESTS::
216
+
217
+ sage: QM = QuasiModularForms(1)
218
+ sage: QM.0 + QM.1
219
+ 2 + 216*q + 2088*q^2 + 6624*q^3 + 17352*q^4 + 30096*q^5 + O(q^6)
220
+ sage: QM.0 + (QM.1 + QM.2) == (QM.0 + QM.1) + QM.2
221
+ True
222
+ sage: QM = QuasiModularForms(5)
223
+ sage: QM.0 + QM.1 + QM.2 + QM.3
224
+ 3 - 17*q - 54*q^2 - 62*q^3 - 98*q^4 + 137*q^5 + O(q^6)
225
+ """
226
+ return self.__class__(self.parent(), self._polynomial + other._polynomial)
227
+
228
+ def __neg__(self):
229
+ r"""
230
+ The negation of ``self``.
231
+
232
+ TESTS::
233
+
234
+ sage: -QuasiModularForms(1).0
235
+ -1 + 24*q + 72*q^2 + 96*q^3 + 168*q^4 + 144*q^5 + O(q^6)
236
+ sage: QuasiModularForms(1).0 - QuasiModularForms(1).0
237
+ 0
238
+ sage: -QuasiModularForms(Gamma1(2)).2
239
+ -1 - 240*q^2 - 2160*q^4 + O(q^6)
240
+ """
241
+ return self.__class__(self.parent(), -self._polynomial)
242
+
243
+ def _mul_(self, other):
244
+ r"""
245
+ The multiplication of two ``QuasiModularFormElement``.
246
+
247
+ INPUT:
248
+
249
+ - ``other`` -- ``QuasiModularFormElement``
250
+
251
+ OUTPUT: a ``QuasiModularFormElement``
252
+
253
+ TESTS::
254
+
255
+ sage: QM = QuasiModularForms(1)
256
+ sage: QM.0 * QM.1
257
+ 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6)
258
+ sage: (QM.0 * QM.1) * QM.2 == QM.0 * (QM.1 * QM.2)
259
+ True
260
+ sage: QM = QuasiModularForms(Gamma1(5))
261
+ sage: QM.0 * QM.1 * QM.2
262
+ q - 24*q^2 - 66*q^3 - 189*q^4 - 1917*q^5 + O(q^6)
263
+ """
264
+ return self.__class__(self.parent(), self._polynomial * other._polynomial)
265
+
266
+ def _lmul_(self, c):
267
+ r"""
268
+ The left action of the base ring on ``self``.
269
+
270
+ INPUT:
271
+
272
+ - ``other`` -- ``QuasiModularFormElement``
273
+
274
+ OUTPUT: a ``QuasiModularFormElement``
275
+
276
+ TESTS::
277
+
278
+ sage: QM = QuasiModularForms(1)
279
+ sage: (1/2) * QM.0
280
+ 1/2 - 12*q - 36*q^2 - 48*q^3 - 84*q^4 - 72*q^5 + O(q^6)
281
+ sage: QM.0 * (3/2)
282
+ 3/2 - 36*q - 108*q^2 - 144*q^3 - 252*q^4 - 216*q^5 + O(q^6)
283
+ sage: (5/2) * QuasiModularForms(Gamma0(7)).0 * (3/2)
284
+ 15/4 - 90*q - 270*q^2 - 360*q^3 - 630*q^4 - 540*q^5 + O(q^6)
285
+ """
286
+ return self.__class__(self.parent(), c * self._polynomial)
287
+
288
+ def __bool__(self):
289
+ r"""
290
+ Return whether ``self`` is nonzero.
291
+
292
+ EXAMPLES::
293
+
294
+ sage: QM = QuasiModularForms(1)
295
+ sage: bool(QM(0))
296
+ False
297
+ sage: bool(QM(1))
298
+ True
299
+ sage: bool(QM.0)
300
+ True
301
+ """
302
+ return bool(self._polynomial)
303
+
304
+ def depth(self):
305
+ r"""
306
+ Return the depth of this quasimodular form.
307
+
308
+ Note that the quasimodular form must be homogeneous of weight
309
+ `k`. Recall that the *depth* is the integer `p` such that
310
+
311
+ .. MATH::
312
+
313
+ f = f_0 + f_1 E_2 + \cdots + f_p E_2^p,
314
+
315
+ where `f_i` is a modular form of weight `k - 2i` and `f_p` is
316
+ nonzero.
317
+
318
+ EXAMPLES::
319
+
320
+ sage: QM = QuasiModularForms(1)
321
+ sage: E2, E4, E6 = QM.gens()
322
+ sage: E2.depth()
323
+ 1
324
+ sage: F = E4^2 + E6*E2 + E4*E2^2 + E2^4
325
+ sage: F.depth()
326
+ 4
327
+ sage: QM(7/11).depth()
328
+ 0
329
+
330
+ TESTS::
331
+
332
+ sage: QM = QuasiModularForms(1)
333
+ sage: (QM.0 + QM.1).depth()
334
+ Traceback (most recent call last):
335
+ ...
336
+ ValueError: the given graded quasiform is not an homogeneous element
337
+ """
338
+ if not self.is_homogeneous():
339
+ raise ValueError("the given graded quasiform is not an "
340
+ "homogeneous element")
341
+ return self._polynomial.degree()
342
+
343
+ def is_zero(self) -> bool:
344
+ r"""
345
+ Return whether the given quasimodular form is zero.
346
+
347
+ EXAMPLES::
348
+
349
+ sage: QM = QuasiModularForms(1)
350
+ sage: QM.zero().is_zero()
351
+ True
352
+ sage: QM(0).is_zero()
353
+ True
354
+ sage: QM(1/2).is_zero()
355
+ False
356
+ sage: (QM.0).is_zero()
357
+ False
358
+ sage: QM = QuasiModularForms(Gamma0(2))
359
+ sage: QM(0).is_zero()
360
+ True
361
+ """
362
+ return not self
363
+
364
+ def is_one(self) -> bool:
365
+ r"""
366
+ Return whether the given quasimodular form is 1, i.e. the
367
+ multiplicative identity.
368
+
369
+ EXAMPLES::
370
+
371
+ sage: QM = QuasiModularForms(1)
372
+ sage: QM.one().is_one()
373
+ True
374
+ sage: QM(1).is_one()
375
+ True
376
+ sage: (QM.0).is_one()
377
+ False
378
+ sage: QM = QuasiModularForms(Gamma0(2))
379
+ sage: QM(1).is_one()
380
+ True
381
+ """
382
+ return self._polynomial.is_one()
383
+
384
+ def is_graded_modular_form(self) -> bool:
385
+ r"""
386
+ Return whether the given quasimodular form is a
387
+ graded modular form element
388
+ (see :class:`~sage.modular.modform.element.GradedModularFormElement`).
389
+
390
+ EXAMPLES::
391
+
392
+ sage: QM = QuasiModularForms(1)
393
+ sage: (QM.0).is_graded_modular_form()
394
+ False
395
+ sage: (QM.1).is_graded_modular_form()
396
+ True
397
+ sage: (QM.1 + QM.0^2).is_graded_modular_form()
398
+ False
399
+ sage: (QM.1^2 + QM.2).is_graded_modular_form()
400
+ True
401
+ sage: QM = QuasiModularForms(Gamma0(6))
402
+ sage: (QM.0).is_graded_modular_form()
403
+ False
404
+ sage: (QM.1 + QM.2 + QM.1 * QM.3).is_graded_modular_form()
405
+ True
406
+ sage: QM.zero().is_graded_modular_form()
407
+ True
408
+ sage: QM = QuasiModularForms(Gamma0(6))
409
+ sage: (QM.0).is_graded_modular_form()
410
+ False
411
+ sage: (QM.0 + QM.1*QM.2 + QM.3).is_graded_modular_form()
412
+ False
413
+ sage: (QM.1*QM.2 + QM.3).is_graded_modular_form()
414
+ True
415
+
416
+ .. NOTE::
417
+
418
+ A graded modular form in SageMath is not necessarily a modular form
419
+ as it can have mixed weight components. To check for modular forms
420
+ only, see the method :meth:`is_modular_form`.
421
+ """
422
+ return self._polynomial.degree() <= 0
423
+
424
+ def is_modular_form(self) -> bool:
425
+ r"""
426
+ Return whether the given quasimodular form is a modular form.
427
+
428
+ EXAMPLES::
429
+
430
+ sage: QM = QuasiModularForms(1)
431
+ sage: (QM.0).is_modular_form()
432
+ False
433
+ sage: (QM.1).is_modular_form()
434
+ True
435
+ sage: (QM.1 + QM.2).is_modular_form() # mixed weight components
436
+ False
437
+ sage: QM.zero().is_modular_form()
438
+ True
439
+ sage: QM = QuasiModularForms(Gamma0(4))
440
+ sage: (QM.0).is_modular_form()
441
+ False
442
+ sage: (QM.1).is_modular_form()
443
+ True
444
+ """
445
+ return self._polynomial.degree() <= 0 and self._polynomial[0].is_modular_form()
446
+
447
+ def polynomial(self, names=None):
448
+ r"""
449
+ Return a multivariate polynomial such that every variable corresponds to
450
+ a generator of the ring, ordered by the method:
451
+ :meth:`~sage.modular.quasimodform.ring.QuasiModularForms.gens`.
452
+
453
+ An alias of this method is ``to_polynomial``.
454
+
455
+ INPUT:
456
+
457
+ - ``names``-- string (default: ``None``); list or tuple of names
458
+ (strings), or a comma separated string. Defines the names for the
459
+ generators of the multivariate polynomial ring. The default names are
460
+ of the form ``ABCk`` where ``k`` is a number corresponding to the
461
+ weight of the form ``ABC``.
462
+
463
+ OUTPUT: a multivariate polynomial in the variables ``names``
464
+
465
+ EXAMPLES::
466
+
467
+ sage: QM = QuasiModularForms(1)
468
+ sage: (QM.0 + QM.1).polynomial()
469
+ E4 + E2
470
+ sage: (1/2 + QM.0 + 2*QM.1^2 + QM.0*QM.2).polynomial()
471
+ E2*E6 + 2*E4^2 + E2 + 1/2
472
+
473
+ Check that :issue:`34569` is fixed::
474
+
475
+ sage: QM = QuasiModularForms(Gamma1(3))
476
+ sage: QM.ngens()
477
+ 5
478
+ sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).polynomial()
479
+ E3_1*E4_0 + E2_0*E3_0 + E2 + E2_0
480
+ """
481
+ P = self.parent().polynomial_ring(names)
482
+ poly_gens = P.gens()
483
+ E2 = poly_gens[0]
484
+ poly_gens = poly_gens[1:]
485
+ modform_poly_gens = self.parent().modular_forms_subring().polynomial_ring(names='x').gens()
486
+ subs_dictionary = {}
487
+ for idx, g in enumerate(modform_poly_gens):
488
+ subs_dictionary[g] = poly_gens[idx]
489
+ return sum(f.to_polynomial().subs(subs_dictionary) * E2 ** exp for exp, f in enumerate(self._polynomial.coefficients(sparse=False)))
490
+
491
+ to_polynomial = polynomial # alias
492
+
493
+ def weights_list(self):
494
+ r"""
495
+ Return the list of the weights of all the graded components of the given
496
+ graded quasimodular form.
497
+
498
+ EXAMPLES::
499
+
500
+ sage: QM = QuasiModularForms(1)
501
+ sage: (QM.0).weights_list()
502
+ [2]
503
+ sage: (QM.0 + QM.1 + QM.2).weights_list()
504
+ [2, 4, 6]
505
+ sage: (QM.0 * QM.1 + QM.2).weights_list()
506
+ [6]
507
+ sage: QM(1/2).weights_list()
508
+ [0]
509
+ sage: QM = QuasiModularForms(Gamma1(3))
510
+ sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).weights_list()
511
+ [2, 5, 7]
512
+ """
513
+ return sorted(self.homogeneous_components().keys())
514
+
515
+ def is_homogeneous(self) -> bool:
516
+ r"""
517
+ Return whether the graded quasimodular form is a homogeneous element,
518
+ that is, it lives in a unique graded components of the parent of
519
+ ``self``.
520
+
521
+ EXAMPLES::
522
+
523
+ sage: QM = QuasiModularForms(1)
524
+ sage: E2, E4, E6 = QM.gens()
525
+ sage: (E2).is_homogeneous()
526
+ True
527
+ sage: (E2 + E4).is_homogeneous()
528
+ False
529
+ sage: (E2 * E4 + E6).is_homogeneous()
530
+ True
531
+ sage: QM(1).is_homogeneous()
532
+ True
533
+ sage: (1 + E2).is_homogeneous()
534
+ False
535
+ sage: F = E6^3 + E4^4*E2 + (E4^2*E6)*E2^2 + (E4^3 + E6^2)*E2^3
536
+ sage: F.is_homogeneous()
537
+ True
538
+ """
539
+ k = None
540
+ for i, c in enumerate(self._polynomial.coefficients(sparse=False)):
541
+ if c:
542
+ if not c.is_homogeneous():
543
+ return False
544
+ if k is None:
545
+ k = c.weight() + 2*i
546
+ continue
547
+ if c.weight() + 2*i != k:
548
+ return False
549
+ return True
550
+
551
+ def weight(self):
552
+ r"""
553
+ Return the weight of the given quasimodular form.
554
+
555
+ Note that the given form must be homogeneous. An alias of this method is
556
+ ``degree``.
557
+
558
+ EXAMPLES::
559
+
560
+ sage: QM = QuasiModularForms(1)
561
+ sage: (QM.0).weight()
562
+ 2
563
+ sage: (QM.0 * QM.1 + QM.2).weight()
564
+ 6
565
+ sage: QM(1/2).weight()
566
+ 0
567
+ sage: (QM.0).degree()
568
+ 2
569
+ sage: (QM.0 + QM.1).weight()
570
+ Traceback (most recent call last):
571
+ ...
572
+ ValueError: the given graded quasiform is not an homogeneous element
573
+ """
574
+ if self.is_homogeneous():
575
+ return (self._polynomial.leading_coefficient().weight()
576
+ + 2*self._polynomial.degree())
577
+ else:
578
+ raise ValueError("the given graded quasiform is not an homogeneous \
579
+ element")
580
+
581
+ degree = weight # alias
582
+
583
+ def homogeneous_components(self):
584
+ r"""
585
+ Return a dictionary where the values are the homogeneous components of
586
+ the given graded form and the keys are the weights of those components.
587
+
588
+ EXAMPLES::
589
+
590
+ sage: QM = QuasiModularForms(1)
591
+ sage: (QM.0).homogeneous_components()
592
+ {2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)}
593
+ sage: (QM.0 + QM.1 + QM.2).homogeneous_components()
594
+ {2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
595
+ 4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
596
+ 6: 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)}
597
+ sage: (1 + QM.0).homogeneous_components()
598
+ {0: 1, 2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)}
599
+ sage: QM5 = QuasiModularForms(Gamma1(3))
600
+ sage: F = QM.1 + QM.1*QM.2 + QM.1*QM.0 + (QM.1 + QM.2^2)*QM.0^3
601
+ sage: F.homogeneous_components()
602
+ {4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
603
+ 6: 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6),
604
+ 10: 2 - 96*q - 149040*q^2 - 4986240*q^3 - 67535952*q^4 - 538187328*q^5 + O(q^6),
605
+ 18: 1 - 1080*q + 294840*q^2 - 902880*q^3 - 452402280*q^4 + 105456816*q^5 + O(q^6)}
606
+ sage: F = QM.zero()
607
+ sage: F.homogeneous_components()
608
+ {0: 0}
609
+ sage: F = QM(42/13)
610
+ sage: F.homogeneous_components()
611
+ {0: 42/13}
612
+ """
613
+ QM = self.parent()
614
+ if self.is_zero():
615
+ return {ZZ(0): self}
616
+ components = {}
617
+ E2 = self.parent().weight_2_eisenstein_series()
618
+ for i, c in enumerate(self._polynomial.coefficients(sparse=False)):
619
+ if c:
620
+ forms = c._forms_dictionary
621
+ for k in forms.keys():
622
+ try:
623
+ components[ZZ(k + 2*i)] += QM(forms[k]*(E2**i))
624
+ except KeyError:
625
+ components[ZZ(k + 2*i)] = QM(forms[k]*(E2**i))
626
+ return components
627
+
628
+ def __getitem__(self, weight):
629
+ r"""
630
+ Return the homogeneous component of the given quasimodular form ring
631
+ element.
632
+
633
+ An alias of this method is ``homogeneous_component``.
634
+
635
+ EXAMPLES::
636
+
637
+ sage: QM = QuasiModularForms(1)
638
+ sage: E2, E4, E6 = QM.gens()
639
+ sage: F = E2 + E4*E6 + E2^3*E6
640
+ sage: F[2]
641
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
642
+ sage: F[10]
643
+ 1 - 264*q - 135432*q^2 - 5196576*q^3 - 69341448*q^4 - 515625264*q^5 + O(q^6)
644
+ sage: F[12]
645
+ 1 - 576*q + 21168*q^2 + 308736*q^3 - 15034608*q^4 - 39208320*q^5 + O(q^6)
646
+ sage: F[4]
647
+ 0
648
+ sage: F.homogeneous_component(2)
649
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
650
+
651
+ TESTS::
652
+
653
+ sage: F[x] # needs sage.symbolic
654
+ Traceback (most recent call last):
655
+ ...
656
+ KeyError: 'the weight must be an integer'
657
+ sage: F[-1]
658
+ Traceback (most recent call last):
659
+ ...
660
+ ValueError: the weight must be nonnegative
661
+ """
662
+ if not isinstance(weight, (int, Integer)):
663
+ raise KeyError("the weight must be an integer")
664
+ if weight < 0:
665
+ raise ValueError("the weight must be nonnegative")
666
+ return self.homogeneous_components().get(weight, self.parent().zero())
667
+
668
+ homogeneous_component = __getitem__ # alias
669
+
670
+ def serre_derivative(self):
671
+ r"""
672
+ Return the Serre derivative of the given quasimodular form.
673
+
674
+ If the form is not homogeneous, then this method sums the Serre
675
+ derivative of each homogeneous component.
676
+
677
+ EXAMPLES::
678
+
679
+ sage: QM = QuasiModularForms(1)
680
+ sage: E2, E4, E6 = QM.gens()
681
+ sage: DE2 = E2.serre_derivative(); DE2
682
+ -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6)
683
+ sage: DE2 == (-E2^2 - E4)/12
684
+ True
685
+ sage: DE4 = E4.serre_derivative(); DE4
686
+ -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6)
687
+ sage: DE4 == (-1/3) * E6
688
+ True
689
+ sage: DE6 = E6.serre_derivative(); DE6
690
+ -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6)
691
+ sage: DE6 == (-1/2) * E4^2
692
+ True
693
+
694
+ The Serre derivative raises the weight of homogeneous elements by 2::
695
+
696
+ sage: F = E6 + E4 * E2
697
+ sage: F.weight()
698
+ 6
699
+ sage: F.serre_derivative().weight()
700
+ 8
701
+
702
+ Check that :issue:`34569` is fixed::
703
+
704
+ sage: QM = QuasiModularForms(Gamma1(3))
705
+ sage: E2 = QM.weight_2_eisenstein_series()
706
+ sage: E2.serre_derivative()
707
+ -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6)
708
+ sage: F = QM.0 + QM.1*QM.2
709
+ """
710
+ # initial variables:
711
+ QM = self.parent()
712
+ R = QM.base_ring()
713
+ E2 = QM.gen(0)
714
+ if isinstance(QM.group(), SL2Z_class):
715
+ E4 = QM.gen(1)
716
+ else:
717
+ E4 = QM(EisensteinForms(group=1, weight=4, base_ring=R).gen(0))
718
+
719
+ # compute the derivative of E2: q*dE2/dq
720
+ E2deriv = R(12).inverse_of_unit() * (E2 ** 2 - E4)
721
+
722
+ # sum the Serre derivative of each monomial of the form: f * E2^n
723
+ # they are equal to:
724
+ # [E2^n * serre_deriv(f)] + [n * f * E2^(n-1) * D(E2)] - [n/6 * f * E2^(n+1)]
725
+ # = A + B - C
726
+ der = QM.zero()
727
+ u6 = R(6).inverse_of_unit()
728
+ for n, f in enumerate(self._polynomial.coefficients(sparse=False)):
729
+ if n == 0:
730
+ der += QM(f.serre_derivative())
731
+ else:
732
+ A = (E2 ** n) * f.serre_derivative()
733
+ B = R(n) * f * E2 ** (n - 1) * E2deriv
734
+ C = R(n) * u6 * E2 ** (n + 1) * f
735
+ der += QM(A + B - C)
736
+ return der
737
+
738
+ def derivative(self):
739
+ r"""
740
+ Return the derivative `q \frac{d}{dq}` of the given quasimodular form.
741
+
742
+ If the form is not homogeneous, then this method sums the derivative of
743
+ each homogeneous component.
744
+
745
+ EXAMPLES::
746
+
747
+ sage: QM = QuasiModularForms(1)
748
+ sage: E2, E4, E6 = QM.gens()
749
+ sage: dE2 = E2.derivative(); dE2
750
+ -24*q - 144*q^2 - 288*q^3 - 672*q^4 - 720*q^5 + O(q^6)
751
+ sage: dE2 == (E2^2 - E4)/12 # Ramanujan identity
752
+ True
753
+ sage: dE4 = E4.derivative(); dE4
754
+ 240*q + 4320*q^2 + 20160*q^3 + 70080*q^4 + 151200*q^5 + O(q^6)
755
+ sage: dE4 == (E2 * E4 - E6)/3 # Ramanujan identity
756
+ True
757
+ sage: dE6 = E6.derivative(); dE6
758
+ -504*q - 33264*q^2 - 368928*q^3 - 2130912*q^4 - 7877520*q^5 + O(q^6)
759
+ sage: dE6 == (E2 * E6 - E4^2)/2 # Ramanujan identity
760
+ True
761
+
762
+ Note that the derivative of a modular form is not necessarily a modular form::
763
+
764
+ sage: dE4.is_modular_form()
765
+ False
766
+ sage: dE4.weight()
767
+ 6
768
+ """
769
+ QM = self.parent()
770
+ E2 = QM.gen(0)
771
+ R = self.base_ring()
772
+ u = R(12).inverse_of_unit()
773
+ hom_comp = self.homogeneous_components()
774
+
775
+ return sum(f.serre_derivative() + R(k) * u * f * E2 for k, f in hom_comp.items())
776
+
777
+ def _compute(self, X):
778
+ r"""
779
+ Compute the coefficients of `q^n` of the `q`-expansion of this,
780
+ graded quasimodular form for `n` in the list `X`.
781
+
782
+ The results are not cached. (Use coefficients for cached results).
783
+
784
+ EXAMPLES::
785
+
786
+ sage: E2 = QuasiModularForms(1).0
787
+ sage: E2.q_expansion(10)
788
+ 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10)
789
+ sage: E2._compute([3, 6])
790
+ [-96, -288]
791
+ sage: E2._compute([])
792
+ []
793
+ """
794
+ if not isinstance(X, list) or not X:
795
+ return []
796
+ bound = max(X)
797
+ q_exp = self.q_expansion(bound + 1)
798
+ return [q_exp[i] for i in X]
799
+
800
+ def coefficients(self, X):
801
+ r"""
802
+ Return the coefficients of `q^n` of the `q`-expansion of this,
803
+ graded quasimodular form for `n` in the list `X`.
804
+
805
+ If X is an integer, return coefficients for indices from 1
806
+ to X. This method caches the result.
807
+
808
+ EXAMPLES::
809
+
810
+ sage: E2, E4 = QuasiModularForms(1).0, QuasiModularForms(1).1
811
+ sage: f = E2^2
812
+ sage: g = E2^3 * E4
813
+ sage: f.coefficients(10)
814
+ [-48, 432, 3264, 9456, 21600, 39744, 66432, 105840, 147984, 220320]
815
+ sage: f.coefficients([0,1])
816
+ [1, -48]
817
+ sage: f.coefficients([0,1,2,3])
818
+ [1, -48, 432, 3264]
819
+ sage: f.coefficients([2,3])
820
+ [432, 3264]
821
+ sage: g.coefficients(10)
822
+ [168,
823
+ -13608,
824
+ 210336,
825
+ 1805496,
826
+ -22562064,
827
+ -322437024,
828
+ -2063087808,
829
+ -9165872520,
830
+ -32250917496,
831
+ -96383477232]
832
+ sage: g.coefficients([3, 7])
833
+ [210336, -2063087808]
834
+ """
835
+ try:
836
+ self.__coefficients
837
+ except AttributeError:
838
+ self.__coefficients = {}
839
+ if isinstance(X, Integer):
840
+ X = list(range(1, X + 1))
841
+ Y = [n for n in X if n not in self.__coefficients]
842
+ v = self._compute(Y)
843
+ for i in range(len(v)):
844
+ self.__coefficients[Y[i]] = v[i]
845
+ return [self.__coefficients[x] for x in X]