passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-schemes might be problematic. Click here for more details.

Files changed (314) 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.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.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-314-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-314-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-314-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-314-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-314-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-314-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-314-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-314-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.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,4131 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.libs.flint sage.libs.pari
3
+ """
4
+ Elements of modular forms spaces
5
+
6
+ Class hierarchy:
7
+
8
+ - :class:`ModularForm_abstract`
9
+
10
+ - :class:`Newform`
11
+
12
+ - :class:`ModularFormElement_elliptic_curve`
13
+
14
+ - :class:`ModularFormElement`
15
+
16
+ - :class:`EisensteinSeries`
17
+
18
+ - :class:`GradedModularFormElement`
19
+
20
+ AUTHORS:
21
+
22
+ - William Stein (2004-2008): first version
23
+ - David Ayotte (2021-06): GradedModularFormElement class
24
+ """
25
+ # ****************************************************************************
26
+ # Copyright (C) 2004-2008 William Stein <wstein@gmail.com>
27
+ # 2021 David Ayotte
28
+ #
29
+ # This program is free software: you can redistribute it and/or modify
30
+ # it under the terms of the GNU General Public License as published by
31
+ # the Free Software Foundation, either version 2 of the License, or
32
+ # (at your option) any later version.
33
+ # https://www.gnu.org/licenses/
34
+ # ****************************************************************************
35
+
36
+ from sage.arith.functions import lcm
37
+ from sage.arith.misc import divisors, moebius, sigma, factor, crt
38
+ from sage.arith.srange import xsrange
39
+ from sage.matrix.constructor import Matrix
40
+ from sage.matrix.constructor import matrix
41
+ from sage.misc.cachefunc import cached_method
42
+ from sage.misc.lazy_import import lazy_import
43
+ from sage.misc.misc_c import prod
44
+ from sage.misc.verbose import verbose
45
+ from sage.modular.dirichlet import DirichletGroup
46
+ from sage.modular.modsym.modsym import ModularSymbols
47
+ from sage.modular.modsym.p1list import lift_to_sl2z
48
+ from sage.modular.modsym.space import ModularSymbolsSpace
49
+ from sage.modules.free_module_element import vector
50
+ from sage.rings.complex_mpfr import ComplexField
51
+ from sage.rings.fast_arith import prime_range
52
+ from sage.rings.integer import Integer
53
+ from sage.rings.integer_ring import ZZ
54
+ from sage.rings.morphism import RingHomomorphism
55
+ from sage.rings.power_series_ring import PowerSeriesRing
56
+ from sage.rings.rational_field import QQ
57
+ from sage.rings.real_mpfr import RealField
58
+ from sage.structure.element import coercion_model, ModuleElement, Element
59
+ from sage.structure.richcmp import richcmp, op_NE, op_EQ
60
+
61
+ import sage.modular.hecke.element as element
62
+ from . import defaults
63
+
64
+ lazy_import('sage.combinat.integer_vector_weighted', 'WeightedIntegerVectors')
65
+ lazy_import('sage.rings.number_field.number_field_morphisms', 'NumberFieldEmbedding')
66
+
67
+
68
+ def is_ModularFormElement(x):
69
+ """
70
+ Return ``True`` if x is a modular form.
71
+
72
+ EXAMPLES::
73
+
74
+ sage: from sage.modular.modform.element import is_ModularFormElement
75
+ sage: is_ModularFormElement(5)
76
+ doctest:warning...
77
+ DeprecationWarning: The function is_ModularFormElement is deprecated;
78
+ use 'isinstance(..., ModularFormElement)' instead.
79
+ See https://github.com/sagemath/sage/issues/38184 for details.
80
+ False
81
+ sage: is_ModularFormElement(ModularForms(11).0)
82
+ True
83
+ """
84
+ from sage.misc.superseded import deprecation
85
+ deprecation(38184,
86
+ "The function is_ModularFormElement is deprecated; "
87
+ "use 'isinstance(..., ModularFormElement)' instead.")
88
+ return isinstance(x, ModularFormElement)
89
+
90
+
91
+ def delta_lseries(prec=53, max_imaginary_part=0,
92
+ max_asymp_coeffs=40, algorithm=None):
93
+ r"""
94
+ Return the `L`-series of the modular form `\Delta`.
95
+
96
+ If algorithm is ``'gp'``, this returns an interface to Tim
97
+ Dokchitser's program for computing with the `L`-series of the
98
+ modular form `\Delta`.
99
+
100
+ If algorithm is ``'pari'``, this returns instead an interface to Pari's
101
+ own general implementation of `L`-functions.
102
+
103
+ INPUT:
104
+
105
+ - ``prec`` -- integer (bits precision)
106
+
107
+ - ``max_imaginary_part`` -- real number
108
+
109
+ - ``max_asymp_coeffs`` -- integer
110
+
111
+ - ``algorithm`` -- string; ``'gp'`` (default), ``'pari'``
112
+
113
+ OUTPUT:
114
+
115
+ The `L`-series of `\Delta`.
116
+
117
+ EXAMPLES::
118
+
119
+ sage: L = delta_lseries()
120
+ sage: L(1)
121
+ 0.0374412812685155
122
+
123
+ sage: L = delta_lseries(algorithm='pari')
124
+ sage: L(1)
125
+ 0.0374412812685155
126
+ """
127
+ if algorithm is None:
128
+ algorithm = 'pari'
129
+
130
+ if algorithm == 'gp':
131
+ from sage.lfunctions.dokchitser import Dokchitser
132
+ L = Dokchitser(conductor=1, gammaV=[0, 1], weight=12, eps=1,
133
+ prec=prec)
134
+ s = 'tau(n) = (5*sigma(n,3)+7*sigma(n,5))*n/12-35*sum(k=1,n-1,(6*k-4*(n-k))*sigma(k,3)*sigma(n-k,5));'
135
+ L.init_coeffs('tau(k)', pari_precode=s,
136
+ max_imaginary_part=max_imaginary_part,
137
+ max_asymp_coeffs=max_asymp_coeffs)
138
+ L.set_coeff_growth('2*n^(11/2)')
139
+ L.rename('L-series associated to the modular form Delta')
140
+ return L
141
+ elif algorithm == 'pari':
142
+ from sage.lfunctions.pari import LFunction, lfun_delta
143
+ return LFunction(lfun_delta(), prec=prec)
144
+
145
+ raise ValueError('algorithm must be "gp" or "pari"')
146
+
147
+
148
+ class ModularForm_abstract(ModuleElement):
149
+ """
150
+ Constructor for generic class of a modular form. This
151
+ should never be called directly; instead one should
152
+ instantiate one of the derived classes of this
153
+ class.
154
+ """
155
+ def group(self):
156
+ """
157
+ Return the group for which ``self`` is a modular form.
158
+
159
+ EXAMPLES::
160
+
161
+ sage: ModularForms(Gamma1(11), 2).gen(0).group()
162
+ Congruence Subgroup Gamma1(11)
163
+ """
164
+ return self.parent().group()
165
+
166
+ def weight(self):
167
+ """
168
+ Return the weight of ``self``.
169
+
170
+ EXAMPLES::
171
+
172
+ sage: (ModularForms(Gamma1(9),2).6).weight()
173
+ 2
174
+ """
175
+ return self.parent().weight()
176
+
177
+ def level(self):
178
+ """
179
+ Return the level of ``self``.
180
+
181
+ EXAMPLES::
182
+
183
+ sage: ModularForms(25,4).0.level()
184
+ 25
185
+ """
186
+ return self.parent().level()
187
+
188
+ def is_homogeneous(self) -> bool:
189
+ """
190
+ Return ``True``.
191
+
192
+ For compatibility with elements of a graded modular forms ring.
193
+
194
+ An alias of this method is ``is_modular_form``.
195
+
196
+ .. SEEALSO::
197
+
198
+ :meth:`sage.modular.modform.element.GradedModularFormElement.is_homogeneous`
199
+
200
+ EXAMPLES::
201
+
202
+ sage: ModularForms(1,12).0.is_homogeneous()
203
+ True
204
+ """
205
+ return True
206
+
207
+ is_modular_form = is_homogeneous # alias
208
+
209
+ def _repr_(self):
210
+ """
211
+ Return the string representation of ``self``.
212
+
213
+ EXAMPLES::
214
+
215
+ sage: ModularForms(25,4).0._repr_()
216
+ 'q + O(q^6)'
217
+
218
+ sage: ModularForms(25,4).3._repr_()
219
+ 'q^4 + O(q^6)'
220
+ """
221
+ return str(self.q_expansion())
222
+
223
+ def _pari_init_(self):
224
+ """
225
+ Conversion to Pari.
226
+
227
+ TESTS::
228
+
229
+ sage: M = EisensteinForms(96, 2)
230
+ sage: M.6
231
+ O(q^6)
232
+ sage: M.7
233
+ O(q^6)
234
+ sage: pari(M.6) == pari(M.7)
235
+ False
236
+ sage: pari(M.6).mfcoefs(10)
237
+ [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
238
+
239
+ sage: M = ModularForms(DirichletGroup(17).0^2, 2)
240
+ sage: pari(M.0).mfcoefs(5)
241
+ [0, 1, Mod(-t^3 + t^2 - 1, t^4 + 1), Mod(t^3 - t^2 - t - 1, t^4 + 1), Mod(2*t^3 - t^2 + 2*t, t^4 + 1), Mod(-t^3 - t^2, t^4 + 1)]
242
+ sage: M.0.qexp(5)
243
+ q + (-zeta8^3 + zeta8^2 - 1)*q^2 + (zeta8^3 - zeta8^2 - zeta8 - 1)*q^3 + (2*zeta8^3 - zeta8^2 + 2*zeta8)*q^4 + O(q^5)
244
+ """
245
+ from sage.libs.pari import pari
246
+ from sage.rings.number_field.number_field_element import NumberFieldElement
247
+ M = pari(self.parent())
248
+ f = self.qexp(self.parent().sturm_bound())
249
+ coefficients = [
250
+ x.__pari__('t') if isinstance(x, NumberFieldElement) else x
251
+ for x in f]
252
+ # we cannot compute pari(f) directly because we need to set the variable name as t
253
+ return M.mflinear(M.mftobasis(coefficients + [0] * (f.prec() - len(coefficients))))
254
+
255
+ def __call__(self, x, prec=None):
256
+ """
257
+ Evaluate the `q`-expansion of this modular form at x.
258
+
259
+ EXAMPLES::
260
+
261
+ sage: f = ModularForms(DirichletGroup(17).0^2,2).2
262
+
263
+ sage: q = f.q_expansion().parent().gen()
264
+ sage: f(q^2 + O(q^7))
265
+ q^2 + (-zeta8^2 + 2)*q^4 + (zeta8 + 3)*q^6 + O(q^7)
266
+
267
+ sage: f(0)
268
+ 0
269
+
270
+ Evaluate numerically::
271
+
272
+ sage: f = ModularForms(1, 12).0
273
+ sage: f(0.3) # rel tol 1e-12
274
+ 2.34524576548591e-6
275
+ sage: f = EisensteinForms(1, 4).0
276
+ sage: f(0.9) # rel tol 1e-12
277
+ 1.26475942209241e7
278
+
279
+ TESTS::
280
+
281
+ sage: f = ModularForms(96, 2).0
282
+ sage: f(0.3) # rel tol 1e-12
283
+ 0.299999997396191
284
+ sage: f(0.0+0.0*I)
285
+ 0
286
+
287
+ For simplicity, ``float`` or ``complex`` input are converted to ``CC``, except for
288
+ input ``0`` where exact result is returned::
289
+
290
+ sage: result = f(0.3r); result # rel tol 1e-12
291
+ 0.299999997396191
292
+ sage: result.parent()
293
+ Complex Field with 53 bits of precision
294
+ sage: result = f(0.3r + 0.3jr); result # rel tol 1e-12
295
+ 0.299999359878484 + 0.299999359878484*I
296
+ sage: result.parent()
297
+ Complex Field with 53 bits of precision
298
+
299
+ Symbolic numerical values use precision of ``CC`` by default::
300
+
301
+ sage: f(sqrt(1/2)) # rel tol 1e-12
302
+ 0.700041406692037
303
+ sage: f(sqrt(1/2)*QQbar.zeta(8)) # rel tol 1e-12
304
+ 0.496956554651376 + 0.496956554651376*I
305
+
306
+ Higher precision::
307
+
308
+ sage: f(ComplexField(128)(0.3)) # rel tol 1e-36
309
+ 0.29999999739619131029285166058750164058
310
+ sage: f(ComplexField(128)(1+2*I)/3) # rel tol 1e-36
311
+ 0.32165384572356882556790532669389900691 + 0.67061244638367586302820790711257777390*I
312
+
313
+ Confirm numerical evaluation matches the q-expansion::
314
+
315
+ sage: f = EisensteinForms(1, 4).0
316
+ sage: f(0.3) # rel tol 1e-12
317
+ 741.741819297986
318
+ sage: f.qexp(50).polynomial()(0.3) # rel tol 1e-12
319
+ 741.741819297986
320
+
321
+ With a nontrivial character::
322
+
323
+ sage: M = ModularForms(DirichletGroup(17).0^2, 2)
324
+ sage: M.0(0.5) # rel tol 1e-12
325
+ 0.166916655031616 + 0.0111529051752428*I
326
+ sage: M.0.qexp(60).polynomial()(0.5) # rel tol 1e-12
327
+ 0.166916655031616 + 0.0111529051752428*I
328
+
329
+ Higher precision::
330
+
331
+ sage: f(ComplexField(128)(1+2*I)/3) # rel tol 1e-36
332
+ 429.19994832206294278688085399056359632 - 786.15736284188243351153830824852974995*I
333
+ sage: f.qexp(400).polynomial()(ComplexField(128)(1+2*I)/3) # rel tol 1e-36
334
+ 429.19994832206294278688085399056359631 - 786.15736284188243351153830824852974999*I
335
+
336
+ Check ``SR`` does not make the result lose precision::
337
+
338
+ sage: f(ComplexField(128)(1+2*I)/3 + x - x) # rel tol 1e-36
339
+ 429.19994832206294278688085399056359632 - 786.15736284188243351153830824852974995*I
340
+ """
341
+ from sage.misc.functional import log
342
+ from sage.structure.element import parent
343
+ from sage.rings.complex_mpfr import ComplexNumber
344
+ from sage.rings.cc import CC
345
+ from sage.rings.real_mpfr import RealNumber
346
+ from sage.symbolic.constants import pi
347
+ from sage.rings.imaginary_unit import I # import from here instead of sage.symbolic.constants to avoid cast to SR
348
+ from sage.symbolic.expression import Expression
349
+ if isinstance(x, Expression):
350
+ try:
351
+ x = x.pyobject()
352
+ except TypeError:
353
+ pass
354
+ if x in CC:
355
+ if x == 0:
356
+ return self.qexp(1)[0]
357
+ if not isinstance(x, (RealNumber, ComplexNumber)):
358
+ x = CC(x) # might lose precision if this is done unconditionally (TODO what about interval and ball types?)
359
+ if isinstance(x, (RealNumber, ComplexNumber)):
360
+ return self.eval_at_tau(log(x) / (2 * parent(x)(pi) * I)) # cast to parent(x) to force numerical evaluation of pi
361
+ return self.q_expansion(prec)(x)
362
+
363
+ def eval_at_tau(self, tau):
364
+ r"""
365
+ Evaluate this modular form at the half-period ratio `\tau`.
366
+ This is related to `q` by `q = e^{2\pi i \tau}`.
367
+
368
+ EXAMPLES::
369
+
370
+ sage: f = ModularForms(1, 12).0
371
+ sage: f.eval_at_tau(0.3 * I) # rel tol 1e-12
372
+ 0.00150904633897550
373
+
374
+ TESTS:
375
+
376
+ Symbolic numerical values use precision of ``CC`` by default::
377
+
378
+ sage: f.eval_at_tau(sqrt(1/5)*I) # rel tol 1e-12
379
+ 0.0123633234207127
380
+ sage: f.eval_at_tau(sqrt(1/2)*QQbar.zeta(8)) # rel tol 1e-12
381
+ -0.114263670441098
382
+
383
+ For simplicity, ``complex`` input are converted to ``CC``::
384
+
385
+ sage: result = f.eval_at_tau(0.3jr); result # rel tol 1e-12
386
+ 0.00150904633897550
387
+ sage: result.parent()
388
+ Complex Field with 53 bits of precision
389
+
390
+ Check ``SR`` does not make the result lose precision::
391
+
392
+ sage: f = EisensteinForms(1, 4).0
393
+ sage: f.eval_at_tau(ComplexField(128)(1+2*I)/3 + x - x) # rel tol 1e-36
394
+ -1.0451570582202060056197878314286036966 + 2.7225112098519803098203933583286590274*I
395
+ """
396
+ from sage.libs.pari import pari
397
+ from sage.rings.cc import CC
398
+ from sage.rings.complex_mpfr import ComplexNumber, ComplexField
399
+ from sage.rings.real_mpfr import RealNumber
400
+ from sage.symbolic.expression import Expression
401
+ if isinstance(tau, Expression):
402
+ try:
403
+ tau = tau.pyobject()
404
+ except TypeError:
405
+ pass
406
+ if not isinstance(tau, (RealNumber, ComplexNumber)):
407
+ tau = CC(tau)
408
+ precision = tau.prec()
409
+ return ComplexField(precision)(pari.mfeval(self.parent(), self, tau, precision=precision))
410
+
411
+ @cached_method
412
+ def valuation(self):
413
+ """
414
+ Return the valuation of ``self`` (i.e. as an element of the power
415
+ series ring in q).
416
+
417
+ EXAMPLES::
418
+
419
+ sage: ModularForms(11,2).0.valuation()
420
+ 1
421
+ sage: ModularForms(11,2).1.valuation()
422
+ 0
423
+ sage: ModularForms(25,6).1.valuation()
424
+ 2
425
+ sage: ModularForms(25,6).6.valuation()
426
+ 7
427
+ """
428
+ v = self.qexp().valuation()
429
+ if v != self.qexp().prec():
430
+ return v
431
+ return self.qexp(self.parent().sturm_bound()).valuation()
432
+
433
+ def qexp(self, prec=None):
434
+ """
435
+ Same as ``self.q_expansion(prec)``.
436
+
437
+ .. SEEALSO:: :meth:`q_expansion`
438
+
439
+ EXAMPLES::
440
+
441
+ sage: CuspForms(1,12).0.qexp()
442
+ q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
443
+ """
444
+ return self.q_expansion(prec)
445
+
446
+ def __eq__(self, other):
447
+ """
448
+ Compare ``self`` to ``other``.
449
+
450
+ EXAMPLES::
451
+
452
+ sage: f = ModularForms(6,4).0
453
+ sage: g = ModularForms(23,2).0
454
+ sage: f == g # indirect doctest
455
+ False
456
+ sage: f == f
457
+ True
458
+ sage: f == loads(dumps(f))
459
+ True
460
+ """
461
+ if not isinstance(other, ModularFormElement) or \
462
+ self.ambient_module() != other.ambient_module():
463
+ return False
464
+ else:
465
+ return self.element() == other.element()
466
+
467
+ def __ne__(self, other):
468
+ """
469
+ Return ``True`` if ``self != other``.
470
+
471
+ EXAMPLES::
472
+
473
+ sage: f = Newforms(Gamma1(30), 2, names='a')[1]
474
+ sage: g = ModularForms(23, 2).0
475
+ sage: f != g
476
+ True
477
+ sage: f != f
478
+ False
479
+
480
+ TESTS:
481
+
482
+ The following used to fail (see :issue:`18068`)::
483
+
484
+ sage: f != loads(dumps(f))
485
+ False
486
+ """
487
+ return not (self == other)
488
+
489
+ def _compute(self, X):
490
+ """
491
+ Compute the coefficients of `q^n` of the power series of self,
492
+ for `n` in the list `X`. The results are not cached. (Use
493
+ coefficients for cached results).
494
+
495
+ EXAMPLES::
496
+
497
+ sage: f = ModularForms(18,2).1
498
+ sage: f.q_expansion(20)
499
+ q + 8*q^7 + 4*q^10 + 14*q^13 - 4*q^16 + 20*q^19 + O(q^20)
500
+ sage: f._compute([10,17])
501
+ [4, 0]
502
+ sage: f._compute([])
503
+ []
504
+ """
505
+ if not isinstance(X, list) or not X:
506
+ return []
507
+ bound = max(X)
508
+ q_exp = self.q_expansion(bound + 1)
509
+ return [q_exp[i] for i in X]
510
+
511
+ def coefficients(self, X):
512
+ r"""
513
+ Return the coefficients `a_n` of the `q`-expansion of this modular form.
514
+
515
+ This function caches the results of the compute function.
516
+
517
+ INPUT:
518
+
519
+ - ``X`` -- an iterator or an integer. If ``X`` is an iterator, a list
520
+ containing all `a_{X_i}` is returned. If ``X`` is an integer, it must
521
+ be positive, in which case the coefficients `a_1` to `a_X` are
522
+ returned in a list.
523
+
524
+ TESTS::
525
+
526
+ sage: e = DirichletGroup(11).gen()
527
+ sage: f = EisensteinForms(e, 3).eisenstein_series()[0]
528
+ sage: f.coefficients([0,1])
529
+ [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11,
530
+ 1]
531
+ sage: f.coefficients([0,1,2,3])
532
+ [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11,
533
+ 1,
534
+ 4*zeta10 + 1,
535
+ -9*zeta10^3 + 1]
536
+ sage: f.coefficients([2,3])
537
+ [4*zeta10 + 1,
538
+ -9*zeta10^3 + 1]
539
+
540
+ Running this twice once revealed a bug, so we test it::
541
+
542
+ sage: f.coefficients([0,1,2,3])
543
+ [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11,
544
+ 1,
545
+ 4*zeta10 + 1,
546
+ -9*zeta10^3 + 1]
547
+ """
548
+ try:
549
+ self.__coefficients
550
+ except AttributeError:
551
+ self.__coefficients = {}
552
+ if isinstance(X, (int, Integer)):
553
+ X = list(range(1, ZZ(X) + 1))
554
+ Y = [n for n in X if n not in self.__coefficients]
555
+ v = self._compute(Y)
556
+ for i in range(len(v)):
557
+ self.__coefficients[Y[i]] = v[i]
558
+ return [self.__coefficients[x] for x in X]
559
+
560
+ def __getitem__(self, n):
561
+ """
562
+ Return the `q^n` coefficient of the `q`-expansion of ``self`` or
563
+ returns a list containing the `q^i` coefficients of self
564
+ where `i` is in slice `n`.
565
+
566
+ EXAMPLES::
567
+
568
+ sage: f = ModularForms(DirichletGroup(17).0^2,2).2
569
+ sage: f.__getitem__(10)
570
+ zeta8^3 - 5*zeta8^2 - 2*zeta8 + 10
571
+ sage: f[30]
572
+ -2*zeta8^3 - 17*zeta8^2 + 4*zeta8 + 29
573
+ sage: f[10:15]
574
+ [zeta8^3 - 5*zeta8^2 - 2*zeta8 + 10,
575
+ -zeta8^3 + 11,
576
+ -2*zeta8^3 - 6*zeta8^2 + 3*zeta8 + 9,
577
+ 12,
578
+ 2*zeta8^3 - 7*zeta8^2 + zeta8 + 14]
579
+ """
580
+ if isinstance(n, slice):
581
+ if n.stop is None:
582
+ return self.q_expansion().list()[n]
583
+ else:
584
+ return self.q_expansion(n.stop + 1).list()[n]
585
+ else:
586
+ return self.q_expansion(n + 1)[int(n)]
587
+
588
+ def coefficient(self, n):
589
+ r"""
590
+ Return the `n`-th coefficient of the `q`-expansion of ``self``.
591
+
592
+ INPUT:
593
+
594
+ - ``n`` -- nonnegative integer
595
+
596
+ EXAMPLES::
597
+
598
+ sage: f = ModularForms(1, 12).0; f
599
+ q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
600
+ sage: f.coefficient(0)
601
+ 0
602
+ sage: f.coefficient(1)
603
+ 1
604
+ sage: f.coefficient(2)
605
+ -24
606
+ sage: f.coefficient(3)
607
+ 252
608
+ sage: f.coefficient(4)
609
+ -1472
610
+ """
611
+ n = ZZ(n)
612
+ return self.q_expansion(n + 1)[n]
613
+
614
+ def padded_list(self, n):
615
+ """
616
+ Return a list of length n whose entries are the first n
617
+ coefficients of the `q`-expansion of ``self``.
618
+
619
+ EXAMPLES::
620
+
621
+ sage: CuspForms(1,12).0.padded_list(20)
622
+ [0, 1, -24, 252, -1472, 4830, -6048, -16744, 84480, -113643,
623
+ -115920, 534612, -370944, -577738, 401856, 1217160, 987136,
624
+ -6905934, 2727432, 10661420]
625
+ """
626
+ return self.q_expansion(n).padded_list(n)
627
+
628
+ def _latex_(self):
629
+ """
630
+ Return the LaTeX expression of ``self``.
631
+
632
+ EXAMPLES::
633
+
634
+ sage: ModularForms(25,4).0._latex_()
635
+ 'q + O(q^{6})'
636
+
637
+ sage: ModularForms(25,4).4._latex_()
638
+ 'q^{5} + O(q^{6})'
639
+ """
640
+ return self.q_expansion()._latex_()
641
+
642
+ def character(self, compute=True):
643
+ """
644
+ Return the character of ``self``. If ``compute=False``, then this will
645
+ return None unless the form was explicitly created as an element of a
646
+ space of forms with character, skipping the (potentially expensive)
647
+ computation of the matrices of the diamond operators.
648
+
649
+ EXAMPLES::
650
+
651
+ sage: ModularForms(DirichletGroup(17).0^2,2).2.character()
652
+ Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta8
653
+
654
+ sage: CuspForms(Gamma1(7), 3).gen(0).character()
655
+ Dirichlet character modulo 7 of conductor 7 mapping 3 |--> -1
656
+ sage: CuspForms(Gamma1(7), 3).gen(0).character(compute = False) is None
657
+ True
658
+ sage: M = CuspForms(Gamma1(7), 5).gen(0).character()
659
+ Traceback (most recent call last):
660
+ ...
661
+ ValueError: Form is not an eigenvector for <3>
662
+ """
663
+ chi = self.parent().character()
664
+ if (chi is not None) or (not compute):
665
+ return chi
666
+ else: # do the expensive computation
667
+ G = DirichletGroup(self.parent().level(), base_ring=self.parent().base_ring())
668
+ gens = G.unit_gens()
669
+ i = self.valuation()
670
+ vals = []
671
+ for g in gens:
672
+ df = self.parent().diamond_bracket_operator(g)(self)
673
+ if df != (df[i] / self[i]) * self:
674
+ raise ValueError("Form is not an eigenvector for <%s>" % g)
675
+ vals.append(df[i] / self[i])
676
+ return G(vals)
677
+
678
+ def __bool__(self):
679
+ """
680
+ Return ``True`` if ``self`` is nonzero, and ``False`` if not.
681
+
682
+ EXAMPLES::
683
+
684
+ sage: bool(ModularForms(25,6).6)
685
+ True
686
+ """
687
+ return not self.element().is_zero()
688
+
689
+ def prec(self):
690
+ """
691
+ Return the precision to which self.q_expansion() is
692
+ currently known. Note that this may be 0.
693
+
694
+ EXAMPLES::
695
+
696
+ sage: M = ModularForms(2,14)
697
+ sage: f = M.0
698
+ sage: f.prec()
699
+ 0
700
+
701
+ sage: M.prec(20)
702
+ 20
703
+ sage: f.prec()
704
+ 0
705
+ sage: x = f.q_expansion() ; f.prec()
706
+ 20
707
+ """
708
+ try:
709
+ return self.__q_expansion[0]
710
+ except AttributeError:
711
+ return 0
712
+
713
+ def q_expansion(self, prec=None):
714
+ r"""
715
+ The `q`-expansion of the modular form to precision `O(q^\text{prec})`.
716
+ This function takes one argument, which is the integer prec.
717
+
718
+ EXAMPLES:
719
+
720
+ We compute the cusp form `\Delta`::
721
+
722
+ sage: delta = CuspForms(1,12).0
723
+ sage: delta.q_expansion()
724
+ q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
725
+
726
+ We compute the `q`-expansion of one of the cusp forms of level 23::
727
+
728
+ sage: f = CuspForms(23,2).0
729
+ sage: f.q_expansion()
730
+ q - q^3 - q^4 + O(q^6)
731
+ sage: f.q_expansion(10)
732
+ q - q^3 - q^4 - 2*q^6 + 2*q^7 - q^8 + 2*q^9 + O(q^10)
733
+ sage: f.q_expansion(2)
734
+ q + O(q^2)
735
+ sage: f.q_expansion(1)
736
+ O(q^1)
737
+ sage: f.q_expansion(0)
738
+ O(q^0)
739
+ sage: f.q_expansion(-1)
740
+ Traceback (most recent call last):
741
+ ...
742
+ ValueError: prec (= -1) must be nonnegative
743
+ """
744
+ if prec is None:
745
+ prec = self.parent().prec()
746
+ prec = Integer(prec)
747
+ try:
748
+ current_prec, f = self.__q_expansion
749
+ except AttributeError:
750
+ current_prec = 0
751
+ f = self.parent()._q_expansion_ring()(0, 0)
752
+
753
+ if current_prec == prec:
754
+ return f
755
+ elif current_prec > prec:
756
+ return f.add_bigoh(prec)
757
+ else:
758
+ f = self._compute_q_expansion(prec)
759
+ self.__q_expansion = (prec, f)
760
+ return f
761
+
762
+ def serre_derivative(self):
763
+ """
764
+ Return the Serre derivative of the given modular form.
765
+
766
+ If ``self`` is of weight `k`, then the returned modular form will be of
767
+ weight `k+2`.
768
+
769
+ EXAMPLES::
770
+
771
+ sage: E4 = ModularForms(1, 4).0
772
+ sage: E6 = ModularForms(1, 6).0
773
+ sage: DE4 = E4.serre_derivative(); DE4
774
+ -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6)
775
+ sage: DE6 = E6.serre_derivative(); DE6
776
+ -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6)
777
+ sage: Del = ModularForms(1, 12).0 # Modular discriminant
778
+ sage: Del.serre_derivative()
779
+ 0
780
+ sage: f = ModularForms(DirichletGroup(5).0, 1).0
781
+ sage: Df = f.serre_derivative(); Df
782
+ -1/12 + (-11/12*zeta4 + 19/4)*q + (11/6*zeta4 + 59/3)*q^2 + (-41/3*zeta4 + 239/6)*q^3 + (31/4*zeta4 + 839/12)*q^4 + (-251/12*zeta4 + 459/4)*q^5 + O(q^6)
783
+
784
+ The Serre derivative raises the weight of a modular form by `2`::
785
+
786
+ sage: DE4.weight()
787
+ 6
788
+ sage: DE6.weight()
789
+ 8
790
+ sage: Df.weight()
791
+ 3
792
+
793
+ The Ramanujan identities are verified (see :wikipedia:`Eisenstein_series#Ramanujan_identities`)::
794
+
795
+ sage: DE4 == (-1/3) * E6
796
+ True
797
+ sage: DE6 == (-1/2) * E4 * E4
798
+ True
799
+ """
800
+ from .eis_series import eisenstein_series_qexp
801
+ from .constructor import ModularForms
802
+
803
+ # check if the parent space has a character or not
804
+ if self.parent().has_character():
805
+ group = self.parent().character()
806
+ else:
807
+ group = self.parent().group()
808
+
809
+ # raise the weight by 2
810
+ parent_space = ModularForms(group, self.weight() + 2, self.base_ring())
811
+
812
+ # compute the precision for q-expansions
813
+ bound = parent_space._q_expansion_module().degree() + 1
814
+ E2 = eisenstein_series_qexp(2, prec=bound, K=self.base_ring(), normalization='integral')
815
+ self_qexp = self.q_expansion(prec=bound)
816
+
817
+ # compute the derivative via q-expansions
818
+ R = self.base_ring()
819
+ q = self_qexp.parent().gen()
820
+ mult = R(self.weight()) * R(12).inverse_of_unit()
821
+ der = q * self_qexp.derivative() + (mult) * E2 * self_qexp
822
+
823
+ return parent_space(der)
824
+
825
+ def atkin_lehner_eigenvalue(self, d=None, embedding=None):
826
+ """
827
+ Return the eigenvalue of the Atkin-Lehner operator `W_d`
828
+ acting on ``self``.
829
+
830
+ INPUT:
831
+
832
+ - ``d`` -- positive integer exactly dividing the level `N`
833
+ of ``self``, i.e. `d` divides `N` and is coprime to `N/d`
834
+ (default: `d = N`)
835
+
836
+ - ``embedding`` -- (optional) embedding of the base ring of
837
+ ``self`` into another ring
838
+
839
+ OUTPUT:
840
+
841
+ The Atkin-Lehner eigenvalue of `W_d` on ``self``. This is
842
+ returned as an element of the codomain of ``embedding`` if
843
+ specified, and in (a suitable extension of) the base field of
844
+ ``self`` otherwise.
845
+
846
+ If ``self`` is not an eigenform for `W_d`, a :exc:`ValueError` is
847
+ raised.
848
+
849
+ .. SEEALSO::
850
+
851
+ :meth:`sage.modular.hecke.module.HeckeModule_free_module.atkin_lehner_operator`
852
+ (especially for the conventions used to define the operator `W_d`).
853
+
854
+ EXAMPLES::
855
+
856
+ sage: CuspForms(1, 12).0.atkin_lehner_eigenvalue()
857
+ 1
858
+ sage: CuspForms(2, 8).0.atkin_lehner_eigenvalue()
859
+ Traceback (most recent call last):
860
+ ...
861
+ NotImplementedError: don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead)
862
+ """
863
+ raise NotImplementedError("don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead)")
864
+
865
+ # The methods period() and lseries() below currently live
866
+ # in ModularForm_abstract so they are inherited by Newform (which
867
+ # does *not* derive from ModularFormElement).
868
+
869
+ def period(self, M, prec=53):
870
+ r"""
871
+ Return the period of ``self`` with respect to `M`.
872
+
873
+ INPUT:
874
+
875
+ - ``self`` -- a cusp form `f` of weight 2 for `Gamma_0(N)`
876
+
877
+ - ``M`` -- an element of `\Gamma_0(N)`
878
+
879
+ - ``prec`` -- (default: 53) the working precision in bits. If
880
+ `f` is a normalised eigenform, then the output is correct to
881
+ approximately this number of bits.
882
+
883
+ OUTPUT:
884
+
885
+ A numerical approximation of the period `P_f(M)`. This period
886
+ is defined by the following integral over the complex upper
887
+ half-plane, for any `\alpha` in `\Bold{P}^1(\QQ)`:
888
+
889
+ .. MATH::
890
+
891
+ P_f(M) = 2 \pi i \int_\alpha^{M(\alpha)} f(z) dz.
892
+
893
+ This is independent of the choice of `\alpha`.
894
+
895
+ EXAMPLES::
896
+
897
+ sage: C = Newforms(11, 2)[0]
898
+ sage: m = C.group()(matrix([[-4, -3], [11, 8]]))
899
+ sage: C.period(m)
900
+ -0.634604652139776 - 1.45881661693850*I
901
+
902
+ sage: f = Newforms(15, 2)[0]
903
+ sage: g = Gamma0(15)(matrix([[-4, -3], [15, 11]]))
904
+ sage: f.period(g) # abs tol 1e-15
905
+ 2.17298044293747e-16 - 1.59624222213178*I
906
+
907
+ If `E` is an elliptic curve over `\QQ` and `f` is the newform
908
+ associated to `E`, then the periods of `f` are in the period
909
+ lattice of `E` up to an integer multiple::
910
+
911
+ sage: # needs database_cremona_mini_ellcurve
912
+ sage: E = EllipticCurve('11a3')
913
+ sage: f = E.newform()
914
+ sage: g = Gamma0(11)([3, 1, 11, 4])
915
+ sage: f.period(g)
916
+ 0.634604652139777 + 1.45881661693850*I
917
+ sage: omega1, omega2 = E.period_lattice().basis()
918
+ sage: -2/5*omega1 + omega2
919
+ 0.634604652139777 + 1.45881661693850*I
920
+
921
+ The integer multiple is 5 in this case, which is explained by
922
+ the fact that there is a 5-isogeny between the elliptic curves
923
+ `J_0(5)` and `E`.
924
+
925
+ The elliptic curve `E` has a pair of modular symbols attached
926
+ to it, which can be computed using the method
927
+ :meth:`sage.schemes.elliptic_curves.ell_rational_field.EllipticCurve_rational_field.modular_symbol`.
928
+ These can be used to express the periods of `f` as exact
929
+ linear combinations of the real and the imaginary period of `E`::
930
+
931
+ sage: # needs database_cremona_mini_ellcurve eclib
932
+ sage: s = E.modular_symbol(sign=+1)
933
+ sage: t = E.modular_symbol(sign=-1, implementation='sage')
934
+ sage: s(3/11), t(3/11)
935
+ (1/10, 1/2)
936
+ sage: s(3/11)*omega1 + t(3/11)*2*omega2.imag()*I
937
+ 0.634604652139777 + 1.45881661693850*I
938
+
939
+ ALGORITHM:
940
+
941
+ We use the series expression from [Cre1997]_, Chapter II,
942
+ Proposition 2.10.3. The algorithm sums the first `T` terms of
943
+ this series, where `T` is chosen in such a way that the result
944
+ would approximate `P_f(M)` with an absolute error of at most
945
+ `2^{-\text{prec}}` if all computations were done exactly.
946
+
947
+ Since the actual precision is finite, the output is currently
948
+ *not* guaranteed to be correct to ``prec`` bits of precision.
949
+
950
+ TESTS::
951
+
952
+ sage: C = Newforms(11, 2)[0]
953
+ sage: g = Gamma0(15)(matrix([[-4, -3], [15, 11]]))
954
+ sage: C.period(g)
955
+ Traceback (most recent call last):
956
+ ...
957
+ TypeError: matrix [-4 -3]
958
+ [15 11]
959
+ is not an element of Congruence Subgroup Gamma0(11)
960
+
961
+ sage: f = Newforms(Gamma0(15), 4)[0]
962
+ sage: f.period(g)
963
+ Traceback (most recent call last):
964
+ ...
965
+ ValueError: period pairing only defined for cusp forms of weight 2
966
+
967
+ sage: S = Newforms(Gamma1(17), 2, names='a')
968
+ sage: f = S[1]
969
+ sage: g = Gamma1(17)([18, 1, 17, 1])
970
+ sage: f.period(g)
971
+ Traceback (most recent call last):
972
+ ...
973
+ NotImplementedError: period pairing only implemented for cusp forms of trivial character
974
+
975
+ sage: E = ModularForms(Gamma0(4), 2).eisenstein_series()[0]
976
+ sage: gamma = Gamma0(4)([1, 0, 4, 1])
977
+ sage: E.period(gamma)
978
+ Traceback (most recent call last):
979
+ ...
980
+ NotImplementedError: don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead)
981
+
982
+ sage: # needs database_cremona_mini_ellcurve
983
+ sage: E = EllipticCurve('19a1')
984
+ sage: M = Gamma0(19)([10, 1, 19, 2])
985
+ sage: E.newform().period(M) # abs tol 1e-14
986
+ -1.35975973348831 + 1.09365931898146e-16*I
987
+ """
988
+ R = RealField(prec)
989
+
990
+ N = self.level()
991
+ if not self.character().is_trivial():
992
+ raise NotImplementedError('period pairing only implemented for cusp forms of trivial character')
993
+ if self.weight() != 2:
994
+ raise ValueError('period pairing only defined for cusp forms of weight 2')
995
+ if not isinstance(self, (Newform, ModularFormElement_elliptic_curve)):
996
+ print('Warning: not a newform, precision not guaranteed')
997
+
998
+ M = self.group()(M)
999
+ # coefficients of the matrix M
1000
+ b, c, d = (M.b(), M.c() / N, M.d())
1001
+ if d == 0:
1002
+ return R.zero()
1003
+ if d < 0:
1004
+ b, c, d = (-b, -c, -d)
1005
+
1006
+ twopi = 2 * R.pi()
1007
+ I = R.complex_field().gen()
1008
+ rootN = R(N).sqrt()
1009
+
1010
+ eps = self.atkin_lehner_eigenvalue()
1011
+ mu_N = (-twopi / rootN).exp()
1012
+ mu_dN = (-twopi / d / rootN).exp()
1013
+ mu_d = (twopi * I / d).exp()
1014
+
1015
+ # We bound the tail of the series by means of the triangle
1016
+ # inequality and the following bounds (tau(n) = #divisors(n)):
1017
+ # mu_N <= mu_dN
1018
+ # |a_n(f)| <= tau(n)*sqrt(n) (holds if f is a newform)
1019
+ # tau(n) <= sqrt(3)*sqrt(n) for all n >= 1
1020
+ # This gives a correct but somewhat coarse lower bound on the
1021
+ # number of terms needed. We ignore rounding errors.
1022
+ numterms = (((1 - mu_dN) * R(2)**(-prec)
1023
+ / ((abs(eps - 1) + 2) * R(3).sqrt())).log()
1024
+ / mu_dN.log()).ceil()
1025
+ coeff = self.coefficients(numterms)
1026
+
1027
+ return sum((coeff[n - 1] / n)
1028
+ * ((eps - 1) * mu_N ** n
1029
+ + mu_dN ** n * (mu_d ** (n * b) - eps * mu_d ** (n * c)))
1030
+ for n in range(1, numterms + 1))
1031
+
1032
+ def lseries(self, embedding=0, prec=53, max_imaginary_part=0,
1033
+ max_asymp_coeffs=40):
1034
+ r"""
1035
+ Return the `L`-series of the weight k cusp form
1036
+ `f` on `\Gamma_0(N)`.
1037
+
1038
+ This actually returns an interface to Tim Dokchitser's program for
1039
+ computing with the `L`-series of the cusp form.
1040
+
1041
+ INPUT:
1042
+
1043
+ - ``embedding`` -- either an embedding of the coefficient field of self
1044
+ into `\CC`, or an integer `i` between 0 and D-1 where D is the degree
1045
+ of the coefficient field (meaning to pick the `i`-th embedding).
1046
+ (default: 0)
1047
+
1048
+ - ``prec`` -- integer (default: 53); bits precision
1049
+
1050
+ - ``max_imaginary_part`` -- real number (default: 0)
1051
+
1052
+ - ``max_asymp_coeffs`` -- integer (default: 40)
1053
+
1054
+ For more information on the significance of the last three arguments,
1055
+ see :mod:`~sage.lfunctions.dokchitser`.
1056
+
1057
+ .. NOTE::
1058
+
1059
+ If an explicit embedding is given, but this embedding is specified
1060
+ to smaller precision than ``prec``, it will be automatically
1061
+ refined to precision ``prec``.
1062
+
1063
+ OUTPUT:
1064
+
1065
+ The `L`-series of the cusp form, as a
1066
+ :class:`sage.lfunctions.dokchitser.Dokchitser` object.
1067
+
1068
+ EXAMPLES::
1069
+
1070
+ sage: f = CuspForms(2,8).newforms()[0]
1071
+ sage: L = f.lseries()
1072
+ sage: L
1073
+ L-series associated to the cusp form q - 8*q^2 + 12*q^3 + 64*q^4 - 210*q^5 + O(q^6)
1074
+ sage: L(1)
1075
+ 0.0884317737041015
1076
+ sage: L(0.5)
1077
+ 0.0296568512531983
1078
+
1079
+ As a consistency check, we verify that the functional equation holds::
1080
+
1081
+ sage: abs(L.check_functional_equation()) < 1.0e-20
1082
+ True
1083
+
1084
+ For non-rational newforms we can specify an embedding of the coefficient field::
1085
+
1086
+ sage: f = Newforms(43, names='a')[1]
1087
+ sage: K = f.hecke_eigenvalue_field()
1088
+ sage: phi1, phi2 = K.embeddings(CC)
1089
+ sage: L = f.lseries(embedding=phi1)
1090
+ sage: L
1091
+ L-series associated to the cusp form q + a1*q^2 - a1*q^3 + (-a1 + 2)*q^5 + O(q^6), a1=-1.41421356237310
1092
+ sage: L(1)
1093
+ 0.620539857407845
1094
+ sage: L = f.lseries(embedding=1)
1095
+ sage: L(1)
1096
+ 0.921328017272472
1097
+
1098
+ An example with a non-real coefficient field (`\QQ(\zeta_3)`
1099
+ in this case)::
1100
+
1101
+ sage: f = Newforms(Gamma1(13), 2, names='a')[0]
1102
+ sage: f.lseries(embedding=0)(1)
1103
+ 0.298115272465799 - 0.0402203326076734*I
1104
+ sage: f.lseries(embedding=1)(1)
1105
+ 0.298115272465799 + 0.0402203326076732*I
1106
+
1107
+ We compute with the `L`-series of the Eisenstein series `E_4`::
1108
+
1109
+ sage: f = ModularForms(1,4).0
1110
+ sage: L = f.lseries()
1111
+ sage: L(1)
1112
+ -0.0304484570583933
1113
+ sage: L = eisenstein_series_lseries(4)
1114
+ sage: L(1)
1115
+ -0.0304484570583933
1116
+
1117
+ Consistency check with delta_lseries (which computes coefficients in pari)::
1118
+
1119
+ sage: delta = CuspForms(1,12).0
1120
+ sage: L = delta.lseries()
1121
+ sage: L(1)
1122
+ 0.0374412812685155
1123
+ sage: L = delta_lseries()
1124
+ sage: L(1)
1125
+ 0.0374412812685155
1126
+
1127
+ We check that :issue:`5262` is fixed::
1128
+
1129
+ sage: # needs database_cremona_mini_ellcurve
1130
+ sage: E = EllipticCurve('37b2')
1131
+ sage: h = Newforms(37)[1]
1132
+ sage: Lh = h.lseries()
1133
+ sage: LE = E.lseries()
1134
+ sage: Lh(1), LE(1)
1135
+ (0.725681061936153, 0.725681061936153)
1136
+ sage: CuspForms(1, 30).0.lseries().eps
1137
+ -1.00000000000000
1138
+
1139
+ We check that :issue:`25369` is fixed::
1140
+
1141
+ sage: f5 = Newforms(Gamma1(4), 5, names='a')[0]; f5
1142
+ q - 4*q^2 + 16*q^4 - 14*q^5 + O(q^6)
1143
+ sage: L5 = f5.lseries()
1144
+ sage: abs(L5.check_functional_equation()) < 1e-15
1145
+ True
1146
+ sage: abs(L5(4) - (gamma(1/4)^8/(3840*pi^2)).n()) < 1e-15
1147
+ True
1148
+
1149
+ We can change the precision (in bits)::
1150
+
1151
+ sage: f = Newforms(389, names='a')[0]
1152
+ sage: L = f.lseries(prec=30)
1153
+ sage: abs(L(1)) < 2^-30
1154
+ True
1155
+ sage: L = f.lseries(prec=53)
1156
+ sage: abs(L(1)) < 2^-53
1157
+ True
1158
+ sage: L = f.lseries(prec=100)
1159
+ sage: abs(L(1)) < 2^-100
1160
+ True
1161
+
1162
+ sage: f = Newforms(27, names='a')[0]
1163
+ sage: L = f.lseries()
1164
+ sage: L(1)
1165
+ 0.588879583428483
1166
+ """
1167
+ from sage.lfunctions.dokchitser import Dokchitser
1168
+
1169
+ # compute the requested embedding
1170
+ C = ComplexField(prec)
1171
+ K = self.base_ring()
1172
+ if isinstance(embedding, RingHomomorphism):
1173
+ # Target of embedding might have precision less than desired, so
1174
+ # need to refine
1175
+ emb = NumberFieldEmbedding(K, C, embedding(K.gen()))
1176
+ else:
1177
+ emb = self.base_ring().embeddings(C)[embedding]
1178
+
1179
+ # key = (prec, max_imaginary_part, max_asymp_coeffs)
1180
+ l = self.weight()
1181
+ N = self.level()
1182
+
1183
+ # get global root number
1184
+ w = self.atkin_lehner_eigenvalue(N, embedding=emb)
1185
+ e = ~C.gen()**l * w
1186
+
1187
+ if self.is_cuspidal():
1188
+ poles = [] # cuspidal
1189
+ else:
1190
+ poles = [l] # non-cuspidal
1191
+
1192
+ L = Dokchitser(conductor=N, gammaV=[0, 1], weight=l, eps=e, poles=poles,
1193
+ prec=prec)
1194
+ # Find out how many coefficients of the Dirichlet series are needed
1195
+ # in order to compute to the required precision
1196
+ num_coeffs = L.num_coeffs()
1197
+ coeffs = self.q_expansion(num_coeffs + 1).padded_list()[1:]
1198
+
1199
+ # renormalize so that coefficient of q is 1
1200
+ b = coeffs[0]
1201
+ if b != 1:
1202
+ invb = 1 / b
1203
+ coeffs = (invb * c for c in coeffs)
1204
+
1205
+ v = [emb(c) for c in coeffs]
1206
+ w = [c.conjugate() for c in v]
1207
+ L.init_coeffs(v=v, w=w,
1208
+ max_imaginary_part=max_imaginary_part,
1209
+ max_asymp_coeffs=max_asymp_coeffs)
1210
+ L.check_functional_equation()
1211
+ if K == QQ:
1212
+ L.rename('L-series associated to the cusp form %s' % self)
1213
+ else:
1214
+ L.rename('L-series associated to the cusp form %s, %s=%s'
1215
+ % (self, K.variable_name(), emb(K.gen())))
1216
+ return L
1217
+
1218
+ def symsquare_lseries(self, chi=None, embedding=0, prec=53):
1219
+ r"""
1220
+ Compute the symmetric square `L`-series of this modular form, twisted by
1221
+ the character `\chi`.
1222
+
1223
+ INPUT:
1224
+
1225
+ - ``chi`` -- Dirichlet character to twist by, or ``None`` (default:
1226
+ ``None``), interpreted as the trivial character)
1227
+ - ``embedding`` -- embedding of the coefficient field into `\RR` or
1228
+ `\CC`, or an integer `i` (in which case take the `i`-th embedding)
1229
+ - ``prec`` -- the desired precision in bits (default: 53)
1230
+
1231
+ OUTPUT: the symmetric square `L`-series of the cusp form, as a
1232
+ :class:`sage.lfunctions.dokchitser.Dokchitser` object.
1233
+
1234
+ EXAMPLES::
1235
+
1236
+ sage: CuspForms(1, 12).0.symsquare_lseries()(22)
1237
+ 0.999645711124771
1238
+
1239
+ An example twisted by a nontrivial character::
1240
+
1241
+ sage: psi = DirichletGroup(7).0^2
1242
+ sage: L = CuspForms(1, 16).0.symsquare_lseries(psi)
1243
+ sage: L(22)
1244
+ 0.998407750967420 - 0.00295712911510708*I
1245
+
1246
+ An example with coefficients not in `\QQ`::
1247
+
1248
+ sage: F = Newforms(1, 24, names='a')[0]
1249
+ sage: K = F.hecke_eigenvalue_field()
1250
+ sage: phi = K.embeddings(RR)[0]
1251
+ sage: L = F.symsquare_lseries(embedding=phi)
1252
+ sage: L(5)
1253
+ verbose -1 (...: dokchitser.py, __call__) Warning: Loss of 8 decimal digits due to cancellation
1254
+ -3.57698266793901e19
1255
+
1256
+ TESTS::
1257
+
1258
+ sage: CuspForms(1,16).0.symsquare_lseries(prec=200).check_functional_equation().abs() < 1.0e-80
1259
+ True
1260
+ sage: CuspForms(1, 12).0.symsquare_lseries(prec=1000)(22) # long time (20s)
1261
+ 0.999645711124771397835729622033153189549796658647254961493709341358991830134499267117001769570658192128781135161587571716303826382489492569725002840546129937149159065273765309218543427544527498868033604310899372849565046516553245752253255585377793879866297612679545029546953895098375829822346290125161
1262
+
1263
+ Check that :issue:`23247` is fixed::
1264
+
1265
+ sage: F = Newforms(1,12)[0]
1266
+ sage: chi = DirichletGroup(7).0
1267
+ sage: abs(F.symsquare_lseries(chi).check_functional_equation()) < 1e-5 # long time
1268
+ True
1269
+
1270
+ AUTHORS:
1271
+
1272
+ - Martin Raum (2011) -- original code posted to sage-nt
1273
+ - David Loeffler (2015) -- added support for twists, integrated into
1274
+ Sage library
1275
+ """
1276
+ from sage.lfunctions.dokchitser import Dokchitser
1277
+ weight = self.weight()
1278
+ C = ComplexField(prec)
1279
+ if self.level() != 1:
1280
+ raise NotImplementedError("Symmetric square L-functions only implemented for level 1")
1281
+
1282
+ # compute the requested embedding
1283
+ if isinstance(embedding, RingHomomorphism):
1284
+ # Target of embedding might have precision less than desired, so
1285
+ # need to refine
1286
+ K = self.base_ring()
1287
+ emb = NumberFieldEmbedding(K, ComplexField(prec), embedding(K.gen()))
1288
+ else:
1289
+ emb = self.base_ring().embeddings(ComplexField(prec))[embedding]
1290
+
1291
+ if chi is None:
1292
+ eps = 1
1293
+ N = 1
1294
+ else:
1295
+ assert chi.is_primitive()
1296
+ chi = chi.change_ring(C)
1297
+ eps = chi.gauss_sum()**3 / chi.base_ring()(chi.conductor())**QQ((3, 2))
1298
+ N = chi.conductor()**3
1299
+
1300
+ if (chi is None) or chi.is_even():
1301
+ L = Dokchitser(N, [0, 1, -weight + 2], 2 * weight - 1,
1302
+ eps, prec=prec)
1303
+ else:
1304
+ L = Dokchitser(N, [0, 1, -weight + 1], 2 * weight - 1,
1305
+ eps * C((0, 1)), prec=prec)
1306
+ lcoeffs_prec = L.num_coeffs()
1307
+
1308
+ t = verbose("Computing %s coefficients of F" % lcoeffs_prec, level=1)
1309
+ F_series = [u**2 for u in self.qexp(lcoeffs_prec + 1).list()[1:]]
1310
+ verbose("done", t, level=1)
1311
+
1312
+ # utility function for Dirichlet convolution of series
1313
+ def dirichlet_convolution(A, B):
1314
+ return [sum(A[d - 1] * B[n // d - 1] for d in divisors(n))
1315
+ for n in range(1, 1 + min(len(A), len(B)))]
1316
+
1317
+ # The Dirichlet series for \zeta(2 s - 2 k + 2)
1318
+ riemann_series = [n**(weight - 1) if n.is_square() else 0
1319
+ for n in xsrange(1, lcoeffs_prec + 1)]
1320
+ # The Dirichlet series for 1 / \zeta(s - k + 1)
1321
+ mu_series = [moebius(n) * n**(weight - 1) for n in xsrange(1, lcoeffs_prec + 1)]
1322
+ conv_series = dirichlet_convolution(mu_series, riemann_series)
1323
+
1324
+ dirichlet_series = dirichlet_convolution(conv_series, F_series)
1325
+
1326
+ # If the base ring is QQ we pass the coefficients to GP/PARI as exact
1327
+ # rationals. Otherwise, need to use the embedding.
1328
+ if self.base_ring() != QQ:
1329
+ dirichlet_series = [emb(cf) for cf in dirichlet_series]
1330
+
1331
+ if chi is not None:
1332
+ pari_precode_chi = str(chi.values()) + "[n%" + str(chi.conductor()) + "+1]; "
1333
+ else:
1334
+ pari_precode_chi = "1"
1335
+
1336
+ pari_precode = "hhh(n) = " + str(dirichlet_series) + "[n] * " + pari_precode_chi
1337
+
1338
+ L.init_coeffs("hhh(k)", w="conj(hhh(k))",
1339
+ pari_precode=pari_precode)
1340
+
1341
+ return L
1342
+
1343
+ def petersson_norm(self, embedding=0, prec=53):
1344
+ r"""
1345
+ Compute the Petersson scalar product of f with itself:
1346
+
1347
+ .. MATH::
1348
+
1349
+ \langle f, f \rangle = \int_{\Gamma_0(N) \backslash \mathbb{H}} |f(x + iy)|^2 y^k\, \mathrm{d}x\, \mathrm{d}y.
1350
+
1351
+ Only implemented for N = 1 at present. It is assumed that `f` has real
1352
+ coefficients. The norm is computed as a special value of the symmetric
1353
+ square `L`-function, using the identity
1354
+
1355
+ .. MATH::
1356
+
1357
+ \langle f, f \rangle = \frac{(k-1)! L(\mathrm{Sym}^2 f, k)}{2^{2k-1} \pi^{k+1}}
1358
+
1359
+ INPUT:
1360
+
1361
+ - ``embedding`` -- embedding of the coefficient field into `\RR` or
1362
+ `\CC`, or an integer `i` (interpreted as the `i`-th embedding)
1363
+ (default: 0)
1364
+ - ``prec`` -- integer (default: 53); precision in bits
1365
+
1366
+ EXAMPLES::
1367
+
1368
+ sage: CuspForms(1, 16).0.petersson_norm()
1369
+ verbose -1 (...: dokchitser.py, __call__) Warning: Loss of 2 decimal digits due to cancellation
1370
+ 2.16906134759063e-6
1371
+
1372
+ The Petersson norm depends on a choice of embedding::
1373
+
1374
+ sage: set_verbose(-2, "dokchitser.py") # disable precision-loss warnings
1375
+ sage: F = Newforms(1, 24, names='a')[0]
1376
+ sage: F.petersson_norm(embedding=0)
1377
+ 0.000107836545077234
1378
+ sage: F.petersson_norm(embedding=1)
1379
+ 0.000128992800758160
1380
+
1381
+ TESTS:
1382
+
1383
+ Verify that the Petersson norm is a quadratic form::
1384
+
1385
+ sage: F, G = CuspForms(1, 24).basis()
1386
+ sage: X = lambda u: u.petersson_norm(prec=100)
1387
+ sage: (X(F + G) + X(F - G) - 2*X(F) - 2*X(G)).abs() < 1e-25
1388
+ True
1389
+ """
1390
+ pi = RealField(prec).pi()
1391
+ L = self.symsquare_lseries(prec=prec, embedding=embedding)
1392
+ k = self.weight()
1393
+ return (ZZ(k - 1).factorial() / 2**(2 * k - 1) / pi**(k + 1)) * L(k).real_part()
1394
+
1395
+ def _q_expansion_bound(self, eps):
1396
+ r"""
1397
+ This function takes as input a modular form, ``self`` and a
1398
+ Dirichlet character ``eps`` and returns an integer bound such
1399
+ that if ``self`` and its twist by ``eps`` have the same
1400
+ `q`-expansion up to this bound, then they are equal.
1401
+
1402
+ The bound is taken from [Mu1997]_. See also [Shi1971]_, Proposition
1403
+ 3.64.
1404
+
1405
+ INPUT:
1406
+
1407
+ - ``eps`` -- a Dirichlet character
1408
+
1409
+ OUTPUT: a positive integer
1410
+
1411
+ EXAMPLES:
1412
+
1413
+ Here is an example that can easily be checked by hand. ::
1414
+
1415
+ sage: M = ModularForms(Gamma0(11), 2)
1416
+ sage: C = M.cuspidal_submodule()
1417
+ sage: f = C.gens()[0]
1418
+ sage: F = CyclotomicField(5)
1419
+ sage: D = DirichletGroup(11, F)
1420
+ sage: eps = D.gens()[0]
1421
+ sage: f._q_expansion_bound(eps)
1422
+ 22
1423
+
1424
+ The level of ``self`` does not have to be related to the conductor
1425
+ of eps. ::
1426
+
1427
+ sage: M = ModularForms(Gamma0(1), 12)
1428
+ sage: C = M.cuspidal_submodule()
1429
+ sage: Delta = C.gens()[0]
1430
+ sage: F = CyclotomicField(12)
1431
+ sage: D = DirichletGroup(13, F)
1432
+ sage: eps = D.gens()[0]
1433
+ sage: Delta._q_expansion_bound(eps)
1434
+ 182
1435
+ """
1436
+ chi = self.character()
1437
+ M = lcm([self.level(), eps.conductor()**2,
1438
+ chi.conductor() * eps.conductor()])
1439
+ y = QQ(self.weight()) / QQ(12) * M
1440
+ for p in M.prime_divisors():
1441
+ y *= (1 + 1 / QQ(p))
1442
+ return y.ceil()
1443
+
1444
+ @cached_method
1445
+ def has_cm(self) -> bool:
1446
+ r"""
1447
+ Return whether the modular form ``self`` has complex multiplication.
1448
+
1449
+ OUTPUT: boolean
1450
+
1451
+ .. SEEALSO::
1452
+
1453
+ - :meth:`cm_discriminant` (to return the CM field)
1454
+ - :meth:`sage.schemes.elliptic_curves.ell_rational_field.has_cm`
1455
+
1456
+ EXAMPLES::
1457
+
1458
+ sage: G = DirichletGroup(21); eps = G.0 * G.1
1459
+ sage: Newforms(eps, 2)[0].has_cm()
1460
+ True
1461
+
1462
+ This example illustrates what happens when
1463
+ candidate_characters(self) is the empty list. ::
1464
+
1465
+ sage: M = ModularForms(Gamma0(1), 12)
1466
+ sage: C = M.cuspidal_submodule()
1467
+ sage: Delta = C.gens()[0]
1468
+ sage: Delta.has_cm()
1469
+ False
1470
+
1471
+ We now compare the function has_cm between elliptic curves and
1472
+ their associated modular forms. ::
1473
+
1474
+ sage: E = EllipticCurve([-1, 0])
1475
+ sage: f = E.modular_form()
1476
+ sage: f.has_cm()
1477
+ True
1478
+ sage: E.has_cm() == f.has_cm()
1479
+ True
1480
+
1481
+ Here is a non-cm example coming from elliptic curves. ::
1482
+
1483
+ sage: # needs database_cremona_mini_ellcurve
1484
+ sage: E = EllipticCurve('11a')
1485
+ sage: f = E.modular_form()
1486
+ sage: f.has_cm()
1487
+ False
1488
+ sage: E.has_cm() == f.has_cm()
1489
+ True
1490
+ """
1491
+ N = self.level()
1492
+ M = self.character().conductor()
1493
+
1494
+ for p in N.prime_factors():
1495
+ if M % p and N.valuation(p) == 1:
1496
+ verbose("Form is Steinberg at %s, cannot be CM" % p, level=1)
1497
+ return False
1498
+ cand_chars = [(x, self._q_expansion_bound(x)) for x in DirichletGroup(N, QQ) if x.is_odd()]
1499
+
1500
+ verbose("Conductors of candidate characters: %s" % (", ".join(str(x[0].conductor()) for x in cand_chars)), level=1)
1501
+ verbose("Qexp bounds: %s" % (", ".join(str(x[1]) for x in cand_chars)), level=1)
1502
+ # If there are no candidate characters, then self cannot have CM.
1503
+ if not cand_chars:
1504
+ return False
1505
+
1506
+ # Test each prime and discard characters for which eps(p) != 1 when f[p] != 0.
1507
+ p = ZZ(2)
1508
+ while p <= min(B for (eps, B) in cand_chars):
1509
+ verbose("Checking p = %s (%s candidate characters left))" % (p, len(cand_chars)), level=1)
1510
+ # We only have to test the CM condition at primes that do not
1511
+ # divide the level of self.
1512
+ if not self.level() % p:
1513
+ p = p.next_prime()
1514
+ continue
1515
+
1516
+ # Evaluating characters is cheap, while computing f[p] is
1517
+ # expensive, so if eps(p) = 1 for all p, then we don't bother to
1518
+ # compute f[p].
1519
+ cand_chars = [(eps, B) for (eps, B) in cand_chars if (eps(p) == 1 or self[p] == 0)]
1520
+
1521
+ if len(cand_chars) == 0:
1522
+ # f doesn't have CM
1523
+ return False
1524
+
1525
+ # go on to next prime
1526
+ p = p.next_prime()
1527
+
1528
+ B0 = min(B for (eps, B) in cand_chars)
1529
+ C = [eps for (eps, B) in cand_chars if B == B0]
1530
+ if len(C) > 1:
1531
+ # can't happen (except in weight 1, which isn't implemented yet
1532
+ # anyway)
1533
+ raise ArithmeticError("Got multiple characters in has_cm")
1534
+ self.__cm_char = C[0].primitive_character()
1535
+ return True
1536
+
1537
+ def cm_discriminant(self):
1538
+ r"""
1539
+ Return the discriminant of the CM field associated to this form. An
1540
+ error will be raised if the form isn't of CM type.
1541
+
1542
+ EXAMPLES::
1543
+
1544
+ sage: Newforms(49, 2)[0].cm_discriminant()
1545
+ -7
1546
+ sage: CuspForms(1, 12).gen(0).cm_discriminant()
1547
+ Traceback (most recent call last):
1548
+ ...
1549
+ ValueError: Not a CM form
1550
+ """
1551
+ if not self.has_cm():
1552
+ raise ValueError("Not a CM form")
1553
+ return -self.__cm_char.conductor()
1554
+
1555
+
1556
+ class Newform(ModularForm_abstract):
1557
+ # The reasons why Newform does not inherit from ModularFormElement
1558
+ # should really be documented somewhere.
1559
+
1560
+ def __init__(self, parent, component, names, check=True):
1561
+ r"""
1562
+ Initialize a Newform object.
1563
+
1564
+ INPUT:
1565
+
1566
+ - ``parent`` -- an ambient cuspidal space of modular forms for
1567
+ which ``self`` is a newform
1568
+
1569
+ - ``component`` -- a simple component of a cuspidal modular
1570
+ symbols space of any sign corresponding to this newform
1571
+
1572
+ - ``check`` -- if check is ``True``, check that parent and
1573
+ component have the same weight, level, and character, that
1574
+ component has sign 1 and is simple, and that the types are
1575
+ correct on all inputs.
1576
+
1577
+ EXAMPLES::
1578
+
1579
+ sage: sage.modular.modform.element.Newform(CuspForms(11,2), ModularSymbols(11,2,sign=1).cuspidal_subspace(), 'a')
1580
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
1581
+
1582
+ sage: f = Newforms(DirichletGroup(5).0, 7,names='a')[0]; f[2].trace(f.base_ring().base_field())
1583
+ -5*zeta4 - 5
1584
+ """
1585
+ from .space import ModularFormsSpace
1586
+ if check:
1587
+ if not isinstance(parent, ModularFormsSpace):
1588
+ raise TypeError("parent must be a space of modular forms")
1589
+ if not isinstance(component, ModularSymbolsSpace):
1590
+ raise TypeError("component must be a space of modular symbols")
1591
+ if parent.group() != component.group():
1592
+ raise ValueError("parent and component must be defined by the same congruence subgroup")
1593
+ if parent.weight() != component.weight():
1594
+ raise ValueError("parent and component must have the same weight")
1595
+ if not component.is_cuspidal():
1596
+ raise ValueError("component must be cuspidal")
1597
+ if not component.is_simple():
1598
+ raise ValueError("component must be simple")
1599
+ extension_field = component.eigenvalue(1, name=names).parent()
1600
+ if extension_field != parent.base_ring(): # .degree() != 1 and rings.is_NumberField(extension_field):
1601
+ assert extension_field.base_field() == parent.base_ring()
1602
+ extension_field = parent.base_ring().extension(extension_field.relative_polynomial(), names=names)
1603
+ self.__name = names
1604
+ ModuleElement.__init__(self, parent.base_extend(extension_field))
1605
+ self.__modsym_space = component
1606
+ self.__hecke_eigenvalue_field = extension_field
1607
+
1608
+ def _name(self):
1609
+ r"""
1610
+ Return the name of the generator of the Hecke eigenvalue field
1611
+ of ``self``. Note that a name exists even when this field is `\QQ`.
1612
+
1613
+ EXAMPLES::
1614
+
1615
+ sage: [ f._name() for f in Newforms(38,4,names='a') ]
1616
+ ['a0', 'a1', 'a2']
1617
+ """
1618
+ return self.__name
1619
+
1620
+ def _compute_q_expansion(self, prec):
1621
+ """
1622
+ Return the `q`-expansion of ``self`` to precision ``prec``.
1623
+
1624
+ EXAMPLES::
1625
+
1626
+ sage: forms = Newforms(31, 6, names='a')
1627
+ sage: forms[0]._compute_q_expansion(10)
1628
+ q + a0*q^2 + (5/704*a0^4 + 43/704*a0^3 - 61/88*a0^2 - 197/44*a0 + 717/88)*q^3 + (a0^2 - 32)*q^4 + (-31/352*a0^4 - 249/352*a0^3 + 111/22*a0^2 + 218/11*a0 - 2879/44)*q^5 + (-1/352*a0^4 - 79/352*a0^3 - 67/44*a0^2 + 13/22*a0 - 425/44)*q^6 + (17/88*a0^4 + 133/88*a0^3 - 405/44*a0^2 - 1005/22*a0 - 35/11)*q^7 + (a0^3 - 64*a0)*q^8 + (39/352*a0^4 + 441/352*a0^3 - 93/44*a0^2 - 441/22*a0 - 5293/44)*q^9 + O(q^10)
1629
+ sage: forms[0]._compute_q_expansion(15)
1630
+ q + a0*q^2 + (5/704*a0^4 + 43/704*a0^3 - 61/88*a0^2 - 197/44*a0 + 717/88)*q^3 + (a0^2 - 32)*q^4 + (-31/352*a0^4 - 249/352*a0^3 + 111/22*a0^2 + 218/11*a0 - 2879/44)*q^5 + (-1/352*a0^4 - 79/352*a0^3 - 67/44*a0^2 + 13/22*a0 - 425/44)*q^6 + (17/88*a0^4 + 133/88*a0^3 - 405/44*a0^2 - 1005/22*a0 - 35/11)*q^7 + (a0^3 - 64*a0)*q^8 + (39/352*a0^4 + 441/352*a0^3 - 93/44*a0^2 - 441/22*a0 - 5293/44)*q^9 + (15/176*a0^4 - 135/176*a0^3 - 185/11*a0^2 + 311/11*a0 + 2635/22)*q^10 + (-291/704*a0^4 - 3629/704*a0^3 + 1139/88*a0^2 + 10295/44*a0 - 21067/88)*q^11 + (-75/176*a0^4 - 645/176*a0^3 + 475/22*a0^2 + 1503/11*a0 - 5651/22)*q^12 + (207/704*a0^4 + 2977/704*a0^3 + 581/88*a0^2 - 3307/44*a0 - 35753/88)*q^13 + (-5/22*a0^4 + 39/11*a0^3 + 763/22*a0^2 - 2296/11*a0 - 2890/11)*q^14 + O(q^15)
1631
+ """
1632
+ return self.modular_symbols(1).q_eigenform(prec, names=self._name())
1633
+
1634
+ def __eq__(self, other):
1635
+ """
1636
+ Return ``True`` if ``self`` equals ``other``, and ``False`` otherwise.
1637
+
1638
+ EXAMPLES::
1639
+
1640
+ sage: f1, f2 = Newforms(17,4,names='a')
1641
+ sage: f1.__eq__(f1)
1642
+ True
1643
+ sage: f1.__eq__(f2)
1644
+ False
1645
+
1646
+ We test comparison of equal newforms with different parents
1647
+ (see :issue:`18478`)::
1648
+
1649
+ sage: f = Newforms(Gamma1(11), 2)[0]; f
1650
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
1651
+ sage: g = Newforms(Gamma0(11), 2)[0]; g
1652
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
1653
+ sage: f == g
1654
+ True
1655
+
1656
+ sage: f = Newforms(DirichletGroup(4)[1], 5)[0]; f
1657
+ q - 4*q^2 + 16*q^4 - 14*q^5 + O(q^6)
1658
+ sage: g = Newforms(Gamma1(4), 5)[0]; g
1659
+ q - 4*q^2 + 16*q^4 - 14*q^5 + O(q^6)
1660
+ sage: f == g
1661
+ True
1662
+ """
1663
+ if (not isinstance(other, ModularForm_abstract) or self.weight() != other.weight()):
1664
+ return False
1665
+ if isinstance(other, Newform):
1666
+ if (self.level() != other.level() or self.character() != other.character()):
1667
+ return False
1668
+ # The two parents may have different Sturm bounds in case
1669
+ # one of them is a space of cusp forms with character
1670
+ # (possibly trivial, i.e. for the group Gamma0(n)) and the
1671
+ # other is a space of cusp forms for Gamma1(n). It is
1672
+ # safe to take the smaller bound because we have checked
1673
+ # that the characters agree.
1674
+ bound = min(self.parent().sturm_bound(),
1675
+ other.parent().sturm_bound())
1676
+ return self.q_expansion(bound) == other.q_expansion(bound)
1677
+ # other is a ModularFormElement
1678
+ return self.element() == other
1679
+
1680
+ @cached_method
1681
+ def abelian_variety(self):
1682
+ """
1683
+ Return the abelian variety associated to ``self``.
1684
+
1685
+ EXAMPLES::
1686
+
1687
+ sage: Newforms(14,2)[0]
1688
+ q - q^2 - 2*q^3 + q^4 + O(q^6)
1689
+ sage: Newforms(14,2)[0].abelian_variety()
1690
+ Newform abelian subvariety 14a of dimension 1 of J0(14)
1691
+ sage: Newforms(1, 12)[0].abelian_variety()
1692
+ Traceback (most recent call last):
1693
+ ...
1694
+ TypeError: f must have weight 2
1695
+ """
1696
+ from sage.modular.abvar.abvar_newform import ModularAbelianVariety_newform
1697
+ return ModularAbelianVariety_newform(self)
1698
+
1699
+ def hecke_eigenvalue_field(self):
1700
+ r"""
1701
+ Return the field generated over the rationals by the
1702
+ coefficients of this newform.
1703
+
1704
+ EXAMPLES::
1705
+
1706
+ sage: ls = Newforms(35, 2, names='a') ; ls
1707
+ [q + q^3 - 2*q^4 - q^5 + O(q^6),
1708
+ q + a1*q^2 + (-a1 - 1)*q^3 + (-a1 + 2)*q^4 + q^5 + O(q^6)]
1709
+ sage: ls[0].hecke_eigenvalue_field()
1710
+ Rational Field
1711
+ sage: ls[1].hecke_eigenvalue_field()
1712
+ Number Field in a1 with defining polynomial x^2 + x - 4
1713
+ """
1714
+ return self.__hecke_eigenvalue_field
1715
+
1716
+ def coefficient(self, n):
1717
+ """
1718
+ Return the coefficient of `q^n` in the power series of ``self``.
1719
+
1720
+ INPUT:
1721
+
1722
+ - ``n`` -- positive integer
1723
+
1724
+ OUTPUT: the coefficient of `q^n` in the power series of ``self``
1725
+
1726
+ EXAMPLES::
1727
+
1728
+ sage: f = Newforms(11)[0]; f
1729
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
1730
+ sage: f.coefficient(100)
1731
+ -8
1732
+
1733
+ sage: g = Newforms(23, names='a')[0]; g
1734
+ q + a0*q^2 + (-2*a0 - 1)*q^3 + (-a0 - 1)*q^4 + 2*a0*q^5 + O(q^6)
1735
+ sage: g.coefficient(3)
1736
+ -2*a0 - 1
1737
+ """
1738
+ return self.modular_symbols(1).eigenvalue(n, self._name())
1739
+
1740
+ def _compute(self, X):
1741
+ """
1742
+ Compute the coefficients of `q^n` of the power series of self,
1743
+ for `n` in the list `X`. The results are not cached. (Use
1744
+ coefficients for cached results).
1745
+
1746
+ EXAMPLES::
1747
+
1748
+ sage: f = Newforms(39,4,names='a')[1] ; f
1749
+ q + a1*q^2 - 3*q^3 + (2*a1 + 5)*q^4 + (-2*a1 + 14)*q^5 + O(q^6)
1750
+ sage: f._compute([2,3,7])
1751
+ [a1, -3, -2*a1 + 2]
1752
+ sage: f._compute([])
1753
+ []
1754
+
1755
+ Check that :issue:`20793` is fixed::
1756
+
1757
+ sage: f = Newforms(83, 2, names='a')[1]; f
1758
+ q + a1*q^2 + (1/2*a1^4 - 1/2*a1^3 - 7/2*a1^2 + 3/2*a1 + 4)*q^3 + (a1^2 - 2)*q^4 + (-1/2*a1^5 - 1/2*a1^4 + 9/2*a1^3 + 7/2*a1^2 - 8*a1 - 2)*q^5 + O(q^6)
1759
+ sage: K = f.hecke_eigenvalue_field(); K
1760
+ Number Field in a1 with defining polynomial x^6 - x^5 - 9*x^4 + 7*x^3 + 20*x^2 - 12*x - 8
1761
+ sage: l = f.coefficients(20); l[-1]
1762
+ -a1^4 + 5*a1^2 - 4
1763
+ sage: l[-1].parent() is K
1764
+ True
1765
+ """
1766
+ M = self.modular_symbols(1)
1767
+ return [M.eigenvalue(x, name=self._name()) for x in X]
1768
+
1769
+ def element(self):
1770
+ """
1771
+ Find an element of the ambient space of modular forms which
1772
+ represents this newform.
1773
+
1774
+ .. NOTE::
1775
+
1776
+ This can be quite expensive. Also, the polynomial defining
1777
+ the field of Hecke eigenvalues should be considered random,
1778
+ since it is generated by a random sum of Hecke
1779
+ operators. (The field itself is not random, of course.)
1780
+
1781
+ EXAMPLES::
1782
+
1783
+ sage: ls = Newforms(38,4,names='a')
1784
+ sage: ls[0]
1785
+ q - 2*q^2 - 2*q^3 + 4*q^4 - 9*q^5 + O(q^6)
1786
+ sage: ls # random
1787
+ [q - 2*q^2 - 2*q^3 + 4*q^4 - 9*q^5 + O(q^6),
1788
+ q - 2*q^2 + (-a1 - 2)*q^3 + 4*q^4 + (2*a1 + 10)*q^5 + O(q^6),
1789
+ q + 2*q^2 + (1/2*a2 - 1)*q^3 + 4*q^4 + (-3/2*a2 + 12)*q^5 + O(q^6)]
1790
+ sage: type(ls[0])
1791
+ <class 'sage.modular.modform.element.Newform'>
1792
+ sage: ls[2][3].minpoly()
1793
+ x^2 - 9*x + 2
1794
+ sage: ls2 = [ x.element() for x in ls ]
1795
+ sage: ls2 # random
1796
+ [q - 2*q^2 - 2*q^3 + 4*q^4 - 9*q^5 + O(q^6),
1797
+ q - 2*q^2 + (-a1 - 2)*q^3 + 4*q^4 + (2*a1 + 10)*q^5 + O(q^6),
1798
+ q + 2*q^2 + (1/2*a2 - 1)*q^3 + 4*q^4 + (-3/2*a2 + 12)*q^5 + O(q^6)]
1799
+ sage: type(ls2[0])
1800
+ <class 'sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_g0_Q_with_category.element_class'>
1801
+ sage: ls2[2][3].minpoly()
1802
+ x^2 - 9*x + 2
1803
+ """
1804
+ S = self.parent()
1805
+ return S(self.q_expansion(S.sturm_bound()))
1806
+
1807
+ def is_cuspidal(self) -> bool:
1808
+ """
1809
+ Return ``True``.
1810
+
1811
+ For compatibility with elements of modular forms spaces.
1812
+
1813
+ EXAMPLES::
1814
+
1815
+ sage: Newforms(11, 2)[0].is_cuspidal()
1816
+ True
1817
+ """
1818
+ return True
1819
+
1820
+ def modular_symbols(self, sign=0):
1821
+ """
1822
+ Return the subspace with the specified sign of the space of
1823
+ modular symbols corresponding to this newform.
1824
+
1825
+ EXAMPLES::
1826
+
1827
+ sage: f = Newforms(18,4)[0]
1828
+ sage: f.modular_symbols()
1829
+ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_0(18) of weight 4 with sign 0 over Rational Field
1830
+ sage: f.modular_symbols(1)
1831
+ Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 11 for Gamma_0(18) of weight 4 with sign 1 over Rational Field
1832
+ """
1833
+ return self.__modsym_space.modular_symbols_of_sign(sign)
1834
+
1835
+ @cached_method
1836
+ def modsym_eigenspace(self, sign=0):
1837
+ """
1838
+ Return a submodule of dimension 1 or 2 of the ambient space of
1839
+ the sign 0 modular symbols space associated to ``self``,
1840
+ base-extended to the Hecke eigenvalue field, which is an
1841
+ eigenspace for the Hecke operators with the same eigenvalues
1842
+ as this newform, *and* is an eigenspace for the star
1843
+ involution of the appropriate sign if the sign is not 0.
1844
+
1845
+ EXAMPLES::
1846
+
1847
+ sage: N = Newform("37a")
1848
+ sage: N.modular_symbols(0)
1849
+ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field
1850
+ sage: M = N.modular_symbols(0)
1851
+ sage: V = N.modsym_eigenspace(1); V
1852
+ Vector space of degree 5 and dimension 1 over Rational Field
1853
+ Basis matrix:
1854
+ [ 0 1 -1 1 0]
1855
+ sage: V.0 in M.free_module()
1856
+ True
1857
+ sage: V = N.modsym_eigenspace(-1); V
1858
+ Vector space of degree 5 and dimension 1 over Rational Field
1859
+ Basis matrix:
1860
+ [ 0 0 0 1 -1/2]
1861
+ sage: V.0 in M.free_module()
1862
+ True
1863
+ """
1864
+ M = self.modular_symbols(sign=0)
1865
+ if sign != 0:
1866
+ Ms = M.sign_submodule(sign)
1867
+ r = 1
1868
+ else:
1869
+ Ms = M
1870
+ r = 2
1871
+ # silly thing: can't do Ms.eigenvector(), even when Ms is simple,
1872
+ # because it can't be relied on to choose the coefficient fields
1873
+ # consistently
1874
+ A = M.ambient()
1875
+ X = Ms.free_module().base_extend(self.hecke_eigenvalue_field())
1876
+ p = ZZ(2)
1877
+ while X.rank() > r:
1878
+ assert p <= M.sturm_bound()
1879
+ X = (A.hecke_matrix(p).base_extend(self.hecke_eigenvalue_field()) - self[p]).kernel_on(X)
1880
+ p = p.next_prime()
1881
+
1882
+ # should really return a modular symbol submodule object, but these are
1883
+ # not implemented over non-minimal base rings
1884
+ return X
1885
+
1886
+ def _defining_modular_symbols(self):
1887
+ """
1888
+ Return the modular symbols space corresponding to ``self``.
1889
+
1890
+ EXAMPLES::
1891
+
1892
+ sage: Newforms(43,2,names='a')
1893
+ [q - 2*q^2 - 2*q^3 + 2*q^4 - 4*q^5 + O(q^6),
1894
+ q + a1*q^2 - a1*q^3 + (-a1 + 2)*q^5 + O(q^6)]
1895
+ sage: [ x._defining_modular_symbols() for x in Newforms(43,2,names='a') ]
1896
+ [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field,
1897
+ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field]
1898
+ sage: ModularSymbols(43,2,sign=1).cuspidal_subspace().new_subspace().decomposition()
1899
+ [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field,
1900
+ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field]
1901
+ """
1902
+ return self.__modsym_space
1903
+
1904
+ def number(self):
1905
+ """
1906
+ Return the index of this space in the list of simple, new,
1907
+ cuspidal subspaces of the full space of modular symbols for
1908
+ this weight and level.
1909
+
1910
+ EXAMPLES::
1911
+
1912
+ sage: Newforms(43, 2, names='a')[1].number()
1913
+ 1
1914
+ """
1915
+ return self._defining_modular_symbols().ambient().cuspidal_subspace().new_subspace().decomposition().index(self._defining_modular_symbols())
1916
+
1917
+ def __bool__(self):
1918
+ """
1919
+ Return ``True``, as newforms are never zero.
1920
+
1921
+ EXAMPLES::
1922
+
1923
+ sage: bool(Newforms(14,2)[0])
1924
+ True
1925
+ """
1926
+ return True
1927
+
1928
+ def character(self):
1929
+ r"""
1930
+ The nebentypus character of this newform (as a Dirichlet character with
1931
+ values in the field of Hecke eigenvalues of the form).
1932
+
1933
+ EXAMPLES::
1934
+
1935
+ sage: Newforms(Gamma1(7), 4,names='a')[1].character()
1936
+ Dirichlet character modulo 7 of conductor 7 mapping 3 |--> 1/2*a1
1937
+ sage: chi = DirichletGroup(3).0; Newforms(chi, 7)[0].character() == chi
1938
+ True
1939
+ """
1940
+ return self._defining_modular_symbols().q_eigenform_character(self._name())
1941
+
1942
+ ###########################
1943
+ # Atkin--Lehner operators #
1944
+ ###########################
1945
+
1946
+ def _atkin_lehner_eigenvalue_from_qexp(self, Q):
1947
+ """
1948
+ Return the arithmetically-normalized `W_Q`-pseudoeigenvalue of
1949
+ ``self``, using a formula based on `q`-expansions (Theorem 2.1 of
1950
+ [AL1978]_).
1951
+
1952
+ INPUT:
1953
+
1954
+ - ``self`` -- a newform `f`
1955
+
1956
+ - ``Q`` -- integer exactly dividing the level of ``self``
1957
+
1958
+ .. NOTE::
1959
+
1960
+ This method assumes that the `Q`-th coefficient in the
1961
+ `q`-expansion of ``self`` is nonzero.
1962
+
1963
+ TESTS::
1964
+
1965
+ sage: f = Newforms(Gamma0(18), 4)[0]; f
1966
+ q + 2*q^2 + 4*q^4 - 6*q^5 + O(q^6)
1967
+ sage: f._atkin_lehner_eigenvalue_from_qexp(2)
1968
+ -2
1969
+ sage: f._atkin_lehner_eigenvalue_from_qexp(9)
1970
+ Traceback (most recent call last):
1971
+ ...
1972
+ ValueError: a_Q must be nonzero
1973
+
1974
+ An example with odd weight::
1975
+
1976
+ sage: f = Newforms(Gamma1(15), 3, names='a')[2]; f
1977
+ q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6)
1978
+ sage: f._atkin_lehner_eigenvalue_from_qexp(5)
1979
+ a2
1980
+ """
1981
+ if Q == 1:
1982
+ return ZZ.one()
1983
+ a_Q = self[Q]
1984
+ if not a_Q:
1985
+ raise ValueError("a_Q must be nonzero")
1986
+
1987
+ l = ZZ.one()
1988
+ M = self.character().conductor()
1989
+ for p, e in Q.factor():
1990
+ if p.divides(M): # principal series at p
1991
+ l *= (p**(self.weight() - 2) / self[p])**e
1992
+ else: # special at p
1993
+ l *= -self[p]
1994
+ return l
1995
+
1996
+ def _atkin_lehner_eigenvalue_from_modsym(self, Q):
1997
+ """
1998
+ Return the arithmetically-normalized `W_Q`-pseudoeigenvalue of
1999
+ ``self``, using the action of `W_Q` on modular symbols.
2000
+
2001
+ INPUT:
2002
+
2003
+ - ``self`` -- a newform `f`
2004
+
2005
+ - ``Q`` -- positive integer exactly dividing the level of ``self``
2006
+
2007
+ .. NOTE::
2008
+
2009
+ This algorithm is only valid if, for every prime `p` dividing `Q`,
2010
+ the `p`-part of the level of `f` is strictly larger than the
2011
+ `p`-part of the conductor of its character.
2012
+
2013
+ EXAMPLES::
2014
+
2015
+ sage: F = Newforms(Gamma1(15), 3, names='a')[2]
2016
+ sage: F._atkin_lehner_eigenvalue_from_modsym(5)
2017
+ a2
2018
+ sage: _ == F._atkin_lehner_eigenvalue_from_qexp(5)
2019
+ True
2020
+ """
2021
+ if Q == 1:
2022
+ return ZZ.one()
2023
+
2024
+ S = self._defining_modular_symbols()
2025
+ A = S.ambient()
2026
+ N = self.level()
2027
+ M = self.character().conductor()
2028
+ Q0 = M // M.prime_to_m_part(Q)
2029
+
2030
+ W = self.group().atkin_lehner_matrix(Q)
2031
+ if Q0 == 1:
2032
+ L = [W]
2033
+ else:
2034
+ L = []
2035
+ for a in xsrange(Q0):
2036
+ if a.gcd(Q0) > 1:
2037
+ continue
2038
+ aa = crt(a, 1, Q, N.prime_to_m_part(Q))
2039
+ diam = matrix(ZZ, 2, lift_to_sl2z(0, aa, N))
2040
+ L.append((W * diam * matrix(QQ, 2, [1, a / Q0, 0, 1])).change_ring(ZZ))
2041
+
2042
+ W = A._matrix_of_operator_on_modular_symbols(A, [x.list() for x in L])
2043
+ e = S.dual_eigenvector(names=self._name())
2044
+ i = e.nonzero_positions()[0]
2045
+ w = (W * e)[i] / e[i]
2046
+ if W * e != w * e:
2047
+ raise ArithmeticError("Bug in Atkin--Lehner computation: eigenspace not invariant")
2048
+ sign = prod([eps(-1) for eps in self.character().decomposition() if eps.conductor().divides(Q)])
2049
+ return w / Q0 / sign * self.character()(crt(1, Q // Q0, Q, N // Q))
2050
+
2051
+ def atkin_lehner_action(self, d=None, normalization='analytic', embedding=None):
2052
+ r"""
2053
+ Return the result of the Atkin-Lehner operator `W_d` on this form `f`,
2054
+ in the form of a constant `\lambda_d(f)` and a normalized newform `f'`
2055
+ such that
2056
+
2057
+ .. math::
2058
+
2059
+ f \mid W_d = \lambda_d(f) f'.
2060
+
2061
+ See :meth:`atkin_lehner_eigenvalue` for further details.
2062
+
2063
+ EXAMPLES::
2064
+
2065
+ sage: f = Newforms(DirichletGroup(30).1^2, 2, names='a')[0]
2066
+ sage: emb = f.base_ring().complex_embeddings()[0]
2067
+ sage: for d in divisors(30):
2068
+ ....: print(f.atkin_lehner_action(d, embedding=emb))
2069
+ (1.00000000000000, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2070
+ (-1.00000000000000*I, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2071
+ (1.00000000000000*I, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2072
+ (-0.894427190999916 + 0.447213595499958*I, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2073
+ (1.00000000000000, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2074
+ (-0.447213595499958 - 0.894427190999916*I, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2075
+ (0.447213595499958 + 0.894427190999916*I, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2076
+ (-0.894427190999916 + 0.447213595499958*I, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2077
+
2078
+ The above computation can also be done exactly::
2079
+
2080
+ sage: K.<z> = CyclotomicField(20)
2081
+ sage: f = Newforms(DirichletGroup(30).1^2, 2, names='a')[0]
2082
+ sage: emb = f.base_ring().embeddings(CyclotomicField(20, 'z'))[0]
2083
+ sage: for d in divisors(30):
2084
+ ....: print(f.atkin_lehner_action(d, embedding=emb))
2085
+ (1, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2086
+ (z^5, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2087
+ (-z^5, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2088
+ (-2/5*z^7 + 4/5*z^6 + 1/5*z^5 - 4/5*z^4 - 2/5*z^3 - 2/5, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2089
+ (1, q + a0*q^2 - a0*q^3 - q^4 + (a0 - 2)*q^5 + O(q^6))
2090
+ (4/5*z^7 + 2/5*z^6 - 2/5*z^5 - 2/5*z^4 + 4/5*z^3 - 1/5, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2091
+ (-4/5*z^7 - 2/5*z^6 + 2/5*z^5 + 2/5*z^4 - 4/5*z^3 + 1/5, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2092
+ (-2/5*z^7 + 4/5*z^6 + 1/5*z^5 - 4/5*z^4 - 2/5*z^3 - 2/5, q - a0*q^2 + a0*q^3 - q^4 + (-a0 - 2)*q^5 + O(q^6))
2093
+
2094
+ We can compute the eigenvalue of `W_{p^e}` in certain cases
2095
+ where the `p`-th coefficient of `f` is zero::
2096
+
2097
+ sage: f = Newforms(169, names='a')[0]; f
2098
+ q + a0*q^2 + 2*q^3 + q^4 - a0*q^5 + O(q^6)
2099
+ sage: f[13]
2100
+ 0
2101
+ sage: f.atkin_lehner_eigenvalue(169)
2102
+ -1
2103
+
2104
+ An example showing the non-multiplicativity of the pseudo-eigenvalues::
2105
+
2106
+ sage: chi = DirichletGroup(18).0^4
2107
+ sage: f = Newforms(chi, 2)[0]
2108
+ sage: w2, _ = f.atkin_lehner_action(2); w2
2109
+ zeta6
2110
+ sage: w9, _ = f.atkin_lehner_action(9); w9
2111
+ -zeta18^4
2112
+ sage: w18,_ = f.atkin_lehner_action(18); w18
2113
+ -zeta18
2114
+ sage: w18 == w2 * w9 * chi( crt(2, 9, 9, 2) )
2115
+ True
2116
+
2117
+ TESTS::
2118
+
2119
+ sage: K.<a> = QuadraticField(1129)
2120
+ sage: f = Newforms(Gamma0(20), 8, base_ring=K)[2]; f
2121
+ q + (2*a - 10)*q^3 + 125*q^5 + O(q^6)
2122
+ sage: f.atkin_lehner_action(2)
2123
+ (-1, q + (2*a - 10)*q^3 + 125*q^5 + O(q^6))
2124
+
2125
+ sage: f = Newforms(Gamma1(11), 2)[0]
2126
+ sage: f.atkin_lehner_action(2)
2127
+ Traceback (most recent call last):
2128
+ ...
2129
+ ValueError: d (= 2) does not divide the level (= 11)
2130
+ """
2131
+ # normalise d
2132
+ N = self.level()
2133
+ if d is None:
2134
+ d = N
2135
+ else:
2136
+ d = ZZ(d)
2137
+ if not d.divides(N):
2138
+ raise ValueError('d (= {}) does not divide the level (= {})'.format(d, N))
2139
+ d = N // N.prime_to_m_part(d)
2140
+
2141
+ if d == 1:
2142
+ w = self.base_ring().one()
2143
+ if embedding is not None:
2144
+ w = embedding(w)
2145
+ return w, self
2146
+
2147
+ eps_d = prod([eps.extend(d) for eps in self.character().decomposition() if eps.modulus().divides(d)])
2148
+ if eps_d.is_trivial():
2149
+ g = self
2150
+ else:
2151
+ g = self.twist(~eps_d, level=N)
2152
+ l = self.atkin_lehner_eigenvalue(d, normalization, embedding)
2153
+ return l, g
2154
+
2155
+ def atkin_lehner_eigenvalue(self, d=None, normalization='analytic', embedding=None):
2156
+ r"""
2157
+ Return the pseudo-eigenvalue of the Atkin-Lehner operator `W_d`
2158
+ acting on this form `f`.
2159
+
2160
+ INPUT:
2161
+
2162
+ - ``d`` -- positive integer exactly dividing the level `N` of `f`,
2163
+ i.e., `d` divides `N` and is coprime to `N/d`; the default is `d = N`
2164
+
2165
+ If `d` does not divide `N` exactly, then it will be replaced with a
2166
+ multiple `D` of `d` such that `D` exactly divides `N` and `D` has the
2167
+ same prime factors as `d`. An error will be raised if `d` does not
2168
+ divide `N`.
2169
+
2170
+ - ``normalization`` -- either ``'analytic'`` (the default) or
2171
+ ``'arithmetic'``; see below
2172
+
2173
+ - ``embedding`` -- (optional) embedding of the coefficient field of `f`
2174
+ into another ring; ignored if ``'normalization='arithmetic'``
2175
+
2176
+ OUTPUT:
2177
+
2178
+ The Atkin-Lehner pseudo-eigenvalue of `W_d` on `f`, as an element of
2179
+ the coefficient field of `f`, or the codomain of ``embedding`` if
2180
+ specified.
2181
+
2182
+ As defined in [AL1978]_, the pseudo-eigenvalue is the constant
2183
+ `\lambda_d(f)` such that
2184
+
2185
+ ..math::
2186
+
2187
+ f \mid W_d = \lambda_d(f) f'
2188
+
2189
+ where `f'` is some normalised newform (not necessarily equal to `f`).
2190
+
2191
+ If ``normalisation='analytic'`` (the default), this routine will
2192
+ compute `\lambda_d`, using the conventions of [AL1978]_ for the weight
2193
+ `k` action, which imply that `\lambda_d` has complex absolute value 1.
2194
+ However, with these conventions `\lambda_d` is not in the Hecke
2195
+ eigenvalue field of `f` in general, so it is often necessary to specify
2196
+ an embedding of the eigenvalue field into a larger ring (which needs to
2197
+ contain roots of unity of sufficiently large order, and a square root
2198
+ of `d` if `k` is odd).
2199
+
2200
+ If ``normalisation='arithmetic'`` we compute instead the quotient
2201
+
2202
+ ..math::
2203
+
2204
+ d^{k/2-1} \lambda_d(f) \varepsilon_{N/d}(d / d_0) / G(\varepsilon_d),
2205
+
2206
+ where `G(\varepsilon_d)` is the Gauss sum of the `d`-primary part of
2207
+ the nebentype of `f` (more precisely, of its associated primitive
2208
+ character), and `d_0` its conductor. This ratio is always in the Hecke
2209
+ eigenvalue field of `f` (and can be computed using only arithmetic in
2210
+ this field), so specifying an embedding is not needed, although we
2211
+ still allow it for consistency.
2212
+
2213
+ (Note that if `k = 2` and `\varepsilon` is trivial, both
2214
+ normalisations coincide.)
2215
+
2216
+ .. SEEALSO::
2217
+
2218
+ - :meth:`sage.modular.hecke.module.atkin_lehner_operator`
2219
+ (especially for the conventions used to define the operator
2220
+ `W_d`)
2221
+
2222
+ - :meth:`atkin_lehner_action`, which returns both the
2223
+ pseudo-eigenvalue and the newform `f'`.
2224
+
2225
+ EXAMPLES::
2226
+
2227
+ sage: [x.atkin_lehner_eigenvalue() for x in ModularForms(53).newforms('a')]
2228
+ [1, -1]
2229
+
2230
+ sage: f = Newforms(Gamma1(15), 3, names='a')[2]; f
2231
+ q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6)
2232
+ sage: f.atkin_lehner_eigenvalue(5)
2233
+ Traceback (most recent call last):
2234
+ ...
2235
+ ValueError: Unable to compute square root. Try specifying an embedding into a larger ring
2236
+ sage: L = f.hecke_eigenvalue_field(); x = polygen(QQ); M.<sqrt5> = L.extension(x^2 - 5)
2237
+ sage: f.atkin_lehner_eigenvalue(5, embedding=M.coerce_map_from(L))
2238
+ 1/5*a2*sqrt5
2239
+ sage: f.atkin_lehner_eigenvalue(5, normalization='arithmetic')
2240
+ a2
2241
+
2242
+ sage: Newforms(DirichletGroup(5).0^2, 6, names='a')[0].atkin_lehner_eigenvalue()
2243
+ Traceback (most recent call last):
2244
+ ...
2245
+ ValueError: Unable to compute Gauss sum. Try specifying an embedding into a larger ring
2246
+
2247
+ TESTS:
2248
+
2249
+ Check that the bug reported at :issue:`18061` is fixed::
2250
+
2251
+ sage: K.<i> = CyclotomicField(4)
2252
+ sage: f = Newforms(DirichletGroup(30, QQ).1, 2, K)[0]
2253
+ sage: f.atkin_lehner_eigenvalue(embedding=K.embeddings(QQbar)[1])
2254
+ -0.8944271909999159? - 0.4472135954999580?*I
2255
+
2256
+ Check that :issue:`24086` is fixed::
2257
+
2258
+ sage: f = Newforms(24, 4)[0]
2259
+ sage: f.atkin_lehner_eigenvalue(8)
2260
+ -1
2261
+ sage: f.atkin_lehner_eigenvalue(3)
2262
+ -1
2263
+
2264
+ A case where the eigenvalue isn't in the coefficient field of `f`::
2265
+
2266
+ sage: chi = DirichletGroup(7, QQ).0
2267
+ sage: f = Newforms(chi, 3)[0]
2268
+ sage: f.atkin_lehner_eigenvalue()
2269
+ Traceback (most recent call last):
2270
+ ...
2271
+ ValueError: Unable to compute square root. Try specifying an embedding into a larger ring
2272
+ sage: emb = f.hecke_eigenvalue_field().embeddings(QQbar)[0]
2273
+ sage: f.atkin_lehner_eigenvalue(embedding=emb)
2274
+ 0.?e-18 - 1.000000000000000?*I
2275
+
2276
+ A case where the embeddings really matter::
2277
+
2278
+ sage: chi2 = chi.extend(63)
2279
+ sage: g = Newforms(chi2, 3, names='a')[2]
2280
+ sage: g.atkin_lehner_eigenvalue(7)
2281
+ Traceback (most recent call last):
2282
+ ...
2283
+ ValueError: Unable to compute Gauss sum. Try specifying an embedding into a larger ring
2284
+ sage: g.atkin_lehner_eigenvalue(7, embedding=g.hecke_eigenvalue_field().embeddings(QQbar)[0])
2285
+ 0.?e-18 + 1.000000000000000?*I
2286
+ """
2287
+ if normalization not in ['arithmetic', 'analytic']:
2288
+ raise ValueError("unknown normalization %s" % normalization)
2289
+ N = self.level()
2290
+ if d is None:
2291
+ d = N
2292
+ d = ZZ(d)
2293
+ if N % d:
2294
+ raise ValueError("d should divide N")
2295
+ d = N // N.prime_to_m_part(d)
2296
+
2297
+ d1 = d2 = d3 = 1
2298
+ for (p, e) in d.factor():
2299
+ if self[p] == 0:
2300
+ d1 *= p**e
2301
+ elif self.character().conductor().valuation(p) == e:
2302
+ d2 *= p**e
2303
+ else:
2304
+ d3 *= p**e
2305
+
2306
+ verbose("computing W_%s using modsym, W_%s using qexp, W_%s using both" % (d1, d2, d3), level=2)
2307
+ w1 = self._atkin_lehner_eigenvalue_from_modsym(d1)
2308
+ w2 = self._atkin_lehner_eigenvalue_from_qexp(d2)
2309
+ w3a = self._atkin_lehner_eigenvalue_from_modsym(d3)
2310
+ w3b = self._atkin_lehner_eigenvalue_from_qexp(d3)
2311
+ assert w3a == w3b
2312
+ w = w1 * w2 * w3a
2313
+
2314
+ if embedding is None:
2315
+ R = self.hecke_eigenvalue_field()
2316
+ embedding = R.Hom(R).identity()
2317
+ else:
2318
+ R = embedding.codomain()
2319
+
2320
+ if normalization == 'arithmetic':
2321
+ return embedding(w)
2322
+ else:
2323
+ # get rid of the normalisation factors
2324
+ from sage.modular.dirichlet import trivial_character
2325
+
2326
+ epsd = prod([eps.extend(d) for eps in self.character().decomposition() if eps.modulus().divides(d)], trivial_character(d))
2327
+ epsd = epsd.primitive_character()
2328
+ d0 = epsd.modulus()
2329
+ epsdR = epsd.change_ring(embedding)
2330
+ if d0 > 1:
2331
+ try:
2332
+ G = epsdR.gauss_sum()
2333
+ except NotImplementedError:
2334
+ raise ValueError("Unable to compute Gauss sum. Try specifying an embedding into a larger ring")
2335
+ else:
2336
+ G = R(1)
2337
+ if not R(d**(self.weight() - 2)).is_square():
2338
+ raise ValueError("Unable to compute square root. Try specifying an embedding into a larger ring")
2339
+ ratio = R(d**(self.weight() - 2)).sqrt() * embedding(self.character()(crt(1, d // d0, d, N // d))) / G
2340
+ return embedding(w) / ratio
2341
+
2342
+ def twist(self, chi, level=None, check=True):
2343
+ r"""
2344
+ Return the twist of the newform ``self`` by the Dirichlet
2345
+ character ``chi``.
2346
+
2347
+ If ``self`` is a newform `f` with character `\epsilon` and
2348
+ `q`-expansion
2349
+
2350
+ .. MATH::
2351
+
2352
+ f(q) = \sum_{n=1}^\infty a_n q^n,
2353
+
2354
+ then the twist by `\chi` is the unique newform `f\otimes\chi`
2355
+ with character `\epsilon\chi^2` and `q`-expansion
2356
+
2357
+ .. MATH::
2358
+
2359
+ (f\otimes\chi)(q) = \sum_{n=1}^\infty b_n q^n
2360
+
2361
+ satisfying `b_n = \chi(n) a_n` for all but finitely many `n`.
2362
+
2363
+ INPUT:
2364
+
2365
+ - ``chi`` -- a Dirichlet character. Note that Sage must be able to
2366
+ determine a common base field into which both the Hecke eigenvalue
2367
+ field of self, and the field of values of ``chi``, can be embedded.
2368
+
2369
+ - ``level`` -- (optional) the level `N` of the twisted form. If `N` is
2370
+ not given, the algorithm tries to compute `N` using [AL1978]_,
2371
+ Theorem 3.1; if this is not possible, it returns an error. If `N` is
2372
+ given but incorrect, i.e. the twisted form does not have level `N`,
2373
+ then this function will attempt to detect this and return an error,
2374
+ but it may sometimes return an incorrect answer (a newform of level
2375
+ `N` whose first few coefficients agree with those of `f \otimes
2376
+ \chi`).
2377
+
2378
+ - ``check`` -- (optional) boolean; if ``True`` (default), ensure that
2379
+ the space of modular symbols that is computed is genuinely simple and
2380
+ new. This makes it less likely, but not impossible, that a wrong
2381
+ result is returned if an incorrect ``level`` is specified.
2382
+
2383
+ OUTPUT:
2384
+
2385
+ The form `f\otimes\chi` as an element of the set of newforms
2386
+ for `\Gamma_1(N)` with character `\epsilon\chi^2`.
2387
+
2388
+ EXAMPLES::
2389
+
2390
+ sage: G = DirichletGroup(3, base_ring=QQ)
2391
+ sage: Delta = Newforms(SL2Z, 12)[0]; Delta
2392
+ q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
2393
+ sage: Delta.twist(G[0]) == Delta
2394
+ True
2395
+ sage: Delta.twist(G[1]) # long time (about 5 s)
2396
+ q + 24*q^2 - 1472*q^4 - 4830*q^5 + O(q^6)
2397
+
2398
+ sage: M = CuspForms(Gamma1(13), 2)
2399
+ sage: f = M.newforms('a')[0]; f
2400
+ q + a0*q^2 + (-2*a0 - 4)*q^3 + (-a0 - 1)*q^4 + (2*a0 + 3)*q^5 + O(q^6)
2401
+ sage: f.twist(G[1])
2402
+ q - a0*q^2 + (-a0 - 1)*q^4 + (-2*a0 - 3)*q^5 + O(q^6)
2403
+
2404
+ sage: f = Newforms(Gamma1(30), 2, names='a')[1]; f
2405
+ q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6)
2406
+ sage: f.twist(f.character())
2407
+ Traceback (most recent call last):
2408
+ ...
2409
+ NotImplementedError: cannot calculate 5-primary part of the level of the twist of q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6) by Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1
2410
+ sage: f.twist(f.character(), level=30)
2411
+ q - a1*q^2 + a1*q^3 - q^4 + (-a1 - 2)*q^5 + O(q^6)
2412
+
2413
+ TESTS:
2414
+
2415
+ We test that feeding inappropriate values of the ``level`` parameter is handled gracefully::
2416
+
2417
+ sage: chi = DirichletGroup(1)[0]
2418
+ sage: Delta.twist(chi, level=3)
2419
+ Traceback (most recent call last):
2420
+ ...
2421
+ ValueError: twist of q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) by Dirichlet character modulo 1 of conductor 1 is not a newform of level 3
2422
+
2423
+ Twisting and twisting back works::
2424
+
2425
+ sage: f = Newforms(11)[0]
2426
+ sage: chi = DirichletGroup(5).0
2427
+ sage: f.twist(chi).twist(~chi, level=11) == f
2428
+ True
2429
+
2430
+ AUTHORS:
2431
+
2432
+ - Peter Bruin (April 2015)
2433
+ """
2434
+ from sage.modular.all import CuspForms
2435
+ R = coercion_model.common_parent(self.base_ring(), chi.base_ring())
2436
+ N = self.level()
2437
+ epsilon = self.character()
2438
+ chi = chi.primitive_character()
2439
+ if level is None:
2440
+ N_epsilon = epsilon.conductor()
2441
+ N_chi = chi.conductor()
2442
+ G = DirichletGroup(N_epsilon.lcm(N_chi), base_ring=R)
2443
+ epsilon_chi = G(epsilon) * G(chi)
2444
+ N_epsilon_chi = epsilon_chi.conductor()
2445
+ for q in N_chi.prime_divisors():
2446
+ # See [AL1978], Theorem 3.1.
2447
+ alpha = N_epsilon.valuation(q)
2448
+ beta = N_chi.valuation(q)
2449
+ gamma = N.valuation(q)
2450
+ delta = max(alpha + beta, 2 * beta, gamma)
2451
+ if delta == gamma and max(alpha + beta, 2 * beta) < gamma:
2452
+ continue
2453
+ if delta > gamma and N_epsilon_chi.valuation(q) == max(alpha, beta):
2454
+ continue
2455
+ raise NotImplementedError('cannot calculate %s-primary part of the level of the twist of %s by %s'
2456
+ % (q, self, chi))
2457
+ level = lcm([N, N_epsilon * N_chi, N_chi**2])
2458
+
2459
+ # determine the character of the twisted form
2460
+ G = DirichletGroup(lcm([N, chi.modulus(), level]), base_ring=R)
2461
+ eps_new = (G(epsilon) * G(chi)**2).restrict(level)
2462
+
2463
+ # create an ambient space
2464
+ D = ModularSymbols(eps_new, self.weight(), base_ring=R, sign=1).new_submodule()
2465
+ S = CuspForms(eps_new, self.weight(), base_ring=R)
2466
+
2467
+ # pull out the eigenspace
2468
+ for p in prime_range(500):
2469
+ if p.divides(chi.level()):
2470
+ continue
2471
+ D = (D.hecke_operator(p) - self[p] * chi(p)).kernel()
2472
+ if D.rank() == 1:
2473
+ break
2474
+ if D.is_zero():
2475
+ raise ValueError('twist of %s by %s is not a newform of level %s' % (self, chi, level))
2476
+ else:
2477
+ raise RuntimeError('unable to identify modular symbols for twist of %s by %s' % (self, chi))
2478
+ return Newform(S, D, names='_', check=check)
2479
+
2480
+ def minimal_twist(self, p=None):
2481
+ r"""
2482
+ Compute a pair `(g, chi)` such that `g = f \otimes \chi`, where `f` is
2483
+ this newform and `\chi` is a Dirichlet character, such that `g` has
2484
+ level as small as possible. If the optional argument `p` is given,
2485
+ consider only twists by Dirichlet characters of `p`-power conductor.
2486
+
2487
+ EXAMPLES::
2488
+
2489
+ sage: f = Newforms(121, 2)[3]
2490
+ sage: g, chi = f.minimal_twist()
2491
+ sage: g
2492
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
2493
+ sage: chi
2494
+ Dirichlet character modulo 11 of conductor 11 mapping 2 |--> -1
2495
+ sage: f.twist(chi, level=11) == g
2496
+ True
2497
+
2498
+ sage: # long time
2499
+ sage: f = Newforms(575, 2, names='a')[4]
2500
+ sage: g, chi = f.minimal_twist(5)
2501
+ sage: g
2502
+ q + a*q^2 - a*q^3 - 2*q^4 + (1/2*a + 2)*q^5 + O(q^6)
2503
+ sage: chi
2504
+ Dirichlet character modulo 5 of conductor 5 mapping 2 |--> 1/2*a
2505
+ sage: f.twist(chi, level=g.level()) == g
2506
+ True
2507
+ """
2508
+ if p is None:
2509
+ # test local minimality at all primes
2510
+ for p in self.level().prime_divisors():
2511
+ g, chi = self.minimal_twist(p)
2512
+ if g.level() < self.level():
2513
+ h, tau = g.minimal_twist(p=None)
2514
+ M = chi.modulus().lcm(tau.modulus())
2515
+ return (h, chi.extend(M) * tau.extend(M))
2516
+ # f locally minimal at all p, hence globally minimal
2517
+ return (self, DirichletGroup(1, self.base_ring())(1))
2518
+
2519
+ p = ZZ(p)
2520
+ N = self.level()
2521
+ r = N.valuation(p)
2522
+ c = self.character().conductor().valuation(p)
2523
+ if not (p.is_prime() and p.divides(N)):
2524
+ raise ValueError("p should be prime factor of N")
2525
+
2526
+ if (r == c) or (r == 1 and c == 0):
2527
+ # easy cases
2528
+ return (self, DirichletGroup(1, self.base_ring())(1))
2529
+ elif r < 2 * c:
2530
+ # In this case we know that there is a unique chi of conductor p^u
2531
+ # such that self x chi has level N/p^u, where u = r-c, and this
2532
+ # twist is minimal.
2533
+ candidates = []
2534
+ for chi in DirichletGroup(p**(r - c), self.base_ring()):
2535
+ if not chi.is_primitive():
2536
+ continue
2537
+ try:
2538
+ g = self.twist(chi, level=N // p**(r - c))
2539
+ candidates.append((g, chi))
2540
+ except ValueError:
2541
+ continue
2542
+
2543
+ l = ZZ.one()
2544
+ while len(candidates) > 1:
2545
+ l = l.next_prime()
2546
+ if l == p:
2547
+ continue
2548
+ candidates = [(h, chi) for (h, chi) in candidates if h[l] == chi(l) * self[l]]
2549
+ if l > 10000 or not candidates:
2550
+ raise RuntimeError("bug finding minimal twist")
2551
+ return candidates[0]
2552
+ else:
2553
+ # The hard case. Now f might be ramified principal series, twist of
2554
+ # Steinberg, or supercuspidal, and the minimal twist is not unique
2555
+ # any more. So we use the slow, but very general, type-space
2556
+ # algorithm.
2557
+ from sage.modular.local_comp.type_space import TypeSpace
2558
+ T = TypeSpace(self, p)
2559
+ if T.is_minimal():
2560
+ return (self, DirichletGroup(1, self.base_ring())(1))
2561
+
2562
+ g = T.minimal_twist()
2563
+ epsg = g.character().extend(N)
2564
+ chisq = (epsg / self.character()).restrict(p**(r // 2))
2565
+ K = coercion_model.common_parent(self.base_ring(), g.base_ring())
2566
+ chis = [chi for chi in DirichletGroup(p**(r // 2), K) if chi**2 == chisq]
2567
+
2568
+ if g.has_cm() and g.cm_discriminant().prime_divisors() == [p]:
2569
+ # Quicker to test g than self, because g has smaller level.
2570
+ t = 2
2571
+ else:
2572
+ t = 1
2573
+ l = ZZ.one()
2574
+ while len(chis) > t:
2575
+ l = l.next_prime()
2576
+ if l == p:
2577
+ continue
2578
+ chis = [chi for chi in chis if g[l] == chi(l) * self[l]]
2579
+ if l > 10000 or not chis:
2580
+ raise RuntimeError("bug finding minimal twist")
2581
+ return (g, chis[0])
2582
+
2583
+ def local_component(self, p, twist_factor=None):
2584
+ """
2585
+ Calculate the local component at the prime `p` of the automorphic
2586
+ representation attached to this newform. For more information, see the
2587
+ documentation of the :func:`LocalComponent` function.
2588
+
2589
+ EXAMPLES::
2590
+
2591
+ sage: f = Newform("49a")
2592
+ sage: f.local_component(7)
2593
+ Smooth representation of GL_2(Q_7) with conductor 7^2
2594
+ """
2595
+ from sage.modular.local_comp.local_comp import LocalComponent
2596
+ return LocalComponent(self, p, twist_factor)
2597
+
2598
+
2599
+ class ModularFormElement(ModularForm_abstract, element.HeckeModuleElement):
2600
+ def __init__(self, parent, x, check=True):
2601
+ r"""
2602
+ An element of a space of modular forms.
2603
+
2604
+ INPUT:
2605
+
2606
+ - ``parent`` -- :class:`ModularFormsSpace` (an ambient space of modular
2607
+ forms)
2608
+
2609
+ - ``x`` -- a vector on the basis for parent
2610
+
2611
+ - ``check`` -- if check is ``True``, check the types of the
2612
+ inputs
2613
+
2614
+ OUTPUT: ``ModularFormElement`` -- a modular form
2615
+
2616
+ EXAMPLES::
2617
+
2618
+ sage: M = ModularForms(Gamma0(11),2)
2619
+ sage: f = M.0
2620
+ sage: f.parent()
2621
+ Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
2622
+ """
2623
+ from .space import ModularFormsSpace
2624
+ if not isinstance(parent, ModularFormsSpace):
2625
+ raise TypeError("First argument must be an ambient space of modular forms.")
2626
+ element.HeckeModuleElement.__init__(self, parent, x)
2627
+
2628
+ def _compute_q_expansion(self, prec):
2629
+ """
2630
+ Compute the `q`-expansion of ``self`` to precision ``prec``.
2631
+
2632
+ EXAMPLES::
2633
+
2634
+ sage: # needs database_cremona_mini_ellcurve
2635
+ sage: f = EllipticCurve('37a').modular_form()
2636
+ sage: f.q_expansion() # indirect doctest
2637
+ q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)
2638
+ sage: f._compute_q_expansion(10)
2639
+ q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + O(q^10)
2640
+ """
2641
+ return self.parent()._q_expansion(element=self.element(), prec=prec)
2642
+
2643
+ def _add_(self, other):
2644
+ """
2645
+ Add ``self`` to ``other``.
2646
+
2647
+ EXAMPLES::
2648
+
2649
+ sage: f = ModularForms(DirichletGroup(17).0^2,2).2
2650
+ sage: g = ModularForms(DirichletGroup(17).0^2,2).1
2651
+ sage: f
2652
+ q + (-zeta8^2 + 2)*q^2 + (zeta8 + 3)*q^3 + (-2*zeta8^2 + 3)*q^4 + (-zeta8 + 5)*q^5 + O(q^6)
2653
+
2654
+ sage: g
2655
+ 1 + (-14/73*zeta8^3 + 57/73*zeta8^2 + 13/73*zeta8 - 6/73)*q^2 + (-90/73*zeta8^3 + 64/73*zeta8^2 - 52/73*zeta8 + 24/73)*q^3 + (-81/73*zeta8^3 + 189/73*zeta8^2 - 3/73*zeta8 + 153/73)*q^4 + (72/73*zeta8^3 + 124/73*zeta8^2 + 100/73*zeta8 + 156/73)*q^5 + O(q^6)
2656
+
2657
+ sage: f+g # indirect doctest
2658
+ 1 + q + (-14/73*zeta8^3 - 16/73*zeta8^2 + 13/73*zeta8 + 140/73)*q^2 + (-90/73*zeta8^3 + 64/73*zeta8^2 + 21/73*zeta8 + 243/73)*q^3 + (-81/73*zeta8^3 + 43/73*zeta8^2 - 3/73*zeta8 + 372/73)*q^4 + (72/73*zeta8^3 + 124/73*zeta8^2 + 27/73*zeta8 + 521/73)*q^5 + O(q^6)
2659
+ """
2660
+ return ModularFormElement(self.parent(), self.element() + other.element())
2661
+
2662
+ def __mul__(self, other):
2663
+ r"""
2664
+ Calculate the product ``self * other``.
2665
+
2666
+ This tries to determine the
2667
+ characters of ``self`` and ``other``, in order to avoid having to compute a
2668
+ (potentially very large) Gamma1 space. Note that this might lead to
2669
+ a modular form that is defined with respect to a larger subgroup than
2670
+ the factors are.
2671
+
2672
+ An example with character::
2673
+
2674
+ sage: f = ModularForms(DirichletGroup(3).0, 3).0
2675
+ sage: f * f
2676
+ 1 + 108*q^2 + 144*q^3 + 2916*q^4 + 8640*q^5 + O(q^6)
2677
+ sage: (f*f).parent()
2678
+ Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(3) of weight 6 over Rational Field
2679
+ sage: (f*f*f).parent()
2680
+ Modular Forms space of dimension 4, character [-1] and weight 9 over Rational Field
2681
+
2682
+ An example where the character is computed on-the-fly::
2683
+
2684
+ sage: f = ModularForms(Gamma1(3), 5).0
2685
+ sage: f*f
2686
+ 1 - 180*q^2 - 480*q^3 + 8100*q^4 + 35712*q^5 + O(q^6)
2687
+ sage: (f*f).parent()
2688
+ Modular Forms space of dimension 4 for Congruence Subgroup Gamma0(3) of weight 10 over Rational Field
2689
+
2690
+ sage: f = ModularForms(Gamma1(3), 7).0
2691
+ sage: f*f
2692
+ q^2 - 54*q^4 + 128*q^5 + O(q^6)
2693
+ sage: (f*f).parent()
2694
+ Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(3) of weight 14 over Rational Field
2695
+
2696
+ An example with no character::
2697
+
2698
+ sage: f = ModularForms(Gamma1(5), 2).0
2699
+ sage: f*f
2700
+ 1 + 120*q^3 - 240*q^4 + 480*q^5 + O(q^6)
2701
+ sage: (f*f).parent()
2702
+ Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(5) of weight 4 over Rational Field
2703
+
2704
+ TESTS:
2705
+
2706
+ This shows that the issue at :issue:`7548` is fixed::
2707
+
2708
+ sage: M = CuspForms(Gamma0(5*3^2), 2)
2709
+ sage: f = M.basis()[0]
2710
+ sage: 2*f
2711
+ 2*q - 2*q^4 + O(q^6)
2712
+ sage: f*2
2713
+ 2*q - 2*q^4 + O(q^6)
2714
+ """
2715
+
2716
+ # boring case: scalar multiplication
2717
+ if not isinstance(other, ModularFormElement):
2718
+ return element.HeckeModuleElement.__mul__(self, other)
2719
+
2720
+ # first ensure the levels are equal
2721
+ if self.level() != other.level():
2722
+ raise NotImplementedError("Cannot multiply forms of different levels")
2723
+
2724
+ # find out about characters
2725
+ try:
2726
+ eps1 = self.character()
2727
+ verbose("character of left is %s" % eps1)
2728
+ eps2 = other.character()
2729
+ verbose("character of right is %s" % eps2)
2730
+ newchar = eps1 * eps2
2731
+ verbose("character of product is %s" % newchar)
2732
+ except (NotImplementedError, ValueError):
2733
+ newchar = None
2734
+ verbose("character of product not determined")
2735
+
2736
+ # now do the math
2737
+ from .constructor import ModularForms
2738
+ if newchar is not None:
2739
+ verbose("creating a parent with char")
2740
+ newparent = ModularForms(newchar, self.weight() + other.weight(),
2741
+ base_ring=newchar.base_ring())
2742
+ verbose("parent is %s" % newparent)
2743
+ else:
2744
+ newparent = ModularForms(self.group(),
2745
+ self.weight() + other.weight(),
2746
+ base_ring=ZZ)
2747
+ m = newparent.sturm_bound()
2748
+ newqexp = self.qexp(m) * other.qexp(m)
2749
+
2750
+ return newparent.base_extend(newqexp.base_ring())(newqexp)
2751
+
2752
+ def _pow_int(self, n):
2753
+ """
2754
+ Raises ``self`` to integer powers.
2755
+
2756
+ TESTS::
2757
+
2758
+ sage: F = ModularForms(1, 12).0
2759
+ sage: (F^5).qexp(20)
2760
+ q^5 - 120*q^6 + 7020*q^7 - 266560*q^8 + 7379190*q^9 - 158562144*q^10 + 2748847640*q^11 -
2761
+ 39443189760*q^12 + 476711357265*q^13 - 4910778324400*q^14 + 43440479153652*q^15 -
2762
+ 331129448133120*q^16 + 2173189785854230*q^17 - 12199334429782080*q^18 +
2763
+ 57636170473930920*q^19 + O(q^20)
2764
+ sage: _ == (F.qexp(20)**5)
2765
+ True
2766
+
2767
+ Testing modular forms of nontrivial character::
2768
+
2769
+ sage: F = ModularForms(DirichletGroup(17).0^2, 2).2
2770
+ sage: F3 = F^3; F3
2771
+ q^3 + (-3*zeta8^2 + 6)*q^4 + (-12*zeta8^2 + 3*zeta8 + 18)*q^5 + O(q^6)
2772
+ sage: F3.qexp(6) == F.qexp(6)^3
2773
+ True
2774
+ sage: F3.character() == F.character()^3
2775
+ True
2776
+
2777
+ Testing modular forms of level greater than 1::
2778
+
2779
+ sage: for F in ModularForms(Gamma0(4), 2).gens():
2780
+ ....: assert (F**5).qexp(10) == F.qexp(10)**5
2781
+ """
2782
+ # shamelessly copied from above
2783
+ try:
2784
+ eps = self.character()
2785
+ verbose(f"character of self is {eps}")
2786
+ newchar = eps ** n
2787
+ verbose(f"character of product is {newchar}")
2788
+ except (NotImplementedError, ValueError):
2789
+ newchar = None
2790
+ verbose("character of product not determined")
2791
+
2792
+ from .constructor import ModularForms
2793
+ if newchar is not None:
2794
+ verbose("creating a parent with char")
2795
+ newparent = ModularForms(newchar, self.weight() * n,
2796
+ base_ring=newchar.base_ring())
2797
+ verbose(f"parent is {newparent}")
2798
+ else:
2799
+ newparent = ModularForms(self.group(), self.weight() * n,
2800
+ base_ring=ZZ)
2801
+ m = newparent.sturm_bound()
2802
+ newqexp = self.qexp(m) ** n
2803
+
2804
+ return newparent.base_extend(newqexp.base_ring())(newqexp)
2805
+
2806
+ def atkin_lehner_eigenvalue(self, d=None, embedding=None):
2807
+ """
2808
+ Return the result of the Atkin-Lehner operator `W_d` on
2809
+ ``self``.
2810
+
2811
+ INPUT:
2812
+
2813
+ - ``d`` -- positive integer exactly dividing the level `N` of
2814
+ ``self``, i.e. `d` divides `N` and is coprime to `N/d`. (default: `d
2815
+ = N`)
2816
+
2817
+ - ``embedding`` -- ignored (but accepted for compatibility with
2818
+ :meth:`Newform.atkin_lehner_eigenvalue`)
2819
+
2820
+ OUTPUT:
2821
+
2822
+ The Atkin-Lehner eigenvalue of `W_d` on ``self``. If ``self`` is not an
2823
+ eigenform for `W_d`, a :exc:`ValueError` is raised.
2824
+
2825
+ .. SEEALSO::
2826
+
2827
+ For the conventions used to define the operator `W_d`, see
2828
+ :meth:`sage.modular.hecke.module.HeckeModule_free_module.atkin_lehner_operator`.
2829
+
2830
+ EXAMPLES::
2831
+
2832
+ sage: CuspForms(1, 30).0.atkin_lehner_eigenvalue()
2833
+ 1
2834
+ sage: CuspForms(2, 8).0.atkin_lehner_eigenvalue()
2835
+ Traceback (most recent call last):
2836
+ ...
2837
+ NotImplementedError: don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead)
2838
+ """
2839
+ if d is None:
2840
+ d = self.level()
2841
+ try:
2842
+ f = self.parent().atkin_lehner_operator(d)(self)
2843
+ except NotImplementedError:
2844
+ raise NotImplementedError("don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead)")
2845
+ w = self.element().nonzero_positions()[0]
2846
+ t = f.element()[w] / self.element()[w]
2847
+ if f.element() == self.element() * t:
2848
+ return t
2849
+ else:
2850
+ raise ValueError("%r is not an eigenform for W_%r" % (self, d))
2851
+
2852
+ def twist(self, chi, level=None):
2853
+ r"""
2854
+ Return the twist of the modular form ``self`` by the Dirichlet
2855
+ character ``chi``.
2856
+
2857
+ If ``self`` is a modular form `f` with character `\epsilon`
2858
+ and `q`-expansion
2859
+
2860
+ .. MATH::
2861
+
2862
+ f(q) = \sum_{n=0}^\infty a_n q^n,
2863
+
2864
+ then the twist by `\chi` is a modular form `f_\chi` with
2865
+ character `\epsilon\chi^2` and `q`-expansion
2866
+
2867
+ .. MATH::
2868
+
2869
+ f_\chi(q) = \sum_{n=0}^\infty \chi(n) a_n q^n.
2870
+
2871
+ INPUT:
2872
+
2873
+ - ``chi`` -- a Dirichlet character
2874
+
2875
+ - ``level`` -- (optional) the level `N` of the twisted form.
2876
+ By default, the algorithm chooses some not necessarily
2877
+ minimal value for `N` using [AL1978]_, Proposition 3.1,
2878
+ (See also [Kob1993]_, Proposition III.3.17, for a simpler
2879
+ but slightly weaker bound.)
2880
+
2881
+ OUTPUT:
2882
+
2883
+ The form `f_\chi` as an element of the space of modular forms
2884
+ for `\Gamma_1(N)` with character `\epsilon\chi^2`.
2885
+
2886
+ EXAMPLES::
2887
+
2888
+ sage: f = CuspForms(11, 2).0
2889
+ sage: f.parent()
2890
+ Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
2891
+ sage: f.q_expansion(6)
2892
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
2893
+ sage: eps = DirichletGroup(3).0
2894
+ sage: eps.parent()
2895
+ Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 2 and degree 1
2896
+ sage: f_eps = f.twist(eps)
2897
+ sage: f_eps.parent()
2898
+ Cuspidal subspace of dimension 9 of Modular Forms space of dimension 16 for Congruence Subgroup Gamma0(99) of weight 2 over Cyclotomic Field of order 2 and degree 1
2899
+ sage: f_eps.q_expansion(6)
2900
+ q + 2*q^2 + 2*q^4 - q^5 + O(q^6)
2901
+
2902
+ Modular forms without character are supported::
2903
+
2904
+ sage: M = ModularForms(Gamma1(5), 2)
2905
+ sage: f = M.gen(0); f
2906
+ 1 + 60*q^3 - 120*q^4 + 240*q^5 + O(q^6)
2907
+ sage: chi = DirichletGroup(2)[0]
2908
+ sage: f.twist(chi)
2909
+ 60*q^3 + 240*q^5 + O(q^6)
2910
+
2911
+ The base field of the twisted form is extended if necessary::
2912
+
2913
+ sage: E4 = ModularForms(1, 4).gen(0)
2914
+ sage: E4.parent()
2915
+ Modular Forms space of dimension 1 for Modular Group SL(2,Z) of weight 4 over Rational Field
2916
+ sage: chi = DirichletGroup(5)[1]
2917
+ sage: chi.base_ring()
2918
+ Cyclotomic Field of order 4 and degree 2
2919
+ sage: E4_chi = E4.twist(chi)
2920
+ sage: E4_chi.parent()
2921
+ Modular Forms space of dimension 10, character [-1] and weight 4 over Cyclotomic Field of order 4 and degree 2
2922
+
2923
+ REFERENCES:
2924
+
2925
+ - [AL1978]_
2926
+
2927
+ - [Kob1993]_
2928
+
2929
+ AUTHORS:
2930
+
2931
+ - \L. J. P. Kilford (2009-08-28)
2932
+
2933
+ - Peter Bruin (2015-03-30)
2934
+ """
2935
+ from sage.modular.all import CuspForms, ModularForms
2936
+ R = coercion_model.common_parent(self.base_ring(), chi.base_ring())
2937
+ N = self.level()
2938
+ Q = chi.modulus()
2939
+ try:
2940
+ epsilon = self.character()
2941
+ except ValueError:
2942
+ epsilon = None
2943
+ constructor = CuspForms if self.is_cuspidal() else ModularForms
2944
+ if epsilon is not None:
2945
+ if level is None:
2946
+ # See [AL1978], Proposition 3.1.
2947
+ level = lcm([N, epsilon.conductor() * Q, Q**2])
2948
+ G = DirichletGroup(level, base_ring=R)
2949
+ M = constructor(G(epsilon) * G(chi)**2, self.weight(), base_ring=R)
2950
+ else:
2951
+ from sage.modular.arithgroup.all import Gamma1
2952
+ if level is None:
2953
+ # See [AL1978], Proposition 3.1.
2954
+ level = lcm([N, Q]) * Q
2955
+ M = constructor(Gamma1(level), self.weight(), base_ring=R)
2956
+ bound = M.sturm_bound() + 1
2957
+ S = PowerSeriesRing(R, 'q')
2958
+ f_twist = S([self[i] * chi(i) for i in range(bound)], prec=bound)
2959
+ return M(f_twist)
2960
+
2961
+
2962
+ class ModularFormElement_elliptic_curve(Newform):
2963
+ r"""
2964
+ A modular form attached to an elliptic curve over `\QQ`.
2965
+ """
2966
+ def __init__(self, parent, E):
2967
+ """
2968
+ Modular form attached to an elliptic curve as an element
2969
+ of a space of modular forms.
2970
+
2971
+ EXAMPLES::
2972
+
2973
+ sage: # needs database_cremona_mini_ellcurve
2974
+ sage: E = EllipticCurve('389a')
2975
+ sage: f = E.modular_form()
2976
+ sage: f
2977
+ q - 2*q^2 - 2*q^3 + 2*q^4 - 3*q^5 + O(q^6)
2978
+ sage: f.q_expansion(10)
2979
+ q - 2*q^2 - 2*q^3 + 2*q^4 - 3*q^5 + 4*q^6 - 5*q^7 + q^9 + O(q^10)
2980
+ sage: f.parent()
2981
+ Modular Forms space of dimension 33 for Congruence Subgroup Gamma0(389) of weight 2 over Rational Field
2982
+
2983
+ sage: # needs database_cremona_mini_ellcurve
2984
+ sage: E = EllipticCurve('37a')
2985
+ sage: f = E.modular_form(); f
2986
+ q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)
2987
+ sage: f == loads(dumps(f))
2988
+ True
2989
+ """
2990
+ Newform.__init__(self, parent, E.modular_symbol_space(), names=None)
2991
+ self.__E = E
2992
+
2993
+ def elliptic_curve(self):
2994
+ """
2995
+ Return elliptic curve associated to ``self``.
2996
+
2997
+ EXAMPLES::
2998
+
2999
+ sage: # needs database_cremona_mini_ellcurve
3000
+ sage: E = EllipticCurve('11a')
3001
+ sage: f = E.modular_form()
3002
+ sage: f.elliptic_curve()
3003
+ Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
3004
+ sage: f.elliptic_curve() is E
3005
+ True
3006
+ """
3007
+ return self.__E
3008
+
3009
+ def _compute_element(self):
3010
+ """
3011
+ Compute ``self`` as a linear combination of the basis elements
3012
+ of parent.
3013
+
3014
+ EXAMPLES::
3015
+
3016
+ sage: # needs database_cremona_mini_ellcurve
3017
+ sage: EllipticCurve('11a1').modular_form()._compute_element()
3018
+ (1, 0)
3019
+ sage: EllipticCurve('389a1').modular_form()._compute_element()
3020
+ (1, -2, -2, 2, -3, 4, -5, 0, 1, 6, -4, -4, -3, 10, 6, -4, -6, -2, 5, -6, 10, 8, -4, 0, 4, 6, 4, -10, -6, -12, 4, 8, 0)
3021
+ """
3022
+ M = self.parent()
3023
+ S = M.cuspidal_subspace()
3024
+ # return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() )
3025
+ return vector(S.find_in_space(self.__E.q_expansion(S.sturm_bound())) + [0] * (M.dimension() - S.dimension()))
3026
+
3027
+ def _compute_q_expansion(self, prec):
3028
+ r"""
3029
+ The `q`-expansion of the modular form to precision `O(q^\text{prec})`.
3030
+
3031
+ This function takes one argument, which is the integer ``prec``.
3032
+
3033
+ EXAMPLES::
3034
+
3035
+ sage: # needs database_cremona_mini_ellcurve
3036
+ sage: E = EllipticCurve('11a'); f = E.modular_form()
3037
+ sage: f._compute_q_expansion(10)
3038
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)
3039
+ sage: f._compute_q_expansion(30)
3040
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 - 2*q^10 + q^11 - 2*q^12 + 4*q^13 + 4*q^14 - q^15 - 4*q^16 - 2*q^17 + 4*q^18 + 2*q^20 + 2*q^21 - 2*q^22 - q^23 - 4*q^25 - 8*q^26 + 5*q^27 - 4*q^28 + O(q^30)
3041
+ sage: f._compute_q_expansion(10)
3042
+ q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)
3043
+ """
3044
+ return self.__E.q_expansion(prec)
3045
+
3046
+ def atkin_lehner_eigenvalue(self, d=None, embedding=None):
3047
+ """
3048
+ Return the result of the Atkin-Lehner operator `W_d` on
3049
+ ``self``.
3050
+
3051
+ INPUT:
3052
+
3053
+ - ``d`` -- positive integer exactly dividing the level `N` of
3054
+ ``self``, i.e. `d` divides `N` and is coprime to `N/d`. (Defaults to
3055
+ `d = N` if not given.)
3056
+
3057
+ - ``embedding`` -- ignored (but accepted for compatibility with
3058
+ :meth:`Newform.atkin_lehner_action`)
3059
+
3060
+ OUTPUT:
3061
+
3062
+ The Atkin-Lehner eigenvalue of `W_d` on ``self``. This is either `1` or
3063
+ `-1`.
3064
+
3065
+ EXAMPLES::
3066
+
3067
+ sage: # needs database_cremona_mini_ellcurve
3068
+ sage: EllipticCurve('57a1').newform().atkin_lehner_eigenvalue()
3069
+ 1
3070
+ sage: EllipticCurve('57b1').newform().atkin_lehner_eigenvalue()
3071
+ -1
3072
+ sage: EllipticCurve('57b1').newform().atkin_lehner_eigenvalue(19)
3073
+ 1
3074
+ """
3075
+ if d == self.level():
3076
+ w = -self.__E.root_number()
3077
+ else:
3078
+ # The space of modular symbols attached to E is
3079
+ # one-dimensional.
3080
+ w = self.__E.modular_symbol_space().atkin_lehner_operator(d).matrix()[0, 0]
3081
+ return w
3082
+
3083
+
3084
+ class EisensteinSeries(ModularFormElement):
3085
+ """
3086
+ An Eisenstein series.
3087
+
3088
+ EXAMPLES::
3089
+
3090
+ sage: E = EisensteinForms(1,12)
3091
+ sage: E.eisenstein_series()
3092
+ [691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6)]
3093
+ sage: E = EisensteinForms(11,2)
3094
+ sage: E.eisenstein_series()
3095
+ [5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)]
3096
+ sage: E = EisensteinForms(Gamma1(7),2)
3097
+ sage: E.set_precision(4)
3098
+ sage: E.eisenstein_series()
3099
+ [1/4 + q + 3*q^2 + 4*q^3 + O(q^4),
3100
+ 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4),
3101
+ q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4),
3102
+ -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4),
3103
+ q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4)]
3104
+ """
3105
+ def __init__(self, parent, vector, t, chi, psi):
3106
+ """
3107
+ An Eisenstein series.
3108
+
3109
+ EXAMPLES::
3110
+
3111
+ sage: E = EisensteinForms(1,12) # indirect doctest
3112
+ sage: E.eisenstein_series()
3113
+ [691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6)]
3114
+ sage: E = EisensteinForms(11,2)
3115
+ sage: E.eisenstein_series()
3116
+ [5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)]
3117
+ sage: E = EisensteinForms(Gamma1(7),2)
3118
+ sage: E.set_precision(4)
3119
+ sage: E.eisenstein_series()
3120
+ [1/4 + q + 3*q^2 + 4*q^3 + O(q^4),
3121
+ 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4),
3122
+ q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4),
3123
+ -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4),
3124
+ q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4)]
3125
+ """
3126
+ N = parent.level()
3127
+ K = parent.base_ring()
3128
+ if chi.parent().modulus() != N or psi.parent().modulus() != N:
3129
+ raise ArithmeticError("Incompatible moduli")
3130
+ if chi.parent().base_ring() != K or psi.parent().base_ring() != K:
3131
+ raise ArithmeticError("Incompatible base rings")
3132
+ t = int(t)
3133
+ if parent.weight() == 2 and chi.is_trivial() and psi.is_trivial() and t == 1:
3134
+ raise ArithmeticError("If chi and psi are trivial and k=2, then t must be >1.")
3135
+ ModularFormElement.__init__(self, parent, vector)
3136
+ self.__chi = chi
3137
+ self.__psi = psi
3138
+ self.__t = t
3139
+
3140
+ def _compute_q_expansion(self, prec=None):
3141
+ """
3142
+ Compute the `q`-expansion of ``self`` to precision ``prec``.
3143
+
3144
+ EXAMPLES::
3145
+
3146
+ sage: EisensteinForms(11,2).eisenstein_series()[0]._compute_q_expansion(10)
3147
+ 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + 12*q^6 + 8*q^7 + 15*q^8 + 13*q^9 + O(q^10)
3148
+ """
3149
+ if prec is None:
3150
+ prec = self.parent().prec()
3151
+ F = self._compute(list(range(prec)))
3152
+ R = self.parent()._q_expansion_ring()
3153
+ return R(F, prec)
3154
+
3155
+ def _compute(self, X):
3156
+ r"""
3157
+ Compute the coefficients of `q^n` of the power series of self,
3158
+ for `n` in the list `X`. The results are not cached. (Use
3159
+ coefficients for cached results).
3160
+
3161
+ EXAMPLES::
3162
+
3163
+ sage: e = DirichletGroup(11).gen()
3164
+ sage: f = EisensteinForms(e, 3).eisenstein_series()[0]
3165
+ sage: f._compute([3,4,5])
3166
+ [-9*zeta10^3 + 1,
3167
+ 16*zeta10^2 + 4*zeta10 + 1,
3168
+ 25*zeta10^3 - 25*zeta10^2 + 25*zeta10 - 24]
3169
+ """
3170
+ if self.weight() == 2 and (self.__chi.is_trivial() and self.__psi.is_trivial()):
3171
+ return self.__compute_weight2_trivial_character(X)
3172
+ else: # general case
3173
+ return self.__compute_general_case(X)
3174
+
3175
+ def __compute_weight2_trivial_character(self, X):
3176
+ r"""
3177
+ Compute coefficients for ``self`` an Eisenstein series of the form
3178
+ `E_2 - t*E_2(q^t)`. Computes `a_n` for each `n \in X`.
3179
+
3180
+ EXAMPLES::
3181
+
3182
+ sage: EisensteinForms(14,2).eisenstein_series()[0]._EisensteinSeries__compute_weight2_trivial_character([0])
3183
+ [1/24]
3184
+ sage: EisensteinForms(14,2).eisenstein_series()[0]._EisensteinSeries__compute_weight2_trivial_character([0,4,11,38])
3185
+ [1/24, 1, 12, 20]
3186
+ """
3187
+ F = self.base_ring()
3188
+ v = []
3189
+ t = self.__t
3190
+ for n in X:
3191
+ if n < 0:
3192
+ pass
3193
+ elif n == 0:
3194
+ v.append(F(t - 1) / F(24))
3195
+ else:
3196
+ an = sigma(n, 1)
3197
+ if n % t == 0:
3198
+ an -= t * sigma(n // t, 1)
3199
+ v.append(an)
3200
+ return v
3201
+
3202
+ def __compute_general_case(self, X):
3203
+ r"""
3204
+ Return the list coefficients of `q^n` of the power series of self,
3205
+ for `n` in the list `X`. The results are not cached. (Use
3206
+ coefficients for cached results).
3207
+
3208
+ General case (except weight 2, trivial character, where this
3209
+ is wrong!) `\chi` is a primitive character of conductor `L`
3210
+ `\psi` is a primitive character of conductor `M` We have
3211
+ `MLt \mid N`, and
3212
+
3213
+ .. MATH::
3214
+
3215
+ E_k(chi,psi,t) =
3216
+ c_0 + sum_{m \geq 1}[sum_{n|m} psi(n) * chi(m/n) * n^(k-1)] q^{mt},
3217
+
3218
+ with `c_0=0` if `L>1`, and `c_0=L(1-k,psi)/2` if `L=1` (that
3219
+ second `L` is an `L`-function `L`).
3220
+
3221
+ EXAMPLES::
3222
+
3223
+ sage: e = DirichletGroup(11).gen()
3224
+ sage: f = EisensteinForms(e, 3).eisenstein_series()[0]
3225
+ sage: f._EisensteinSeries__compute_general_case([1])
3226
+ [1]
3227
+ sage: f._EisensteinSeries__compute_general_case([2])
3228
+ [4*zeta10 + 1]
3229
+ sage: f._EisensteinSeries__compute_general_case([0,1,2])
3230
+ [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11, 1, 4*zeta10 + 1]
3231
+ """
3232
+ c0, chi, psi, K, n, t, L, M = self.__defining_parameters()
3233
+ zero = K.zero()
3234
+ k = self.weight()
3235
+ v = []
3236
+ for i in X:
3237
+ if i == 0:
3238
+ v.append(c0)
3239
+ continue
3240
+ if i % t != 0:
3241
+ v.append(zero)
3242
+ else:
3243
+ m = i // t
3244
+ v.append(sum([psi(d) * chi(m / d) * d ** (k - 1)
3245
+ for d in divisors(m)]))
3246
+ return v
3247
+
3248
+ @cached_method
3249
+ def __defining_parameters(self):
3250
+ r"""
3251
+ Return defining parameters for ``self``.
3252
+
3253
+ EXAMPLES::
3254
+
3255
+ sage: EisensteinForms(11,2).eisenstein_series()[0]._EisensteinSeries__defining_parameters()
3256
+ (-1/24, Dirichlet character modulo 1 of conductor 1, Dirichlet character modulo 1 of conductor 1, Rational Field, 2, 11, 1, 1)
3257
+ """
3258
+ chi = self.__chi.primitive_character()
3259
+ psi = self.__psi.primitive_character()
3260
+ k = self.weight()
3261
+ t = self.__t
3262
+ L = chi.conductor()
3263
+ M = psi.conductor()
3264
+ K = chi.base_ring()
3265
+ n = K.zeta_order()
3266
+ if L == 1:
3267
+ c0 = K(-psi.bernoulli(k)) / K(2 * k)
3268
+ else:
3269
+ c0 = K.zero()
3270
+ return (c0, chi, psi, K, n, t, L, M)
3271
+
3272
+ def chi(self):
3273
+ """
3274
+ Return the parameter chi associated to ``self``.
3275
+
3276
+ EXAMPLES::
3277
+
3278
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].chi()
3279
+ Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta16
3280
+ """
3281
+ return self.__chi
3282
+
3283
+ def psi(self):
3284
+ """
3285
+ Return the parameter psi associated to ``self``.
3286
+
3287
+ EXAMPLES::
3288
+
3289
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].psi()
3290
+ Dirichlet character modulo 17 of conductor 1 mapping 3 |--> 1
3291
+ """
3292
+ return self.__psi
3293
+
3294
+ def t(self):
3295
+ """
3296
+ Return the parameter t associated to ``self``.
3297
+
3298
+ EXAMPLES::
3299
+
3300
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].t()
3301
+ 1
3302
+ """
3303
+ return self.__t
3304
+
3305
+ def parameters(self):
3306
+ """
3307
+ Return chi, psi, and t, which are the defining parameters of ``self``.
3308
+
3309
+ EXAMPLES::
3310
+
3311
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].parameters()
3312
+ (Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta16, Dirichlet character modulo 17 of conductor 1 mapping 3 |--> 1, 1)
3313
+ """
3314
+ return self.__chi, self.__psi, self.__t
3315
+
3316
+ def L(self):
3317
+ """
3318
+ Return the conductor of self.chi().
3319
+
3320
+ EXAMPLES::
3321
+
3322
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].L()
3323
+ 17
3324
+ """
3325
+ return self.__chi.conductor()
3326
+
3327
+ def M(self):
3328
+ """
3329
+ Return the conductor of self.psi().
3330
+
3331
+ EXAMPLES::
3332
+
3333
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].M()
3334
+ 1
3335
+ """
3336
+ return self.__psi.conductor()
3337
+
3338
+ @cached_method
3339
+ def character(self):
3340
+ """
3341
+ Return the character associated to ``self``.
3342
+
3343
+ EXAMPLES::
3344
+
3345
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].character()
3346
+ Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta16
3347
+
3348
+ sage: chi = DirichletGroup(7)[4]
3349
+ sage: E = EisensteinForms(chi).eisenstein_series() ; E
3350
+ [-1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 4)*q^5 + O(q^6),
3351
+ q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + (zeta6 + 2)*q^4 + (zeta6 + 4)*q^5 + O(q^6)]
3352
+ sage: E[0].character() == chi
3353
+ True
3354
+ sage: E[1].character() == chi
3355
+ True
3356
+
3357
+ TESTS::
3358
+
3359
+ sage: [ [ f.character() == chi for f in EisensteinForms(chi).eisenstein_series() ] for chi in DirichletGroup(17) ]
3360
+ [[True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], []]
3361
+
3362
+ sage: [ [ f.character() == chi for f in EisensteinForms(chi).eisenstein_series() ] for chi in DirichletGroup(16) ]
3363
+ [[True, True, True, True, True], [], [True, True], [], [True, True, True, True], [], [True, True], []]
3364
+ """
3365
+ return self.__chi * self.__psi
3366
+
3367
+ def new_level(self):
3368
+ """
3369
+ Return level at which ``self`` is new.
3370
+
3371
+ EXAMPLES::
3372
+
3373
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].level()
3374
+ 17
3375
+ sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].new_level()
3376
+ 17
3377
+ sage: [ [x.level(), x.new_level()] for x in EisensteinForms(DirichletGroup(60).0^2,2).eisenstein_series() ]
3378
+ [[60, 2], [60, 3], [60, 2], [60, 5], [60, 2], [60, 2], [60, 2], [60, 3], [60, 2], [60, 2], [60, 2]]
3379
+ """
3380
+ if self.__chi.is_trivial() and self.__psi.is_trivial() and self.weight() == 2:
3381
+ return factor(self.__t)[0][0]
3382
+ return self.L() * self.M()
3383
+
3384
+
3385
+ class GradedModularFormElement(ModuleElement):
3386
+ r"""
3387
+ The element class for ``ModularFormsRing``. A ``GradedModularFormElement`` is basically a
3388
+ formal sum of modular forms of different weight: `f_1 + f_2 + ... + f_n`. Note that a
3389
+ ``GradedModularFormElement`` is not necessarily a modular form (as it can have mixed weight
3390
+ components).
3391
+
3392
+ A ``GradedModularFormElement`` should not be constructed directly via this class. Instead,
3393
+ one should use the element constructor of the parent class (``ModularFormsRing``).
3394
+
3395
+ EXAMPLES::
3396
+
3397
+ sage: M = ModularFormsRing(1)
3398
+ sage: D = CuspForms(1, 12).0
3399
+ sage: M(D).parent()
3400
+ Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
3401
+
3402
+ A graded modular form can be initiated via a dictionary or a list::
3403
+
3404
+ sage: E4 = ModularForms(1, 4).0
3405
+ sage: M({4:E4, 12:D}) # dictionary
3406
+ 1 + 241*q + 2136*q^2 + 6972*q^3 + 16048*q^4 + 35070*q^5 + O(q^6)
3407
+ sage: M([E4, D]) # list
3408
+ 1 + 241*q + 2136*q^2 + 6972*q^3 + 16048*q^4 + 35070*q^5 + O(q^6)
3409
+
3410
+ Also, when adding two modular forms of different weights, a graded modular form element will be created::
3411
+
3412
+ sage: (E4 + D).parent()
3413
+ Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
3414
+ sage: M([E4, D]) == E4 + D
3415
+ True
3416
+
3417
+ Graded modular forms elements for congruence subgroups are also supported::
3418
+
3419
+ sage: M = ModularFormsRing(Gamma0(3))
3420
+ sage: f = ModularForms(Gamma0(3), 4).0
3421
+ sage: g = ModularForms(Gamma0(3), 2).0
3422
+ sage: M([f, g])
3423
+ 2 + 12*q + 36*q^2 + 252*q^3 + 84*q^4 + 72*q^5 + O(q^6)
3424
+ sage: M({4:f, 2:g})
3425
+ 2 + 12*q + 36*q^2 + 252*q^3 + 84*q^4 + 72*q^5 + O(q^6)
3426
+ """
3427
+ def __init__(self, parent, forms_datum):
3428
+ r"""
3429
+ INPUT:
3430
+
3431
+ - ``parent`` -- an object of the class ``ModularFormsRing``
3432
+ - ``forms_datum`` -- dictionary ``{k_1:f_1, k_2:f_2, ..., k_n:f_n}``
3433
+ or a list ``[f_1, f_2,..., f_n]`` where `f_i` is a modular form of
3434
+ weight `k_i`
3435
+
3436
+ OUTPUT: a ``GradedModularFormElement`` corresponding to `f_1 + f_2 + ... + f_n`
3437
+
3438
+ TESTS::
3439
+
3440
+ sage: M = ModularFormsRing(1)
3441
+ sage: E4 = ModularForms(1,4).0
3442
+ sage: M({6:E4})
3443
+ Traceback (most recent call last):
3444
+ ...
3445
+ ValueError: at least one key (6) of the defining dictionary does not correspond to the weight of its value (1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)). Real weight: 4
3446
+ sage: M({4:'f'})
3447
+ Traceback (most recent call last):
3448
+ ...
3449
+ ValueError: at least one value (f) of the defining dictionary is not a `ModularFormElement`
3450
+ sage: M({4.:E4})
3451
+ Traceback (most recent call last):
3452
+ ...
3453
+ ValueError: at least one key (4.00000000000000) of the defining dictionary is not an integer
3454
+ sage: M({0:E4})
3455
+ Traceback (most recent call last):
3456
+ ...
3457
+ TypeError: no canonical coercion from Modular Forms space of dimension 1 for Modular Group SL(2,Z) of weight 4 over Rational Field to Rational Field
3458
+ sage: M([E4, x]) # needs sage.symbolic
3459
+ Traceback (most recent call last):
3460
+ ...
3461
+ TypeError: no canonical coercion from Symbolic Ring to Rational Field
3462
+ sage: M([E4, ModularForms(3, 6).0])
3463
+ Traceback (most recent call last):
3464
+ ...
3465
+ ValueError: the group and/or the base ring of at least one modular form (q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)) is not consistent with the base space
3466
+ sage: M({4:E4, 6:ModularForms(3, 6).0})
3467
+ Traceback (most recent call last):
3468
+ ...
3469
+ ValueError: the group and/or the base ring of at least one modular form (q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)) is not consistent with the base space
3470
+ sage: M = ModularFormsRing(Gamma0(2))
3471
+ sage: E4 = ModularForms(1, 4).0
3472
+ sage: M(E4)[4].parent()
3473
+ Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(2) of weight 4 over Rational Field
3474
+ sage: M = ModularFormsRing(Gamma1(3), base_ring=GF(7))
3475
+ sage: E6 = ModularForms(1, 6, base_ring=GF(7)).0
3476
+ sage: M(E6)[6].parent()
3477
+ Modular Forms space of dimension 3 for Congruence Subgroup Gamma1(3) of weight 6 over Finite Field of size 7
3478
+ """
3479
+ forms_dictionary = {}
3480
+ if isinstance(forms_datum, dict):
3481
+ for k, f in forms_datum.items():
3482
+ if isinstance(k, (int, Integer)):
3483
+ k = ZZ(k)
3484
+ if k == 0:
3485
+ forms_dictionary[k] = parent.base_ring().coerce(f)
3486
+ elif isinstance(f, ModularFormElement):
3487
+ if f.weight() == k:
3488
+ if parent.group().is_subgroup(f.group()) and parent.base_ring().has_coerce_map_from(f.base_ring()):
3489
+ M = parent.modular_forms_of_weight(f.weight()).change_ring(parent.base_ring())
3490
+ forms_dictionary[k] = M(f)
3491
+ else:
3492
+ raise ValueError('the group and/or the base ring of at least one modular form (%s) is not consistent with the base space' % (f))
3493
+ else:
3494
+ raise ValueError('at least one key (%s) of the defining dictionary does not correspond to the weight of its value (%s). Real weight: %s' % (k, f, f.weight()))
3495
+ else:
3496
+ raise ValueError('at least one value (%s) of the defining dictionary is not a `ModularFormElement`' % (f))
3497
+ else:
3498
+ raise ValueError('at least one key (%s) of the defining dictionary is not an integer' % (k))
3499
+ elif isinstance(forms_datum, list):
3500
+ for f in forms_datum:
3501
+ if isinstance(f, ModularFormElement):
3502
+ chi = f.character(compute=False)
3503
+ if (chi is not None) and (not chi.is_trivial()):
3504
+ raise NotImplementedError("graded modular forms for non-trivial characters is not yet implemented")
3505
+ if parent.group().is_subgroup(f.group()) and parent.base_ring().has_coerce_map_from(f.base_ring()):
3506
+ M = parent.modular_forms_of_weight(f.weight()).change_ring(parent.base_ring())
3507
+ forms_dictionary[f.weight()] = M(forms_dictionary.get(f.weight(), 0) + f)
3508
+ else:
3509
+ raise ValueError('the group and/or the base ring of at least one modular form (%s) is not consistent with the base space' % (f))
3510
+ else:
3511
+ forms_dictionary[ZZ.zero()] = parent.base_ring().coerce(f)
3512
+ else:
3513
+ raise TypeError('the defining data structure should be a list or a dictionary')
3514
+ self._forms_dictionary = {k: f for k, f in forms_dictionary.items() if not f.is_zero()} # remove the zero values
3515
+ Element.__init__(self, parent)
3516
+
3517
+ def __bool__(self) -> bool:
3518
+ r"""
3519
+ Return "True" if ``self`` is nonzero and "False" otherwise.
3520
+
3521
+ EXAMPLES::
3522
+
3523
+ sage: M = ModularFormsRing(1)
3524
+ sage: bool(M(0))
3525
+ False
3526
+ sage: bool(M(1))
3527
+ True
3528
+ sage: bool(M(ModularForms(1,6).0))
3529
+ True
3530
+ """
3531
+ return bool(self._forms_dictionary)
3532
+
3533
+ def is_zero(self) -> bool:
3534
+ r"""
3535
+ Return "True" if the graded form is 0 and "False" otherwise.
3536
+
3537
+ EXAMPLES::
3538
+
3539
+ sage: M = ModularFormsRing(1)
3540
+ sage: M(0).is_zero()
3541
+ True
3542
+ sage: M(1/2).is_zero()
3543
+ False
3544
+ sage: E6 = M.1
3545
+ sage: M(E6).is_zero()
3546
+ False
3547
+ """
3548
+ return not self
3549
+
3550
+ def is_one(self) -> bool:
3551
+ r"""
3552
+ Return "True" if the graded form is 1 and "False" otherwise.
3553
+
3554
+ EXAMPLES::
3555
+
3556
+ sage: M = ModularFormsRing(1)
3557
+ sage: M(1).is_one()
3558
+ True
3559
+ sage: M(2).is_one()
3560
+ False
3561
+ sage: E6 = M.0
3562
+ sage: E6.is_one()
3563
+ False
3564
+ """
3565
+ return len(self._forms_dictionary) == 1 and self[0].is_one()
3566
+
3567
+ def group(self):
3568
+ r"""
3569
+ Return the group for which ``self`` is a modular form.
3570
+
3571
+ EXAMPLES::
3572
+
3573
+ sage: M = ModularFormsRing(1)
3574
+ sage: E4 = M.0
3575
+ sage: E4.group()
3576
+ Modular Group SL(2,Z)
3577
+ sage: M5 = ModularFormsRing(Gamma1(5))
3578
+ sage: f = M5(ModularForms(Gamma1(5)).0);
3579
+ sage: f.group()
3580
+ Congruence Subgroup Gamma1(5)
3581
+ """
3582
+ return self.parent().group()
3583
+
3584
+ def q_expansion(self, prec=None):
3585
+ r"""
3586
+ Return the `q`-expansion of the graded modular form up to precision
3587
+ ``prec`` (default: 6).
3588
+
3589
+ An alias of this method is ``qexp``.
3590
+
3591
+ EXAMPLES::
3592
+
3593
+ sage: M = ModularFormsRing(1)
3594
+ sage: zer = M(0); zer.q_expansion()
3595
+ 0
3596
+ sage: M(5/7).q_expansion()
3597
+ 5/7
3598
+ sage: E4 = M.0; E4
3599
+ 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
3600
+ sage: E6 = M.1; E6
3601
+ 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)
3602
+ sage: F = E4 + E6; F
3603
+ 2 - 264*q - 14472*q^2 - 116256*q^3 - 515208*q^4 - 1545264*q^5 + O(q^6)
3604
+ sage: F.q_expansion()
3605
+ 2 - 264*q - 14472*q^2 - 116256*q^3 - 515208*q^4 - 1545264*q^5 + O(q^6)
3606
+ sage: F.q_expansion(10)
3607
+ 2 - 264*q - 14472*q^2 - 116256*q^3 - 515208*q^4 - 1545264*q^5 - 3997728*q^6 - 8388672*q^7 - 16907400*q^8 - 29701992*q^9 + O(q^10)
3608
+ """
3609
+ # We sum the two cases: (weight 0) + (weights k \neq 0)
3610
+ Pow = PowerSeriesRing(self.base_ring(), name=defaults.DEFAULT_VARIABLE)
3611
+ return Pow(self._forms_dictionary.get(0, Pow.zero())) + sum(f.q_expansion(prec) for k, f in self._forms_dictionary.items() if k != 0)
3612
+
3613
+ qexp = q_expansion # alias
3614
+
3615
+ def coefficients(self, X):
3616
+ r"""
3617
+ Return the coefficients `a_n` of the `q`-expansion of this modular form.
3618
+
3619
+ INPUT:
3620
+
3621
+ - ``X`` -- an iterable or an integer. If ``X`` is iterable, a list
3622
+ containing all `a_{X_i}` is returned. If ``X`` is an integer, it must
3623
+ be positive, in which case the coefficients `a_1` to `a_X` are
3624
+ returned in a list.
3625
+
3626
+ EXAMPLES::
3627
+
3628
+ sage: M = ModularFormsRing(1)
3629
+ sage: E4 = M.0; E6 = M.1
3630
+ sage: F = E4 + E6
3631
+ sage: F.coefficients([0,1,3,6])
3632
+ [2, -264, -116256, -3997728]
3633
+ sage: F.coefficients(10)
3634
+ [-264, -14472, -116256, -515208, -1545264, -3997728, -8388672, -16907400, -29701992, -51719472]
3635
+ sage: assert _ == F.coefficients(range(1, 11)) == list(F.qexp(11))[1:]
3636
+
3637
+ ::
3638
+
3639
+ sage: F = ModularFormsRing(13).0
3640
+ sage: (F^3).coefficients(range(10, 20))
3641
+ [22812, 36552, 57680, 85686, 126744, 177408, 249246, 332172, 448926, 575736]
3642
+ """
3643
+ if isinstance(X, (int, Integer)):
3644
+ return list(self.q_expansion(X + 1))[1:X + 1]
3645
+ prec = max(X)
3646
+ v = self.q_expansion(prec + 1)
3647
+ return [v[x] for x in X]
3648
+
3649
+ def _repr_(self):
3650
+ r"""
3651
+ The string representation of ``self``.
3652
+
3653
+ EXAMPLES::
3654
+
3655
+ sage: M = ModularFormsRing(Gamma0(7))
3656
+ sage: m = ModularForms(Gamma0(7), 14)
3657
+ sage: f = m.8
3658
+ sage: F = M(f)
3659
+ sage: F # indirect doctest
3660
+ q + 8193*q^2 + 1594324*q^3 + 67117057*q^4 + 1220703126*q^5 + O(q^6)
3661
+ """
3662
+ return str(self.q_expansion())
3663
+
3664
+ def _latex_(self):
3665
+ r"""
3666
+ Return a latex representation of ``self``.
3667
+
3668
+ TESTS::
3669
+
3670
+ sage: M = ModularFormsRing(1)
3671
+ sage: latex(M.0)
3672
+ 1 + 240 q + 2160 q^{2} + 6720 q^{3} + 17520 q^{4} + 30240 q^{5} + O(q^{6})
3673
+ """
3674
+ return self.q_expansion()._latex_()
3675
+
3676
+ def __getitem__(self, weight):
3677
+ r"""
3678
+ Return the homogeneous component of the given graded modular form.
3679
+
3680
+ INPUT:
3681
+
3682
+ - ``weight`` -- integer corresponding to the weight of the
3683
+ homogeneous component of the given graded modular form
3684
+
3685
+ EXAMPLES::
3686
+
3687
+ sage: M = ModularFormsRing(1)
3688
+ sage: f4 = ModularForms(1, 4).0; f6 = ModularForms(1, 6).0; f8 = ModularForms(1, 8).0
3689
+ sage: F = M(f4) + M(f6) + M(f8)
3690
+ sage: F[4] # indirect doctest
3691
+ 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
3692
+ sage: F[6] # indirect doctest
3693
+ 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)
3694
+ sage: F[8] # indirect doctest
3695
+ 1 + 480*q + 61920*q^2 + 1050240*q^3 + 7926240*q^4 + 37500480*q^5 + O(q^6)
3696
+ sage: F[10] # indirect doctest
3697
+ 0
3698
+ sage: F.homogeneous_component(4)
3699
+ 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
3700
+
3701
+ TESTS::
3702
+
3703
+ sage: M = ModularFormsRing(1)
3704
+ sage: f = M.0
3705
+ sage: f['a']
3706
+ Traceback (most recent call last):
3707
+ ...
3708
+ KeyError: 'the weight must be an integer'
3709
+ sage: f[-1]
3710
+ Traceback (most recent call last):
3711
+ ...
3712
+ ValueError: the weight must be nonnegative
3713
+ """
3714
+ if not isinstance(weight, (int, Integer)):
3715
+ raise KeyError("the weight must be an integer")
3716
+ if weight < 0:
3717
+ raise ValueError("the weight must be nonnegative")
3718
+ return self._forms_dictionary.get(weight, self.parent().zero())
3719
+ homogeneous_component = __getitem__ # alias
3720
+
3721
+ def __call__(self, x, prec=None):
3722
+ r"""
3723
+ Evaluate the `q`-expansion of this graded modular form at x.
3724
+
3725
+ EXAMPLES::
3726
+
3727
+ sage: M = ModularFormsRing(1)
3728
+ sage: f4 = ModularForms(1, 4).0; f6 = ModularForms(1, 6).0; f8 = ModularForms(1, 8).0
3729
+ sage: F = M(f4) + M(f6) + M(f8); F # indirect doctest
3730
+ 3 + 216*q + 47448*q^2 + 933984*q^3 + 7411032*q^4 + 35955216*q^5 + O(q^6)
3731
+ sage: q = F.q_expansion().parent().gen()
3732
+ sage: F(q^2) # indirect doctest
3733
+ 3 + 216*q^2 + 47448*q^4 + 933984*q^6 + 7411032*q^8 + 35955216*q^10 + O(q^12)
3734
+ sage: G = M(113/19)
3735
+ sage: G(q) # indirect doctest
3736
+ 113/19
3737
+ """
3738
+ return self.q_expansion(prec)(x)
3739
+
3740
+ def _add_(self, other):
3741
+ r"""
3742
+ Addition of two ``GradedModularFormElement``.
3743
+
3744
+ TESTS::
3745
+
3746
+ sage: M = ModularFormsRing(1)
3747
+ sage: f4 = ModularForms(1, 4).0; f6 = ModularForms(1, 6).0; f8 = ModularForms(1, 8).0
3748
+ sage: F4 = M(f4); F6 = M(f6); F8 = M(f8)
3749
+ sage: F4 + F6 # indirect doctest
3750
+ 2 - 264*q - 14472*q^2 - 116256*q^3 - 515208*q^4 - 1545264*q^5 + O(q^6)
3751
+ sage: F4 + f6 #coercion # indirect doctest
3752
+ 2 - 264*q - 14472*q^2 - 116256*q^3 - 515208*q^4 - 1545264*q^5 + O(q^6)
3753
+ sage: F = F4 + F6 + F8; F # indirect doctest
3754
+ 3 + 216*q + 47448*q^2 + 933984*q^3 + 7411032*q^4 + 35955216*q^5 + O(q^6)
3755
+ sage: F.parent()
3756
+ Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
3757
+ sage: g = ModularForms(Gamma1(7), 12).0
3758
+ sage: F+g #sum of two forms of different type
3759
+ Traceback (most recent call last):
3760
+ ...
3761
+ TypeError: unsupported operand parent(s) for +: 'Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field' and 'Modular Forms space of dimension 25 for Congruence Subgroup Gamma1(7) of weight 12 over Rational Field'
3762
+ """
3763
+ GM = self.__class__
3764
+ f_self = self._forms_dictionary
3765
+ f_other = other._forms_dictionary
3766
+ f_sum = {k: f_self.get(k, 0) + f_other.get(k, 0) for k in set(f_self) | set(f_other)}
3767
+ return GM(self.parent(), f_sum)
3768
+
3769
+ def __neg__(self):
3770
+ r"""
3771
+ The negation of ``self``.
3772
+
3773
+ TESTS::
3774
+
3775
+ sage: M = ModularFormsRing(1)
3776
+ sage: F4 = M(ModularForms(1, 4).0); F6 = M(ModularForms(1, 6).0);
3777
+ sage: -F4 # indirect doctest
3778
+ -1 - 240*q - 2160*q^2 - 6720*q^3 - 17520*q^4 - 30240*q^5 + O(q^6)
3779
+ sage: F4 - F6 # indirect doctest
3780
+ 744*q + 18792*q^2 + 129696*q^3 + 550248*q^4 + 1605744*q^5 + O(q^6)
3781
+ """
3782
+ GM = self.__class__
3783
+ f_self = self._forms_dictionary
3784
+ minus_self = {k: -f for k, f in f_self.items()}
3785
+ return GM(self.parent(), minus_self)
3786
+
3787
+ def _mul_(self, other):
3788
+ r"""
3789
+ Multiplication of two ``GradedModularFormElement``.
3790
+
3791
+ INPUT:
3792
+
3793
+ - ``other`` -- a ``GradedModularFormElement``
3794
+
3795
+ OUTPUT: the ``GradedModularFormElement`` corresponding to the
3796
+ multiplication of ``self`` and ``other``.
3797
+
3798
+ TESTS::
3799
+
3800
+ sage: M = ModularFormsRing(1)
3801
+ sage: F4 = M.0; F6 = M.1;
3802
+ sage: F4*F6 # indirect doctest
3803
+ 1 - 264*q - 135432*q^2 - 5196576*q^3 - 69341448*q^4 - 515625264*q^5 + O(q^6)
3804
+
3805
+ sage: E4 = EisensteinForms(1, 4).0
3806
+ sage: E4^2
3807
+ 1 + 480*q + 61920*q^2 + 1050240*q^3 + 7926240*q^4 + 37500480*q^5 + O(q^6)
3808
+
3809
+ This shows that the issue at :issue:`35932` is fixed::
3810
+
3811
+ sage: (F4 + M(1))^2
3812
+ 4 + 960*q + 66240*q^2 + 1063680*q^3 + 7961280*q^4 + 37560960*q^5 + O(q^6)
3813
+ """
3814
+ from collections import defaultdict
3815
+
3816
+ GM = self.__class__
3817
+ f_self = self._forms_dictionary
3818
+ f_other = other._forms_dictionary
3819
+ f_mul = defaultdict(int)
3820
+
3821
+ for k_self in f_self.keys():
3822
+ for k_other in f_other.keys():
3823
+ f_mul[k_self + k_other] += f_self[k_self] * f_other[k_other]
3824
+
3825
+ return GM(self.parent(), f_mul)
3826
+
3827
+ def _lmul_(self, c):
3828
+ r"""
3829
+ The left action of the base ring on ``self``.
3830
+
3831
+ INPUT:
3832
+
3833
+ - ``c`` -- an element of the base ring of self
3834
+
3835
+ OUTPUT: a ``GradedModularFormElement``
3836
+
3837
+ TESTS::
3838
+
3839
+ sage: M = ModularFormsRing(1)
3840
+ sage: E4 = M(ModularForms(1, 4).0); E4
3841
+ 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)
3842
+ sage: 42 * E4 # indirect doctest
3843
+ 42 + 10080*q + 90720*q^2 + 282240*q^3 + 735840*q^4 + 1270080*q^5 + O(q^6)
3844
+ sage: 1/5 * E4 # indirect doctest
3845
+ 1/5 + 48*q + 432*q^2 + 1344*q^3 + 3504*q^4 + 6048*q^5 + O(q^6)
3846
+ sage: I*E4 # indirect doctest
3847
+ Traceback (most recent call last):
3848
+ ...
3849
+ TypeError: unsupported operand parent(s) for *: 'Number Field in I with defining polynomial x^2 + 1 with I = 1*I' and 'Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field'
3850
+ """
3851
+ GM = self.__class__
3852
+ f_self = self._forms_dictionary
3853
+ f_mul = {k: c * f for k, f in f_self.items()}
3854
+ return GM(self.parent(), f_mul)
3855
+
3856
+ def _richcmp_(self, other, op):
3857
+ r"""
3858
+ Compare ``self`` with ``other``.
3859
+
3860
+ TESTS::
3861
+
3862
+ sage: M = ModularFormsRing(1)
3863
+ sage: M(1) == M(1)
3864
+ True
3865
+ sage: M(1) == M(2)
3866
+ False
3867
+ sage: E4 = M.0
3868
+ sage: E4 == E4
3869
+ True
3870
+ sage: E6 = M.1
3871
+ sage: E4 == E6
3872
+ False
3873
+ sage: E4 != E6
3874
+ True
3875
+ sage: E4 < E6
3876
+ Traceback (most recent call last):
3877
+ ...
3878
+ TypeError: invalid comparison between modular forms ring elements
3879
+ sage: E4 > 6
3880
+ Traceback (most recent call last):
3881
+ ...
3882
+ TypeError: invalid comparison between modular forms ring elements
3883
+ sage: E4 <= E6
3884
+ Traceback (most recent call last):
3885
+ ...
3886
+ TypeError: invalid comparison between modular forms ring elements
3887
+ """
3888
+ if op != op_EQ and op != op_NE:
3889
+ raise TypeError('invalid comparison between modular forms ring elements')
3890
+ return richcmp(self._forms_dictionary, other._forms_dictionary, op)
3891
+
3892
+ def weight(self):
3893
+ r"""
3894
+ Return the weight of the given form if it is homogeneous (i.e. a modular form).
3895
+
3896
+ EXAMPLES::
3897
+
3898
+ sage: D = ModularForms(1,12).0; M = ModularFormsRing(1)
3899
+ sage: M(D).weight()
3900
+ 12
3901
+ sage: M.zero().weight()
3902
+ 0
3903
+ sage: e4 = ModularForms(1,4).0
3904
+ sage: (M(D)+e4).weight()
3905
+ Traceback (most recent call last):
3906
+ ...
3907
+ ValueError: the given graded form is not homogeneous (not a modular form)
3908
+ """
3909
+ if self.is_homogeneous():
3910
+ if self.is_zero():
3911
+ return ZZ.zero()
3912
+ return next(iter(self._forms_dictionary))
3913
+ else:
3914
+ raise ValueError("the given graded form is not homogeneous (not a modular form)")
3915
+
3916
+ def weights_list(self):
3917
+ r"""
3918
+ Return the list of the weights of all the homogeneous components of the
3919
+ given graded modular form.
3920
+
3921
+ EXAMPLES::
3922
+
3923
+ sage: M = ModularFormsRing(1)
3924
+ sage: f4 = ModularForms(1, 4).0; f6 = ModularForms(1, 6).0; f8 = ModularForms(1, 8).0
3925
+ sage: F4 = M(f4); F6 = M(f6); F8 = M(f8)
3926
+ sage: F = F4 + F6 + F8
3927
+ sage: F.weights_list()
3928
+ [4, 6, 8]
3929
+ sage: M(0).weights_list()
3930
+ [0]
3931
+ """
3932
+ if self.is_zero():
3933
+ return [ZZ.zero()]
3934
+ return sorted(self._forms_dictionary)
3935
+
3936
+ def is_homogeneous(self) -> bool:
3937
+ r"""
3938
+ Return ``True`` if the graded modular form is homogeneous, i.e. if it
3939
+ is a modular forms of a certain weight.
3940
+
3941
+ An alias of this method is ``is_modular_form``
3942
+
3943
+ EXAMPLES::
3944
+
3945
+ sage: M = ModularFormsRing(1)
3946
+ sage: E4 = M.0; E6 = M.1;
3947
+ sage: E4.is_homogeneous()
3948
+ True
3949
+ sage: F = E4 + E6 # Not a modular form
3950
+ sage: F.is_homogeneous()
3951
+ False
3952
+ """
3953
+ return len(self._forms_dictionary) <= 1
3954
+ is_modular_form = is_homogeneous # alias
3955
+
3956
+ def _homogeneous_to_polynomial(self, names, gens):
3957
+ r"""
3958
+ Return a polynomial `P(x_0,..., x_n)` corresponding to the given homogeneous graded form.
3959
+
3960
+ Each variable `x_i` of the returned polynomial correspond to a generator `g_i` of the
3961
+ list ``gens`` (following the order of the list)
3962
+
3963
+ INPUT:
3964
+
3965
+ - ``names`` -- list or tuple of names (strings), or a comma separated
3966
+ string
3967
+ - ``gens`` -- (list) a list of generator of ``self``
3968
+
3969
+ OUTPUT: a polynomial in the variables ``names``
3970
+
3971
+ TESTS::
3972
+
3973
+ sage: M = ModularFormsRing(1)
3974
+ sage: gens = M.gen_forms()
3975
+ sage: M.0._homogeneous_to_polynomial('x', gens)
3976
+ x0
3977
+ sage: M.1._homogeneous_to_polynomial('E4, E6', gens)
3978
+ E6
3979
+ sage: M(1/2).to_polynomial()
3980
+ 1/2
3981
+ sage: p = ((M.0)**3 + (M.1)**2)._homogeneous_to_polynomial('x', gens); p
3982
+ x0^3 + x1^2
3983
+ sage: M(p) == (M.0)**3 + (M.1)**2
3984
+ True
3985
+ sage: (M.0 + M.1)._homogeneous_to_polynomial('x', gens)
3986
+ Traceback (most recent call last):
3987
+ ...
3988
+ ValueError: the given graded form is not homogeneous (not a modular form)
3989
+ sage: E4 = ModularForms(1, 4, GF(7)).0
3990
+ sage: M = ModularFormsRing(1, GF(7))
3991
+ sage: M(E4).to_polynomial()
3992
+ Traceback (most recent call last):
3993
+ ...
3994
+ NotImplementedError: conversion to polynomial are not implemented if the base ring is not Q
3995
+ """
3996
+ if not self.base_ring() == QQ:
3997
+ raise NotImplementedError("conversion to polynomial are not implemented if the base ring is not Q")
3998
+ M = self.parent()
3999
+ k = self.weight() # only if self is homogeneous
4000
+ poly_parent = M.polynomial_ring(names, gens)
4001
+ if k == 0:
4002
+ return poly_parent(self[k])
4003
+
4004
+ # create the set of "weighted exponents" and compute sturm bound
4005
+ weights_of_generators = [gen.weight() for gen in gens]
4006
+ W = WeightedIntegerVectors(k, weights_of_generators).list()
4007
+ sturm_bound = self.group().sturm_bound(k)
4008
+
4009
+ # initialize the matrix of coefficients
4010
+ matrix_datum = []
4011
+
4012
+ # form the matrix of coefficients and list the monomials of weight k
4013
+ monomial_forms = [prod(M(gen) ** exp for exp, gen in zip(exps, gens)) for exps in W]
4014
+ monomial_polys = [prod(poly_gen ** exp for exp, poly_gen in zip(exps, poly_parent.gens())) for exps in W]
4015
+ matrix_datum = M._to_matrix(monomial_forms, prec=sturm_bound)
4016
+ mat = Matrix(matrix_datum).transpose()
4017
+
4018
+ # initialize the column vector of the coefficients of self
4019
+ coef_self = vector(self[k].coefficients(range(0, sturm_bound + 1))).column()
4020
+
4021
+ # solve the linear system: mat * X = coef_self
4022
+ soln = mat.solve_right(coef_self)
4023
+
4024
+ # initialize the polynomial associated to self
4025
+ poly = poly_parent.zero()
4026
+ for i, p in enumerate(monomial_polys):
4027
+ poly += soln[i, 0] * p
4028
+ return poly
4029
+
4030
+ def to_polynomial(self, names='x', gens=None):
4031
+ r"""
4032
+ Return a polynomial `P(x_0,..., x_n)` such that `P(g_0,..., g_n)` is equal to ``self``
4033
+ where `g_0, ..., g_n` is a list of generators of the parent.
4034
+
4035
+ INPUT:
4036
+
4037
+ - ``names`` -- list or tuple of names (strings), or a comma separated
4038
+ string; corresponds to the names of the variables
4039
+ - ``gens`` -- (default: ``None``) a list of generator of the parent of
4040
+ ``self``. If set to ``None``, the list returned by
4041
+ :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms`
4042
+ is used instead
4043
+
4044
+ OUTPUT: a polynomial in the variables ``names``
4045
+
4046
+ EXAMPLES::
4047
+
4048
+ sage: M = ModularFormsRing(1)
4049
+ sage: (M.0 + M.1).to_polynomial()
4050
+ x1 + x0
4051
+ sage: (M.0^10 + M.0 * M.1).to_polynomial()
4052
+ x0^10 + x0*x1
4053
+
4054
+ This method is not necessarily the inverse of
4055
+ :meth:`~sage.modular.modform.ring.ModularFormsRing.from_polynomial` since there may be some
4056
+ relations between the generators of the modular forms ring::
4057
+
4058
+ sage: M = ModularFormsRing(Gamma0(6))
4059
+ sage: P.<x0,x1,x2> = M.polynomial_ring()
4060
+ sage: M.from_polynomial(x1^2).to_polynomial()
4061
+ x0*x2 + 2*x1*x2 + 11*x2^2
4062
+ """
4063
+ M = self.parent()
4064
+ if gens is None:
4065
+ gens = M.gen_forms()
4066
+
4067
+ # sum the polynomial of each homogeneous part
4068
+ return sum(M(self[k])._homogeneous_to_polynomial(names, gens) for k in self.weights_list())
4069
+
4070
+ def serre_derivative(self):
4071
+ r"""
4072
+ Return the Serre derivative of the given graded modular form.
4073
+
4074
+ If ``self`` is a modular form of weight `k`, then the returned modular
4075
+ form will be of weight `k + 2`. If the form is not homogeneous, then
4076
+ this method sums the Serre derivative of each homogeneous component.
4077
+
4078
+ EXAMPLES::
4079
+
4080
+ sage: M = ModularFormsRing(1)
4081
+ sage: E4 = M.0
4082
+ sage: E6 = M.1
4083
+ sage: DE4 = E4.serre_derivative(); DE4
4084
+ -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6)
4085
+ sage: DE4 == (-1/3) * E6
4086
+ True
4087
+ sage: DE6 = E6.serre_derivative(); DE6
4088
+ -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6)
4089
+ sage: DE6 == (-1/2) * E4^2
4090
+ True
4091
+ sage: f = E4 + E6
4092
+ sage: Df = f.serre_derivative(); Df
4093
+ -5/6 - 72*q - 25416*q^2 - 484128*q^3 - 3785544*q^4 - 18225072*q^5 + O(q^6)
4094
+ sage: Df == (-1/3) * E6 + (-1/2) * E4^2
4095
+ True
4096
+ sage: M(1/2).serre_derivative()
4097
+ 0
4098
+ """
4099
+ M = self.parent()
4100
+ return M(sum(M(f.serre_derivative()) for k, f in self._forms_dictionary.items() if k != 0))
4101
+
4102
+ def derivative(self, name='E2'):
4103
+ r"""
4104
+ Return the derivative `q \frac{d}{dq}` of the given graded form.
4105
+
4106
+ Note that this method returns an element of a new parent, that is a
4107
+ quasimodular form. If the form is not homogeneous, then this method sums
4108
+ the derivative of each homogeneous component.
4109
+
4110
+ INPUT:
4111
+
4112
+ - ``name``-- string (default: ``'E2'``); the name of the weight 2
4113
+ Eisenstein series generating the graded algebra of quasimodular forms
4114
+ over the ring of modular forms
4115
+
4116
+ OUTPUT: a :class:`sage.modular.quasimodform.element.QuasiModularFormsElement`
4117
+
4118
+ EXAMPLES::
4119
+
4120
+ sage: M = ModularFormsRing(1)
4121
+ sage: E4 = M.0; E6 = M.1
4122
+ sage: dE4 = E4.derivative(); dE4
4123
+ 240*q + 4320*q^2 + 20160*q^3 + 70080*q^4 + 151200*q^5 + O(q^6)
4124
+ sage: dE4.parent()
4125
+ Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
4126
+ sage: dE4.is_modular_form()
4127
+ False
4128
+ """
4129
+ from sage.modular.quasimodform.ring import QuasiModularForms
4130
+ F = QuasiModularForms(self.group(), self.base_ring(), name)(self)
4131
+ return F.derivative()