passagemath-schemes 10.8.1a4__cp314-cp314t-macosx_13_0_arm64.whl

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